diff --git a/src/Exception.php b/src/Exception.php new file mode 100644 index 000000000..0249e50bd --- /dev/null +++ b/src/Exception.php @@ -0,0 +1,38 @@ + false, + 'charAlnum' => 'A-Za-z0-9', + 'charMark' => '-_.!~*\'()\[\]', + 'charReserved' => ';\/?:@&=+$,', + 'charSegment' => ':@&=+$,;', + 'escaped' => '%[[:xdigit:]]{2}', + 'unreserved' => null, + 'path' => null, + 'segment' => null, + 'uric' => null, + 'unwise' => '{}|\\\\^`' + ); + + /** + * @var bool + */ + protected $_allowUnwise = false; + + /**#@+ + * Part of a URL + * + * @var string|array + */ + protected $_scheme = null; + protected $_username = null; + protected $_password = null; + protected $_host = null; + protected $_port = null; + protected $_path = null; + protected $_query = null; + protected $_fragment = null; + /**#@-*/ + + /** + * _getRegex() + * + * @param string $regexName + * @param bool $allowUnwiseCharset + */ + final protected static function _getRegex($regexName, $allowUnwiseCharset = false) + { + if (!self::$_regex['initialized']) { + // Unreserved characters + self::$_regex['unreserved'] = '[' . self::$_regex['charAlnum'] + . self::$_regex['charMark'] . ']'; + + // Segment can use escaped, unreserved or a set of additional chars + self::$_regex['segment'] = '(?:' . self::$_regex['escaped'] . '|[' + . self::$_regex['charAlnum'] . self::$_regex['charMark'] + . self::$_regex['charSegment'] . '])*'; + + // Path can be a series of segmets char strings seperated by '/' + self::$_regex['path'] = '(?:\/(?:' . self::$_regex['segment'] . ')?)+'; + + // URI characters can be escaped, alphanumeric, mark or reserved chars + self::$_regex['uric'] = '(?:' . self::$_regex['escaped'] . '|[' + . self::$_regex['charAlnum'] . self::$_regex['charMark'] + . self::$_regex['charReserved'] + . '])'; + + self::$_regex['initialized'] = true; + } + + if (!array_key_exists($regexName, self::$_regex)) { + throw new \InvalidArgumentException('Requested regex ' . $regexName . ' is not a valid regexName'); + } + + switch ($regexName) { + case 'uric': + $regex = self::$_regex['uric']; + if ($allowUnwiseCharset) { + // alter the regex to include uwise charset + $regex = substr($regex, 0, -2) . self::$_regex['unwise'] . '])'; + } + break; + default: + $regex = self::$_regex[$regexName]; + break; + } + + + return $regex; + } + + public static function validate($url) + { + if (empty($url)) { + return false; + } + try { + $url = new self($url); + } catch (\Exception $exception) { + return false; + } + + if (!$url->getScheme()) { + return false; + } + + return $url->isValid(); + } + + /** + * validateUsername() + * + * @param string $username + * @return bool + */ + public static function validateUsername($username) + { + // If the username is empty, then it is considered valid + if (strlen($username) === 0) { + return true; + } + + // get predefined regexs to build custom regex + $escapedRegex = self::_getRegex('escaped'); + $charAlnumRegex = self::_getRegex('charAlnum'); + $charMarkRegex = self::_getRegex('charMark'); + + // Check the username against the allowed values + $status = preg_match( + '/^(?:' . $escapedRegex . '|[' . $charAlnumRegex . $charMarkRegex . ';:&=+$,' . '])+$/', + $username + ); + + return $status === 1; + } + + /** + * validatePassword() + * + * @param string $password + * @return boolean + */ + public static function validatePassword($password) + { + // If the password is empty, then it is considered valid + if (strlen($password) === 0) { + return true; + } + + // get predefined regexs to build custom regex + $escapedRegex = self::_getRegex('escaped'); + $charAlnumRegex = self::_getRegex('charAlnum'); + $charMarkRegex = self::_getRegex('charMark'); + + // Check the password against the allowed values + $status = preg_match( + '/^(?:' . $escapedRegex . '|[' . $charAlnumRegex . $charMarkRegex . ';:&=+$,' . '])+$/', + $password + ); + + return $status == 1; + } + + /** + * validateHost() + * + * @param $host + * @return bool + */ + public static function validateHost($host) + { + // If the host is empty, then it is considered invalid + if (strlen($host) === 0) { + return false; + } + + // Check the host against the allowed values; delegated to Zend_Filter. + $validate = new Hostname(Hostname::ALLOW_ALL); + + return $validate->isValid($host); + } + + /** + * validatePort() + * + * @param string|int $port + * @return bool + */ + public static function validatePort($port) + { + // If the port is empty, then it is considered valid + if (strlen($port) === 0) { + return true; + } + + // Check the port against the allowed values + return ctype_digit((string) $port) and 1 <= $port and $port <= 65535; + } + + /** + * validatePath() + * + * @param string $path + * @return bool + */ + public static function validatePath($path) + { + // If the path is empty, then it is considered valid + if (strlen($path) === 0) { + return true; + } + + // Determine whether the path is well-formed + $pathRegex = self::_getRegex('path'); + $status = preg_match('/^' . $pathRegex . '$/', $path); + + return (boolean) $status; + } + + /** + * validateQuery() + * + * @param string $query + * @return bool + */ + public static function validateQuery($query, $allowUnwiseCharacters = false) + { + // If query is empty, it is considered to be valid + if (strlen($query) === 0) { + return true; + } + + $uricRegex = self::_getRegex('uric', $allowUnwiseCharacters); + + // Determine whether the query is well-formed + $status = preg_match('/^' . $uricRegex . '*$/', $query, $matches); + + return ($status == 1); + } + + /** + * validateFragment() + * + * @param string $fragment + * @return bool + */ + public static function validateFragment($fragment, $allowUnwiseCharacters = false) + { + // If fragment is empty, it is considered to be valid + if (strlen($fragment) === 0) { + return true; + } + + $uricRegex = self::_getRegex('uric', $allowUnwiseCharacters); + + // Determine whether the fragment is well-formed + $status = preg_match('/^' . $uricRegex . '*$/', $fragment); + + return (boolean) $status; + } + + /** + * Constructor + * + * @param array|string $options + */ + public function __construct($optionsOrURL = null) + { + if (is_string($optionsOrURL)) { + $this->parse($optionsOrURL); + } elseif (is_array($optionsOrURL) && $optionsOrURL) { + $this->setOptions($optionsOrURL); + } + } + + /** + * setOptions + * + * @param $options + * @return URL + */ + public function setOptions(Array $options) + { + foreach ($options as $optionName => $optionValue) { + $methodName = 'set' . $optionName; + if (method_exists($this, $methodName)) { + $this->{$methodName}($optionValue); + } + } + return $this; + } + + /** + * setAllowUnwise() + * + * @param bool $allowUnwise + * @return \Zend\Uri\Url + */ + public function setAllowUnwise($allowUnwise = false) + { + $this->_allowUnwise = (bool) $allowUnwise; + return $this; + } + + /** + * parse() + * @param unknown_type $url + */ + public function parse($url) + { + // use PHP's parse_url + $parts = parse_url($url); + + if ($parts === false) { + throw new Exception('The url provided ' . $url . ' is not parsable.'); + } + + $options = array(); + foreach ($parts as $partName => $partValue) { + switch (strtolower($partName)) { + case 'url': + case 'fromurl': + $this->parse($partValue); + break; + case 'user': + $options['username'] = $partValue; + break; + case 'pass': + $options['password'] = $partValue; + break; + default: + $options[$partName] = $partValue; + break; + } + } + if ($options) { + $this->setOptions($options); + } + return $this; + } + + /** + * getScheme() + * + * @return string + */ + public function getScheme() + { + return $this->_scheme; + } + + /** + * setScheme() + * + * @param string $scheme + * @return URL + */ + public function setScheme($scheme) + { + $this->_scheme = strtolower($scheme); + return $this; + } + + /** + * getHost() + * + * @return string + */ + public function getHost() + { + return $this->_host; + } + + /** + * setHost() + * + * @param $host + * @return URL + */ + public function setHost($host) + { + $this->_host = $host; + return $this; + } + + /** + * isValidHost() + * + * @return bool + */ + public function isValidHost() + { + if ($this->_host) { + return self::validateHost($this->_host); + } + return true; + } + + /** + * getPort() + * + * @return string + */ + public function getPort() + { + return $this->_port; + } + + /** + * setPort() + * + * @param int|string $port + * @return URL + */ + public function setPort($port) + { + $this->_port = $port; + return $this; + } + + /** + * isValidPort() + * + */ + public function isValidPort() + { + if ($this->_port) { + return self::validatePort($this->_port); + } + + return true; + } + + /** + * getUsername() + * + * @return string + */ + public function getUsername() + { + return $this->_username; + } + + /** + * setUsername() + * + * @param string $username + * @return URL + */ + public function setUsername($username) + { + $this->_username = $username; + return $this; + } + + /** + * isValidUsername() + * + */ + public function isValidUsername() + { + if ($this->_username) { + return self::validateUsername($this->_username); + } + return true; + } + + /** + * getPassword() + * + * @return string + */ + public function getPassword() + { + return $this->_password; + } + + /** + * setPassword() + * + * @param string $password + * @return URL + */ + public function setPassword($password) + { + $this->_password = $password; + return $this; + } + + /** + * isValidPassword() + * + * @return bool + */ + public function isValidPassword() + { + // If the password is nonempty, but there is no username, then it is considered invalid + if (strlen($this->_password) > 0 and strlen($this->_username) === 0) { + return false; + } elseif ($this->_password != '') { + return self::validatePassword($this->_password); + } + + return true; + } + + + /** + * getPath() + * + * @return string + */ + public function getPath() + { + return $this->_path; + } + + /** + * setPath() + * + * @param $path + * @return URL + */ + public function setPath($path) + { + if (empty($path)) { + $path = '/'; + } + $this->_path = $path; + return $this; + } + + /** + * isValidPath() + * + * @return bool + */ + public function isValidPath() + { + if ($this->_path) { + return self::validatePath($this->_path); + } + + return true; + } + + /** + * getQuery() + * + * @return string + */ + public function getQuery() + { + return $this->_query; + } + + /** + * setQuery() + * + * @param string|array $query + * @return URL + */ + public function setQuery($query) + { + // If query is empty, set an empty string + if (empty($query) === true) { + $this->_query = ''; + return $this; + } + + // If query is an array, make a string out of it + if (is_array($query) === true) { + $query = http_build_query($query, '', '&'); + } else { + // If it is a string, make sure it is valid. If not parse and encode it + $query = (string) $query; + if (self::validateQuery($query, $this->_allowUnwise) === false) { + parse_str($query, $queryArray); + $query = http_build_query($queryArray, '', '&'); + } + } + + $this->_query = $query; + return $this; + } + + /** + * isValidQuery() + * + * @return bool + */ + public function isValidQuery() + { + if ($this->_query) { + return self::validateQuery($this->_query, $this->_allowUnwise); + } + + return true; + } + + /** + * Returns the query portion of the URL (after ?) as a + * key-value-array. If the query is empty an empty array + * is returned + * + * @return array + */ + public function getQueryAsArray() + { + $query = $this->getQuery(); + $queryParts = array(); + if ($query !== false) { + parse_str($query, $queryParts); + } + return $queryParts; + } + + /** + * Add or replace params in the query string for the current URI, and + * return the old query. + * + * @param array $queryParams + * @return string Old query string + */ + public function addReplaceQueryParameters(array $queryParams) + { + $queryParams = array_merge($this->getQueryAsArray(), $queryParams); + return $this->setQuery($queryParams); + } + + /** + * Remove params in the query string for the current URI, and + * return the old query. + * + * @param array $queryParamKeys + * @return string Old query string + */ + public function removeQueryParameters(array $queryParamKeys) + { + $queryParams = array_diff_key($this->getQueryAsArray(), array_fill_keys($queryParamKeys, 0)); + return $this->setQuery($queryParams); + } + + /** + * getFragement() + * + * @return true + */ + public function getFragment() + { + return $this->_fragment; + } + + /** + * setFragment() + * + * @param $fragment + * @return URL + */ + public function setFragment($fragment) + { + $this->_fragment = $fragment; + return $this; + } + + /** + * isValidFragment() + * + * @return bool + */ + public function isValidFragment() + { + if ($this->_fragment) { + return self::validateFragment($this->_fragment); + } + + return true; + } + + public function isValid() + { + // Return true if and only if all parts of the URI have passed validation + if ($this->isValidUsername() + && $this->isValidPassword() + && $this->isValidHost() + && $this->isValidPort() + && $this->isValidPath() + && $this->isValidQuery() + && $this->isValidFragment() + ) { + if (!$this->getScheme()) { + return false; + } + if (!$this->getHost()) { + return false; + } + return true; + } + return false; + } + + /** + * generate() + * + * @return string + */ + public function generate() + { + $url = ''; + + $password = strlen($this->_password) > 0 ? ":$this->_password" : ''; + $auth = strlen($this->_username) > 0 ? "$this->_username$password@" : ''; + $port = strlen($this->_port) > 0 ? ":$this->_port" : ''; + $query = strlen($this->_query) > 0 ? "?$this->_query" : ''; + $fragment = strlen($this->_fragment) > 0 ? "#$this->_fragment" : ''; + + $url = $this->_scheme + . '://' + . $auth + . $this->_host + . $port + . $this->_path + . $query + . $fragment; + + return $url; + } + + /** + * __toString() + * + * @return string + */ + public function __toString() + { + return $this->generate(); + } + +} + diff --git a/test/UrlTest.php b/test/UrlTest.php new file mode 100644 index 000000000..79aefb289 --- /dev/null +++ b/test/UrlTest.php @@ -0,0 +1,169 @@ +assertTrue($url->isValid()); + $this->assertEquals('http', $url->getScheme()); + $this->assertEquals('www.zend.com', $url->getHost()); + } + + /** + * Test that fromString() works proprerly for simple valid URLs + * + */ + public function testURLReturnsProperURL() + { + $tests = array( + 'http://www.zend.com', + 'https://www.zend.com', + 'http://www.zend.com/path', + 'http://www.zend.com/path?query=value' + ); + + foreach ($tests as $testURL) { + $obj = new Url($testURL); + $this->assertEquals($testURL, $obj->generate(), + "getUri() returned value that differs from input for $testURL"); + } + } + + public function testAllParts() + { + $url = new Url('http://andi:password@www.zend.com:8080/path/to/file?a=1&b=2#top'); + $this->assertEquals('http', $url->getScheme()); + $this->assertEquals('andi', $url->getUsername()); + $this->assertEquals('password', $url->getPassword()); + $this->assertEquals('www.zend.com', $url->getHost()); + $this->assertEquals('8080', $url->getPort()); + $this->assertEquals('/path/to/file', $url->getPath()); + $this->assertEquals('a=1&b=2', $url->getQuery()); + $this->assertEquals('top', $url->getFragment()); + $this->assertTrue($url->isValid()); + } + + public function testURLSupportsVariousCharacters() + { + $urlTarget = 'http://a_.!~*\'(-)n0123Di%25%26:pass;:&=+$,word@www.zend.com'; + $url = new Url($urlTarget); + $this->assertEquals($urlTarget, $url->generate()); + } + + public function testInvalidCharacter() + { + $url = new Url('http://an`di:password@www.zend.com'); + $this->assertFalse($url->isValid()); + } + + public function testSquareBrackets() + { + $url = new Url('https://example.com/foo/?var[]=1&var[]=2&some[thing]=3'); + $this->assertEquals('var[]=1&var[]=2&some[thing]=3', $url->getQuery()); + + $targetArray = array ( + 'var' => array ('1', '2'), + 'some' => array ('thing' => '3'), + ); + + $this->assertEquals($targetArray, $url->getQueryAsArray()); + } + + /** + * Ensures that successive slashes are considered valid + * + * @return void + */ + public function testSuccessiveSlashes() + { + + $url = new Url('http://example.com/foo//bar/baz//fob/'); + $this->assertTrue($url->isValid()); + $this->assertEquals('/foo//bar/baz//fob/', $url->getPath()); + + } + + /** + * Test that setQuery() can handle unencoded query parameters (as other + * browsers do), ZF-1934 + * + * @group ZF-1934 + * @return void + */ + public function testUnencodedQueryParameters() + { + $url = new Url('http://foo.com/bar'); + $url->setQuery('id=123&url=http://example.com/?bar=foo baz'); + $this->assertEquals('http://foo.com/bar?id=123&url=http%3A%2F%2Fexample.com%2F%3Fbar%3Dfoo+baz', $url->generate()); + } + + + /** + * Test that an extremely long URI does not break things up + * + * @group ZF-3712 + * @group ZF-7840 + */ + public function testVeryLongUrl() + { + if (!constant('TESTS_ZEND_URI_CRASH_TEST_ENABLED')) { + $this->markTestSkipped('Skipping test for "very long URLs" due to potential to crash on 32-bit systems'); + } + $urlString = file_get_contents(dirname(realpath(__FILE__)) . DIRECTORY_SEPARATOR . + '_files' . DIRECTORY_SEPARATOR . 'testVeryLongUriZF3712.txt'); + $url = new Url($urlString); + $this->assertEquals($urlString, $url->generate()); + } + + /** + * @group ZF-1480 + */ + public function testGetQueryAsArrayReturnsCorrectArray() + { + $url = new Url('http://example.com/foo/?test=a&var[]=1&var[]=2&some[thing]=3'); + $this->assertEquals(array( + 'test' => 'a', + 'var' => array(1, 2), + 'some' => array('thing' => 3) + ), + $url->getQueryAsArray() + ); + } + + /** + * @group ZF-1480 + */ + public function testAddReplaceQueryParametersModifiesQueryAndReturnsOldQuery() + { + $url = new Url('http://example.com/foo/?a=1&b=2&c=3'); + $url->addReplaceQueryParameters(array('b' => 4, 'd' => -1)); + $this->assertEquals(array( + 'a' => 1, + 'b' => 4, + 'c' => 3, + 'd' => -1 + ), $url->getQueryAsArray()); + $this->assertEquals('a=1&b=4&c=3&d=-1', $url->getQuery()); + } + + /** + * @group ZF-1480 + */ + public function testRemoveQueryParametersModifiesQueryAndReturnsOldQuery() + { + $url = new Url('http://example.com/foo/?a=1&b=2&c=3&d=4'); + $url->removeQueryParameters(array('b', 'd', 'e')); + $this->assertEquals(array('a' => 1, 'c' => 3), $url->getQueryAsArray()); + $this->assertEquals('a=1&c=3', $url->getQuery()); + } + +} diff --git a/test/_files/testVeryLongUriZF3712.txt b/test/_files/testVeryLongUriZF3712.txt new file mode 100644 index 000000000..1241eec39 --- /dev/null +++ b/test/_files/testVeryLongUriZF3712.txt @@ -0,0 +1 @@ +http://localhost:4444/selenium-server/driver/?cmd=type&1=banner_code&2=if+%28+typeof%28+globalseed+%29+%3D%3D+%22undefined%22%29+%7B%0A%09var+globalseed++%3D+Math.round%28Math.random%28%29%2A65535%29%3B+%0A%7D%0Avar+haveFlash1234562404000+%3D+false%3B%0Afunction+CAWBrowser%28%29%7B%0A%09var+ua+%3D+navigator.userAgent%3B%0A%09this.msie+%3D+%28ua+%26%26+%28+parseFloat%28+navigator.appVersion+%29++%3E%3D4+%29+%26%26+%28+ua.indexOf%28%22Opera%22%29+%3C+0+%29+%26%26+%28+ua.indexOf%28%22MSIE+4%22%29+%3C+0+%29+%26%26+%28+ua.indexOf%28+%22MSIE%22+%29+%3E%3D0%29+%29%3B%0A%09this.win+%3D+%28ua+%26%26+%28%28ua.indexOf%28+%22Windows+95%22+%29+%3E%3D0%29+%7C%7C+%28ua.indexOf%28%22Windows+NT%22%29+%3E%3D0+%29+%7C%7C+%28ua.indexOf%28%22Windows+98%22%29+%3E%3D0%29+%29+%29%3B%0A%09this.mac+%3D+%28navigator.platform+%26%26+%28navigator.platform.indexOf%28%27Mac%27%29%21%3D-1%29%29%3B%0A%09this.opera7+%3D+%28%28ua.indexOf%28%27Opera%27%29+%21%3D+-1%29+%26%26+window.opera+%26%26+document.readyState%29+%3F+1+%3A+0%3B%0A%09this.gecko+++%3D+%28ua.toLowerCase%28%29.indexOf%28%27gecko%27%29+%21%3D+-1%29+%26%26+%28ua.indexOf%28%27safari%27%29+%3D%3D+-1%29%3B%0A%09haveFlash1234562404000+%3D+%28navigator.mimeTypes+%26%26+navigator.mimeTypes%5B%22application%2Fx-shockwave-flash%22%5D%29+%3F+navigator.mimeTypes%5B%22application%2Fx-shockwave-flash%22%5D.enabledPlugin+%3A+0%3B%0A%09if%28+haveFlash1234562404000+%29%7B%0A%09%09haveFlash1234562404000+%3D+%28parseInt%28haveFlash1234562404000.description.substring%28haveFlash1234562404000.description.indexOf%28%22.%22%29-1%29%29%3E%3D6%29%3B%0A%09%7Delse+if+%28+this.msie+%26%26+this.win+%26%26+%21this.mac%29%7B%0A%09%09document.write%28%27%3CSCR%27+%2B+%27IPT+LANGUAGE%3DVBScript%5C%3E+%5Cn%27%0A%09%09%09%2B+%27+on+error+resume+next+%5Cn%27%0A%09%09%09%2B+%27+haveFlash1234562404000+%3D+%28IsObject%28CreateObject%28%22ShockwaveFlash.ShockwaveFlash.6%22%29%29%29%5Cn%27%0A%09%09%09%2B+%27%3C%2FSCR%27+%2B+%27IPT%5C%3E+%5Cn%27+%29%3B%0A%09%7D%0A%09%0A%09this.other+%3D+%21%28+%28this.gecko+%7C%7C+this.msie%29+%26%26+this.win+%26%26+%21this.mac%29%3B%0A%09this.desc+%3D++this.msie+%3F+%22msie+%22+%3A+this.gecko+%3F+%22gecko+%22+%3A+this.opera7+%3F+%22opera7%28other%29+%22+%3A+this.other%3F+%22other%22+%3A+%22ukn%22%3B%0A%09this.flash+%3D+haveFlash1234562404000+%3F+6+%3A+0%3B%09%0A%7D%0Afunction+CAWCode1234562404000%28%29%7B%0A%09this.server+%3D+%22engine.awaps.net%22%3B+%0A%09this.section+%3D+123456%3B%0A%09this.adw_w+%3D+240%3B%0A%09this.adw_h+%3D+400%3B%0A%09this.wh+%3D+%22240400%22%3B%0A%09this.subsection+%3D+0%3B%0A%09this.uniq+%3D+%221234562404000%22%3B%0A%09this.html_code+%3D+%22%22%3B%0A%09this.adw_a+%3D+0%3B%0A%09this.adw_p+%3D+0%3B%0A%09this.i_type+%3D+0%3B%0A%09this.seed+%3D+Math.round%28Math.random%28%29%2A65535%29%3B%0A%09this.jsinfo_onload+%3D+function%28t%2C+a%2C+p%2C+cmd%29%7B%0A%09++++++++var+d%3Ddocument%3B%0A%09%09this.adw_a+%3D+a%3B%0A%09%09this.adw_p+%3D+p%3B%0A%0A%09%09if+%28+this.adw_a+%3D%3D+0+%7C%7C+cmd+%3D%3D+2+%29%7B%0A%09%09%09if+%28%21aw_br.other%29%7B%0A%09%09%09%09aw_tb+%3D+d.getElementById%28%27aw_tb%27+%2B+this.uniq%29%3B%09%09%0A%09%09%09%09aw_tb.style.display+%3D+%27none%27%3B%0A%09%09%09%7D%0A++++++++%09%09return%3B%0A%09%09%7D%0A%0A%09%09if+%28+cmd+%3D%3D+1%29%7B%0A%09%09%09switch+%28+t+%29%7B%0A%09%09%09%09case+1%3A+this.writeGIF%28%29%3B+break%3B%0A%09%09%09%09case+2%3A+this.writeHTM%28%29%3B+break%3B%0A%09%09%09%09case+3%3A+this.writeSWF%28%29%3B+break%3B%0A%09%09%09%09case+4%3A%09this.writeJS%28%29%3B+break%3B%0A%09%09%09%09case+24%3A+this.writeJS%28%29%3B+break%3B%0A%09%09%09%09case+5%3A%09this.writeCustom%28%29%3B+return%3B+break%3B%0A%09%09%09%09default%3A+this.writeDef%28+97+%29%3B+return%3B+break%3B%0A%09%09%09%7D%0A%09%0A%09%09%09if%28+aw_br.other+%29%7B%0A%09%09%09%09d.write%28+this.html_code+%29%3B%09%09%0A%09%09%09%7Delse%7B%0A%09%09%09%09aw_td+%3D+d.getElementById%28%27aw_td%27+%2B+this.uniq%29%3B%09%09%09%0A%09%09%09%09aw_td.innerHTML+%3D+this.html_code%3B%09%09%0A%09%09%09%7D%0A%09%09%7D%0A%09%0A%09%7D%0A%09this.writeCustom+%3D+function%28%29%7B%0A%09%09%2F%2F+emplement+custom+code%2C+like+site+default+code%0A%09%7D%0A%09this.writeJS+%3D+function%28%29%7B%0A%09%09var+jssrc+%3D+%27http%3A%2F%2F%27+%2B+this.server+%2B+%27%2F0%2F%27+%2B+this.section+%2B+%27%2F%27+%2B+this.wh+%2B+%27.htm%3F0-0-%27+%2B+this.seed+%2B+%27-0-la%3A%27+%2B+this.adw_a+%2B+%27p%3A%27+%2B+this.adw_p+%2B+%27%26subsection%3D%27+%2B+this.subsection+%2B+%27%26c_uniq%3D%27+%2B+this.uniq%3B%0A%09%09if%28+aw_br.other+%29%7B%0A%09%09%09this.html_code+%3D+%27%3Csc%27%2B%27ript+src%3D%22%27+%2B+jssrc+%2B%27%22%3E%3C%2Fsc%27%2B%27ript%3E%27%3B%0A%09%09%7Delse%7B%0A%09%09%09this.html_code%3D%22%22%3B%0A%09%09%09var+h+%3D+document.getElementsByTagName%28%27head%27%29%5B0%5D%3B%0A%09%09%09var+s+%3D+document.createElement%28%27script%27%29%3B%0A%09%09%09s.type+%3D+%27text%2Fjavascript%27%3B%0A%09%09%09s.src+%3D+jssrc%3B%0A%09%09%09h.appendChild%28s%29%3B%0A%09%09%7D%0A%09%7D%0A%09this.writeGIF+%3D+function%28%29%7B%0A%09%09this.html_code+%3D++%27%3Ca+href%3Dhttp%3A%2F%2F%27+%2B+this.server+%2B+%27%2F1%2F%27+%2B+this.section+%2B+%27%2F%27+%2B+this.wh+%2B+%27.gif%3F0-0-%27+%2B+this.seed+%2B+%27-0-la%3A%27+%2B+this.adw_a+%2B+%27p%3A%27+%2B+this.adw_p+%2B+%27+target%3D_blank+%3E%27%0A%09%09%09%2B+%27%3Cimg+src%3Dhttp%3A%2F%2F%27+%2B+this.server+%2B+%27%2F0%2F%27+%2B+this.section+%2B+%27%2F%27+%2B+this.wh+%2B+%27.gif%3F0-0-%27+%2B+this.seed+%2B+%27-0-la%3A%27+%2B+this.adw_a+%2B+%27p%3A%27+%2B+this.adw_p+%2B+%27%26%27+%2B+%27timestamp%3D%27+%2B+this.seed+%2B+%27%26subsection%3D%27+%2B+this.subsection%0A%09%09%09%2B+%27+width%3D%27+%2B+this.adw_w+%2B+%27+height%3D%27+%2B+this.adw_h+%2B+%27+border%3D0%3E%3C%2Fa%3E%27%3B%0A%09%7D%0A%09this.writeHTM+%3D+function%28%29%7B%0A%09%09this.html_code+%3D++%27%3CIFRAME++src%3Dhttp%3A%2F%2F%27+%2B+this.server+%2B+%27%2F0%2F%27+%2B+this.section+%2B+%27%2F%27+%2B+this.wh+%2B+%27.htm%3F0-0-%27+%2B+this.seed+%2B+%27-0-la%3A%27+%2B+this.adw_a+%2B+%27p%3A%27+%2B+this.adw_p+%2B+%27%26subsection%3D%27+%2B+this.subsection%0A%09%09%09%2B+%27++width%3D%22%27+%2B+this.adw_w+%2B+%27%22+height%3D%22%27+%2B+this.adw_h+%2B+%27%22+frameborder%3D0+marginwidth%3D%220%22+marginheight%3D%220%22+scrolling%3D%22no%22%3E+%3C%2FIFRAME%3E%27%3B%0A%09%7D%0A%09this.writeSWF+%3D+function%28%29%7B%0A%09%09var+c_linkNmbs+%3D+%27%27%3B%0A%09%09for+%28var+n_linkNmb+%3D+0%3B+n_linkNmb+%3C+6%3B+n_linkNmb%2B%2B%29+%7B%0A%09%09%09c_linkNmbs+%2B%3D+%28n_linkNmb+%3D%3D+0+%3F+%27%27+%3A+%27%26%27%29+%2B+%27link%27+%2B+%28n_linkNmb+%2B+1%29+%2B+%27%3D%27+%2B+%27http%3A%2F%2F%27+%2B+this.server+%2B+%27%2F1%2F%27+%2B+this.section+%2B+%27%2F%27+%2B+this.wh+%2B+%27.swf%3F0-%27+%2B+n_linkNmb+%2B+%27-%27+%2B+this.seed+%2B+%27-0-la%3A%27+%2B+this.adw_a+%2B+%27p%3A%27+%2B+this.adw_p+%2B+%27%27%3B%0A%09%09%7D%0A%0A%09%09var+swf_url+%3D+%27http%3A%2F%2F%27+%2B+this.server+%2B+%27%2F0%2F%27+%2B+this.section+%2B+%27%2F%27%2B+this.wh+%2B+%27.swf%3F0-0-%27+%2B+this.seed+%2B+%27-0-la%3A%27+%2B+this.adw_a+%2B+%27p%3A%27+%2B+this.adw_p+%2B+%27-%26%27+%2B+%27section%3D%27+%2B+this.section+%2B+%27%26subsection%3D%27+%2B+this.subsection+%2B+%27%26%27+%2B+c_linkNmbs%3B%0A%0A%09%09this.html_code+%3D+%27%3Cobject+classid%3Dclsid%3AD27CDB6E-AE6D-11cf-96B8-444553540000+codebase%3Dhttp%3A%2F%2Fdownload.macromedia.com%2Fpub%2Fshockwave%2Fcabs%2Fflash%2Fswflash.cab%23version%3D5%2C0%2C0%2C0+width%3D%27%0A%09%09%09%2B+this.adw_w+%2B+%27+height%3D%27+%2B+this.adw_h+%2B+%27+%3E+%27+%2B+%27%3Cparam+name%3Dmovie+value%3D%27+%2B+swf_url+%2B+%27+%3E%3Cparam+name%3Dmenu+value%3Dfalse%3E%3Cparam+name%3Dquality+value%3Dhigh%3E%27%0A%09%09%09%2B+%27%3CEM%27+%2B+%27BED+src%3D%22%27+%2B+swf_url+%2B+%27%22+quality%3Dhigh+%27%0A%09%09%09%2B+%27menu%3Dfalse+swLiveConnect%3DFALSE+WIDTH%3D%27%2B+this.adw_w+%2B%27+HEIGHT%3D%27+%2B+this.adw_h+%0A%09%09%09%2B+%27+TYPE%3D%22application%2Fx-shockwave-flash%22+PLUGINSPAGE%3D%22http%3A%2F%2Fwww.macromedia.com%2Fshockwave%2Fdownload%2Findex.cgi%3FP1_Prod_Version%3DShockwaveFlash%22%3E%27%0A%09%09%09%2B+%27%3C%2FEMBED%3E%27%0A%09%09%09%2B+%27+%3C%2Fobject%3E%27%3B%0A%09%7D%0A%09this.writeDef+%3D+function%28num%29%7B%0A%09%09var+info+%3D+new+Image%28%29%3B%0A%09%09info.src+%3D+%22http%3A%2F%2F%22+%2B+this.server+%2B+%22%2F%22+%2B+num+%2B+%22%2F%22+%2B+this.section+%2B+%22%2F%22+%2B+this.wh+%2B+%22.gif%3F0-0-%22+%2B+this.seed%3B%0A%09%7D%0A%09this.write+%3D+function%28%29%7B%09%09%0A%09%09var+jssrc+%3D+%22http%3A%2F%2F%22+%2B+this.server+%2B+%22%2F3%2F%22+%2B+this.section+%2B+%22%2F%22+%2B+this.wh+%2B+%22.%3F%22%0A%09%09%09%2B+globalseed+%2B+%0A%09%09%09%22-0-%22+%2B+this.seed+%2B+%22%26swfcode%3D6%26awcode%3D33%26subsection%3D%22+%2B+this.subsection+%2B+%22%26c_uniq%3D%22+%2B+this.uniq+%2B+%22%26jsaction4%3D1%26flash%3D%22+%2B+aw_br.flash%3B%0A%09%09var+jssrc_code+%3D+%27%3Csc%27%2B%27ript+src%3D%22%27+%2B+jssrc+%2B%27%22%3E%3C%2Fsc%27%2B%27ript%3E%27%3B%0A%0A%09%09if+%28+%21aw_br.other%29%7B%0A%09%09%09document.write%28+%27%3Ctable+style%3D%22display%3Ainline%22+border%3D0+cellpadding%3D0+cellspacing%3D0+id%3D%22aw_tb%27%2Bthis.uniq%2B%27%22+width%3D%27+%2B+this.adw_w+%2B+%27+height%3D%27+%2B+this.adw_h+%2B+%27%22%3E%3Ctr%3E%3Ctd+id%3D%22aw_td%27%2Bthis.uniq%2B%27%22%3E%3C%2Ftd%3E%3C%2Ftr%3E%3C%2Ftable%3E%27+%29%3B%09%0A%09%09%09var+h+%3D+document.getElementsByTagName%28%27head%27%29%5B0%5D%3B%0A%09%09%09var+s+%3D+document.createElement%28%27scr%27%2B%27ipt%27%29%3B%0A%09%09%09s.type+%3D+%27text%2Fjavasc%27%2B%27ript%27%3B%0A%09%09%09s.src+%3D+jssrc%3B%0A%09%09%09h.appendChild%28s%29%3B%09%09%09%09%09%0A%09%09%7Delse%7B+%0A%09%09%09document.write%28jssrc_code%29%3B%0A%09%09%7D%0A%09%7D%0A%7D%0Afunction+aw_jsinfo_onload1234562404000%28t%2Ca%2Cp%2Ccmd%29%7B%0A%09code1234562404000.jsinfo_onload%28t%2Ca%2Cp%2Ccmd%29%3B%0A%7D%0Avar+aw_br+%3D+new+CAWBrowser%28%29%3B%0Avar+code1234562404000+%3D+new+CAWCode1234562404000%28%29%3B%0Acode1234562404000.write%28%29%3B&sessionId=140666 \ No newline at end of file