tfcconnection/.shadow-cljs/builds/app/dev/goog-js/goog.uri.uri.js

1 line
144 KiB
JavaScript

["^ ","~:resource-id",["~:shadow.build.classpath/resource","goog/uri/uri.js"],"~:js","goog.provide(\"goog.Uri\");\ngoog.provide(\"goog.Uri.QueryData\");\ngoog.require(\"goog.array\");\ngoog.require(\"goog.asserts\");\ngoog.require(\"goog.collections.maps\");\ngoog.require(\"goog.string\");\ngoog.require(\"goog.structs\");\ngoog.require(\"goog.uri.utils\");\ngoog.require(\"goog.uri.utils.ComponentIndex\");\ngoog.require(\"goog.uri.utils.StandardQueryParam\");\ngoog.Uri = function(opt_uri, opt_ignoreCase) {\n this.scheme_ = \"\";\n this.userInfo_ = \"\";\n this.domain_ = \"\";\n this.port_ = null;\n this.path_ = \"\";\n this.fragment_ = \"\";\n this.isReadOnly_ = false;\n this.ignoreCase_ = false;\n this.queryData_;\n var m;\n if (opt_uri instanceof goog.Uri) {\n this.ignoreCase_ = opt_ignoreCase !== undefined ? opt_ignoreCase : opt_uri.getIgnoreCase();\n this.setScheme(opt_uri.getScheme());\n this.setUserInfo(opt_uri.getUserInfo());\n this.setDomain(opt_uri.getDomain());\n this.setPort(opt_uri.getPort());\n this.setPath(opt_uri.getPath());\n this.setQueryData(opt_uri.getQueryData().clone());\n this.setFragment(opt_uri.getFragment());\n } else if (opt_uri && (m = goog.uri.utils.split(String(opt_uri)))) {\n this.ignoreCase_ = !!opt_ignoreCase;\n this.setScheme(m[goog.uri.utils.ComponentIndex.SCHEME] || \"\", true);\n this.setUserInfo(m[goog.uri.utils.ComponentIndex.USER_INFO] || \"\", true);\n this.setDomain(m[goog.uri.utils.ComponentIndex.DOMAIN] || \"\", true);\n this.setPort(m[goog.uri.utils.ComponentIndex.PORT]);\n this.setPath(m[goog.uri.utils.ComponentIndex.PATH] || \"\", true);\n this.setQueryData(m[goog.uri.utils.ComponentIndex.QUERY_DATA] || \"\", true);\n this.setFragment(m[goog.uri.utils.ComponentIndex.FRAGMENT] || \"\", true);\n } else {\n this.ignoreCase_ = !!opt_ignoreCase;\n this.queryData_ = new goog.Uri.QueryData(null, this.ignoreCase_);\n }\n};\ngoog.Uri.RANDOM_PARAM = goog.uri.utils.StandardQueryParam.RANDOM;\ngoog.Uri.prototype.toString = function() {\n var out = [];\n var scheme = this.getScheme();\n if (scheme) {\n out.push(goog.Uri.encodeSpecialChars_(scheme, goog.Uri.reDisallowedInSchemeOrUserInfo_, true), \":\");\n }\n var domain = this.getDomain();\n if (domain || scheme == \"file\") {\n out.push(\"//\");\n var userInfo = this.getUserInfo();\n if (userInfo) {\n out.push(goog.Uri.encodeSpecialChars_(userInfo, goog.Uri.reDisallowedInSchemeOrUserInfo_, true), \"@\");\n }\n out.push(goog.Uri.removeDoubleEncoding_(goog.string.urlEncode(domain)));\n var port = this.getPort();\n if (port != null) {\n out.push(\":\", String(port));\n }\n }\n var path = this.getPath();\n if (path) {\n if (this.hasDomain() && path.charAt(0) != \"/\") {\n out.push(\"/\");\n }\n out.push(goog.Uri.encodeSpecialChars_(path, path.charAt(0) == \"/\" ? goog.Uri.reDisallowedInAbsolutePath_ : goog.Uri.reDisallowedInRelativePath_, true));\n }\n var query = this.getEncodedQuery();\n if (query) {\n out.push(\"?\", query);\n }\n var fragment = this.getFragment();\n if (fragment) {\n out.push(\"#\", goog.Uri.encodeSpecialChars_(fragment, goog.Uri.reDisallowedInFragment_));\n }\n return out.join(\"\");\n};\ngoog.Uri.prototype.resolve = function(relativeUri) {\n var absoluteUri = this.clone();\n var overridden = relativeUri.hasScheme();\n if (overridden) {\n absoluteUri.setScheme(relativeUri.getScheme());\n } else {\n overridden = relativeUri.hasUserInfo();\n }\n if (overridden) {\n absoluteUri.setUserInfo(relativeUri.getUserInfo());\n } else {\n overridden = relativeUri.hasDomain();\n }\n if (overridden) {\n absoluteUri.setDomain(relativeUri.getDomain());\n } else {\n overridden = relativeUri.hasPort();\n }\n var path = relativeUri.getPath();\n if (overridden) {\n absoluteUri.setPort(relativeUri.getPort());\n } else {\n overridden = relativeUri.hasPath();\n if (overridden) {\n if (path.charAt(0) != \"/\") {\n if (this.hasDomain() && !this.hasPath()) {\n path = \"/\" + path;\n } else {\n var lastSlashIndex = absoluteUri.getPath().lastIndexOf(\"/\");\n if (lastSlashIndex != -1) {\n path = absoluteUri.getPath().slice(0, lastSlashIndex + 1) + path;\n }\n }\n }\n path = goog.Uri.removeDotSegments(path);\n }\n }\n if (overridden) {\n absoluteUri.setPath(path);\n } else {\n overridden = relativeUri.hasQuery();\n }\n if (overridden) {\n absoluteUri.setQueryData(relativeUri.getQueryData().clone());\n } else {\n overridden = relativeUri.hasFragment();\n }\n if (overridden) {\n absoluteUri.setFragment(relativeUri.getFragment());\n }\n return absoluteUri;\n};\ngoog.Uri.prototype.clone = function() {\n return new goog.Uri(this);\n};\ngoog.Uri.prototype.getScheme = function() {\n return this.scheme_;\n};\ngoog.Uri.prototype.setScheme = function(newScheme, opt_decode) {\n this.enforceReadOnly();\n this.scheme_ = opt_decode ? goog.Uri.decodeOrEmpty_(newScheme, true) : newScheme;\n if (this.scheme_) {\n this.scheme_ = this.scheme_.replace(/:$/, \"\");\n }\n return this;\n};\ngoog.Uri.prototype.hasScheme = function() {\n return !!this.scheme_;\n};\ngoog.Uri.prototype.getUserInfo = function() {\n return this.userInfo_;\n};\ngoog.Uri.prototype.setUserInfo = function(newUserInfo, opt_decode) {\n this.enforceReadOnly();\n this.userInfo_ = opt_decode ? goog.Uri.decodeOrEmpty_(newUserInfo) : newUserInfo;\n return this;\n};\ngoog.Uri.prototype.hasUserInfo = function() {\n return !!this.userInfo_;\n};\ngoog.Uri.prototype.getDomain = function() {\n return this.domain_;\n};\ngoog.Uri.prototype.setDomain = function(newDomain, opt_decode) {\n this.enforceReadOnly();\n this.domain_ = opt_decode ? goog.Uri.decodeOrEmpty_(newDomain, true) : newDomain;\n return this;\n};\ngoog.Uri.prototype.hasDomain = function() {\n return !!this.domain_;\n};\ngoog.Uri.prototype.getPort = function() {\n return this.port_;\n};\ngoog.Uri.prototype.setPort = function(newPort) {\n this.enforceReadOnly();\n if (newPort) {\n newPort = Number(newPort);\n if (isNaN(newPort) || newPort < 0) {\n throw new Error(\"Bad port number \" + newPort);\n }\n this.port_ = newPort;\n } else {\n this.port_ = null;\n }\n return this;\n};\ngoog.Uri.prototype.hasPort = function() {\n return this.port_ != null;\n};\ngoog.Uri.prototype.getPath = function() {\n return this.path_;\n};\ngoog.Uri.prototype.setPath = function(newPath, opt_decode) {\n this.enforceReadOnly();\n this.path_ = opt_decode ? goog.Uri.decodeOrEmpty_(newPath, true) : newPath;\n return this;\n};\ngoog.Uri.prototype.hasPath = function() {\n return !!this.path_;\n};\ngoog.Uri.prototype.hasQuery = function() {\n return this.queryData_.toString() !== \"\";\n};\ngoog.Uri.prototype.setQueryData = function(queryData, opt_decode) {\n this.enforceReadOnly();\n if (queryData instanceof goog.Uri.QueryData) {\n this.queryData_ = queryData;\n this.queryData_.setIgnoreCase(this.ignoreCase_);\n } else {\n if (!opt_decode) {\n queryData = goog.Uri.encodeSpecialChars_(queryData, goog.Uri.reDisallowedInQuery_);\n }\n this.queryData_ = new goog.Uri.QueryData(queryData, this.ignoreCase_);\n }\n return this;\n};\ngoog.Uri.prototype.setQuery = function(newQuery, opt_decode) {\n return this.setQueryData(newQuery, opt_decode);\n};\ngoog.Uri.prototype.getEncodedQuery = function() {\n return this.queryData_.toString();\n};\ngoog.Uri.prototype.getDecodedQuery = function() {\n return this.queryData_.toDecodedString();\n};\ngoog.Uri.prototype.getQueryData = function() {\n return this.queryData_;\n};\ngoog.Uri.prototype.getQuery = function() {\n return this.getEncodedQuery();\n};\ngoog.Uri.prototype.setParameterValue = function(key, value) {\n this.enforceReadOnly();\n this.queryData_.set(key, value);\n return this;\n};\ngoog.Uri.prototype.setParameterValues = function(key, values) {\n this.enforceReadOnly();\n if (!Array.isArray(values)) {\n values = [String(values)];\n }\n this.queryData_.setValues(key, values);\n return this;\n};\ngoog.Uri.prototype.getParameterValues = function(name) {\n return this.queryData_.getValues(name);\n};\ngoog.Uri.prototype.getParameterValue = function(paramName) {\n return this.queryData_.get(paramName);\n};\ngoog.Uri.prototype.getFragment = function() {\n return this.fragment_;\n};\ngoog.Uri.prototype.setFragment = function(newFragment, opt_decode) {\n this.enforceReadOnly();\n this.fragment_ = opt_decode ? goog.Uri.decodeOrEmpty_(newFragment) : newFragment;\n return this;\n};\ngoog.Uri.prototype.hasFragment = function() {\n return !!this.fragment_;\n};\ngoog.Uri.prototype.hasSameDomainAs = function(uri2) {\n return (!this.hasDomain() && !uri2.hasDomain() || this.getDomain() == uri2.getDomain()) && (!this.hasPort() && !uri2.hasPort() || this.getPort() == uri2.getPort());\n};\ngoog.Uri.prototype.makeUnique = function() {\n this.enforceReadOnly();\n this.setParameterValue(goog.Uri.RANDOM_PARAM, goog.string.getRandomString());\n return this;\n};\ngoog.Uri.prototype.removeParameter = function(key) {\n this.enforceReadOnly();\n this.queryData_.remove(key);\n return this;\n};\ngoog.Uri.prototype.setReadOnly = function(isReadOnly) {\n this.isReadOnly_ = isReadOnly;\n return this;\n};\ngoog.Uri.prototype.isReadOnly = function() {\n return this.isReadOnly_;\n};\ngoog.Uri.prototype.enforceReadOnly = function() {\n if (this.isReadOnly_) {\n throw new Error(\"Tried to modify a read-only Uri\");\n }\n};\ngoog.Uri.prototype.setIgnoreCase = function(ignoreCase) {\n this.ignoreCase_ = ignoreCase;\n if (this.queryData_) {\n this.queryData_.setIgnoreCase(ignoreCase);\n }\n return this;\n};\ngoog.Uri.prototype.getIgnoreCase = function() {\n return this.ignoreCase_;\n};\ngoog.Uri.parse = function(uri, opt_ignoreCase) {\n return uri instanceof goog.Uri ? uri.clone() : new goog.Uri(uri, opt_ignoreCase);\n};\ngoog.Uri.create = function(opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_query, opt_fragment, opt_ignoreCase) {\n var uri = new goog.Uri(null, opt_ignoreCase);\n opt_scheme && uri.setScheme(opt_scheme);\n opt_userInfo && uri.setUserInfo(opt_userInfo);\n opt_domain && uri.setDomain(opt_domain);\n opt_port && uri.setPort(opt_port);\n opt_path && uri.setPath(opt_path);\n opt_query && uri.setQueryData(opt_query);\n opt_fragment && uri.setFragment(opt_fragment);\n return uri;\n};\ngoog.Uri.resolve = function(base, rel) {\n if (!(base instanceof goog.Uri)) {\n base = goog.Uri.parse(base);\n }\n if (!(rel instanceof goog.Uri)) {\n rel = goog.Uri.parse(rel);\n }\n return base.resolve(rel);\n};\ngoog.Uri.removeDotSegments = function(path) {\n if (path == \"..\" || path == \".\") {\n return \"\";\n } else if (!goog.string.contains(path, \"./\") && !goog.string.contains(path, \"/.\")) {\n return path;\n } else {\n var leadingSlash = goog.string.startsWith(path, \"/\");\n var segments = path.split(\"/\");\n var out = [];\n for (var pos = 0; pos < segments.length;) {\n var segment = segments[pos++];\n if (segment == \".\") {\n if (leadingSlash && pos == segments.length) {\n out.push(\"\");\n }\n } else if (segment == \"..\") {\n if (out.length > 1 || out.length == 1 && out[0] != \"\") {\n out.pop();\n }\n if (leadingSlash && pos == segments.length) {\n out.push(\"\");\n }\n } else {\n out.push(segment);\n leadingSlash = true;\n }\n }\n return out.join(\"/\");\n }\n};\ngoog.Uri.decodeOrEmpty_ = function(val, opt_preserveReserved) {\n if (!val) {\n return \"\";\n }\n return opt_preserveReserved ? decodeURI(val.replace(/%25/g, \"%2525\")) : decodeURIComponent(val);\n};\ngoog.Uri.encodeSpecialChars_ = function(unescapedPart, extra, opt_removeDoubleEncoding) {\n if (typeof unescapedPart === \"string\") {\n var encoded = encodeURI(unescapedPart).replace(extra, goog.Uri.encodeChar_);\n if (opt_removeDoubleEncoding) {\n encoded = goog.Uri.removeDoubleEncoding_(encoded);\n }\n return encoded;\n }\n return null;\n};\ngoog.Uri.encodeChar_ = function(ch) {\n var n = ch.charCodeAt(0);\n return \"%\" + (n >> 4 & 15).toString(16) + (n & 15).toString(16);\n};\ngoog.Uri.removeDoubleEncoding_ = function(doubleEncodedString) {\n return doubleEncodedString.replace(/%25([0-9a-fA-F]{2})/g, \"%$1\");\n};\ngoog.Uri.reDisallowedInSchemeOrUserInfo_ = /[#\\/\\?@]/g;\ngoog.Uri.reDisallowedInRelativePath_ = /[#\\?:]/g;\ngoog.Uri.reDisallowedInAbsolutePath_ = /[#\\?]/g;\ngoog.Uri.reDisallowedInQuery_ = /[#\\?@]/g;\ngoog.Uri.reDisallowedInFragment_ = /#/g;\ngoog.Uri.haveSameDomain = function(uri1String, uri2String) {\n var pieces1 = goog.uri.utils.split(uri1String);\n var pieces2 = goog.uri.utils.split(uri2String);\n return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] == pieces2[goog.uri.utils.ComponentIndex.DOMAIN] && pieces1[goog.uri.utils.ComponentIndex.PORT] == pieces2[goog.uri.utils.ComponentIndex.PORT];\n};\ngoog.Uri.QueryData = function(opt_query, opt_ignoreCase) {\n this.keyMap_ = null;\n this.count_ = null;\n this.encodedQuery_ = opt_query || null;\n this.ignoreCase_ = !!opt_ignoreCase;\n};\ngoog.Uri.QueryData.prototype.ensureKeyMapInitialized_ = function() {\n if (!this.keyMap_) {\n this.keyMap_ = new Map();\n this.count_ = 0;\n if (this.encodedQuery_) {\n var self = this;\n goog.uri.utils.parseQueryData(this.encodedQuery_, function(name, value) {\n self.add(goog.string.urlDecode(name), value);\n });\n }\n }\n};\ngoog.Uri.QueryData.createFromMap = function(map, opt_ignoreCase) {\n var keys = goog.structs.getKeys(map);\n if (typeof keys == \"undefined\") {\n throw new Error(\"Keys are undefined\");\n }\n var queryData = new goog.Uri.QueryData(null, opt_ignoreCase);\n var values = goog.structs.getValues(map);\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = values[i];\n if (!Array.isArray(value)) {\n queryData.add(key, value);\n } else {\n queryData.setValues(key, value);\n }\n }\n return queryData;\n};\ngoog.Uri.QueryData.createFromKeysValues = function(keys, values, opt_ignoreCase) {\n if (keys.length != values.length) {\n throw new Error(\"Mismatched lengths for keys/values\");\n }\n var queryData = new goog.Uri.QueryData(null, opt_ignoreCase);\n for (var i = 0; i < keys.length; i++) {\n queryData.add(keys[i], values[i]);\n }\n return queryData;\n};\ngoog.Uri.QueryData.prototype.getCount = function() {\n this.ensureKeyMapInitialized_();\n return this.count_;\n};\ngoog.Uri.QueryData.prototype.add = function(key, value) {\n this.ensureKeyMapInitialized_();\n this.invalidateCache_();\n key = this.getKeyName_(key);\n var values = this.keyMap_.get(key);\n if (!values) {\n this.keyMap_.set(key, values = []);\n }\n values.push(value);\n this.count_ = goog.asserts.assertNumber(this.count_) + 1;\n return this;\n};\ngoog.Uri.QueryData.prototype.remove = function(key) {\n this.ensureKeyMapInitialized_();\n key = this.getKeyName_(key);\n if (this.keyMap_.has(key)) {\n this.invalidateCache_();\n this.count_ = goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\n return this.keyMap_.delete(key);\n }\n return false;\n};\ngoog.Uri.QueryData.prototype.clear = function() {\n this.invalidateCache_();\n this.keyMap_ = null;\n this.count_ = 0;\n};\ngoog.Uri.QueryData.prototype.isEmpty = function() {\n this.ensureKeyMapInitialized_();\n return this.count_ == 0;\n};\ngoog.Uri.QueryData.prototype.containsKey = function(key) {\n this.ensureKeyMapInitialized_();\n key = this.getKeyName_(key);\n return this.keyMap_.has(key);\n};\ngoog.Uri.QueryData.prototype.containsValue = function(value) {\n var vals = this.getValues();\n return goog.array.contains(vals, value);\n};\ngoog.Uri.QueryData.prototype.forEach = function(f, opt_scope) {\n this.ensureKeyMapInitialized_();\n this.keyMap_.forEach(function(values, key) {\n values.forEach(function(value) {\n f.call(opt_scope, value, key, this);\n }, this);\n }, this);\n};\ngoog.Uri.QueryData.prototype.getKeys = function() {\n this.ensureKeyMapInitialized_();\n const vals = Array.from(this.keyMap_.values());\n const keys = Array.from(this.keyMap_.keys());\n const rv = [];\n for (let i = 0; i < keys.length; i++) {\n const val = vals[i];\n for (let j = 0; j < val.length; j++) {\n rv.push(keys[i]);\n }\n }\n return rv;\n};\ngoog.Uri.QueryData.prototype.getValues = function(opt_key) {\n this.ensureKeyMapInitialized_();\n let rv = [];\n if (typeof opt_key === \"string\") {\n if (this.containsKey(opt_key)) {\n rv = rv.concat(this.keyMap_.get(this.getKeyName_(opt_key)));\n }\n } else {\n const values = Array.from(this.keyMap_.values());\n for (let i = 0; i < values.length; i++) {\n rv = rv.concat(values[i]);\n }\n }\n return rv;\n};\ngoog.Uri.QueryData.prototype.set = function(key, value) {\n this.ensureKeyMapInitialized_();\n this.invalidateCache_();\n key = this.getKeyName_(key);\n if (this.containsKey(key)) {\n this.count_ = goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\n }\n this.keyMap_.set(key, [value]);\n this.count_ = goog.asserts.assertNumber(this.count_) + 1;\n return this;\n};\ngoog.Uri.QueryData.prototype.get = function(key, opt_default) {\n if (!key) {\n return opt_default;\n }\n var values = this.getValues(key);\n return values.length > 0 ? String(values[0]) : opt_default;\n};\ngoog.Uri.QueryData.prototype.setValues = function(key, values) {\n this.remove(key);\n if (values.length > 0) {\n this.invalidateCache_();\n this.keyMap_.set(this.getKeyName_(key), goog.array.clone(values));\n this.count_ = goog.asserts.assertNumber(this.count_) + values.length;\n }\n};\ngoog.Uri.QueryData.prototype.toString = function() {\n if (this.encodedQuery_) {\n return this.encodedQuery_;\n }\n if (!this.keyMap_) {\n return \"\";\n }\n const sb = [];\n const keys = Array.from(this.keyMap_.keys());\n for (var i = 0; i < keys.length; i++) {\n const key = keys[i];\n const encodedKey = goog.string.urlEncode(key);\n const val = this.getValues(key);\n for (var j = 0; j < val.length; j++) {\n var param = encodedKey;\n if (val[j] !== \"\") {\n param += \"\\x3d\" + goog.string.urlEncode(val[j]);\n }\n sb.push(param);\n }\n }\n return this.encodedQuery_ = sb.join(\"\\x26\");\n};\ngoog.Uri.QueryData.prototype.toDecodedString = function() {\n return goog.Uri.decodeOrEmpty_(this.toString());\n};\ngoog.Uri.QueryData.prototype.invalidateCache_ = function() {\n this.encodedQuery_ = null;\n};\ngoog.Uri.QueryData.prototype.filterKeys = function(keys) {\n this.ensureKeyMapInitialized_();\n this.keyMap_.forEach(function(value, key) {\n if (!goog.array.contains(keys, key)) {\n this.remove(key);\n }\n }, this);\n return this;\n};\ngoog.Uri.QueryData.prototype.clone = function() {\n var rv = new goog.Uri.QueryData();\n rv.encodedQuery_ = this.encodedQuery_;\n if (this.keyMap_) {\n rv.keyMap_ = new Map(this.keyMap_);\n rv.count_ = this.count_;\n }\n return rv;\n};\ngoog.Uri.QueryData.prototype.getKeyName_ = function(arg) {\n var keyName = String(arg);\n if (this.ignoreCase_) {\n keyName = keyName.toLowerCase();\n }\n return keyName;\n};\ngoog.Uri.QueryData.prototype.setIgnoreCase = function(ignoreCase) {\n var resetKeys = ignoreCase && !this.ignoreCase_;\n if (resetKeys) {\n this.ensureKeyMapInitialized_();\n this.invalidateCache_();\n this.keyMap_.forEach(function(value, key) {\n var lowerCase = key.toLowerCase();\n if (key != lowerCase) {\n this.remove(key);\n this.setValues(lowerCase, value);\n }\n }, this);\n }\n this.ignoreCase_ = ignoreCase;\n};\ngoog.Uri.QueryData.prototype.extend = function(var_args) {\n for (var i = 0; i < arguments.length; i++) {\n var data = arguments[i];\n goog.structs.forEach(data, function(value, key) {\n this.add(key, value);\n }, this);\n }\n};\n","~:source","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Class for parsing and formatting URIs.\n *\n * This package is deprecated in favour of the Closure URL package (goog.url)\n * when manipulating URIs for use by a browser. This package uses regular\n * expressions to parse a potential URI which can fall out of sync with how a\n * browser will actually interpret the URI. See\n * `goog.uri.utils.setUrlPackageSupportLoggingHandler` for one way to identify\n * URIs that should instead be parsed using the URL package.\n *\n * Use goog.Uri(string) to parse a URI string. Use goog.Uri.create(...) to\n * create a new instance of the goog.Uri object from Uri parts.\n *\n * e.g: <code>var myUri = new goog.Uri(window.location);</code>\n *\n * Implements RFC 3986 for parsing/formatting URIs.\n * http://www.ietf.org/rfc/rfc3986.txt\n *\n * Some changes have been made to the interface (more like .NETs), though the\n * internal representation is now of un-encoded parts, this will change the\n * behavior slightly.\n */\n\ngoog.provide('goog.Uri');\ngoog.provide('goog.Uri.QueryData');\n\ngoog.require('goog.array');\ngoog.require('goog.asserts');\ngoog.require('goog.collections.maps');\ngoog.require('goog.string');\ngoog.require('goog.structs');\ngoog.require('goog.uri.utils');\ngoog.require('goog.uri.utils.ComponentIndex');\ngoog.require('goog.uri.utils.StandardQueryParam');\n\n\n\n/**\n * This class contains setters and getters for the parts of the URI.\n * The <code>getXyz</code>/<code>setXyz</code> methods return the decoded part\n * -- so<code>goog.Uri.parse('/foo%20bar').getPath()</code> will return the\n * decoded path, <code>/foo bar</code>.\n *\n * Reserved characters (see RFC 3986 section 2.2) can be present in\n * their percent-encoded form in scheme, domain, and path URI components and\n * will not be auto-decoded. For example:\n * <code>goog.Uri.parse('rel%61tive/path%2fto/resource').getPath()</code> will\n * return <code>relative/path%2fto/resource</code>.\n *\n * The constructor accepts an optional unparsed, raw URI string. The parser\n * is relaxed, so special characters that aren't escaped but don't cause\n * ambiguities will not cause parse failures.\n *\n * All setters return <code>this</code> and so may be chained, a la\n * <code>goog.Uri.parse('/foo').setFragment('part').toString()</code>.\n *\n * @param {*=} opt_uri Optional string URI to parse\n * (use goog.Uri.create() to create a URI from parts), or if\n * a goog.Uri is passed, a clone is created.\n * @param {boolean=} opt_ignoreCase If true, #getParameterValue will ignore\n * the case of the parameter name.\n *\n * @throws URIError If opt_uri is provided and URI is malformed (that is,\n * if decodeURIComponent fails on any of the URI components).\n * @constructor\n * @struct\n */\ngoog.Uri = function(opt_uri, opt_ignoreCase) {\n 'use strict';\n /**\n * Scheme such as \"http\".\n * @private {string}\n */\n this.scheme_ = '';\n\n /**\n * User credentials in the form \"username:password\".\n * @private {string}\n */\n this.userInfo_ = '';\n\n /**\n * Domain part, e.g. \"www.google.com\".\n * @private {string}\n */\n this.domain_ = '';\n\n /**\n * Port, e.g. 8080.\n * @private {?number}\n */\n this.port_ = null;\n\n /**\n * Path, e.g. \"/tests/img.png\".\n * @private {string}\n */\n this.path_ = '';\n\n /**\n * The fragment without the #.\n * @private {string}\n */\n this.fragment_ = '';\n\n /**\n * Whether or not this Uri should be treated as Read Only.\n * @private {boolean}\n */\n this.isReadOnly_ = false;\n\n /**\n * Whether or not to ignore case when comparing query params.\n * @private {boolean}\n */\n this.ignoreCase_ = false;\n\n /**\n * Object representing query data.\n * @private {!goog.Uri.QueryData}\n */\n this.queryData_;\n\n // Parse in the uri string\n var m;\n if (opt_uri instanceof goog.Uri) {\n this.ignoreCase_ = (opt_ignoreCase !== undefined) ? opt_ignoreCase :\n opt_uri.getIgnoreCase();\n this.setScheme(opt_uri.getScheme());\n this.setUserInfo(opt_uri.getUserInfo());\n this.setDomain(opt_uri.getDomain());\n this.setPort(opt_uri.getPort());\n this.setPath(opt_uri.getPath());\n this.setQueryData(opt_uri.getQueryData().clone());\n this.setFragment(opt_uri.getFragment());\n } else if (opt_uri && (m = goog.uri.utils.split(String(opt_uri)))) {\n this.ignoreCase_ = !!opt_ignoreCase;\n\n // Set the parts -- decoding as we do so.\n // COMPATIBILITY NOTE - In IE, unmatched fields may be empty strings,\n // whereas in other browsers they will be undefined.\n this.setScheme(m[goog.uri.utils.ComponentIndex.SCHEME] || '', true);\n this.setUserInfo(m[goog.uri.utils.ComponentIndex.USER_INFO] || '', true);\n this.setDomain(m[goog.uri.utils.ComponentIndex.DOMAIN] || '', true);\n this.setPort(m[goog.uri.utils.ComponentIndex.PORT]);\n this.setPath(m[goog.uri.utils.ComponentIndex.PATH] || '', true);\n this.setQueryData(m[goog.uri.utils.ComponentIndex.QUERY_DATA] || '', true);\n this.setFragment(m[goog.uri.utils.ComponentIndex.FRAGMENT] || '', true);\n\n } else {\n this.ignoreCase_ = !!opt_ignoreCase;\n this.queryData_ = new goog.Uri.QueryData(null, this.ignoreCase_);\n }\n};\n\n\n/**\n * Parameter name added to stop caching.\n * @type {string}\n */\ngoog.Uri.RANDOM_PARAM = goog.uri.utils.StandardQueryParam.RANDOM;\n\n\n/**\n * @return {string} The string form of the url.\n * @override\n */\ngoog.Uri.prototype.toString = function() {\n 'use strict';\n var out = [];\n\n var scheme = this.getScheme();\n if (scheme) {\n out.push(\n goog.Uri.encodeSpecialChars_(\n scheme, goog.Uri.reDisallowedInSchemeOrUserInfo_, true),\n ':');\n }\n\n var domain = this.getDomain();\n if (domain || scheme == 'file') {\n out.push('//');\n\n var userInfo = this.getUserInfo();\n if (userInfo) {\n out.push(\n goog.Uri.encodeSpecialChars_(\n userInfo, goog.Uri.reDisallowedInSchemeOrUserInfo_, true),\n '@');\n }\n\n out.push(goog.Uri.removeDoubleEncoding_(goog.string.urlEncode(domain)));\n\n var port = this.getPort();\n if (port != null) {\n out.push(':', String(port));\n }\n }\n\n var path = this.getPath();\n if (path) {\n if (this.hasDomain() && path.charAt(0) != '/') {\n out.push('/');\n }\n out.push(goog.Uri.encodeSpecialChars_(\n path,\n path.charAt(0) == '/' ? goog.Uri.reDisallowedInAbsolutePath_ :\n goog.Uri.reDisallowedInRelativePath_,\n true));\n }\n\n var query = this.getEncodedQuery();\n if (query) {\n out.push('?', query);\n }\n\n var fragment = this.getFragment();\n if (fragment) {\n out.push(\n '#',\n goog.Uri.encodeSpecialChars_(\n fragment, goog.Uri.reDisallowedInFragment_));\n }\n return out.join('');\n};\n\n\n/**\n * Resolves the given relative URI (a goog.Uri object), using the URI\n * represented by this instance as the base URI.\n *\n * There are several kinds of relative URIs:<br>\n * 1. foo - replaces the last part of the path, the whole query and fragment<br>\n * 2. /foo - replaces the path, the query and fragment<br>\n * 3. //foo - replaces everything from the domain on. foo is a domain name<br>\n * 4. ?foo - replace the query and fragment<br>\n * 5. #foo - replace the fragment only\n *\n * Additionally, if relative URI has a non-empty path, all \"..\" and \".\"\n * segments will be resolved, as described in RFC 3986.\n *\n * @param {!goog.Uri} relativeUri The relative URI to resolve.\n * @return {!goog.Uri} The resolved URI.\n */\ngoog.Uri.prototype.resolve = function(relativeUri) {\n 'use strict';\n var absoluteUri = this.clone();\n\n // we satisfy these conditions by looking for the first part of relativeUri\n // that is not blank and applying defaults to the rest\n\n var overridden = relativeUri.hasScheme();\n\n if (overridden) {\n absoluteUri.setScheme(relativeUri.getScheme());\n } else {\n overridden = relativeUri.hasUserInfo();\n }\n\n if (overridden) {\n absoluteUri.setUserInfo(relativeUri.getUserInfo());\n } else {\n overridden = relativeUri.hasDomain();\n }\n\n if (overridden) {\n absoluteUri.setDomain(relativeUri.getDomain());\n } else {\n overridden = relativeUri.hasPort();\n }\n\n var path = relativeUri.getPath();\n if (overridden) {\n absoluteUri.setPort(relativeUri.getPort());\n } else {\n overridden = relativeUri.hasPath();\n if (overridden) {\n // resolve path properly\n if (path.charAt(0) != '/') {\n // path is relative\n if (this.hasDomain() && !this.hasPath()) {\n // RFC 3986, section 5.2.3, case 1\n path = '/' + path;\n } else {\n // RFC 3986, section 5.2.3, case 2\n var lastSlashIndex = absoluteUri.getPath().lastIndexOf('/');\n if (lastSlashIndex != -1) {\n path = absoluteUri.getPath().slice(0, lastSlashIndex + 1) + path;\n }\n }\n }\n path = goog.Uri.removeDotSegments(path);\n }\n }\n\n if (overridden) {\n absoluteUri.setPath(path);\n } else {\n overridden = relativeUri.hasQuery();\n }\n\n if (overridden) {\n absoluteUri.setQueryData(relativeUri.getQueryData().clone());\n } else {\n overridden = relativeUri.hasFragment();\n }\n\n if (overridden) {\n absoluteUri.setFragment(relativeUri.getFragment());\n }\n\n return absoluteUri;\n};\n\n\n/**\n * Clones the URI instance.\n * @return {!goog.Uri} New instance of the URI object.\n */\ngoog.Uri.prototype.clone = function() {\n 'use strict';\n return new goog.Uri(this);\n};\n\n\n/**\n * @return {string} The encoded scheme/protocol for the URI.\n */\ngoog.Uri.prototype.getScheme = function() {\n 'use strict';\n return this.scheme_;\n};\n\n\n/**\n * Sets the scheme/protocol.\n * @throws URIError If opt_decode is true and newScheme is malformed (that is,\n * if decodeURIComponent fails).\n * @param {string} newScheme New scheme value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setScheme = function(newScheme, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n this.scheme_ =\n opt_decode ? goog.Uri.decodeOrEmpty_(newScheme, true) : newScheme;\n\n // remove an : at the end of the scheme so somebody can pass in\n // window.location.protocol\n if (this.scheme_) {\n this.scheme_ = this.scheme_.replace(/:$/, '');\n }\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the scheme has been set.\n */\ngoog.Uri.prototype.hasScheme = function() {\n 'use strict';\n return !!this.scheme_;\n};\n\n\n/**\n * @return {string} The decoded user info.\n */\ngoog.Uri.prototype.getUserInfo = function() {\n 'use strict';\n return this.userInfo_;\n};\n\n\n/**\n * Sets the userInfo.\n * @throws URIError If opt_decode is true and newUserInfo is malformed (that is,\n * if decodeURIComponent fails).\n * @param {string} newUserInfo New userInfo value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setUserInfo = function(newUserInfo, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n this.userInfo_ =\n opt_decode ? goog.Uri.decodeOrEmpty_(newUserInfo) : newUserInfo;\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the user info has been set.\n */\ngoog.Uri.prototype.hasUserInfo = function() {\n 'use strict';\n return !!this.userInfo_;\n};\n\n\n/**\n * @return {string} The decoded domain.\n */\ngoog.Uri.prototype.getDomain = function() {\n 'use strict';\n return this.domain_;\n};\n\n\n/**\n * Sets the domain.\n * @throws URIError If opt_decode is true and newDomain is malformed (that is,\n * if decodeURIComponent fails).\n * @param {string} newDomain New domain value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setDomain = function(newDomain, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n this.domain_ =\n opt_decode ? goog.Uri.decodeOrEmpty_(newDomain, true) : newDomain;\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the domain has been set.\n */\ngoog.Uri.prototype.hasDomain = function() {\n 'use strict';\n return !!this.domain_;\n};\n\n\n/**\n * @return {?number} The port number.\n */\ngoog.Uri.prototype.getPort = function() {\n 'use strict';\n return this.port_;\n};\n\n\n/**\n * Sets the port number.\n * @param {*} newPort Port number. Will be explicitly casted to a number.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setPort = function(newPort) {\n 'use strict';\n this.enforceReadOnly();\n\n if (newPort) {\n newPort = Number(newPort);\n if (isNaN(newPort) || newPort < 0) {\n throw new Error('Bad port number ' + newPort);\n }\n this.port_ = newPort;\n } else {\n this.port_ = null;\n }\n\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the port has been set.\n */\ngoog.Uri.prototype.hasPort = function() {\n 'use strict';\n return this.port_ != null;\n};\n\n\n/**\n * @return {string} The decoded path.\n */\ngoog.Uri.prototype.getPath = function() {\n 'use strict';\n return this.path_;\n};\n\n\n/**\n * Sets the path.\n * @throws URIError If opt_decode is true and newPath is malformed (that is,\n * if decodeURIComponent fails).\n * @param {string} newPath New path value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setPath = function(newPath, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n this.path_ = opt_decode ? goog.Uri.decodeOrEmpty_(newPath, true) : newPath;\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the path has been set.\n */\ngoog.Uri.prototype.hasPath = function() {\n 'use strict';\n return !!this.path_;\n};\n\n\n/**\n * @return {boolean} Whether the query string has been set.\n */\ngoog.Uri.prototype.hasQuery = function() {\n 'use strict';\n return this.queryData_.toString() !== '';\n};\n\n\n/**\n * Sets the query data.\n * @param {goog.Uri.QueryData|string|undefined} queryData QueryData object.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * Applies only if queryData is a string.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setQueryData = function(queryData, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n\n if (queryData instanceof goog.Uri.QueryData) {\n this.queryData_ = queryData;\n this.queryData_.setIgnoreCase(this.ignoreCase_);\n } else {\n if (!opt_decode) {\n // QueryData accepts encoded query string, so encode it if\n // opt_decode flag is not true.\n queryData = goog.Uri.encodeSpecialChars_(\n queryData, goog.Uri.reDisallowedInQuery_);\n }\n this.queryData_ = new goog.Uri.QueryData(queryData, this.ignoreCase_);\n }\n\n return this;\n};\n\n\n/**\n * Sets the URI query.\n * @param {string} newQuery New query value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setQuery = function(newQuery, opt_decode) {\n 'use strict';\n return this.setQueryData(newQuery, opt_decode);\n};\n\n\n/**\n * @return {string} The encoded URI query, not including the ?.\n */\ngoog.Uri.prototype.getEncodedQuery = function() {\n 'use strict';\n return this.queryData_.toString();\n};\n\n\n/**\n * @return {string} The decoded URI query, not including the ?.\n */\ngoog.Uri.prototype.getDecodedQuery = function() {\n 'use strict';\n return this.queryData_.toDecodedString();\n};\n\n\n/**\n * Returns the query data.\n * @return {!goog.Uri.QueryData} QueryData object.\n */\ngoog.Uri.prototype.getQueryData = function() {\n 'use strict';\n return this.queryData_;\n};\n\n\n/**\n * @return {string} The encoded URI query, not including the ?.\n *\n * Warning: This method, unlike other getter methods, returns encoded\n * value, instead of decoded one.\n */\ngoog.Uri.prototype.getQuery = function() {\n 'use strict';\n return this.getEncodedQuery();\n};\n\n\n/**\n * Sets the value of the named query parameters, clearing previous values for\n * that key.\n *\n * @param {string} key The parameter to set.\n * @param {*} value The new value. Value does not need to be encoded.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setParameterValue = function(key, value) {\n 'use strict';\n this.enforceReadOnly();\n this.queryData_.set(key, value);\n return this;\n};\n\n\n/**\n * Sets the values of the named query parameters, clearing previous values for\n * that key. Not new values will currently be moved to the end of the query\n * string.\n *\n * So, <code>goog.Uri.parse('foo?a=b&c=d&e=f').setParameterValues('c', ['new'])\n * </code> yields <tt>foo?a=b&e=f&c=new</tt>.</p>\n *\n * @param {string} key The parameter to set.\n * @param {*} values The new values. If values is a single\n * string then it will be treated as the sole value. Values do not need to\n * be encoded.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setParameterValues = function(key, values) {\n 'use strict';\n this.enforceReadOnly();\n\n if (!Array.isArray(values)) {\n values = [String(values)];\n }\n\n this.queryData_.setValues(key, values);\n\n return this;\n};\n\n\n/**\n * Returns the value<b>s</b> for a given cgi parameter as a list of decoded\n * query parameter values.\n * @param {string} name The parameter to get values for.\n * @return {!Array<?>} The values for a given cgi parameter as a list of\n * decoded query parameter values.\n */\ngoog.Uri.prototype.getParameterValues = function(name) {\n 'use strict';\n return this.queryData_.getValues(name);\n};\n\n\n/**\n * Returns the first value for a given cgi parameter or undefined if the given\n * parameter name does not appear in the query string.\n * @param {string} paramName Unescaped parameter name.\n * @return {string|undefined} The first value for a given cgi parameter or\n * undefined if the given parameter name does not appear in the query\n * string.\n */\ngoog.Uri.prototype.getParameterValue = function(paramName) {\n 'use strict';\n return /** @type {string|undefined} */ (this.queryData_.get(paramName));\n};\n\n\n/**\n * @return {string} The URI fragment, not including the #.\n */\ngoog.Uri.prototype.getFragment = function() {\n 'use strict';\n return this.fragment_;\n};\n\n\n/**\n * Sets the URI fragment.\n * @throws URIError If opt_decode is true and newFragment is malformed (that is,\n * if decodeURIComponent fails).\n * @param {string} newFragment New fragment value.\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.setFragment = function(newFragment, opt_decode) {\n 'use strict';\n this.enforceReadOnly();\n this.fragment_ =\n opt_decode ? goog.Uri.decodeOrEmpty_(newFragment) : newFragment;\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the URI has a fragment set.\n */\ngoog.Uri.prototype.hasFragment = function() {\n 'use strict';\n return !!this.fragment_;\n};\n\n\n/**\n * Returns true if this has the same domain as that of uri2.\n * @param {!goog.Uri} uri2 The URI object to compare to.\n * @return {boolean} true if same domain; false otherwise.\n */\ngoog.Uri.prototype.hasSameDomainAs = function(uri2) {\n 'use strict';\n return ((!this.hasDomain() && !uri2.hasDomain()) ||\n this.getDomain() == uri2.getDomain()) &&\n ((!this.hasPort() && !uri2.hasPort()) ||\n this.getPort() == uri2.getPort());\n};\n\n\n/**\n * Adds a random parameter to the Uri.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.makeUnique = function() {\n 'use strict';\n this.enforceReadOnly();\n this.setParameterValue(goog.Uri.RANDOM_PARAM, goog.string.getRandomString());\n\n return this;\n};\n\n\n/**\n * Removes the named query parameter.\n *\n * @param {string} key The parameter to remove.\n * @return {!goog.Uri} Reference to this URI object.\n */\ngoog.Uri.prototype.removeParameter = function(key) {\n 'use strict';\n this.enforceReadOnly();\n this.queryData_.remove(key);\n return this;\n};\n\n\n/**\n * Sets whether Uri is read only. If this goog.Uri is read-only,\n * enforceReadOnly_ will be called at the start of any function that may modify\n * this Uri.\n * @param {boolean} isReadOnly whether this goog.Uri should be read only.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.setReadOnly = function(isReadOnly) {\n 'use strict';\n this.isReadOnly_ = isReadOnly;\n return this;\n};\n\n\n/**\n * @return {boolean} Whether the URI is read only.\n */\ngoog.Uri.prototype.isReadOnly = function() {\n 'use strict';\n return this.isReadOnly_;\n};\n\n\n/**\n * Checks if this Uri has been marked as read only, and if so, throws an error.\n * This should be called whenever any modifying function is called.\n */\ngoog.Uri.prototype.enforceReadOnly = function() {\n 'use strict';\n if (this.isReadOnly_) {\n throw new Error('Tried to modify a read-only Uri');\n }\n};\n\n\n/**\n * Sets whether to ignore case.\n * NOTE: If there are already key/value pairs in the QueryData, and\n * ignoreCase_ is set to false, the keys will all be lower-cased.\n * @param {boolean} ignoreCase whether this goog.Uri should ignore case.\n * @return {!goog.Uri} Reference to this Uri object.\n */\ngoog.Uri.prototype.setIgnoreCase = function(ignoreCase) {\n 'use strict';\n this.ignoreCase_ = ignoreCase;\n if (this.queryData_) {\n this.queryData_.setIgnoreCase(ignoreCase);\n }\n return this;\n};\n\n\n/**\n * @return {boolean} Whether to ignore case.\n */\ngoog.Uri.prototype.getIgnoreCase = function() {\n 'use strict';\n return this.ignoreCase_;\n};\n\n\n//==============================================================================\n// Static members\n//==============================================================================\n\n\n/**\n * Creates a uri from the string form. Basically an alias of new goog.Uri().\n * If a Uri object is passed to parse then it will return a clone of the object.\n *\n * @throws URIError If parsing the URI is malformed. The passed URI components\n * should all be parseable by decodeURIComponent.\n * @param {*} uri Raw URI string or instance of Uri\n * object.\n * @param {boolean=} opt_ignoreCase Whether to ignore the case of parameter\n * names in #getParameterValue.\n * @return {!goog.Uri} The new URI object.\n */\ngoog.Uri.parse = function(uri, opt_ignoreCase) {\n 'use strict';\n return uri instanceof goog.Uri ? uri.clone() :\n new goog.Uri(uri, opt_ignoreCase);\n};\n\n\n/**\n * Creates a new goog.Uri object from unencoded parts.\n *\n * @param {?string=} opt_scheme Scheme/protocol or full URI to parse.\n * @param {?string=} opt_userInfo username:password.\n * @param {?string=} opt_domain www.google.com.\n * @param {?number=} opt_port 9830.\n * @param {?string=} opt_path /some/path/to/a/file.html.\n * @param {string|goog.Uri.QueryData=} opt_query a=1&b=2.\n * @param {?string=} opt_fragment The fragment without the #.\n * @param {boolean=} opt_ignoreCase Whether to ignore parameter name case in\n * #getParameterValue.\n *\n * @return {!goog.Uri} The new URI object.\n */\ngoog.Uri.create = function(\n opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_query,\n opt_fragment, opt_ignoreCase) {\n 'use strict';\n var uri = new goog.Uri(null, opt_ignoreCase);\n\n // Only set the parts if they are defined and not empty strings.\n opt_scheme && uri.setScheme(opt_scheme);\n opt_userInfo && uri.setUserInfo(opt_userInfo);\n opt_domain && uri.setDomain(opt_domain);\n opt_port && uri.setPort(opt_port);\n opt_path && uri.setPath(opt_path);\n opt_query && uri.setQueryData(opt_query);\n opt_fragment && uri.setFragment(opt_fragment);\n\n return uri;\n};\n\n\n/**\n * Resolves a relative Uri against a base Uri, accepting both strings and\n * Uri objects.\n *\n * @param {*} base Base Uri.\n * @param {*} rel Relative Uri.\n * @return {!goog.Uri} Resolved uri.\n */\ngoog.Uri.resolve = function(base, rel) {\n 'use strict';\n if (!(base instanceof goog.Uri)) {\n base = goog.Uri.parse(base);\n }\n\n if (!(rel instanceof goog.Uri)) {\n rel = goog.Uri.parse(rel);\n }\n\n return base.resolve(rel);\n};\n\n\n/**\n * Removes dot segments in given path component, as described in\n * RFC 3986, section 5.2.4.\n *\n * @param {string} path A non-empty path component.\n * @return {string} Path component with removed dot segments.\n */\ngoog.Uri.removeDotSegments = function(path) {\n 'use strict';\n if (path == '..' || path == '.') {\n return '';\n\n } else if (\n !goog.string.contains(path, './') && !goog.string.contains(path, '/.')) {\n // This optimization detects uris which do not contain dot-segments,\n // and as a consequence do not require any processing.\n return path;\n\n } else {\n var leadingSlash = goog.string.startsWith(path, '/');\n var segments = path.split('/');\n var out = [];\n\n for (var pos = 0; pos < segments.length;) {\n var segment = segments[pos++];\n\n if (segment == '.') {\n if (leadingSlash && pos == segments.length) {\n out.push('');\n }\n } else if (segment == '..') {\n if (out.length > 1 || out.length == 1 && out[0] != '') {\n out.pop();\n }\n if (leadingSlash && pos == segments.length) {\n out.push('');\n }\n } else {\n out.push(segment);\n leadingSlash = true;\n }\n }\n\n return out.join('/');\n }\n};\n\n\n/**\n * Decodes a value or returns the empty string if it isn't defined or empty.\n * @throws URIError If decodeURIComponent fails to decode val.\n * @param {string|undefined} val Value to decode.\n * @param {boolean=} opt_preserveReserved If true, restricted characters will\n * not be decoded.\n * @return {string} Decoded value.\n * @private\n */\ngoog.Uri.decodeOrEmpty_ = function(val, opt_preserveReserved) {\n 'use strict';\n // Don't use UrlDecode() here because val is not a query parameter.\n if (!val) {\n return '';\n }\n\n // decodeURI has the same output for '%2f' and '%252f'. We double encode %25\n // so that we can distinguish between the 2 inputs. This is later undone by\n // removeDoubleEncoding_.\n return opt_preserveReserved ? decodeURI(val.replace(/%25/g, '%2525')) :\n decodeURIComponent(val);\n};\n\n\n/**\n * If unescapedPart is non null, then escapes any characters in it that aren't\n * valid characters in a url and also escapes any special characters that\n * appear in extra.\n *\n * @param {*} unescapedPart The string to encode.\n * @param {RegExp} extra A character set of characters in [\\01-\\177].\n * @param {boolean=} opt_removeDoubleEncoding If true, remove double percent\n * encoding.\n * @return {?string} null iff unescapedPart == null.\n * @private\n */\ngoog.Uri.encodeSpecialChars_ = function(\n unescapedPart, extra, opt_removeDoubleEncoding) {\n 'use strict';\n if (typeof unescapedPart === 'string') {\n var encoded = encodeURI(unescapedPart).replace(extra, goog.Uri.encodeChar_);\n if (opt_removeDoubleEncoding) {\n // encodeURI double-escapes %XX sequences used to represent restricted\n // characters in some URI components, remove the double escaping here.\n encoded = goog.Uri.removeDoubleEncoding_(encoded);\n }\n return encoded;\n }\n return null;\n};\n\n\n/**\n * Converts a character in [\\01-\\177] to its unicode character equivalent.\n * @param {string} ch One character string.\n * @return {string} Encoded string.\n * @private\n */\ngoog.Uri.encodeChar_ = function(ch) {\n 'use strict';\n var n = ch.charCodeAt(0);\n return '%' + ((n >> 4) & 0xf).toString(16) + (n & 0xf).toString(16);\n};\n\n\n/**\n * Removes double percent-encoding from a string.\n * @param {string} doubleEncodedString String\n * @return {string} String with double encoding removed.\n * @private\n */\ngoog.Uri.removeDoubleEncoding_ = function(doubleEncodedString) {\n 'use strict';\n return doubleEncodedString.replace(/%25([0-9a-fA-F]{2})/g, '%$1');\n};\n\n\n/**\n * Regular expression for characters that are disallowed in the scheme or\n * userInfo part of the URI.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInSchemeOrUserInfo_ = /[#\\/\\?@]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in a relative path.\n * Colon is included due to RFC 3986 3.3.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInRelativePath_ = /[\\#\\?:]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in an absolute path.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInAbsolutePath_ = /[\\#\\?]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in the query.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInQuery_ = /[\\#\\?@]/g;\n\n\n/**\n * Regular expression for characters that are disallowed in the fragment.\n * @type {RegExp}\n * @private\n */\ngoog.Uri.reDisallowedInFragment_ = /#/g;\n\n\n/**\n * Checks whether two URIs have the same domain.\n * @param {string} uri1String First URI string.\n * @param {string} uri2String Second URI string.\n * @return {boolean} true if the two URIs have the same domain; false otherwise.\n */\ngoog.Uri.haveSameDomain = function(uri1String, uri2String) {\n 'use strict';\n // Differs from goog.uri.utils.haveSameDomain, since this ignores scheme.\n // TODO(gboyer): Have this just call goog.uri.util.haveSameDomain.\n var pieces1 = goog.uri.utils.split(uri1String);\n var pieces2 = goog.uri.utils.split(uri2String);\n return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==\n pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&\n pieces1[goog.uri.utils.ComponentIndex.PORT] ==\n pieces2[goog.uri.utils.ComponentIndex.PORT];\n};\n\n\n\n/**\n * Class used to represent URI query parameters. It is essentially a hash of\n * name-value pairs, though a name can be present more than once.\n *\n * Has the same interface as the collections in goog.structs.\n *\n * @param {?string=} opt_query Optional encoded query string to parse into\n * the object.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n * name in #get.\n * @constructor\n * @struct\n * @final\n */\ngoog.Uri.QueryData = function(opt_query, opt_ignoreCase) {\n 'use strict';\n /**\n * The map containing name/value or name/array-of-values pairs.\n * May be null if it requires parsing from the query string.\n *\n * We need to use a Map because we cannot guarantee that the key names will\n * not be problematic for IE.\n *\n * @private {?Map<string, !Array<*>>}\n */\n this.keyMap_ = null;\n\n /**\n * The number of params, or null if it requires computing.\n * @private {?number}\n */\n this.count_ = null;\n\n /**\n * Encoded query string, or null if it requires computing from the key map.\n * @private {?string}\n */\n this.encodedQuery_ = opt_query || null;\n\n /**\n * If true, ignore the case of the parameter name in #get.\n * @private {boolean}\n */\n this.ignoreCase_ = !!opt_ignoreCase;\n};\n\n\n/**\n * If the underlying key map is not yet initialized, it parses the\n * query string and fills the map with parsed data.\n * @private\n */\ngoog.Uri.QueryData.prototype.ensureKeyMapInitialized_ = function() {\n 'use strict';\n if (!this.keyMap_) {\n this.keyMap_ = /** @type {!Map<string, !Array<*>>} */ (new Map());\n this.count_ = 0;\n if (this.encodedQuery_) {\n var self = this;\n goog.uri.utils.parseQueryData(this.encodedQuery_, function(name, value) {\n 'use strict';\n self.add(goog.string.urlDecode(name), value);\n });\n }\n }\n};\n\n\n/**\n * Creates a new query data instance from a map of names and values.\n *\n * @param {!goog.collections.maps.MapLike<string, ?>|!Object} map Map of string\n * parameter names to parameter value. If parameter value is an array, it is\n * treated as if the key maps to each individual value in the\n * array.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n * name in #get.\n * @return {!goog.Uri.QueryData} The populated query data instance.\n */\ngoog.Uri.QueryData.createFromMap = function(map, opt_ignoreCase) {\n 'use strict';\n var keys = goog.structs.getKeys(map);\n if (typeof keys == 'undefined') {\n throw new Error('Keys are undefined');\n }\n\n var queryData = new goog.Uri.QueryData(null, opt_ignoreCase);\n var values = goog.structs.getValues(map);\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = values[i];\n if (!Array.isArray(value)) {\n queryData.add(key, value);\n } else {\n queryData.setValues(key, value);\n }\n }\n return queryData;\n};\n\n\n/**\n * Creates a new query data instance from parallel arrays of parameter names\n * and values. Allows for duplicate parameter names. Throws an error if the\n * lengths of the arrays differ.\n *\n * @param {!Array<string>} keys Parameter names.\n * @param {!Array<?>} values Parameter values.\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\n * name in #get.\n * @return {!goog.Uri.QueryData} The populated query data instance.\n */\ngoog.Uri.QueryData.createFromKeysValues = function(\n keys, values, opt_ignoreCase) {\n 'use strict';\n if (keys.length != values.length) {\n throw new Error('Mismatched lengths for keys/values');\n }\n var queryData = new goog.Uri.QueryData(null, opt_ignoreCase);\n for (var i = 0; i < keys.length; i++) {\n queryData.add(keys[i], values[i]);\n }\n return queryData;\n};\n\n\n/**\n * @return {?number} The number of parameters.\n */\ngoog.Uri.QueryData.prototype.getCount = function() {\n 'use strict';\n this.ensureKeyMapInitialized_();\n return this.count_;\n};\n\n\n/**\n * Adds a key value pair.\n * @param {string} key Name.\n * @param {*} value Value.\n * @return {!goog.Uri.QueryData} Instance of this object.\n */\ngoog.Uri.QueryData.prototype.add = function(key, value) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n this.invalidateCache_();\n\n key = this.getKeyName_(key);\n var values = this.keyMap_.get(key);\n if (!values) {\n this.keyMap_.set(key, (values = []));\n }\n values.push(value);\n this.count_ = goog.asserts.assertNumber(this.count_) + 1;\n return this;\n};\n\n\n/**\n * Removes all the params with the given key.\n * @param {string} key Name.\n * @return {boolean} Whether any parameter was removed.\n */\ngoog.Uri.QueryData.prototype.remove = function(key) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n\n key = this.getKeyName_(key);\n if (this.keyMap_.has(key)) {\n this.invalidateCache_();\n\n // Decrement parameter count.\n this.count_ =\n goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\n return this.keyMap_.delete(key);\n }\n return false;\n};\n\n\n/**\n * Clears the parameters.\n */\ngoog.Uri.QueryData.prototype.clear = function() {\n 'use strict';\n this.invalidateCache_();\n this.keyMap_ = null;\n this.count_ = 0;\n};\n\n\n/**\n * @return {boolean} Whether we have any parameters.\n */\ngoog.Uri.QueryData.prototype.isEmpty = function() {\n 'use strict';\n this.ensureKeyMapInitialized_();\n return this.count_ == 0;\n};\n\n\n/**\n * Whether there is a parameter with the given name\n * @param {string} key The parameter name to check for.\n * @return {boolean} Whether there is a parameter with the given name.\n */\ngoog.Uri.QueryData.prototype.containsKey = function(key) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n key = this.getKeyName_(key);\n return this.keyMap_.has(key);\n};\n\n\n/**\n * Whether there is a parameter with the given value.\n * @param {*} value The value to check for.\n * @return {boolean} Whether there is a parameter with the given value.\n */\ngoog.Uri.QueryData.prototype.containsValue = function(value) {\n 'use strict';\n // NOTE(arv): This solution goes through all the params even if it was the\n // first param. We can get around this by not reusing code or by switching to\n // iterators.\n var vals = this.getValues();\n return goog.array.contains(vals, value);\n};\n\n\n/**\n * Runs a callback on every key-value pair in the map, including duplicate keys.\n * This won't maintain original order when duplicate keys are interspersed (like\n * getKeys() / getValues()).\n * @param {function(this:SCOPE, ?, string, !goog.Uri.QueryData)} f\n * @param {SCOPE=} opt_scope The value of \"this\" inside f.\n * @template SCOPE\n */\ngoog.Uri.QueryData.prototype.forEach = function(f, opt_scope) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n this.keyMap_.forEach(function(values, key) {\n 'use strict';\n values.forEach(function(value) {\n 'use strict';\n f.call(opt_scope, value, key, this);\n }, this);\n }, this);\n};\n\n\n/**\n * Returns all the keys of the parameters. If a key is used multiple times\n * it will be included multiple times in the returned array\n * @return {!Array<string>} All the keys of the parameters.\n */\ngoog.Uri.QueryData.prototype.getKeys = function() {\n 'use strict';\n this.ensureKeyMapInitialized_();\n // We need to get the values to know how many keys to add.\n const vals = Array.from(this.keyMap_.values());\n const keys = Array.from(this.keyMap_.keys());\n const rv = [];\n for (let i = 0; i < keys.length; i++) {\n const val = vals[i];\n for (let j = 0; j < val.length; j++) {\n rv.push(keys[i]);\n }\n }\n return rv;\n};\n\n\n/**\n * Returns all the values of the parameters with the given name. If the query\n * data has no such key this will return an empty array. If no key is given\n * all values wil be returned.\n * @param {string=} opt_key The name of the parameter to get the values for.\n * @return {!Array<?>} All the values of the parameters with the given name.\n */\ngoog.Uri.QueryData.prototype.getValues = function(opt_key) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n let rv = [];\n if (typeof opt_key === 'string') {\n if (this.containsKey(opt_key)) {\n rv = rv.concat(this.keyMap_.get(this.getKeyName_(opt_key)));\n }\n } else {\n // Return all values.\n const values = Array.from(this.keyMap_.values());\n for (let i = 0; i < values.length; i++) {\n rv = rv.concat(values[i]);\n }\n }\n return rv;\n};\n\n\n/**\n * Sets a key value pair and removes all other keys with the same value.\n *\n * @param {string} key Name.\n * @param {*} value Value.\n * @return {!goog.Uri.QueryData} Instance of this object.\n */\ngoog.Uri.QueryData.prototype.set = function(key, value) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n this.invalidateCache_();\n\n // TODO(chrishenry): This could be better written as\n // this.remove(key), this.add(key, value), but that would reorder\n // the key (since the key is first removed and then added at the\n // end) and we would have to fix unit tests that depend on key\n // ordering.\n key = this.getKeyName_(key);\n if (this.containsKey(key)) {\n this.count_ =\n goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\n }\n this.keyMap_.set(key, [value]);\n this.count_ = goog.asserts.assertNumber(this.count_) + 1;\n return this;\n};\n\n\n/**\n * Returns the first value associated with the key. If the query data has no\n * such key this will return undefined or the optional default.\n * @param {string} key The name of the parameter to get the value for.\n * @param {*=} opt_default The default value to return if the query data\n * has no such key.\n * @return {*} The first string value associated with the key, or opt_default\n * if there's no value.\n */\ngoog.Uri.QueryData.prototype.get = function(key, opt_default) {\n 'use strict';\n if (!key) {\n return opt_default;\n }\n var values = this.getValues(key);\n return values.length > 0 ? String(values[0]) : opt_default;\n};\n\n\n/**\n * Sets the values for a key. If the key already exists, this will\n * override all of the existing values that correspond to the key.\n * @param {string} key The key to set values for.\n * @param {!Array<?>} values The values to set.\n */\ngoog.Uri.QueryData.prototype.setValues = function(key, values) {\n 'use strict';\n this.remove(key);\n\n if (values.length > 0) {\n this.invalidateCache_();\n this.keyMap_.set(this.getKeyName_(key), goog.array.clone(values));\n this.count_ = goog.asserts.assertNumber(this.count_) + values.length;\n }\n};\n\n\n/**\n * @return {string} Encoded query string.\n * @override\n */\ngoog.Uri.QueryData.prototype.toString = function() {\n 'use strict';\n if (this.encodedQuery_) {\n return this.encodedQuery_;\n }\n\n if (!this.keyMap_) {\n return '';\n }\n\n const sb = [];\n\n // In the past, we use this.getKeys() and this.getVals(), but that\n // generates a lot of allocations as compared to simply iterating\n // over the keys.\n const keys = Array.from(this.keyMap_.keys());\n for (var i = 0; i < keys.length; i++) {\n const key = keys[i];\n const encodedKey = goog.string.urlEncode(key);\n const val = this.getValues(key);\n for (var j = 0; j < val.length; j++) {\n var param = encodedKey;\n // Ensure that null and undefined are encoded into the url as\n // literal strings.\n if (val[j] !== '') {\n param += '=' + goog.string.urlEncode(val[j]);\n }\n sb.push(param);\n }\n }\n\n return this.encodedQuery_ = sb.join('&');\n};\n\n\n/**\n * @throws URIError If URI is malformed (that is, if decodeURIComponent fails on\n * any of the URI components).\n * @return {string} Decoded query string.\n */\ngoog.Uri.QueryData.prototype.toDecodedString = function() {\n 'use strict';\n return goog.Uri.decodeOrEmpty_(this.toString());\n};\n\n\n/**\n * Invalidate the cache.\n * @private\n */\ngoog.Uri.QueryData.prototype.invalidateCache_ = function() {\n 'use strict';\n this.encodedQuery_ = null;\n};\n\n\n/**\n * Removes all keys that are not in the provided list. (Modifies this object.)\n * @param {Array<string>} keys The desired keys.\n * @return {!goog.Uri.QueryData} a reference to this object.\n */\ngoog.Uri.QueryData.prototype.filterKeys = function(keys) {\n 'use strict';\n this.ensureKeyMapInitialized_();\n this.keyMap_.forEach(function(value, key) {\n 'use strict';\n if (!goog.array.contains(keys, key)) {\n this.remove(key);\n }\n }, this);\n return this;\n};\n\n\n/**\n * Clone the query data instance.\n * @return {!goog.Uri.QueryData} New instance of the QueryData object.\n */\ngoog.Uri.QueryData.prototype.clone = function() {\n 'use strict';\n var rv = new goog.Uri.QueryData();\n rv.encodedQuery_ = this.encodedQuery_;\n if (this.keyMap_) {\n rv.keyMap_ = /** @type {!Map<string, !Array<*>>} */ (new Map(this.keyMap_));\n rv.count_ = this.count_;\n }\n return rv;\n};\n\n\n/**\n * Helper function to get the key name from a JavaScript object. Converts\n * the object to a string, and to lower case if necessary.\n * @private\n * @param {*} arg The object to get a key name from.\n * @return {string} valid key name which can be looked up in #keyMap_.\n */\ngoog.Uri.QueryData.prototype.getKeyName_ = function(arg) {\n 'use strict';\n var keyName = String(arg);\n if (this.ignoreCase_) {\n keyName = keyName.toLowerCase();\n }\n return keyName;\n};\n\n\n/**\n * Ignore case in parameter names.\n * NOTE: If there are already key/value pairs in the QueryData, and\n * ignoreCase_ is set to false, the keys will all be lower-cased.\n * @param {boolean} ignoreCase whether this goog.Uri should ignore case.\n */\ngoog.Uri.QueryData.prototype.setIgnoreCase = function(ignoreCase) {\n 'use strict';\n var resetKeys = ignoreCase && !this.ignoreCase_;\n if (resetKeys) {\n this.ensureKeyMapInitialized_();\n this.invalidateCache_();\n this.keyMap_.forEach(function(value, key) {\n 'use strict';\n var lowerCase = key.toLowerCase();\n if (key != lowerCase) {\n this.remove(key);\n this.setValues(lowerCase, value);\n }\n }, this);\n }\n this.ignoreCase_ = ignoreCase;\n};\n\n\n/**\n * Extends a query data object with another query data or map like object. This\n * operates 'in-place', it does not create a new QueryData object.\n *\n * @param {...(?goog.Uri.QueryData|?goog.collections.maps.MapLike<?,\n * ?>|?Object)} var_args The object from which key value pairs will be\n * copied. Note: does not accept null.\n * @suppress {deprecated} Use deprecated goog.structs.forEach to allow different\n * types of parameters.\n */\ngoog.Uri.QueryData.prototype.extend = function(var_args) {\n 'use strict';\n for (var i = 0; i < arguments.length; i++) {\n var data = arguments[i];\n goog.structs.forEach(data, function(value, key) {\n 'use strict';\n this.add(key, value);\n }, this);\n }\n};\n","~:compiled-at",1684858197948,"~:source-map-json","{\n\"version\":3,\n\"file\":\"goog.uri.uri.js\",\n\"lineCount\":614,\n\"mappings\":\"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\",\n\"sources\":[\"goog/uri/uri.js\"],\n\"sourcesContent\":[\"/**\\n * @license\\n * Copyright The Closure Library Authors.\\n * SPDX-License-Identifier: Apache-2.0\\n */\\n\\n/**\\n * @fileoverview Class for parsing and formatting URIs.\\n *\\n * This package is deprecated in favour of the Closure URL package (goog.url)\\n * when manipulating URIs for use by a browser. This package uses regular\\n * expressions to parse a potential URI which can fall out of sync with how a\\n * browser will actually interpret the URI. See\\n * `goog.uri.utils.setUrlPackageSupportLoggingHandler` for one way to identify\\n * URIs that should instead be parsed using the URL package.\\n *\\n * Use goog.Uri(string) to parse a URI string. Use goog.Uri.create(...) to\\n * create a new instance of the goog.Uri object from Uri parts.\\n *\\n * e.g: <code>var myUri = new goog.Uri(window.location);</code>\\n *\\n * Implements RFC 3986 for parsing/formatting URIs.\\n * http://www.ietf.org/rfc/rfc3986.txt\\n *\\n * Some changes have been made to the interface (more like .NETs), though the\\n * internal representation is now of un-encoded parts, this will change the\\n * behavior slightly.\\n */\\n\\ngoog.provide('goog.Uri');\\ngoog.provide('goog.Uri.QueryData');\\n\\ngoog.require('goog.array');\\ngoog.require('goog.asserts');\\ngoog.require('goog.collections.maps');\\ngoog.require('goog.string');\\ngoog.require('goog.structs');\\ngoog.require('goog.uri.utils');\\ngoog.require('goog.uri.utils.ComponentIndex');\\ngoog.require('goog.uri.utils.StandardQueryParam');\\n\\n\\n\\n/**\\n * This class contains setters and getters for the parts of the URI.\\n * The <code>getXyz</code>/<code>setXyz</code> methods return the decoded part\\n * -- so<code>goog.Uri.parse('/foo%20bar').getPath()</code> will return the\\n * decoded path, <code>/foo bar</code>.\\n *\\n * Reserved characters (see RFC 3986 section 2.2) can be present in\\n * their percent-encoded form in scheme, domain, and path URI components and\\n * will not be auto-decoded. For example:\\n * <code>goog.Uri.parse('rel%61tive/path%2fto/resource').getPath()</code> will\\n * return <code>relative/path%2fto/resource</code>.\\n *\\n * The constructor accepts an optional unparsed, raw URI string. The parser\\n * is relaxed, so special characters that aren't escaped but don't cause\\n * ambiguities will not cause parse failures.\\n *\\n * All setters return <code>this</code> and so may be chained, a la\\n * <code>goog.Uri.parse('/foo').setFragment('part').toString()</code>.\\n *\\n * @param {*=} opt_uri Optional string URI to parse\\n * (use goog.Uri.create() to create a URI from parts), or if\\n * a goog.Uri is passed, a clone is created.\\n * @param {boolean=} opt_ignoreCase If true, #getParameterValue will ignore\\n * the case of the parameter name.\\n *\\n * @throws URIError If opt_uri is provided and URI is malformed (that is,\\n * if decodeURIComponent fails on any of the URI components).\\n * @constructor\\n * @struct\\n */\\ngoog.Uri = function(opt_uri, opt_ignoreCase) {\\n 'use strict';\\n /**\\n * Scheme such as \\\"http\\\".\\n * @private {string}\\n */\\n this.scheme_ = '';\\n\\n /**\\n * User credentials in the form \\\"username:password\\\".\\n * @private {string}\\n */\\n this.userInfo_ = '';\\n\\n /**\\n * Domain part, e.g. \\\"www.google.com\\\".\\n * @private {string}\\n */\\n this.domain_ = '';\\n\\n /**\\n * Port, e.g. 8080.\\n * @private {?number}\\n */\\n this.port_ = null;\\n\\n /**\\n * Path, e.g. \\\"/tests/img.png\\\".\\n * @private {string}\\n */\\n this.path_ = '';\\n\\n /**\\n * The fragment without the #.\\n * @private {string}\\n */\\n this.fragment_ = '';\\n\\n /**\\n * Whether or not this Uri should be treated as Read Only.\\n * @private {boolean}\\n */\\n this.isReadOnly_ = false;\\n\\n /**\\n * Whether or not to ignore case when comparing query params.\\n * @private {boolean}\\n */\\n this.ignoreCase_ = false;\\n\\n /**\\n * Object representing query data.\\n * @private {!goog.Uri.QueryData}\\n */\\n this.queryData_;\\n\\n // Parse in the uri string\\n var m;\\n if (opt_uri instanceof goog.Uri) {\\n this.ignoreCase_ = (opt_ignoreCase !== undefined) ? opt_ignoreCase :\\n opt_uri.getIgnoreCase();\\n this.setScheme(opt_uri.getScheme());\\n this.setUserInfo(opt_uri.getUserInfo());\\n this.setDomain(opt_uri.getDomain());\\n this.setPort(opt_uri.getPort());\\n this.setPath(opt_uri.getPath());\\n this.setQueryData(opt_uri.getQueryData().clone());\\n this.setFragment(opt_uri.getFragment());\\n } else if (opt_uri && (m = goog.uri.utils.split(String(opt_uri)))) {\\n this.ignoreCase_ = !!opt_ignoreCase;\\n\\n // Set the parts -- decoding as we do so.\\n // COMPATIBILITY NOTE - In IE, unmatched fields may be empty strings,\\n // whereas in other browsers they will be undefined.\\n this.setScheme(m[goog.uri.utils.ComponentIndex.SCHEME] || '', true);\\n this.setUserInfo(m[goog.uri.utils.ComponentIndex.USER_INFO] || '', true);\\n this.setDomain(m[goog.uri.utils.ComponentIndex.DOMAIN] || '', true);\\n this.setPort(m[goog.uri.utils.ComponentIndex.PORT]);\\n this.setPath(m[goog.uri.utils.ComponentIndex.PATH] || '', true);\\n this.setQueryData(m[goog.uri.utils.ComponentIndex.QUERY_DATA] || '', true);\\n this.setFragment(m[goog.uri.utils.ComponentIndex.FRAGMENT] || '', true);\\n\\n } else {\\n this.ignoreCase_ = !!opt_ignoreCase;\\n this.queryData_ = new goog.Uri.QueryData(null, this.ignoreCase_);\\n }\\n};\\n\\n\\n/**\\n * Parameter name added to stop caching.\\n * @type {string}\\n */\\ngoog.Uri.RANDOM_PARAM = goog.uri.utils.StandardQueryParam.RANDOM;\\n\\n\\n/**\\n * @return {string} The string form of the url.\\n * @override\\n */\\ngoog.Uri.prototype.toString = function() {\\n 'use strict';\\n var out = [];\\n\\n var scheme = this.getScheme();\\n if (scheme) {\\n out.push(\\n goog.Uri.encodeSpecialChars_(\\n scheme, goog.Uri.reDisallowedInSchemeOrUserInfo_, true),\\n ':');\\n }\\n\\n var domain = this.getDomain();\\n if (domain || scheme == 'file') {\\n out.push('//');\\n\\n var userInfo = this.getUserInfo();\\n if (userInfo) {\\n out.push(\\n goog.Uri.encodeSpecialChars_(\\n userInfo, goog.Uri.reDisallowedInSchemeOrUserInfo_, true),\\n '@');\\n }\\n\\n out.push(goog.Uri.removeDoubleEncoding_(goog.string.urlEncode(domain)));\\n\\n var port = this.getPort();\\n if (port != null) {\\n out.push(':', String(port));\\n }\\n }\\n\\n var path = this.getPath();\\n if (path) {\\n if (this.hasDomain() && path.charAt(0) != '/') {\\n out.push('/');\\n }\\n out.push(goog.Uri.encodeSpecialChars_(\\n path,\\n path.charAt(0) == '/' ? goog.Uri.reDisallowedInAbsolutePath_ :\\n goog.Uri.reDisallowedInRelativePath_,\\n true));\\n }\\n\\n var query = this.getEncodedQuery();\\n if (query) {\\n out.push('?', query);\\n }\\n\\n var fragment = this.getFragment();\\n if (fragment) {\\n out.push(\\n '#',\\n goog.Uri.encodeSpecialChars_(\\n fragment, goog.Uri.reDisallowedInFragment_));\\n }\\n return out.join('');\\n};\\n\\n\\n/**\\n * Resolves the given relative URI (a goog.Uri object), using the URI\\n * represented by this instance as the base URI.\\n *\\n * There are several kinds of relative URIs:<br>\\n * 1. foo - replaces the last part of the path, the whole query and fragment<br>\\n * 2. /foo - replaces the path, the query and fragment<br>\\n * 3. //foo - replaces everything from the domain on. foo is a domain name<br>\\n * 4. ?foo - replace the query and fragment<br>\\n * 5. #foo - replace the fragment only\\n *\\n * Additionally, if relative URI has a non-empty path, all \\\"..\\\" and \\\".\\\"\\n * segments will be resolved, as described in RFC 3986.\\n *\\n * @param {!goog.Uri} relativeUri The relative URI to resolve.\\n * @return {!goog.Uri} The resolved URI.\\n */\\ngoog.Uri.prototype.resolve = function(relativeUri) {\\n 'use strict';\\n var absoluteUri = this.clone();\\n\\n // we satisfy these conditions by looking for the first part of relativeUri\\n // that is not blank and applying defaults to the rest\\n\\n var overridden = relativeUri.hasScheme();\\n\\n if (overridden) {\\n absoluteUri.setScheme(relativeUri.getScheme());\\n } else {\\n overridden = relativeUri.hasUserInfo();\\n }\\n\\n if (overridden) {\\n absoluteUri.setUserInfo(relativeUri.getUserInfo());\\n } else {\\n overridden = relativeUri.hasDomain();\\n }\\n\\n if (overridden) {\\n absoluteUri.setDomain(relativeUri.getDomain());\\n } else {\\n overridden = relativeUri.hasPort();\\n }\\n\\n var path = relativeUri.getPath();\\n if (overridden) {\\n absoluteUri.setPort(relativeUri.getPort());\\n } else {\\n overridden = relativeUri.hasPath();\\n if (overridden) {\\n // resolve path properly\\n if (path.charAt(0) != '/') {\\n // path is relative\\n if (this.hasDomain() && !this.hasPath()) {\\n // RFC 3986, section 5.2.3, case 1\\n path = '/' + path;\\n } else {\\n // RFC 3986, section 5.2.3, case 2\\n var lastSlashIndex = absoluteUri.getPath().lastIndexOf('/');\\n if (lastSlashIndex != -1) {\\n path = absoluteUri.getPath().slice(0, lastSlashIndex + 1) + path;\\n }\\n }\\n }\\n path = goog.Uri.removeDotSegments(path);\\n }\\n }\\n\\n if (overridden) {\\n absoluteUri.setPath(path);\\n } else {\\n overridden = relativeUri.hasQuery();\\n }\\n\\n if (overridden) {\\n absoluteUri.setQueryData(relativeUri.getQueryData().clone());\\n } else {\\n overridden = relativeUri.hasFragment();\\n }\\n\\n if (overridden) {\\n absoluteUri.setFragment(relativeUri.getFragment());\\n }\\n\\n return absoluteUri;\\n};\\n\\n\\n/**\\n * Clones the URI instance.\\n * @return {!goog.Uri} New instance of the URI object.\\n */\\ngoog.Uri.prototype.clone = function() {\\n 'use strict';\\n return new goog.Uri(this);\\n};\\n\\n\\n/**\\n * @return {string} The encoded scheme/protocol for the URI.\\n */\\ngoog.Uri.prototype.getScheme = function() {\\n 'use strict';\\n return this.scheme_;\\n};\\n\\n\\n/**\\n * Sets the scheme/protocol.\\n * @throws URIError If opt_decode is true and newScheme is malformed (that is,\\n * if decodeURIComponent fails).\\n * @param {string} newScheme New scheme value.\\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\\n * @return {!goog.Uri} Reference to this URI object.\\n */\\ngoog.Uri.prototype.setScheme = function(newScheme, opt_decode) {\\n 'use strict';\\n this.enforceReadOnly();\\n this.scheme_ =\\n opt_decode ? goog.Uri.decodeOrEmpty_(newScheme, true) : newScheme;\\n\\n // remove an : at the end of the scheme so somebody can pass in\\n // window.location.protocol\\n if (this.scheme_) {\\n this.scheme_ = this.scheme_.replace(/:$/, '');\\n }\\n return this;\\n};\\n\\n\\n/**\\n * @return {boolean} Whether the scheme has been set.\\n */\\ngoog.Uri.prototype.hasScheme = function() {\\n 'use strict';\\n return !!this.scheme_;\\n};\\n\\n\\n/**\\n * @return {string} The decoded user info.\\n */\\ngoog.Uri.prototype.getUserInfo = function() {\\n 'use strict';\\n return this.userInfo_;\\n};\\n\\n\\n/**\\n * Sets the userInfo.\\n * @throws URIError If opt_decode is true and newUserInfo is malformed (that is,\\n * if decodeURIComponent fails).\\n * @param {string} newUserInfo New userInfo value.\\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\\n * @return {!goog.Uri} Reference to this URI object.\\n */\\ngoog.Uri.prototype.setUserInfo = function(newUserInfo, opt_decode) {\\n 'use strict';\\n this.enforceReadOnly();\\n this.userInfo_ =\\n opt_decode ? goog.Uri.decodeOrEmpty_(newUserInfo) : newUserInfo;\\n return this;\\n};\\n\\n\\n/**\\n * @return {boolean} Whether the user info has been set.\\n */\\ngoog.Uri.prototype.hasUserInfo = function() {\\n 'use strict';\\n return !!this.userInfo_;\\n};\\n\\n\\n/**\\n * @return {string} The decoded domain.\\n */\\ngoog.Uri.prototype.getDomain = function() {\\n 'use strict';\\n return this.domain_;\\n};\\n\\n\\n/**\\n * Sets the domain.\\n * @throws URIError If opt_decode is true and newDomain is malformed (that is,\\n * if decodeURIComponent fails).\\n * @param {string} newDomain New domain value.\\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\\n * @return {!goog.Uri} Reference to this URI object.\\n */\\ngoog.Uri.prototype.setDomain = function(newDomain, opt_decode) {\\n 'use strict';\\n this.enforceReadOnly();\\n this.domain_ =\\n opt_decode ? goog.Uri.decodeOrEmpty_(newDomain, true) : newDomain;\\n return this;\\n};\\n\\n\\n/**\\n * @return {boolean} Whether the domain has been set.\\n */\\ngoog.Uri.prototype.hasDomain = function() {\\n 'use strict';\\n return !!this.domain_;\\n};\\n\\n\\n/**\\n * @return {?number} The port number.\\n */\\ngoog.Uri.prototype.getPort = function() {\\n 'use strict';\\n return this.port_;\\n};\\n\\n\\n/**\\n * Sets the port number.\\n * @param {*} newPort Port number. Will be explicitly casted to a number.\\n * @return {!goog.Uri} Reference to this URI object.\\n */\\ngoog.Uri.prototype.setPort = function(newPort) {\\n 'use strict';\\n this.enforceReadOnly();\\n\\n if (newPort) {\\n newPort = Number(newPort);\\n if (isNaN(newPort) || newPort < 0) {\\n throw new Error('Bad port number ' + newPort);\\n }\\n this.port_ = newPort;\\n } else {\\n this.port_ = null;\\n }\\n\\n return this;\\n};\\n\\n\\n/**\\n * @return {boolean} Whether the port has been set.\\n */\\ngoog.Uri.prototype.hasPort = function() {\\n 'use strict';\\n return this.port_ != null;\\n};\\n\\n\\n/**\\n * @return {string} The decoded path.\\n */\\ngoog.Uri.prototype.getPath = function() {\\n 'use strict';\\n return this.path_;\\n};\\n\\n\\n/**\\n * Sets the path.\\n * @throws URIError If opt_decode is true and newPath is malformed (that is,\\n * if decodeURIComponent fails).\\n * @param {string} newPath New path value.\\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\\n * @return {!goog.Uri} Reference to this URI object.\\n */\\ngoog.Uri.prototype.setPath = function(newPath, opt_decode) {\\n 'use strict';\\n this.enforceReadOnly();\\n this.path_ = opt_decode ? goog.Uri.decodeOrEmpty_(newPath, true) : newPath;\\n return this;\\n};\\n\\n\\n/**\\n * @return {boolean} Whether the path has been set.\\n */\\ngoog.Uri.prototype.hasPath = function() {\\n 'use strict';\\n return !!this.path_;\\n};\\n\\n\\n/**\\n * @return {boolean} Whether the query string has been set.\\n */\\ngoog.Uri.prototype.hasQuery = function() {\\n 'use strict';\\n return this.queryData_.toString() !== '';\\n};\\n\\n\\n/**\\n * Sets the query data.\\n * @param {goog.Uri.QueryData|string|undefined} queryData QueryData object.\\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\\n * Applies only if queryData is a string.\\n * @return {!goog.Uri} Reference to this URI object.\\n */\\ngoog.Uri.prototype.setQueryData = function(queryData, opt_decode) {\\n 'use strict';\\n this.enforceReadOnly();\\n\\n if (queryData instanceof goog.Uri.QueryData) {\\n this.queryData_ = queryData;\\n this.queryData_.setIgnoreCase(this.ignoreCase_);\\n } else {\\n if (!opt_decode) {\\n // QueryData accepts encoded query string, so encode it if\\n // opt_decode flag is not true.\\n queryData = goog.Uri.encodeSpecialChars_(\\n queryData, goog.Uri.reDisallowedInQuery_);\\n }\\n this.queryData_ = new goog.Uri.QueryData(queryData, this.ignoreCase_);\\n }\\n\\n return this;\\n};\\n\\n\\n/**\\n * Sets the URI query.\\n * @param {string} newQuery New query value.\\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\\n * @return {!goog.Uri} Reference to this URI object.\\n */\\ngoog.Uri.prototype.setQuery = function(newQuery, opt_decode) {\\n 'use strict';\\n return this.setQueryData(newQuery, opt_decode);\\n};\\n\\n\\n/**\\n * @return {string} The encoded URI query, not including the ?.\\n */\\ngoog.Uri.prototype.getEncodedQuery = function() {\\n 'use strict';\\n return this.queryData_.toString();\\n};\\n\\n\\n/**\\n * @return {string} The decoded URI query, not including the ?.\\n */\\ngoog.Uri.prototype.getDecodedQuery = function() {\\n 'use strict';\\n return this.queryData_.toDecodedString();\\n};\\n\\n\\n/**\\n * Returns the query data.\\n * @return {!goog.Uri.QueryData} QueryData object.\\n */\\ngoog.Uri.prototype.getQueryData = function() {\\n 'use strict';\\n return this.queryData_;\\n};\\n\\n\\n/**\\n * @return {string} The encoded URI query, not including the ?.\\n *\\n * Warning: This method, unlike other getter methods, returns encoded\\n * value, instead of decoded one.\\n */\\ngoog.Uri.prototype.getQuery = function() {\\n 'use strict';\\n return this.getEncodedQuery();\\n};\\n\\n\\n/**\\n * Sets the value of the named query parameters, clearing previous values for\\n * that key.\\n *\\n * @param {string} key The parameter to set.\\n * @param {*} value The new value. Value does not need to be encoded.\\n * @return {!goog.Uri} Reference to this URI object.\\n */\\ngoog.Uri.prototype.setParameterValue = function(key, value) {\\n 'use strict';\\n this.enforceReadOnly();\\n this.queryData_.set(key, value);\\n return this;\\n};\\n\\n\\n/**\\n * Sets the values of the named query parameters, clearing previous values for\\n * that key. Not new values will currently be moved to the end of the query\\n * string.\\n *\\n * So, <code>goog.Uri.parse('foo?a=b&c=d&e=f').setParameterValues('c', ['new'])\\n * </code> yields <tt>foo?a=b&e=f&c=new</tt>.</p>\\n *\\n * @param {string} key The parameter to set.\\n * @param {*} values The new values. If values is a single\\n * string then it will be treated as the sole value. Values do not need to\\n * be encoded.\\n * @return {!goog.Uri} Reference to this URI object.\\n */\\ngoog.Uri.prototype.setParameterValues = function(key, values) {\\n 'use strict';\\n this.enforceReadOnly();\\n\\n if (!Array.isArray(values)) {\\n values = [String(values)];\\n }\\n\\n this.queryData_.setValues(key, values);\\n\\n return this;\\n};\\n\\n\\n/**\\n * Returns the value<b>s</b> for a given cgi parameter as a list of decoded\\n * query parameter values.\\n * @param {string} name The parameter to get values for.\\n * @return {!Array<?>} The values for a given cgi parameter as a list of\\n * decoded query parameter values.\\n */\\ngoog.Uri.prototype.getParameterValues = function(name) {\\n 'use strict';\\n return this.queryData_.getValues(name);\\n};\\n\\n\\n/**\\n * Returns the first value for a given cgi parameter or undefined if the given\\n * parameter name does not appear in the query string.\\n * @param {string} paramName Unescaped parameter name.\\n * @return {string|undefined} The first value for a given cgi parameter or\\n * undefined if the given parameter name does not appear in the query\\n * string.\\n */\\ngoog.Uri.prototype.getParameterValue = function(paramName) {\\n 'use strict';\\n return /** @type {string|undefined} */ (this.queryData_.get(paramName));\\n};\\n\\n\\n/**\\n * @return {string} The URI fragment, not including the #.\\n */\\ngoog.Uri.prototype.getFragment = function() {\\n 'use strict';\\n return this.fragment_;\\n};\\n\\n\\n/**\\n * Sets the URI fragment.\\n * @throws URIError If opt_decode is true and newFragment is malformed (that is,\\n * if decodeURIComponent fails).\\n * @param {string} newFragment New fragment value.\\n * @param {boolean=} opt_decode Optional param for whether to decode new value.\\n * @return {!goog.Uri} Reference to this URI object.\\n */\\ngoog.Uri.prototype.setFragment = function(newFragment, opt_decode) {\\n 'use strict';\\n this.enforceReadOnly();\\n this.fragment_ =\\n opt_decode ? goog.Uri.decodeOrEmpty_(newFragment) : newFragment;\\n return this;\\n};\\n\\n\\n/**\\n * @return {boolean} Whether the URI has a fragment set.\\n */\\ngoog.Uri.prototype.hasFragment = function() {\\n 'use strict';\\n return !!this.fragment_;\\n};\\n\\n\\n/**\\n * Returns true if this has the same domain as that of uri2.\\n * @param {!goog.Uri} uri2 The URI object to compare to.\\n * @return {boolean} true if same domain; false otherwise.\\n */\\ngoog.Uri.prototype.hasSameDomainAs = function(uri2) {\\n 'use strict';\\n return ((!this.hasDomain() && !uri2.hasDomain()) ||\\n this.getDomain() == uri2.getDomain()) &&\\n ((!this.hasPort() && !uri2.hasPort()) ||\\n this.getPort() == uri2.getPort());\\n};\\n\\n\\n/**\\n * Adds a random parameter to the Uri.\\n * @return {!goog.Uri} Reference to this Uri object.\\n */\\ngoog.Uri.prototype.makeUnique = function() {\\n 'use strict';\\n this.enforceReadOnly();\\n this.setParameterValue(goog.Uri.RANDOM_PARAM, goog.string.getRandomString());\\n\\n return this;\\n};\\n\\n\\n/**\\n * Removes the named query parameter.\\n *\\n * @param {string} key The parameter to remove.\\n * @return {!goog.Uri} Reference to this URI object.\\n */\\ngoog.Uri.prototype.removeParameter = function(key) {\\n 'use strict';\\n this.enforceReadOnly();\\n this.queryData_.remove(key);\\n return this;\\n};\\n\\n\\n/**\\n * Sets whether Uri is read only. If this goog.Uri is read-only,\\n * enforceReadOnly_ will be called at the start of any function that may modify\\n * this Uri.\\n * @param {boolean} isReadOnly whether this goog.Uri should be read only.\\n * @return {!goog.Uri} Reference to this Uri object.\\n */\\ngoog.Uri.prototype.setReadOnly = function(isReadOnly) {\\n 'use strict';\\n this.isReadOnly_ = isReadOnly;\\n return this;\\n};\\n\\n\\n/**\\n * @return {boolean} Whether the URI is read only.\\n */\\ngoog.Uri.prototype.isReadOnly = function() {\\n 'use strict';\\n return this.isReadOnly_;\\n};\\n\\n\\n/**\\n * Checks if this Uri has been marked as read only, and if so, throws an error.\\n * This should be called whenever any modifying function is called.\\n */\\ngoog.Uri.prototype.enforceReadOnly = function() {\\n 'use strict';\\n if (this.isReadOnly_) {\\n throw new Error('Tried to modify a read-only Uri');\\n }\\n};\\n\\n\\n/**\\n * Sets whether to ignore case.\\n * NOTE: If there are already key/value pairs in the QueryData, and\\n * ignoreCase_ is set to false, the keys will all be lower-cased.\\n * @param {boolean} ignoreCase whether this goog.Uri should ignore case.\\n * @return {!goog.Uri} Reference to this Uri object.\\n */\\ngoog.Uri.prototype.setIgnoreCase = function(ignoreCase) {\\n 'use strict';\\n this.ignoreCase_ = ignoreCase;\\n if (this.queryData_) {\\n this.queryData_.setIgnoreCase(ignoreCase);\\n }\\n return this;\\n};\\n\\n\\n/**\\n * @return {boolean} Whether to ignore case.\\n */\\ngoog.Uri.prototype.getIgnoreCase = function() {\\n 'use strict';\\n return this.ignoreCase_;\\n};\\n\\n\\n//==============================================================================\\n// Static members\\n//==============================================================================\\n\\n\\n/**\\n * Creates a uri from the string form. Basically an alias of new goog.Uri().\\n * If a Uri object is passed to parse then it will return a clone of the object.\\n *\\n * @throws URIError If parsing the URI is malformed. The passed URI components\\n * should all be parseable by decodeURIComponent.\\n * @param {*} uri Raw URI string or instance of Uri\\n * object.\\n * @param {boolean=} opt_ignoreCase Whether to ignore the case of parameter\\n * names in #getParameterValue.\\n * @return {!goog.Uri} The new URI object.\\n */\\ngoog.Uri.parse = function(uri, opt_ignoreCase) {\\n 'use strict';\\n return uri instanceof goog.Uri ? uri.clone() :\\n new goog.Uri(uri, opt_ignoreCase);\\n};\\n\\n\\n/**\\n * Creates a new goog.Uri object from unencoded parts.\\n *\\n * @param {?string=} opt_scheme Scheme/protocol or full URI to parse.\\n * @param {?string=} opt_userInfo username:password.\\n * @param {?string=} opt_domain www.google.com.\\n * @param {?number=} opt_port 9830.\\n * @param {?string=} opt_path /some/path/to/a/file.html.\\n * @param {string|goog.Uri.QueryData=} opt_query a=1&b=2.\\n * @param {?string=} opt_fragment The fragment without the #.\\n * @param {boolean=} opt_ignoreCase Whether to ignore parameter name case in\\n * #getParameterValue.\\n *\\n * @return {!goog.Uri} The new URI object.\\n */\\ngoog.Uri.create = function(\\n opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_query,\\n opt_fragment, opt_ignoreCase) {\\n 'use strict';\\n var uri = new goog.Uri(null, opt_ignoreCase);\\n\\n // Only set the parts if they are defined and not empty strings.\\n opt_scheme && uri.setScheme(opt_scheme);\\n opt_userInfo && uri.setUserInfo(opt_userInfo);\\n opt_domain && uri.setDomain(opt_domain);\\n opt_port && uri.setPort(opt_port);\\n opt_path && uri.setPath(opt_path);\\n opt_query && uri.setQueryData(opt_query);\\n opt_fragment && uri.setFragment(opt_fragment);\\n\\n return uri;\\n};\\n\\n\\n/**\\n * Resolves a relative Uri against a base Uri, accepting both strings and\\n * Uri objects.\\n *\\n * @param {*} base Base Uri.\\n * @param {*} rel Relative Uri.\\n * @return {!goog.Uri} Resolved uri.\\n */\\ngoog.Uri.resolve = function(base, rel) {\\n 'use strict';\\n if (!(base instanceof goog.Uri)) {\\n base = goog.Uri.parse(base);\\n }\\n\\n if (!(rel instanceof goog.Uri)) {\\n rel = goog.Uri.parse(rel);\\n }\\n\\n return base.resolve(rel);\\n};\\n\\n\\n/**\\n * Removes dot segments in given path component, as described in\\n * RFC 3986, section 5.2.4.\\n *\\n * @param {string} path A non-empty path component.\\n * @return {string} Path component with removed dot segments.\\n */\\ngoog.Uri.removeDotSegments = function(path) {\\n 'use strict';\\n if (path == '..' || path == '.') {\\n return '';\\n\\n } else if (\\n !goog.string.contains(path, './') && !goog.string.contains(path, '/.')) {\\n // This optimization detects uris which do not contain dot-segments,\\n // and as a consequence do not require any processing.\\n return path;\\n\\n } else {\\n var leadingSlash = goog.string.startsWith(path, '/');\\n var segments = path.split('/');\\n var out = [];\\n\\n for (var pos = 0; pos < segments.length;) {\\n var segment = segments[pos++];\\n\\n if (segment == '.') {\\n if (leadingSlash && pos == segments.length) {\\n out.push('');\\n }\\n } else if (segment == '..') {\\n if (out.length > 1 || out.length == 1 && out[0] != '') {\\n out.pop();\\n }\\n if (leadingSlash && pos == segments.length) {\\n out.push('');\\n }\\n } else {\\n out.push(segment);\\n leadingSlash = true;\\n }\\n }\\n\\n return out.join('/');\\n }\\n};\\n\\n\\n/**\\n * Decodes a value or returns the empty string if it isn't defined or empty.\\n * @throws URIError If decodeURIComponent fails to decode val.\\n * @param {string|undefined} val Value to decode.\\n * @param {boolean=} opt_preserveReserved If true, restricted characters will\\n * not be decoded.\\n * @return {string} Decoded value.\\n * @private\\n */\\ngoog.Uri.decodeOrEmpty_ = function(val, opt_preserveReserved) {\\n 'use strict';\\n // Don't use UrlDecode() here because val is not a query parameter.\\n if (!val) {\\n return '';\\n }\\n\\n // decodeURI has the same output for '%2f' and '%252f'. We double encode %25\\n // so that we can distinguish between the 2 inputs. This is later undone by\\n // removeDoubleEncoding_.\\n return opt_preserveReserved ? decodeURI(val.replace(/%25/g, '%2525')) :\\n decodeURIComponent(val);\\n};\\n\\n\\n/**\\n * If unescapedPart is non null, then escapes any characters in it that aren't\\n * valid characters in a url and also escapes any special characters that\\n * appear in extra.\\n *\\n * @param {*} unescapedPart The string to encode.\\n * @param {RegExp} extra A character set of characters in [\\\\01-\\\\177].\\n * @param {boolean=} opt_removeDoubleEncoding If true, remove double percent\\n * encoding.\\n * @return {?string} null iff unescapedPart == null.\\n * @private\\n */\\ngoog.Uri.encodeSpecialChars_ = function(\\n unescapedPart, extra, opt_removeDoubleEncoding) {\\n 'use strict';\\n if (typeof unescapedPart === 'string') {\\n var encoded = encodeURI(unescapedPart).replace(extra, goog.Uri.encodeChar_);\\n if (opt_removeDoubleEncoding) {\\n // encodeURI double-escapes %XX sequences used to represent restricted\\n // characters in some URI components, remove the double escaping here.\\n encoded = goog.Uri.removeDoubleEncoding_(encoded);\\n }\\n return encoded;\\n }\\n return null;\\n};\\n\\n\\n/**\\n * Converts a character in [\\\\01-\\\\177] to its unicode character equivalent.\\n * @param {string} ch One character string.\\n * @return {string} Encoded string.\\n * @private\\n */\\ngoog.Uri.encodeChar_ = function(ch) {\\n 'use strict';\\n var n = ch.charCodeAt(0);\\n return '%' + ((n >> 4) & 0xf).toString(16) + (n & 0xf).toString(16);\\n};\\n\\n\\n/**\\n * Removes double percent-encoding from a string.\\n * @param {string} doubleEncodedString String\\n * @return {string} String with double encoding removed.\\n * @private\\n */\\ngoog.Uri.removeDoubleEncoding_ = function(doubleEncodedString) {\\n 'use strict';\\n return doubleEncodedString.replace(/%25([0-9a-fA-F]{2})/g, '%$1');\\n};\\n\\n\\n/**\\n * Regular expression for characters that are disallowed in the scheme or\\n * userInfo part of the URI.\\n * @type {RegExp}\\n * @private\\n */\\ngoog.Uri.reDisallowedInSchemeOrUserInfo_ = /[#\\\\/\\\\?@]/g;\\n\\n\\n/**\\n * Regular expression for characters that are disallowed in a relative path.\\n * Colon is included due to RFC 3986 3.3.\\n * @type {RegExp}\\n * @private\\n */\\ngoog.Uri.reDisallowedInRelativePath_ = /[\\\\#\\\\?:]/g;\\n\\n\\n/**\\n * Regular expression for characters that are disallowed in an absolute path.\\n * @type {RegExp}\\n * @private\\n */\\ngoog.Uri.reDisallowedInAbsolutePath_ = /[\\\\#\\\\?]/g;\\n\\n\\n/**\\n * Regular expression for characters that are disallowed in the query.\\n * @type {RegExp}\\n * @private\\n */\\ngoog.Uri.reDisallowedInQuery_ = /[\\\\#\\\\?@]/g;\\n\\n\\n/**\\n * Regular expression for characters that are disallowed in the fragment.\\n * @type {RegExp}\\n * @private\\n */\\ngoog.Uri.reDisallowedInFragment_ = /#/g;\\n\\n\\n/**\\n * Checks whether two URIs have the same domain.\\n * @param {string} uri1String First URI string.\\n * @param {string} uri2String Second URI string.\\n * @return {boolean} true if the two URIs have the same domain; false otherwise.\\n */\\ngoog.Uri.haveSameDomain = function(uri1String, uri2String) {\\n 'use strict';\\n // Differs from goog.uri.utils.haveSameDomain, since this ignores scheme.\\n // TODO(gboyer): Have this just call goog.uri.util.haveSameDomain.\\n var pieces1 = goog.uri.utils.split(uri1String);\\n var pieces2 = goog.uri.utils.split(uri2String);\\n return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] ==\\n pieces2[goog.uri.utils.ComponentIndex.DOMAIN] &&\\n pieces1[goog.uri.utils.ComponentIndex.PORT] ==\\n pieces2[goog.uri.utils.ComponentIndex.PORT];\\n};\\n\\n\\n\\n/**\\n * Class used to represent URI query parameters. It is essentially a hash of\\n * name-value pairs, though a name can be present more than once.\\n *\\n * Has the same interface as the collections in goog.structs.\\n *\\n * @param {?string=} opt_query Optional encoded query string to parse into\\n * the object.\\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\\n * name in #get.\\n * @constructor\\n * @struct\\n * @final\\n */\\ngoog.Uri.QueryData = function(opt_query, opt_ignoreCase) {\\n 'use strict';\\n /**\\n * The map containing name/value or name/array-of-values pairs.\\n * May be null if it requires parsing from the query string.\\n *\\n * We need to use a Map because we cannot guarantee that the key names will\\n * not be problematic for IE.\\n *\\n * @private {?Map<string, !Array<*>>}\\n */\\n this.keyMap_ = null;\\n\\n /**\\n * The number of params, or null if it requires computing.\\n * @private {?number}\\n */\\n this.count_ = null;\\n\\n /**\\n * Encoded query string, or null if it requires computing from the key map.\\n * @private {?string}\\n */\\n this.encodedQuery_ = opt_query || null;\\n\\n /**\\n * If true, ignore the case of the parameter name in #get.\\n * @private {boolean}\\n */\\n this.ignoreCase_ = !!opt_ignoreCase;\\n};\\n\\n\\n/**\\n * If the underlying key map is not yet initialized, it parses the\\n * query string and fills the map with parsed data.\\n * @private\\n */\\ngoog.Uri.QueryData.prototype.ensureKeyMapInitialized_ = function() {\\n 'use strict';\\n if (!this.keyMap_) {\\n this.keyMap_ = /** @type {!Map<string, !Array<*>>} */ (new Map());\\n this.count_ = 0;\\n if (this.encodedQuery_) {\\n var self = this;\\n goog.uri.utils.parseQueryData(this.encodedQuery_, function(name, value) {\\n 'use strict';\\n self.add(goog.string.urlDecode(name), value);\\n });\\n }\\n }\\n};\\n\\n\\n/**\\n * Creates a new query data instance from a map of names and values.\\n *\\n * @param {!goog.collections.maps.MapLike<string, ?>|!Object} map Map of string\\n * parameter names to parameter value. If parameter value is an array, it is\\n * treated as if the key maps to each individual value in the\\n * array.\\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\\n * name in #get.\\n * @return {!goog.Uri.QueryData} The populated query data instance.\\n */\\ngoog.Uri.QueryData.createFromMap = function(map, opt_ignoreCase) {\\n 'use strict';\\n var keys = goog.structs.getKeys(map);\\n if (typeof keys == 'undefined') {\\n throw new Error('Keys are undefined');\\n }\\n\\n var queryData = new goog.Uri.QueryData(null, opt_ignoreCase);\\n var values = goog.structs.getValues(map);\\n for (var i = 0; i < keys.length; i++) {\\n var key = keys[i];\\n var value = values[i];\\n if (!Array.isArray(value)) {\\n queryData.add(key, value);\\n } else {\\n queryData.setValues(key, value);\\n }\\n }\\n return queryData;\\n};\\n\\n\\n/**\\n * Creates a new query data instance from parallel arrays of parameter names\\n * and values. Allows for duplicate parameter names. Throws an error if the\\n * lengths of the arrays differ.\\n *\\n * @param {!Array<string>} keys Parameter names.\\n * @param {!Array<?>} values Parameter values.\\n * @param {boolean=} opt_ignoreCase If true, ignore the case of the parameter\\n * name in #get.\\n * @return {!goog.Uri.QueryData} The populated query data instance.\\n */\\ngoog.Uri.QueryData.createFromKeysValues = function(\\n keys, values, opt_ignoreCase) {\\n 'use strict';\\n if (keys.length != values.length) {\\n throw new Error('Mismatched lengths for keys/values');\\n }\\n var queryData = new goog.Uri.QueryData(null, opt_ignoreCase);\\n for (var i = 0; i < keys.length; i++) {\\n queryData.add(keys[i], values[i]);\\n }\\n return queryData;\\n};\\n\\n\\n/**\\n * @return {?number} The number of parameters.\\n */\\ngoog.Uri.QueryData.prototype.getCount = function() {\\n 'use strict';\\n this.ensureKeyMapInitialized_();\\n return this.count_;\\n};\\n\\n\\n/**\\n * Adds a key value pair.\\n * @param {string} key Name.\\n * @param {*} value Value.\\n * @return {!goog.Uri.QueryData} Instance of this object.\\n */\\ngoog.Uri.QueryData.prototype.add = function(key, value) {\\n 'use strict';\\n this.ensureKeyMapInitialized_();\\n this.invalidateCache_();\\n\\n key = this.getKeyName_(key);\\n var values = this.keyMap_.get(key);\\n if (!values) {\\n this.keyMap_.set(key, (values = []));\\n }\\n values.push(value);\\n this.count_ = goog.asserts.assertNumber(this.count_) + 1;\\n return this;\\n};\\n\\n\\n/**\\n * Removes all the params with the given key.\\n * @param {string} key Name.\\n * @return {boolean} Whether any parameter was removed.\\n */\\ngoog.Uri.QueryData.prototype.remove = function(key) {\\n 'use strict';\\n this.ensureKeyMapInitialized_();\\n\\n key = this.getKeyName_(key);\\n if (this.keyMap_.has(key)) {\\n this.invalidateCache_();\\n\\n // Decrement parameter count.\\n this.count_ =\\n goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\\n return this.keyMap_.delete(key);\\n }\\n return false;\\n};\\n\\n\\n/**\\n * Clears the parameters.\\n */\\ngoog.Uri.QueryData.prototype.clear = function() {\\n 'use strict';\\n this.invalidateCache_();\\n this.keyMap_ = null;\\n this.count_ = 0;\\n};\\n\\n\\n/**\\n * @return {boolean} Whether we have any parameters.\\n */\\ngoog.Uri.QueryData.prototype.isEmpty = function() {\\n 'use strict';\\n this.ensureKeyMapInitialized_();\\n return this.count_ == 0;\\n};\\n\\n\\n/**\\n * Whether there is a parameter with the given name\\n * @param {string} key The parameter name to check for.\\n * @return {boolean} Whether there is a parameter with the given name.\\n */\\ngoog.Uri.QueryData.prototype.containsKey = function(key) {\\n 'use strict';\\n this.ensureKeyMapInitialized_();\\n key = this.getKeyName_(key);\\n return this.keyMap_.has(key);\\n};\\n\\n\\n/**\\n * Whether there is a parameter with the given value.\\n * @param {*} value The value to check for.\\n * @return {boolean} Whether there is a parameter with the given value.\\n */\\ngoog.Uri.QueryData.prototype.containsValue = function(value) {\\n 'use strict';\\n // NOTE(arv): This solution goes through all the params even if it was the\\n // first param. We can get around this by not reusing code or by switching to\\n // iterators.\\n var vals = this.getValues();\\n return goog.array.contains(vals, value);\\n};\\n\\n\\n/**\\n * Runs a callback on every key-value pair in the map, including duplicate keys.\\n * This won't maintain original order when duplicate keys are interspersed (like\\n * getKeys() / getValues()).\\n * @param {function(this:SCOPE, ?, string, !goog.Uri.QueryData)} f\\n * @param {SCOPE=} opt_scope The value of \\\"this\\\" inside f.\\n * @template SCOPE\\n */\\ngoog.Uri.QueryData.prototype.forEach = function(f, opt_scope) {\\n 'use strict';\\n this.ensureKeyMapInitialized_();\\n this.keyMap_.forEach(function(values, key) {\\n 'use strict';\\n values.forEach(function(value) {\\n 'use strict';\\n f.call(opt_scope, value, key, this);\\n }, this);\\n }, this);\\n};\\n\\n\\n/**\\n * Returns all the keys of the parameters. If a key is used multiple times\\n * it will be included multiple times in the returned array\\n * @return {!Array<string>} All the keys of the parameters.\\n */\\ngoog.Uri.QueryData.prototype.getKeys = function() {\\n 'use strict';\\n this.ensureKeyMapInitialized_();\\n // We need to get the values to know how many keys to add.\\n const vals = Array.from(this.keyMap_.values());\\n const keys = Array.from(this.keyMap_.keys());\\n const rv = [];\\n for (let i = 0; i < keys.length; i++) {\\n const val = vals[i];\\n for (let j = 0; j < val.length; j++) {\\n rv.push(keys[i]);\\n }\\n }\\n return rv;\\n};\\n\\n\\n/**\\n * Returns all the values of the parameters with the given name. If the query\\n * data has no such key this will return an empty array. If no key is given\\n * all values wil be returned.\\n * @param {string=} opt_key The name of the parameter to get the values for.\\n * @return {!Array<?>} All the values of the parameters with the given name.\\n */\\ngoog.Uri.QueryData.prototype.getValues = function(opt_key) {\\n 'use strict';\\n this.ensureKeyMapInitialized_();\\n let rv = [];\\n if (typeof opt_key === 'string') {\\n if (this.containsKey(opt_key)) {\\n rv = rv.concat(this.keyMap_.get(this.getKeyName_(opt_key)));\\n }\\n } else {\\n // Return all values.\\n const values = Array.from(this.keyMap_.values());\\n for (let i = 0; i < values.length; i++) {\\n rv = rv.concat(values[i]);\\n }\\n }\\n return rv;\\n};\\n\\n\\n/**\\n * Sets a key value pair and removes all other keys with the same value.\\n *\\n * @param {string} key Name.\\n * @param {*} value Value.\\n * @return {!goog.Uri.QueryData} Instance of this object.\\n */\\ngoog.Uri.QueryData.prototype.set = function(key, value) {\\n 'use strict';\\n this.ensureKeyMapInitialized_();\\n this.invalidateCache_();\\n\\n // TODO(chrishenry): This could be better written as\\n // this.remove(key), this.add(key, value), but that would reorder\\n // the key (since the key is first removed and then added at the\\n // end) and we would have to fix unit tests that depend on key\\n // ordering.\\n key = this.getKeyName_(key);\\n if (this.containsKey(key)) {\\n this.count_ =\\n goog.asserts.assertNumber(this.count_) - this.keyMap_.get(key).length;\\n }\\n this.keyMap_.set(key, [value]);\\n this.count_ = goog.asserts.assertNumber(this.count_) + 1;\\n return this;\\n};\\n\\n\\n/**\\n * Returns the first value associated with the key. If the query data has no\\n * such key this will return undefined or the optional default.\\n * @param {string} key The name of the parameter to get the value for.\\n * @param {*=} opt_default The default value to return if the query data\\n * has no such key.\\n * @return {*} The first string value associated with the key, or opt_default\\n * if there's no value.\\n */\\ngoog.Uri.QueryData.prototype.get = function(key, opt_default) {\\n 'use strict';\\n if (!key) {\\n return opt_default;\\n }\\n var values = this.getValues(key);\\n return values.length > 0 ? String(values[0]) : opt_default;\\n};\\n\\n\\n/**\\n * Sets the values for a key. If the key already exists, this will\\n * override all of the existing values that correspond to the key.\\n * @param {string} key The key to set values for.\\n * @param {!Array<?>} values The values to set.\\n */\\ngoog.Uri.QueryData.prototype.setValues = function(key, values) {\\n 'use strict';\\n this.remove(key);\\n\\n if (values.length > 0) {\\n this.invalidateCache_();\\n this.keyMap_.set(this.getKeyName_(key), goog.array.clone(values));\\n this.count_ = goog.asserts.assertNumber(this.count_) + values.length;\\n }\\n};\\n\\n\\n/**\\n * @return {string} Encoded query string.\\n * @override\\n */\\ngoog.Uri.QueryData.prototype.toString = function() {\\n 'use strict';\\n if (this.encodedQuery_) {\\n return this.encodedQuery_;\\n }\\n\\n if (!this.keyMap_) {\\n return '';\\n }\\n\\n const sb = [];\\n\\n // In the past, we use this.getKeys() and this.getVals(), but that\\n // generates a lot of allocations as compared to simply iterating\\n // over the keys.\\n const keys = Array.from(this.keyMap_.keys());\\n for (var i = 0; i < keys.length; i++) {\\n const key = keys[i];\\n const encodedKey = goog.string.urlEncode(key);\\n const val = this.getValues(key);\\n for (var j = 0; j < val.length; j++) {\\n var param = encodedKey;\\n // Ensure that null and undefined are encoded into the url as\\n // literal strings.\\n if (val[j] !== '') {\\n param += '=' + goog.string.urlEncode(val[j]);\\n }\\n sb.push(param);\\n }\\n }\\n\\n return this.encodedQuery_ = sb.join('&');\\n};\\n\\n\\n/**\\n * @throws URIError If URI is malformed (that is, if decodeURIComponent fails on\\n * any of the URI components).\\n * @return {string} Decoded query string.\\n */\\ngoog.Uri.QueryData.prototype.toDecodedString = function() {\\n 'use strict';\\n return goog.Uri.decodeOrEmpty_(this.toString());\\n};\\n\\n\\n/**\\n * Invalidate the cache.\\n * @private\\n */\\ngoog.Uri.QueryData.prototype.invalidateCache_ = function() {\\n 'use strict';\\n this.encodedQuery_ = null;\\n};\\n\\n\\n/**\\n * Removes all keys that are not in the provided list. (Modifies this object.)\\n * @param {Array<string>} keys The desired keys.\\n * @return {!goog.Uri.QueryData} a reference to this object.\\n */\\ngoog.Uri.QueryData.prototype.filterKeys = function(keys) {\\n 'use strict';\\n this.ensureKeyMapInitialized_();\\n this.keyMap_.forEach(function(value, key) {\\n 'use strict';\\n if (!goog.array.contains(keys, key)) {\\n this.remove(key);\\n }\\n }, this);\\n return this;\\n};\\n\\n\\n/**\\n * Clone the query data instance.\\n * @return {!goog.Uri.QueryData} New instance of the QueryData object.\\n */\\ngoog.Uri.QueryData.prototype.clone = function() {\\n 'use strict';\\n var rv = new goog.Uri.QueryData();\\n rv.encodedQuery_ = this.encodedQuery_;\\n if (this.keyMap_) {\\n rv.keyMap_ = /** @type {!Map<string, !Array<*>>} */ (new Map(this.keyMap_));\\n rv.count_ = this.count_;\\n }\\n return rv;\\n};\\n\\n\\n/**\\n * Helper function to get the key name from a JavaScript object. Converts\\n * the object to a string, and to lower case if necessary.\\n * @private\\n * @param {*} arg The object to get a key name from.\\n * @return {string} valid key name which can be looked up in #keyMap_.\\n */\\ngoog.Uri.QueryData.prototype.getKeyName_ = function(arg) {\\n 'use strict';\\n var keyName = String(arg);\\n if (this.ignoreCase_) {\\n keyName = keyName.toLowerCase();\\n }\\n return keyName;\\n};\\n\\n\\n/**\\n * Ignore case in parameter names.\\n * NOTE: If there are already key/value pairs in the QueryData, and\\n * ignoreCase_ is set to false, the keys will all be lower-cased.\\n * @param {boolean} ignoreCase whether this goog.Uri should ignore case.\\n */\\ngoog.Uri.QueryData.prototype.setIgnoreCase = function(ignoreCase) {\\n 'use strict';\\n var resetKeys = ignoreCase && !this.ignoreCase_;\\n if (resetKeys) {\\n this.ensureKeyMapInitialized_();\\n this.invalidateCache_();\\n this.keyMap_.forEach(function(value, key) {\\n 'use strict';\\n var lowerCase = key.toLowerCase();\\n if (key != lowerCase) {\\n this.remove(key);\\n this.setValues(lowerCase, value);\\n }\\n }, this);\\n }\\n this.ignoreCase_ = ignoreCase;\\n};\\n\\n\\n/**\\n * Extends a query data object with another query data or map like object. This\\n * operates 'in-place', it does not create a new QueryData object.\\n *\\n * @param {...(?goog.Uri.QueryData|?goog.collections.maps.MapLike<?,\\n * ?>|?Object)} var_args The object from which key value pairs will be\\n * copied. Note: does not accept null.\\n * @suppress {deprecated} Use deprecated goog.structs.forEach to allow different\\n * types of parameters.\\n */\\ngoog.Uri.QueryData.prototype.extend = function(var_args) {\\n 'use strict';\\n for (var i = 0; i < arguments.length; i++) {\\n var data = arguments[i];\\n goog.structs.forEach(data, function(value, key) {\\n 'use strict';\\n this.add(key, value);\\n }, this);\\n }\\n};\\n\"],\n\"names\":[\"goog\",\"provide\",\"require\",\"Uri\",\"goog.Uri\",\"opt_uri\",\"opt_ignoreCase\",\"scheme_\",\"userInfo_\",\"domain_\",\"port_\",\"path_\",\"fragment_\",\"isReadOnly_\",\"ignoreCase_\",\"queryData_\",\"m\",\"undefined\",\"getIgnoreCase\",\"setScheme\",\"getScheme\",\"setUserInfo\",\"getUserInfo\",\"setDomain\",\"getDomain\",\"setPort\",\"getPort\",\"setPath\",\"getPath\",\"setQueryData\",\"getQueryData\",\"clone\",\"setFragment\",\"getFragment\",\"uri\",\"utils\",\"split\",\"String\",\"ComponentIndex\",\"SCHEME\",\"USER_INFO\",\"DOMAIN\",\"PORT\",\"PATH\",\"QUERY_DATA\",\"FRAGMENT\",\"QueryData\",\"RANDOM_PARAM\",\"StandardQueryParam\",\"RANDOM\",\"prototype\",\"toString\",\"goog.Uri.prototype.toString\",\"out\",\"scheme\",\"push\",\"encodeSpecialChars_\",\"reDisallowedInSchemeOrUserInfo_\",\"domain\",\"userInfo\",\"removeDoubleEncoding_\",\"string\",\"urlEncode\",\"port\",\"path\",\"hasDomain\",\"charAt\",\"reDisallowedInAbsolutePath_\",\"reDisallowedInRelativePath_\",\"query\",\"getEncodedQuery\",\"fragment\",\"reDisallowedInFragment_\",\"join\",\"resolve\",\"goog.Uri.prototype.resolve\",\"relativeUri\",\"absoluteUri\",\"overridden\",\"hasScheme\",\"hasUserInfo\",\"hasPort\",\"hasPath\",\"lastSlashIndex\",\"lastIndexOf\",\"slice\",\"removeDotSegments\",\"hasQuery\",\"hasFragment\",\"goog.Uri.prototype.clone\",\"goog.Uri.prototype.getScheme\",\"goog.Uri.prototype.setScheme\",\"newScheme\",\"opt_decode\",\"enforceReadOnly\",\"decodeOrEmpty_\",\"replace\",\"goog.Uri.prototype.hasScheme\",\"goog.Uri.prototype.getUserInfo\",\"goog.Uri.prototype.setUserInfo\",\"newUserInfo\",\"goog.Uri.prototype.hasUserInfo\",\"goog.Uri.prototype.getDomain\",\"goog.Uri.prototype.setDomain\",\"newDomain\",\"goog.Uri.prototype.hasDomain\",\"goog.Uri.prototype.getPort\",\"goog.Uri.prototype.setPort\",\"newPort\",\"Number\",\"isNaN\",\"Error\",\"goog.Uri.prototype.hasPort\",\"goog.Uri.prototype.getPath\",\"goog.Uri.prototype.setPath\",\"newPath\",\"goog.Uri.prototype.hasPath\",\"goog.Uri.prototype.hasQuery\",\"goog.Uri.prototype.setQueryData\",\"queryData\",\"setIgnoreCase\",\"reDisallowedInQuery_\",\"setQuery\",\"goog.Uri.prototype.setQuery\",\"newQuery\",\"goog.Uri.prototype.getEncodedQuery\",\"getDecodedQuery\",\"goog.Uri.prototype.getDecodedQuery\",\"toDecodedString\",\"goog.Uri.prototype.getQueryData\",\"getQuery\",\"goog.Uri.prototype.getQuery\",\"setParameterValue\",\"goog.Uri.prototype.setParameterValue\",\"key\",\"value\",\"set\",\"setParameterValues\",\"goog.Uri.prototype.setParameterValues\",\"values\",\"Array\",\"isArray\",\"setValues\",\"getParameterValues\",\"goog.Uri.prototype.getParameterValues\",\"name\",\"getValues\",\"getParameterValue\",\"goog.Uri.prototype.getParameterValue\",\"paramName\",\"get\",\"goog.Uri.prototype.getFragment\",\"goog.Uri.prototype.setFragment\",\"newFragment\",\"goog.Uri.prototype.hasFragment\",\"hasSameDomainAs\",\"goog.Uri.prototype.hasSameDomainAs\",\"uri2\",\"makeUnique\",\"goog.Uri.prototype.makeUnique\",\"getRandomString\",\"removeParameter\",\"goog.Uri.prototype.removeParameter\",\"remove\",\"setReadOnly\",\"goog.Uri.prototype.setReadOnly\",\"isReadOnly\",\"goog.Uri.prototype.isReadOnly\",\"goog.Uri.prototype.enforceReadOnly\",\"goog.Uri.prototype.setIgnoreCase\",\"ignoreCase\",\"goog.Uri.prototype.getIgnoreCase\",\"parse\",\"goog.Uri.parse\",\"create\",\"goog.Uri.create\",\"opt_scheme\",\"opt_userInfo\",\"opt_domain\",\"opt_port\",\"opt_path\",\"opt_query\",\"opt_fragment\",\"goog.Uri.resolve\",\"base\",\"rel\",\"goog.Uri.removeDotSegments\",\"contains\",\"leadingSlash\",\"startsWith\",\"segments\",\"pos\",\"length\",\"segment\",\"pop\",\"goog.Uri.decodeOrEmpty_\",\"val\",\"opt_preserveReserved\",\"decodeURI\",\"decodeURIComponent\",\"goog.Uri.encodeSpecialChars_\",\"unescapedPart\",\"extra\",\"opt_removeDoubleEncoding\",\"encoded\",\"encodeURI\",\"encodeChar_\",\"goog.Uri.encodeChar_\",\"ch\",\"n\",\"charCodeAt\",\"goog.Uri.removeDoubleEncoding_\",\"doubleEncodedString\",\"haveSameDomain\",\"goog.Uri.haveSameDomain\",\"uri1String\",\"uri2String\",\"pieces1\",\"pieces2\",\"goog.Uri.QueryData\",\"keyMap_\",\"count_\",\"encodedQuery_\",\"ensureKeyMapInitialized_\",\"goog.Uri.QueryData.prototype.ensureKeyMapInitialized_\",\"Map\",\"self\",\"parseQueryData\",\"add\",\"urlDecode\",\"createFromMap\",\"goog.Uri.QueryData.createFromMap\",\"map\",\"keys\",\"structs\",\"getKeys\",\"i\",\"createFromKeysValues\",\"goog.Uri.QueryData.createFromKeysValues\",\"getCount\",\"goog.Uri.QueryData.prototype.getCount\",\"goog.Uri.QueryData.prototype.add\",\"invalidateCache_\",\"getKeyName_\",\"asserts\",\"assertNumber\",\"goog.Uri.QueryData.prototype.remove\",\"has\",\"delete\",\"clear\",\"goog.Uri.QueryData.prototype.clear\",\"isEmpty\",\"goog.Uri.QueryData.prototype.isEmpty\",\"containsKey\",\"goog.Uri.QueryData.prototype.containsKey\",\"containsValue\",\"goog.Uri.QueryData.prototype.containsValue\",\"vals\",\"array\",\"forEach\",\"goog.Uri.QueryData.prototype.forEach\",\"f\",\"opt_scope\",\"call\",\"goog.Uri.QueryData.prototype.getKeys\",\"from\",\"rv\",\"j\",\"goog.Uri.QueryData.prototype.getValues\",\"opt_key\",\"concat\",\"goog.Uri.QueryData.prototype.set\",\"goog.Uri.QueryData.prototype.get\",\"opt_default\",\"goog.Uri.QueryData.prototype.setValues\",\"goog.Uri.QueryData.prototype.toString\",\"sb\",\"encodedKey\",\"param\",\"goog.Uri.QueryData.prototype.toDecodedString\",\"goog.Uri.QueryData.prototype.invalidateCache_\",\"filterKeys\",\"goog.Uri.QueryData.prototype.filterKeys\",\"goog.Uri.QueryData.prototype.clone\",\"goog.Uri.QueryData.prototype.getKeyName_\",\"arg\",\"keyName\",\"toLowerCase\",\"goog.Uri.QueryData.prototype.setIgnoreCase\",\"resetKeys\",\"lowerCase\",\"extend\",\"goog.Uri.QueryData.prototype.extend\",\"var_args\",\"arguments\",\"data\"]\n}\n"]