function uri_parse(uriStr){var m=uriStr.match(URI_RE_);if(!m){return null}return new URI(uri_nullIfAbsent_(m[1]),uri_nullIfAbsent_(m[2]),uri_nullIfAbsent_(m[3]),uri_nullIfAbsent_(m[4]),uri_nullIfAbsent_(m[5]),uri_nullIfAbsent_(m[6]),uri_nullIfAbsent_(m[7]))}function uri_create(scheme,credentials,domain,port,path,cgiParamList,fragment){var uri=new URI(uri_encodeIfExists2_(scheme,URI_DISALLOWED_IN_SCHEME_OR_CREDENTIALS_),uri_encodeIfExists2_(credentials,URI_DISALLOWED_IN_SCHEME_OR_CREDENTIALS_),uri_encodeIfExists_(domain),port>0?port.toString():null,uri_encodeIfExists2_(path,URI_DISALLOWED_IN_PATH_),null,uri_encodeIfExists_(fragment));if(cgiParamList){uri.SetAllCgiParameters(cgiParamList)}return uri}function uri_encodeIfExists_(unescapedPart){if("string"==typeof unescapedPart){return encodeURIComponent(unescapedPart)}return null}function uri_encodeIfExists2_(unescapedPart,extra){if("string"==typeof unescapedPart){return encodeURI(unescapedPart).replace(extra,uri_encodeOne_)}return null}function uri_encodeOne_(ch){var n=ch.charCodeAt(0);return"%"+"0123456789ABCDEF".charAt((n>>4)&15)+"0123456789ABCDEF".charAt(n&15)}function uri_resolve(baseUri,relativeUri){var absoluteUri=baseUri.Clone();var overridden=relativeUri.HasScheme();if(overridden){absoluteUri.SetRawScheme(relativeUri.GetRawScheme())}else{overridden=relativeUri.HasCredentials()}if(overridden){absoluteUri.SetRawCredentials(relativeUri.GetRawCredentials())}else{overridden=relativeUri.HasDomain()}if(overridden){absoluteUri.SetRawDomain(relativeUri.GetRawDomain())}else{overridden=relativeUri.HasPort()}var rawPath=relativeUri.GetRawPath();if(overridden){absoluteUri.SetPort(relativeUri.GetPort())}else{overridden=relativeUri.HasPath();if(overridden){if(!new RegExp("^/").test(rawPath)){rawPath=absoluteUri.GetRawPath().replace(new RegExp("/?[^/]*$"),"/"+rawPath)}}}if(overridden){absoluteUri.SetRawPath(rawPath)}else{overridden=relativeUri.HasQuery()}if(overridden){absoluteUri.SetRawQuery(relativeUri.GetRawQuery())}else{overridden=relativeUri.HasFragment()}if(overridden){absoluteUri.SetRawFragment(relativeUri.GetRawFragment())}return absoluteUri}function URI(rawScheme,rawCredentials,rawDomain,port,rawPath,rawQuery,rawFragment){this.scheme_=rawScheme;this.credentials_=rawCredentials;this.domain_=rawDomain;this.port_=port;this.path_=rawPath;this.query_=rawQuery;this.fragment_=rawFragment;this.paramCache_=null}URI.prototype.toString=function(){var out=[];if(null!==this.scheme_){out.push(this.scheme_,":")}if(null!==this.domain_){out.push("//");if(null!==this.credentials_){out.push(this.credentials_,"@")}out.push(this.domain_);if(null!==this.port_){out.push(":",this.port_.toString())}}if(null!==this.path_){out.push(this.path_)}if(null!==this.query_){out.push("?",this.query_)}if(null!==this.fragment_){out.push("#",this.fragment_)}return out.join("")};URI.prototype.Clone=function(){return new URI(this.scheme_,this.credentials_,this.domain_,this.port_,this.path_,this.query_,this.fragment_)};URI.prototype.GetScheme=function(){return this.scheme_&&uri_decodeThatWorks_(this.scheme_)};URI.prototype.GetRawScheme=function(){return this.scheme_};URI.prototype.SetScheme=function(newScheme){this.scheme_=uri_encodeIfExists2_(newScheme,URI_DISALLOWED_IN_SCHEME_OR_CREDENTIALS_);return this};URI.prototype.SetRawScheme=function(newScheme){this.scheme_=newScheme?newScheme:null;return this};URI.prototype.HasScheme=function(){return null!==this.scheme_};URI.prototype.GetCredentials=function(){return this.credentials_&&uri_decodeThatWorks_(this.credentials_)};URI.prototype.GetRawCredentials=function(){return this.credentials_};URI.prototype.SetCredentials=function(newCredentials){this.credentials_=uri_encodeIfExists2_(newCredentials,URI_DISALLOWED_IN_SCHEME_OR_CREDENTIALS_);return this};URI.prototype.SetRawCredentials=function(newCredentials){this.credentials_=newCredentials?newCredentials:null;return this};URI.prototype.HasCredentials=function(){return null!==this.credentials_};URI.prototype.GetDomain=function(){return this.domain_&&uri_decodeThatWorks_(this.domain_)
};URI.prototype.GetRawDomain=function(){return this.domain_};URI.prototype.SetDomain=function(newDomain){this.domain_=newDomain?encodeURIComponent(newDomain):null;return this};URI.prototype.SetRawDomain=function(newDomain){this.domain_=newDomain?newDomain:null;return this};URI.prototype.HasDomain=function(){return null!==this.domain_};URI.prototype.GetPort=function(){return this.port_&&uri_decodeThatWorks_(this.port_)};URI.prototype.SetPort=function(newPort){if(newPort){if("number"!==typeof newPort){newPort=parseInt(newPort,10);if(newPort<0||isNaN(newPort)){throw new Error("Bad port number "+newPort)}}this.port_=newPort.toString()}else{this.port_=null}return this};URI.prototype.HasPort=function(){return null!==this.port_};URI.prototype.GetPath=function(){return this.path_&&uri_decodeThatWorks_(this.path_)};URI.prototype.GetRawPath=function(){return this.path_};URI.prototype.SetPath=function(newPath){this.path_=uri_encodeIfExists2_(newPath,URI_DISALLOWED_IN_PATH_);return this};URI.prototype.SetRawPath=function(newPath){this.path_=newPath?newPath:null;return this};URI.prototype.HasPath=function(){return null!==this.path_};URI.prototype.GetQuery=function(){return this.query_&&uri_decodeThatWorks_(this.query_)};URI.prototype.GetRawQuery=function(){return this.query_};URI.prototype.SetQuery=function(newQuery){this.paramCache_=null;this.query_=uri_encodeIfExists_(newQuery);return this};URI.prototype.SetRawQuery=function(newQuery){this.paramCache_=null;this.query_=newQuery?newQuery:null;return this};URI.prototype.HasQuery=function(){return null!==this.query_};URI.prototype.SetAllCgiParameters=function(unescapedCgiParameters){this.paramCache_=null;var queryBuf=[];var separator="";for(var i=0;i<unescapedCgiParameters.length;){var k=unescapedCgiParameters[i++];var v=unescapedCgiParameters[i++];queryBuf.push(separator,encodeURIComponent(k.toString()));separator="&";if(v){queryBuf.push("=",encodeURIComponent(v.toString()))}}this.query_=queryBuf.join("");return this};URI.prototype.CheckParameterCache_=function(){if(!this.paramCache_){if(!this.query_){this.paramCache_=[]}else{var cgiParams=this.query_.split(/[&\?]/);var out=[];for(var i=0;i<cgiParams.length;++i){var m=cgiParams[i].match(/^([^=]*)(?:=(.*))?$/);out.push(uri_decodeThatWorks_(m[1]),uri_decodeThatWorks_(m[2]||""))}this.paramCache_=out}}};URI.prototype.SetCgiParameterValues=function(key,values){if(typeof values==="string"){values=[values]}this.CheckParameterCache_();var newValueIndex=0;var pc=this.paramCache_;var params=[];for(var i=0,k=0;i<pc.length;i+=2){if(key===pc[i]){if(newValueIndex<values.length){params.push(key,values[newValueIndex++])}}else{params.push(pc[i],pc[i+1])}}while(newValueIndex<values.length){params.push(key,values[newValueIndex++])}this.SetAllCgiParameters(params);return this};URI.prototype.GetAllCgiParameters=function(){this.CheckParameterCache_();return this.paramCache_.slice(0,this.paramCache_.length)};URI.prototype.GetCgiParameterValues=function(paramNameUnescaped){this.CheckParameterCache_();var values=[];for(var i=0;i<this.paramCache_.length;i+=2){if(paramNameUnescaped===this.paramCache_[i]){values.push(this.paramCache_[i+1])}}return values};URI.prototype.GetCgiParameterMap=function(paramNameUnescaped){this.CheckParameterCache_();var paramMap={};for(var i=0;i<this.paramCache_.length;i+=2){var key=this.paramCache_[i++],value=this.paramCache_[i++];if(!(key in paramMap)){paramMap[key]=[value]}else{paramMap[key].push(value)}}return paramMap};URI.prototype.GetCgiParameterValue=function(paramNameUnescaped){this.CheckParameterCache_();for(var i=0;i<this.paramCache_.length;i+=2){if(paramNameUnescaped===this.paramCache_[i]){return this.paramCache_[i+1]}}return null};URI.prototype.GetFragment=function(){return this.fragment_&&uri_decodeThatWorks_(this.fragment_)};URI.prototype.GetRawFragment=function(){return this.fragment_};URI.prototype.SetFragment=function(newFragment){this.fragment_=newFragment?encodeURIComponent(newFragment):null;return this};URI.prototype.SetRawFragment=function(newFragment){this.fragment_=newFragment?newFragment:null;
return this};URI.prototype.HasFragment=function(){return null!==this.fragment_};function uri_decodeThatWorks_(s){return decodeURIComponent(s).replace(/\+/g," ")}function uri_nullIfAbsent_(matchPart){return("string"==typeof matchPart)&&(matchPart.length>0)?matchPart:null}var URI_RE_=new RegExp("^"+"(?:"+"([^:/?#]+)"+":)?"+"(?://"+"(?:([^/?#]*)@)?"+"([^/?#:@]*)"+"(?::([0-9]+))?"+")?"+"([^?#]+)?"+"(?:\\?([^#]*))?"+"(?:#(.*))?"+"$");var URI_DISALLOWED_IN_SCHEME_OR_CREDENTIALS_=/[#\/\?@]/g;var URI_DISALLOWED_IN_PATH_=/[\#\?]/g;
