Created
June 23, 2014 09:07
-
-
Save chirayudesai/9dd678d722d0948ee79c to your computer and use it in GitHub Desktop.
easy_unlock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var goog = goog || {}; | |
goog.global = this; | |
goog.isDef = function(val) { | |
return void 0 !== val; | |
}; | |
goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) { | |
var parts = name.split("."), cur = opt_objectToExportTo || goog.global; | |
parts[0] in cur || !cur.execScript || cur.execScript("var " + parts[0]); | |
for (var part;parts.length && (part = parts.shift());) { | |
!parts.length && goog.isDef(opt_object) ? cur[part] = opt_object : cur = cur[part] ? cur[part] : cur[part] = {}; | |
} | |
}; | |
goog.define = function(name, defaultValue) { | |
goog.exportPath_(name, defaultValue); | |
}; | |
goog.DEBUG = !0; | |
goog.LOCALE = "en"; | |
goog.TRUSTED_SITE = !0; | |
goog.STRICT_MODE_COMPATIBLE = !1; | |
goog.provide = function(name) { | |
goog.exportPath_(name); | |
}; | |
goog.setTestOnly = function(opt_message) { | |
if (!goog.DEBUG) { | |
throw opt_message = opt_message || "", Error("Importing test-only code into non-debug environment" + (opt_message ? ": " + opt_message : ".")); | |
} | |
}; | |
goog.forwardDeclare = function() { | |
}; | |
goog.getObjectByName = function(name) { | |
for (var parts = name.split("."), cur = goog.global, part;part = parts.shift();) { | |
if (goog.isDefAndNotNull(cur[part])) { | |
cur = cur[part]; | |
} else { | |
return null; | |
} | |
} | |
return cur; | |
}; | |
goog.globalize = function(obj, opt_global) { | |
var global = opt_global || goog.global, x; | |
for (x in obj) { | |
global[x] = obj[x]; | |
} | |
}; | |
goog.addDependency = function(relPath, provides, requires) { | |
if (goog.DEPENDENCIES_ENABLED) { | |
for (var provide, require, path = relPath.replace(/\\/g, "/"), deps = goog.dependencies_, i = 0;provide = provides[i];i++) { | |
deps.nameToPath[provide] = path, path in deps.pathToNames || (deps.pathToNames[path] = {}), deps.pathToNames[path][provide] = !0; | |
} | |
for (var j = 0;require = requires[j];j++) { | |
path in deps.requires || (deps.requires[path] = {}), deps.requires[path][require] = !0; | |
} | |
} | |
}; | |
goog.useStrictRequires = !1; | |
goog.ENABLE_DEBUG_LOADER = !0; | |
goog.require = function() { | |
}; | |
goog.basePath = ""; | |
goog.nullFunction = function() { | |
}; | |
goog.identityFunction = function(opt_returnValue) { | |
return opt_returnValue; | |
}; | |
goog.abstractMethod = function() { | |
throw Error("unimplemented abstract method"); | |
}; | |
goog.addSingletonGetter = function(ctor) { | |
ctor.getInstance = function() { | |
if (ctor.instance_) { | |
return ctor.instance_; | |
} | |
goog.DEBUG && (goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor); | |
return ctor.instance_ = new ctor; | |
}; | |
}; | |
goog.instantiatedSingletons_ = []; | |
goog.DEPENDENCIES_ENABLED = !1; | |
goog.DEPENDENCIES_ENABLED && (goog.included_ = {}, goog.dependencies_ = {pathToNames:{}, nameToPath:{}, requires:{}, visited:{}, written:{}}, goog.inHtmlDocument_ = function() { | |
var doc = goog.global.document; | |
return "undefined" != typeof doc && "write" in doc; | |
}, goog.findBasePath_ = function() { | |
if (goog.global.CLOSURE_BASE_PATH) { | |
goog.basePath = goog.global.CLOSURE_BASE_PATH; | |
} else { | |
if (goog.inHtmlDocument_()) { | |
for (var scripts = goog.global.document.getElementsByTagName("script"), i = scripts.length - 1;0 <= i;--i) { | |
var src = scripts[i].src, qmark = src.lastIndexOf("?"), l = -1 == qmark ? src.length : qmark; | |
if ("base.js" == src.substr(l - 7, 7)) { | |
goog.basePath = src.substr(0, l - 7); | |
break; | |
} | |
} | |
} | |
} | |
}, goog.importScript_ = function(src) { | |
var importScript = goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_; | |
!goog.dependencies_.written[src] && importScript(src) && (goog.dependencies_.written[src] = !0); | |
}, goog.writeScriptTag_ = function(src) { | |
if (goog.inHtmlDocument_()) { | |
var doc = goog.global.document; | |
if ("complete" == doc.readyState) { | |
if (/\bdeps.js$/.test(src)) { | |
return!1; | |
} | |
throw Error('Cannot write "' + src + '" after document load'); | |
} | |
doc.write('<script type="text/javascript" src="' + src + '">\x3c/script>'); | |
return!0; | |
} | |
return!1; | |
}, goog.writeScripts_ = function() { | |
function visitNode(path) { | |
if (!(path in deps.written)) { | |
if (!(path in deps.visited) && (deps.visited[path] = !0, path in deps.requires)) { | |
for (var requireName in deps.requires[path]) { | |
if (!goog.isProvided_(requireName)) { | |
if (requireName in deps.nameToPath) { | |
visitNode(deps.nameToPath[requireName]); | |
} else { | |
throw Error("Undefined nameToPath for " + requireName); | |
} | |
} | |
} | |
} | |
path in seenScript || (seenScript[path] = !0, scripts.push(path)); | |
} | |
} | |
var scripts = [], seenScript = {}, deps = goog.dependencies_, path$$0; | |
for (path$$0 in goog.included_) { | |
deps.written[path$$0] || visitNode(path$$0); | |
} | |
for (var i = 0;i < scripts.length;i++) { | |
if (scripts[i]) { | |
goog.importScript_(goog.basePath + scripts[i]); | |
} else { | |
throw Error("Undefined script input"); | |
} | |
} | |
}, goog.getPathFromDeps_ = function(rule) { | |
return rule in goog.dependencies_.nameToPath ? goog.dependencies_.nameToPath[rule] : null; | |
}, goog.findBasePath_(), goog.global.CLOSURE_NO_DEPS || goog.importScript_(goog.basePath + "deps.js")); | |
goog.typeOf = function(value) { | |
var s = typeof value; | |
if ("object" == s) { | |
if (value) { | |
if (value instanceof Array) { | |
return "array"; | |
} | |
if (value instanceof Object) { | |
return s; | |
} | |
var className = Object.prototype.toString.call(value); | |
if ("[object Window]" == className) { | |
return "object"; | |
} | |
if ("[object Array]" == className || "number" == typeof value.length && "undefined" != typeof value.splice && "undefined" != typeof value.propertyIsEnumerable && !value.propertyIsEnumerable("splice")) { | |
return "array"; | |
} | |
if ("[object Function]" == className || "undefined" != typeof value.call && "undefined" != typeof value.propertyIsEnumerable && !value.propertyIsEnumerable("call")) { | |
return "function"; | |
} | |
} else { | |
return "null"; | |
} | |
} else { | |
if ("function" == s && "undefined" == typeof value.call) { | |
return "object"; | |
} | |
} | |
return s; | |
}; | |
goog.isNull = function(val) { | |
return null === val; | |
}; | |
goog.isDefAndNotNull = function(val) { | |
return null != val; | |
}; | |
goog.isArray = function(val) { | |
return "array" == goog.typeOf(val); | |
}; | |
goog.isArrayLike = function(val) { | |
var type = goog.typeOf(val); | |
return "array" == type || "object" == type && "number" == typeof val.length; | |
}; | |
goog.isDateLike = function(val) { | |
return goog.isObject(val) && "function" == typeof val.getFullYear; | |
}; | |
goog.isString = function(val) { | |
return "string" == typeof val; | |
}; | |
goog.isBoolean = function(val) { | |
return "boolean" == typeof val; | |
}; | |
goog.isNumber = function(val) { | |
return "number" == typeof val; | |
}; | |
goog.isFunction = function(val) { | |
return "function" == goog.typeOf(val); | |
}; | |
goog.isObject = function(val) { | |
var type = typeof val; | |
return "object" == type && null != val || "function" == type; | |
}; | |
goog.getUid = function(obj) { | |
return obj[goog.UID_PROPERTY_] || (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_); | |
}; | |
goog.hasUid = function(obj) { | |
return!!obj[goog.UID_PROPERTY_]; | |
}; | |
goog.removeUid = function(obj) { | |
"removeAttribute" in obj && obj.removeAttribute(goog.UID_PROPERTY_); | |
try { | |
delete obj[goog.UID_PROPERTY_]; | |
} catch (ex) { | |
} | |
}; | |
goog.UID_PROPERTY_ = "closure_uid_" + (1E9 * Math.random() >>> 0); | |
goog.uidCounter_ = 0; | |
goog.getHashCode = goog.getUid; | |
goog.removeHashCode = goog.removeUid; | |
goog.cloneObject = function(obj) { | |
var type = goog.typeOf(obj); | |
if ("object" == type || "array" == type) { | |
if (obj.clone) { | |
return obj.clone(); | |
} | |
var clone = "array" == type ? [] : {}, key; | |
for (key in obj) { | |
clone[key] = goog.cloneObject(obj[key]); | |
} | |
return clone; | |
} | |
return obj; | |
}; | |
goog.bindNative_ = function(fn, selfObj, var_args) { | |
return fn.call.apply(fn.bind, arguments); | |
}; | |
goog.bindJs_ = function(fn, selfObj, var_args) { | |
if (!fn) { | |
throw Error(); | |
} | |
if (2 < arguments.length) { | |
var boundArgs = Array.prototype.slice.call(arguments, 2); | |
return function() { | |
var newArgs = Array.prototype.slice.call(arguments); | |
Array.prototype.unshift.apply(newArgs, boundArgs); | |
return fn.apply(selfObj, newArgs); | |
}; | |
} | |
return function() { | |
return fn.apply(selfObj, arguments); | |
}; | |
}; | |
goog.bind = function(fn, selfObj, var_args) { | |
Function.prototype.bind && -1 != Function.prototype.bind.toString().indexOf("native code") ? goog.bind = goog.bindNative_ : goog.bind = goog.bindJs_; | |
return goog.bind.apply(null, arguments); | |
}; | |
goog.partial = function(fn, var_args) { | |
var args = Array.prototype.slice.call(arguments, 1); | |
return function() { | |
var newArgs = args.slice(); | |
newArgs.push.apply(newArgs, arguments); | |
return fn.apply(this, newArgs); | |
}; | |
}; | |
goog.mixin = function(target, source) { | |
for (var x in source) { | |
target[x] = source[x]; | |
} | |
}; | |
goog.now = goog.TRUSTED_SITE && Date.now || function() { | |
return+new Date; | |
}; | |
goog.globalEval = function(script) { | |
if (goog.global.execScript) { | |
goog.global.execScript(script, "JavaScript"); | |
} else { | |
if (goog.global.eval) { | |
if (null == goog.evalWorksForGlobals_ && (goog.global.eval("var _et_ = 1;"), "undefined" != typeof goog.global._et_ ? (delete goog.global._et_, goog.evalWorksForGlobals_ = !0) : goog.evalWorksForGlobals_ = !1), goog.evalWorksForGlobals_) { | |
goog.global.eval(script); | |
} else { | |
var doc = goog.global.document, scriptElt = doc.createElement("script"); | |
scriptElt.type = "text/javascript"; | |
scriptElt.defer = !1; | |
scriptElt.appendChild(doc.createTextNode(script)); | |
doc.body.appendChild(scriptElt); | |
doc.body.removeChild(scriptElt); | |
} | |
} else { | |
throw Error("goog.globalEval not available"); | |
} | |
} | |
}; | |
goog.evalWorksForGlobals_ = null; | |
goog.getCssName = function(className, opt_modifier) { | |
var getMapping = function(cssName) { | |
return goog.cssNameMapping_[cssName] || cssName; | |
}, renameByParts = function(cssName) { | |
for (var parts = cssName.split("-"), mapped = [], i = 0;i < parts.length;i++) { | |
mapped.push(getMapping(parts[i])); | |
} | |
return mapped.join("-"); | |
}, rename; | |
rename = goog.cssNameMapping_ ? "BY_WHOLE" == goog.cssNameMappingStyle_ ? getMapping : renameByParts : function(a) { | |
return a; | |
}; | |
return opt_modifier ? className + "-" + rename(opt_modifier) : rename(className); | |
}; | |
goog.setCssNameMapping = function(mapping, opt_style) { | |
goog.cssNameMapping_ = mapping; | |
goog.cssNameMappingStyle_ = opt_style; | |
}; | |
goog.getMsg = function(str, opt_values) { | |
opt_values && (str = str.replace(/\{\$([^}]+)}/g, function(match, key) { | |
return key in opt_values ? opt_values[key] : match; | |
})); | |
return str; | |
}; | |
goog.getMsgWithFallback = function(a) { | |
return a; | |
}; | |
goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) { | |
goog.exportPath_(publicPath, object, opt_objectToExportTo); | |
}; | |
goog.exportProperty = function(object, publicName, symbol) { | |
object[publicName] = symbol; | |
}; | |
goog.inherits = function(childCtor, parentCtor) { | |
function tempCtor() { | |
} | |
tempCtor.prototype = parentCtor.prototype; | |
childCtor.superClass_ = parentCtor.prototype; | |
childCtor.prototype = new tempCtor; | |
childCtor.prototype.constructor = childCtor; | |
childCtor.base = function(me, methodName, var_args) { | |
var args = Array.prototype.slice.call(arguments, 2); | |
return parentCtor.prototype[methodName].apply(me, args); | |
}; | |
}; | |
goog.base = function(me, opt_methodName, var_args) { | |
var caller = arguments.callee.caller; | |
if (goog.STRICT_MODE_COMPATIBLE || goog.DEBUG && !caller) { | |
throw Error("arguments.caller not defined. goog.base() cannot be used with strict mode code. See http://www.ecma-international.org/ecma-262/5.1/#sec-C"); | |
} | |
if (caller.superClass_) { | |
return caller.superClass_.constructor.apply(me, Array.prototype.slice.call(arguments, 1)); | |
} | |
for (var args = Array.prototype.slice.call(arguments, 2), foundCaller = !1, ctor = me.constructor;ctor;ctor = ctor.superClass_ && ctor.superClass_.constructor) { | |
if (ctor.prototype[opt_methodName] === caller) { | |
foundCaller = !0; | |
} else { | |
if (foundCaller) { | |
return ctor.prototype[opt_methodName].apply(me, args); | |
} | |
} | |
} | |
if (me[opt_methodName] === caller) { | |
return me.constructor.prototype[opt_methodName].apply(me, args); | |
} | |
throw Error("goog.base called from a method of one name to a method of a different name"); | |
}; | |
goog.scope = function(fn) { | |
fn.call(goog.global); | |
}; | |
goog.MODIFY_FUNCTION_PROTOTYPES = !0; | |
goog.MODIFY_FUNCTION_PROTOTYPES && (Function.prototype.bind = Function.prototype.bind || function(selfObj, var_args) { | |
if (1 < arguments.length) { | |
var args = Array.prototype.slice.call(arguments, 1); | |
args.unshift(this, selfObj); | |
return goog.bind.apply(null, args); | |
} | |
return goog.bind(this, selfObj); | |
}, Function.prototype.partial = function(var_args) { | |
var args = Array.prototype.slice.call(arguments); | |
args.unshift(this, null); | |
return goog.bind.apply(null, args); | |
}, Function.prototype.inherits = function(parentCtor) { | |
goog.inherits(this, parentCtor); | |
}, Function.prototype.mixin = function(source) { | |
goog.mixin(this.prototype, source); | |
}); | |
goog.defineClass = function(superClass, def) { | |
var constructor = def.constructor, statics = def.statics; | |
if (!constructor || constructor == Object.prototype.constructor) { | |
throw Error("constructor property is required."); | |
} | |
var cls = goog.defineClass.createSealingConstructor_(constructor); | |
superClass && goog.inherits(cls, superClass); | |
delete def.constructor; | |
delete def.statics; | |
goog.defineClass.applyProperties_(cls.prototype, def); | |
null != statics && (statics instanceof Function ? statics(cls) : goog.defineClass.applyProperties_(cls, statics)); | |
return cls; | |
}; | |
goog.defineClass.SEAL_CLASS_INSTANCES = goog.DEBUG; | |
goog.defineClass.createSealingConstructor_ = function(ctr) { | |
if (goog.defineClass.SEAL_CLASS_INSTANCES && Object.seal instanceof Function) { | |
var wrappedCtr = function() { | |
var instance = ctr.apply(this, arguments) || this; | |
this.constructor === wrappedCtr && Object.seal(instance); | |
return instance; | |
}; | |
return wrappedCtr; | |
} | |
return ctr; | |
}; | |
goog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = "constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "); | |
goog.defineClass.applyProperties_ = function(target, source) { | |
for (var key in source) { | |
Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); | |
} | |
for (var i = 0;i < goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length;i++) { | |
key = goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[i], Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); | |
} | |
}; | |
goog.disposable = {}; | |
goog.disposable.IDisposable = function() { | |
}; | |
goog.Disposable = function() { | |
goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF && (goog.Disposable.instances_[goog.getUid(this)] = this); | |
}; | |
goog.Disposable.MonitoringMode = {OFF:0, PERMANENT:1, INTERACTIVE:2}; | |
goog.Disposable.MONITORING_MODE = 0; | |
goog.Disposable.INCLUDE_STACK_ON_CREATION = !0; | |
goog.Disposable.instances_ = {}; | |
goog.Disposable.getUndisposedObjects = function() { | |
var ret = [], id; | |
for (id in goog.Disposable.instances_) { | |
goog.Disposable.instances_.hasOwnProperty(id) && ret.push(goog.Disposable.instances_[Number(id)]); | |
} | |
return ret; | |
}; | |
goog.Disposable.clearUndisposedObjects = function() { | |
goog.Disposable.instances_ = {}; | |
}; | |
goog.Disposable.prototype.disposed_ = !1; | |
goog.Disposable.prototype.isDisposed = function() { | |
return this.disposed_; | |
}; | |
goog.Disposable.prototype.dispose = function() { | |
if (!this.disposed_ && (this.disposed_ = !0, this.disposeInternal(), goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF)) { | |
var uid = goog.getUid(this); | |
if (goog.Disposable.MONITORING_MODE == goog.Disposable.MonitoringMode.PERMANENT && !goog.Disposable.instances_.hasOwnProperty(uid)) { | |
throw Error(this + " did not call the goog.Disposable base constructor or was disposed of after a clearUndisposedObjects call"); | |
} | |
delete goog.Disposable.instances_[uid]; | |
} | |
}; | |
goog.Disposable.prototype.disposeInternal = function() { | |
if (this.onDisposeCallbacks_) { | |
for (;this.onDisposeCallbacks_.length;) { | |
this.onDisposeCallbacks_.shift()(); | |
} | |
} | |
}; | |
goog.Disposable.isDisposed = function(obj) { | |
return obj && "function" == typeof obj.isDisposed ? obj.isDisposed() : !1; | |
}; | |
goog.dispose = function(obj) { | |
obj && "function" == typeof obj.dispose && obj.dispose(); | |
}; | |
goog.disposeAll = function(var_args) { | |
for (var i = 0, len = arguments.length;i < len;++i) { | |
var disposable = arguments[i]; | |
goog.isArrayLike(disposable) ? goog.disposeAll.apply(null, disposable) : goog.dispose(disposable); | |
} | |
}; | |
goog.debug = {}; | |
goog.debug.Error = function(opt_msg) { | |
if (Error.captureStackTrace) { | |
Error.captureStackTrace(this, goog.debug.Error); | |
} else { | |
var stack = Error().stack; | |
stack && (this.stack = stack); | |
} | |
opt_msg && (this.message = String(opt_msg)); | |
}; | |
goog.inherits(goog.debug.Error, Error); | |
goog.debug.Error.prototype.name = "CustomError"; | |
goog.dom = {}; | |
goog.dom.NodeType = {ELEMENT:1, ATTRIBUTE:2, TEXT:3, CDATA_SECTION:4, ENTITY_REFERENCE:5, ENTITY:6, PROCESSING_INSTRUCTION:7, COMMENT:8, DOCUMENT:9, DOCUMENT_TYPE:10, DOCUMENT_FRAGMENT:11, NOTATION:12}; | |
goog.string = {}; | |
goog.string.DETECT_DOUBLE_ESCAPING = !1; | |
goog.string.Unicode = {NBSP:"\u00a0"}; | |
goog.string.startsWith = function(str) { | |
return 0 == str.lastIndexOf("/", 0); | |
}; | |
goog.string.endsWith = function(str) { | |
var l = str.length - 1; | |
return 0 <= l && str.indexOf("/", l) == l; | |
}; | |
goog.string.caseInsensitiveStartsWith = function(str, prefix) { | |
return 0 == goog.string.caseInsensitiveCompare(prefix, str.substr(0, prefix.length)); | |
}; | |
goog.string.caseInsensitiveEndsWith = function(str, suffix) { | |
return 0 == goog.string.caseInsensitiveCompare(suffix, str.substr(str.length - suffix.length, suffix.length)); | |
}; | |
goog.string.caseInsensitiveEquals = function(str2) { | |
return goog.net.XhrIo.CONTENT_TYPE_HEADER.toLowerCase() == str2.toLowerCase(); | |
}; | |
goog.string.subs = function(str, var_args) { | |
for (var splitParts = str.split("%s"), returnString = "", subsArguments = Array.prototype.slice.call(arguments, 1);subsArguments.length && 1 < splitParts.length;) { | |
returnString += splitParts.shift() + subsArguments.shift(); | |
} | |
return returnString + splitParts.join("%s"); | |
}; | |
goog.string.collapseWhitespace = function(str) { | |
return str.replace(/[\s\xa0]+/g, " ").replace(/^\s+|\s+$/g, ""); | |
}; | |
goog.string.isEmpty = function(str) { | |
return/^[\s\xa0]*$/.test(str); | |
}; | |
goog.string.isEmptySafe = function(str) { | |
return goog.string.isEmpty(goog.string.makeSafe(str)); | |
}; | |
goog.string.isBreakingWhitespace = function(str) { | |
return!/[^\t\n\r ]/.test(str); | |
}; | |
goog.string.isAlpha = function(str) { | |
return!/[^a-zA-Z]/.test(str); | |
}; | |
goog.string.isNumeric = function(str) { | |
return!/[^0-9]/.test(str); | |
}; | |
goog.string.isAlphaNumeric = function(str) { | |
return!/[^a-zA-Z0-9]/.test(str); | |
}; | |
goog.string.isSpace = function(ch) { | |
return " " == ch; | |
}; | |
goog.string.isUnicodeChar = function(ch) { | |
return 1 == ch.length && " " <= ch && "~" >= ch || "\u0080" <= ch && "\ufffd" >= ch; | |
}; | |
goog.string.stripNewlines = function(str) { | |
return str.replace(/(\r\n|\r|\n)+/g, " "); | |
}; | |
goog.string.canonicalizeNewlines = function(str) { | |
return str.replace(/(\r\n|\r|\n)/g, "\n"); | |
}; | |
goog.string.normalizeWhitespace = function(str) { | |
return str.replace(/\xa0|\s/g, " "); | |
}; | |
goog.string.normalizeSpaces = function(str) { | |
return str.replace(/\xa0|[ \t]+/g, " "); | |
}; | |
goog.string.collapseBreakingSpaces = function(str) { | |
return str.replace(/[\t\r\n ]+/g, " ").replace(/^[\t\r\n ]+|[\t\r\n ]+$/g, ""); | |
}; | |
goog.string.trim = function(str) { | |
return str.replace(/^[\s\xa0]+|[\s\xa0]+$/g, ""); | |
}; | |
goog.string.trimLeft = function(str) { | |
return str.replace(/^[\s\xa0]+/, ""); | |
}; | |
goog.string.trimRight = function(str) { | |
return str.replace(/[\s\xa0]+$/, ""); | |
}; | |
goog.string.caseInsensitiveCompare = function(str1, str2) { | |
var test1 = String(str1).toLowerCase(), test2 = String(str2).toLowerCase(); | |
return test1 < test2 ? -1 : test1 == test2 ? 0 : 1; | |
}; | |
goog.string.numerateCompareRegExp_ = /(\.\d+)|(\d+)|(\D+)/g; | |
goog.string.numerateCompare = function(str1, str2) { | |
if (str1 == str2) { | |
return 0; | |
} | |
if (!str1) { | |
return-1; | |
} | |
if (!str2) { | |
return 1; | |
} | |
for (var tokens1 = str1.toLowerCase().match(goog.string.numerateCompareRegExp_), tokens2 = str2.toLowerCase().match(goog.string.numerateCompareRegExp_), count = Math.min(tokens1.length, tokens2.length), i = 0;i < count;i++) { | |
var a = tokens1[i], b = tokens2[i]; | |
if (a != b) { | |
var num1 = parseInt(a, 10); | |
if (!isNaN(num1)) { | |
var num2 = parseInt(b, 10); | |
if (!isNaN(num2) && num1 - num2) { | |
return num1 - num2; | |
} | |
} | |
return a < b ? -1 : 1; | |
} | |
} | |
return tokens1.length != tokens2.length ? tokens1.length - tokens2.length : str1 < str2 ? -1 : 1; | |
}; | |
goog.string.urlEncode = function(str) { | |
return encodeURIComponent(String(str)); | |
}; | |
goog.string.urlDecode = function(str) { | |
return decodeURIComponent(str.replace(/\+/g, " ")); | |
}; | |
goog.string.newLineToBr = function(str, opt_xml) { | |
return str.replace(/(\r\n|\r|\n)/g, opt_xml ? "<br />" : "<br>"); | |
}; | |
goog.string.htmlEscape = function(str) { | |
if (!goog.string.ALL_RE_.test(str)) { | |
return str; | |
} | |
-1 != str.indexOf("&") && (str = str.replace(goog.string.AMP_RE_, "&")); | |
-1 != str.indexOf("<") && (str = str.replace(goog.string.LT_RE_, "<")); | |
-1 != str.indexOf(">") && (str = str.replace(goog.string.GT_RE_, ">")); | |
-1 != str.indexOf('"') && (str = str.replace(goog.string.QUOT_RE_, """)); | |
-1 != str.indexOf("'") && (str = str.replace(goog.string.SINGLE_QUOTE_RE_, "'")); | |
-1 != str.indexOf("\x00") && (str = str.replace(goog.string.NULL_RE_, "�")); | |
goog.string.DETECT_DOUBLE_ESCAPING && -1 != str.indexOf("e") && (str = str.replace(goog.string.E_RE_, "e")); | |
return str; | |
}; | |
goog.string.AMP_RE_ = /&/g; | |
goog.string.LT_RE_ = /</g; | |
goog.string.GT_RE_ = />/g; | |
goog.string.QUOT_RE_ = /"/g; | |
goog.string.SINGLE_QUOTE_RE_ = /'/g; | |
goog.string.NULL_RE_ = /\x00/g; | |
goog.string.E_RE_ = /e/g; | |
goog.string.ALL_RE_ = goog.string.DETECT_DOUBLE_ESCAPING ? /[\x00&<>"'e]/ : /[\x00&<>"']/; | |
goog.string.unescapeEntities = function(str) { | |
return goog.string.contains(str, "&") ? "document" in goog.global ? goog.string.unescapeEntitiesUsingDom_(str) : goog.string.unescapePureXmlEntities_(str) : str; | |
}; | |
goog.string.unescapeEntitiesWithDocument = function(str, document) { | |
return goog.string.contains(str, "&") ? goog.string.unescapeEntitiesUsingDom_(str, document) : str; | |
}; | |
goog.string.unescapeEntitiesUsingDom_ = function(str, opt_document) { | |
var seen = {"&":"&", "<":"<", ">":">", """:'"'}, div; | |
div = opt_document ? opt_document.createElement("div") : goog.global.document.createElement("div"); | |
return str.replace(goog.string.HTML_ENTITY_PATTERN_, function(s, entity) { | |
var value = seen[s]; | |
if (value) { | |
return value; | |
} | |
if ("#" == entity.charAt(0)) { | |
var n = Number("0" + entity.substr(1)); | |
isNaN(n) || (value = String.fromCharCode(n)); | |
} | |
value || (div.innerHTML = s + " ", value = div.firstChild.nodeValue.slice(0, -1)); | |
return seen[s] = value; | |
}); | |
}; | |
goog.string.unescapePureXmlEntities_ = function(str) { | |
return str.replace(/&([^;]+);/g, function(s, entity) { | |
switch(entity) { | |
case "amp": | |
return "&"; | |
case "lt": | |
return "<"; | |
case "gt": | |
return ">"; | |
case "quot": | |
return'"'; | |
default: | |
if ("#" == entity.charAt(0)) { | |
var n = Number("0" + entity.substr(1)); | |
if (!isNaN(n)) { | |
return String.fromCharCode(n); | |
} | |
} | |
return s; | |
} | |
}); | |
}; | |
goog.string.HTML_ENTITY_PATTERN_ = /&([^;\s<&]+);?/g; | |
goog.string.whitespaceEscape = function(str, opt_xml) { | |
return goog.string.newLineToBr(str.replace(/ /g, "  "), opt_xml); | |
}; | |
goog.string.preserveSpaces = function(str) { | |
return str.replace(/(^|[\n ]) /g, "$1" + goog.string.Unicode.NBSP); | |
}; | |
goog.string.stripQuotes = function(str, quoteChars) { | |
for (var length = quoteChars.length, i = 0;i < length;i++) { | |
var quoteChar = 1 == length ? quoteChars : quoteChars.charAt(i); | |
if (str.charAt(0) == quoteChar && str.charAt(str.length - 1) == quoteChar) { | |
return str.substring(1, str.length - 1); | |
} | |
} | |
return str; | |
}; | |
goog.string.truncate = function(str, chars, opt_protectEscapedCharacters) { | |
opt_protectEscapedCharacters && (str = goog.string.unescapeEntities(str)); | |
str.length > chars && (str = str.substring(0, chars - 3) + "..."); | |
opt_protectEscapedCharacters && (str = goog.string.htmlEscape(str)); | |
return str; | |
}; | |
goog.string.truncateMiddle = function(str, chars, opt_protectEscapedCharacters, opt_trailingChars) { | |
opt_protectEscapedCharacters && (str = goog.string.unescapeEntities(str)); | |
if (opt_trailingChars && str.length > chars) { | |
opt_trailingChars > chars && (opt_trailingChars = chars), str = str.substring(0, chars - opt_trailingChars) + "..." + str.substring(str.length - opt_trailingChars); | |
} else { | |
if (str.length > chars) { | |
var half = Math.floor(chars / 2), endPos = str.length - half; | |
str = str.substring(0, half + chars % 2) + "..." + str.substring(endPos); | |
} | |
} | |
opt_protectEscapedCharacters && (str = goog.string.htmlEscape(str)); | |
return str; | |
}; | |
goog.string.specialEscapeChars_ = {"\x00":"\\0", "\b":"\\b", "\f":"\\f", "\n":"\\n", "\r":"\\r", "\t":"\\t", "\x0B":"\\x0B", '"':'\\"', "\\":"\\\\"}; | |
goog.string.jsEscapeCache_ = {"'":"\\'"}; | |
goog.string.quote = function(s) { | |
s = String(s); | |
if (s.quote) { | |
return s.quote(); | |
} | |
for (var sb = ['"'], i = 0;i < s.length;i++) { | |
var ch = s.charAt(i), cc = ch.charCodeAt(0); | |
sb[i + 1] = goog.string.specialEscapeChars_[ch] || (31 < cc && 127 > cc ? ch : goog.string.escapeChar(ch)); | |
} | |
sb.push('"'); | |
return sb.join(""); | |
}; | |
goog.string.escapeString = function(str) { | |
for (var sb = [], i = 0;i < str.length;i++) { | |
sb[i] = goog.string.escapeChar(str.charAt(i)); | |
} | |
return sb.join(""); | |
}; | |
goog.string.escapeChar = function(c) { | |
if (c in goog.string.jsEscapeCache_) { | |
return goog.string.jsEscapeCache_[c]; | |
} | |
if (c in goog.string.specialEscapeChars_) { | |
return goog.string.jsEscapeCache_[c] = goog.string.specialEscapeChars_[c]; | |
} | |
var rv = c, cc = c.charCodeAt(0); | |
if (31 < cc && 127 > cc) { | |
rv = c; | |
} else { | |
if (256 > cc) { | |
if (rv = "\\x", 16 > cc || 256 < cc) { | |
rv += "0"; | |
} | |
} else { | |
rv = "\\u", 4096 > cc && (rv += "0"); | |
} | |
rv += cc.toString(16).toUpperCase(); | |
} | |
return goog.string.jsEscapeCache_[c] = rv; | |
}; | |
goog.string.toMap = function(s) { | |
for (var rv = {}, i = 0;i < s.length;i++) { | |
rv[s.charAt(i)] = !0; | |
} | |
return rv; | |
}; | |
goog.string.contains = function(str, subString) { | |
return-1 != str.indexOf(subString); | |
}; | |
goog.string.caseInsensitiveContains = function() { | |
return goog.string.contains(goog.labs.userAgent.util.getUserAgent().toLowerCase(), "webkit"); | |
}; | |
goog.string.countOf = function(s, ss) { | |
return s && ss ? s.split(ss).length - 1 : 0; | |
}; | |
goog.string.removeAt = function(s, index, stringLength) { | |
var resultStr = s; | |
0 <= index && index < s.length && 0 < stringLength && (resultStr = s.substr(0, index) + s.substr(index + stringLength, s.length - index - stringLength)); | |
return resultStr; | |
}; | |
goog.string.remove = function(s, ss) { | |
var re = new RegExp(goog.string.regExpEscape(ss), ""); | |
return s.replace(re, ""); | |
}; | |
goog.string.removeAll = function(s, ss) { | |
var re = new RegExp(goog.string.regExpEscape(ss), "g"); | |
return s.replace(re, ""); | |
}; | |
goog.string.regExpEscape = function(s) { | |
return String(s).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, "\\$1").replace(/\x08/g, "\\x08"); | |
}; | |
goog.string.repeat = function(string, length) { | |
return Array(length + 1).join(string); | |
}; | |
goog.string.padNumber = function(num, length, opt_precision) { | |
var s = goog.isDef(opt_precision) ? num.toFixed(opt_precision) : String(num), index = s.indexOf("."); | |
-1 == index && (index = s.length); | |
return goog.string.repeat("0", Math.max(0, length - index)) + s; | |
}; | |
goog.string.makeSafe = function(obj) { | |
return null == obj ? "" : String(obj); | |
}; | |
goog.string.buildString = function(var_args) { | |
return Array.prototype.join.call(arguments, ""); | |
}; | |
goog.string.getRandomString = function() { | |
return Math.floor(2147483648 * Math.random()).toString(36) + Math.abs(Math.floor(2147483648 * Math.random()) ^ goog.now()).toString(36); | |
}; | |
goog.string.compareVersions = function(version1, version2) { | |
for (var order = 0, v1Subs = goog.string.trim(String(version1)).split("."), v2Subs = goog.string.trim(String(version2)).split("."), subCount = Math.max(v1Subs.length, v2Subs.length), subIdx = 0;0 == order && subIdx < subCount;subIdx++) { | |
var v1Sub = v1Subs[subIdx] || "", v2Sub = v2Subs[subIdx] || "", v1CompParser = /(\d*)(\D*)/g, v2CompParser = /(\d*)(\D*)/g; | |
do { | |
var v1Comp = v1CompParser.exec(v1Sub) || ["", "", ""], v2Comp = v2CompParser.exec(v2Sub) || ["", "", ""]; | |
if (0 == v1Comp[0].length && 0 == v2Comp[0].length) { | |
break; | |
} | |
order = goog.string.compareElements_(0 == v1Comp[1].length ? 0 : parseInt(v1Comp[1], 10), 0 == v2Comp[1].length ? 0 : parseInt(v2Comp[1], 10)) || goog.string.compareElements_(0 == v1Comp[2].length, 0 == v2Comp[2].length) || goog.string.compareElements_(v1Comp[2], v2Comp[2]); | |
} while (0 == order); | |
} | |
return order; | |
}; | |
goog.string.compareElements_ = function(left, right) { | |
return left < right ? -1 : left > right ? 1 : 0; | |
}; | |
goog.string.HASHCODE_MAX_ = 4294967296; | |
goog.string.hashCode = function(str) { | |
for (var result = 0, i = 0;i < str.length;++i) { | |
result = 31 * result + str.charCodeAt(i), result %= goog.string.HASHCODE_MAX_; | |
} | |
return result; | |
}; | |
goog.string.uniqueStringCounter_ = 2147483648 * Math.random() | 0; | |
goog.string.createUniqueString = function() { | |
return "goog_" + goog.string.uniqueStringCounter_++; | |
}; | |
goog.string.toNumber = function(str) { | |
var num = Number(str); | |
return 0 == num && goog.string.isEmpty(str) ? NaN : num; | |
}; | |
goog.string.isLowerCamelCase = function(str) { | |
return/^[a-z]+([A-Z][a-z]*)*$/.test(str); | |
}; | |
goog.string.isUpperCamelCase = function(str) { | |
return/^([A-Z][a-z]*)+$/.test(str); | |
}; | |
goog.string.toCamelCase = function(str) { | |
return String(str).replace(/\-([a-z])/g, function(all, match) { | |
return match.toUpperCase(); | |
}); | |
}; | |
goog.string.toSelectorCase = function(str) { | |
return String(str).replace(/([A-Z])/g, "-$1").toLowerCase(); | |
}; | |
goog.string.toTitleCase = function(str, opt_delimiters) { | |
var delimiters = goog.isString(opt_delimiters) ? goog.string.regExpEscape(opt_delimiters) : "\\s"; | |
return str.replace(new RegExp("(^" + (delimiters ? "|[" + delimiters + "]+" : "") + ")([a-z])", "g"), function(all, p1, p2) { | |
return p1 + p2.toUpperCase(); | |
}); | |
}; | |
goog.string.parseInt = function(value) { | |
isFinite(value) && (value = String(value)); | |
return goog.isString(value) ? /^\s*-?0x/i.test(value) ? parseInt(value, 16) : parseInt(value, 10) : NaN; | |
}; | |
goog.string.splitLimit = function(str, separator, limit) { | |
for (var parts = str.split(separator), returnVal = [];0 < limit && parts.length;) { | |
returnVal.push(parts.shift()), limit--; | |
} | |
parts.length && returnVal.push(parts.join(separator)); | |
return returnVal; | |
}; | |
goog.asserts = {}; | |
goog.asserts.ENABLE_ASSERTS = goog.DEBUG; | |
goog.asserts.AssertionError = function(messagePattern, messageArgs) { | |
messageArgs.unshift(messagePattern); | |
goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs)); | |
messageArgs.shift(); | |
}; | |
goog.inherits(goog.asserts.AssertionError, goog.debug.Error); | |
goog.asserts.AssertionError.prototype.name = "AssertionError"; | |
goog.asserts.DEFAULT_ERROR_HANDLER = function(e) { | |
throw e; | |
}; | |
goog.asserts.errorHandler_ = goog.asserts.DEFAULT_ERROR_HANDLER; | |
goog.asserts.doAssertFailure_ = function(defaultMessage, defaultArgs, givenMessage, givenArgs) { | |
var message = "Assertion failed"; | |
if (givenMessage) { | |
var message = message + (": " + givenMessage), args = givenArgs | |
} else { | |
defaultMessage && (message += ": " + defaultMessage, args = defaultArgs); | |
} | |
var e = new goog.asserts.AssertionError("" + message, args || []); | |
goog.asserts.errorHandler_(e); | |
}; | |
goog.asserts.setErrorHandler = function(errorHandler) { | |
goog.asserts.ENABLE_ASSERTS && (goog.asserts.errorHandler_ = errorHandler); | |
}; | |
goog.asserts.assert = function(condition, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !condition && goog.asserts.doAssertFailure_("", null, opt_message, Array.prototype.slice.call(arguments, 2)); | |
return condition; | |
}; | |
goog.asserts.fail = function(opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && goog.asserts.errorHandler_(new goog.asserts.AssertionError("Failure" + (opt_message ? ": " + opt_message : ""), Array.prototype.slice.call(arguments, 1))); | |
}; | |
goog.asserts.assertNumber = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value) && goog.asserts.doAssertFailure_("Expected number but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
}; | |
goog.asserts.assertString = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isString(value) && goog.asserts.doAssertFailure_("Expected string but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
return value; | |
}; | |
goog.asserts.assertFunction = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value) && goog.asserts.doAssertFailure_("Expected function but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
return value; | |
}; | |
goog.asserts.assertObject = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isObject(value) && goog.asserts.doAssertFailure_("Expected object but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
return value; | |
}; | |
goog.asserts.assertArray = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isArray(value) && goog.asserts.doAssertFailure_("Expected array but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
}; | |
goog.asserts.assertBoolean = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value) && goog.asserts.doAssertFailure_("Expected boolean but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
return value; | |
}; | |
goog.asserts.assertElement = function(value, opt_message, var_args) { | |
!goog.asserts.ENABLE_ASSERTS || goog.isObject(value) && value.nodeType == goog.dom.NodeType.ELEMENT || goog.asserts.doAssertFailure_("Expected Element but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
return value; | |
}; | |
goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) { | |
!goog.asserts.ENABLE_ASSERTS || value instanceof type || goog.asserts.doAssertFailure_("instanceof check failed.", null, opt_message, Array.prototype.slice.call(arguments, 3)); | |
return value; | |
}; | |
goog.asserts.assertObjectPrototypeIsIntact = function() { | |
for (var key in Object.prototype) { | |
goog.asserts.fail(key + " should not be enumerable in Object.prototype."); | |
} | |
}; | |
goog.object = {}; | |
goog.object.forEach = function(obj, f, opt_obj) { | |
for (var key in obj) { | |
f.call(opt_obj, obj[key], key, obj); | |
} | |
}; | |
goog.object.filter = function(obj, f, opt_obj) { | |
var res = {}, key; | |
for (key in obj) { | |
f.call(opt_obj, obj[key], key, obj) && (res[key] = obj[key]); | |
} | |
return res; | |
}; | |
goog.object.map = function(obj, f, opt_obj) { | |
var res = {}, key; | |
for (key in obj) { | |
res[key] = f.call(opt_obj, obj[key], key, obj); | |
} | |
return res; | |
}; | |
goog.object.some = function(obj, f, opt_obj) { | |
for (var key in obj) { | |
if (f.call(opt_obj, obj[key], key, obj)) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
goog.object.every = function(obj, f, opt_obj) { | |
for (var key in obj) { | |
if (!f.call(opt_obj, obj[key], key, obj)) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.object.getCount = function(obj) { | |
var rv = 0, key; | |
for (key in obj) { | |
rv++; | |
} | |
return rv; | |
}; | |
goog.object.getAnyKey = function(obj) { | |
for (var key in obj) { | |
return key; | |
} | |
}; | |
goog.object.getAnyValue = function(obj) { | |
for (var key in obj) { | |
return obj[key]; | |
} | |
}; | |
goog.object.contains = function(obj, val) { | |
return goog.object.containsValue(obj, val); | |
}; | |
goog.object.getValues = function(obj) { | |
var res = [], i = 0, key; | |
for (key in obj) { | |
res[i++] = obj[key]; | |
} | |
return res; | |
}; | |
goog.object.getKeys = function(obj) { | |
var res = [], i = 0, key; | |
for (key in obj) { | |
res[i++] = key; | |
} | |
return res; | |
}; | |
goog.object.getValueByKeys = function(obj, var_args) { | |
for (var isArrayLike = goog.isArrayLike(var_args), keys = isArrayLike ? var_args : arguments, i = isArrayLike ? 0 : 1;i < keys.length && (obj = obj[keys[i]], goog.isDef(obj));i++) { | |
} | |
return obj; | |
}; | |
goog.object.containsKey = function(obj, key) { | |
return key in obj; | |
}; | |
goog.object.containsValue = function(obj, val) { | |
for (var key in obj) { | |
if (obj[key] == val) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
goog.object.findKey = function(obj, f, opt_this) { | |
for (var key in obj) { | |
if (f.call(opt_this, obj[key], key, obj)) { | |
return key; | |
} | |
} | |
}; | |
goog.object.findValue = function(obj, f, opt_this) { | |
var key = goog.object.findKey(obj, f, opt_this); | |
return key && obj[key]; | |
}; | |
goog.object.isEmpty = function(obj) { | |
for (var key in obj) { | |
return!1; | |
} | |
return!0; | |
}; | |
goog.object.clear = function(obj) { | |
for (var i in obj) { | |
delete obj[i]; | |
} | |
}; | |
goog.object.remove = function(obj, key) { | |
var rv; | |
(rv = key in obj) && delete obj[key]; | |
return rv; | |
}; | |
goog.object.add = function(obj, key, val) { | |
if (key in obj) { | |
throw Error('The object already contains the key "' + key + '"'); | |
} | |
goog.object.set(obj, key, val); | |
}; | |
goog.object.get = function(obj, key, opt_val) { | |
return key in obj ? obj[key] : opt_val; | |
}; | |
goog.object.set = function(obj, key, value) { | |
obj[key] = value; | |
}; | |
goog.object.setIfUndefined = function(obj, key, value) { | |
return key in obj ? obj[key] : obj[key] = value; | |
}; | |
goog.object.clone = function(obj) { | |
var res = {}, key; | |
for (key in obj) { | |
res[key] = obj[key]; | |
} | |
return res; | |
}; | |
goog.object.unsafeClone = function(obj) { | |
var type = goog.typeOf(obj); | |
if ("object" == type || "array" == type) { | |
if (obj.clone) { | |
return obj.clone(); | |
} | |
var clone = "array" == type ? [] : {}, key; | |
for (key in obj) { | |
clone[key] = goog.object.unsafeClone(obj[key]); | |
} | |
return clone; | |
} | |
return obj; | |
}; | |
goog.object.transpose = function(obj) { | |
var transposed = {}, key; | |
for (key in obj) { | |
transposed[obj[key]] = key; | |
} | |
return transposed; | |
}; | |
goog.object.PROTOTYPE_FIELDS_ = "constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "); | |
goog.object.extend = function(target, var_args) { | |
for (var key, source, i = 1;i < arguments.length;i++) { | |
source = arguments[i]; | |
for (key in source) { | |
target[key] = source[key]; | |
} | |
for (var j = 0;j < goog.object.PROTOTYPE_FIELDS_.length;j++) { | |
key = goog.object.PROTOTYPE_FIELDS_[j], Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); | |
} | |
} | |
}; | |
goog.object.create = function(var_args) { | |
var argLength = arguments.length; | |
if (1 == argLength && goog.isArray(arguments[0])) { | |
return goog.object.create.apply(null, arguments[0]); | |
} | |
if (argLength % 2) { | |
throw Error("Uneven number of arguments"); | |
} | |
for (var rv = {}, i = 0;i < argLength;i += 2) { | |
rv[arguments[i]] = arguments[i + 1]; | |
} | |
return rv; | |
}; | |
goog.object.createSet = function(var_args) { | |
var argLength = arguments.length; | |
if (1 == argLength && goog.isArray(arguments[0])) { | |
return goog.object.createSet.apply(null, arguments[0]); | |
} | |
for (var rv = {}, i = 0;i < argLength;i++) { | |
rv[arguments[i]] = !0; | |
} | |
return rv; | |
}; | |
goog.object.createImmutableView = function(obj) { | |
var result = obj; | |
Object.isFrozen && !Object.isFrozen(obj) && (result = Object.create(obj), Object.freeze(result)); | |
return result; | |
}; | |
goog.object.isImmutableView = function(obj) { | |
return!!Object.isFrozen && Object.isFrozen(obj); | |
}; | |
goog.events = {}; | |
goog.events.EventId = function(eventId) { | |
this.id = eventId; | |
}; | |
goog.events.EventId.prototype.toString = function() { | |
return this.id; | |
}; | |
goog.events.Event = function(type, opt_target) { | |
this.type = type instanceof goog.events.EventId ? String(type) : type; | |
this.currentTarget = this.target = opt_target; | |
this.defaultPrevented = this.propagationStopped_ = !1; | |
this.returnValue_ = !0; | |
}; | |
goog.events.Event.prototype.disposeInternal = function() { | |
}; | |
goog.events.Event.prototype.dispose = function() { | |
}; | |
goog.events.Event.prototype.stopPropagation = function() { | |
this.propagationStopped_ = !0; | |
}; | |
goog.events.Event.prototype.preventDefault = function() { | |
this.defaultPrevented = !0; | |
this.returnValue_ = !1; | |
}; | |
goog.events.Event.stopPropagation = function(e) { | |
e.stopPropagation(); | |
}; | |
goog.events.Event.preventDefault = function(e) { | |
e.preventDefault(); | |
}; | |
goog.debug.entryPointRegistry = {}; | |
goog.debug.EntryPointMonitor = function() { | |
}; | |
goog.debug.entryPointRegistry.refList_ = []; | |
goog.debug.entryPointRegistry.monitors_ = []; | |
goog.debug.entryPointRegistry.monitorsMayExist_ = !1; | |
goog.debug.entryPointRegistry.register = function(callback) { | |
goog.debug.entryPointRegistry.refList_[goog.debug.entryPointRegistry.refList_.length] = callback; | |
if (goog.debug.entryPointRegistry.monitorsMayExist_) { | |
for (var monitors = goog.debug.entryPointRegistry.monitors_, i = 0;i < monitors.length;i++) { | |
callback(goog.bind(monitors[i].wrap, monitors[i])); | |
} | |
} | |
}; | |
goog.debug.entryPointRegistry.monitorAll = function(monitor) { | |
goog.debug.entryPointRegistry.monitorsMayExist_ = !0; | |
for (var transformer = goog.bind(monitor.wrap, monitor), i = 0;i < goog.debug.entryPointRegistry.refList_.length;i++) { | |
goog.debug.entryPointRegistry.refList_[i](transformer); | |
} | |
goog.debug.entryPointRegistry.monitors_.push(monitor); | |
}; | |
goog.debug.entryPointRegistry.unmonitorAllIfPossible = function(monitor) { | |
var monitors = goog.debug.entryPointRegistry.monitors_; | |
goog.asserts.assert(monitor == monitors[monitors.length - 1], "Only the most recent monitor can be unwrapped."); | |
for (var transformer = goog.bind(monitor.unwrap, monitor), i = 0;i < goog.debug.entryPointRegistry.refList_.length;i++) { | |
goog.debug.entryPointRegistry.refList_[i](transformer); | |
} | |
monitors.length--; | |
}; | |
goog.reflect = {}; | |
goog.reflect.object = function(type, object) { | |
return object; | |
}; | |
goog.reflect.sinkValue = function(x) { | |
goog.reflect.sinkValue[" "](x); | |
return x; | |
}; | |
goog.reflect.sinkValue[" "] = goog.nullFunction; | |
goog.reflect.canAccessProperty = function(obj) { | |
try { | |
return goog.reflect.sinkValue(obj.nodeName), !0; | |
} catch (e) { | |
} | |
return!1; | |
}; | |
goog.array = {}; | |
goog.NATIVE_ARRAY_PROTOTYPES = goog.TRUSTED_SITE; | |
goog.array.ASSUME_NATIVE_FUNCTIONS = !1; | |
goog.array.peek = function(array) { | |
return array[array.length - 1]; | |
}; | |
goog.array.last = goog.array.peek; | |
goog.array.ARRAY_PROTOTYPE_ = Array.prototype; | |
goog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.indexOf) ? function(arr, obj, opt_fromIndex) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.indexOf.call(arr, obj, opt_fromIndex); | |
} : function(arr, obj, opt_fromIndex) { | |
var fromIndex = null == opt_fromIndex ? 0 : 0 > opt_fromIndex ? Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex; | |
if (goog.isString(arr)) { | |
return goog.isString(obj) && 1 == obj.length ? arr.indexOf(obj, fromIndex) : -1; | |
} | |
for (var i = fromIndex;i < arr.length;i++) { | |
if (i in arr && arr[i] === obj) { | |
return i; | |
} | |
} | |
return-1; | |
}; | |
goog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.lastIndexOf) ? function(arr, obj, opt_fromIndex) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.lastIndexOf.call(arr, obj, null == opt_fromIndex ? arr.length - 1 : opt_fromIndex); | |
} : function(arr, obj, opt_fromIndex) { | |
var fromIndex = null == opt_fromIndex ? arr.length - 1 : opt_fromIndex; | |
0 > fromIndex && (fromIndex = Math.max(0, arr.length + fromIndex)); | |
if (goog.isString(arr)) { | |
return goog.isString(obj) && 1 == obj.length ? arr.lastIndexOf(obj, fromIndex) : -1; | |
} | |
for (var i = fromIndex;0 <= i;i--) { | |
if (i in arr && arr[i] === obj) { | |
return i; | |
} | |
} | |
return-1; | |
}; | |
goog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.forEach) ? function(arr, f, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
goog.array.ARRAY_PROTOTYPE_.forEach.call(arr, f, opt_obj); | |
} : function(arr, f, opt_obj) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
i in arr2 && f.call(opt_obj, arr2[i], i, arr); | |
} | |
}; | |
goog.array.forEachRight = function(arr, f) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = l - 1;0 <= i;--i) { | |
i in arr2 && f.call(void 0, arr2[i], i, arr); | |
} | |
}; | |
goog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.filter) ? function(arr, f, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.filter.call(arr, f, opt_obj); | |
} : function(arr, f, opt_obj) { | |
for (var l = arr.length, res = [], resLength = 0, arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
if (i in arr2) { | |
var val = arr2[i]; | |
f.call(opt_obj, val, i, arr) && (res[resLength++] = val); | |
} | |
} | |
return res; | |
}; | |
goog.array.map = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.map) ? function(arr, f, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.map.call(arr, f, opt_obj); | |
} : function(arr, f, opt_obj) { | |
for (var l = arr.length, res = Array(l), arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
i in arr2 && (res[i] = f.call(opt_obj, arr2[i], i, arr)); | |
} | |
return res; | |
}; | |
goog.array.reduce = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.reduce) ? function(arr, f, val, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
opt_obj && (f = goog.bind(f, opt_obj)); | |
return goog.array.ARRAY_PROTOTYPE_.reduce.call(arr, f, val); | |
} : function(arr, f, val$$0, opt_obj) { | |
var rval = val$$0; | |
goog.array.forEach(arr, function(val, index) { | |
rval = f.call(opt_obj, rval, val, index, arr); | |
}); | |
return rval; | |
}; | |
goog.array.reduceRight = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.reduceRight) ? function(arr, f, val, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
opt_obj && (f = goog.bind(f, opt_obj)); | |
return goog.array.ARRAY_PROTOTYPE_.reduceRight.call(arr, f, val); | |
} : function(arr, f, val$$0, opt_obj) { | |
var rval = val$$0; | |
goog.array.forEachRight(arr, function(val, index) { | |
rval = f.call(opt_obj, rval, val, index, arr); | |
}); | |
return rval; | |
}; | |
goog.array.some = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.some) ? function(arr, f, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.some.call(arr, f, opt_obj); | |
} : function(arr, f, opt_obj) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
goog.array.every = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.every) ? function(arr, f, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.every.call(arr, f, opt_obj); | |
} : function(arr, f, opt_obj) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.array.count = function(arr$$0, f, opt_obj) { | |
var count = 0; | |
goog.array.forEach(arr$$0, function(element, index, arr) { | |
f.call(opt_obj, element, index, arr) && ++count; | |
}, opt_obj); | |
return count; | |
}; | |
goog.array.find = function(arr, f, opt_obj) { | |
var i = goog.array.findIndex(arr, f, opt_obj); | |
return 0 > i ? null : goog.isString(arr) ? arr.charAt(i) : arr[i]; | |
}; | |
goog.array.findIndex = function(arr, f, opt_obj) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { | |
return i; | |
} | |
} | |
return-1; | |
}; | |
goog.array.findRight = function(arr, f, opt_obj) { | |
var i = goog.array.findIndexRight(arr, f, opt_obj); | |
return 0 > i ? null : goog.isString(arr) ? arr.charAt(i) : arr[i]; | |
}; | |
goog.array.findIndexRight = function(arr, f, opt_obj) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = l - 1;0 <= i;i--) { | |
if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { | |
return i; | |
} | |
} | |
return-1; | |
}; | |
goog.array.contains = function(arr, obj) { | |
return 0 <= goog.array.indexOf(arr, obj); | |
}; | |
goog.array.isEmpty = function(arr) { | |
return 0 == arr.length; | |
}; | |
goog.array.clear = function(arr) { | |
if (!goog.isArray(arr)) { | |
for (var i = arr.length - 1;0 <= i;i--) { | |
delete arr[i]; | |
} | |
} | |
arr.length = 0; | |
}; | |
goog.array.insert = function(arr, obj) { | |
goog.array.contains(arr, obj) || arr.push(obj); | |
}; | |
goog.array.insertAt = function(arr, obj, opt_i) { | |
goog.array.splice(arr, opt_i, 0, obj); | |
}; | |
goog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) { | |
goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd); | |
}; | |
goog.array.insertBefore = function(arr, obj, opt_obj2) { | |
var i; | |
2 == arguments.length || 0 > (i = goog.array.indexOf(arr, opt_obj2)) ? arr.push(obj) : goog.array.insertAt(arr, obj, i); | |
}; | |
goog.array.remove = function(arr, obj) { | |
var i = goog.array.indexOf(arr, obj), rv; | |
(rv = 0 <= i) && goog.array.removeAt(arr, i); | |
return rv; | |
}; | |
goog.array.removeAt = function(arr, i) { | |
goog.asserts.assert(null != arr.length); | |
return 1 == goog.array.ARRAY_PROTOTYPE_.splice.call(arr, i, 1).length; | |
}; | |
goog.array.removeIf = function(arr, f, opt_obj) { | |
var i = goog.array.findIndex(arr, f, opt_obj); | |
return 0 <= i ? (goog.array.removeAt(arr, i), !0) : !1; | |
}; | |
goog.array.concat = function(var_args) { | |
return goog.array.ARRAY_PROTOTYPE_.concat.apply(goog.array.ARRAY_PROTOTYPE_, arguments); | |
}; | |
goog.array.join = function(var_args) { | |
return goog.array.ARRAY_PROTOTYPE_.concat.apply(goog.array.ARRAY_PROTOTYPE_, arguments); | |
}; | |
goog.array.toArray = function(object) { | |
var length = object.length; | |
if (0 < length) { | |
for (var rv = Array(length), i = 0;i < length;i++) { | |
rv[i] = object[i]; | |
} | |
return rv; | |
} | |
return[]; | |
}; | |
goog.array.clone = goog.array.toArray; | |
goog.array.extend = function(arr1, var_args) { | |
for (var i = 1;i < arguments.length;i++) { | |
var arr2 = arguments[i], isArrayLike; | |
if (goog.isArray(arr2) || (isArrayLike = goog.isArrayLike(arr2)) && Object.prototype.hasOwnProperty.call(arr2, "callee")) { | |
arr1.push.apply(arr1, arr2); | |
} else { | |
if (isArrayLike) { | |
for (var len1 = arr1.length, len2 = arr2.length, j = 0;j < len2;j++) { | |
arr1[len1 + j] = arr2[j]; | |
} | |
} else { | |
arr1.push(arr2); | |
} | |
} | |
} | |
}; | |
goog.array.splice = function(arr, index, howMany, var_args) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.splice.apply(arr, goog.array.slice(arguments, 1)); | |
}; | |
goog.array.slice = function(arr, start, opt_end) { | |
goog.asserts.assert(null != arr.length); | |
return 2 >= arguments.length ? goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start) : goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start, opt_end); | |
}; | |
goog.array.removeDuplicates = function(arr, opt_rv) { | |
for (var returnArray = opt_rv || arr, hashFn = function() { | |
return goog.isObject(current) ? "o" + goog.getUid(current) : (typeof current).charAt(0) + current; | |
}, seen = {}, cursorInsert = 0, cursorRead = 0;cursorRead < arr.length;) { | |
var current = arr[cursorRead++], key = hashFn(); | |
Object.prototype.hasOwnProperty.call(seen, key) || (seen[key] = !0, returnArray[cursorInsert++] = current); | |
} | |
returnArray.length = cursorInsert; | |
}; | |
goog.array.binarySearch = function(arr, target, opt_compareFn) { | |
return goog.array.binarySearch_(arr, opt_compareFn || goog.array.defaultCompare, !1, target); | |
}; | |
goog.array.binarySelect = function(arr, evaluator, opt_obj) { | |
return goog.array.binarySearch_(arr, evaluator, !0, void 0, opt_obj); | |
}; | |
goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target, opt_selfObj) { | |
for (var left = 0, right = arr.length, found;left < right;) { | |
var middle = left + right >> 1, compareResult; | |
compareResult = isEvaluator ? compareFn.call(opt_selfObj, arr[middle], middle, arr) : compareFn(opt_target, arr[middle]); | |
0 < compareResult ? left = middle + 1 : (right = middle, found = !compareResult); | |
} | |
return found ? left : ~left; | |
}; | |
goog.array.sort = function(arr, opt_compareFn) { | |
arr.sort(opt_compareFn || goog.array.defaultCompare); | |
}; | |
goog.array.stableSort = function(arr, opt_compareFn) { | |
for (var i = 0;i < arr.length;i++) { | |
arr[i] = {index:i, value:arr[i]}; | |
} | |
var valueCompareFn = opt_compareFn || goog.array.defaultCompare; | |
goog.array.sort(arr, function(obj1, obj2) { | |
return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index; | |
}); | |
for (i = 0;i < arr.length;i++) { | |
arr[i] = arr[i].value; | |
} | |
}; | |
goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) { | |
var compare = opt_compareFn || goog.array.defaultCompare; | |
goog.array.sort(arr, function(a, b) { | |
return compare(a[key], b[key]); | |
}); | |
}; | |
goog.array.isSorted = function(arr) { | |
for (var compare = goog.array.defaultCompare, i = 1;i < arr.length;i++) { | |
if (0 < compare(arr[i - 1], arr[i])) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.array.equals = function(arr1, arr2, opt_equalsFn) { | |
if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || arr1.length != arr2.length) { | |
return!1; | |
} | |
for (var l = arr1.length, equalsFn = opt_equalsFn || goog.array.defaultCompareEquality, i = 0;i < l;i++) { | |
if (!equalsFn(arr1[i], arr2[i])) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.array.compare3 = function(arr1, arr2, opt_compareFn) { | |
for (var compare = opt_compareFn || goog.array.defaultCompare, l = Math.min(arr1.length, arr2.length), i = 0;i < l;i++) { | |
var result = compare(arr1[i], arr2[i]); | |
if (0 != result) { | |
return result; | |
} | |
} | |
return goog.array.defaultCompare(arr1.length, arr2.length); | |
}; | |
goog.array.defaultCompare = function(a, b) { | |
return a > b ? 1 : a < b ? -1 : 0; | |
}; | |
goog.array.defaultCompareEquality = function(a, b) { | |
return a === b; | |
}; | |
goog.array.binaryInsert = function(array, value, opt_compareFn) { | |
var index = goog.array.binarySearch(array, value, opt_compareFn); | |
return 0 > index ? (goog.array.insertAt(array, value, -(index + 1)), !0) : !1; | |
}; | |
goog.array.binaryRemove = function(array, value, opt_compareFn) { | |
var index = goog.array.binarySearch(array, value, opt_compareFn); | |
return 0 <= index ? goog.array.removeAt(array, index) : !1; | |
}; | |
goog.array.bucket = function(array, sorter, opt_obj) { | |
for (var buckets = {}, i = 0;i < array.length;i++) { | |
var value = array[i], key = sorter.call(opt_obj, value, i, array); | |
goog.isDef(key) && (buckets[key] || (buckets[key] = [])).push(value); | |
} | |
return buckets; | |
}; | |
goog.array.toObject = function(arr, keyFunc, opt_obj) { | |
var ret = {}; | |
goog.array.forEach(arr, function(element, index) { | |
ret[keyFunc.call(opt_obj, element, index, arr)] = element; | |
}); | |
return ret; | |
}; | |
goog.array.range = function(startOrEnd, opt_end, opt_step) { | |
var array = [], start = 0, end = startOrEnd, step = opt_step || 1; | |
void 0 !== opt_end && (start = startOrEnd, end = opt_end); | |
if (0 > step * (end - start)) { | |
return[]; | |
} | |
if (0 < step) { | |
for (var i = start;i < end;i += step) { | |
array.push(i); | |
} | |
} else { | |
for (i = start;i > end;i += step) { | |
array.push(i); | |
} | |
} | |
return array; | |
}; | |
goog.array.repeat = function(value, n) { | |
for (var array = [], i = 0;i < n;i++) { | |
array[i] = value; | |
} | |
return array; | |
}; | |
goog.array.flatten = function(var_args) { | |
for (var result = [], i = 0;i < arguments.length;i++) { | |
var element = arguments[i]; | |
goog.isArray(element) ? result.push.apply(result, goog.array.flatten.apply(null, element)) : result.push(element); | |
} | |
return result; | |
}; | |
goog.array.rotate = function(array, n) { | |
goog.asserts.assert(null != array.length); | |
array.length && (n %= array.length, 0 < n ? goog.array.ARRAY_PROTOTYPE_.unshift.apply(array, array.splice(-n, n)) : 0 > n && goog.array.ARRAY_PROTOTYPE_.push.apply(array, array.splice(0, -n))); | |
return array; | |
}; | |
goog.array.moveItem = function(arr, fromIndex, toIndex) { | |
goog.asserts.assert(0 <= fromIndex && fromIndex < arr.length); | |
goog.asserts.assert(0 <= toIndex && toIndex < arr.length); | |
var removedItems = goog.array.ARRAY_PROTOTYPE_.splice.call(arr, fromIndex, 1); | |
goog.array.ARRAY_PROTOTYPE_.splice.call(arr, toIndex, 0, removedItems[0]); | |
}; | |
goog.array.zip = function(var_args) { | |
if (!arguments.length) { | |
return[]; | |
} | |
for (var result = [], i = 0;;i++) { | |
for (var value = [], j = 0;j < arguments.length;j++) { | |
var arr = arguments[j]; | |
if (i >= arr.length) { | |
return result; | |
} | |
value.push(arr[i]); | |
} | |
result.push(value); | |
} | |
}; | |
goog.array.shuffle = function(arr, opt_randFn) { | |
for (var randFn = opt_randFn || Math.random, i = arr.length - 1;0 < i;i--) { | |
var j = Math.floor(randFn() * (i + 1)), tmp = arr[i]; | |
arr[i] = arr[j]; | |
arr[j] = tmp; | |
} | |
}; | |
goog.labs = {}; | |
goog.labs.userAgent = {}; | |
goog.labs.userAgent.util = {}; | |
goog.labs.userAgent.util.getNativeUserAgentString_ = function() { | |
var navigator = goog.labs.userAgent.util.getNavigator_(); | |
if (navigator) { | |
var userAgent = navigator.userAgent; | |
if (userAgent) { | |
return userAgent; | |
} | |
} | |
return ""; | |
}; | |
goog.labs.userAgent.util.getNavigator_ = function() { | |
return goog.global.navigator; | |
}; | |
goog.labs.userAgent.util.userAgent_ = goog.labs.userAgent.util.getNativeUserAgentString_(); | |
goog.labs.userAgent.util.setUserAgent = function(opt_userAgent) { | |
goog.labs.userAgent.util.userAgent_ = opt_userAgent || goog.labs.userAgent.util.getNativeUserAgentString_(); | |
}; | |
goog.labs.userAgent.util.getUserAgent = function() { | |
return goog.labs.userAgent.util.userAgent_; | |
}; | |
goog.labs.userAgent.util.matchUserAgent = function(str) { | |
return goog.string.contains(goog.labs.userAgent.util.getUserAgent(), str); | |
}; | |
goog.labs.userAgent.util.matchUserAgentIgnoreCase = function() { | |
return goog.string.caseInsensitiveContains(); | |
}; | |
goog.labs.userAgent.util.extractVersionTuples = function(userAgent) { | |
for (var versionRegExp = /(\w[\w ]+)\/([^\s]+)\s*(?:\((.*?)\))?/g, data = [], match;match = versionRegExp.exec(userAgent);) { | |
data.push([match[1], match[2], match[3] || void 0]); | |
} | |
return data; | |
}; | |
goog.labs.userAgent.browser = {}; | |
goog.labs.userAgent.browser.matchOpera_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Opera") || goog.labs.userAgent.util.matchUserAgent("OPR"); | |
}; | |
goog.labs.userAgent.browser.matchIE_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Trident") || goog.labs.userAgent.util.matchUserAgent("MSIE"); | |
}; | |
goog.labs.userAgent.browser.matchFirefox_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Firefox"); | |
}; | |
goog.labs.userAgent.browser.matchSafari_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Safari") && !goog.labs.userAgent.util.matchUserAgent("Chrome") && !goog.labs.userAgent.util.matchUserAgent("CriOS") && !goog.labs.userAgent.util.matchUserAgent("Android"); | |
}; | |
goog.labs.userAgent.browser.matchChrome_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Chrome") || goog.labs.userAgent.util.matchUserAgent("CriOS"); | |
}; | |
goog.labs.userAgent.browser.matchAndroidBrowser_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Android") && !goog.labs.userAgent.util.matchUserAgent("Chrome") && !goog.labs.userAgent.util.matchUserAgent("CriOS"); | |
}; | |
goog.labs.userAgent.browser.isOpera = goog.labs.userAgent.browser.matchOpera_; | |
goog.labs.userAgent.browser.isIE = goog.labs.userAgent.browser.matchIE_; | |
goog.labs.userAgent.browser.isFirefox = goog.labs.userAgent.browser.matchFirefox_; | |
goog.labs.userAgent.browser.isSafari = goog.labs.userAgent.browser.matchSafari_; | |
goog.labs.userAgent.browser.isChrome = goog.labs.userAgent.browser.matchChrome_; | |
goog.labs.userAgent.browser.isAndroidBrowser = goog.labs.userAgent.browser.matchAndroidBrowser_; | |
goog.labs.userAgent.browser.isSilk = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Silk"); | |
}; | |
goog.labs.userAgent.browser.getVersion = function() { | |
var userAgentString = goog.labs.userAgent.util.getUserAgent(); | |
if (goog.labs.userAgent.browser.isIE()) { | |
return goog.labs.userAgent.browser.getIEVersion_(userAgentString); | |
} | |
if (goog.labs.userAgent.browser.isOpera()) { | |
return goog.labs.userAgent.browser.getOperaVersion_(userAgentString); | |
} | |
var versionTuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString); | |
return goog.labs.userAgent.browser.getVersionFromTuples_(versionTuples); | |
}; | |
goog.labs.userAgent.browser.isVersionOrHigher = function(version) { | |
return 0 <= goog.string.compareVersions(goog.labs.userAgent.browser.getVersion(), version); | |
}; | |
goog.labs.userAgent.browser.getIEVersion_ = function(userAgent) { | |
var rv = /rv: *([\d\.]*)/.exec(userAgent); | |
if (rv && rv[1]) { | |
return rv[1]; | |
} | |
var version = "", msie = /MSIE +([\d\.]+)/.exec(userAgent); | |
if (msie && msie[1]) { | |
var tridentVersion = /Trident\/(\d.\d)/.exec(userAgent); | |
if ("7.0" == msie[1]) { | |
if (tridentVersion && tridentVersion[1]) { | |
switch(tridentVersion[1]) { | |
case "4.0": | |
version = "8.0"; | |
break; | |
case "5.0": | |
version = "9.0"; | |
break; | |
case "6.0": | |
version = "10.0"; | |
break; | |
case "7.0": | |
version = "11.0"; | |
} | |
} else { | |
version = "7.0"; | |
} | |
} else { | |
version = msie[1]; | |
} | |
} | |
return version; | |
}; | |
goog.labs.userAgent.browser.getOperaVersion_ = function(userAgent) { | |
var versionTuples = goog.labs.userAgent.util.extractVersionTuples(userAgent), lastTuple = goog.array.peek(versionTuples); | |
return "OPR" == lastTuple[0] && lastTuple[1] ? lastTuple[1] : goog.labs.userAgent.browser.getVersionFromTuples_(versionTuples); | |
}; | |
goog.labs.userAgent.browser.getVersionFromTuples_ = function(versionTuples) { | |
goog.asserts.assert(2 < versionTuples.length, "Couldn't extract version tuple from user agent string"); | |
return versionTuples[2] && versionTuples[2][1] ? versionTuples[2][1] : ""; | |
}; | |
goog.labs.userAgent.engine = {}; | |
goog.labs.userAgent.engine.isPresto = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Presto"); | |
}; | |
goog.labs.userAgent.engine.isTrident = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Trident") || goog.labs.userAgent.util.matchUserAgent("MSIE"); | |
}; | |
goog.labs.userAgent.engine.isWebKit = function() { | |
return goog.labs.userAgent.util.matchUserAgentIgnoreCase(); | |
}; | |
goog.labs.userAgent.engine.isGecko = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Gecko") && !goog.labs.userAgent.engine.isWebKit() && !goog.labs.userAgent.engine.isTrident(); | |
}; | |
goog.labs.userAgent.engine.getVersion = function() { | |
var userAgentString = goog.labs.userAgent.util.getUserAgent(); | |
if (userAgentString) { | |
var tuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString), engineTuple = tuples[1]; | |
if (engineTuple) { | |
return "Gecko" == engineTuple[0] ? goog.labs.userAgent.engine.getVersionForKey_(tuples) : engineTuple[1]; | |
} | |
var browserTuple = tuples[0], info; | |
if (browserTuple && (info = browserTuple[2])) { | |
var match = /Trident\/([^\s;]+)/.exec(info); | |
if (match) { | |
return match[1]; | |
} | |
} | |
} | |
return ""; | |
}; | |
goog.labs.userAgent.engine.isVersionOrHigher = function(version) { | |
return 0 <= goog.string.compareVersions(goog.labs.userAgent.engine.getVersion(), version); | |
}; | |
goog.labs.userAgent.engine.getVersionForKey_ = function(tuples) { | |
var pair = goog.array.find(tuples, function(pair) { | |
return "Firefox" == pair[0]; | |
}); | |
return pair && pair[1] || ""; | |
}; | |
goog.userAgent = {}; | |
goog.userAgent.ASSUME_IE = !1; | |
goog.userAgent.ASSUME_GECKO = !1; | |
goog.userAgent.ASSUME_WEBKIT = !1; | |
goog.userAgent.ASSUME_MOBILE_WEBKIT = !1; | |
goog.userAgent.ASSUME_OPERA = !1; | |
goog.userAgent.ASSUME_ANY_VERSION = !1; | |
goog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE || goog.userAgent.ASSUME_GECKO || goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_OPERA; | |
goog.userAgent.getUserAgentString = function() { | |
return goog.labs.userAgent.util.getUserAgent(); | |
}; | |
goog.userAgent.getNavigator = function() { | |
return goog.global.navigator || null; | |
}; | |
goog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_OPERA : goog.labs.userAgent.browser.isOpera(); | |
goog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_IE : goog.labs.userAgent.browser.isIE(); | |
goog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_GECKO : goog.labs.userAgent.engine.isGecko(); | |
goog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT : goog.labs.userAgent.engine.isWebKit(); | |
goog.userAgent.isMobile_ = function() { | |
return goog.userAgent.WEBKIT && goog.labs.userAgent.util.matchUserAgent("Mobile"); | |
}; | |
goog.userAgent.MOBILE = goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_(); | |
goog.userAgent.SAFARI = goog.userAgent.WEBKIT; | |
goog.userAgent.determinePlatform_ = function() { | |
var navigator = goog.userAgent.getNavigator(); | |
return navigator && navigator.platform || ""; | |
}; | |
goog.userAgent.PLATFORM = goog.userAgent.determinePlatform_(); | |
goog.userAgent.ASSUME_MAC = !1; | |
goog.userAgent.ASSUME_WINDOWS = !1; | |
goog.userAgent.ASSUME_LINUX = !1; | |
goog.userAgent.ASSUME_X11 = !1; | |
goog.userAgent.ASSUME_ANDROID = !1; | |
goog.userAgent.ASSUME_IPHONE = !1; | |
goog.userAgent.ASSUME_IPAD = !1; | |
goog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC || goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX || goog.userAgent.ASSUME_X11 || goog.userAgent.ASSUME_ANDROID || goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD; | |
goog.userAgent.initPlatform_ = function() { | |
goog.userAgent.detectedMac_ = goog.string.contains(goog.userAgent.PLATFORM, "Mac"); | |
goog.userAgent.detectedWindows_ = goog.string.contains(goog.userAgent.PLATFORM, "Win"); | |
goog.userAgent.detectedLinux_ = goog.string.contains(goog.userAgent.PLATFORM, "Linux"); | |
goog.userAgent.detectedX11_ = !!goog.userAgent.getNavigator() && goog.string.contains(goog.userAgent.getNavigator().appVersion || "", "X11"); | |
var ua = goog.userAgent.getUserAgentString(); | |
goog.userAgent.detectedAndroid_ = !!ua && goog.string.contains(ua, "Android"); | |
goog.userAgent.detectedIPhone_ = !!ua && goog.string.contains(ua, "iPhone"); | |
goog.userAgent.detectedIPad_ = !!ua && goog.string.contains(ua, "iPad"); | |
}; | |
goog.userAgent.PLATFORM_KNOWN_ || goog.userAgent.initPlatform_(); | |
goog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_MAC : goog.userAgent.detectedMac_; | |
goog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_WINDOWS : goog.userAgent.detectedWindows_; | |
goog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_LINUX : goog.userAgent.detectedLinux_; | |
goog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_X11 : goog.userAgent.detectedX11_; | |
goog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_ANDROID : goog.userAgent.detectedAndroid_; | |
goog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_IPHONE : goog.userAgent.detectedIPhone_; | |
goog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_IPAD : goog.userAgent.detectedIPad_; | |
goog.userAgent.determineVersion_ = function() { | |
var version = "", re; | |
if (goog.userAgent.OPERA && goog.global.opera) { | |
var operaVersion = goog.global.opera.version; | |
return goog.isFunction(operaVersion) ? operaVersion() : operaVersion; | |
} | |
goog.userAgent.GECKO ? re = /rv\:([^\);]+)(\)|;)/ : goog.userAgent.IE ? re = /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/ : goog.userAgent.WEBKIT && (re = /WebKit\/(\S+)/); | |
if (re) { | |
var arr = re.exec(goog.userAgent.getUserAgentString()), version = arr ? arr[1] : "" | |
} | |
if (goog.userAgent.IE) { | |
var docMode = goog.userAgent.getDocumentMode_(); | |
if (docMode > parseFloat(version)) { | |
return String(docMode); | |
} | |
} | |
return version; | |
}; | |
goog.userAgent.getDocumentMode_ = function() { | |
var doc = goog.global.document; | |
return doc ? doc.documentMode : void 0; | |
}; | |
goog.userAgent.VERSION = goog.userAgent.determineVersion_(); | |
goog.userAgent.compare = function(v1, v2) { | |
return goog.string.compareVersions(v1, v2); | |
}; | |
goog.userAgent.isVersionOrHigherCache_ = {}; | |
goog.userAgent.isVersionOrHigher = function(version) { | |
return goog.userAgent.ASSUME_ANY_VERSION || goog.userAgent.isVersionOrHigherCache_[version] || (goog.userAgent.isVersionOrHigherCache_[version] = 0 <= goog.string.compareVersions(goog.userAgent.VERSION, version)); | |
}; | |
goog.userAgent.isVersion = goog.userAgent.isVersionOrHigher; | |
goog.userAgent.isDocumentModeOrHigher = function(documentMode) { | |
return goog.userAgent.IE && goog.userAgent.DOCUMENT_MODE >= documentMode; | |
}; | |
goog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher; | |
goog.userAgent.DOCUMENT_MODE = function() { | |
var doc = goog.global.document; | |
return doc && goog.userAgent.IE ? goog.userAgent.getDocumentMode_() || ("CSS1Compat" == doc.compatMode ? parseInt(goog.userAgent.VERSION, 10) : 5) : void 0; | |
}(); | |
goog.events.BrowserFeature = {HAS_W3C_BUTTON:!goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9), HAS_W3C_EVENT_SUPPORT:!goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9), SET_KEY_CODE_TO_PREVENT_DEFAULT:goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("9"), HAS_NAVIGATOR_ONLINE_PROPERTY:!goog.userAgent.WEBKIT || goog.userAgent.isVersionOrHigher("528"), HAS_HTML5_NETWORK_EVENT_SUPPORT:goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher("1.9b") || goog.userAgent.IE && | |
goog.userAgent.isVersionOrHigher("8") || goog.userAgent.OPERA && goog.userAgent.isVersionOrHigher("9.5") || goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher("528"), HTML5_NETWORK_EVENTS_FIRE_ON_BODY:goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher("8") || goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("9"), TOUCH_ENABLED:"ontouchstart" in goog.global || !!(goog.global.document && document.documentElement && "ontouchstart" in document.documentElement) || !(!goog.global.navigator || | |
!goog.global.navigator.msMaxTouchPoints)}; | |
goog.events.getVendorPrefixedName_ = function(eventName) { | |
return goog.userAgent.WEBKIT ? "webkit" + eventName : goog.userAgent.OPERA ? "o" + eventName.toLowerCase() : eventName.toLowerCase(); | |
}; | |
goog.events.EventType = {CLICK:"click", RIGHTCLICK:"rightclick", DBLCLICK:"dblclick", MOUSEDOWN:"mousedown", MOUSEUP:"mouseup", MOUSEOVER:"mouseover", MOUSEOUT:"mouseout", MOUSEMOVE:"mousemove", MOUSEENTER:"mouseenter", MOUSELEAVE:"mouseleave", SELECTSTART:"selectstart", KEYPRESS:"keypress", KEYDOWN:"keydown", KEYUP:"keyup", BLUR:"blur", FOCUS:"focus", DEACTIVATE:"deactivate", FOCUSIN:goog.userAgent.IE ? "focusin" : "DOMFocusIn", FOCUSOUT:goog.userAgent.IE ? "focusout" : "DOMFocusOut", CHANGE:"change", | |
SELECT:"select", SUBMIT:"submit", INPUT:"input", PROPERTYCHANGE:"propertychange", DRAGSTART:"dragstart", DRAG:"drag", DRAGENTER:"dragenter", DRAGOVER:"dragover", DRAGLEAVE:"dragleave", DROP:"drop", DRAGEND:"dragend", TOUCHSTART:"touchstart", TOUCHMOVE:"touchmove", TOUCHEND:"touchend", TOUCHCANCEL:"touchcancel", BEFOREUNLOAD:"beforeunload", CONSOLEMESSAGE:"consolemessage", CONTEXTMENU:"contextmenu", DOMCONTENTLOADED:"DOMContentLoaded", ERROR:"error", HELP:"help", LOAD:"load", LOSECAPTURE:"losecapture", | |
ORIENTATIONCHANGE:"orientationchange", READYSTATECHANGE:"readystatechange", RESIZE:"resize", SCROLL:"scroll", UNLOAD:"unload", HASHCHANGE:"hashchange", PAGEHIDE:"pagehide", PAGESHOW:"pageshow", POPSTATE:"popstate", COPY:"copy", PASTE:"paste", CUT:"cut", BEFORECOPY:"beforecopy", BEFORECUT:"beforecut", BEFOREPASTE:"beforepaste", ONLINE:"online", OFFLINE:"offline", MESSAGE:"message", CONNECT:"connect", ANIMATIONSTART:goog.events.getVendorPrefixedName_("AnimationStart"), ANIMATIONEND:goog.events.getVendorPrefixedName_("AnimationEnd"), | |
ANIMATIONITERATION:goog.events.getVendorPrefixedName_("AnimationIteration"), TRANSITIONEND:goog.events.getVendorPrefixedName_("TransitionEnd"), POINTERDOWN:"pointerdown", POINTERUP:"pointerup", POINTERCANCEL:"pointercancel", POINTERMOVE:"pointermove", POINTEROVER:"pointerover", POINTEROUT:"pointerout", POINTERENTER:"pointerenter", POINTERLEAVE:"pointerleave", GOTPOINTERCAPTURE:"gotpointercapture", LOSTPOINTERCAPTURE:"lostpointercapture", MSGESTURECHANGE:"MSGestureChange", MSGESTUREEND:"MSGestureEnd", | |
MSGESTUREHOLD:"MSGestureHold", MSGESTURESTART:"MSGestureStart", MSGESTURETAP:"MSGestureTap", MSGOTPOINTERCAPTURE:"MSGotPointerCapture", MSINERTIASTART:"MSInertiaStart", MSLOSTPOINTERCAPTURE:"MSLostPointerCapture", MSPOINTERCANCEL:"MSPointerCancel", MSPOINTERDOWN:"MSPointerDown", MSPOINTERENTER:"MSPointerEnter", MSPOINTERHOVER:"MSPointerHover", MSPOINTERLEAVE:"MSPointerLeave", MSPOINTERMOVE:"MSPointerMove", MSPOINTEROUT:"MSPointerOut", MSPOINTEROVER:"MSPointerOver", MSPOINTERUP:"MSPointerUp", TEXTINPUT:"textinput", | |
COMPOSITIONSTART:"compositionstart", COMPOSITIONUPDATE:"compositionupdate", COMPOSITIONEND:"compositionend", EXIT:"exit", LOADABORT:"loadabort", LOADCOMMIT:"loadcommit", LOADREDIRECT:"loadredirect", LOADSTART:"loadstart", LOADSTOP:"loadstop", RESPONSIVE:"responsive", SIZECHANGED:"sizechanged", UNRESPONSIVE:"unresponsive", VISIBILITYCHANGE:"visibilitychange", STORAGE:"storage", DOMSUBTREEMODIFIED:"DOMSubtreeModified", DOMNODEINSERTED:"DOMNodeInserted", DOMNODEREMOVED:"DOMNodeRemoved", DOMNODEREMOVEDFROMDOCUMENT:"DOMNodeRemovedFromDocument", | |
DOMNODEINSERTEDINTODOCUMENT:"DOMNodeInsertedIntoDocument", DOMATTRMODIFIED:"DOMAttrModified", DOMCHARACTERDATAMODIFIED:"DOMCharacterDataModified"}; | |
goog.events.BrowserEvent = function(opt_e, opt_currentTarget) { | |
goog.events.Event.call(this, opt_e ? opt_e.type : ""); | |
this.relatedTarget = this.currentTarget = this.target = null; | |
this.charCode = this.keyCode = this.button = this.screenY = this.screenX = this.clientY = this.clientX = this.offsetY = this.offsetX = 0; | |
this.metaKey = this.shiftKey = this.altKey = this.ctrlKey = !1; | |
this.event_ = this.state = null; | |
opt_e && this.init(opt_e, opt_currentTarget); | |
}; | |
goog.inherits(goog.events.BrowserEvent, goog.events.Event); | |
goog.events.BrowserEvent.MouseButton = {LEFT:0, MIDDLE:1, RIGHT:2}; | |
goog.events.BrowserEvent.IEButtonMap = [1, 4, 2]; | |
goog.events.BrowserEvent.prototype.init = function(e, opt_currentTarget) { | |
var type = this.type = e.type; | |
this.target = e.target || e.srcElement; | |
this.currentTarget = opt_currentTarget; | |
var relatedTarget = e.relatedTarget; | |
relatedTarget ? goog.userAgent.GECKO && (goog.reflect.canAccessProperty(relatedTarget) || (relatedTarget = null)) : type == goog.events.EventType.MOUSEOVER ? relatedTarget = e.fromElement : type == goog.events.EventType.MOUSEOUT && (relatedTarget = e.toElement); | |
this.relatedTarget = relatedTarget; | |
this.offsetX = goog.userAgent.WEBKIT || void 0 !== e.offsetX ? e.offsetX : e.layerX; | |
this.offsetY = goog.userAgent.WEBKIT || void 0 !== e.offsetY ? e.offsetY : e.layerY; | |
this.clientX = void 0 !== e.clientX ? e.clientX : e.pageX; | |
this.clientY = void 0 !== e.clientY ? e.clientY : e.pageY; | |
this.screenX = e.screenX || 0; | |
this.screenY = e.screenY || 0; | |
this.button = e.button; | |
this.keyCode = e.keyCode || 0; | |
this.charCode = e.charCode || ("keypress" == type ? e.keyCode : 0); | |
this.ctrlKey = e.ctrlKey; | |
this.altKey = e.altKey; | |
this.shiftKey = e.shiftKey; | |
this.metaKey = e.metaKey; | |
this.state = e.state; | |
this.event_ = e; | |
e.defaultPrevented && this.preventDefault(); | |
}; | |
goog.events.BrowserEvent.prototype.stopPropagation = function() { | |
goog.events.BrowserEvent.superClass_.stopPropagation.call(this); | |
this.event_.stopPropagation ? this.event_.stopPropagation() : this.event_.cancelBubble = !0; | |
}; | |
goog.events.BrowserEvent.prototype.preventDefault = function() { | |
goog.events.BrowserEvent.superClass_.preventDefault.call(this); | |
var be = this.event_; | |
if (be.preventDefault) { | |
be.preventDefault(); | |
} else { | |
if (be.returnValue = !1, goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT) { | |
try { | |
if (be.ctrlKey || 112 <= be.keyCode && 123 >= be.keyCode) { | |
be.keyCode = -1; | |
} | |
} catch (ex) { | |
} | |
} | |
} | |
}; | |
goog.events.BrowserEvent.prototype.disposeInternal = function() { | |
}; | |
goog.events.Listenable = function() { | |
}; | |
goog.events.Listenable.IMPLEMENTED_BY_PROP = "closure_listenable_" + (1E6 * Math.random() | 0); | |
goog.events.Listenable.addImplementation = function() { | |
goog.events.EventTarget.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP] = !0; | |
}; | |
goog.events.Listenable.isImplementedBy = function(obj) { | |
return!(!obj || !obj[goog.events.Listenable.IMPLEMENTED_BY_PROP]); | |
}; | |
goog.events.ListenableKey = function() { | |
}; | |
goog.events.ListenableKey.counter_ = 0; | |
goog.events.ListenableKey.reserveKey = function() { | |
return++goog.events.ListenableKey.counter_; | |
}; | |
goog.events.Listener = function(listener, proxy, src, type, capture, opt_handler) { | |
this.listener = listener; | |
this.proxy = proxy; | |
this.src = src; | |
this.type = type; | |
this.capture = !!capture; | |
this.handler = opt_handler; | |
this.key = goog.events.ListenableKey.reserveKey(); | |
this.removed = this.callOnce = !1; | |
}; | |
goog.events.Listener.ENABLE_MONITORING = !1; | |
var JSCompiler_StaticMethods_markAsRemoved = function(JSCompiler_StaticMethods_markAsRemoved$self) { | |
JSCompiler_StaticMethods_markAsRemoved$self.removed = !0; | |
JSCompiler_StaticMethods_markAsRemoved$self.listener = null; | |
JSCompiler_StaticMethods_markAsRemoved$self.proxy = null; | |
JSCompiler_StaticMethods_markAsRemoved$self.src = null; | |
JSCompiler_StaticMethods_markAsRemoved$self.handler = null; | |
}; | |
goog.events.ListenerMap = function(src) { | |
this.src = src; | |
this.listeners = {}; | |
this.typeCount_ = 0; | |
}; | |
var JSCompiler_StaticMethods_getTypeCount = function(JSCompiler_StaticMethods_getTypeCount$self) { | |
return JSCompiler_StaticMethods_getTypeCount$self.typeCount_; | |
}; | |
goog.events.ListenerMap.prototype.add = function(type, listener, callOnce, opt_useCapture, opt_listenerScope) { | |
var typeStr = type.toString(), listenerArray = this.listeners[typeStr]; | |
listenerArray || (listenerArray = this.listeners[typeStr] = [], this.typeCount_++); | |
var listenerObj, index = goog.events.ListenerMap.findListenerIndex_(listenerArray, listener, opt_useCapture, opt_listenerScope); | |
-1 < index ? (listenerObj = listenerArray[index], callOnce || (listenerObj.callOnce = !1)) : (listenerObj = new goog.events.Listener(listener, null, this.src, typeStr, !!opt_useCapture, opt_listenerScope), listenerObj.callOnce = callOnce, listenerArray.push(listenerObj)); | |
return listenerObj; | |
}; | |
goog.events.ListenerMap.prototype.remove = function(type, listener, opt_useCapture, opt_listenerScope) { | |
var typeStr = type.toString(); | |
if (!(typeStr in this.listeners)) { | |
return!1; | |
} | |
var listenerArray = this.listeners[typeStr], index = goog.events.ListenerMap.findListenerIndex_(listenerArray, listener, opt_useCapture, opt_listenerScope); | |
return-1 < index ? (JSCompiler_StaticMethods_markAsRemoved(listenerArray[index]), goog.array.removeAt(listenerArray, index), 0 == listenerArray.length && (delete this.listeners[typeStr], this.typeCount_--), !0) : !1; | |
}; | |
var JSCompiler_StaticMethods_removeByKey = function(JSCompiler_StaticMethods_removeByKey$self, listener) { | |
var type = listener.type; | |
if (!(type in JSCompiler_StaticMethods_removeByKey$self.listeners)) { | |
return!1; | |
} | |
var removed = goog.array.remove(JSCompiler_StaticMethods_removeByKey$self.listeners[type], listener); | |
removed && (JSCompiler_StaticMethods_markAsRemoved(listener), 0 == JSCompiler_StaticMethods_removeByKey$self.listeners[type].length && (delete JSCompiler_StaticMethods_removeByKey$self.listeners[type], JSCompiler_StaticMethods_removeByKey$self.typeCount_--)); | |
return removed; | |
}; | |
goog.events.ListenerMap.prototype.removeAll = function(opt_type) { | |
var typeStr = opt_type && opt_type.toString(), count = 0, type; | |
for (type in this.listeners) { | |
if (!typeStr || type == typeStr) { | |
for (var listenerArray = this.listeners[type], i = 0;i < listenerArray.length;i++) { | |
++count, JSCompiler_StaticMethods_markAsRemoved(listenerArray[i]); | |
} | |
delete this.listeners[type]; | |
this.typeCount_--; | |
} | |
} | |
return count; | |
}; | |
goog.events.ListenerMap.prototype.getListeners = function(type, capture) { | |
var listenerArray = this.listeners[type.toString()], rv = []; | |
if (listenerArray) { | |
for (var i = 0;i < listenerArray.length;++i) { | |
var listenerObj = listenerArray[i]; | |
listenerObj.capture == capture && rv.push(listenerObj); | |
} | |
} | |
return rv; | |
}; | |
goog.events.ListenerMap.prototype.getListener = function(type, listener, capture, opt_listenerScope) { | |
var listenerArray = this.listeners[type.toString()], i = -1; | |
listenerArray && (i = goog.events.ListenerMap.findListenerIndex_(listenerArray, listener, capture, opt_listenerScope)); | |
return-1 < i ? listenerArray[i] : null; | |
}; | |
goog.events.ListenerMap.prototype.hasListener = function(opt_type, opt_capture) { | |
var hasType = goog.isDef(opt_type), typeStr = hasType ? opt_type.toString() : "", hasCapture = goog.isDef(opt_capture); | |
return goog.object.some(this.listeners, function(listenerArray) { | |
for (var i = 0;i < listenerArray.length;++i) { | |
if (!(hasType && listenerArray[i].type != typeStr || hasCapture && listenerArray[i].capture != opt_capture)) { | |
return!0; | |
} | |
} | |
return!1; | |
}); | |
}; | |
goog.events.ListenerMap.findListenerIndex_ = function(listenerArray, listener, opt_useCapture, opt_listenerScope) { | |
for (var i = 0;i < listenerArray.length;++i) { | |
var listenerObj = listenerArray[i]; | |
if (!listenerObj.removed && listenerObj.listener == listener && listenerObj.capture == !!opt_useCapture && listenerObj.handler == opt_listenerScope) { | |
return i; | |
} | |
} | |
return-1; | |
}; | |
goog.events.listeners_ = {}; | |
goog.events.LISTENER_MAP_PROP_ = "closure_lm_" + (1E6 * Math.random() | 0); | |
goog.events.onString_ = "on"; | |
goog.events.onStringMap_ = {}; | |
goog.events.CaptureSimulationMode = {OFF_AND_FAIL:0, OFF_AND_SILENT:1, ON:2}; | |
goog.events.CAPTURE_SIMULATION_MODE = 2; | |
goog.events.listenerCountEstimate_ = 0; | |
goog.events.listen = function(src, type, listener, opt_capt, opt_handler) { | |
if (goog.isArray(type)) { | |
for (var i = 0;i < type.length;i++) { | |
goog.events.listen(src, type[i], listener, opt_capt, opt_handler); | |
} | |
return null; | |
} | |
listener = goog.events.wrapListener(listener); | |
return goog.events.Listenable.isImplementedBy(src) ? src.listen(type, listener, opt_capt, opt_handler) : goog.events.listen_(src, type, listener, !1, opt_capt, opt_handler); | |
}; | |
goog.events.listen_ = function(src, type, listener, callOnce, opt_capt, opt_handler) { | |
if (!type) { | |
throw Error("Invalid event type"); | |
} | |
var capture = !!opt_capt; | |
if (capture && !goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) { | |
if (goog.events.CAPTURE_SIMULATION_MODE == goog.events.CaptureSimulationMode.OFF_AND_FAIL) { | |
return goog.asserts.fail("Can not register capture listener in IE8-."), null; | |
} | |
if (goog.events.CAPTURE_SIMULATION_MODE == goog.events.CaptureSimulationMode.OFF_AND_SILENT) { | |
return null; | |
} | |
} | |
var listenerMap = goog.events.getListenerMap_(src); | |
listenerMap || (src[goog.events.LISTENER_MAP_PROP_] = listenerMap = new goog.events.ListenerMap(src)); | |
var listenerObj = listenerMap.add(type, listener, callOnce, opt_capt, opt_handler); | |
if (listenerObj.proxy) { | |
return listenerObj; | |
} | |
var proxy = goog.events.getProxy(); | |
listenerObj.proxy = proxy; | |
proxy.src = src; | |
proxy.listener = listenerObj; | |
src.addEventListener ? src.addEventListener(type.toString(), proxy, capture) : src.attachEvent(goog.events.getOnString_(type.toString()), proxy); | |
goog.events.listenerCountEstimate_++; | |
return listenerObj; | |
}; | |
goog.events.getProxy = function() { | |
var proxyCallbackFunction = goog.events.handleBrowserEvent_, f = goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT ? function(eventObject) { | |
return proxyCallbackFunction.call(f.src, f.listener, eventObject); | |
} : function(eventObject) { | |
var v = proxyCallbackFunction.call(f.src, f.listener, eventObject); | |
if (!v) { | |
return v; | |
} | |
}; | |
return f; | |
}; | |
goog.events.listenOnce = function(src, type, listener, opt_capt, opt_handler) { | |
if (goog.isArray(type)) { | |
for (var i = 0;i < type.length;i++) { | |
goog.events.listenOnce(src, type[i], listener, opt_capt, opt_handler); | |
} | |
return null; | |
} | |
listener = goog.events.wrapListener(listener); | |
return goog.events.Listenable.isImplementedBy(src) ? src.listenOnce(type, listener, opt_capt, opt_handler) : goog.events.listen_(src, type, listener, !0, opt_capt, opt_handler); | |
}; | |
goog.events.listenWithWrapper = function(src, wrapper, listener, opt_capt, opt_handler) { | |
wrapper.listen(src, listener, opt_capt, opt_handler); | |
}; | |
goog.events.unlisten = function(src, type, listener, opt_capt, opt_handler) { | |
if (goog.isArray(type)) { | |
for (var i = 0;i < type.length;i++) { | |
goog.events.unlisten(src, type[i], listener, opt_capt, opt_handler); | |
} | |
return null; | |
} | |
listener = goog.events.wrapListener(listener); | |
if (goog.events.Listenable.isImplementedBy(src)) { | |
return src.unlisten(type, listener, opt_capt, opt_handler); | |
} | |
if (!src) { | |
return!1; | |
} | |
var listenerMap = goog.events.getListenerMap_(src); | |
if (listenerMap) { | |
var listenerObj = listenerMap.getListener(type, listener, !!opt_capt, opt_handler); | |
if (listenerObj) { | |
return goog.events.unlistenByKey(listenerObj); | |
} | |
} | |
return!1; | |
}; | |
goog.events.unlistenByKey = function(key) { | |
if (goog.isNumber(key) || !key || key.removed) { | |
return!1; | |
} | |
var src = key.src; | |
if (goog.events.Listenable.isImplementedBy(src)) { | |
return src.unlistenByKey(key); | |
} | |
var type = key.type, proxy = key.proxy; | |
src.removeEventListener ? src.removeEventListener(type, proxy, key.capture) : src.detachEvent && src.detachEvent(goog.events.getOnString_(type), proxy); | |
goog.events.listenerCountEstimate_--; | |
var listenerMap = goog.events.getListenerMap_(src); | |
listenerMap ? (JSCompiler_StaticMethods_removeByKey(listenerMap, key), 0 == JSCompiler_StaticMethods_getTypeCount(listenerMap) && (listenerMap.src = null, src[goog.events.LISTENER_MAP_PROP_] = null)) : JSCompiler_StaticMethods_markAsRemoved(key); | |
return!0; | |
}; | |
goog.events.unlistenWithWrapper = function(src, wrapper, listener, opt_capt, opt_handler) { | |
wrapper.unlisten(src, listener, opt_capt, opt_handler); | |
}; | |
goog.events.removeAll = function(opt_obj, opt_type) { | |
if (!opt_obj) { | |
return 0; | |
} | |
if (goog.events.Listenable.isImplementedBy(opt_obj)) { | |
return JSCompiler_StaticMethods_removeAllListeners(opt_obj, opt_type); | |
} | |
var listenerMap = goog.events.getListenerMap_(opt_obj); | |
if (!listenerMap) { | |
return 0; | |
} | |
var count = 0, typeStr = opt_type && opt_type.toString(), type; | |
for (type in listenerMap.listeners) { | |
if (!typeStr || type == typeStr) { | |
for (var listeners = listenerMap.listeners[type].concat(), i = 0;i < listeners.length;++i) { | |
goog.events.unlistenByKey(listeners[i]) && ++count; | |
} | |
} | |
} | |
return count; | |
}; | |
goog.events.removeAllNativeListeners = function() { | |
return goog.events.listenerCountEstimate_ = 0; | |
}; | |
goog.events.getListeners = function(obj, type, capture) { | |
if (goog.events.Listenable.isImplementedBy(obj)) { | |
return obj.getListeners(type, capture); | |
} | |
if (!obj) { | |
return[]; | |
} | |
var listenerMap = goog.events.getListenerMap_(obj); | |
return listenerMap ? listenerMap.getListeners(type, capture) : []; | |
}; | |
goog.events.getListener = function(src, type, listener, opt_capt, opt_handler) { | |
listener = goog.events.wrapListener(listener); | |
var capture = !!opt_capt; | |
if (goog.events.Listenable.isImplementedBy(src)) { | |
return src.getListener(type, listener, capture, opt_handler); | |
} | |
if (!src) { | |
return null; | |
} | |
var listenerMap = goog.events.getListenerMap_(src); | |
return listenerMap ? listenerMap.getListener(type, listener, capture, opt_handler) : null; | |
}; | |
goog.events.hasListener = function(obj, opt_type, opt_capture) { | |
if (goog.events.Listenable.isImplementedBy(obj)) { | |
return obj.hasListener(opt_type, opt_capture); | |
} | |
var listenerMap = goog.events.getListenerMap_(obj); | |
return!!listenerMap && listenerMap.hasListener(opt_type, opt_capture); | |
}; | |
goog.events.expose = function(e) { | |
var str = [], key; | |
for (key in e) { | |
e[key] && e[key].id ? str.push(key + " = " + e[key] + " (" + e[key].id + ")") : str.push(key + " = " + e[key]); | |
} | |
return str.join("\n"); | |
}; | |
goog.events.getOnString_ = function(type) { | |
return type in goog.events.onStringMap_ ? goog.events.onStringMap_[type] : goog.events.onStringMap_[type] = goog.events.onString_ + type; | |
}; | |
goog.events.fireListeners = function(obj, type, capture, eventObject) { | |
return goog.events.Listenable.isImplementedBy(obj) ? obj.fireListeners(type, capture, eventObject) : goog.events.fireListeners_(obj, type, capture, eventObject); | |
}; | |
goog.events.fireListeners_ = function(obj, type, capture, eventObject) { | |
var retval = 1, listenerMap = goog.events.getListenerMap_(obj); | |
if (listenerMap) { | |
var listenerArray = listenerMap.listeners[type.toString()]; | |
if (listenerArray) { | |
for (var listenerArray = listenerArray.concat(), i = 0;i < listenerArray.length;i++) { | |
var listener = listenerArray[i]; | |
listener && listener.capture == capture && !listener.removed && (retval &= !1 !== goog.events.fireListener(listener, eventObject)); | |
} | |
} | |
} | |
return Boolean(retval); | |
}; | |
goog.events.fireListener = function(listener, eventObject) { | |
var listenerFn = listener.listener, listenerHandler = listener.handler || listener.src; | |
listener.callOnce && goog.events.unlistenByKey(listener); | |
return listenerFn.call(listenerHandler, eventObject); | |
}; | |
goog.events.getTotalListenerCount = function() { | |
return goog.events.listenerCountEstimate_; | |
}; | |
goog.events.dispatchEvent = function(src, e) { | |
goog.asserts.assert(goog.events.Listenable.isImplementedBy(src), "Can not use goog.events.dispatchEvent with non-goog.events.Listenable instance."); | |
return src.dispatchEvent(e); | |
}; | |
goog.events.protectBrowserEventEntryPoint = function(errorHandler) { | |
goog.events.handleBrowserEvent_ = errorHandler.protectEntryPoint(goog.events.handleBrowserEvent_); | |
}; | |
goog.events.handleBrowserEvent_ = function(listener, opt_evt) { | |
if (listener.removed) { | |
return!0; | |
} | |
if (!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) { | |
var ieEvent = opt_evt || goog.getObjectByName("window.event"), evt = new goog.events.BrowserEvent(ieEvent, this), retval = !0; | |
if (goog.events.CAPTURE_SIMULATION_MODE == goog.events.CaptureSimulationMode.ON) { | |
if (!goog.events.isMarkedIeEvent_(ieEvent)) { | |
goog.events.markIeEvent_(ieEvent); | |
for (var ancestors = [], parent = evt.currentTarget;parent;parent = parent.parentNode) { | |
ancestors.push(parent); | |
} | |
for (var type = listener.type, i = ancestors.length - 1;!evt.propagationStopped_ && 0 <= i;i--) { | |
evt.currentTarget = ancestors[i], retval &= goog.events.fireListeners_(ancestors[i], type, !0, evt); | |
} | |
for (i = 0;!evt.propagationStopped_ && i < ancestors.length;i++) { | |
evt.currentTarget = ancestors[i], retval &= goog.events.fireListeners_(ancestors[i], type, !1, evt); | |
} | |
} | |
} else { | |
retval = goog.events.fireListener(listener, evt); | |
} | |
return retval; | |
} | |
return goog.events.fireListener(listener, new goog.events.BrowserEvent(opt_evt, this)); | |
}; | |
goog.events.markIeEvent_ = function(e) { | |
var useReturnValue = !1; | |
if (0 == e.keyCode) { | |
try { | |
e.keyCode = -1; | |
return; | |
} catch (ex) { | |
useReturnValue = !0; | |
} | |
} | |
if (useReturnValue || void 0 == e.returnValue) { | |
e.returnValue = !0; | |
} | |
}; | |
goog.events.isMarkedIeEvent_ = function(e) { | |
return 0 > e.keyCode || void 0 != e.returnValue; | |
}; | |
goog.events.uniqueIdCounter_ = 0; | |
goog.events.getUniqueId = function(identifier) { | |
return identifier + "_" + goog.events.uniqueIdCounter_++; | |
}; | |
goog.events.getListenerMap_ = function(src) { | |
var listenerMap = src[goog.events.LISTENER_MAP_PROP_]; | |
return listenerMap instanceof goog.events.ListenerMap ? listenerMap : null; | |
}; | |
goog.events.LISTENER_WRAPPER_PROP_ = "__closure_events_fn_" + (1E9 * Math.random() >>> 0); | |
goog.events.wrapListener = function(listener) { | |
goog.asserts.assert(listener, "Listener can not be null."); | |
if (goog.isFunction(listener)) { | |
return listener; | |
} | |
goog.asserts.assert(listener.handleEvent, "An object listener must have handleEvent method."); | |
return listener[goog.events.LISTENER_WRAPPER_PROP_] || (listener[goog.events.LISTENER_WRAPPER_PROP_] = function(e) { | |
return listener.handleEvent(e); | |
}); | |
}; | |
goog.debug.entryPointRegistry.register(function(transformer) { | |
goog.events.handleBrowserEvent_ = transformer(goog.events.handleBrowserEvent_); | |
}); | |
goog.events.EventTarget = function() { | |
goog.Disposable.call(this); | |
this.eventTargetListeners_ = new goog.events.ListenerMap(this); | |
this.actualEventTarget_ = this; | |
}; | |
goog.inherits(goog.events.EventTarget, goog.Disposable); | |
goog.events.Listenable.addImplementation(); | |
goog.events.EventTarget.MAX_ANCESTORS_ = 1E3; | |
goog.events.EventTarget.prototype.parentEventTarget_ = null; | |
var JSCompiler_StaticMethods_getParentEventTarget = function(JSCompiler_StaticMethods_getParentEventTarget$self) { | |
return JSCompiler_StaticMethods_getParentEventTarget$self.parentEventTarget_; | |
}; | |
goog.events.EventTarget.prototype.addEventListener = function(type, handler, opt_capture, opt_handlerScope) { | |
goog.events.listen(this, type, handler, opt_capture, opt_handlerScope); | |
}; | |
goog.events.EventTarget.prototype.removeEventListener = function(type, handler, opt_capture, opt_handlerScope) { | |
goog.events.unlisten(this, type, handler, opt_capture, opt_handlerScope); | |
}; | |
goog.events.EventTarget.prototype.dispatchEvent = function(e) { | |
JSCompiler_StaticMethods_assertInitialized_(this); | |
var ancestorsTree, ancestor = JSCompiler_StaticMethods_getParentEventTarget(this); | |
if (ancestor) { | |
ancestorsTree = []; | |
for (var ancestorCount = 1;ancestor;ancestor = JSCompiler_StaticMethods_getParentEventTarget(ancestor)) { | |
ancestorsTree.push(ancestor), goog.asserts.assert(++ancestorCount < goog.events.EventTarget.MAX_ANCESTORS_, "infinite loop"); | |
} | |
} | |
return goog.events.EventTarget.dispatchEventInternal_(this.actualEventTarget_, e, ancestorsTree); | |
}; | |
goog.events.EventTarget.prototype.disposeInternal = function() { | |
goog.events.EventTarget.superClass_.disposeInternal.call(this); | |
JSCompiler_StaticMethods_removeAllListeners(this); | |
this.parentEventTarget_ = null; | |
}; | |
goog.events.EventTarget.prototype.listen = function(type, listener, opt_useCapture, opt_listenerScope) { | |
JSCompiler_StaticMethods_assertInitialized_(this); | |
return this.eventTargetListeners_.add(String(type), listener, !1, opt_useCapture, opt_listenerScope); | |
}; | |
goog.events.EventTarget.prototype.listenOnce = function(type, listener, opt_useCapture, opt_listenerScope) { | |
return this.eventTargetListeners_.add(String(type), listener, !0, opt_useCapture, opt_listenerScope); | |
}; | |
goog.events.EventTarget.prototype.unlisten = function(type, listener, opt_useCapture, opt_listenerScope) { | |
return this.eventTargetListeners_.remove(String(type), listener, opt_useCapture, opt_listenerScope); | |
}; | |
goog.events.EventTarget.prototype.unlistenByKey = function(key) { | |
return JSCompiler_StaticMethods_removeByKey(this.eventTargetListeners_, key); | |
}; | |
var JSCompiler_StaticMethods_removeAllListeners = function(JSCompiler_StaticMethods_removeAllListeners$self, opt_type) { | |
return JSCompiler_StaticMethods_removeAllListeners$self.eventTargetListeners_ ? JSCompiler_StaticMethods_removeAllListeners$self.eventTargetListeners_.removeAll(opt_type) : 0; | |
}; | |
goog.events.EventTarget.prototype.fireListeners = function(type, capture, eventObject) { | |
var listenerArray = this.eventTargetListeners_.listeners[String(type)]; | |
if (!listenerArray) { | |
return!0; | |
} | |
for (var listenerArray = listenerArray.concat(), rv = !0, i = 0;i < listenerArray.length;++i) { | |
var listener = listenerArray[i]; | |
if (listener && !listener.removed && listener.capture == capture) { | |
var listenerFn = listener.listener, listenerHandler = listener.handler || listener.src; | |
listener.callOnce && this.unlistenByKey(listener); | |
rv = !1 !== listenerFn.call(listenerHandler, eventObject) && rv; | |
} | |
} | |
return rv && !1 != eventObject.returnValue_; | |
}; | |
goog.events.EventTarget.prototype.getListeners = function(type, capture) { | |
return this.eventTargetListeners_.getListeners(String(type), capture); | |
}; | |
goog.events.EventTarget.prototype.getListener = function(type, listener, capture, opt_listenerScope) { | |
return this.eventTargetListeners_.getListener(String(type), listener, capture, opt_listenerScope); | |
}; | |
goog.events.EventTarget.prototype.hasListener = function(opt_type, opt_capture) { | |
return this.eventTargetListeners_.hasListener(goog.isDef(opt_type) ? String(opt_type) : void 0, opt_capture); | |
}; | |
var JSCompiler_StaticMethods_assertInitialized_ = function(JSCompiler_StaticMethods_assertInitialized_$self) { | |
goog.asserts.assert(JSCompiler_StaticMethods_assertInitialized_$self.eventTargetListeners_, "Event target is not initialized. Did you call the superclass (goog.events.EventTarget) constructor?"); | |
}; | |
goog.events.EventTarget.dispatchEventInternal_ = function(target, e, opt_ancestorsTree) { | |
var type = e.type || e; | |
if (goog.isString(e)) { | |
e = new goog.events.Event(e, target); | |
} else { | |
if (e instanceof goog.events.Event) { | |
e.target = e.target || target; | |
} else { | |
var oldEvent = e; | |
e = new goog.events.Event(type, target); | |
goog.object.extend(e, oldEvent); | |
} | |
} | |
var rv = !0, currentTarget; | |
if (opt_ancestorsTree) { | |
for (var i = opt_ancestorsTree.length - 1;!e.propagationStopped_ && 0 <= i;i--) { | |
currentTarget = e.currentTarget = opt_ancestorsTree[i], rv = currentTarget.fireListeners(type, !0, e) && rv; | |
} | |
} | |
e.propagationStopped_ || (currentTarget = e.currentTarget = target, rv = currentTarget.fireListeners(type, !0, e) && rv, e.propagationStopped_ || (rv = currentTarget.fireListeners(type, !1, e) && rv)); | |
if (opt_ancestorsTree) { | |
for (i = 0;!e.propagationStopped_ && i < opt_ancestorsTree.length;i++) { | |
currentTarget = e.currentTarget = opt_ancestorsTree[i], rv = currentTarget.fireListeners(type, !1, e) && rv; | |
} | |
} | |
return rv; | |
}; | |
goog.Timer = function(opt_interval, opt_timerObject) { | |
goog.events.EventTarget.call(this); | |
this.interval_ = opt_interval || 1; | |
this.timerObject_ = opt_timerObject || goog.Timer.defaultTimerObject; | |
this.boundTick_ = goog.bind(this.tick_, this); | |
this.last_ = goog.now(); | |
}; | |
goog.inherits(goog.Timer, goog.events.EventTarget); | |
goog.Timer.MAX_TIMEOUT_ = 2147483647; | |
goog.Timer.prototype.enabled = !1; | |
goog.Timer.defaultTimerObject = goog.global; | |
goog.Timer.intervalScale = .8; | |
goog.Timer.prototype.timer_ = null; | |
goog.Timer.prototype.setInterval = function(interval) { | |
this.interval_ = interval; | |
this.timer_ && this.enabled ? (this.stop(), this.start()) : this.timer_ && this.stop(); | |
}; | |
goog.Timer.prototype.tick_ = function() { | |
if (this.enabled) { | |
var elapsed = goog.now() - this.last_; | |
0 < elapsed && elapsed < this.interval_ * goog.Timer.intervalScale ? this.timer_ = this.timerObject_.setTimeout(this.boundTick_, this.interval_ - elapsed) : (this.timer_ && (this.timerObject_.clearTimeout(this.timer_), this.timer_ = null), JSCompiler_StaticMethods_dispatchTick(this), this.enabled && (this.timer_ = this.timerObject_.setTimeout(this.boundTick_, this.interval_), this.last_ = goog.now())); | |
} | |
}; | |
var JSCompiler_StaticMethods_dispatchTick = function(JSCompiler_StaticMethods_dispatchTick$self) { | |
JSCompiler_StaticMethods_dispatchTick$self.dispatchEvent(goog.Timer.TICK); | |
}; | |
goog.Timer.prototype.start = function() { | |
this.enabled = !0; | |
this.timer_ || (this.timer_ = this.timerObject_.setTimeout(this.boundTick_, this.interval_), this.last_ = goog.now()); | |
}; | |
goog.Timer.prototype.stop = function() { | |
this.enabled = !1; | |
this.timer_ && (this.timerObject_.clearTimeout(this.timer_), this.timer_ = null); | |
}; | |
goog.Timer.prototype.disposeInternal = function() { | |
goog.Timer.superClass_.disposeInternal.call(this); | |
this.stop(); | |
delete this.timerObject_; | |
}; | |
goog.Timer.TICK = "tick"; | |
goog.Timer.callOnce = function(listener, opt_delay, opt_handler) { | |
if (goog.isFunction(listener)) { | |
opt_handler && (listener = goog.bind(listener, opt_handler)); | |
} else { | |
if (listener && "function" == typeof listener.handleEvent) { | |
listener = goog.bind(listener.handleEvent, listener); | |
} else { | |
throw Error("Invalid listener argument"); | |
} | |
} | |
return opt_delay > goog.Timer.MAX_TIMEOUT_ ? -1 : goog.Timer.defaultTimerObject.setTimeout(listener, opt_delay || 0); | |
}; | |
goog.Timer.clear = function(timerId) { | |
goog.Timer.defaultTimerObject.clearTimeout(timerId); | |
}; | |
goog.async = {}; | |
goog.async.Delay = function(listener, opt_interval, opt_handler) { | |
goog.Disposable.call(this); | |
this.listener_ = listener; | |
this.interval_ = opt_interval || 0; | |
this.handler_ = opt_handler; | |
this.callback_ = goog.bind(this.doAction_, this); | |
}; | |
goog.inherits(goog.async.Delay, goog.Disposable); | |
goog.Delay = goog.async.Delay; | |
goog.async.Delay.prototype.id_ = 0; | |
goog.async.Delay.prototype.disposeInternal = function() { | |
goog.async.Delay.superClass_.disposeInternal.call(this); | |
this.stop(); | |
delete this.listener_; | |
delete this.handler_; | |
}; | |
goog.async.Delay.prototype.start = function(opt_interval) { | |
this.stop(); | |
this.id_ = goog.Timer.callOnce(this.callback_, goog.isDef(opt_interval) ? opt_interval : this.interval_); | |
}; | |
goog.async.Delay.prototype.stop = function() { | |
this.isActive() && goog.Timer.clear(this.id_); | |
this.id_ = 0; | |
}; | |
goog.async.Delay.prototype.fire = function() { | |
this.stop(); | |
this.doAction_(); | |
}; | |
goog.async.Delay.prototype.isActive = function() { | |
return 0 != this.id_; | |
}; | |
goog.async.Delay.prototype.doAction_ = function() { | |
this.id_ = 0; | |
this.listener_ && this.listener_.call(this.handler_); | |
}; | |
goog.crypt = {}; | |
goog.crypt.BlockCipher = function() { | |
}; | |
goog.crypt.Aes = function(key) { | |
goog.crypt.Aes.assertKeyArray_(key); | |
this.key_ = key; | |
this.keyLength_ = this.key_.length / 4; | |
this.numberOfRounds_ = this.keyLength_ + 6; | |
this.state_ = [[], [], [], []]; | |
this.temp_ = [[], [], [], []]; | |
JSCompiler_StaticMethods_keyExpansion_(this); | |
}; | |
goog.crypt.Aes.ENABLE_TEST_MODE = !1; | |
goog.crypt.Aes.prototype.encrypt = function(input) { | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testKeySchedule_(0, this.keySchedule_, 0); | |
JSCompiler_StaticMethods_copyInput_(this, input); | |
JSCompiler_StaticMethods_addRoundKey_(this, 0); | |
for (var round = 1;round < this.numberOfRounds_;++round) { | |
goog.crypt.Aes.ENABLE_TEST_MODE && (this.testKeySchedule_(round, this.keySchedule_, round), this.testStartRound_(round, this.state_)), JSCompiler_StaticMethods_subBytes_(this, goog.crypt.Aes.SBOX_), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterSubBytes_(round, this.state_), JSCompiler_StaticMethods_shiftRows_(this), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterShiftRows_(round, this.state_), JSCompiler_StaticMethods_mixColumns_(this), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterMixColumns_(round, | |
this.state_), JSCompiler_StaticMethods_addRoundKey_(this, round); | |
} | |
JSCompiler_StaticMethods_subBytes_(this, goog.crypt.Aes.SBOX_); | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterSubBytes_(round, this.state_); | |
JSCompiler_StaticMethods_shiftRows_(this); | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterShiftRows_(round, this.state_); | |
JSCompiler_StaticMethods_addRoundKey_(this, this.numberOfRounds_); | |
return JSCompiler_StaticMethods_generateOutput_(this); | |
}; | |
goog.crypt.Aes.prototype.decrypt = function(input) { | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testKeySchedule_(0, this.keySchedule_, this.numberOfRounds_); | |
JSCompiler_StaticMethods_copyInput_(this, input); | |
JSCompiler_StaticMethods_addRoundKey_(this, this.numberOfRounds_); | |
for (var round = 1;round < this.numberOfRounds_;++round) { | |
goog.crypt.Aes.ENABLE_TEST_MODE && (this.testKeySchedule_(round, this.keySchedule_, this.numberOfRounds_ - round), this.testStartRound_(round, this.state_)), JSCompiler_StaticMethods_invShiftRows_(this), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterShiftRows_(round, this.state_), JSCompiler_StaticMethods_subBytes_(this, goog.crypt.Aes.INV_SBOX_), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterSubBytes_(round, this.state_), JSCompiler_StaticMethods_addRoundKey_(this, this.numberOfRounds_ - | |
round), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterAddRoundKey_(round, this.state_), JSCompiler_StaticMethods_invMixColumns_(this); | |
} | |
JSCompiler_StaticMethods_invShiftRows_(this); | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterShiftRows_(round, this.state_); | |
JSCompiler_StaticMethods_subBytes_(this, goog.crypt.Aes.INV_SBOX_); | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterSubBytes_(this.numberOfRounds_, this.state_); | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testKeySchedule_(this.numberOfRounds_, this.keySchedule_, 0); | |
JSCompiler_StaticMethods_addRoundKey_(this, 0); | |
return JSCompiler_StaticMethods_generateOutput_(this); | |
}; | |
goog.crypt.Aes.BLOCK_SIZE_ = 4; | |
goog.crypt.Aes.assertKeyArray_ = function(arr) { | |
if (goog.asserts.ENABLE_ASSERTS) { | |
goog.asserts.assert(16 == arr.length || 24 == arr.length || 32 == arr.length, "Key must have length 16, 24, or 32."); | |
for (var i = 0;i < arr.length;i++) { | |
goog.asserts.assertNumber(arr[i]), goog.asserts.assert(0 <= arr[i] && 255 >= arr[i]); | |
} | |
} | |
}; | |
goog.crypt.Aes.prototype.testStartRound_ = goog.nullFunction; | |
goog.crypt.Aes.prototype.testAfterSubBytes_ = goog.nullFunction; | |
goog.crypt.Aes.prototype.testAfterShiftRows_ = goog.nullFunction; | |
goog.crypt.Aes.prototype.testAfterMixColumns_ = goog.nullFunction; | |
goog.crypt.Aes.prototype.testAfterAddRoundKey_ = goog.nullFunction; | |
goog.crypt.Aes.prototype.testKeySchedule_ = goog.nullFunction; | |
var JSCompiler_StaticMethods_copyInput_ = function(JSCompiler_StaticMethods_copyInput_$self, input) { | |
var v, p; | |
goog.asserts.assert(input.length == 4 * goog.crypt.Aes.BLOCK_SIZE_, "Expecting input of 4 times block size."); | |
for (var r = 0;r < goog.crypt.Aes.BLOCK_SIZE_;r++) { | |
for (var c = 0;4 > c;c++) { | |
p = 4 * c + r, v = input[p], goog.asserts.assert(255 >= v && 0 <= v, "Invalid input. Value %s at position %s is not a byte.", v, p), JSCompiler_StaticMethods_copyInput_$self.state_[r][c] = v; | |
} | |
} | |
}, JSCompiler_StaticMethods_generateOutput_ = function(JSCompiler_StaticMethods_generateOutput_$self) { | |
for (var output = [], r = 0;r < goog.crypt.Aes.BLOCK_SIZE_;r++) { | |
for (var c = 0;4 > c;c++) { | |
output[4 * c + r] = JSCompiler_StaticMethods_generateOutput_$self.state_[r][c]; | |
} | |
} | |
return output; | |
}, JSCompiler_StaticMethods_addRoundKey_ = function(JSCompiler_StaticMethods_addRoundKey_$self, round) { | |
for (var r = 0;4 > r;r++) { | |
for (var c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_addRoundKey_$self.state_[r][c] ^= JSCompiler_StaticMethods_addRoundKey_$self.keySchedule_[4 * round + c][r]; | |
} | |
} | |
}, JSCompiler_StaticMethods_subBytes_ = function(JSCompiler_StaticMethods_subBytes_$self, box) { | |
for (var r = 0;4 > r;r++) { | |
for (var c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_subBytes_$self.state_[r][c] = box[JSCompiler_StaticMethods_subBytes_$self.state_[r][c]]; | |
} | |
} | |
}, JSCompiler_StaticMethods_shiftRows_ = function(JSCompiler_StaticMethods_shiftRows_$self) { | |
for (var r = 1;4 > r;r++) { | |
for (var c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_shiftRows_$self.temp_[r][c] = JSCompiler_StaticMethods_shiftRows_$self.state_[r][c]; | |
} | |
} | |
for (r = 1;4 > r;r++) { | |
for (c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_shiftRows_$self.state_[r][c] = JSCompiler_StaticMethods_shiftRows_$self.temp_[r][(c + r) % goog.crypt.Aes.BLOCK_SIZE_]; | |
} | |
} | |
}, JSCompiler_StaticMethods_invShiftRows_ = function(JSCompiler_StaticMethods_invShiftRows_$self) { | |
for (var r = 1;4 > r;r++) { | |
for (var c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_invShiftRows_$self.temp_[r][(c + r) % goog.crypt.Aes.BLOCK_SIZE_] = JSCompiler_StaticMethods_invShiftRows_$self.state_[r][c]; | |
} | |
} | |
for (r = 1;4 > r;r++) { | |
for (c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_invShiftRows_$self.state_[r][c] = JSCompiler_StaticMethods_invShiftRows_$self.temp_[r][c]; | |
} | |
} | |
}, JSCompiler_StaticMethods_mixColumns_ = function(JSCompiler_StaticMethods_mixColumns_$self) { | |
for (var s = JSCompiler_StaticMethods_mixColumns_$self.state_, t = JSCompiler_StaticMethods_mixColumns_$self.temp_[0], c = 0;4 > c;c++) { | |
t[0] = s[0][c], t[1] = s[1][c], t[2] = s[2][c], t[3] = s[3][c], s[0][c] = goog.crypt.Aes.MULT_2_[t[0]] ^ goog.crypt.Aes.MULT_3_[t[1]] ^ t[2] ^ t[3], s[1][c] = t[0] ^ goog.crypt.Aes.MULT_2_[t[1]] ^ goog.crypt.Aes.MULT_3_[t[2]] ^ t[3], s[2][c] = t[0] ^ t[1] ^ goog.crypt.Aes.MULT_2_[t[2]] ^ goog.crypt.Aes.MULT_3_[t[3]], s[3][c] = goog.crypt.Aes.MULT_3_[t[0]] ^ t[1] ^ t[2] ^ goog.crypt.Aes.MULT_2_[t[3]]; | |
} | |
}, JSCompiler_StaticMethods_invMixColumns_ = function(JSCompiler_StaticMethods_invMixColumns_$self) { | |
for (var s = JSCompiler_StaticMethods_invMixColumns_$self.state_, t = JSCompiler_StaticMethods_invMixColumns_$self.temp_[0], c = 0;4 > c;c++) { | |
t[0] = s[0][c], t[1] = s[1][c], t[2] = s[2][c], t[3] = s[3][c], s[0][c] = goog.crypt.Aes.MULT_E_[t[0]] ^ goog.crypt.Aes.MULT_B_[t[1]] ^ goog.crypt.Aes.MULT_D_[t[2]] ^ goog.crypt.Aes.MULT_9_[t[3]], s[1][c] = goog.crypt.Aes.MULT_9_[t[0]] ^ goog.crypt.Aes.MULT_E_[t[1]] ^ goog.crypt.Aes.MULT_B_[t[2]] ^ goog.crypt.Aes.MULT_D_[t[3]], s[2][c] = goog.crypt.Aes.MULT_D_[t[0]] ^ goog.crypt.Aes.MULT_9_[t[1]] ^ goog.crypt.Aes.MULT_E_[t[2]] ^ goog.crypt.Aes.MULT_B_[t[3]], s[3][c] = goog.crypt.Aes.MULT_B_[t[0]] ^ | |
goog.crypt.Aes.MULT_D_[t[1]] ^ goog.crypt.Aes.MULT_9_[t[2]] ^ goog.crypt.Aes.MULT_E_[t[3]]; | |
} | |
}, JSCompiler_StaticMethods_keyExpansion_ = function(JSCompiler_StaticMethods_keyExpansion_$self) { | |
JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_ = Array(goog.crypt.Aes.BLOCK_SIZE_ * (JSCompiler_StaticMethods_keyExpansion_$self.numberOfRounds_ + 1)); | |
for (var rowNum = 0;rowNum < JSCompiler_StaticMethods_keyExpansion_$self.keyLength_;rowNum++) { | |
JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum] = [JSCompiler_StaticMethods_keyExpansion_$self.key_[4 * rowNum], JSCompiler_StaticMethods_keyExpansion_$self.key_[4 * rowNum + 1], JSCompiler_StaticMethods_keyExpansion_$self.key_[4 * rowNum + 2], JSCompiler_StaticMethods_keyExpansion_$self.key_[4 * rowNum + 3]]; | |
} | |
for (var temp = Array(4), rowNum = JSCompiler_StaticMethods_keyExpansion_$self.keyLength_;rowNum < goog.crypt.Aes.BLOCK_SIZE_ * (JSCompiler_StaticMethods_keyExpansion_$self.numberOfRounds_ + 1);rowNum++) { | |
temp[0] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - 1][0], temp[1] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - 1][1], temp[2] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - 1][2], temp[3] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - 1][3], 0 == rowNum % JSCompiler_StaticMethods_keyExpansion_$self.keyLength_ ? (JSCompiler_StaticMethods_rotWord_(temp), JSCompiler_StaticMethods_subWord_(temp), temp[0] ^= | |
goog.crypt.Aes.RCON_[rowNum / JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][0], temp[1] ^= goog.crypt.Aes.RCON_[rowNum / JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][1], temp[2] ^= goog.crypt.Aes.RCON_[rowNum / JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][2], temp[3] ^= goog.crypt.Aes.RCON_[rowNum / JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][3]) : 6 < JSCompiler_StaticMethods_keyExpansion_$self.keyLength_ && 4 == rowNum % JSCompiler_StaticMethods_keyExpansion_$self.keyLength_ && | |
JSCompiler_StaticMethods_subWord_(temp), JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum] = Array(4), JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum][0] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][0] ^ temp[0], JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum][1] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][1] ^ | |
temp[1], JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum][2] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][2] ^ temp[2], JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum][3] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][3] ^ temp[3]; | |
} | |
}, JSCompiler_StaticMethods_subWord_ = function(w) { | |
w[0] = goog.crypt.Aes.SBOX_[w[0]]; | |
w[1] = goog.crypt.Aes.SBOX_[w[1]]; | |
w[2] = goog.crypt.Aes.SBOX_[w[2]]; | |
w[3] = goog.crypt.Aes.SBOX_[w[3]]; | |
}, JSCompiler_StaticMethods_rotWord_ = function(w) { | |
var temp = w[0]; | |
w[0] = w[1]; | |
w[1] = w[2]; | |
w[2] = w[3]; | |
w[3] = temp; | |
}; | |
goog.crypt.Aes.SBOX_ = [99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, | |
249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, | |
14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22]; | |
goog.crypt.Aes.INV_SBOX_ = [82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, | |
10, 247, 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, | |
74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125]; | |
goog.crypt.Aes.RCON_ = [[0, 0, 0, 0], [1, 0, 0, 0], [2, 0, 0, 0], [4, 0, 0, 0], [8, 0, 0, 0], [16, 0, 0, 0], [32, 0, 0, 0], [64, 0, 0, 0], [128, 0, 0, 0], [27, 0, 0, 0], [54, 0, 0, 0]]; | |
goog.crypt.Aes.MULT_2_ = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, | |
212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 27, 25, 31, 29, 19, 17, 23, 21, 11, 9, 15, 13, 3, 1, 7, 5, 59, 57, 63, 61, 51, 49, 55, 53, 43, 41, 47, 45, 35, 33, 39, 37, 91, 89, 95, 93, 83, 81, 87, 85, 75, 73, 79, 77, 67, 65, 71, 69, 123, 121, 127, 125, 115, 113, 119, 117, 107, 105, 111, 109, 99, 97, 103, 101, 155, 153, 159, 157, 147, 145, 151, 149, 139, 137, 143, 141, 131, 129, 135, 133, 187, 185, 191, 189, 179, 177, 183, 181, 171, 169, | |
175, 173, 163, 161, 167, 165, 219, 217, 223, 221, 211, 209, 215, 213, 203, 201, 207, 205, 195, 193, 199, 197, 251, 249, 255, 253, 243, 241, 247, 245, 235, 233, 239, 237, 227, 225, 231, 229]; | |
goog.crypt.Aes.MULT_3_ = [0, 3, 6, 5, 12, 15, 10, 9, 24, 27, 30, 29, 20, 23, 18, 17, 48, 51, 54, 53, 60, 63, 58, 57, 40, 43, 46, 45, 36, 39, 34, 33, 96, 99, 102, 101, 108, 111, 106, 105, 120, 123, 126, 125, 116, 119, 114, 113, 80, 83, 86, 85, 92, 95, 90, 89, 72, 75, 78, 77, 68, 71, 66, 65, 192, 195, 198, 197, 204, 207, 202, 201, 216, 219, 222, 221, 212, 215, 210, 209, 240, 243, 246, 245, 252, 255, 250, 249, 232, 235, 238, 237, 228, 231, 226, 225, 160, 163, 166, 165, 172, 175, 170, 169, 184, 187, | |
190, 189, 180, 183, 178, 177, 144, 147, 150, 149, 156, 159, 154, 153, 136, 139, 142, 141, 132, 135, 130, 129, 155, 152, 157, 158, 151, 148, 145, 146, 131, 128, 133, 134, 143, 140, 137, 138, 171, 168, 173, 174, 167, 164, 161, 162, 179, 176, 181, 182, 191, 188, 185, 186, 251, 248, 253, 254, 247, 244, 241, 242, 227, 224, 229, 230, 239, 236, 233, 234, 203, 200, 205, 206, 199, 196, 193, 194, 211, 208, 213, 214, 223, 220, 217, 218, 91, 88, 93, 94, 87, 84, 81, 82, 67, 64, 69, 70, 79, 76, 73, 74, 107, 104, | |
109, 110, 103, 100, 97, 98, 115, 112, 117, 118, 127, 124, 121, 122, 59, 56, 61, 62, 55, 52, 49, 50, 35, 32, 37, 38, 47, 44, 41, 42, 11, 8, 13, 14, 7, 4, 1, 2, 19, 16, 21, 22, 31, 28, 25, 26]; | |
goog.crypt.Aes.MULT_9_ = [0, 9, 18, 27, 36, 45, 54, 63, 72, 65, 90, 83, 108, 101, 126, 119, 144, 153, 130, 139, 180, 189, 166, 175, 216, 209, 202, 195, 252, 245, 238, 231, 59, 50, 41, 32, 31, 22, 13, 4, 115, 122, 97, 104, 87, 94, 69, 76, 171, 162, 185, 176, 143, 134, 157, 148, 227, 234, 241, 248, 199, 206, 213, 220, 118, 127, 100, 109, 82, 91, 64, 73, 62, 55, 44, 37, 26, 19, 8, 1, 230, 239, 244, 253, 194, 203, 208, 217, 174, 167, 188, 181, 138, 131, 152, 145, 77, 68, 95, 86, 105, 96, 123, 114, 5, | |
12, 23, 30, 33, 40, 51, 58, 221, 212, 207, 198, 249, 240, 235, 226, 149, 156, 135, 142, 177, 184, 163, 170, 236, 229, 254, 247, 200, 193, 218, 211, 164, 173, 182, 191, 128, 137, 146, 155, 124, 117, 110, 103, 88, 81, 74, 67, 52, 61, 38, 47, 16, 25, 2, 11, 215, 222, 197, 204, 243, 250, 225, 232, 159, 150, 141, 132, 187, 178, 169, 160, 71, 78, 85, 92, 99, 106, 113, 120, 15, 6, 29, 20, 43, 34, 57, 48, 154, 147, 136, 129, 190, 183, 172, 165, 210, 219, 192, 201, 246, 255, 228, 237, 10, 3, 24, 17, 46, 39, | |
60, 53, 66, 75, 80, 89, 102, 111, 116, 125, 161, 168, 179, 186, 133, 140, 151, 158, 233, 224, 251, 242, 205, 196, 223, 214, 49, 56, 35, 42, 21, 28, 7, 14, 121, 112, 107, 98, 93, 84, 79, 70]; | |
goog.crypt.Aes.MULT_B_ = [0, 11, 22, 29, 44, 39, 58, 49, 88, 83, 78, 69, 116, 127, 98, 105, 176, 187, 166, 173, 156, 151, 138, 129, 232, 227, 254, 245, 196, 207, 210, 217, 123, 112, 109, 102, 87, 92, 65, 74, 35, 40, 53, 62, 15, 4, 25, 18, 203, 192, 221, 214, 231, 236, 241, 250, 147, 152, 133, 142, 191, 180, 169, 162, 246, 253, 224, 235, 218, 209, 204, 199, 174, 165, 184, 179, 130, 137, 148, 159, 70, 77, 80, 91, 106, 97, 124, 119, 30, 21, 8, 3, 50, 57, 36, 47, 141, 134, 155, 144, 161, 170, 183, 188, | |
213, 222, 195, 200, 249, 242, 239, 228, 61, 54, 43, 32, 17, 26, 7, 12, 101, 110, 115, 120, 73, 66, 95, 84, 247, 252, 225, 234, 219, 208, 205, 198, 175, 164, 185, 178, 131, 136, 149, 158, 71, 76, 81, 90, 107, 96, 125, 118, 31, 20, 9, 2, 51, 56, 37, 46, 140, 135, 154, 145, 160, 171, 182, 189, 212, 223, 194, 201, 248, 243, 238, 229, 60, 55, 42, 33, 16, 27, 6, 13, 100, 111, 114, 121, 72, 67, 94, 85, 1, 10, 23, 28, 45, 38, 59, 48, 89, 82, 79, 68, 117, 126, 99, 104, 177, 186, 167, 172, 157, 150, 139, 128, | |
233, 226, 255, 244, 197, 206, 211, 216, 122, 113, 108, 103, 86, 93, 64, 75, 34, 41, 52, 63, 14, 5, 24, 19, 202, 193, 220, 215, 230, 237, 240, 251, 146, 153, 132, 143, 190, 181, 168, 163]; | |
goog.crypt.Aes.MULT_D_ = [0, 13, 26, 23, 52, 57, 46, 35, 104, 101, 114, 127, 92, 81, 70, 75, 208, 221, 202, 199, 228, 233, 254, 243, 184, 181, 162, 175, 140, 129, 150, 155, 187, 182, 161, 172, 143, 130, 149, 152, 211, 222, 201, 196, 231, 234, 253, 240, 107, 102, 113, 124, 95, 82, 69, 72, 3, 14, 25, 20, 55, 58, 45, 32, 109, 96, 119, 122, 89, 84, 67, 78, 5, 8, 31, 18, 49, 60, 43, 38, 189, 176, 167, 170, 137, 132, 147, 158, 213, 216, 207, 194, 225, 236, 251, 246, 214, 219, 204, 193, 226, 239, 248, 245, | |
190, 179, 164, 169, 138, 135, 144, 157, 6, 11, 28, 17, 50, 63, 40, 37, 110, 99, 116, 121, 90, 87, 64, 77, 218, 215, 192, 205, 238, 227, 244, 249, 178, 191, 168, 165, 134, 139, 156, 145, 10, 7, 16, 29, 62, 51, 36, 41, 98, 111, 120, 117, 86, 91, 76, 65, 97, 108, 123, 118, 85, 88, 79, 66, 9, 4, 19, 30, 61, 48, 39, 42, 177, 188, 171, 166, 133, 136, 159, 146, 217, 212, 195, 206, 237, 224, 247, 250, 183, 186, 173, 160, 131, 142, 153, 148, 223, 210, 197, 200, 235, 230, 241, 252, 103, 106, 125, 112, 83, | |
94, 73, 68, 15, 2, 21, 24, 59, 54, 33, 44, 12, 1, 22, 27, 56, 53, 34, 47, 100, 105, 126, 115, 80, 93, 74, 71, 220, 209, 198, 203, 232, 229, 242, 255, 180, 185, 174, 163, 128, 141, 154, 151]; | |
goog.crypt.Aes.MULT_E_ = [0, 14, 28, 18, 56, 54, 36, 42, 112, 126, 108, 98, 72, 70, 84, 90, 224, 238, 252, 242, 216, 214, 196, 202, 144, 158, 140, 130, 168, 166, 180, 186, 219, 213, 199, 201, 227, 237, 255, 241, 171, 165, 183, 185, 147, 157, 143, 129, 59, 53, 39, 41, 3, 13, 31, 17, 75, 69, 87, 89, 115, 125, 111, 97, 173, 163, 177, 191, 149, 155, 137, 135, 221, 211, 193, 207, 229, 235, 249, 247, 77, 67, 81, 95, 117, 123, 105, 103, 61, 51, 33, 47, 5, 11, 25, 23, 118, 120, 106, 100, 78, 64, 82, 92, | |
6, 8, 26, 20, 62, 48, 34, 44, 150, 152, 138, 132, 174, 160, 178, 188, 230, 232, 250, 244, 222, 208, 194, 204, 65, 79, 93, 83, 121, 119, 101, 107, 49, 63, 45, 35, 9, 7, 21, 27, 161, 175, 189, 179, 153, 151, 133, 139, 209, 223, 205, 195, 233, 231, 245, 251, 154, 148, 134, 136, 162, 172, 190, 176, 234, 228, 246, 248, 210, 220, 206, 192, 122, 116, 102, 104, 66, 76, 94, 80, 10, 4, 22, 24, 50, 60, 46, 32, 236, 226, 240, 254, 212, 218, 200, 198, 156, 146, 128, 142, 164, 170, 184, 182, 12, 2, 16, 30, 52, | |
58, 40, 38, 124, 114, 96, 110, 68, 74, 88, 86, 55, 57, 43, 37, 15, 1, 19, 29, 71, 73, 91, 85, 127, 113, 99, 109, 215, 217, 203, 197, 239, 225, 243, 253, 167, 169, 187, 181, 159, 145, 131, 141]; | |
goog.crypt.stringToByteArray = function(str) { | |
for (var output = [], p = 0, i = 0;i < str.length;i++) { | |
for (var c = str.charCodeAt(i);255 < c;) { | |
output[p++] = c & 255, c >>= 8; | |
} | |
output[p++] = c; | |
} | |
return output; | |
}; | |
goog.crypt.byteArrayToString = function(bytes) { | |
if (8192 > bytes.length) { | |
return String.fromCharCode.apply(null, bytes); | |
} | |
for (var str = "", i = 0;i < bytes.length;i += 8192) { | |
var chunk = goog.array.slice(bytes, i, i + 8192), str = str + String.fromCharCode.apply(null, chunk) | |
} | |
return str; | |
}; | |
goog.crypt.byteArrayToHex = function(array) { | |
return goog.array.map(array, function(numByte) { | |
var hexByte = numByte.toString(16); | |
return 1 < hexByte.length ? hexByte : "0" + hexByte; | |
}).join(""); | |
}; | |
goog.crypt.hexToByteArray = function(hexString) { | |
goog.asserts.assert(0 == hexString.length % 2, "Key string length must be multiple of 2"); | |
for (var arr = [], i = 0;i < hexString.length;i += 2) { | |
arr.push(parseInt(hexString.substring(i, i + 2), 16)); | |
} | |
return arr; | |
}; | |
goog.crypt.stringToUtf8ByteArray = function(str) { | |
str = str.replace(/\r\n/g, "\n"); | |
for (var out = [], p = 0, i = 0;i < str.length;i++) { | |
var c = str.charCodeAt(i); | |
128 > c ? out[p++] = c : (2048 > c ? out[p++] = c >> 6 | 192 : (out[p++] = c >> 12 | 224, out[p++] = c >> 6 & 63 | 128), out[p++] = c & 63 | 128); | |
} | |
return out; | |
}; | |
goog.crypt.utf8ByteArrayToString = function(bytes) { | |
for (var out = [], pos = 0, c = 0;pos < bytes.length;) { | |
var c1 = bytes[pos++]; | |
if (128 > c1) { | |
out[c++] = String.fromCharCode(c1); | |
} else { | |
if (191 < c1 && 224 > c1) { | |
var c2 = bytes[pos++]; | |
out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63); | |
} else { | |
var c2 = bytes[pos++], c3 = bytes[pos++]; | |
out[c++] = String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63); | |
} | |
} | |
} | |
return out.join(""); | |
}; | |
goog.crypt.xorByteArray = function(bytes1, bytes2) { | |
goog.asserts.assert(bytes1.length == bytes2.length, "XOR array lengths must match"); | |
for (var result = [], i = 0;i < bytes1.length;i++) { | |
result.push(bytes1[i] ^ bytes2[i]); | |
} | |
return result; | |
}; | |
goog.crypt.base64 = {}; | |
goog.crypt.base64.byteToCharMap_ = null; | |
goog.crypt.base64.charToByteMap_ = null; | |
goog.crypt.base64.byteToCharMapWebSafe_ = null; | |
goog.crypt.base64.charToByteMapWebSafe_ = null; | |
goog.crypt.base64.ENCODED_VALS_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | |
goog.crypt.base64.ENCODED_VALS = goog.crypt.base64.ENCODED_VALS_BASE + "+/="; | |
goog.crypt.base64.ENCODED_VALS_WEBSAFE = goog.crypt.base64.ENCODED_VALS_BASE + "-_."; | |
goog.crypt.base64.HAS_NATIVE_SUPPORT = goog.userAgent.GECKO || goog.userAgent.WEBKIT || goog.userAgent.OPERA || "function" == typeof goog.global.atob; | |
goog.crypt.base64.encodeByteArray = function(input, opt_webSafe) { | |
if (!goog.isArrayLike(input)) { | |
throw Error("encodeByteArray takes an array as a parameter"); | |
} | |
goog.crypt.base64.init_(); | |
for (var byteToCharMap = opt_webSafe ? goog.crypt.base64.byteToCharMapWebSafe_ : goog.crypt.base64.byteToCharMap_, output = [], i = 0;i < input.length;i += 3) { | |
var byte1 = input[i], haveByte2 = i + 1 < input.length, byte2 = haveByte2 ? input[i + 1] : 0, haveByte3 = i + 2 < input.length, byte3 = haveByte3 ? input[i + 2] : 0, outByte1 = byte1 >> 2, outByte2 = (byte1 & 3) << 4 | byte2 >> 4, outByte3 = (byte2 & 15) << 2 | byte3 >> 6, outByte4 = byte3 & 63; | |
haveByte3 || (outByte4 = 64, haveByte2 || (outByte3 = 64)); | |
output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]); | |
} | |
return output.join(""); | |
}; | |
goog.crypt.base64.encodeString = function(input, opt_webSafe) { | |
return goog.crypt.base64.HAS_NATIVE_SUPPORT && !opt_webSafe ? goog.global.btoa(input) : goog.crypt.base64.encodeByteArray(goog.crypt.stringToByteArray(input), opt_webSafe); | |
}; | |
goog.crypt.base64.decodeString = function(input, opt_webSafe) { | |
return goog.crypt.base64.HAS_NATIVE_SUPPORT && !opt_webSafe ? goog.global.atob(input) : goog.crypt.byteArrayToString(goog.crypt.base64.decodeStringToByteArray(input, opt_webSafe)); | |
}; | |
goog.crypt.base64.decodeStringToByteArray = function(input, opt_webSafe) { | |
goog.crypt.base64.init_(); | |
for (var charToByteMap = opt_webSafe ? goog.crypt.base64.charToByteMapWebSafe_ : goog.crypt.base64.charToByteMap_, output = [], i = 0;i < input.length;) { | |
var byte1 = charToByteMap[input.charAt(i++)], byte2 = i < input.length ? charToByteMap[input.charAt(i)] : 0; | |
++i; | |
var byte3 = i < input.length ? charToByteMap[input.charAt(i)] : 64; | |
++i; | |
var byte4 = i < input.length ? charToByteMap[input.charAt(i)] : 64; | |
++i; | |
if (null == byte1 || null == byte2 || null == byte3 || null == byte4) { | |
throw Error(); | |
} | |
output.push(byte1 << 2 | byte2 >> 4); | |
64 != byte3 && (output.push(byte2 << 4 & 240 | byte3 >> 2), 64 != byte4 && output.push(byte3 << 6 & 192 | byte4)); | |
} | |
return output; | |
}; | |
goog.crypt.base64.init_ = function() { | |
if (!goog.crypt.base64.byteToCharMap_) { | |
goog.crypt.base64.byteToCharMap_ = {}; | |
goog.crypt.base64.charToByteMap_ = {}; | |
goog.crypt.base64.byteToCharMapWebSafe_ = {}; | |
goog.crypt.base64.charToByteMapWebSafe_ = {}; | |
for (var i = 0;i < goog.crypt.base64.ENCODED_VALS.length;i++) { | |
goog.crypt.base64.byteToCharMap_[i] = goog.crypt.base64.ENCODED_VALS.charAt(i), goog.crypt.base64.charToByteMap_[goog.crypt.base64.byteToCharMap_[i]] = i, goog.crypt.base64.byteToCharMapWebSafe_[i] = goog.crypt.base64.ENCODED_VALS_WEBSAFE.charAt(i), goog.crypt.base64.charToByteMapWebSafe_[goog.crypt.base64.byteToCharMapWebSafe_[i]] = i; | |
} | |
} | |
}; | |
goog.crypt.Cbc = function(cipher, opt_blockSize) { | |
this.cipher_ = cipher; | |
this.blockSize_ = opt_blockSize || 16; | |
}; | |
goog.crypt.Cbc.prototype.encrypt = function(plainText, initialVector) { | |
goog.asserts.assert(0 == plainText.length % this.blockSize_, "Data's length must be multiple of block size."); | |
goog.asserts.assert(initialVector.length == this.blockSize_, "Initial vector must be size of one block."); | |
for (var cipherText = [], vector = initialVector, blockStartIndex = 0;blockStartIndex < plainText.length;blockStartIndex += this.blockSize_) { | |
var plainTextBlock = goog.array.slice(plainText, blockStartIndex, blockStartIndex + this.blockSize_), input = goog.crypt.xorByteArray(plainTextBlock, vector), resultBlock = this.cipher_.encrypt(input); | |
goog.array.extend(cipherText, resultBlock); | |
vector = resultBlock; | |
} | |
return cipherText; | |
}; | |
goog.crypt.Cbc.prototype.decrypt = function(cipherText, initialVector) { | |
goog.asserts.assert(0 == cipherText.length % this.blockSize_, "Data's length must be multiple of block size."); | |
goog.asserts.assert(initialVector.length == this.blockSize_, "Initial vector must be size of one block."); | |
for (var plainText = [], blockStartIndex = 0, vector = initialVector;blockStartIndex < cipherText.length;) { | |
var cipherTextBlock = goog.array.slice(cipherText, blockStartIndex, blockStartIndex + this.blockSize_), resultBlock = this.cipher_.decrypt(cipherTextBlock), plainTextBlock = goog.crypt.xorByteArray(vector, resultBlock); | |
goog.array.extend(plainText, plainTextBlock); | |
vector = cipherTextBlock; | |
blockStartIndex += this.blockSize_; | |
} | |
return plainText; | |
}; | |
goog.json = {}; | |
goog.json.USE_NATIVE_JSON = !1; | |
goog.json.isValid_ = function(s) { | |
return/^\s*$/.test(s) ? !1 : /^[\],:{}\s\u2028\u2029]*$/.test(s.replace(/\\["\\\/bfnrtu]/g, "@").replace(/"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g, "")); | |
}; | |
goog.json.parse = goog.json.USE_NATIVE_JSON ? goog.global.JSON.parse : function(s) { | |
var o = String(s); | |
if (goog.json.isValid_(o)) { | |
try { | |
return eval("(" + o + ")"); | |
} catch (ex) { | |
} | |
} | |
throw Error("Invalid JSON string: " + o); | |
}; | |
goog.json.unsafeParse = goog.json.USE_NATIVE_JSON ? goog.global.JSON.parse : function(s) { | |
return eval("(" + s + ")"); | |
}; | |
goog.json.serialize = goog.json.USE_NATIVE_JSON ? goog.global.JSON.stringify : function(object, opt_replacer) { | |
return(new goog.json.Serializer(opt_replacer)).serialize(object); | |
}; | |
goog.json.Serializer = function(opt_replacer) { | |
this.replacer_ = opt_replacer; | |
}; | |
goog.json.Serializer.prototype.serialize = function(object) { | |
var sb = []; | |
JSCompiler_StaticMethods_serializeInternal(this, object, sb); | |
return sb.join(""); | |
}; | |
var JSCompiler_StaticMethods_serializeInternal = function(JSCompiler_StaticMethods_serializeInternal$self, object, sb) { | |
switch(typeof object) { | |
case "string": | |
JSCompiler_StaticMethods_serializeString_(object, sb); | |
break; | |
case "number": | |
JSCompiler_StaticMethods_serializeNumber_(object, sb); | |
break; | |
case "boolean": | |
sb.push(object); | |
break; | |
case "undefined": | |
sb.push("null"); | |
break; | |
case "object": | |
if (null == object) { | |
sb.push("null"); | |
break; | |
} | |
if (goog.isArray(object)) { | |
JSCompiler_StaticMethods_serializeArray(JSCompiler_StaticMethods_serializeInternal$self, object, sb); | |
break; | |
} | |
JSCompiler_StaticMethods_serializeObject_(JSCompiler_StaticMethods_serializeInternal$self, object, sb); | |
break; | |
case "function": | |
break; | |
default: | |
throw Error("Unknown type: " + typeof object);; | |
} | |
}; | |
goog.json.Serializer.charToJsonCharCache_ = {'"':'\\"', "\\":"\\\\", "/":"\\/", "\b":"\\b", "\f":"\\f", "\n":"\\n", "\r":"\\r", "\t":"\\t", "\x0B":"\\u000b"}; | |
goog.json.Serializer.charsToReplace_ = /\uffff/.test("\uffff") ? /[\\\"\x00-\x1f\x7f-\uffff]/g : /[\\\"\x00-\x1f\x7f-\xff]/g; | |
var JSCompiler_StaticMethods_serializeString_ = function(s, sb) { | |
sb.push('"', s.replace(goog.json.Serializer.charsToReplace_, function(c) { | |
if (c in goog.json.Serializer.charToJsonCharCache_) { | |
return goog.json.Serializer.charToJsonCharCache_[c]; | |
} | |
var cc = c.charCodeAt(0), rv = "\\u"; | |
16 > cc ? rv += "000" : 256 > cc ? rv += "00" : 4096 > cc && (rv += "0"); | |
return goog.json.Serializer.charToJsonCharCache_[c] = rv + cc.toString(16); | |
}), '"'); | |
}, JSCompiler_StaticMethods_serializeNumber_ = function(n, sb) { | |
sb.push(isFinite(n) && !isNaN(n) ? n : "null"); | |
}, JSCompiler_StaticMethods_serializeArray = function(JSCompiler_StaticMethods_serializeArray$self, arr, sb) { | |
var l = arr.length; | |
sb.push("["); | |
for (var sep = "", i = 0;i < l;i++) { | |
sb.push(sep); | |
var value = arr[i]; | |
JSCompiler_StaticMethods_serializeInternal(JSCompiler_StaticMethods_serializeArray$self, JSCompiler_StaticMethods_serializeArray$self.replacer_ ? JSCompiler_StaticMethods_serializeArray$self.replacer_.call(arr, String(i), value) : value, sb); | |
sep = ","; | |
} | |
sb.push("]"); | |
}, JSCompiler_StaticMethods_serializeObject_ = function(JSCompiler_StaticMethods_serializeObject_$self, obj, sb) { | |
sb.push("{"); | |
var sep = "", key; | |
for (key in obj) { | |
if (Object.prototype.hasOwnProperty.call(obj, key)) { | |
var value = obj[key]; | |
"function" != typeof value && (sb.push(sep), JSCompiler_StaticMethods_serializeString_(key, sb), sb.push(":"), JSCompiler_StaticMethods_serializeInternal(JSCompiler_StaticMethods_serializeObject_$self, JSCompiler_StaticMethods_serializeObject_$self.replacer_ ? JSCompiler_StaticMethods_serializeObject_$self.replacer_.call(obj, key, value) : value, sb), sep = ","); | |
} | |
} | |
sb.push("}"); | |
}; | |
goog.structs = {}; | |
goog.structs.Collection = function() { | |
}; | |
goog.functions = {}; | |
goog.functions.constant = function(retValue) { | |
return function() { | |
return retValue; | |
}; | |
}; | |
goog.functions.FALSE = goog.functions.constant(!1); | |
goog.functions.TRUE = goog.functions.constant(!0); | |
goog.functions.NULL = goog.functions.constant(null); | |
goog.functions.identity = function(opt_returnValue) { | |
return opt_returnValue; | |
}; | |
goog.functions.error = function(message) { | |
return function() { | |
throw Error(message); | |
}; | |
}; | |
goog.functions.fail = function(err) { | |
return function() { | |
throw err; | |
}; | |
}; | |
goog.functions.lock = function(f, opt_numArgs) { | |
opt_numArgs = opt_numArgs || 0; | |
return function() { | |
return f.apply(this, Array.prototype.slice.call(arguments, 0, opt_numArgs)); | |
}; | |
}; | |
goog.functions.nth = function(n) { | |
return function() { | |
return arguments[n]; | |
}; | |
}; | |
goog.functions.withReturnValue = function(f, retValue) { | |
return goog.functions.sequence(f, goog.functions.constant(retValue)); | |
}; | |
goog.functions.compose = function(fn, var_args) { | |
var functions = arguments, length = functions.length; | |
return function() { | |
var result; | |
length && (result = functions[length - 1].apply(this, arguments)); | |
for (var i = length - 2;0 <= i;i--) { | |
result = functions[i].call(this, result); | |
} | |
return result; | |
}; | |
}; | |
goog.functions.sequence = function(var_args) { | |
var functions = arguments, length = functions.length; | |
return function() { | |
for (var result, i = 0;i < length;i++) { | |
result = functions[i].apply(this, arguments); | |
} | |
return result; | |
}; | |
}; | |
goog.functions.and = function(var_args) { | |
var functions = arguments, length = functions.length; | |
return function() { | |
for (var i = 0;i < length;i++) { | |
if (!functions[i].apply(this, arguments)) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
}; | |
goog.functions.or = function(var_args) { | |
var functions = arguments, length = functions.length; | |
return function() { | |
for (var i = 0;i < length;i++) { | |
if (functions[i].apply(this, arguments)) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
}; | |
goog.functions.not = function(f) { | |
return function() { | |
return!f.apply(this, arguments); | |
}; | |
}; | |
goog.functions.create = function(constructor, var_args) { | |
var temp = function() { | |
}; | |
temp.prototype = constructor.prototype; | |
var obj = new temp; | |
constructor.apply(obj, Array.prototype.slice.call(arguments, 1)); | |
return obj; | |
}; | |
goog.functions.CACHE_RETURN_VALUE = !0; | |
goog.functions.cacheReturnValue = function(fn) { | |
var called = !1, value; | |
return function() { | |
if (!goog.functions.CACHE_RETURN_VALUE) { | |
return fn(); | |
} | |
called || (value = fn(), called = !0); | |
return value; | |
}; | |
}; | |
goog.math = {}; | |
goog.math.randomInt = function(a) { | |
return Math.floor(Math.random() * a); | |
}; | |
goog.math.uniformRandom = function(a, b) { | |
return a + Math.random() * (b - a); | |
}; | |
goog.math.clamp = function(value, min, max) { | |
return Math.min(Math.max(value, min), max); | |
}; | |
goog.math.modulo = function(a, b) { | |
var r = a % b; | |
return 0 > r * b ? r + b : r; | |
}; | |
goog.math.lerp = function(a, b, x) { | |
return a + x * (b - a); | |
}; | |
goog.math.nearlyEquals = function(a, b, opt_tolerance) { | |
return Math.abs(a - b) <= (opt_tolerance || 1E-6); | |
}; | |
goog.math.standardAngle = function(angle) { | |
return goog.math.modulo(angle, 360); | |
}; | |
goog.math.standardAngleInRadians = function(angle) { | |
return goog.math.modulo(angle, 2 * Math.PI); | |
}; | |
goog.math.toRadians = function(angleDegrees) { | |
return angleDegrees * Math.PI / 180; | |
}; | |
goog.math.toDegrees = function(angleRadians) { | |
return 180 * angleRadians / Math.PI; | |
}; | |
goog.math.angleDx = function(degrees, radius) { | |
return radius * Math.cos(goog.math.toRadians(degrees)); | |
}; | |
goog.math.angleDy = function(degrees, radius) { | |
return radius * Math.sin(goog.math.toRadians(degrees)); | |
}; | |
goog.math.angle = function(x1, y1, x2, y2) { | |
return goog.math.standardAngle(goog.math.toDegrees(Math.atan2(y2 - y1, x2 - x1))); | |
}; | |
goog.math.angleDifference = function(startAngle, endAngle) { | |
var d = goog.math.standardAngle(endAngle) - goog.math.standardAngle(startAngle); | |
180 < d ? d -= 360 : -180 >= d && (d = 360 + d); | |
return d; | |
}; | |
goog.math.sign = function(x) { | |
return 0 == x ? 0 : 0 > x ? -1 : 1; | |
}; | |
goog.math.longestCommonSubsequence = function(array1, array2, opt_compareFn, opt_collectorFn) { | |
for (var compare = opt_compareFn || function(a, b) { | |
return a == b; | |
}, collect = opt_collectorFn || function(i1) { | |
return array1[i1]; | |
}, length1 = array1.length, length2 = array2.length, arr = [], i = 0;i < length1 + 1;i++) { | |
arr[i] = [], arr[i][0] = 0; | |
} | |
for (var j = 0;j < length2 + 1;j++) { | |
arr[0][j] = 0; | |
} | |
for (i = 1;i <= length1;i++) { | |
for (j = 1;j <= length2;j++) { | |
compare(array1[i - 1], array2[j - 1]) ? arr[i][j] = arr[i - 1][j - 1] + 1 : arr[i][j] = Math.max(arr[i - 1][j], arr[i][j - 1]); | |
} | |
} | |
for (var result = [], i = length1, j = length2;0 < i && 0 < j;) { | |
compare(array1[i - 1], array2[j - 1]) ? (result.unshift(collect(i - 1, j - 1)), i--, j--) : arr[i - 1][j] > arr[i][j - 1] ? i-- : j--; | |
} | |
return result; | |
}; | |
goog.math.sum = function(var_args) { | |
return goog.array.reduce(arguments, function(sum, value) { | |
return sum + value; | |
}, 0); | |
}; | |
goog.math.average = function(var_args) { | |
return goog.math.sum.apply(null, arguments) / arguments.length; | |
}; | |
goog.math.sampleVariance = function(var_args) { | |
var sampleSize = arguments.length; | |
if (2 > sampleSize) { | |
return 0; | |
} | |
var mean = goog.math.average.apply(null, arguments); | |
return goog.math.sum.apply(null, goog.array.map(arguments, function(val) { | |
return Math.pow(val - mean, 2); | |
})) / (sampleSize - 1); | |
}; | |
goog.math.standardDeviation = function(var_args) { | |
return Math.sqrt(goog.math.sampleVariance.apply(null, arguments)); | |
}; | |
goog.math.isInt = function(num) { | |
return isFinite(num) && 0 == num % 1; | |
}; | |
goog.math.isFiniteNumber = function(num) { | |
return isFinite(num) && !isNaN(num); | |
}; | |
goog.math.log10Floor = function(num) { | |
if (0 < num) { | |
var x = Math.round(Math.log(num) * Math.LOG10E); | |
return x - (parseFloat("1e" + x) > num); | |
} | |
return 0 == num ? -Infinity : NaN; | |
}; | |
goog.math.safeFloor = function(num, opt_epsilon) { | |
goog.asserts.assert(!goog.isDef(opt_epsilon) || 0 < opt_epsilon); | |
return Math.floor(num + (opt_epsilon || 2E-15)); | |
}; | |
goog.math.safeCeil = function(num, opt_epsilon) { | |
goog.asserts.assert(!goog.isDef(opt_epsilon) || 0 < opt_epsilon); | |
return Math.ceil(num - (opt_epsilon || 2E-15)); | |
}; | |
goog.iter = {}; | |
goog.iter.StopIteration = "StopIteration" in goog.global ? goog.global.StopIteration : Error("StopIteration"); | |
goog.iter.Iterator = function() { | |
}; | |
goog.iter.Iterator.prototype.next = function() { | |
throw goog.iter.StopIteration; | |
}; | |
goog.iter.Iterator.prototype.__iterator__ = function() { | |
return this; | |
}; | |
goog.iter.toIterator = function(iterable) { | |
if (iterable instanceof goog.iter.Iterator) { | |
return iterable; | |
} | |
if ("function" == typeof iterable.__iterator__) { | |
return iterable.__iterator__(!1); | |
} | |
if (goog.isArrayLike(iterable)) { | |
var i = 0, newIter = new goog.iter.Iterator; | |
newIter.next = function() { | |
for (;;) { | |
if (i >= iterable.length) { | |
throw goog.iter.StopIteration; | |
} | |
if (i in iterable) { | |
return iterable[i++]; | |
} | |
i++; | |
} | |
}; | |
return newIter; | |
} | |
throw Error("Not implemented"); | |
}; | |
goog.iter.forEach = function(iterable, f, opt_obj) { | |
if (goog.isArrayLike(iterable)) { | |
try { | |
goog.array.forEach(iterable, f, opt_obj); | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
} | |
} else { | |
iterable = goog.iter.toIterator(iterable); | |
try { | |
for (;;) { | |
f.call(opt_obj, iterable.next(), void 0, iterable); | |
} | |
} catch (ex$$0) { | |
if (ex$$0 !== goog.iter.StopIteration) { | |
throw ex$$0; | |
} | |
} | |
} | |
}; | |
goog.iter.filter = function(iterable, f, opt_obj) { | |
var iterator = goog.iter.toIterator(iterable), newIter = new goog.iter.Iterator; | |
newIter.next = function() { | |
for (;;) { | |
var val = iterator.next(); | |
if (f.call(opt_obj, val, void 0, iterator)) { | |
return val; | |
} | |
} | |
}; | |
return newIter; | |
}; | |
goog.iter.filterFalse = function(iterable, f, opt_obj) { | |
return goog.iter.filter(iterable, goog.functions.not(f), opt_obj); | |
}; | |
goog.iter.range = function(startOrStop, opt_stop, opt_step) { | |
var start = 0, stop = startOrStop, step = opt_step || 1; | |
1 < arguments.length && (start = startOrStop, stop = opt_stop); | |
if (0 == step) { | |
throw Error("Range step argument must not be zero"); | |
} | |
var newIter = new goog.iter.Iterator; | |
newIter.next = function() { | |
if (0 < step && start >= stop || 0 > step && start <= stop) { | |
throw goog.iter.StopIteration; | |
} | |
var rv = start; | |
start += step; | |
return rv; | |
}; | |
return newIter; | |
}; | |
goog.iter.join = function(iterable, deliminator) { | |
return goog.iter.toArray(iterable).join(deliminator); | |
}; | |
goog.iter.map = function(iterable, f, opt_obj) { | |
var iterator = goog.iter.toIterator(iterable), newIter = new goog.iter.Iterator; | |
newIter.next = function() { | |
var val = iterator.next(); | |
return f.call(opt_obj, val, void 0, iterator); | |
}; | |
return newIter; | |
}; | |
goog.iter.reduce = function(iterable, f, val$$0, opt_obj) { | |
var rval = val$$0; | |
goog.iter.forEach(iterable, function(val) { | |
rval = f.call(opt_obj, rval, val); | |
}); | |
return rval; | |
}; | |
goog.iter.some = function(iterable, f, opt_obj) { | |
iterable = goog.iter.toIterator(iterable); | |
try { | |
for (;;) { | |
if (f.call(opt_obj, iterable.next(), void 0, iterable)) { | |
return!0; | |
} | |
} | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
} | |
return!1; | |
}; | |
goog.iter.every = function(iterable, f, opt_obj) { | |
iterable = goog.iter.toIterator(iterable); | |
try { | |
for (;;) { | |
if (!f.call(opt_obj, iterable.next(), void 0, iterable)) { | |
return!1; | |
} | |
} | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
} | |
return!0; | |
}; | |
goog.iter.chain = function(var_args) { | |
var iterator = goog.iter.toIterator(arguments), iter = new goog.iter.Iterator, current = null; | |
iter.next = function() { | |
for (;;) { | |
if (null == current) { | |
var it = iterator.next(); | |
current = goog.iter.toIterator(it); | |
} | |
try { | |
return current.next(); | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
current = null; | |
} | |
} | |
}; | |
return iter; | |
}; | |
goog.iter.chainFromIterable = function(iterable) { | |
return goog.iter.chain.apply(void 0, iterable); | |
}; | |
goog.iter.dropWhile = function(iterable, f, opt_obj) { | |
var iterator = goog.iter.toIterator(iterable), newIter = new goog.iter.Iterator, dropping = !0; | |
newIter.next = function() { | |
for (;;) { | |
var val = iterator.next(); | |
if (!dropping || !f.call(opt_obj, val, void 0, iterator)) { | |
return dropping = !1, val; | |
} | |
} | |
}; | |
return newIter; | |
}; | |
goog.iter.takeWhile = function(iterable, f, opt_obj) { | |
var iterator = goog.iter.toIterator(iterable), newIter = new goog.iter.Iterator, taking = !0; | |
newIter.next = function() { | |
for (;;) { | |
if (taking) { | |
var val = iterator.next(); | |
if (f.call(opt_obj, val, void 0, iterator)) { | |
return val; | |
} | |
taking = !1; | |
} else { | |
throw goog.iter.StopIteration; | |
} | |
} | |
}; | |
return newIter; | |
}; | |
goog.iter.toArray = function(iterable) { | |
if (goog.isArrayLike(iterable)) { | |
return goog.array.toArray(iterable); | |
} | |
iterable = goog.iter.toIterator(iterable); | |
var array = []; | |
goog.iter.forEach(iterable, function(val) { | |
array.push(val); | |
}); | |
return array; | |
}; | |
goog.iter.equals = function(iterable1, iterable2) { | |
var pairs = goog.iter.zipLongest({}, iterable1, iterable2); | |
return goog.iter.every(pairs, function(pair) { | |
return pair[0] == pair[1]; | |
}); | |
}; | |
goog.iter.nextOrValue = function(iterable) { | |
try { | |
goog.iter.toIterator(iterable).next(); | |
} catch (e) { | |
if (e != goog.iter.StopIteration) { | |
throw e; | |
} | |
} | |
}; | |
goog.iter.product = function(var_args) { | |
if (goog.array.some(arguments, function(arr) { | |
return!arr.length; | |
}) || !arguments.length) { | |
return new goog.iter.Iterator; | |
} | |
var iter = new goog.iter.Iterator, arrays = arguments, indicies = goog.array.repeat(0, arrays.length); | |
iter.next = function() { | |
if (indicies) { | |
for (var retVal = goog.array.map(indicies, function(valueIndex, arrayIndex) { | |
return arrays[arrayIndex][valueIndex]; | |
}), i = indicies.length - 1;0 <= i;i--) { | |
goog.asserts.assert(indicies); | |
if (indicies[i] < arrays[i].length - 1) { | |
indicies[i]++; | |
break; | |
} | |
if (0 == i) { | |
indicies = null; | |
break; | |
} | |
indicies[i] = 0; | |
} | |
return retVal; | |
} | |
throw goog.iter.StopIteration; | |
}; | |
return iter; | |
}; | |
goog.iter.cycle = function(iterable) { | |
var baseIterator = goog.iter.toIterator(iterable), cache = [], cacheIndex = 0, iter = new goog.iter.Iterator, useCache = !1; | |
iter.next = function() { | |
var returnElement = null; | |
if (!useCache) { | |
try { | |
return returnElement = baseIterator.next(), cache.push(returnElement), returnElement; | |
} catch (e) { | |
if (e != goog.iter.StopIteration || goog.array.isEmpty(cache)) { | |
throw e; | |
} | |
useCache = !0; | |
} | |
} | |
returnElement = cache[cacheIndex]; | |
cacheIndex = (cacheIndex + 1) % cache.length; | |
return returnElement; | |
}; | |
return iter; | |
}; | |
goog.iter.count = function(opt_start, opt_step) { | |
var counter = opt_start || 0, step = goog.isDef(opt_step) ? opt_step : 1, iter = new goog.iter.Iterator; | |
iter.next = function() { | |
var returnValue = counter; | |
counter += step; | |
return returnValue; | |
}; | |
return iter; | |
}; | |
goog.iter.repeat = function(value) { | |
var iter = new goog.iter.Iterator; | |
iter.next = goog.functions.constant(value); | |
return iter; | |
}; | |
goog.iter.accumulate = function(iterable) { | |
var iterator = goog.iter.toIterator(iterable), total = 0, iter = new goog.iter.Iterator; | |
iter.next = function() { | |
return total += iterator.next(); | |
}; | |
return iter; | |
}; | |
goog.iter.zip = function(var_args) { | |
var args = arguments, iter = new goog.iter.Iterator; | |
if (0 < args.length) { | |
var iterators = goog.array.map(args, goog.iter.toIterator); | |
iter.next = function() { | |
return goog.array.map(iterators, function(it) { | |
return it.next(); | |
}); | |
}; | |
} | |
return iter; | |
}; | |
goog.iter.zipLongest = function(fillValue, var_args) { | |
var args = goog.array.slice(arguments, 1), iter = new goog.iter.Iterator; | |
if (0 < args.length) { | |
var iterators = goog.array.map(args, goog.iter.toIterator); | |
iter.next = function() { | |
var iteratorsHaveValues = !1, arr = goog.array.map(iterators, function(it) { | |
var returnValue; | |
try { | |
returnValue = it.next(), iteratorsHaveValues = !0; | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
returnValue = fillValue; | |
} | |
return returnValue; | |
}); | |
if (!iteratorsHaveValues) { | |
throw goog.iter.StopIteration; | |
} | |
return arr; | |
}; | |
} | |
return iter; | |
}; | |
goog.iter.compress = function(iterable, selectors) { | |
var selectorIterator = goog.iter.toIterator(selectors); | |
return goog.iter.filter(iterable, function() { | |
return!!selectorIterator.next(); | |
}); | |
}; | |
goog.iter.GroupByIterator_ = function(iterable, opt_keyFunc) { | |
this.iterator = goog.iter.toIterator(iterable); | |
this.keyFunc = opt_keyFunc || goog.functions.identity; | |
}; | |
goog.inherits(goog.iter.GroupByIterator_, goog.iter.Iterator); | |
goog.iter.GroupByIterator_.prototype.next = function() { | |
for (;this.currentKey == this.targetKey;) { | |
this.currentValue = this.iterator.next(), this.currentKey = this.keyFunc(this.currentValue); | |
} | |
this.targetKey = this.currentKey; | |
return[this.currentKey, JSCompiler_StaticMethods_groupItems_(this, this.targetKey)]; | |
}; | |
var JSCompiler_StaticMethods_groupItems_ = function(JSCompiler_StaticMethods_groupItems_$self, targetKey) { | |
for (var arr = [];JSCompiler_StaticMethods_groupItems_$self.currentKey == targetKey;) { | |
arr.push(JSCompiler_StaticMethods_groupItems_$self.currentValue); | |
try { | |
JSCompiler_StaticMethods_groupItems_$self.currentValue = JSCompiler_StaticMethods_groupItems_$self.iterator.next(); | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
break; | |
} | |
JSCompiler_StaticMethods_groupItems_$self.currentKey = JSCompiler_StaticMethods_groupItems_$self.keyFunc(JSCompiler_StaticMethods_groupItems_$self.currentValue); | |
} | |
return arr; | |
}; | |
goog.iter.groupBy = function(iterable, opt_keyFunc) { | |
return new goog.iter.GroupByIterator_(iterable, opt_keyFunc); | |
}; | |
goog.iter.starMap = function(iterable, f, opt_obj) { | |
var iterator = goog.iter.toIterator(iterable), iter = new goog.iter.Iterator; | |
iter.next = function() { | |
var args = goog.iter.toArray(iterator.next()); | |
return f.apply(opt_obj, goog.array.concat(args, void 0, iterator)); | |
}; | |
return iter; | |
}; | |
goog.iter.tee = function(iterable, opt_num) { | |
var iterator = goog.iter.toIterator(iterable), buffers = goog.array.map(goog.array.range(goog.isNumber(opt_num) ? opt_num : 2), function() { | |
return[]; | |
}), addNextIteratorValueToBuffers = function() { | |
var val = iterator.next(); | |
goog.array.forEach(buffers, function(buffer) { | |
buffer.push(val); | |
}); | |
}; | |
return goog.array.map(buffers, function(buffer) { | |
var iter = new goog.iter.Iterator; | |
iter.next = function() { | |
goog.array.isEmpty(buffer) && addNextIteratorValueToBuffers(); | |
goog.asserts.assert(!goog.array.isEmpty(buffer)); | |
return buffer.shift(); | |
}; | |
return iter; | |
}); | |
}; | |
goog.iter.enumerate = function(iterable, opt_start) { | |
return goog.iter.zip(goog.iter.count(opt_start), iterable); | |
}; | |
goog.iter.limit = function(iterable, limitSize) { | |
goog.asserts.assert(goog.math.isInt(limitSize) && 0 <= limitSize); | |
var iterator = goog.iter.toIterator(iterable), iter = new goog.iter.Iterator, remaining = limitSize; | |
iter.next = function() { | |
if (0 < remaining--) { | |
return iterator.next(); | |
} | |
throw goog.iter.StopIteration; | |
}; | |
return iter; | |
}; | |
goog.iter.consume = function(iterable, count) { | |
goog.asserts.assert(goog.math.isInt(count) && 0 <= count); | |
for (var iterator = goog.iter.toIterator(iterable);0 < count--;) { | |
goog.iter.nextOrValue(iterator); | |
} | |
return iterator; | |
}; | |
goog.iter.slice = function(iterable, start, opt_end) { | |
goog.asserts.assert(goog.math.isInt(start) && 0 <= start); | |
var iterator = goog.iter.consume(iterable, start); | |
goog.isNumber(opt_end) && (goog.asserts.assert(goog.math.isInt(opt_end) && opt_end >= start), iterator = goog.iter.limit(iterator, opt_end - start)); | |
return iterator; | |
}; | |
goog.iter.hasDuplicates_ = function(arr) { | |
var deduped = []; | |
goog.array.removeDuplicates(arr, deduped); | |
return arr.length != deduped.length; | |
}; | |
goog.iter.permutations = function(iterable, opt_length) { | |
var elements = goog.iter.toArray(iterable), sets = goog.array.repeat(elements, goog.isNumber(opt_length) ? opt_length : elements.length), product = goog.iter.product.apply(void 0, sets); | |
return goog.iter.filter(product, function(arr) { | |
return!goog.iter.hasDuplicates_(arr); | |
}); | |
}; | |
goog.iter.combinations = function(iterable, length) { | |
function getIndexFromElements(index) { | |
return elements[index]; | |
} | |
var elements = goog.iter.toArray(iterable), indexes = goog.iter.range(elements.length), indexIterator = goog.iter.permutations(indexes, length), sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) { | |
return goog.array.isSorted(arr); | |
}), iter = new goog.iter.Iterator; | |
iter.next = function() { | |
return goog.array.map(sortedIndexIterator.next(), getIndexFromElements); | |
}; | |
return iter; | |
}; | |
goog.iter.combinationsWithReplacement = function(iterable, length) { | |
function getIndexFromElements(index) { | |
return elements[index]; | |
} | |
var elements = goog.iter.toArray(iterable), indexes = goog.array.range(elements.length), sets = goog.array.repeat(indexes, length), indexIterator = goog.iter.product.apply(void 0, sets), sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) { | |
return goog.array.isSorted(arr); | |
}), iter = new goog.iter.Iterator; | |
iter.next = function() { | |
return goog.array.map(sortedIndexIterator.next(), getIndexFromElements); | |
}; | |
return iter; | |
}; | |
goog.structs.Map = function(opt_map, var_args) { | |
this.map_ = {}; | |
this.keys_ = []; | |
this.version_ = this.count_ = 0; | |
var argLength = arguments.length; | |
if (1 < argLength) { | |
if (argLength % 2) { | |
throw Error("Uneven number of arguments"); | |
} | |
for (var i = 0;i < argLength;i += 2) { | |
this.set(arguments[i], arguments[i + 1]); | |
} | |
} else { | |
opt_map && this.addAll(opt_map); | |
} | |
}; | |
goog.structs.Map.prototype.getCount = function() { | |
return this.count_; | |
}; | |
goog.structs.Map.prototype.getValues = function() { | |
JSCompiler_StaticMethods_cleanupKeysArray_(this); | |
for (var rv = [], i = 0;i < this.keys_.length;i++) { | |
rv.push(this.map_[this.keys_[i]]); | |
} | |
return rv; | |
}; | |
goog.structs.Map.prototype.getKeys = function() { | |
JSCompiler_StaticMethods_cleanupKeysArray_(this); | |
return this.keys_.concat(); | |
}; | |
goog.structs.Map.prototype.containsKey = function(key) { | |
return goog.structs.Map.hasKey_(this.map_, key); | |
}; | |
goog.structs.Map.prototype.containsValue = function(val) { | |
for (var i = 0;i < this.keys_.length;i++) { | |
var key = this.keys_[i]; | |
if (goog.structs.Map.hasKey_(this.map_, key) && this.map_[key] == val) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
goog.structs.Map.prototype.equals = function(otherMap, opt_equalityFn) { | |
if (this === otherMap) { | |
return!0; | |
} | |
if (this.count_ != otherMap.getCount()) { | |
return!1; | |
} | |
var equalityFn = opt_equalityFn || goog.structs.Map.defaultEquals; | |
JSCompiler_StaticMethods_cleanupKeysArray_(this); | |
for (var key, i = 0;key = this.keys_[i];i++) { | |
if (!equalityFn(this.get(key), otherMap.get(key))) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.structs.Map.defaultEquals = function(a, b) { | |
return a === b; | |
}; | |
goog.structs.Map.prototype.isEmpty = function() { | |
return 0 == this.count_; | |
}; | |
goog.structs.Map.prototype.clear = function() { | |
this.map_ = {}; | |
this.version_ = this.count_ = this.keys_.length = 0; | |
}; | |
goog.structs.Map.prototype.remove = function(key) { | |
return goog.structs.Map.hasKey_(this.map_, key) ? (delete this.map_[key], this.count_--, this.version_++, this.keys_.length > 2 * this.count_ && JSCompiler_StaticMethods_cleanupKeysArray_(this), !0) : !1; | |
}; | |
var JSCompiler_StaticMethods_cleanupKeysArray_ = function(JSCompiler_StaticMethods_cleanupKeysArray_$self) { | |
if (JSCompiler_StaticMethods_cleanupKeysArray_$self.count_ != JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length) { | |
for (var srcIndex = 0, destIndex = 0;srcIndex < JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length;) { | |
var key = JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_[srcIndex]; | |
goog.structs.Map.hasKey_(JSCompiler_StaticMethods_cleanupKeysArray_$self.map_, key) && (JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_[destIndex++] = key); | |
srcIndex++; | |
} | |
JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length = destIndex; | |
} | |
if (JSCompiler_StaticMethods_cleanupKeysArray_$self.count_ != JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length) { | |
for (var seen = {}, destIndex = srcIndex = 0;srcIndex < JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length;) { | |
key = JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_[srcIndex], goog.structs.Map.hasKey_(seen, key) || (JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_[destIndex++] = key, seen[key] = 1), srcIndex++; | |
} | |
JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length = destIndex; | |
} | |
}; | |
goog.structs.Map.prototype.get = function(key, opt_val) { | |
return goog.structs.Map.hasKey_(this.map_, key) ? this.map_[key] : opt_val; | |
}; | |
goog.structs.Map.prototype.set = function(key, value) { | |
goog.structs.Map.hasKey_(this.map_, key) || (this.count_++, this.keys_.push(key), this.version_++); | |
this.map_[key] = value; | |
}; | |
goog.structs.Map.prototype.addAll = function(map) { | |
var keys, values; | |
map instanceof goog.structs.Map ? (keys = map.getKeys(), values = map.getValues()) : (keys = goog.object.getKeys(map), values = goog.object.getValues(map)); | |
for (var i = 0;i < keys.length;i++) { | |
this.set(keys[i], values[i]); | |
} | |
}; | |
goog.structs.Map.prototype.forEach = function(f, opt_obj) { | |
for (var keys = this.getKeys(), i = 0;i < keys.length;i++) { | |
var key = keys[i], value = this.get(key); | |
f.call(opt_obj, value, key, this); | |
} | |
}; | |
goog.structs.Map.prototype.clone = function() { | |
return new goog.structs.Map(this); | |
}; | |
goog.structs.Map.prototype.transpose = function() { | |
for (var transposed = new goog.structs.Map, i = 0;i < this.keys_.length;i++) { | |
var key = this.keys_[i]; | |
transposed.set(this.map_[key], key); | |
} | |
return transposed; | |
}; | |
goog.structs.Map.prototype.toObject = function() { | |
JSCompiler_StaticMethods_cleanupKeysArray_(this); | |
for (var obj = {}, i = 0;i < this.keys_.length;i++) { | |
var key = this.keys_[i]; | |
obj[key] = this.map_[key]; | |
} | |
return obj; | |
}; | |
goog.structs.Map.prototype.__iterator__ = function(opt_keys) { | |
JSCompiler_StaticMethods_cleanupKeysArray_(this); | |
var i = 0, keys = this.keys_, map = this.map_, version = this.version_, selfObj = this, newIter = new goog.iter.Iterator; | |
newIter.next = function() { | |
for (;;) { | |
if (version != selfObj.version_) { | |
throw Error("The map has changed since the iterator was created"); | |
} | |
if (i >= keys.length) { | |
throw goog.iter.StopIteration; | |
} | |
var key = keys[i++]; | |
return opt_keys ? key : map[key]; | |
} | |
}; | |
return newIter; | |
}; | |
goog.structs.Map.hasKey_ = function(obj, key) { | |
return Object.prototype.hasOwnProperty.call(obj, key); | |
}; | |
goog.structs.getCount = function(col) { | |
return "function" == typeof col.getCount ? col.getCount() : goog.isArrayLike(col) || goog.isString(col) ? col.length : goog.object.getCount(col); | |
}; | |
goog.structs.getValues = function(col) { | |
if ("function" == typeof col.getValues) { | |
return col.getValues(); | |
} | |
if (goog.isString(col)) { | |
return col.split(""); | |
} | |
if (goog.isArrayLike(col)) { | |
for (var rv = [], l = col.length, i = 0;i < l;i++) { | |
rv.push(col[i]); | |
} | |
return rv; | |
} | |
return goog.object.getValues(col); | |
}; | |
goog.structs.getKeys = function(col) { | |
if ("function" == typeof col.getKeys) { | |
return col.getKeys(); | |
} | |
if ("function" != typeof col.getValues) { | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
for (var rv = [], l = col.length, i = 0;i < l;i++) { | |
rv.push(i); | |
} | |
return rv; | |
} | |
return goog.object.getKeys(col); | |
} | |
}; | |
goog.structs.contains = function(col, val) { | |
return "function" == typeof col.contains ? col.contains(val) : "function" == typeof col.containsValue ? col.containsValue(val) : goog.isArrayLike(col) || goog.isString(col) ? goog.array.contains(col, val) : goog.object.containsValue(col, val); | |
}; | |
goog.structs.isEmpty = function(col) { | |
return "function" == typeof col.isEmpty ? col.isEmpty() : goog.isArrayLike(col) || goog.isString(col) ? goog.array.isEmpty(col) : goog.object.isEmpty(col); | |
}; | |
goog.structs.clear = function(col) { | |
"function" == typeof col.clear ? col.clear() : goog.isArrayLike(col) ? goog.array.clear(col) : goog.object.clear(col); | |
}; | |
goog.structs.forEach = function(col, f, opt_obj) { | |
if ("function" == typeof col.forEach) { | |
col.forEach(f, opt_obj); | |
} else { | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
goog.array.forEach(col, f, opt_obj); | |
} else { | |
for (var keys = goog.structs.getKeys(col), values = goog.structs.getValues(col), l = values.length, i = 0;i < l;i++) { | |
f.call(opt_obj, values[i], keys && keys[i], col); | |
} | |
} | |
} | |
}; | |
goog.structs.filter = function(col, f, opt_obj) { | |
if ("function" == typeof col.filter) { | |
return col.filter(f, opt_obj); | |
} | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
return goog.array.filter(col, f, opt_obj); | |
} | |
var rv, keys = goog.structs.getKeys(col), values = goog.structs.getValues(col), l = values.length; | |
if (keys) { | |
rv = {}; | |
for (var i = 0;i < l;i++) { | |
f.call(opt_obj, values[i], keys[i], col) && (rv[keys[i]] = values[i]); | |
} | |
} else { | |
for (rv = [], i = 0;i < l;i++) { | |
f.call(opt_obj, values[i], void 0, col) && rv.push(values[i]); | |
} | |
} | |
return rv; | |
}; | |
goog.structs.map = function(col, f, opt_obj) { | |
if ("function" == typeof col.map) { | |
return col.map(f, opt_obj); | |
} | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
return goog.array.map(col, f, opt_obj); | |
} | |
var rv, keys = goog.structs.getKeys(col), values = goog.structs.getValues(col), l = values.length; | |
if (keys) { | |
rv = {}; | |
for (var i = 0;i < l;i++) { | |
rv[keys[i]] = f.call(opt_obj, values[i], keys[i], col); | |
} | |
} else { | |
for (rv = [], i = 0;i < l;i++) { | |
rv[i] = f.call(opt_obj, values[i], void 0, col); | |
} | |
} | |
return rv; | |
}; | |
goog.structs.some = function(col, f, opt_obj) { | |
if ("function" == typeof col.some) { | |
return col.some(f, opt_obj); | |
} | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
return goog.array.some(col, f, opt_obj); | |
} | |
for (var keys = goog.structs.getKeys(col), values = goog.structs.getValues(col), l = values.length, i = 0;i < l;i++) { | |
if (f.call(opt_obj, values[i], keys && keys[i], col)) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
goog.structs.every = function(col, f, opt_obj) { | |
if ("function" == typeof col.every) { | |
return col.every(f, opt_obj); | |
} | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
return goog.array.every(col, f, opt_obj); | |
} | |
for (var keys = goog.structs.getKeys(col), values = goog.structs.getValues(col), l = values.length, i = 0;i < l;i++) { | |
if (!f.call(opt_obj, values[i], keys && keys[i], col)) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.structs.Set = function(opt_values) { | |
this.map_ = new goog.structs.Map; | |
opt_values && this.addAll(opt_values); | |
}; | |
goog.structs.Set.getKey_ = function(val) { | |
var type = typeof val; | |
return "object" == type && val || "function" == type ? "o" + goog.getUid(val) : type.substr(0, 1) + val; | |
}; | |
goog.structs.Set.prototype.getCount = function() { | |
return this.map_.getCount(); | |
}; | |
goog.structs.Set.prototype.add = function(element) { | |
this.map_.set(goog.structs.Set.getKey_(element), element); | |
}; | |
goog.structs.Set.prototype.addAll = function(col) { | |
for (var values = goog.structs.getValues(col), l = values.length, i = 0;i < l;i++) { | |
this.add(values[i]); | |
} | |
}; | |
goog.structs.Set.prototype.removeAll = function(col) { | |
for (var values = goog.structs.getValues(col), l = values.length, i = 0;i < l;i++) { | |
this.remove(values[i]); | |
} | |
}; | |
goog.structs.Set.prototype.remove = function(element) { | |
return this.map_.remove(goog.structs.Set.getKey_(element)); | |
}; | |
goog.structs.Set.prototype.clear = function() { | |
this.map_.clear(); | |
}; | |
goog.structs.Set.prototype.isEmpty = function() { | |
return this.map_.isEmpty(); | |
}; | |
goog.structs.Set.prototype.contains = function(element) { | |
return this.map_.containsKey(goog.structs.Set.getKey_(element)); | |
}; | |
goog.structs.Set.prototype.getValues = function() { | |
return this.map_.getValues(); | |
}; | |
goog.structs.Set.prototype.clone = function() { | |
return new goog.structs.Set(this); | |
}; | |
goog.structs.Set.prototype.equals = function(col) { | |
return this.getCount() == goog.structs.getCount(col) && JSCompiler_StaticMethods_isSubsetOf(this, col); | |
}; | |
var JSCompiler_StaticMethods_isSubsetOf = function(JSCompiler_StaticMethods_isSubsetOf$self, col) { | |
var colCount = goog.structs.getCount(col); | |
if (JSCompiler_StaticMethods_isSubsetOf$self.getCount() > colCount) { | |
return!1; | |
} | |
!(col instanceof goog.structs.Set) && 5 < colCount && (col = new goog.structs.Set(col)); | |
return goog.structs.every(JSCompiler_StaticMethods_isSubsetOf$self, function(value) { | |
return goog.structs.contains(col, value); | |
}); | |
}; | |
goog.structs.Set.prototype.__iterator__ = function() { | |
return this.map_.__iterator__(!1); | |
}; | |
goog.debug.LOGGING_ENABLED = goog.DEBUG; | |
goog.debug.catchErrors = function(logFunc, opt_cancel, opt_target) { | |
var target = opt_target || goog.global, oldErrorHandler = target.onerror, retVal = !!opt_cancel; | |
goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher("535.3") && (retVal = !retVal); | |
target.onerror = function(message, url, line, opt_col, opt_error) { | |
oldErrorHandler && oldErrorHandler(message, url, line, opt_col, opt_error); | |
logFunc({message:message, fileName:url, line:line, col:opt_col, error:opt_error}); | |
return retVal; | |
}; | |
}; | |
goog.debug.expose = function(obj, opt_showFn) { | |
if ("undefined" == typeof obj) { | |
return "undefined"; | |
} | |
if (null == obj) { | |
return "NULL"; | |
} | |
var str = [], x; | |
for (x in obj) { | |
if (opt_showFn || !goog.isFunction(obj[x])) { | |
var s = x + " = "; | |
try { | |
s += obj[x]; | |
} catch (e) { | |
s += "*** " + e + " ***"; | |
} | |
str.push(s); | |
} | |
} | |
return str.join("\n"); | |
}; | |
goog.debug.deepExpose = function(obj$$0, opt_showFn) { | |
var str$$0 = [], helper = function(obj, space, parentSeen) { | |
var nestspace = space + " ", seen = new goog.structs.Set(parentSeen), indentMultiline = function(str) { | |
return str.replace(/\n/g, "\n" + space); | |
}; | |
try { | |
if (goog.isDef(obj)) { | |
if (goog.isNull(obj)) { | |
str$$0.push("NULL"); | |
} else { | |
if (goog.isString(obj)) { | |
str$$0.push('"' + indentMultiline(obj) + '"'); | |
} else { | |
if (goog.isFunction(obj)) { | |
str$$0.push(indentMultiline(String(obj))); | |
} else { | |
if (goog.isObject(obj)) { | |
if (seen.contains(obj)) { | |
str$$0.push("*** reference loop detected ***"); | |
} else { | |
seen.add(obj); | |
str$$0.push("{"); | |
for (var x in obj) { | |
if (opt_showFn || !goog.isFunction(obj[x])) { | |
str$$0.push("\n"), str$$0.push(nestspace), str$$0.push(x + " = "), helper(obj[x], nestspace, seen); | |
} | |
} | |
str$$0.push("\n" + space + "}"); | |
} | |
} else { | |
str$$0.push(obj); | |
} | |
} | |
} | |
} | |
} else { | |
str$$0.push("undefined"); | |
} | |
} catch (e) { | |
str$$0.push("*** " + e + " ***"); | |
} | |
}; | |
helper(obj$$0, "", new goog.structs.Set); | |
return str$$0.join(""); | |
}; | |
goog.debug.exposeArray = function(arr) { | |
for (var str = [], i = 0;i < arr.length;i++) { | |
goog.isArray(arr[i]) ? str.push(goog.debug.exposeArray(arr[i])) : str.push(arr[i]); | |
} | |
return "[ " + str.join(", ") + " ]"; | |
}; | |
goog.debug.exposeException = function(err, opt_fn) { | |
try { | |
var e = goog.debug.normalizeErrorObject(err); | |
return "Message: " + goog.string.htmlEscape(e.message) + '\nUrl: <a href="view-source:' + e.fileName + '" target="_new">' + e.fileName + "</a>\nLine: " + e.lineNumber + "\n\nBrowser stack:\n" + goog.string.htmlEscape(e.stack + "-> ") + "[end]\n\nJS stack traversal:\n" + goog.string.htmlEscape(goog.debug.getStacktrace(opt_fn) + "-> "); | |
} catch (e2) { | |
return "Exception trying to expose exception! You win, we lose. " + e2; | |
} | |
}; | |
goog.debug.normalizeErrorObject = function(err) { | |
var href = goog.getObjectByName("window.location.href"); | |
if (goog.isString(err)) { | |
return{message:err, name:"Unknown error", lineNumber:"Not available", fileName:href, stack:"Not available"}; | |
} | |
var lineNumber, fileName, threwError = !1; | |
try { | |
lineNumber = err.lineNumber || err.line || "Not available"; | |
} catch (e) { | |
lineNumber = "Not available", threwError = !0; | |
} | |
try { | |
fileName = err.fileName || err.filename || err.sourceURL || goog.global.$googDebugFname || href; | |
} catch (e$$0) { | |
fileName = "Not available", threwError = !0; | |
} | |
return!threwError && err.lineNumber && err.fileName && err.stack && err.message && err.name ? err : {message:err.message || "Not available", name:err.name || "UnknownError", lineNumber:lineNumber, fileName:fileName, stack:err.stack || "Not available"}; | |
}; | |
goog.debug.enhanceError = function(err, opt_message) { | |
var error; | |
"string" == typeof err ? (error = Error(err), Error.captureStackTrace && Error.captureStackTrace(error, goog.debug.enhanceError)) : error = err; | |
error.stack || (error.stack = goog.debug.getStacktrace(goog.debug.enhanceError)); | |
if (opt_message) { | |
for (var x = 0;error["message" + x];) { | |
++x; | |
} | |
error["message" + x] = String(opt_message); | |
} | |
return error; | |
}; | |
goog.debug.getStacktraceSimple = function(opt_depth) { | |
if (goog.STRICT_MODE_COMPATIBLE) { | |
var stack = goog.debug.getNativeStackTrace_(goog.debug.getStacktraceSimple); | |
if (stack) { | |
return stack; | |
} | |
} | |
for (var sb = [], fn = arguments.callee.caller, depth = 0;fn && (!opt_depth || depth < opt_depth);) { | |
sb.push(goog.debug.getFunctionName(fn)); | |
sb.push("()\n"); | |
try { | |
fn = fn.caller; | |
} catch (e) { | |
sb.push("[exception trying to get caller]\n"); | |
break; | |
} | |
depth++; | |
if (depth >= goog.debug.MAX_STACK_DEPTH) { | |
sb.push("[...long stack...]"); | |
break; | |
} | |
} | |
opt_depth && depth >= opt_depth ? sb.push("[...reached max depth limit...]") : sb.push("[end]"); | |
return sb.join(""); | |
}; | |
goog.debug.MAX_STACK_DEPTH = 50; | |
goog.debug.getNativeStackTrace_ = function(fn) { | |
var tempErr = Error(); | |
if (Error.captureStackTrace) { | |
return Error.captureStackTrace(tempErr, fn), String(tempErr.stack); | |
} | |
try { | |
throw tempErr; | |
} catch (e) { | |
tempErr = e; | |
} | |
var stack = tempErr.stack; | |
return stack ? String(stack) : null; | |
}; | |
goog.debug.getStacktrace = function(opt_fn) { | |
var stack; | |
goog.STRICT_MODE_COMPATIBLE && (stack = goog.debug.getNativeStackTrace_(opt_fn || goog.debug.getStacktrace)); | |
stack || (stack = goog.debug.getStacktraceHelper_(opt_fn || arguments.callee.caller, [])); | |
return stack; | |
}; | |
goog.debug.getStacktraceHelper_ = function(fn, visited) { | |
var sb = []; | |
if (goog.array.contains(visited, fn)) { | |
sb.push("[...circular reference...]"); | |
} else { | |
if (fn && visited.length < goog.debug.MAX_STACK_DEPTH) { | |
sb.push(goog.debug.getFunctionName(fn) + "("); | |
for (var args = fn.arguments, i = 0;args && i < args.length;i++) { | |
0 < i && sb.push(", "); | |
var argDesc, arg = args[i]; | |
switch(typeof arg) { | |
case "object": | |
argDesc = arg ? "object" : "null"; | |
break; | |
case "string": | |
argDesc = arg; | |
break; | |
case "number": | |
argDesc = String(arg); | |
break; | |
case "boolean": | |
argDesc = arg ? "true" : "false"; | |
break; | |
case "function": | |
argDesc = (argDesc = goog.debug.getFunctionName(arg)) ? argDesc : "[fn]"; | |
break; | |
default: | |
argDesc = typeof arg; | |
} | |
40 < argDesc.length && (argDesc = argDesc.substr(0, 40) + "..."); | |
sb.push(argDesc); | |
} | |
visited.push(fn); | |
sb.push(")\n"); | |
try { | |
sb.push(goog.debug.getStacktraceHelper_(fn.caller, visited)); | |
} catch (e) { | |
sb.push("[exception trying to get caller]\n"); | |
} | |
} else { | |
fn ? sb.push("[...long stack...]") : sb.push("[end]"); | |
} | |
} | |
return sb.join(""); | |
}; | |
goog.debug.setFunctionResolver = function(resolver) { | |
goog.debug.fnNameResolver_ = resolver; | |
}; | |
goog.debug.getFunctionName = function(fn) { | |
if (goog.debug.fnNameCache_[fn]) { | |
return goog.debug.fnNameCache_[fn]; | |
} | |
if (goog.debug.fnNameResolver_) { | |
var name = goog.debug.fnNameResolver_(fn); | |
if (name) { | |
return goog.debug.fnNameCache_[fn] = name; | |
} | |
} | |
var functionSource = String(fn); | |
if (!goog.debug.fnNameCache_[functionSource]) { | |
var matches = /function ([^\(]+)/.exec(functionSource); | |
goog.debug.fnNameCache_[functionSource] = matches ? matches[1] : "[Anonymous]"; | |
} | |
return goog.debug.fnNameCache_[functionSource]; | |
}; | |
goog.debug.makeWhitespaceVisible = function(string) { | |
return string.replace(/ /g, "[_]").replace(/\f/g, "[f]").replace(/\n/g, "[n]\n").replace(/\r/g, "[r]").replace(/\t/g, "[t]"); | |
}; | |
goog.debug.fnNameCache_ = {}; | |
goog.debug.LogRecord = function(level, msg, loggerName, opt_time, opt_sequenceNumber) { | |
this.reset(level, msg, loggerName, opt_time, opt_sequenceNumber); | |
}; | |
goog.debug.LogRecord.prototype.exception_ = null; | |
goog.debug.LogRecord.prototype.exceptionText_ = null; | |
goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS = !0; | |
goog.debug.LogRecord.nextSequenceNumber_ = 0; | |
goog.debug.LogRecord.prototype.reset = function(level, msg, loggerName, opt_time, opt_sequenceNumber) { | |
goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS && ("number" == typeof opt_sequenceNumber || goog.debug.LogRecord.nextSequenceNumber_++); | |
this.time_ = opt_time || goog.now(); | |
this.level_ = level; | |
this.msg_ = msg; | |
delete this.exception_; | |
delete this.exceptionText_; | |
}; | |
var JSCompiler_StaticMethods_setException = function(JSCompiler_StaticMethods_setException$self, exception) { | |
JSCompiler_StaticMethods_setException$self.exception_ = exception; | |
}, JSCompiler_StaticMethods_setExceptionText = function(JSCompiler_StaticMethods_setExceptionText$self, text) { | |
JSCompiler_StaticMethods_setExceptionText$self.exceptionText_ = text; | |
}; | |
goog.debug.LogRecord.prototype.setLevel = function(level) { | |
this.level_ = level; | |
}; | |
goog.debug.LogRecord.prototype.getMessage = function() { | |
return this.msg_; | |
}; | |
goog.debug.LogBuffer = function() { | |
goog.asserts.assert(goog.debug.LogBuffer.isBufferingEnabled(), "Cannot use goog.debug.LogBuffer without defining goog.debug.LogBuffer.CAPACITY."); | |
this.clear(); | |
}; | |
goog.debug.LogBuffer.getInstance = function() { | |
goog.debug.LogBuffer.instance_ || (goog.debug.LogBuffer.instance_ = new goog.debug.LogBuffer); | |
return goog.debug.LogBuffer.instance_; | |
}; | |
goog.debug.LogBuffer.CAPACITY = 0; | |
var JSCompiler_StaticMethods_addRecord = function(JSCompiler_StaticMethods_addRecord$self, level, msg, loggerName) { | |
var curIndex = (JSCompiler_StaticMethods_addRecord$self.curIndex_ + 1) % goog.debug.LogBuffer.CAPACITY; | |
JSCompiler_StaticMethods_addRecord$self.curIndex_ = curIndex; | |
if (JSCompiler_StaticMethods_addRecord$self.isFull_) { | |
var ret = JSCompiler_StaticMethods_addRecord$self.buffer_[curIndex]; | |
ret.reset(level, msg, loggerName); | |
return ret; | |
} | |
JSCompiler_StaticMethods_addRecord$self.isFull_ = curIndex == goog.debug.LogBuffer.CAPACITY - 1; | |
return JSCompiler_StaticMethods_addRecord$self.buffer_[curIndex] = new goog.debug.LogRecord(level, msg, loggerName); | |
}; | |
goog.debug.LogBuffer.isBufferingEnabled = function() { | |
return 0 < goog.debug.LogBuffer.CAPACITY; | |
}; | |
goog.debug.LogBuffer.prototype.clear = function() { | |
this.buffer_ = Array(goog.debug.LogBuffer.CAPACITY); | |
this.curIndex_ = -1; | |
this.isFull_ = !1; | |
}; | |
goog.debug.Logger = function(name) { | |
this.name_ = name; | |
this.handlers_ = this.children_ = this.level_ = this.parent_ = null; | |
}; | |
goog.debug.Logger.ROOT_LOGGER_NAME = ""; | |
goog.debug.Logger.ENABLE_HIERARCHY = !0; | |
goog.debug.Logger.ENABLE_HIERARCHY || (goog.debug.Logger.rootHandlers_ = []); | |
goog.debug.Logger.Level = function(name, value) { | |
this.name = name; | |
this.value = value; | |
}; | |
goog.debug.Logger.Level.prototype.toString = function() { | |
return this.name; | |
}; | |
goog.debug.Logger.Level.OFF = new goog.debug.Logger.Level("OFF", Infinity); | |
goog.debug.Logger.Level.SHOUT = new goog.debug.Logger.Level("SHOUT", 1200); | |
goog.debug.Logger.Level.SEVERE = new goog.debug.Logger.Level("SEVERE", 1E3); | |
goog.debug.Logger.Level.WARNING = new goog.debug.Logger.Level("WARNING", 900); | |
goog.debug.Logger.Level.INFO = new goog.debug.Logger.Level("INFO", 800); | |
goog.debug.Logger.Level.CONFIG = new goog.debug.Logger.Level("CONFIG", 700); | |
goog.debug.Logger.Level.FINE = new goog.debug.Logger.Level("FINE", 500); | |
goog.debug.Logger.Level.FINER = new goog.debug.Logger.Level("FINER", 400); | |
goog.debug.Logger.Level.FINEST = new goog.debug.Logger.Level("FINEST", 300); | |
goog.debug.Logger.Level.ALL = new goog.debug.Logger.Level("ALL", 0); | |
goog.debug.Logger.Level.PREDEFINED_LEVELS = [goog.debug.Logger.Level.OFF, goog.debug.Logger.Level.SHOUT, goog.debug.Logger.Level.SEVERE, goog.debug.Logger.Level.WARNING, goog.debug.Logger.Level.INFO, goog.debug.Logger.Level.CONFIG, goog.debug.Logger.Level.FINE, goog.debug.Logger.Level.FINER, goog.debug.Logger.Level.FINEST, goog.debug.Logger.Level.ALL]; | |
goog.debug.Logger.Level.predefinedLevelsCache_ = null; | |
goog.debug.Logger.Level.createPredefinedLevelsCache_ = function() { | |
goog.debug.Logger.Level.predefinedLevelsCache_ = {}; | |
for (var i = 0, level;level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];i++) { | |
goog.debug.Logger.Level.predefinedLevelsCache_[level.value] = level, goog.debug.Logger.Level.predefinedLevelsCache_[level.name] = level; | |
} | |
}; | |
goog.debug.Logger.Level.getPredefinedLevel = function(name) { | |
goog.debug.Logger.Level.predefinedLevelsCache_ || goog.debug.Logger.Level.createPredefinedLevelsCache_(); | |
return goog.debug.Logger.Level.predefinedLevelsCache_[name] || null; | |
}; | |
goog.debug.Logger.Level.getPredefinedLevelByValue = function(value) { | |
goog.debug.Logger.Level.predefinedLevelsCache_ || goog.debug.Logger.Level.createPredefinedLevelsCache_(); | |
if (value in goog.debug.Logger.Level.predefinedLevelsCache_) { | |
return goog.debug.Logger.Level.predefinedLevelsCache_[value]; | |
} | |
for (var i = 0;i < goog.debug.Logger.Level.PREDEFINED_LEVELS.length;++i) { | |
var level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i]; | |
if (level.value <= value) { | |
return level; | |
} | |
} | |
return null; | |
}; | |
goog.debug.Logger.getLogger = function(name) { | |
return goog.debug.LogManager.getLogger(name); | |
}; | |
goog.debug.Logger.logToProfilers = function(msg) { | |
goog.global.console && (goog.global.console.timeStamp ? goog.global.console.timeStamp(msg) : goog.global.console.markTimeline && goog.global.console.markTimeline(msg)); | |
goog.global.msWriteProfilerMark && goog.global.msWriteProfilerMark(msg); | |
}; | |
goog.debug.Logger.prototype.addHandler = function(handler) { | |
goog.debug.LOGGING_ENABLED && (goog.debug.Logger.ENABLE_HIERARCHY ? (this.handlers_ || (this.handlers_ = []), this.handlers_.push(handler)) : (goog.asserts.assert(!this.name_, "Cannot call addHandler on a non-root logger when goog.debug.Logger.ENABLE_HIERARCHY is false."), goog.debug.Logger.rootHandlers_.push(handler))); | |
}; | |
goog.debug.Logger.prototype.removeHandler = function(handler) { | |
if (goog.debug.LOGGING_ENABLED) { | |
var handlers = goog.debug.Logger.ENABLE_HIERARCHY ? this.handlers_ : goog.debug.Logger.rootHandlers_; | |
return!!handlers && goog.array.remove(handlers, handler); | |
} | |
return!1; | |
}; | |
goog.debug.Logger.prototype.getParent = function() { | |
return this.parent_; | |
}; | |
goog.debug.Logger.prototype.getChildren = function() { | |
this.children_ || (this.children_ = {}); | |
return this.children_; | |
}; | |
goog.debug.Logger.prototype.setLevel = function(level) { | |
goog.debug.LOGGING_ENABLED && (goog.debug.Logger.ENABLE_HIERARCHY ? this.level_ = level : (goog.asserts.assert(!this.name_, "Cannot call setLevel() on a non-root logger when goog.debug.Logger.ENABLE_HIERARCHY is false."), goog.debug.Logger.rootLevel_ = level)); | |
}; | |
var JSCompiler_StaticMethods_getEffectiveLevel = function(JSCompiler_StaticMethods_getEffectiveLevel$self) { | |
if (!goog.debug.LOGGING_ENABLED) { | |
return goog.debug.Logger.Level.OFF; | |
} | |
if (!goog.debug.Logger.ENABLE_HIERARCHY) { | |
return goog.debug.Logger.rootLevel_; | |
} | |
if (JSCompiler_StaticMethods_getEffectiveLevel$self.level_) { | |
return JSCompiler_StaticMethods_getEffectiveLevel$self.level_; | |
} | |
if (JSCompiler_StaticMethods_getEffectiveLevel$self.parent_) { | |
return JSCompiler_StaticMethods_getEffectiveLevel(JSCompiler_StaticMethods_getEffectiveLevel$self.parent_); | |
} | |
goog.asserts.fail("Root logger has no level set."); | |
return null; | |
}, JSCompiler_StaticMethods_isLoggable = function(JSCompiler_StaticMethods_isLoggable$self, level) { | |
return goog.debug.LOGGING_ENABLED && level.value >= JSCompiler_StaticMethods_getEffectiveLevel(JSCompiler_StaticMethods_isLoggable$self).value; | |
}; | |
goog.debug.Logger.prototype.log = function(level, msg, opt_exception) { | |
goog.debug.LOGGING_ENABLED && JSCompiler_StaticMethods_isLoggable(this, level) && (goog.isFunction(msg) && (msg = msg()), JSCompiler_StaticMethods_doLogRecord_(this, this.getLogRecord(level, msg, opt_exception, goog.debug.Logger.prototype.log))); | |
}; | |
goog.debug.Logger.prototype.getLogRecord = function(level, msg, opt_exception, opt_fnStackContext) { | |
var logRecord = goog.debug.LogBuffer.isBufferingEnabled() ? JSCompiler_StaticMethods_addRecord(goog.debug.LogBuffer.getInstance(), level, msg, this.name_) : new goog.debug.LogRecord(level, String(msg), this.name_); | |
opt_exception && (JSCompiler_StaticMethods_setException(logRecord, opt_exception), JSCompiler_StaticMethods_setExceptionText(logRecord, goog.debug.exposeException(opt_exception, opt_fnStackContext || goog.debug.Logger.prototype.getLogRecord))); | |
return logRecord; | |
}; | |
var JSCompiler_StaticMethods_severe = function(JSCompiler_StaticMethods_severe$self, msg, opt_exception) { | |
goog.debug.LOGGING_ENABLED && JSCompiler_StaticMethods_severe$self.log(goog.debug.Logger.Level.SEVERE, msg, opt_exception); | |
}; | |
goog.debug.Logger.prototype.warning = function(msg, opt_exception) { | |
goog.debug.LOGGING_ENABLED && this.log(goog.debug.Logger.Level.WARNING, msg, opt_exception); | |
}; | |
goog.debug.Logger.prototype.info = function(msg, opt_exception) { | |
goog.debug.LOGGING_ENABLED && this.log(goog.debug.Logger.Level.INFO, msg, opt_exception); | |
}; | |
goog.debug.Logger.prototype.fine = function(msg, opt_exception) { | |
goog.debug.LOGGING_ENABLED && this.log(goog.debug.Logger.Level.FINE, msg, opt_exception); | |
}; | |
var JSCompiler_StaticMethods_doLogRecord_ = function(JSCompiler_StaticMethods_doLogRecord_$self, logRecord) { | |
goog.debug.Logger.logToProfilers("log:" + logRecord.getMessage()); | |
if (goog.debug.Logger.ENABLE_HIERARCHY) { | |
for (var target = JSCompiler_StaticMethods_doLogRecord_$self;target;) { | |
JSCompiler_StaticMethods_callPublish_(target, logRecord), target = target.getParent(); | |
} | |
} else { | |
for (var i = 0, handler;handler = goog.debug.Logger.rootHandlers_[i++];) { | |
handler(logRecord); | |
} | |
} | |
}, JSCompiler_StaticMethods_callPublish_ = function(JSCompiler_StaticMethods_callPublish_$self, logRecord) { | |
if (JSCompiler_StaticMethods_callPublish_$self.handlers_) { | |
for (var i = 0, handler;handler = JSCompiler_StaticMethods_callPublish_$self.handlers_[i];i++) { | |
handler(logRecord); | |
} | |
} | |
}, JSCompiler_StaticMethods_setParent_ = function(JSCompiler_StaticMethods_setParent_$self, parent) { | |
JSCompiler_StaticMethods_setParent_$self.parent_ = parent; | |
}, JSCompiler_StaticMethods_addChild_ = function(JSCompiler_StaticMethods_addChild_$self, name, logger) { | |
JSCompiler_StaticMethods_addChild_$self.getChildren()[name] = logger; | |
}; | |
goog.debug.LogManager = {}; | |
goog.debug.LogManager.loggers_ = {}; | |
goog.debug.LogManager.rootLogger_ = null; | |
goog.debug.LogManager.initialize = function() { | |
goog.debug.LogManager.rootLogger_ || (goog.debug.LogManager.rootLogger_ = new goog.debug.Logger(goog.debug.Logger.ROOT_LOGGER_NAME), goog.debug.LogManager.loggers_[goog.debug.Logger.ROOT_LOGGER_NAME] = goog.debug.LogManager.rootLogger_, goog.debug.LogManager.rootLogger_.setLevel(goog.debug.Logger.Level.CONFIG)); | |
}; | |
goog.debug.LogManager.getLoggers = function() { | |
return goog.debug.LogManager.loggers_; | |
}; | |
goog.debug.LogManager.getRoot = function() { | |
goog.debug.LogManager.initialize(); | |
return goog.debug.LogManager.rootLogger_; | |
}; | |
goog.debug.LogManager.getLogger = function(name) { | |
goog.debug.LogManager.initialize(); | |
return goog.debug.LogManager.loggers_[name] || goog.debug.LogManager.createLogger_(name); | |
}; | |
goog.debug.LogManager.createFunctionForCatchErrors = function(opt_logger) { | |
return function(info) { | |
JSCompiler_StaticMethods_severe(opt_logger || goog.debug.LogManager.getRoot(), "Error: " + info.message + " (" + info.fileName + " @ Line: " + info.line + ")"); | |
}; | |
}; | |
goog.debug.LogManager.createLogger_ = function(name) { | |
var logger = new goog.debug.Logger(name); | |
if (goog.debug.Logger.ENABLE_HIERARCHY) { | |
var lastDotIndex = name.lastIndexOf("."), leafName = name.substr(lastDotIndex + 1), parentLogger = goog.debug.LogManager.getLogger(name.substr(0, lastDotIndex)); | |
JSCompiler_StaticMethods_addChild_(parentLogger, leafName, logger); | |
JSCompiler_StaticMethods_setParent_(logger, parentLogger); | |
} | |
return goog.debug.LogManager.loggers_[name] = logger; | |
}; | |
goog.log = {}; | |
goog.log.ENABLED = goog.debug.LOGGING_ENABLED; | |
goog.log.ROOT_LOGGER_NAME = goog.debug.Logger.ROOT_LOGGER_NAME; | |
goog.log.Logger = goog.debug.Logger; | |
goog.log.Level = goog.debug.Logger.Level; | |
goog.log.LogRecord = goog.debug.LogRecord; | |
goog.log.getLogger = function(name, opt_level) { | |
if (goog.log.ENABLED) { | |
var logger = goog.debug.LogManager.getLogger(name); | |
opt_level && logger && logger.setLevel(opt_level); | |
return logger; | |
} | |
return null; | |
}; | |
goog.log.addHandler = function(logger, handler) { | |
goog.log.ENABLED && logger && logger.addHandler(handler); | |
}; | |
goog.log.removeHandler = function(logger, handler) { | |
return goog.log.ENABLED && logger ? logger.removeHandler(handler) : !1; | |
}; | |
goog.log.log = function(logger, level, msg, opt_exception) { | |
goog.log.ENABLED && logger && logger.log(level, msg, opt_exception); | |
}; | |
goog.log.error = function(logger, msg, opt_exception) { | |
goog.log.ENABLED && logger && JSCompiler_StaticMethods_severe(logger, msg, opt_exception); | |
}; | |
goog.log.warning = function(logger, msg, opt_exception) { | |
goog.log.ENABLED && logger && logger.warning(msg, opt_exception); | |
}; | |
goog.log.info = function(logger, msg, opt_exception) { | |
goog.log.ENABLED && logger && logger.info(msg, opt_exception); | |
}; | |
goog.log.fine = function(logger, msg, opt_exception) { | |
goog.log.ENABLED && logger && logger.fine(msg, opt_exception); | |
}; | |
goog.uri = {}; | |
goog.uri.utils = {}; | |
goog.uri.utils.CharCode_ = {AMPERSAND:38, EQUAL:61, HASH:35, QUESTION:63}; | |
goog.uri.utils.buildFromEncodedParts = function(opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_queryData, opt_fragment) { | |
var out = ""; | |
opt_scheme && (out += opt_scheme + ":"); | |
opt_domain && (out += "//", opt_userInfo && (out += opt_userInfo + "@"), out += opt_domain, opt_port && (out += ":" + opt_port)); | |
opt_path && (out += opt_path); | |
opt_queryData && (out += "?" + opt_queryData); | |
opt_fragment && (out += "#" + opt_fragment); | |
return out; | |
}; | |
goog.uri.utils.splitRe_ = RegExp("^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#(.*))?$"); | |
goog.uri.utils.ComponentIndex = {SCHEME:1, USER_INFO:2, DOMAIN:3, PORT:4, PATH:5, QUERY_DATA:6, FRAGMENT:7}; | |
goog.uri.utils.split = function(uri) { | |
goog.uri.utils.phishingProtection_(); | |
return uri.match(goog.uri.utils.splitRe_); | |
}; | |
goog.uri.utils.needsPhishingProtection_ = goog.userAgent.WEBKIT; | |
goog.uri.utils.phishingProtection_ = function() { | |
if (goog.uri.utils.needsPhishingProtection_) { | |
goog.uri.utils.needsPhishingProtection_ = !1; | |
var location = goog.global.location; | |
if (location) { | |
var href = location.href; | |
if (href) { | |
var domain = goog.uri.utils.getDomain(href); | |
if (domain && domain != location.hostname) { | |
throw goog.uri.utils.needsPhishingProtection_ = !0, Error(); | |
} | |
} | |
} | |
} | |
}; | |
goog.uri.utils.decodeIfPossible_ = function(uri) { | |
return uri && decodeURIComponent(uri); | |
}; | |
goog.uri.utils.getComponentByIndex_ = function(componentIndex, uri) { | |
return goog.uri.utils.split(uri)[componentIndex] || null; | |
}; | |
goog.uri.utils.getScheme = function(uri) { | |
return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.SCHEME, uri); | |
}; | |
goog.uri.utils.getEffectiveScheme = function(uri) { | |
var scheme = goog.uri.utils.getScheme(uri); | |
if (!scheme && self.location) { | |
var protocol = self.location.protocol, scheme = protocol.substr(0, protocol.length - 1) | |
} | |
return scheme ? scheme.toLowerCase() : ""; | |
}; | |
goog.uri.utils.getUserInfoEncoded = function(uri) { | |
return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.USER_INFO, uri); | |
}; | |
goog.uri.utils.getUserInfo = function(uri) { | |
return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getUserInfoEncoded(uri)); | |
}; | |
goog.uri.utils.getDomainEncoded = function(uri) { | |
return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.DOMAIN, uri); | |
}; | |
goog.uri.utils.getDomain = function(uri) { | |
return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getDomainEncoded(uri)); | |
}; | |
goog.uri.utils.getPort = function(uri) { | |
return Number(goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.PORT, uri)) || null; | |
}; | |
goog.uri.utils.getPathEncoded = function(uri) { | |
return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.PATH, uri); | |
}; | |
goog.uri.utils.getPath = function(uri) { | |
return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getPathEncoded(uri)); | |
}; | |
goog.uri.utils.getQueryData = function(uri) { | |
return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.QUERY_DATA, uri); | |
}; | |
goog.uri.utils.getFragmentEncoded = function(uri) { | |
var hashIndex = uri.indexOf("#"); | |
return 0 > hashIndex ? null : uri.substr(hashIndex + 1); | |
}; | |
goog.uri.utils.setFragmentEncoded = function(uri, fragment) { | |
return goog.uri.utils.removeFragment(uri) + (fragment ? "#" + fragment : ""); | |
}; | |
goog.uri.utils.getFragment = function(uri) { | |
return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getFragmentEncoded(uri)); | |
}; | |
goog.uri.utils.getHost = function(uri) { | |
var pieces = goog.uri.utils.split(uri); | |
return goog.uri.utils.buildFromEncodedParts(pieces[goog.uri.utils.ComponentIndex.SCHEME], pieces[goog.uri.utils.ComponentIndex.USER_INFO], pieces[goog.uri.utils.ComponentIndex.DOMAIN], pieces[goog.uri.utils.ComponentIndex.PORT]); | |
}; | |
goog.uri.utils.getPathAndAfter = function(uri) { | |
var pieces = goog.uri.utils.split(uri); | |
return goog.uri.utils.buildFromEncodedParts(null, null, null, null, pieces[goog.uri.utils.ComponentIndex.PATH], pieces[goog.uri.utils.ComponentIndex.QUERY_DATA], pieces[goog.uri.utils.ComponentIndex.FRAGMENT]); | |
}; | |
goog.uri.utils.removeFragment = function(uri) { | |
var hashIndex = uri.indexOf("#"); | |
return 0 > hashIndex ? uri : uri.substr(0, hashIndex); | |
}; | |
goog.uri.utils.haveSameDomain = function(uri1, uri2) { | |
var pieces1 = goog.uri.utils.split(uri1), pieces2 = goog.uri.utils.split(uri2); | |
return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] == pieces2[goog.uri.utils.ComponentIndex.DOMAIN] && pieces1[goog.uri.utils.ComponentIndex.SCHEME] == pieces2[goog.uri.utils.ComponentIndex.SCHEME] && pieces1[goog.uri.utils.ComponentIndex.PORT] == pieces2[goog.uri.utils.ComponentIndex.PORT]; | |
}; | |
goog.uri.utils.assertNoFragmentsOrQueries_ = function(uri) { | |
if (goog.DEBUG && (0 <= uri.indexOf("#") || 0 <= uri.indexOf("?"))) { | |
throw Error("goog.uri.utils: Fragment or query identifiers are not supported: [" + uri + "]"); | |
} | |
}; | |
goog.uri.utils.appendQueryData_ = function(buffer) { | |
if (buffer[1]) { | |
var baseUri = buffer[0], hashIndex = baseUri.indexOf("#"); | |
0 <= hashIndex && (buffer.push(baseUri.substr(hashIndex)), buffer[0] = baseUri = baseUri.substr(0, hashIndex)); | |
var questionIndex = baseUri.indexOf("?"); | |
0 > questionIndex ? buffer[1] = "?" : questionIndex == baseUri.length - 1 && (buffer[1] = void 0); | |
} | |
return buffer.join(""); | |
}; | |
goog.uri.utils.appendKeyValuePairs_ = function(key, value, pairs) { | |
if (goog.isArray(value)) { | |
goog.asserts.assertArray(value); | |
for (var j = 0;j < value.length;j++) { | |
goog.uri.utils.appendKeyValuePairs_(key, String(value[j]), pairs); | |
} | |
} else { | |
null != value && pairs.push("&", key, "" === value ? "" : "=", goog.string.urlEncode(value)); | |
} | |
}; | |
goog.uri.utils.buildQueryDataBuffer_ = function(buffer, keysAndValues, opt_startIndex) { | |
goog.asserts.assert(0 == Math.max(keysAndValues.length - (opt_startIndex || 0), 0) % 2, "goog.uri.utils: Key/value lists must be even in length."); | |
for (var i = opt_startIndex || 0;i < keysAndValues.length;i += 2) { | |
goog.uri.utils.appendKeyValuePairs_(keysAndValues[i], keysAndValues[i + 1], buffer); | |
} | |
return buffer; | |
}; | |
goog.uri.utils.buildQueryData = function(keysAndValues, opt_startIndex) { | |
var buffer = goog.uri.utils.buildQueryDataBuffer_([], keysAndValues, opt_startIndex); | |
buffer[0] = ""; | |
return buffer.join(""); | |
}; | |
goog.uri.utils.buildQueryDataBufferFromMap_ = function(buffer, map) { | |
for (var key in map) { | |
goog.uri.utils.appendKeyValuePairs_(key, map[key], buffer); | |
} | |
return buffer; | |
}; | |
goog.uri.utils.buildQueryDataFromMap = function(map) { | |
var buffer = goog.uri.utils.buildQueryDataBufferFromMap_([], map); | |
buffer[0] = ""; | |
return buffer.join(""); | |
}; | |
goog.uri.utils.appendParams = function(uri, var_args) { | |
return goog.uri.utils.appendQueryData_(2 == arguments.length ? goog.uri.utils.buildQueryDataBuffer_([uri], arguments[1], 0) : goog.uri.utils.buildQueryDataBuffer_([uri], arguments, 1)); | |
}; | |
goog.uri.utils.appendParamsFromMap = function(uri, map) { | |
return goog.uri.utils.appendQueryData_(goog.uri.utils.buildQueryDataBufferFromMap_([uri], map)); | |
}; | |
goog.uri.utils.appendParam = function(uri, key, opt_value) { | |
var paramArr = [uri, "&", key]; | |
goog.isDefAndNotNull(opt_value) && paramArr.push("=", goog.string.urlEncode(opt_value)); | |
return goog.uri.utils.appendQueryData_(paramArr); | |
}; | |
goog.uri.utils.findParam_ = function(uri, startIndex, keyEncoded, hashOrEndIndex) { | |
for (var index = startIndex, keyLength = keyEncoded.length;0 <= (index = uri.indexOf(keyEncoded, index)) && index < hashOrEndIndex;) { | |
var precedingChar = uri.charCodeAt(index - 1); | |
if (precedingChar == goog.uri.utils.CharCode_.AMPERSAND || precedingChar == goog.uri.utils.CharCode_.QUESTION) { | |
var followingChar = uri.charCodeAt(index + keyLength); | |
if (!followingChar || followingChar == goog.uri.utils.CharCode_.EQUAL || followingChar == goog.uri.utils.CharCode_.AMPERSAND || followingChar == goog.uri.utils.CharCode_.HASH) { | |
return index; | |
} | |
} | |
index += keyLength + 1; | |
} | |
return-1; | |
}; | |
goog.uri.utils.hashOrEndRe_ = /#|$/; | |
goog.uri.utils.hasParam = function(uri, keyEncoded) { | |
return 0 <= goog.uri.utils.findParam_(uri, 0, keyEncoded, uri.search(goog.uri.utils.hashOrEndRe_)); | |
}; | |
goog.uri.utils.getParamValue = function(uri, keyEncoded) { | |
var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_), foundIndex = goog.uri.utils.findParam_(uri, 0, keyEncoded, hashOrEndIndex); | |
if (0 > foundIndex) { | |
return null; | |
} | |
var endPosition = uri.indexOf("&", foundIndex); | |
if (0 > endPosition || endPosition > hashOrEndIndex) { | |
endPosition = hashOrEndIndex; | |
} | |
foundIndex += keyEncoded.length + 1; | |
return goog.string.urlDecode(uri.substr(foundIndex, endPosition - foundIndex)); | |
}; | |
goog.uri.utils.getParamValues = function(uri, keyEncoded) { | |
for (var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_), position = 0, foundIndex, result = [];0 <= (foundIndex = goog.uri.utils.findParam_(uri, position, keyEncoded, hashOrEndIndex));) { | |
position = uri.indexOf("&", foundIndex); | |
if (0 > position || position > hashOrEndIndex) { | |
position = hashOrEndIndex; | |
} | |
foundIndex += keyEncoded.length + 1; | |
result.push(goog.string.urlDecode(uri.substr(foundIndex, position - foundIndex))); | |
} | |
return result; | |
}; | |
goog.uri.utils.trailingQueryPunctuationRe_ = /[?&]($|#)/; | |
goog.uri.utils.removeParam = function(uri, keyEncoded) { | |
for (var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_), position = 0, foundIndex, buffer = [];0 <= (foundIndex = goog.uri.utils.findParam_(uri, position, keyEncoded, hashOrEndIndex));) { | |
buffer.push(uri.substring(position, foundIndex)), position = Math.min(uri.indexOf("&", foundIndex) + 1 || hashOrEndIndex, hashOrEndIndex); | |
} | |
buffer.push(uri.substr(position)); | |
return buffer.join("").replace(goog.uri.utils.trailingQueryPunctuationRe_, "$1"); | |
}; | |
goog.uri.utils.setParam = function(uri, keyEncoded, value) { | |
return goog.uri.utils.appendParam(goog.uri.utils.removeParam(uri, keyEncoded), keyEncoded, value); | |
}; | |
goog.uri.utils.appendPath = function(baseUri, path) { | |
goog.uri.utils.assertNoFragmentsOrQueries_(baseUri); | |
goog.string.endsWith(baseUri) && (baseUri = baseUri.substr(0, baseUri.length - 1)); | |
goog.string.startsWith(path) && (path = path.substr(1)); | |
return goog.string.buildString(baseUri, "/", path); | |
}; | |
goog.uri.utils.setPath = function(uri, path) { | |
goog.string.startsWith(path) || (path = "/" + path); | |
var parts = goog.uri.utils.split(uri); | |
return goog.uri.utils.buildFromEncodedParts(parts[goog.uri.utils.ComponentIndex.SCHEME], parts[goog.uri.utils.ComponentIndex.USER_INFO], parts[goog.uri.utils.ComponentIndex.DOMAIN], parts[goog.uri.utils.ComponentIndex.PORT], path, parts[goog.uri.utils.ComponentIndex.QUERY_DATA], parts[goog.uri.utils.ComponentIndex.FRAGMENT]); | |
}; | |
goog.uri.utils.StandardQueryParam = {RANDOM:"zx"}; | |
goog.uri.utils.makeUnique = function(uri) { | |
return goog.uri.utils.setParam(uri, goog.uri.utils.StandardQueryParam.RANDOM, goog.string.getRandomString()); | |
}; | |
goog.net = {}; | |
goog.net.ErrorCode = {NO_ERROR:0, ACCESS_DENIED:1, FILE_NOT_FOUND:2, FF_SILENT_ERROR:3, CUSTOM_ERROR:4, EXCEPTION:5, HTTP_ERROR:6, ABORT:7, TIMEOUT:8, OFFLINE:9}; | |
goog.net.ErrorCode.getDebugMessage = function(errorCode) { | |
switch(errorCode) { | |
case goog.net.ErrorCode.NO_ERROR: | |
return "No Error"; | |
case goog.net.ErrorCode.ACCESS_DENIED: | |
return "Access denied to content document"; | |
case goog.net.ErrorCode.FILE_NOT_FOUND: | |
return "File not found"; | |
case goog.net.ErrorCode.FF_SILENT_ERROR: | |
return "Firefox silently errored"; | |
case goog.net.ErrorCode.CUSTOM_ERROR: | |
return "Application custom error"; | |
case goog.net.ErrorCode.EXCEPTION: | |
return "An exception occurred"; | |
case goog.net.ErrorCode.HTTP_ERROR: | |
return "Http response at 400 or 500 level"; | |
case goog.net.ErrorCode.ABORT: | |
return "Request was aborted"; | |
case goog.net.ErrorCode.TIMEOUT: | |
return "Request timed out"; | |
case goog.net.ErrorCode.OFFLINE: | |
return "The resource is not available offline"; | |
default: | |
return "Unrecognized error code"; | |
} | |
}; | |
goog.net.EventType = {COMPLETE:"complete", SUCCESS:"success", ERROR:"error", ABORT:"abort", READY:"ready", READY_STATE_CHANGE:"readystatechange", TIMEOUT:"timeout", INCREMENTAL_DATA:"incrementaldata", PROGRESS:"progress"}; | |
goog.net.HttpStatus = {CONTINUE:100, SWITCHING_PROTOCOLS:101, OK:200, CREATED:201, ACCEPTED:202, NON_AUTHORITATIVE_INFORMATION:203, NO_CONTENT:204, RESET_CONTENT:205, PARTIAL_CONTENT:206, MULTIPLE_CHOICES:300, MOVED_PERMANENTLY:301, FOUND:302, SEE_OTHER:303, NOT_MODIFIED:304, USE_PROXY:305, TEMPORARY_REDIRECT:307, BAD_REQUEST:400, UNAUTHORIZED:401, PAYMENT_REQUIRED:402, FORBIDDEN:403, NOT_FOUND:404, METHOD_NOT_ALLOWED:405, NOT_ACCEPTABLE:406, PROXY_AUTHENTICATION_REQUIRED:407, REQUEST_TIMEOUT:408, | |
CONFLICT:409, GONE:410, LENGTH_REQUIRED:411, PRECONDITION_FAILED:412, REQUEST_ENTITY_TOO_LARGE:413, REQUEST_URI_TOO_LONG:414, UNSUPPORTED_MEDIA_TYPE:415, REQUEST_RANGE_NOT_SATISFIABLE:416, EXPECTATION_FAILED:417, INTERNAL_SERVER_ERROR:500, NOT_IMPLEMENTED:501, BAD_GATEWAY:502, SERVICE_UNAVAILABLE:503, GATEWAY_TIMEOUT:504, HTTP_VERSION_NOT_SUPPORTED:505, QUIRK_IE_NO_CONTENT:1223}; | |
goog.net.HttpStatus.isSuccess = function(status) { | |
switch(status) { | |
case goog.net.HttpStatus.OK: | |
; | |
case goog.net.HttpStatus.CREATED: | |
; | |
case goog.net.HttpStatus.ACCEPTED: | |
; | |
case goog.net.HttpStatus.NO_CONTENT: | |
; | |
case goog.net.HttpStatus.PARTIAL_CONTENT: | |
; | |
case goog.net.HttpStatus.NOT_MODIFIED: | |
; | |
case goog.net.HttpStatus.QUIRK_IE_NO_CONTENT: | |
return!0; | |
default: | |
return!1; | |
} | |
}; | |
goog.net.XhrLike = function() { | |
}; | |
goog.net.XhrLike.prototype.open = function() { | |
}; | |
goog.net.XhrLike.prototype.send = function() { | |
}; | |
goog.net.XhrLike.prototype.abort = function() { | |
}; | |
goog.net.XhrLike.prototype.setRequestHeader = function() { | |
}; | |
goog.net.XmlHttpFactory = function() { | |
}; | |
goog.net.XmlHttpFactory.prototype.cachedOptions_ = null; | |
goog.net.XmlHttpFactory.prototype.getOptions = function() { | |
return this.cachedOptions_ || (this.cachedOptions_ = JSCompiler_StaticMethods_internalGetOptions(this)); | |
}; | |
goog.net.WrapperXmlHttpFactory = function(xhrFactory, optionsFactory) { | |
this.xhrFactory_ = xhrFactory; | |
this.optionsFactory_ = optionsFactory; | |
}; | |
goog.inherits(goog.net.WrapperXmlHttpFactory, goog.net.XmlHttpFactory); | |
goog.net.WrapperXmlHttpFactory.prototype.createInstance = function() { | |
return this.xhrFactory_(); | |
}; | |
goog.net.WrapperXmlHttpFactory.prototype.getOptions = function() { | |
return this.optionsFactory_(); | |
}; | |
goog.net.XmlHttp = function() { | |
return goog.net.XmlHttp.factory_.createInstance(); | |
}; | |
goog.net.XmlHttp.ASSUME_NATIVE_XHR = !1; | |
goog.net.XmlHttpDefines = {}; | |
goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR = !1; | |
goog.net.XmlHttp.getOptions = function() { | |
return goog.net.XmlHttp.factory_.getOptions(); | |
}; | |
goog.net.XmlHttp.OptionType = {USE_NULL_FUNCTION:0, LOCAL_REQUEST_ERROR:1}; | |
goog.net.XmlHttp.ReadyState = {UNINITIALIZED:0, LOADING:1, LOADED:2, INTERACTIVE:3, COMPLETE:4}; | |
goog.net.XmlHttp.setFactory = function(factory, optionsFactory) { | |
goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory(goog.asserts.assert(factory), goog.asserts.assert(optionsFactory))); | |
}; | |
goog.net.XmlHttp.setGlobalFactory = function(factory) { | |
goog.net.XmlHttp.factory_ = factory; | |
}; | |
goog.net.DefaultXmlHttpFactory = function() { | |
}; | |
goog.inherits(goog.net.DefaultXmlHttpFactory, goog.net.XmlHttpFactory); | |
goog.net.DefaultXmlHttpFactory.prototype.createInstance = function() { | |
var progId = JSCompiler_StaticMethods_getProgId_(this); | |
return progId ? new ActiveXObject(progId) : new XMLHttpRequest; | |
}; | |
var JSCompiler_StaticMethods_internalGetOptions = function(JSCompiler_StaticMethods_internalGetOptions$self) { | |
var options = {}; | |
JSCompiler_StaticMethods_getProgId_(JSCompiler_StaticMethods_internalGetOptions$self) && (options[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] = !0, options[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] = !0); | |
return options; | |
}, JSCompiler_StaticMethods_getProgId_ = function(JSCompiler_StaticMethods_getProgId_$self) { | |
if (goog.net.XmlHttp.ASSUME_NATIVE_XHR || goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR) { | |
return ""; | |
} | |
if (!JSCompiler_StaticMethods_getProgId_$self.ieProgId_ && "undefined" == typeof XMLHttpRequest && "undefined" != typeof ActiveXObject) { | |
for (var ACTIVE_X_IDENTS = ["MSXML2.XMLHTTP.6.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"], i = 0;i < ACTIVE_X_IDENTS.length;i++) { | |
var candidate = ACTIVE_X_IDENTS[i]; | |
try { | |
return new ActiveXObject(candidate), JSCompiler_StaticMethods_getProgId_$self.ieProgId_ = candidate; | |
} catch (e) { | |
} | |
} | |
throw Error("Could not create ActiveXObject. ActiveX might be disabled, or MSXML might not be installed"); | |
} | |
return JSCompiler_StaticMethods_getProgId_$self.ieProgId_; | |
}; | |
goog.net.XmlHttp.setGlobalFactory(new goog.net.DefaultXmlHttpFactory); | |
goog.net.XhrIo = function(opt_xmlHttpFactory) { | |
goog.events.EventTarget.call(this); | |
this.headers = new goog.structs.Map; | |
this.xmlHttpFactory_ = opt_xmlHttpFactory || null; | |
this.active_ = !1; | |
this.xhrOptions_ = this.xhr_ = null; | |
this.lastError_ = this.lastMethod_ = this.lastUri_ = ""; | |
this.inAbort_ = this.inOpen_ = this.inSend_ = this.errorDispatched_ = !1; | |
this.timeoutInterval_ = 0; | |
this.timeoutId_ = null; | |
this.responseType_ = goog.net.XhrIo.ResponseType.DEFAULT; | |
this.useXhr2Timeout_ = this.withCredentials_ = !1; | |
}; | |
goog.inherits(goog.net.XhrIo, goog.events.EventTarget); | |
goog.net.XhrIo.ResponseType = {DEFAULT:"", TEXT:"text", DOCUMENT:"document", BLOB:"blob", ARRAY_BUFFER:"arraybuffer"}; | |
goog.net.XhrIo.prototype.logger_ = goog.log.getLogger("goog.net.XhrIo"); | |
goog.net.XhrIo.CONTENT_TYPE_HEADER = "Content-Type"; | |
goog.net.XhrIo.HTTP_SCHEME_PATTERN = /^https?$/i; | |
goog.net.XhrIo.METHODS_WITH_FORM_DATA = ["POST", "PUT"]; | |
goog.net.XhrIo.FORM_CONTENT_TYPE = "application/x-www-form-urlencoded;charset=utf-8"; | |
goog.net.XhrIo.XHR2_TIMEOUT_ = "timeout"; | |
goog.net.XhrIo.XHR2_ON_TIMEOUT_ = "ontimeout"; | |
goog.net.XhrIo.sendInstances_ = []; | |
goog.net.XhrIo.send = function(url, opt_callback, opt_method, opt_content, opt_headers, opt_timeoutInterval, opt_withCredentials) { | |
var x = new goog.net.XhrIo; | |
goog.net.XhrIo.sendInstances_.push(x); | |
opt_callback && x.listen(goog.net.EventType.COMPLETE, opt_callback); | |
x.listenOnce(goog.net.EventType.READY, x.cleanupSend_); | |
opt_timeoutInterval && JSCompiler_StaticMethods_setTimeoutInterval(x, opt_timeoutInterval); | |
opt_withCredentials && JSCompiler_StaticMethods_setWithCredentials(x, opt_withCredentials); | |
x.send(url, opt_method, opt_content, opt_headers); | |
}; | |
goog.net.XhrIo.cleanup = function() { | |
for (var instances = goog.net.XhrIo.sendInstances_;instances.length;) { | |
instances.pop().dispose(); | |
} | |
}; | |
goog.net.XhrIo.protectEntryPoints = function(errorHandler) { | |
goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = errorHandler.protectEntryPoint(goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_); | |
}; | |
goog.net.XhrIo.prototype.cleanupSend_ = function() { | |
this.dispose(); | |
goog.array.remove(goog.net.XhrIo.sendInstances_, this); | |
}; | |
var JSCompiler_StaticMethods_setTimeoutInterval = function(JSCompiler_StaticMethods_setTimeoutInterval$self, ms) { | |
JSCompiler_StaticMethods_setTimeoutInterval$self.timeoutInterval_ = Math.max(0, ms); | |
}, JSCompiler_StaticMethods_setWithCredentials = function(JSCompiler_StaticMethods_setWithCredentials$self, withCredentials) { | |
JSCompiler_StaticMethods_setWithCredentials$self.withCredentials_ = withCredentials; | |
}; | |
goog.net.XhrIo.prototype.send = function(url, opt_method, opt_content, opt_headers) { | |
if (this.xhr_) { | |
throw Error("[goog.net.XhrIo] Object is active with another request=" + this.lastUri_ + "; newUri=" + url); | |
} | |
var method = opt_method ? opt_method.toUpperCase() : "GET"; | |
this.lastUri_ = url; | |
this.lastError_ = ""; | |
this.lastMethod_ = method; | |
this.errorDispatched_ = !1; | |
this.active_ = !0; | |
this.xhr_ = JSCompiler_StaticMethods_createXhr(this); | |
this.xhrOptions_ = this.xmlHttpFactory_ ? this.xmlHttpFactory_.getOptions() : goog.net.XmlHttp.getOptions(); | |
this.xhr_.onreadystatechange = goog.bind(this.onReadyStateChange_, this); | |
try { | |
goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Opening Xhr")), this.inOpen_ = !0, this.xhr_.open(method, String(url), !0), this.inOpen_ = !1; | |
} catch (err) { | |
goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Error opening Xhr: " + err.message)); | |
JSCompiler_StaticMethods_error_(this, err); | |
return; | |
} | |
var content = opt_content || "", headers = this.headers.clone(); | |
opt_headers && goog.structs.forEach(opt_headers, function(value, key) { | |
headers.set(key, value); | |
}); | |
var contentTypeKey = goog.array.find(headers.getKeys(), goog.net.XhrIo.isContentTypeHeader_), contentIsFormData = goog.global.FormData && content instanceof goog.global.FormData; | |
!goog.array.contains(goog.net.XhrIo.METHODS_WITH_FORM_DATA, method) || contentTypeKey || contentIsFormData || headers.set(goog.net.XhrIo.CONTENT_TYPE_HEADER, goog.net.XhrIo.FORM_CONTENT_TYPE); | |
headers.forEach(function(value, key) { | |
this.xhr_.setRequestHeader(key, value); | |
}, this); | |
this.responseType_ && (this.xhr_.responseType = this.responseType_); | |
goog.object.containsKey(this.xhr_, "withCredentials") && (this.xhr_.withCredentials = this.withCredentials_); | |
try { | |
JSCompiler_StaticMethods_cleanUpTimeoutTimer_(this), 0 < this.timeoutInterval_ && (this.useXhr2Timeout_ = goog.net.XhrIo.shouldUseXhr2Timeout_(this.xhr_), goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Will abort after " + this.timeoutInterval_ + "ms if incomplete, xhr2 " + this.useXhr2Timeout_)), this.useXhr2Timeout_ ? (this.xhr_[goog.net.XhrIo.XHR2_TIMEOUT_] = this.timeoutInterval_, this.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] = goog.bind(this.timeout_, this)) : this.timeoutId_ = | |
goog.Timer.callOnce(this.timeout_, this.timeoutInterval_, this)), goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Sending request")), this.inSend_ = !0, this.xhr_.send(content), this.inSend_ = !1; | |
} catch (err$$0) { | |
goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Send error: " + err$$0.message)), JSCompiler_StaticMethods_error_(this, err$$0); | |
} | |
}; | |
goog.net.XhrIo.shouldUseXhr2Timeout_ = function(xhr) { | |
return goog.userAgent.IE && goog.userAgent.isVersionOrHigher(9) && goog.isNumber(xhr[goog.net.XhrIo.XHR2_TIMEOUT_]) && goog.isDef(xhr[goog.net.XhrIo.XHR2_ON_TIMEOUT_]); | |
}; | |
goog.net.XhrIo.isContentTypeHeader_ = function(header) { | |
return goog.string.caseInsensitiveEquals(header); | |
}; | |
var JSCompiler_StaticMethods_createXhr = function(JSCompiler_StaticMethods_createXhr$self) { | |
return JSCompiler_StaticMethods_createXhr$self.xmlHttpFactory_ ? JSCompiler_StaticMethods_createXhr$self.xmlHttpFactory_.createInstance() : goog.net.XmlHttp(); | |
}; | |
goog.net.XhrIo.prototype.timeout_ = function() { | |
"undefined" != typeof goog && this.xhr_ && (this.lastError_ = "Timed out after " + this.timeoutInterval_ + "ms, aborting", goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, this.lastError_)), this.dispatchEvent(goog.net.EventType.TIMEOUT), this.abort(goog.net.ErrorCode.TIMEOUT)); | |
}; | |
var JSCompiler_StaticMethods_error_ = function(JSCompiler_StaticMethods_error_$self, err) { | |
JSCompiler_StaticMethods_error_$self.active_ = !1; | |
JSCompiler_StaticMethods_error_$self.xhr_ && (JSCompiler_StaticMethods_error_$self.inAbort_ = !0, JSCompiler_StaticMethods_error_$self.xhr_.abort(), JSCompiler_StaticMethods_error_$self.inAbort_ = !1); | |
JSCompiler_StaticMethods_error_$self.lastError_ = err; | |
JSCompiler_StaticMethods_dispatchErrors_(JSCompiler_StaticMethods_error_$self); | |
JSCompiler_StaticMethods_cleanUpXhr_(JSCompiler_StaticMethods_error_$self); | |
}, JSCompiler_StaticMethods_dispatchErrors_ = function(JSCompiler_StaticMethods_dispatchErrors_$self) { | |
JSCompiler_StaticMethods_dispatchErrors_$self.errorDispatched_ || (JSCompiler_StaticMethods_dispatchErrors_$self.errorDispatched_ = !0, JSCompiler_StaticMethods_dispatchErrors_$self.dispatchEvent(goog.net.EventType.COMPLETE), JSCompiler_StaticMethods_dispatchErrors_$self.dispatchEvent(goog.net.EventType.ERROR)); | |
}; | |
goog.net.XhrIo.prototype.abort = function() { | |
this.xhr_ && this.active_ && (goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Aborting")), this.active_ = !1, this.inAbort_ = !0, this.xhr_.abort(), this.inAbort_ = !1, this.dispatchEvent(goog.net.EventType.COMPLETE), this.dispatchEvent(goog.net.EventType.ABORT), JSCompiler_StaticMethods_cleanUpXhr_(this)); | |
}; | |
goog.net.XhrIo.prototype.disposeInternal = function() { | |
this.xhr_ && (this.active_ && (this.active_ = !1, this.inAbort_ = !0, this.xhr_.abort(), this.inAbort_ = !1), JSCompiler_StaticMethods_cleanUpXhr_(this, !0)); | |
goog.net.XhrIo.superClass_.disposeInternal.call(this); | |
}; | |
goog.net.XhrIo.prototype.onReadyStateChange_ = function() { | |
if (!this.isDisposed()) { | |
if (this.inOpen_ || this.inSend_ || this.inAbort_) { | |
JSCompiler_StaticMethods_onReadyStateChangeHelper_(this); | |
} else { | |
this.onReadyStateChangeEntryPoint_(); | |
} | |
} | |
}; | |
goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = function() { | |
JSCompiler_StaticMethods_onReadyStateChangeHelper_(this); | |
}; | |
var JSCompiler_StaticMethods_onReadyStateChangeHelper_ = function(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self) { | |
if (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.active_ && "undefined" != typeof goog) { | |
if (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.xhrOptions_[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] && JSCompiler_StaticMethods_getReadyState(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self) == goog.net.XmlHttp.ReadyState.COMPLETE && 2 == JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.getStatus()) { | |
goog.log.fine(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.logger_, JSCompiler_StaticMethods_formatMsg_(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self, "Local request error detected and ignored")); | |
} else { | |
if (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.inSend_ && JSCompiler_StaticMethods_getReadyState(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self) == goog.net.XmlHttp.ReadyState.COMPLETE) { | |
goog.Timer.callOnce(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.onReadyStateChange_, 0, JSCompiler_StaticMethods_onReadyStateChangeHelper_$self); | |
} else { | |
if (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.dispatchEvent(goog.net.EventType.READY_STATE_CHANGE), JSCompiler_StaticMethods_isComplete(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self)) { | |
goog.log.fine(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.logger_, JSCompiler_StaticMethods_formatMsg_(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self, "Request complete")); | |
JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.active_ = !1; | |
try { | |
JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.isSuccess() ? (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.dispatchEvent(goog.net.EventType.COMPLETE), JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.dispatchEvent(goog.net.EventType.SUCCESS)) : (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.lastError_ = JSCompiler_StaticMethods_getStatusText(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self) + " [" + JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.getStatus() + | |
"]", JSCompiler_StaticMethods_dispatchErrors_(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self)); | |
} finally { | |
JSCompiler_StaticMethods_cleanUpXhr_(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self); | |
} | |
} | |
} | |
} | |
} | |
}, JSCompiler_StaticMethods_cleanUpXhr_ = function(JSCompiler_StaticMethods_cleanUpXhr_$self, opt_fromDispose) { | |
if (JSCompiler_StaticMethods_cleanUpXhr_$self.xhr_) { | |
JSCompiler_StaticMethods_cleanUpTimeoutTimer_(JSCompiler_StaticMethods_cleanUpXhr_$self); | |
var xhr = JSCompiler_StaticMethods_cleanUpXhr_$self.xhr_, clearedOnReadyStateChange = JSCompiler_StaticMethods_cleanUpXhr_$self.xhrOptions_[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] ? goog.nullFunction : null; | |
JSCompiler_StaticMethods_cleanUpXhr_$self.xhr_ = null; | |
JSCompiler_StaticMethods_cleanUpXhr_$self.xhrOptions_ = null; | |
opt_fromDispose || JSCompiler_StaticMethods_cleanUpXhr_$self.dispatchEvent(goog.net.EventType.READY); | |
try { | |
xhr.onreadystatechange = clearedOnReadyStateChange; | |
} catch (e) { | |
goog.log.error(JSCompiler_StaticMethods_cleanUpXhr_$self.logger_, "Problem encountered resetting onreadystatechange: " + e.message); | |
} | |
} | |
}, JSCompiler_StaticMethods_cleanUpTimeoutTimer_ = function(JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self) { | |
JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.xhr_ && JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.useXhr2Timeout_ && (JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] = null); | |
goog.isNumber(JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.timeoutId_) && (goog.Timer.clear(JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.timeoutId_), JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.timeoutId_ = null); | |
}; | |
goog.net.XhrIo.prototype.isActive = function() { | |
return!!this.xhr_; | |
}; | |
var JSCompiler_StaticMethods_isComplete = function(JSCompiler_StaticMethods_isComplete$self) { | |
return JSCompiler_StaticMethods_getReadyState(JSCompiler_StaticMethods_isComplete$self) == goog.net.XmlHttp.ReadyState.COMPLETE; | |
}; | |
goog.net.XhrIo.prototype.isSuccess = function() { | |
var status = this.getStatus(); | |
return goog.net.HttpStatus.isSuccess(status) || 0 === status && !JSCompiler_StaticMethods_isLastUriEffectiveSchemeHttp_(this); | |
}; | |
var JSCompiler_StaticMethods_isLastUriEffectiveSchemeHttp_ = function(JSCompiler_StaticMethods_isLastUriEffectiveSchemeHttp_$self) { | |
var scheme = goog.uri.utils.getEffectiveScheme(String(JSCompiler_StaticMethods_isLastUriEffectiveSchemeHttp_$self.lastUri_)); | |
return goog.net.XhrIo.HTTP_SCHEME_PATTERN.test(scheme); | |
}, JSCompiler_StaticMethods_getReadyState = function(JSCompiler_StaticMethods_getReadyState$self) { | |
return JSCompiler_StaticMethods_getReadyState$self.xhr_ ? JSCompiler_StaticMethods_getReadyState$self.xhr_.readyState : goog.net.XmlHttp.ReadyState.UNINITIALIZED; | |
}; | |
goog.net.XhrIo.prototype.getStatus = function() { | |
try { | |
return JSCompiler_StaticMethods_getReadyState(this) > goog.net.XmlHttp.ReadyState.LOADED ? this.xhr_.status : -1; | |
} catch (e) { | |
return-1; | |
} | |
}; | |
var JSCompiler_StaticMethods_getStatusText = function(JSCompiler_StaticMethods_getStatusText$self) { | |
try { | |
return JSCompiler_StaticMethods_getReadyState(JSCompiler_StaticMethods_getStatusText$self) > goog.net.XmlHttp.ReadyState.LOADED ? JSCompiler_StaticMethods_getStatusText$self.xhr_.statusText : ""; | |
} catch (e) { | |
return goog.log.fine(JSCompiler_StaticMethods_getStatusText$self.logger_, "Can not get status: " + e.message), ""; | |
} | |
}, JSCompiler_StaticMethods_getResponseText = function(JSCompiler_StaticMethods_getResponseText$self) { | |
try { | |
return JSCompiler_StaticMethods_getResponseText$self.xhr_ ? JSCompiler_StaticMethods_getResponseText$self.xhr_.responseText : ""; | |
} catch (e) { | |
return goog.log.fine(JSCompiler_StaticMethods_getResponseText$self.logger_, "Can not get responseText: " + e.message), ""; | |
} | |
}, JSCompiler_StaticMethods_formatMsg_ = function(JSCompiler_StaticMethods_formatMsg_$self, msg) { | |
return msg + " [" + JSCompiler_StaticMethods_formatMsg_$self.lastMethod_ + " " + JSCompiler_StaticMethods_formatMsg_$self.lastUri_ + " " + JSCompiler_StaticMethods_formatMsg_$self.getStatus() + "]"; | |
}; | |
goog.debug.entryPointRegistry.register(function(transformer) { | |
goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = transformer(goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_); | |
}); | |
var easyUnlock = {Delay:function() { | |
}}; | |
easyUnlock.Delay.prototype.start = function() { | |
}; | |
easyUnlock.Delay.prototype.stop = function() { | |
}; | |
easyUnlock.Delay.prototype.fire = function() { | |
}; | |
easyUnlock.Timer = function() { | |
}; | |
easyUnlock.Timer.prototype.getTime = function() { | |
}; | |
easyUnlock.Timer.prototype.createDelay = function() { | |
}; | |
easyUnlock.TimerImpl = function() { | |
}; | |
easyUnlock.TimerImpl.prototype.getTime = function() { | |
return(new Date).getTime() / 1E3; | |
}; | |
easyUnlock.TimerImpl.prototype.createDelay = function(callback, delaySecs) { | |
return new easyUnlock.DelayImpl(callback, delaySecs); | |
}; | |
easyUnlock.DelayImpl = function(callback, delaySecs) { | |
this.delay_ = new goog.async.Delay(callback, 1E3 * delaySecs); | |
}; | |
easyUnlock.DelayImpl.prototype.start = function() { | |
this.delay_.start(); | |
}; | |
easyUnlock.DelayImpl.prototype.stop = function() { | |
this.delay_.stop(); | |
}; | |
easyUnlock.DelayImpl.prototype.fire = function() { | |
this.delay_.fire(); | |
}; | |
easyUnlock.FakeTimer = function(initialTime) { | |
this.time_ = initialTime; | |
this.delays_ = []; | |
}; | |
easyUnlock.FakeTimer.prototype.getTime = function() { | |
return this.time_; | |
}; | |
easyUnlock.FakeTimer.prototype.createDelay = function(callback) { | |
var delay = new easyUnlock.FakeDelay(this, callback); | |
this.delays_.push(delay); | |
return delay; | |
}; | |
easyUnlock.FakeDelay = function(timer, callback) { | |
this.timer_ = timer; | |
this.callback_ = callback; | |
}; | |
easyUnlock.FakeDelay.prototype.start = function() { | |
}; | |
easyUnlock.FakeDelay.prototype.stop = function() { | |
}; | |
easyUnlock.FakeDelay.prototype.fire = function() { | |
this.stop(); | |
this.callback_(); | |
}; | |
var permit = {crypto:{}}; | |
permit.crypto.BLOCK_SIZE = 16; | |
permit.crypto.KEY_SIZE = 32; | |
permit.crypto.NONCE_SIZE = 32; | |
permit.crypto.IV_SIZE = 16; | |
function getRandomBytes(length) { | |
var array = new Uint8Array(length); | |
window.crypto.getRandomValues(array); | |
return array; | |
} | |
function padBytes(bytes) { | |
var blockSize = permit.crypto.BLOCK_SIZE, paddingLen = blockSize - bytes.length % blockSize; | |
if (0 == paddingLen) { | |
return bytes; | |
} | |
var result = new Uint8Array(bytes.length + paddingLen); | |
result.set(bytes); | |
for (var i = 0;i < paddingLen;i++) { | |
result[bytes.length + i] = paddingLen; | |
} | |
return result; | |
} | |
function unpadBytes(bytes) { | |
var paddingLen = bytes[bytes.length - 1]; | |
return 0 == paddingLen ? bytes : bytes.subarray(0, bytes.length - paddingLen); | |
} | |
permit.crypto.createInitializationVector = function() { | |
return getRandomBytes(permit.crypto.IV_SIZE); | |
}; | |
permit.crypto.createKey = function() { | |
return getRandomBytes(permit.crypto.KEY_SIZE); | |
}; | |
permit.crypto.createNonce = function() { | |
return getRandomBytes(permit.crypto.NONCE_SIZE); | |
}; | |
permit.crypto.encrypt = function(inputBytes, initializationVector, keyBytes) { | |
inputBytes = padBytes(inputBytes); | |
var aes = new goog.crypt.Aes(Array.apply([], keyBytes)); | |
return new Uint8Array((new goog.crypt.Cbc(aes)).encrypt(Array.apply([], inputBytes), Array.apply([], initializationVector))); | |
}; | |
permit.crypto.decrypt = function(inputBytes, initializationVector, keyBytes) { | |
var aes = new goog.crypt.Aes(Array.apply([], keyBytes)), decryptedBytes = (new goog.crypt.Cbc(aes)).decrypt(Array.apply([], inputBytes), Array.apply([], initializationVector)); | |
return unpadBytes(new Uint8Array(decryptedBytes)); | |
}; | |
permit.crypto.base64Encode = function(data) { | |
return goog.crypt.base64.encodeByteArray(data, !0).replace(/\./g, "="); | |
}; | |
permit.crypto.base64Decode = function(data) { | |
data = data.replace(/=/g, "."); | |
try { | |
var decoded = goog.crypt.base64.decodeStringToByteArray(data, !0); | |
return new Uint8Array(decoded); | |
} catch (e) { | |
return console.error("Failed to decode Base64 encoded data:\n" + data + "\n" + e), null; | |
} | |
}; | |
permit.PermitRecord = function(permitId, id, type, data) { | |
this.permitId = permitId; | |
this.id = id; | |
this.type = type; | |
this.data = data || new Uint8Array([]); | |
}; | |
permit.PermitRecord.Type = {ACCESS:"access", LICENSE:"license"}; | |
permit.PermitRecord.prototype.toJSON = function() { | |
return{permitId:this.permitId, id:this.id, type:this.type, data:permit.crypto.base64Encode(this.data)}; | |
}; | |
permit.PermitRecord.fromJSON = function(obj) { | |
var permitId = obj.permitId || null, id = obj.id || null, type = obj.type || null, data = permit.crypto.base64Decode(obj.data); | |
return null == permitId ? null : new permit.PermitRecord(permitId, id, type, data); | |
}; | |
easyUnlock.EasyUnlockDevice = function(bluetoothAddress, name, permitRecord) { | |
this.bluetoothAddress = bluetoothAddress; | |
this.name = name; | |
this.permitRecord = permitRecord || null; | |
}; | |
easyUnlock.EasyUnlockDevice.prototype.toJSON = function() { | |
return{bluetoothAddress:this.bluetoothAddress, name:this.name, permitRecord:this.permitRecord.toJSON()}; | |
}; | |
easyUnlock.EasyUnlockDevice.fromJSON = function(obj) { | |
var address = obj.bluetoothAddress || null, name = obj.name || null, permitRecord = permit.PermitRecord.fromJSON(obj.permitRecord); | |
return null == address || null == name ? null : new easyUnlock.EasyUnlockDevice(address, name, permitRecord); | |
}; | |
permit.util = {}; | |
permit.util.uint8ArrayConcatenate = function(array1, array2) { | |
var result = new Uint8Array(array1.length + array2.length); | |
result.set(array1); | |
result.set(array2, array1.length); | |
return result; | |
}; | |
permit.util.uint8ArrayToString = function(array) { | |
if (!array) { | |
return "<null>"; | |
} | |
for (var str = "[ ", i = 0;i < array.length;i++) { | |
str += array[i], i < array.length - 1 && (str += ", "); | |
} | |
return str + " ]"; | |
}; | |
permit.util.stringToUint8Array = function(string) { | |
return new Uint8Array(goog.crypt.stringToByteArray(string)); | |
}; | |
permit.util.uint8ArrayEquals = function(array1, array2) { | |
if (array1.length != array2.length) { | |
return!1; | |
} | |
for (var i = 0;i < array1.length;++i) { | |
if (array1[i] != array2[i]) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
permit.edata = {}; | |
permit.edata.fromBytes = function(bytes, key) { | |
return 16 > bytes.length ? (console.error("Cannot read IV from bytes."), null) : permit.crypto.decrypt(bytes.subarray(16), bytes.subarray(0, 16), key); | |
}; | |
permit.edata.toBytes = function(data, key, iv) { | |
iv = iv || permit.crypto.createInitializationVector(); | |
var encrypted = permit.crypto.encrypt(data, iv, key); | |
return null == encrypted ? null : permit.util.uint8ArrayConcatenate(iv, encrypted); | |
}; | |
permit.Message = function(permitId, permitRecordId, permitRecordType, data, extraFields) { | |
this.permitId = permitId || null; | |
this.permitRecordId = permitRecordId || null; | |
this.permitRecordType = permitRecordType || permit.PermitRecord.Type.ACCESS; | |
this.data = data || new Uint8Array([]); | |
this.extraFields = extraFields || {}; | |
}; | |
permit.Message.HEADER_LENGTH = 3; | |
permit.Message.readVersionFromHeader = function(bytes) { | |
return 1 > bytes.length ? null : bytes[0]; | |
}; | |
permit.Message.readLengthFromHeader = function(bytes) { | |
return 3 > bytes.length ? null : bytes[1] << 8 | bytes[2]; | |
}; | |
permit.Message.fromBytes = function(messageBytes) { | |
if (3 > messageBytes.length) { | |
return console.error("Expected header when deserializing message, got " + messageBytes.length + " bytes."), null; | |
} | |
var messageVersion = permit.Message.readVersionFromHeader(messageBytes); | |
if (1 != messageVersion) { | |
return console.error("Expected message version 1, got " + messageVersion + " instead."), null; | |
} | |
var bodyLength = permit.Message.readLengthFromHeader(messageBytes), bodyBytes = messageBytes.subarray(3); | |
if (bodyLength != bodyBytes.length) { | |
return console.error("Invalid body length, got " + bodyBytes.length + " expected " + bodyLength), null; | |
} | |
var jsonString = goog.crypt.byteArrayToString(Array.apply([], bodyBytes)), jsonObj = null; | |
try { | |
jsonObj = JSON.parse(jsonString); | |
} catch (e) { | |
return console.error("Failed to parse message content: '" + jsonString + "'"), null; | |
} | |
return permit.Message.fromJSON(jsonObj); | |
}; | |
permit.Message.fromJSON = function(obj) { | |
var expectedFields = {}; | |
expectedFields.permit_id = obj.permit_id; | |
expectedFields.permit_access_id = obj.permit_access_id; | |
expectedFields.permit_license_id = obj.permit_license_id; | |
expectedFields.data = obj.data; | |
var permitRecordId = expectedFields.permit_access_id || expectedFields.permit_license_id, permitRecordType = void 0 != expectedFields.permit_access_id ? permit.PermitRecord.Type.ACCESS : permit.PermitRecord.Type.LICENSE, b64EncodedData = obj.data, data = b64EncodedData ? permit.crypto.base64Decode(b64EncodedData) : b64EncodedData, extraFields = {}, key; | |
for (key in obj) { | |
void 0 == expectedFields[key] && (extraFields[key] = obj[key]); | |
} | |
return new permit.Message(expectedFields.permit_id, permitRecordId, permitRecordType, data, extraFields); | |
}; | |
permit.Message.prototype.toBytes = function() { | |
var jsonString = JSON.stringify(this.toJSON()), bytes = new Uint8Array(goog.crypt.stringToByteArray(jsonString)), bodyLength = bytes.length, header = new Uint8Array([1, bodyLength >> 8, bodyLength & 255]); | |
return permit.util.uint8ArrayConcatenate(header, bytes); | |
}; | |
permit.Message.prototype.toJSON = function() { | |
var b64EncodedData = permit.crypto.base64Encode(this.data), recordIdKey = this.permitRecordType == permit.PermitRecord.Type.ACCESS ? "permit_access_id" : "permit_license_id", obj = {}; | |
obj.permit_id = this.permitId; | |
obj[recordIdKey] = this.permitRecordId; | |
obj.data = b64EncodedData; | |
for (var key in this.extraFields) { | |
obj[key] = this.extraFields[key]; | |
} | |
return obj; | |
}; | |
easyUnlock.ConnectionObserver = function() { | |
}; | |
easyUnlock.ConnectionObserver.prototype.onConnectionStatusChanged = function() { | |
}; | |
easyUnlock.ConnectionObserver.prototype.onMessageReceived = function() { | |
}; | |
easyUnlock.ConnectionObserver.prototype.onSendCompleted = function() { | |
}; | |
easyUnlock.Connection = function(easyUnlockDevice) { | |
this.easyUnlockDevice_ = easyUnlockDevice; | |
this.connectionStatus_ = easyUnlock.Connection.Status.DISCONNECTED; | |
this.observers_ = []; | |
this.buffer_ = new Uint8Array(0); | |
this.messageInProgress_ = null; | |
}; | |
easyUnlock.Connection.Status = {DISCONNECTED:0, IN_PROGRESS:1, CONNECTED:2}; | |
easyUnlock.Connection.prototype.getStatus = function() { | |
return this.connectionStatus_; | |
}; | |
var JSCompiler_StaticMethods_setStatus = function(JSCompiler_StaticMethods_setStatus$self, connectionStatus) { | |
if (JSCompiler_StaticMethods_setStatus$self.connectionStatus_ != connectionStatus) { | |
var oldStatus = JSCompiler_StaticMethods_setStatus$self.connectionStatus_; | |
JSCompiler_StaticMethods_setStatus$self.connectionStatus_ = connectionStatus; | |
JSCompiler_StaticMethods_setStatus$self.buffer_ = new Uint8Array(0); | |
for (var i = 0;i < JSCompiler_StaticMethods_setStatus$self.observers_.length;++i) { | |
JSCompiler_StaticMethods_setStatus$self.observers_[i].onConnectionStatusChanged(oldStatus, JSCompiler_StaticMethods_setStatus$self.connectionStatus_); | |
} | |
} | |
}; | |
easyUnlock.Connection.prototype.isConnected = function() { | |
return this.connectionStatus_ == easyUnlock.Connection.Status.CONNECTED; | |
}; | |
var JSCompiler_StaticMethods_getRemoteDevice = function(JSCompiler_StaticMethods_getRemoteDevice$self) { | |
return JSCompiler_StaticMethods_getRemoteDevice$self.easyUnlockDevice_; | |
}; | |
easyUnlock.Connection.prototype.sendMessage = function(message) { | |
null != this.messageInProgress_ ? console.error("Another message is currently in progress.") : (this.messageInProgress_ = message, this.sendBytes(message.toBytes())); | |
}; | |
var JSCompiler_StaticMethods_cancelSendMessage = function(JSCompiler_StaticMethods_cancelSendMessage$self) { | |
JSCompiler_StaticMethods_cancelSendMessage$self.messageInProgress_ && (JSCompiler_StaticMethods_cancelSendMessage$self.messageInProgress_ = null); | |
}, JSCompiler_StaticMethods_addObserver = function(JSCompiler_StaticMethods_addObserver$self, observer) { | |
JSCompiler_StaticMethods_addObserver$self.observers_.push(observer); | |
}, JSCompiler_StaticMethods_removeObserver = function(JSCompiler_StaticMethods_removeObserver$self, observer) { | |
var idx = JSCompiler_StaticMethods_removeObserver$self.observers_.indexOf(observer); | |
-1 == idx ? console.warn("Observer was not added.") : JSCompiler_StaticMethods_removeObserver$self.observers_.splice(idx, 1); | |
}; | |
easyUnlock.Connection.prototype.setPaused = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.connect = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.disconnect = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.startDiscovery = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.stopDiscovery = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.sendBytes = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.onSendCompleted = function(success) { | |
if (null == this.messageInProgress_) { | |
console.error("Send completed, but no message in progress."); | |
} else { | |
for (var i = 0;i < this.observers_.length;++i) { | |
this.observers_[i].onSendCompleted(this.messageInProgress_, success); | |
} | |
this.messageInProgress_ = null; | |
} | |
}; | |
var JSCompiler_StaticMethods_onBytesReceived = function(JSCompiler_StaticMethods_onBytesReceived$self, bytes) { | |
if (JSCompiler_StaticMethods_onBytesReceived$self.isConnected()) { | |
JSCompiler_StaticMethods_onBytesReceived$self.buffer_ = permit.util.uint8ArrayConcatenate(JSCompiler_StaticMethods_onBytesReceived$self.buffer_, bytes); | |
var messageLength = permit.Message.readLengthFromHeader(JSCompiler_StaticMethods_onBytesReceived$self.buffer_) + permit.Message.HEADER_LENGTH; | |
if (messageLength && JSCompiler_StaticMethods_onBytesReceived$self.buffer_.length >= messageLength) { | |
var message = permit.Message.fromBytes(JSCompiler_StaticMethods_onBytesReceived$self.buffer_.subarray(0, messageLength)); | |
if (message) { | |
JSCompiler_StaticMethods_onBytesReceived$self.buffer_ = JSCompiler_StaticMethods_onBytesReceived$self.buffer_.subarray(messageLength); | |
for (var i = 0;i < JSCompiler_StaticMethods_onBytesReceived$self.observers_.length;++i) { | |
JSCompiler_StaticMethods_onBytesReceived$self.observers_[i].onMessageReceived(message); | |
} | |
} else { | |
console.error("Error: Unable to parse message."); | |
} | |
} | |
} else { | |
console.error("Received bytes, but not connected."); | |
} | |
}; | |
easyUnlock.AuthenticatorDelegate = function() { | |
}; | |
easyUnlock.AuthenticatorDelegate.prototype.onAuthenticationChanged = function() { | |
}; | |
easyUnlock.AuthenticatorDelegate.prototype.onAuthenticationRefreshed = function() { | |
}; | |
easyUnlock.AuthenticatorDelegate.prototype.onAuthenticationFailed = function() { | |
}; | |
easyUnlock.AuthenticatorDelegate.prototype.onAuthenticatorConnnectionChanged = function() { | |
}; | |
easyUnlock.Authenticator = function(connection, permitAccess, delegate, timer) { | |
this.connection_ = connection; | |
this.permitAccess_ = permitAccess; | |
this.delegate_ = delegate; | |
this.timer_ = timer; | |
this.requestContext_ = this.lastSuccessTimestamp_ = null; | |
this.retryQueued_ = !1; | |
this.reauthDelay_ = this.timer_.createDelay(this.reauthTimeout_.bind(this), easyUnlock.Authenticator.AUTHENTICATION_TIME_SECS - easyUnlock.Authenticator.REAUTH_BEFORE_TIMEOUT_SECS); | |
this.deauthDelay_ = this.timer_.createDelay(this.deauthTimeout_.bind(this), easyUnlock.Authenticator.AUTHENTICATION_TIME_SECS); | |
}; | |
easyUnlock.Authenticator.RequestContext = function(nonce, request) { | |
this.nonce = nonce; | |
this.request = request; | |
}; | |
easyUnlock.Authenticator.AUTHENTICATION_TIME_SECS = 600; | |
easyUnlock.Authenticator.REAUTH_BEFORE_TIMEOUT_SECS = 30; | |
easyUnlock.Authenticator.STATUS_SUCCESS = "success"; | |
easyUnlock.Authenticator.STATUS_FAILURE = "failure"; | |
easyUnlock.Authenticator.STATUS_RETRY = "retry"; | |
easyUnlock.Authenticator.prototype.start = function() { | |
JSCompiler_StaticMethods_addObserver(this.connection_, this); | |
this.connection_.setPaused(!1); | |
this.connection_.isConnected() ? JSCompiler_StaticMethods_requestAuthentication(this) : this.connection_.startDiscovery(); | |
}; | |
easyUnlock.Authenticator.prototype.stop = function() { | |
this.isAuthenticated() && JSCompiler_StaticMethods_deauthenticate(this); | |
JSCompiler_StaticMethods_removeObserver(this.connection_, this); | |
}; | |
easyUnlock.Authenticator.prototype.isAuthenticated = function() { | |
return null == this.lastSuccessTimestamp_ ? !1 : this.connection_.isConnected() && this.timer_.getTime() - this.lastSuccessTimestamp_ <= easyUnlock.Authenticator.AUTHENTICATION_TIME_SECS; | |
}; | |
easyUnlock.Authenticator.prototype.isConnected = function() { | |
return this.connection_.isConnected(); | |
}; | |
var JSCompiler_StaticMethods_deauthenticate = function(JSCompiler_StaticMethods_deauthenticate$self) { | |
var wasAuthenticated = null != JSCompiler_StaticMethods_deauthenticate$self.lastSuccessTimestamp_; | |
JSCompiler_StaticMethods_deauthenticate$self.lastSuccessTimestamp_ = null; | |
JSCompiler_StaticMethods_deauthenticate$self.requestContext_ = null; | |
JSCompiler_StaticMethods_cancelSendMessage(JSCompiler_StaticMethods_deauthenticate$self.connection_); | |
JSCompiler_StaticMethods_deauthenticate$self.reauthDelay_.stop(); | |
JSCompiler_StaticMethods_deauthenticate$self.deauthDelay_.stop(); | |
if (wasAuthenticated) { | |
JSCompiler_StaticMethods_deauthenticate$self.delegate_.onAuthenticationChanged(!1); | |
} | |
JSCompiler_StaticMethods_deauthenticate$self.retryQueued_ && (JSCompiler_StaticMethods_deauthenticate$self.retryQueued_ = !1, JSCompiler_StaticMethods_requestAuthentication(JSCompiler_StaticMethods_deauthenticate$self)); | |
}, JSCompiler_StaticMethods_authenticate_ = function(JSCompiler_StaticMethods_authenticate_$self) { | |
var wasAuthenticated = JSCompiler_StaticMethods_authenticate_$self.isAuthenticated(); | |
JSCompiler_StaticMethods_authenticate_$self.lastSuccessTimestamp_ = JSCompiler_StaticMethods_authenticate_$self.timer_.getTime(); | |
JSCompiler_StaticMethods_authenticate_$self.requestContext_ = null; | |
JSCompiler_StaticMethods_authenticate_$self.reauthDelay_.start(); | |
JSCompiler_StaticMethods_authenticate_$self.deauthDelay_.start(); | |
if (wasAuthenticated) { | |
JSCompiler_StaticMethods_authenticate_$self.delegate_.onAuthenticationRefreshed(); | |
} else { | |
JSCompiler_StaticMethods_authenticate_$self.delegate_.onAuthenticationChanged(!0); | |
} | |
JSCompiler_StaticMethods_authenticate_$self.retryQueued_ && (JSCompiler_StaticMethods_authenticate_$self.retryQueued_ = !1, JSCompiler_StaticMethods_requestAuthentication(JSCompiler_StaticMethods_authenticate_$self)); | |
}, JSCompiler_StaticMethods_requestAuthentication = function(JSCompiler_StaticMethods_requestAuthentication$self) { | |
JSCompiler_StaticMethods_requestAuthentication$self.connection_.isConnected() ? JSCompiler_StaticMethods_requestAuthentication$self.requestContext_ ? console.warn("[Auth] Already handling another request.") : (console.log("[Auth] Requesting authentication..."), JSCompiler_StaticMethods_requestAuthentication$self.reauthDelay_.stop(), JSCompiler_StaticMethods_requestAuthentication$self.requestContext_ = JSCompiler_StaticMethods_createRequestContext_(JSCompiler_StaticMethods_requestAuthentication$self), | |
JSCompiler_StaticMethods_requestAuthentication$self.connection_.sendMessage(JSCompiler_StaticMethods_requestAuthentication$self.requestContext_.request)) : console.warn("[Auth] Requesting authentication, but not connected."); | |
}, JSCompiler_StaticMethods_createRequestContext_ = function(JSCompiler_StaticMethods_createRequestContext_$self) { | |
var permitId = JSCompiler_StaticMethods_createRequestContext_$self.permitAccess_.permitId, nonce = permit.crypto.createNonce(), permitIdBytes = permit.util.stringToUint8Array(permitId), payload = permit.edata.toBytes(permit.util.uint8ArrayConcatenate(nonce, permitIdBytes), JSCompiler_StaticMethods_createRequestContext_$self.permitAccess_.data), requestMessage = new permit.Message(permitId, JSCompiler_StaticMethods_createRequestContext_$self.permitAccess_.id, permit.PermitRecord.Type.ACCESS, payload); | |
return new easyUnlock.Authenticator.RequestContext(nonce, requestMessage); | |
}, JSCompiler_StaticMethods_verifyAuthResponse_ = function(JSCompiler_StaticMethods_verifyAuthResponse_$self, message) { | |
if (null == JSCompiler_StaticMethods_verifyAuthResponse_$self.requestContext_ || !JSCompiler_StaticMethods_verifyAuthResponse_$self.connection_.isConnected() || message.permitId != JSCompiler_StaticMethods_verifyAuthResponse_$self.permitAccess_.permitId) { | |
return!1; | |
} | |
var permitLicense = JSCompiler_StaticMethods_getRemoteDevice(JSCompiler_StaticMethods_verifyAuthResponse_$self.connection_).permitRecord; | |
if (message.permitRecordType != permitLicense.type || message.permitRecordId != permitLicense.id || message.extraFields.status != easyUnlock.Authenticator.STATUS_SUCCESS) { | |
return!1; | |
} | |
var decrypted = permit.edata.fromBytes(message.data, permitLicense.data); | |
if (null == decrypted) { | |
return!1; | |
} | |
var nonce = JSCompiler_StaticMethods_verifyAuthResponse_$self.requestContext_.nonce, permitIdBytes = permit.util.stringToUint8Array(JSCompiler_StaticMethods_verifyAuthResponse_$self.permitAccess_.permitId), expectedData = permit.util.uint8ArrayConcatenate(nonce, permitIdBytes); | |
return permit.util.uint8ArrayEquals(expectedData, decrypted); | |
}; | |
easyUnlock.Authenticator.prototype.onConnectionStatusChanged = function(oldStatus, newStatus) { | |
newStatus == easyUnlock.Connection.Status.CONNECTED ? JSCompiler_StaticMethods_requestAuthentication(this) : (JSCompiler_StaticMethods_deauthenticate(this), newStatus == easyUnlock.Connection.Status.DISCONNECTED && this.connection_.startDiscovery()); | |
this.delegate_.onAuthenticatorConnnectionChanged(); | |
}; | |
easyUnlock.Authenticator.prototype.onMessageReceived = function(message) { | |
var status = message.extraFields.status; | |
status == easyUnlock.Authenticator.STATUS_SUCCESS ? JSCompiler_StaticMethods_processSuccess_(this, message) : status == easyUnlock.Authenticator.STATUS_FAILURE ? JSCompiler_StaticMethods_processFailure_(this) : status == easyUnlock.Authenticator.STATUS_RETRY ? JSCompiler_StaticMethods_processRetry_(this) : (console.error("[Auth] Received invalid message:"), console.error(message), JSCompiler_StaticMethods_deauthenticate(this)); | |
}; | |
easyUnlock.Authenticator.prototype.onSendCompleted = function(message, success) { | |
if (success) { | |
if (null == this.requestContext_ || this.requestContext_.request != message) { | |
console.error("[Auth] Sent message successfully, but no request in progress."), JSCompiler_StaticMethods_deauthenticate(this); | |
} | |
} else { | |
console.log("[Auth] Request failed, deauthenticating."), JSCompiler_StaticMethods_deauthenticate(this); | |
} | |
}; | |
var JSCompiler_StaticMethods_processSuccess_ = function(JSCompiler_StaticMethods_processSuccess_$self, message) { | |
JSCompiler_StaticMethods_processSuccess_$self.requestContext_ ? JSCompiler_StaticMethods_verifyAuthResponse_(JSCompiler_StaticMethods_processSuccess_$self, message) && JSCompiler_StaticMethods_authenticate_(JSCompiler_StaticMethods_processSuccess_$self) : console.warn("[Auth] Got success response, but no request in progress."); | |
}, JSCompiler_StaticMethods_processFailure_ = function(JSCompiler_StaticMethods_processFailure_$self) { | |
console.log("[Auth] Authentication request failed."); | |
JSCompiler_StaticMethods_deauthenticate(JSCompiler_StaticMethods_processFailure_$self); | |
JSCompiler_StaticMethods_processFailure_$self.delegate_.onAuthenticationFailed(); | |
}, JSCompiler_StaticMethods_processRetry_ = function(JSCompiler_StaticMethods_processRetry_$self) { | |
JSCompiler_StaticMethods_processRetry_$self.requestContext_ ? (console.warn("[Auth] Got retry message, but request currently in progress. Queueing retry..."), JSCompiler_StaticMethods_processRetry_$self.retryQueued_ = !0) : (console.log("[Auth] Retry message received..."), JSCompiler_StaticMethods_requestAuthentication(JSCompiler_StaticMethods_processRetry_$self)); | |
}; | |
easyUnlock.Authenticator.prototype.reauthTimeout_ = function() { | |
console.log("[Auth] Reauthentication timeout..."); | |
JSCompiler_StaticMethods_requestAuthentication(this); | |
}; | |
easyUnlock.Authenticator.prototype.deauthTimeout_ = function() { | |
console.log("[Auth] Deauthentication timeout..."); | |
JSCompiler_StaticMethods_deauthenticate(this); | |
}; | |
easyUnlock.MessageBuffer = function() { | |
this.messages_ = []; | |
}; | |
easyUnlock.MessageBuffer.prototype.onMessageReceived = function() { | |
}; | |
easyUnlock.MessageBuffer.prototype.onConnectionStatusChanged = function() { | |
}; | |
easyUnlock.MessageBuffer.prototype.onSendCompleted = function(message) { | |
this.messages_.push(message); | |
}; | |
easyUnlock.FakeConnection = function(easyUnlockDevice) { | |
easyUnlock.Connection.call(this, easyUnlockDevice); | |
this.remoteInRange_ = !1; | |
this.remoteBytes_ = new Uint8Array([]); | |
}; | |
goog.inherits(easyUnlock.FakeConnection, easyUnlock.Connection); | |
easyUnlock.FakeConnection.prototype.setPaused = function(paused) { | |
!paused && 0 < this.remoteBytes_.length && (JSCompiler_StaticMethods_onBytesReceived(this, this.remoteBytes_), this.remoteBytes_ = new Uint8Array([])); | |
}; | |
easyUnlock.FakeConnection.prototype.connect = function() { | |
if (this.getStatus() != easyUnlock.Connection.Status.DISCONNECTED) { | |
throw "Connect called but not disconnected."; | |
} | |
this.remoteInRange_ && JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.CONNECTED); | |
}; | |
easyUnlock.FakeConnection.prototype.disconnect = function() { | |
if (this.getStatus() != easyUnlock.Connection.Status.CONNECTED) { | |
throw "Disconnect called but not connected."; | |
} | |
JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.DISCONNECTED); | |
}; | |
easyUnlock.FakeConnection.prototype.startDiscovery = function() { | |
this.remoteInRange_ && this.connect(); | |
}; | |
easyUnlock.FakeConnection.prototype.stopDiscovery = function() { | |
}; | |
easyUnlock.FakeConnection.prototype.sendBytes = function() { | |
if (this.getStatus() != easyUnlock.Connection.Status.CONNECTED) { | |
throw "Can not send bytes when not connected."; | |
} | |
this.onSendCompleted(!0); | |
}; | |
easyUnlock.SetupFlowDelegate = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.getPermitAccess = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.setPermitAccess = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.getBluetoothAddress = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.getUserGaiaId = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.pingUserDevices = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.scanForDevices = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.onSetupCompleted = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.onSetupFailed = function() { | |
}; | |
easyUnlock.SetupFlow = function(delegate, timer) { | |
this.delegate_ = delegate; | |
this.timer_ = timer; | |
this.state_ = easyUnlock.SetupFlow.State.NOT_STARTED; | |
this.tmpKey_ = null; | |
this.pairingDelay_ = this.timer_.createDelay(this.onPairingTimedOut_.bind(this), easyUnlock.SetupFlow.PAIRING_TIMEOUT_SECS); | |
this.pairingHandlers_ = []; | |
this.pairedDevices_ = null; | |
}; | |
easyUnlock.SetupFlow.PAIRING_TIMEOUT_SECS = 5; | |
easyUnlock.SetupFlow.EASY_UNLOCK_PERMIT_ID_PREFIX = "permit://google.com/easyunlock/v1/"; | |
easyUnlock.SetupFlow.State = {NOT_STARTED:0, PINGING_DEVICES:1, SCANNING_DEVICES:2, PAIRING_DEVICES:3, FAILED:4}; | |
easyUnlock.SetupFlow.prototype.start = function() { | |
if (this.state_ != easyUnlock.SetupFlow.State.NOT_STARTED) { | |
throw "Flow has already started."; | |
} | |
var permitAccess = this.delegate_.getPermitAccess(); | |
null == permitAccess && (permitAccess = JSCompiler_StaticMethods_generatePermitAccess_(this), this.delegate_.setPermitAccess(permitAccess)); | |
this.tmpKey_ = permit.crypto.createKey(); | |
var pingData = JSCompiler_StaticMethods_createPingData_(this, permitAccess); | |
this.state_ = easyUnlock.SetupFlow.State.PINGING_DEVICES; | |
this.delegate_.pingUserDevices(pingData, this.onPingCompleted_.bind(this)); | |
}; | |
var JSCompiler_StaticMethods_generatePermitAccess_ = function(JSCompiler_StaticMethods_generatePermitAccess_$self) { | |
var permitId = easyUnlock.SetupFlow.EASY_UNLOCK_PERMIT_ID_PREFIX + JSCompiler_StaticMethods_generatePermitAccess_$self.delegate_.getUserGaiaId(), randomId = "[" + JSCompiler_StaticMethods_generatePermitAccess_$self.delegate_.getUserGaiaId() + "-" + Math.random() + "]"; | |
return new permit.PermitRecord(permitId, randomId, permit.PermitRecord.Type.ACCESS, permit.crypto.createKey()); | |
}, JSCompiler_StaticMethods_createPingData_ = function(JSCompiler_StaticMethods_createPingData_$self, permitAccess) { | |
return{bluetooth_address:JSCompiler_StaticMethods_createPingData_$self.delegate_.getBluetoothAddress(), permit_access_id:permitAccess.id, permit_access_data:permit.crypto.base64Encode(permitAccess.data), tmp_key:permit.crypto.base64Encode(JSCompiler_StaticMethods_createPingData_$self.tmpKey_)}; | |
}; | |
easyUnlock.SetupFlow.prototype.onPingCompleted_ = function(success) { | |
if (this.state_ != easyUnlock.SetupFlow.State.PINGING_DEVICES) { | |
throw "Expected state PINGING_DEVICES."; | |
} | |
success ? (this.state_ = easyUnlock.SetupFlow.State.SCANNING_DEVICES, this.delegate_.scanForDevices(this.onScanCompleted_.bind(this))) : JSCompiler_StaticMethods_fail_(this); | |
}; | |
easyUnlock.SetupFlow.prototype.onScanCompleted_ = function(connections) { | |
if (this.state_ != easyUnlock.SetupFlow.State.SCANNING_DEVICES) { | |
throw "Expected state SCANNING_DEVICES."; | |
} | |
if (0 == connections.length) { | |
JSCompiler_StaticMethods_fail_(this); | |
} else { | |
this.state_ = easyUnlock.SetupFlow.State.PAIRING_DEVICES; | |
this.pairedDevices_ = []; | |
this.pairingDelay_.start(); | |
this.pairingHandlers_ = []; | |
for (var i = 0;i < connections.length;++i) { | |
var handler = new easyUnlock.PairingHandler(connections[i], this.tmpKey_, this.delegate_.getPermitAccess(), this); | |
this.pairingHandlers_.push(handler); | |
handler.start(); | |
} | |
} | |
}; | |
easyUnlock.SetupFlow.prototype.onPairingTimedOut_ = function() { | |
if (this.state_ != easyUnlock.SetupFlow.State.PAIRING_DEVICES) { | |
throw "Expected state PAIRING_DEVICES."; | |
} | |
for (var i = 0;i < this.pairingHandlers_.length;++i) { | |
this.pairingHandlers_[i].stop(); | |
} | |
}; | |
var JSCompiler_StaticMethods_onPairingHandlerCompleted = function(JSCompiler_StaticMethods_onPairingHandlerCompleted$self, handler, device) { | |
null != device && JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairedDevices_.push(device); | |
var idx = JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairingHandlers_.indexOf(handler); | |
JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairingHandlers_.splice(idx, 1); | |
if (0 == JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairingHandlers_.length) { | |
if (0 < JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairedDevices_.length) { | |
JSCompiler_StaticMethods_onPairingHandlerCompleted$self.delegate_.onSetupCompleted(JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairedDevices_); | |
} else { | |
JSCompiler_StaticMethods_onPairingHandlerCompleted$self.delegate_.onSetupFailed(); | |
} | |
} | |
}, JSCompiler_StaticMethods_fail_ = function(JSCompiler_StaticMethods_fail_$self) { | |
JSCompiler_StaticMethods_fail_$self.state_ = easyUnlock.SetupFlow.State.FAILED; | |
JSCompiler_StaticMethods_fail_$self.delegate_.onSetupFailed(); | |
}; | |
easyUnlock.PairingHandler = function(connection, tmpKey, permitAccess, setupFlow) { | |
this.connection_ = connection; | |
this.tmpKey_ = tmpKey; | |
this.permitAccess_ = permitAccess; | |
this.setupFlow_ = setupFlow; | |
this.device_ = JSCompiler_StaticMethods_getRemoteDevice(connection); | |
}; | |
easyUnlock.PairingHandler.prototype.start = function() { | |
JSCompiler_StaticMethods_addObserver(this.connection_, this); | |
this.connection_.isConnected() || this.stop(); | |
this.connection_.setPaused(!1); | |
}; | |
easyUnlock.PairingHandler.prototype.stop = function() { | |
JSCompiler_StaticMethods_removeObserver(this.connection_, this); | |
JSCompiler_StaticMethods_onPairingHandlerCompleted(this.setupFlow_, this, null); | |
}; | |
var JSCompiler_StaticMethods_sendAck_ = function(JSCompiler_StaticMethods_sendAck_$self) { | |
var permitIdBytes = permit.util.stringToUint8Array(JSCompiler_StaticMethods_sendAck_$self.permitAccess_.permitId), edata = permit.edata.toBytes(permitIdBytes, JSCompiler_StaticMethods_sendAck_$self.permitAccess_.data), ack = new permit.Message(JSCompiler_StaticMethods_sendAck_$self.permitAccess_.permitId, JSCompiler_StaticMethods_sendAck_$self.permitAccess_.id, permit.PermitRecord.Type.ACCESS, edata); | |
JSCompiler_StaticMethods_sendAck_$self.connection_.sendMessage(ack); | |
}; | |
easyUnlock.PairingHandler.prototype.onMessageReceived = function(message) { | |
var permitId = message.permitId, permitLicenseId = message.permitRecordId; | |
if (permitId != this.permitAccess_.permitId || null == permitLicenseId || message.permitRecordType != permit.PermitRecord.Type.LICENSE) { | |
console.warn("Invalid permit identifier information in response."), JSCompiler_StaticMethods_onPairingHandlerCompleted(this.setupFlow_, this, null); | |
} else { | |
var payload = permit.edata.fromBytes(message.data, this.tmpKey_), permitIdBytes = permit.util.stringToUint8Array(permitId); | |
if (permit.util.uint8ArrayEquals(permitIdBytes, payload.subarray(0, permitIdBytes.length))) { | |
var licenseData = payload.subarray(permitIdBytes.length); | |
if (licenseData.length != permit.crypto.KEY_SIZE) { | |
console.warn("Invalid key length in response payload."), JSCompiler_StaticMethods_onPairingHandlerCompleted(this.setupFlow_, this, null); | |
} else { | |
var permitLicense = new permit.PermitRecord(permitId, permitLicenseId, permit.PermitRecord.Type.LICENSE, licenseData); | |
this.device_.permitRecord = permitLicense; | |
JSCompiler_StaticMethods_sendAck_(this); | |
} | |
} else { | |
console.warn("Permit id not found in response payload."), JSCompiler_StaticMethods_onPairingHandlerCompleted(this.setupFlow_, this, null); | |
} | |
} | |
}; | |
easyUnlock.PairingHandler.prototype.onConnectionStatusChanged = function(oldStatus, newStatus) { | |
newStatus != easyUnlock.Connection.Status.CONNECTED && this.stop(); | |
}; | |
easyUnlock.PairingHandler.prototype.onSendCompleted = function(message) { | |
message.permitId == this.permitAccess_.permitId ? (JSCompiler_StaticMethods_removeObserver(this.connection_, this), JSCompiler_StaticMethods_onPairingHandlerCompleted(this.setupFlow_, this, this.device_)) : (console.error("Sent unexpected message:"), console.error(message)); | |
}; | |
easyUnlock.FakeSetupFlowDelegate = function(bluetoothAddress, gaiaId) { | |
this.bluetoothAddress_ = bluetoothAddress; | |
this.gaiaId_ = gaiaId; | |
this.permitAccess_ = null; | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.getPermitAccess = function() { | |
return this.permitAccess_; | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.setPermitAccess = function(permitAccess) { | |
this.permitAccess_ = permitAccess; | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.getBluetoothAddress = function() { | |
return this.bluetoothAddress_; | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.getUserGaiaId = function() { | |
return this.gaiaId_; | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.pingUserDevices = function() { | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.scanForDevices = function() { | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.onSetupCompleted = function() { | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.onSetupFailed = function() { | |
}; | |
var app = {Bluetooth:{}}; | |
app.Bluetooth.UNLOCK_PROFILE = {uuid:"0000AB34-0000-1000-8000-00805F9B34FB", name:"Easy Unlock", channel:14, requireAuthorization:!1, requireAuthentication:!1, autoConnect:!0}; | |
app.Bluetooth.SETUP_PROFILE = {uuid:"29422880-D56D-11E3-9C1A-0800200C9A66", name:"Easy Unlock Registration", channel:13, requireAuthorization:!1, requireAuthentication:!1, autoConnect:!0}; | |
app.Bluetooth.adapterState = null; | |
app.Bluetooth.connectionCallback = null; | |
app.Bluetooth.profile = null; | |
app.Bluetooth.refreshAdapterState = function(callback) { | |
chrome.bluetooth.getAdapterState(function(adapterStateParam) { | |
app.Bluetooth.adapterState = adapterStateParam; | |
callback(app.Bluetooth.adapterState); | |
}); | |
}; | |
app.Bluetooth.registerProfile = function(profile) { | |
null != app.Bluetooth.profile ? console.log("[BT] Another profile is already registered: " + app.Bluetooth.profile.uuid + ".") : (chrome.bluetooth.addProfile(profile, function() { | |
chrome.runtime.lastError ? console.error("[BT] Could not add profile: " + chrome.runtime.lastError.message) : console.log("[BT] Profile added channel=" + profile.channel); | |
}), app.Bluetooth.profile = profile); | |
}; | |
app.Bluetooth.unregisterProfile = function(profile) { | |
null == app.Bluetooth.profile ? console.log("[BT] Profile not found: " + profile.uuid + ".") : chrome.bluetooth.removeProfile(profile, function() { | |
chrome.runtime.lastError ? console.log("[BT] Could not unregister profile: " + chrome.runtime.lastError.message) : (console.log("[BT] Profile unregistered."), app.Bluetooth.profile = null); | |
}); | |
}; | |
app.Bluetooth.writeToSocket = function(socket, data, callback) { | |
app.Bluetooth.stopListeningOverBluetooth(); | |
chrome.bluetoothSocket.send(socket.id, data, function(bytesWritten) { | |
var success = !0; | |
chrome.runtime.lastError ? (success = !1, console.log("[BT] Failed to write to BT socket: " + chrome.runtime.lastError.message)) : console.log("[BT] Successfully wrote " + bytesWritten + " bytes."); | |
callback(success); | |
}); | |
}; | |
app.Bluetooth.readFromSocket = function(socket, callback) { | |
var onRead = null, timeoutGuard = new goog.async.Delay(function() { | |
console.error("[BT] Timeout while waiting to read from socket"); | |
if (null == onRead) { | |
throw "Callback expected to be non-null"; | |
} | |
chrome.bluetoothSocket.onReceive.removeListener(onRead); | |
chrome.bluetoothSocket.setPaused(socket.id, !0); | |
callback(!0, new Uint8Array([])); | |
}, 5E3); | |
timeoutGuard.start(); | |
onRead = function(info) { | |
var data = info.data; | |
timeoutGuard.stop(); | |
if (chrome.runtime.lastError) { | |
console.error("[BT] Failed to read from Bluetooth socket " + chrome.runtime.lastError.message), callback(!1, null); | |
} else { | |
if (data && 0 != data.byteLength) { | |
var buffer = data ? new Uint8Array(data) : new Uint8Array([]); | |
console.log("[BT] Read " + buffer.byteLength + " bytes from Bluetooth socket."); | |
callback(!0, buffer); | |
if (null == onRead) { | |
throw "Callback expected to be non-null"; | |
} | |
chrome.bluetoothSocket.onReceive.removeListener(onRead); | |
chrome.bluetoothSocket.setPaused(socket.id, !0); | |
} else { | |
callback(!0, new Uint8Array([])); | |
} | |
} | |
}; | |
chrome.bluetoothSocket.onReceive.addListener(onRead); | |
chrome.bluetoothSocket.setPaused(socket.id, !1); | |
}; | |
app.Bluetooth.onConnectionListenerForReading_ = function(socket) { | |
console.log("[BT] Connection received for reading."); | |
app.Bluetooth.isListening ? app.Bluetooth.connectionCallback(socket) : console.error("[BT] bluetooth.onConnection event listener called when not listening"); | |
}; | |
app.Bluetooth.startListeningOverBluetooth = function(callback) { | |
app.Bluetooth.isListening && app.Bluetooth.stopListeningOverBluetooth(); | |
app.Bluetooth.isListening = !0; | |
app.Bluetooth.connectionCallback = callback; | |
chrome.bluetooth.onConnection.addListener(app.Bluetooth.onConnectionListenerForReading_); | |
}; | |
app.Bluetooth.stopListeningOverBluetooth = function() { | |
app.Bluetooth.isListening = !1; | |
app.Bluetooth.connectionCallback = null; | |
chrome.bluetooth.onConnection.removeListener(app.Bluetooth.onConnectionListenerForReading_); | |
}; | |
app.Bluetooth.openConnection = function(deviceInfo, callback) { | |
if (app.Bluetooth.isListening) { | |
console.error("[BT] Cannot open connection while listening."), callback(null); | |
} else { | |
if (null == app.Bluetooth.profile) { | |
console.error("[BT] No profile registered."), callback(null); | |
} else { | |
var guard = null, onConnectionListener = function(socket) { | |
console.log("[BT] Bluetooth connection established with " + socket.device.address); | |
callback(socket); | |
chrome.bluetooth.onConnection.removeListener(onConnectionListener); | |
window.clearTimeout(guard); | |
}, guard = window.setTimeout(function() { | |
console.log("[BT] Bluetooth connection timed out."); | |
chrome.bluetooth.onConnection.removeListener(onConnectionListener); | |
guard = null; | |
callback(null); | |
}, 1E4); | |
chrome.bluetooth.onConnection.addListener(onConnectionListener); | |
chrome.bluetooth.connect({device:{address:deviceInfo.bluetoothAddress, deviceClass:10390323}, profile:{uuid:app.Bluetooth.profile.uuid}}, function() { | |
null == guard ? console.error("[BT] Connection already timed out, error: " + chrome.runtime.lastError) : chrome.runtime.lastError && (console.error("[BT] Could not connect to device: " + chrome.runtime.lastError.message), "No such file or directory" == chrome.runtime.lastError.message && chrome.runtime.reload(), chrome.bluetooth.onConnection.removeListener(onConnectionListener), window.clearTimeout(guard), callback(null)); | |
}); | |
} | |
} | |
}; | |
app.Bluetooth.closeConnection = function(socket) { | |
socket ? chrome.bluetoothSocket.close(socket.id, function() { | |
chrome.runtime.lastError && console.warn("[BT] Failed to close socket " + chrome.runtime.lastError.message); | |
}) : console.warn("[BT] Attempting to close null socket."); | |
}; | |
app.Bluetooth.startAuthorizingPairingRequests = function() { | |
chrome.bluetoothPrivate && (console.log("[BT] Start authorizing pairing requests..."), chrome.bluetoothPrivate.onPairing.addListener(app.Bluetooth.handlePairingEvent_)); | |
}; | |
app.Bluetooth.stopAuthorizePairingRequests = function() { | |
chrome.bluetoothPrivate && (console.log("[BT] Stop authorizing pairing requests..."), chrome.bluetoothPrivate.onPairing.removeListener(app.Bluetooth.handlePairingEvent_)); | |
}; | |
app.Bluetooth.handlePairingEvent_ = function(pairingEvent) { | |
console.log("[BT] Receive pairing request from " + pairingEvent.device.address + ": " + pairingEvent.pairing); | |
console.log(pairingEvent); | |
"requestAuthorization" == pairingEvent.pairing && chrome.bluetoothPrivate.setPairingResponse({device:pairingEvent.device, response:"confirm"}, function() { | |
console.log("[BT] Authorized pairing request"); | |
}); | |
}; | |
app.Bluetooth.refreshAdapterState(function(adapterState) { | |
app.Bluetooth.adapterState = adapterState; | |
}); | |
app.BluetoothConnection = function(device, opt_socket) { | |
easyUnlock.Connection.call(this, device); | |
this.socket_ = opt_socket || null; | |
this.pollingTimeMs_ = app.BluetoothConnection.DEFAULT_POLLING_TIME_MS; | |
this.onReceiveListener_ = this.pollingOverrideDelay_ = this.connectInterval_ = null; | |
if (null != this.socket_) { | |
this.onConnected_(this.socket_, !0); | |
} | |
}; | |
goog.inherits(app.BluetoothConnection, easyUnlock.Connection); | |
app.BluetoothConnection.DEFAULT_POLLING_TIME_MS = 3E3; | |
app.BluetoothConnection.prototype.getBluetoothAddress = function() { | |
return JSCompiler_StaticMethods_getRemoteDevice(this).bluetoothAddress; | |
}; | |
var JSCompiler_StaticMethods_overridePollingTime = function(JSCompiler_StaticMethods_overridePollingTime$self, pollingTimeMs) { | |
console.log("[BC] Applying polling override of " + pollingTimeMs + "ms for 5000ms."); | |
null != JSCompiler_StaticMethods_overridePollingTime$self.pollingOverrideDelay_ && (JSCompiler_StaticMethods_overridePollingTime$self.pollingOverrideDelay_.fire(), JSCompiler_StaticMethods_overridePollingTime$self.pollingOverrideDelay_ = null); | |
var resetInterval = function() { | |
null != this.connectInterval_ && (window.clearInterval(this.connectInterval_), this.connectInterval_ = window.setInterval(this.pollConnect_.bind(this), this.pollingTimeMs_)); | |
}.bind(JSCompiler_StaticMethods_overridePollingTime$self); | |
JSCompiler_StaticMethods_overridePollingTime$self.pollingTimeMs_ = pollingTimeMs; | |
resetInterval(); | |
JSCompiler_StaticMethods_overridePollingTime$self.pollingOverrideDelay_ = new easyUnlock.DelayImpl(function() { | |
console.log("[BC] Restoring polling override: " + this.pollingTimeMs_ + "ms."); | |
this.pollingTimeMs_ = app.BluetoothConnection.DEFAULT_POLLING_TIME_MS; | |
this.pollingOverrideDelay_ = null; | |
resetInterval(); | |
}.bind(JSCompiler_StaticMethods_overridePollingTime$self), 5); | |
JSCompiler_StaticMethods_overridePollingTime$self.pollingOverrideDelay_.start(); | |
}, JSCompiler_StaticMethods_hasPollingOverride = function(JSCompiler_StaticMethods_hasPollingOverride$self) { | |
return null != JSCompiler_StaticMethods_hasPollingOverride$self.pollingOverrideDelay_; | |
}; | |
app.BluetoothConnection.prototype.setPaused = function(paused) { | |
this.getStatus() == easyUnlock.Connection.Status.CONNECTED && chrome.bluetoothSocket.setPaused(this.socket_.id, paused); | |
}; | |
app.BluetoothConnection.prototype.connect = function() { | |
if (this.getStatus() != easyUnlock.Connection.Status.DISCONNECTED) { | |
throw "Connect called but not disconnected."; | |
} | |
JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.IN_PROGRESS); | |
app.Bluetooth.openConnection({bluetoothAddress:this.getBluetoothAddress()}, this.onConnected_.bind(this)); | |
}; | |
app.BluetoothConnection.prototype.onConnected_ = function(socket, opt_paused) { | |
if (this.getStatus() == easyUnlock.Connection.Status.CONNECTED) { | |
throw "Expected disconnected or in progress"; | |
} | |
socket ? (this.socket_ = socket, null != this.connectInterval_ && this.stopDiscovery(), this.onReceiveListener_ = this.onReceive_.bind(this), chrome.bluetoothSocket.onReceive.addListener(this.onReceiveListener_), JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.CONNECTED), this.setPaused(opt_paused || !1), chrome.bluetoothSocket.update(this.socket_.id, {persistent:!0})) : JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.DISCONNECTED); | |
}; | |
app.BluetoothConnection.prototype.disconnect = function() { | |
if (this.getStatus() != easyUnlock.Connection.Status.CONNECTED) { | |
throw "Disconnect called but not connected."; | |
} | |
app.Bluetooth.closeConnection(this.socket_); | |
this.socket_ = null; | |
null != this.connectInterval_ && this.stopDiscovery(); | |
null != this.onReceiveListener_ && (chrome.bluetoothSocket.onReceive.removeListener(this.onReceiveListener_), this.onReceiveListener_ = null); | |
JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.DISCONNECTED); | |
}; | |
app.BluetoothConnection.prototype.startDiscovery = function() { | |
null == this.connectInterval_ && (console.log("[BC] Discovery started..."), this.connectInterval_ = window.setInterval(this.pollConnect_.bind(this), this.pollingTimeMs_)); | |
}; | |
app.BluetoothConnection.prototype.stopDiscovery = function() { | |
console.log("[BC] Discovery stopped..."); | |
null == this.connectInterval_ ? console.error("Not polling.") : (window.clearInterval(this.connectInterval_), this.connectInterval_ = null); | |
}; | |
app.BluetoothConnection.prototype.sendBytes = function(bytes) { | |
if (this.getStatus() != easyUnlock.Connection.Status.CONNECTED) { | |
throw "Can not send bytes when not connected."; | |
} | |
app.Bluetooth.writeToSocket(this.socket_, bytes.buffer, this.onBytesSent_.bind(this)); | |
}; | |
app.BluetoothConnection.prototype.pollConnect_ = function() { | |
this.getStatus() == easyUnlock.Connection.Status.DISCONNECTED && this.connect(); | |
}; | |
app.BluetoothConnection.prototype.onBytesSent_ = function(success) { | |
this.onSendCompleted(success); | |
success || this.disconnect(); | |
}; | |
app.BluetoothConnection.prototype.onReceive_ = function(info) { | |
if (info.socketId == this.socket_.id) { | |
var bytes = info.data ? new Uint8Array(info.data) : new Uint8Array([]); | |
console.log("[BC] Received " + bytes.length + " bytes."); | |
0 < bytes.length ? JSCompiler_StaticMethods_onBytesReceived(this, bytes) : console.error("[BC] No data received."); | |
} | |
}; | |
app.DeviceManager = function() { | |
this.devices_ = []; | |
this.localDevice_ = null; | |
this.userEmail_ = ""; | |
}; | |
app.DeviceManager.prototype.init = function(callback) { | |
var initEmail = function() { | |
chrome.feedbackPrivate.getUserEmail(function(email) { | |
this.userEmail_ = email; | |
callback(); | |
}.bind(this)); | |
}.bind(this), initDevices = function() { | |
JSCompiler_StaticMethods_loadDevices_(this, initEmail); | |
}.bind(this); | |
app.Bluetooth.refreshAdapterState(initDevices); | |
}; | |
var JSCompiler_StaticMethods_loadDevices_ = function(JSCompiler_StaticMethods_loadDevices_$self, callback) { | |
JSCompiler_StaticMethods_loadDevices_$self.localDevice_ = new easyUnlock.EasyUnlockDevice(app.Bluetooth.adapterState.address, app.Bluetooth.adapterState.name); | |
var storageCallback = function(items) { | |
if (chrome.runtime.lastError) { | |
console.error("Error loading paired device: " + chrome.runtime.lastError), callback(!1); | |
} else { | |
if (void 0 != items.permitAccess) { | |
var permitAccess = permit.PermitRecord.fromJSON(items.permitAccess); | |
this.localDevice_.permitRecord = permitAccess; | |
} | |
for (var devicesJSON = items.easyUnlockDevices || [], i = 0;i < devicesJSON.length;++i) { | |
var device = easyUnlock.EasyUnlockDevice.fromJSON(devicesJSON[i]); | |
null != device && this.devices_.push(device); | |
} | |
callback(!0); | |
} | |
}.bind(JSCompiler_StaticMethods_loadDevices_$self); | |
chrome.storage.local.get(["easyUnlockDevices", "permitAccess"], storageCallback); | |
}; | |
app.DeviceManager.prototype.getUserEmail = function() { | |
return this.userEmail_; | |
}; | |
var JSCompiler_StaticMethods_getLocalDevice = function(JSCompiler_StaticMethods_getLocalDevice$self) { | |
return JSCompiler_StaticMethods_getLocalDevice$self.localDevice_; | |
}, JSCompiler_StaticMethods_getRemoteDevices = function(JSCompiler_StaticMethods_getRemoteDevices$self) { | |
return Array.apply([], JSCompiler_StaticMethods_getRemoteDevices$self.devices_); | |
}, JSCompiler_StaticMethods_addRemoteDevice = function(JSCompiler_StaticMethods_addRemoteDevice$self, device) { | |
JSCompiler_StaticMethods_addRemoteDevice$self.devices_.push(device); | |
var json = JSCompiler_StaticMethods_addRemoteDevice$self.devices_.map(function(value) { | |
return value.toJSON(); | |
}), obj = {}; | |
obj.easyUnlockDevices = json; | |
chrome.storage.local.set(obj, function() { | |
chrome.runtime.lastError && console.error("Error saving paired device: " + chrome.runtime.lastError); | |
}); | |
}; | |
app.DeviceManager.prototype.setPermitAccess = function(permitAccess) { | |
this.localDevice_.permitRecord = permitAccess; | |
if (null == permitAccess) { | |
chrome.storage.local.remove("permitAccess"); | |
} else { | |
var obj = {}; | |
obj.permitAccess = permitAccess.toJSON(); | |
chrome.storage.local.set(obj, function() { | |
chrome.runtime.lastError && console.error("Error saving permit access: " + chrome.runtime.lastError); | |
}); | |
} | |
}; | |
app.Launcher = {WINDOW_ID:"easy_unlock_pairing", WINDOW_URL:"pairing.html", WINDOW_WIDTH:420, WINDOW_HEIGHT:335}; | |
app.Launcher.launchPairingDialog = function() { | |
var screenWidth = screen.availWidth, screenHeight = screen.availHeight, expectedHeight = app.Launcher.WINDOW_HEIGHT, width = Math.min(screenWidth, app.Launcher.WINDOW_WIDTH), height = Math.min(screenHeight, expectedHeight); | |
chrome.app.window.create(app.Launcher.WINDOW_URL, {id:"easyunlock", width:width, height:height, minWidth:width, minHeight:height, maxWidth:width, maxHeight:height, frame:"none", bounds:{left:Math.floor((screenWidth - width) / 2), top:Math.floor((screenHeight - height) / 2), width:width, height:height}}); | |
}; | |
app.Metrics = function() { | |
}; | |
app.Metrics.HistogramNamespace_ = "EasyUnlock"; | |
app.Metrics.NotificationEvent = {SHOWN_SET_UP:"notification-shown-set-up", CLICKED_SET_UP:"notification-clicked-set-up", SHOWN_DONE:"notification-shown-done", CLICKED_DONE:"notification-shown-done"}; | |
app.Metrics.NotificationsHistogramName_ = "NotificationEvent"; | |
app.Metrics.NotificationsHistogramValues_ = [app.Metrics.NotificationEvent.SHOWN_SET_UP, app.Metrics.NotificationEvent.CLICKED_SET_UP, app.Metrics.NotificationEvent.SHOWN_DONE, app.Metrics.NotificationEvent.CLICKED_DONE]; | |
app.Metrics.ButtonClick = {APP_LAUNCHED:"app-launched", FIND:"button-click-find", PAIR:"button-click-pair", TRY_OUT:"button-click-try-out", ENABLE:"button-click-enable", DISABLE:"button-click-disable"}; | |
app.Metrics.ButtonClickHistogramName_ = "ClickedButton"; | |
app.Metrics.ButtonClickHistogramValues_ = [app.Metrics.ButtonClick.APP_LAUNCHED, app.Metrics.ButtonClick.FIND, app.Metrics.ButtonClick.PAIR, app.Metrics.ButtonClick.TRY_OUT, app.Metrics.ButtonClick.ENABLE, app.Metrics.ButtonClick.DISABLE]; | |
app.Metrics.SetupStateOnClose = {SUCCESS:"success", SCAN_INITIAL:"scan-initial", SCAN_IN_PROGRESS:"scan-in-progress", SCAN_ERROR:"scan-error", PAIRING_INITIAL:"pairing-initial", PAIRING_IN_PROGRESS:"pairing-in-progress", PAIRING_ERROR:"pairing-error", HELP:"help"}; | |
app.Metrics.SetupStateOnCloseHistogramName_ = "SetupStateOnClose"; | |
app.Metrics.SetupStateOnCloseHistogramValues_ = [app.Metrics.SetupStateOnClose.SUCCESS, app.Metrics.SetupStateOnClose.SCAN_INITIAL, app.Metrics.SetupStateOnClose.SCAN_IN_PROGRESS, app.Metrics.SetupStateOnClose.SCAN_ERROR, app.Metrics.SetupStateOnClose.PAIRING_INITIAL, app.Metrics.SetupStateOnClose.PAIRING_IN_PROGRESS, app.Metrics.SetupStateOnClose.PAIRING_ERROR, app.Metrics.SetupStateOnClose.HELP]; | |
app.Metrics.UnlockEvent = {UNLOCKED:"screen-unlocked", UNLOCKED_EASY_UNLOCK:"screen-unlocked-easy-unlock"}; | |
app.Metrics.UnlockEventHistogramName_ = "UnlockEvent"; | |
app.Metrics.UnlockEventHistogramValues_ = [app.Metrics.UnlockEvent.UNLOCKED, app.Metrics.UnlockEvent.UNLOCKED_EASY_UNLOCK]; | |
app.Metrics.StartupTimeHistogramName_ = "StartupTimeFromSuspend"; | |
app.Metrics.recordNotificationEvent = function(event) { | |
app.Metrics.recordEnum_(app.Metrics.NotificationsHistogramName_, event, app.Metrics.NotificationsHistogramValues_); | |
}; | |
app.Metrics.recordButtonClick = function(event) { | |
app.Metrics.recordEnum_(app.Metrics.ButtonClickHistogramName_, event, app.Metrics.ButtonClickHistogramValues_); | |
}; | |
app.Metrics.recordSetupStateOnClose = function(state) { | |
state && app.Metrics.recordEnum_(app.Metrics.SetupStateOnCloseHistogramName_, state, app.Metrics.SetupStateOnCloseHistogramValues_); | |
}; | |
app.Metrics.recordUnlockEvent = function(event) { | |
app.Metrics.recordEnum_(app.Metrics.UnlockEventHistogramName_, event, app.Metrics.UnlockEventHistogramValues_); | |
}; | |
app.Metrics.recordStartupTimeFromSuspend = function(timeMs) { | |
var metricName = app.Metrics.getFullMetricName_(app.Metrics.StartupTimeHistogramName_); | |
chrome.metricsPrivate.recordMediumTime(metricName, timeMs); | |
}; | |
app.Metrics.getFullMetricName_ = function(metricName) { | |
return[app.Metrics.HistogramNamespace_, metricName].join("."); | |
}; | |
app.Metrics.recordEnum_ = function(name, value, enumValues) { | |
var enumSize = enumValues.length, valueIndex = enumValues.indexOf(value); | |
0 > valueIndex && (valueIndex = enumSize); | |
var enumConfiguration = {metricName:app.Metrics.getFullMetricName_(name), type:"histogram-linear", min:1, max:enumSize, buckets:enumSize + 1}; | |
try { | |
chrome.metricsPrivate.recordValue(enumConfiguration, valueIndex); | |
} catch (e) { | |
console.warn("Failed to record enum value " + value + " in " + name); | |
} | |
}; | |
app.ProxAuth = {}; | |
app.ProxAuth.MESSAGE_DEVICES_FOR_PAIRING_URL = "https://www-googleapis-staging.sandbox.google.com/cryptauth/sandbox/proximityAuth/messageuserdevicesforpairing?alt=JSON"; | |
app.ProxAuth.messageUserDevicesForPairing = function(params, callback) { | |
chrome.identity.getAuthToken({interactive:!0}, function(token) { | |
if (chrome.runtime.lastError) { | |
console.log("Could not get OAuth token :-( " + chrome.runtime.lastError.message); | |
} else { | |
var paramsBytes = permit.util.stringToUint8Array(JSON.stringify(params)), postContent = {payload:{additionalMetadata:permit.crypto.base64Encode(paramsBytes), contactOnlyAuthDevices:!1}}; | |
goog.net.XhrIo.send(app.ProxAuth.MESSAGE_DEVICES_FOR_PAIRING_URL, function(e) { | |
var xhr = e.target; | |
console.log("Proxy Auth server replied: " + JSCompiler_StaticMethods_getResponseText(xhr)); | |
callback(JSON.parse(JSCompiler_StaticMethods_getResponseText(xhr))); | |
}, "POST", JSON.stringify(postContent), {authorization:"Bearer " + token, "Content-Type":"application/json"}); | |
} | |
}); | |
}; | |
app.AppSetupFlowDelegate = function(deviceManager, connectionCallback) { | |
this.deviceManager_ = deviceManager; | |
this.pendingPermitAccess_ = null; | |
this.connectionCallback_ = connectionCallback; | |
this.completionCallback_ = null; | |
}; | |
app.AppSetupFlowDelegate.prototype.getPermitAccess = function() { | |
return null != this.pendingPermitAccess_ ? this.pendingPermitAccess_ : JSCompiler_StaticMethods_getLocalDevice(this.deviceManager_).permitRecord; | |
}; | |
app.AppSetupFlowDelegate.prototype.setPermitAccess = function(permitAccess) { | |
this.pendingPermitAccess_ = permitAccess; | |
}; | |
app.AppSetupFlowDelegate.prototype.getBluetoothAddress = function() { | |
return JSCompiler_StaticMethods_getLocalDevice(this.deviceManager_).bluetoothAddress; | |
}; | |
app.AppSetupFlowDelegate.prototype.getUserGaiaId = function() { | |
return this.deviceManager_.getUserEmail(); | |
}; | |
app.AppSetupFlowDelegate.prototype.pingUserDevices = function(data, callback) { | |
app.ProxAuth.messageUserDevicesForPairing(data, function(response) { | |
callback(0 < response.numGcmDevicesSucceeded); | |
}); | |
}; | |
app.AppSetupFlowDelegate.prototype.scanForDevices = function() { | |
app.Bluetooth.registerProfile(app.Bluetooth.SETUP_PROFILE); | |
app.Bluetooth.startAuthorizingPairingRequests(); | |
app.Bluetooth.startListeningOverBluetooth(this.onIncomingConnection_.bind(this)); | |
}; | |
app.AppSetupFlowDelegate.prototype.onIncomingConnection_ = function(socket) { | |
if (null != socket) { | |
var connection = new app.BluetoothConnection(new easyUnlock.EasyUnlockDevice(socket.device.address, socket.device.name), socket); | |
null != this.connectionCallback_ && this.connectionCallback_(connection); | |
} | |
}; | |
app.AppSetupFlowDelegate.prototype.onSetupCompleted = function(devices) { | |
for (var i = 0;i < devices.length;++i) { | |
JSCompiler_StaticMethods_addRemoteDevice(this.deviceManager_, devices[i]); | |
} | |
0 < devices.length && (this.completionCallback_(!0), null != this.pendingPermitAccess_ && this.deviceManager_.setPermitAccess(this.pendingPermitAccess_)); | |
}; | |
app.AppSetupFlowDelegate.prototype.onSetupFailed = function() { | |
null != this.completionCallback_ && this.completionCallback_(!1); | |
}; | |
app.ResourceUtil = {}; | |
app.ResourceUtil.ROOT_DIR_100_ = "assets/100/"; | |
app.ResourceUtil.ROOT_DIR_200_ = "assets/200/"; | |
app.ResourceUtil.THROBBER_STEPS = 36; | |
app.ResourceUtil.Icon = {NOTIFICATION_START_SETUP:{path:"magic_auth.png", supports2xAssets:!0}, NOTIFICATION_ALL_SET:{path:"magic_auth_set.png", supports2xAssets:!0}, SCREEN_LOCK_LOCKED:{path:"locked.png", supports2xAssets:!1}, SCREEN_LOCK_UNLOCKED:{path:"unlocked.png", supports2xAssets:!1}, SCREEN_LOCK_LOCKED_OPAQUE:{path:"locked_opaque.png", supports2xAssets:!1}}; | |
app.ResourceUtil.getIconPath = function(icon) { | |
return(1 < window.devicePixelRatio && icon.supports2xAssets ? app.ResourceUtil.ROOT_DIR_200_ : app.ResourceUtil.ROOT_DIR_100_).concat(icon.path); | |
}; | |
app.ResourceUtil.getThrobberPath = function(step) { | |
step = Math.floor(step) % app.ResourceUtil.THROBBER_STEPS; | |
return "assets/throbber/throbber_" + (10 > step ? "0" : "") + step + ".png"; | |
}; | |
app.NotificationController = function() { | |
var that = this; | |
chrome.notifications.onClicked.addListener(function(notificationId) { | |
that.handleButtonClicked_(notificationId); | |
}); | |
chrome.notifications.onButtonClicked.addListener(this.handleButtonClicked_.bind(this)); | |
chrome.notifications.onClosed.addListener(this.handleClosed_.bind(this)); | |
}; | |
app.NotificationController.NOTIFICATION_SETUP_ID = "easy_unlock_setup"; | |
app.NotificationController.NOTIFICATION_ALL_SET_ID = "easy_unlock_all_set"; | |
var JSCompiler_StaticMethods_maybeShowSetup = function() { | |
JSCompiler_StaticMethods_checkIfDismissed_(); | |
}, JSCompiler_StaticMethods_checkIfDismissed_ = function() { | |
chrome.storage.local.get("notificationDismissed", function(items) { | |
console.log("notificationDismissed: " + items.notificationDismissed); | |
chrome.runtime.lastError ? console.error("Error reading from local storage: " + chrome.runtime.lastError) : items.notificationDismissed || JSCompiler_StaticMethods_checkForPairableDevice_(this); | |
}.bind(notificationController)); | |
}, JSCompiler_StaticMethods_checkForPairableDevice_ = function(JSCompiler_StaticMethods_checkForPairableDevice_$self) { | |
app.ProxAuth.messageUserDevicesForPairing({}, function(response) { | |
console.log(response); | |
0 < response.numGcmDevicesSucceeded && JSCompiler_StaticMethods_showSetupNotification(); | |
}.bind(JSCompiler_StaticMethods_checkForPairableDevice_$self)); | |
}, JSCompiler_StaticMethods_saveDismissed_ = function() { | |
chrome.storage.local.set({notificationDismissed:!0}, function() { | |
console.log("saved dismissed: true"); | |
}); | |
}; | |
app.NotificationController.prototype.handleButtonClicked_ = function(notificationId) { | |
notificationId == app.NotificationController.NOTIFICATION_SETUP_ID ? (app.Metrics.recordNotificationEvent(app.Metrics.NotificationEvent.CLICKED_SET_UP), app.Launcher.launchPairingDialog()) : console.error("Unknown notification id: " + notificationId); | |
}; | |
app.NotificationController.prototype.handleClosed_ = function(notificationId, byUser) { | |
notificationId == app.NotificationController.NOTIFICATION_SETUP_ID ? byUser && JSCompiler_StaticMethods_saveDismissed_() : notificationId != app.NotificationController.NOTIFICATION_ALL_SET_ID && console.error("Unknown notification id: " + notificationId); | |
}; | |
var JSCompiler_StaticMethods_showSetupNotification = function() { | |
var opts = {type:"basic", title:"Easy Unlock", message:"Use your phone to unlock your Chromebook. No password necessary.", iconUrl:app.ResourceUtil.getIconPath(app.ResourceUtil.Icon.NOTIFICATION_START_SETUP), isClickable:!0, buttons:[{title:"1-min setup"}]}; | |
app.Metrics.recordNotificationEvent(app.Metrics.NotificationEvent.SHOWN_SET_UP); | |
chrome.notifications.create(app.NotificationController.NOTIFICATION_SETUP_ID, opts, function() { | |
console.log("setup notification created"); | |
}); | |
}, JSCompiler_StaticMethods_clearSetupNotification = function() { | |
chrome.notifications.clear(app.NotificationController.NOTIFICATION_SETUP_ID, function(wasCleared) { | |
console.log("Cleared setup notification success: " + wasCleared); | |
}); | |
}, JSCompiler_StaticMethods_showAllSetNotification = function(deviceName) { | |
deviceName || (deviceName = "phone"); | |
var opts = {type:"basic", title:"All Set!", message:"This Chromebook will now Easy Unlock when you and your " + deviceName + " are nearby.", iconUrl:app.ResourceUtil.getIconPath(app.ResourceUtil.Icon.NOTIFICATION_ALL_SET), isClickable:!1}; | |
app.Metrics.recordNotificationEvent(app.Metrics.NotificationEvent.SHOWN_DONE); | |
chrome.notifications.create(app.NotificationController.NOTIFICATION_ALL_SET_ID, opts, function() { | |
console.log("all set notification created"); | |
}); | |
}; | |
app.SleepDetector = function(onResumeCallback) { | |
this.onResumeCallback_ = onResumeCallback; | |
this.interval_ = null; | |
this.lastSampleMs_ = 0; | |
}; | |
app.SleepDetector.prototype.start = function() { | |
null != this.interval_ ? console.warn("SleepDetector already started") : (this.interval_ = window.setInterval(this.sample_.bind(this), 500), this.lastSampleMs_ = (new Date).getTime()); | |
}; | |
app.SleepDetector.prototype.stop = function() { | |
null == this.interval_ ? console.warn("SleepDetector not started") : window.clearInterval(this.interval_); | |
}; | |
app.SleepDetector.prototype.sample_ = function() { | |
var timeMs = (new Date).getTime(); | |
if (5E3 <= timeMs - this.lastSampleMs_) { | |
this.onResumeCallback_(); | |
} | |
this.lastSampleMs_ = timeMs; | |
}; | |
app.UnlockManager = function(deviceManager, opt_autolock) { | |
this.deviceManager_ = deviceManager; | |
this.connections_ = []; | |
this.authenticators_ = []; | |
this.locked_ = !1; | |
this.autolock_ = opt_autolock || !1; | |
this.throbberAnimator_ = null; | |
this.sleepDetector_ = new app.SleepDetector(this.onResumeFromSleep_.bind(this)); | |
this.resumeFromSleepTimestampMs_ = null; | |
}; | |
app.UnlockManager.ThrobberAnimator = function() { | |
this.animationDelay_ = this.interval_ = null; | |
}; | |
app.UnlockManager.ThrobberAnimator.CYCLE_DURATION_MS = 1E3; | |
var JSCompiler_StaticMethods_animate = function(JSCompiler_StaticMethods_animate$self, opt_callback) { | |
if (null != JSCompiler_StaticMethods_animate$self.interval_) { | |
console.log("[Unlock] Throbber animation already started."); | |
} else { | |
var tickMs = app.UnlockManager.ThrobberAnimator.CYCLE_DURATION_MS / app.ResourceUtil.THROBBER_STEPS; | |
JSCompiler_StaticMethods_animate$self.interval_ = window.setInterval(JSCompiler_StaticMethods_animate$self.step_.bind(JSCompiler_StaticMethods_animate$self), tickMs); | |
var completionFunction = function() { | |
this.stop(); | |
void 0 != opt_callback && opt_callback(); | |
}.bind(JSCompiler_StaticMethods_animate$self); | |
JSCompiler_StaticMethods_animate$self.animationDelay_ = new easyUnlock.DelayImpl(completionFunction, 7); | |
JSCompiler_StaticMethods_animate$self.animationDelay_.start(); | |
} | |
}; | |
app.UnlockManager.ThrobberAnimator.prototype.step_ = function() { | |
var cycleDuration = app.UnlockManager.ThrobberAnimator.CYCLE_DURATION_MS, maxSteps = app.ResourceUtil.THROBBER_STEPS, step = Math.floor(Date.now() % cycleDuration * maxSteps / cycleDuration); | |
chrome.screenlockPrivate.showButton(app.ResourceUtil.getThrobberPath(step)); | |
}; | |
app.UnlockManager.ThrobberAnimator.prototype.stop = function() { | |
null != this.interval_ && (window.clearInterval(this.interval_), this.interval_ = null); | |
null != this.animationDelay_ && (this.animationDelay_.stop(), this.animationDelay_ = null); | |
}; | |
app.UnlockManager.prototype.isAuthenticated = function() { | |
return this.authenticators_.reduce(function(prev, authenticator) { | |
return prev || authenticator.isAuthenticated(); | |
}, !1); | |
}; | |
app.UnlockManager.prototype.isConnected = function() { | |
return this.authenticators_.reduce(function(prev, authenticator) { | |
return prev || authenticator.isConnected(); | |
}, !1); | |
}; | |
app.UnlockManager.prototype.init = function() { | |
app.Bluetooth.registerProfile(app.Bluetooth.UNLOCK_PROFILE); | |
var devices = JSCompiler_StaticMethods_getRemoteDevices(this.deviceManager_), permitAccess = JSCompiler_StaticMethods_getLocalDevice(this.deviceManager_).permitRecord; | |
if (null == permitAccess) { | |
throw "Expected a permit access for the local device."; | |
} | |
this.connections_ = devices.map(function(device) { | |
return new app.BluetoothConnection(device); | |
}); | |
this.authenticators_ = this.connections_.map(function(connection) { | |
return new easyUnlock.Authenticator(connection, permitAccess, this, new easyUnlock.TimerImpl); | |
}, this); | |
chrome.screenlockPrivate.onChanged.addListener(this.onLockStateChanged_.bind(this)); | |
chrome.screenlockPrivate.onAuthAttempted.addListener(this.onAuthAttempted_.bind(this)); | |
chrome.bluetooth.onDeviceChanged.addListener(this.onDeviceChanged_.bind(this)); | |
chrome.screenlockPrivate.getLocked(this.onLockStateChanged_.bind(this)); | |
this.sleepDetector_.start(); | |
this.authenticators_.forEach(function(authenticator) { | |
authenticator.start(); | |
}); | |
this.connections_.forEach(function(conn) { | |
conn.connect(); | |
}); | |
}; | |
app.UnlockManager.prototype.updateLockScreenUI_ = function() { | |
null != this.throbberAnimator_ && (this.throbberAnimator_.stop(), this.throbberAnimator_ = null); | |
if (this.locked_) { | |
var icon = this.isAuthenticated() ? app.ResourceUtil.Icon.SCREEN_LOCK_UNLOCKED : this.isConnected() ? app.ResourceUtil.Icon.SCREEN_LOCK_LOCKED : app.ResourceUtil.Icon.SCREEN_LOCK_LOCKED_OPAQUE; | |
chrome.screenlockPrivate.showButton(app.ResourceUtil.getIconPath(icon)); | |
this.isAuthenticated() ? chrome.screenlockPrivate.setAuthType("userClick", "Click to unlock") : chrome.screenlockPrivate.setAuthType("offlinePassword"); | |
} | |
}; | |
app.UnlockManager.prototype.onLockStateChanged_ = function(locked) { | |
this.locked_ && !locked && app.Metrics.recordUnlockEvent(app.Metrics.UnlockEvent.UNLOCKED); | |
this.locked_ = locked; | |
this.updateLockScreenUI_(); | |
}; | |
app.UnlockManager.prototype.onAuthAttempted_ = function(authType) { | |
"userClick" == authType && (this.isAuthenticated() ? (app.Metrics.recordUnlockEvent(app.Metrics.UnlockEvent.UNLOCKED_EASY_UNLOCK), chrome.screenlockPrivate.acceptAuthAttempt(!0)) : (chrome.screenlockPrivate.setAuthType("offlinePassword"), chrome.screenlockPrivate.acceptAuthAttempt(!1))); | |
}; | |
app.UnlockManager.prototype.onDeviceChanged_ = function(device) { | |
this.connections_.forEach(function(connection) { | |
device.address == connection.getBluetoothAddress() && !device.connected && connection.isConnected() && (console.log("[Unlock] Device disconnected..."), JSCompiler_StaticMethods_hasPollingOverride(connection) || (console.log("[Unlock] Applying cooldown."), JSCompiler_StaticMethods_overridePollingTime(connection, 1E5)), connection.disconnect()); | |
}, this); | |
}; | |
app.UnlockManager.prototype.onResumeFromSleep_ = function() { | |
console.log("[Unlock] Resume from sleep detected..."); | |
this.authenticators_.forEach(function(authenticator) { | |
JSCompiler_StaticMethods_deauthenticate(authenticator); | |
}); | |
this.connections_.forEach(function(conn) { | |
JSCompiler_StaticMethods_overridePollingTime(conn, 500); | |
}); | |
this.locked_ && (null != this.throbberAnimator_ && this.throbberAnimator_.stop(), this.throbberAnimator_ = new app.UnlockManager.ThrobberAnimator, JSCompiler_StaticMethods_animate(this.throbberAnimator_, this.updateLockScreenUI_.bind(this))); | |
this.resumeFromSleepTimestampMs_ = Date.now(); | |
}; | |
var JSCompiler_StaticMethods_recordStartupTimeFromSuspend_ = function(JSCompiler_StaticMethods_recordStartupTimeFromSuspend_$self) { | |
if (null != JSCompiler_StaticMethods_recordStartupTimeFromSuspend_$self.resumeFromSleepTimestampMs_) { | |
var elapsedTimeMs = Date.now() - JSCompiler_StaticMethods_recordStartupTimeFromSuspend_$self.resumeFromSleepTimestampMs_; | |
app.Metrics.recordStartupTimeFromSuspend(elapsedTimeMs); | |
JSCompiler_StaticMethods_recordStartupTimeFromSuspend_$self.resumeFromSleepTimestampMs_ = null; | |
} | |
}; | |
app.UnlockManager.prototype.onAuthenticationChanged = function(authenticated) { | |
console.log("[Unlock] Auth changed: " + authenticated); | |
JSCompiler_StaticMethods_recordStartupTimeFromSuspend_(this); | |
this.locked_ ? this.updateLockScreenUI_() : !authenticated && this.autolock_ && (chrome.screenlockPrivate.setLocked(!0), chrome.screenlockPrivate.showMessage("Phone lost")); | |
}; | |
app.UnlockManager.prototype.onAuthenticationRefreshed = function() { | |
console.log("[Unlock] Auth refreshed"); | |
JSCompiler_StaticMethods_recordStartupTimeFromSuspend_(this); | |
}; | |
app.UnlockManager.prototype.onAuthenticationFailed = function() { | |
console.log("[Unlock] Auth failed"); | |
this.updateLockScreenUI_(); | |
JSCompiler_StaticMethods_recordStartupTimeFromSuspend_(this); | |
}; | |
app.UnlockManager.prototype.onAuthenticatorConnnectionChanged = function() { | |
null == this.throbberAnimator_ && this.updateLockScreenUI_(); | |
}; | |
var deviceManager = new app.DeviceManager, unlockManager = null, notificationController = new app.NotificationController; | |
function loadSettings(callback) { | |
chrome.storage.local.get(["easyUnlockEnabled", "easyUnlockAutolock"], function(items) { | |
var enabled = !0, autolock = !1; | |
chrome.runtime.lastError ? console.error("Error loading settings, using default values.") : (enabled = items.easyUnlockEnabled, void 0 == enabled && (enabled = !0), autolock = items.easyUnlockAutolock, void 0 == autolock && (autolock = !1)); | |
console.log("[BG] Enabled: " + enabled + ", Autolock: " + autolock); | |
callback({easyUnlockEnabled:enabled, easyUnlockAutolock:autolock}); | |
}); | |
} | |
var initialized = !1; | |
function initEasyUnlock() { | |
initialized || (initialized = !0, deviceManager.init(function() { | |
var devices = JSCompiler_StaticMethods_getRemoteDevices(deviceManager); | |
console.log("Found " + devices.length + " registered devices."); | |
0 < devices.length ? loadSettings(function(settings) { | |
settings.easyUnlockEnabled && (unlockManager = new app.UnlockManager(deviceManager, settings.easyUnlockAutolock), unlockManager.init()); | |
}) : JSCompiler_StaticMethods_maybeShowSetup(); | |
var hack = function() { | |
window.setTimeout(function() { | |
chrome.feedbackPrivate.getUserEmail(function() { | |
hack(); | |
}); | |
}, 1E3); | |
}; | |
hack(); | |
})); | |
} | |
function handleShowTutorial() { | |
var showNotificationListener = function(locked) { | |
if (locked) { | |
unlockManager.isConnected() && !unlockManager.isAuthenticated() && chrome.screenlockPrivate.showMessage("Your phone must be unlocked as well in order to Easy Unlock your Chromebook. Give it a try!"); | |
} else { | |
var devices = JSCompiler_StaticMethods_getRemoteDevices(deviceManager); | |
JSCompiler_StaticMethods_showAllSetNotification(devices[devices.length - 1].name); | |
chrome.screenlockPrivate.onChanged.removeListener(showNotificationListener); | |
} | |
}; | |
chrome.screenlockPrivate.onChanged.addListener(showNotificationListener); | |
chrome.screenlockPrivate.setLocked(!0); | |
} | |
chrome.app.runtime.onLaunched.addListener(app.Launcher.launchPairingDialog); | |
chrome.runtime.onMessage.addListener(function(message) { | |
console.log("Message Received: " + message); | |
"pairingCompleted" == message ? (initialized = !1, initEasyUnlock(), JSCompiler_StaticMethods_clearSetupNotification()) : "showTutorial" == message && handleShowTutorial(); | |
}); | |
chrome.runtime.onStartup.addListener(function() { | |
console.log("[Startup]"); | |
initEasyUnlock(); | |
}); | |
initEasyUnlock(); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var goog = goog || {}; | |
goog.global = this; | |
goog.isDef = function(val) { | |
return void 0 !== val; | |
}; | |
goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) { | |
var parts = name.split("."), cur = opt_objectToExportTo || goog.global; | |
parts[0] in cur || !cur.execScript || cur.execScript("var " + parts[0]); | |
for (var part;parts.length && (part = parts.shift());) { | |
!parts.length && goog.isDef(opt_object) ? cur[part] = opt_object : cur = cur[part] ? cur[part] : cur[part] = {}; | |
} | |
}; | |
goog.define = function(name, defaultValue) { | |
goog.exportPath_(name, defaultValue); | |
}; | |
goog.DEBUG = !0; | |
goog.LOCALE = "en"; | |
goog.TRUSTED_SITE = !0; | |
goog.STRICT_MODE_COMPATIBLE = !1; | |
goog.provide = function(name) { | |
goog.exportPath_(name); | |
}; | |
goog.setTestOnly = function(opt_message) { | |
if (!goog.DEBUG) { | |
throw opt_message = opt_message || "", Error("Importing test-only code into non-debug environment" + (opt_message ? ": " + opt_message : ".")); | |
} | |
}; | |
goog.forwardDeclare = function() { | |
}; | |
goog.getObjectByName = function(name) { | |
for (var parts = name.split("."), cur = goog.global, part;part = parts.shift();) { | |
if (goog.isDefAndNotNull(cur[part])) { | |
cur = cur[part]; | |
} else { | |
return null; | |
} | |
} | |
return cur; | |
}; | |
goog.globalize = function(obj, opt_global) { | |
var global = opt_global || goog.global, x; | |
for (x in obj) { | |
global[x] = obj[x]; | |
} | |
}; | |
goog.addDependency = function(relPath, provides, requires) { | |
if (goog.DEPENDENCIES_ENABLED) { | |
for (var provide, require, path = relPath.replace(/\\/g, "/"), deps = goog.dependencies_, i = 0;provide = provides[i];i++) { | |
deps.nameToPath[provide] = path, path in deps.pathToNames || (deps.pathToNames[path] = {}), deps.pathToNames[path][provide] = !0; | |
} | |
for (var j = 0;require = requires[j];j++) { | |
path in deps.requires || (deps.requires[path] = {}), deps.requires[path][require] = !0; | |
} | |
} | |
}; | |
goog.useStrictRequires = !1; | |
goog.ENABLE_DEBUG_LOADER = !0; | |
goog.require = function() { | |
}; | |
goog.basePath = ""; | |
goog.nullFunction = function() { | |
}; | |
goog.identityFunction = function(opt_returnValue) { | |
return opt_returnValue; | |
}; | |
goog.abstractMethod = function() { | |
throw Error("unimplemented abstract method"); | |
}; | |
goog.addSingletonGetter = function(ctor) { | |
ctor.getInstance = function() { | |
if (ctor.instance_) { | |
return ctor.instance_; | |
} | |
goog.DEBUG && (goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor); | |
return ctor.instance_ = new ctor; | |
}; | |
}; | |
goog.instantiatedSingletons_ = []; | |
goog.DEPENDENCIES_ENABLED = !1; | |
goog.DEPENDENCIES_ENABLED && (goog.included_ = {}, goog.dependencies_ = {pathToNames:{}, nameToPath:{}, requires:{}, visited:{}, written:{}}, goog.inHtmlDocument_ = function() { | |
var doc = goog.global.document; | |
return "undefined" != typeof doc && "write" in doc; | |
}, goog.findBasePath_ = function() { | |
if (goog.global.CLOSURE_BASE_PATH) { | |
goog.basePath = goog.global.CLOSURE_BASE_PATH; | |
} else { | |
if (goog.inHtmlDocument_()) { | |
for (var scripts = goog.global.document.getElementsByTagName("script"), i = scripts.length - 1;0 <= i;--i) { | |
var src = scripts[i].src, qmark = src.lastIndexOf("?"), l = -1 == qmark ? src.length : qmark; | |
if ("base.js" == src.substr(l - 7, 7)) { | |
goog.basePath = src.substr(0, l - 7); | |
break; | |
} | |
} | |
} | |
} | |
}, goog.importScript_ = function(src) { | |
var importScript = goog.global.CLOSURE_IMPORT_SCRIPT || goog.writeScriptTag_; | |
!goog.dependencies_.written[src] && importScript(src) && (goog.dependencies_.written[src] = !0); | |
}, goog.writeScriptTag_ = function(src) { | |
if (goog.inHtmlDocument_()) { | |
var doc = goog.global.document; | |
if ("complete" == doc.readyState) { | |
if (/\bdeps.js$/.test(src)) { | |
return!1; | |
} | |
throw Error('Cannot write "' + src + '" after document load'); | |
} | |
doc.write('<script type="text/javascript" src="' + src + '">\x3c/script>'); | |
return!0; | |
} | |
return!1; | |
}, goog.writeScripts_ = function() { | |
function visitNode(path) { | |
if (!(path in deps.written)) { | |
if (!(path in deps.visited) && (deps.visited[path] = !0, path in deps.requires)) { | |
for (var requireName in deps.requires[path]) { | |
if (!goog.isProvided_(requireName)) { | |
if (requireName in deps.nameToPath) { | |
visitNode(deps.nameToPath[requireName]); | |
} else { | |
throw Error("Undefined nameToPath for " + requireName); | |
} | |
} | |
} | |
} | |
path in seenScript || (seenScript[path] = !0, scripts.push(path)); | |
} | |
} | |
var scripts = [], seenScript = {}, deps = goog.dependencies_, path$$0; | |
for (path$$0 in goog.included_) { | |
deps.written[path$$0] || visitNode(path$$0); | |
} | |
for (var i = 0;i < scripts.length;i++) { | |
if (scripts[i]) { | |
goog.importScript_(goog.basePath + scripts[i]); | |
} else { | |
throw Error("Undefined script input"); | |
} | |
} | |
}, goog.getPathFromDeps_ = function(rule) { | |
return rule in goog.dependencies_.nameToPath ? goog.dependencies_.nameToPath[rule] : null; | |
}, goog.findBasePath_(), goog.global.CLOSURE_NO_DEPS || goog.importScript_(goog.basePath + "deps.js")); | |
goog.typeOf = function(value) { | |
var s = typeof value; | |
if ("object" == s) { | |
if (value) { | |
if (value instanceof Array) { | |
return "array"; | |
} | |
if (value instanceof Object) { | |
return s; | |
} | |
var className = Object.prototype.toString.call(value); | |
if ("[object Window]" == className) { | |
return "object"; | |
} | |
if ("[object Array]" == className || "number" == typeof value.length && "undefined" != typeof value.splice && "undefined" != typeof value.propertyIsEnumerable && !value.propertyIsEnumerable("splice")) { | |
return "array"; | |
} | |
if ("[object Function]" == className || "undefined" != typeof value.call && "undefined" != typeof value.propertyIsEnumerable && !value.propertyIsEnumerable("call")) { | |
return "function"; | |
} | |
} else { | |
return "null"; | |
} | |
} else { | |
if ("function" == s && "undefined" == typeof value.call) { | |
return "object"; | |
} | |
} | |
return s; | |
}; | |
goog.isNull = function(val) { | |
return null === val; | |
}; | |
goog.isDefAndNotNull = function(val) { | |
return null != val; | |
}; | |
goog.isArray = function(val) { | |
return "array" == goog.typeOf(val); | |
}; | |
goog.isArrayLike = function(val) { | |
var type = goog.typeOf(val); | |
return "array" == type || "object" == type && "number" == typeof val.length; | |
}; | |
goog.isDateLike = function(val) { | |
return goog.isObject(val) && "function" == typeof val.getFullYear; | |
}; | |
goog.isString = function(val) { | |
return "string" == typeof val; | |
}; | |
goog.isBoolean = function(val) { | |
return "boolean" == typeof val; | |
}; | |
goog.isNumber = function(val) { | |
return "number" == typeof val; | |
}; | |
goog.isFunction = function(val) { | |
return "function" == goog.typeOf(val); | |
}; | |
goog.isObject = function(val) { | |
var type = typeof val; | |
return "object" == type && null != val || "function" == type; | |
}; | |
goog.getUid = function(obj) { | |
return obj[goog.UID_PROPERTY_] || (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_); | |
}; | |
goog.hasUid = function(obj) { | |
return!!obj[goog.UID_PROPERTY_]; | |
}; | |
goog.removeUid = function(obj) { | |
"removeAttribute" in obj && obj.removeAttribute(goog.UID_PROPERTY_); | |
try { | |
delete obj[goog.UID_PROPERTY_]; | |
} catch (ex) { | |
} | |
}; | |
goog.UID_PROPERTY_ = "closure_uid_" + (1E9 * Math.random() >>> 0); | |
goog.uidCounter_ = 0; | |
goog.getHashCode = goog.getUid; | |
goog.removeHashCode = goog.removeUid; | |
goog.cloneObject = function(obj) { | |
var type = goog.typeOf(obj); | |
if ("object" == type || "array" == type) { | |
if (obj.clone) { | |
return obj.clone(); | |
} | |
var clone = "array" == type ? [] : {}, key; | |
for (key in obj) { | |
clone[key] = goog.cloneObject(obj[key]); | |
} | |
return clone; | |
} | |
return obj; | |
}; | |
goog.bindNative_ = function(fn, selfObj, var_args) { | |
return fn.call.apply(fn.bind, arguments); | |
}; | |
goog.bindJs_ = function(fn, selfObj, var_args) { | |
if (!fn) { | |
throw Error(); | |
} | |
if (2 < arguments.length) { | |
var boundArgs = Array.prototype.slice.call(arguments, 2); | |
return function() { | |
var newArgs = Array.prototype.slice.call(arguments); | |
Array.prototype.unshift.apply(newArgs, boundArgs); | |
return fn.apply(selfObj, newArgs); | |
}; | |
} | |
return function() { | |
return fn.apply(selfObj, arguments); | |
}; | |
}; | |
goog.bind = function(fn, selfObj, var_args) { | |
Function.prototype.bind && -1 != Function.prototype.bind.toString().indexOf("native code") ? goog.bind = goog.bindNative_ : goog.bind = goog.bindJs_; | |
return goog.bind.apply(null, arguments); | |
}; | |
goog.partial = function(fn, var_args) { | |
var args = Array.prototype.slice.call(arguments, 1); | |
return function() { | |
var newArgs = args.slice(); | |
newArgs.push.apply(newArgs, arguments); | |
return fn.apply(this, newArgs); | |
}; | |
}; | |
goog.mixin = function(target, source) { | |
for (var x in source) { | |
target[x] = source[x]; | |
} | |
}; | |
goog.now = goog.TRUSTED_SITE && Date.now || function() { | |
return+new Date; | |
}; | |
goog.globalEval = function(script) { | |
if (goog.global.execScript) { | |
goog.global.execScript(script, "JavaScript"); | |
} else { | |
if (goog.global.eval) { | |
if (null == goog.evalWorksForGlobals_ && (goog.global.eval("var _et_ = 1;"), "undefined" != typeof goog.global._et_ ? (delete goog.global._et_, goog.evalWorksForGlobals_ = !0) : goog.evalWorksForGlobals_ = !1), goog.evalWorksForGlobals_) { | |
goog.global.eval(script); | |
} else { | |
var doc = goog.global.document, scriptElt = doc.createElement("script"); | |
scriptElt.type = "text/javascript"; | |
scriptElt.defer = !1; | |
scriptElt.appendChild(doc.createTextNode(script)); | |
doc.body.appendChild(scriptElt); | |
doc.body.removeChild(scriptElt); | |
} | |
} else { | |
throw Error("goog.globalEval not available"); | |
} | |
} | |
}; | |
goog.evalWorksForGlobals_ = null; | |
goog.getCssName = function(className, opt_modifier) { | |
var getMapping = function(cssName) { | |
return goog.cssNameMapping_[cssName] || cssName; | |
}, renameByParts = function(cssName) { | |
for (var parts = cssName.split("-"), mapped = [], i = 0;i < parts.length;i++) { | |
mapped.push(getMapping(parts[i])); | |
} | |
return mapped.join("-"); | |
}, rename; | |
rename = goog.cssNameMapping_ ? "BY_WHOLE" == goog.cssNameMappingStyle_ ? getMapping : renameByParts : function(a) { | |
return a; | |
}; | |
return opt_modifier ? className + "-" + rename(opt_modifier) : rename(className); | |
}; | |
goog.setCssNameMapping = function(mapping, opt_style) { | |
goog.cssNameMapping_ = mapping; | |
goog.cssNameMappingStyle_ = opt_style; | |
}; | |
goog.getMsg = function(str, opt_values) { | |
opt_values && (str = str.replace(/\{\$([^}]+)}/g, function(match, key) { | |
return key in opt_values ? opt_values[key] : match; | |
})); | |
return str; | |
}; | |
goog.getMsgWithFallback = function(a) { | |
return a; | |
}; | |
goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) { | |
goog.exportPath_(publicPath, object, opt_objectToExportTo); | |
}; | |
goog.exportProperty = function(object, publicName, symbol) { | |
object[publicName] = symbol; | |
}; | |
goog.inherits = function(childCtor, parentCtor) { | |
function tempCtor() { | |
} | |
tempCtor.prototype = parentCtor.prototype; | |
childCtor.superClass_ = parentCtor.prototype; | |
childCtor.prototype = new tempCtor; | |
childCtor.prototype.constructor = childCtor; | |
childCtor.base = function(me, methodName, var_args) { | |
var args = Array.prototype.slice.call(arguments, 2); | |
return parentCtor.prototype[methodName].apply(me, args); | |
}; | |
}; | |
goog.base = function(me, opt_methodName, var_args) { | |
var caller = arguments.callee.caller; | |
if (goog.STRICT_MODE_COMPATIBLE || goog.DEBUG && !caller) { | |
throw Error("arguments.caller not defined. goog.base() cannot be used with strict mode code. See http://www.ecma-international.org/ecma-262/5.1/#sec-C"); | |
} | |
if (caller.superClass_) { | |
return caller.superClass_.constructor.apply(me, Array.prototype.slice.call(arguments, 1)); | |
} | |
for (var args = Array.prototype.slice.call(arguments, 2), foundCaller = !1, ctor = me.constructor;ctor;ctor = ctor.superClass_ && ctor.superClass_.constructor) { | |
if (ctor.prototype[opt_methodName] === caller) { | |
foundCaller = !0; | |
} else { | |
if (foundCaller) { | |
return ctor.prototype[opt_methodName].apply(me, args); | |
} | |
} | |
} | |
if (me[opt_methodName] === caller) { | |
return me.constructor.prototype[opt_methodName].apply(me, args); | |
} | |
throw Error("goog.base called from a method of one name to a method of a different name"); | |
}; | |
goog.scope = function(fn) { | |
fn.call(goog.global); | |
}; | |
goog.MODIFY_FUNCTION_PROTOTYPES = !0; | |
goog.MODIFY_FUNCTION_PROTOTYPES && (Function.prototype.bind = Function.prototype.bind || function(selfObj, var_args) { | |
if (1 < arguments.length) { | |
var args = Array.prototype.slice.call(arguments, 1); | |
args.unshift(this, selfObj); | |
return goog.bind.apply(null, args); | |
} | |
return goog.bind(this, selfObj); | |
}, Function.prototype.partial = function(var_args) { | |
var args = Array.prototype.slice.call(arguments); | |
args.unshift(this, null); | |
return goog.bind.apply(null, args); | |
}, Function.prototype.inherits = function(parentCtor) { | |
goog.inherits(this, parentCtor); | |
}, Function.prototype.mixin = function(source) { | |
goog.mixin(this.prototype, source); | |
}); | |
goog.defineClass = function(superClass, def) { | |
var constructor = def.constructor, statics = def.statics; | |
if (!constructor || constructor == Object.prototype.constructor) { | |
throw Error("constructor property is required."); | |
} | |
var cls = goog.defineClass.createSealingConstructor_(constructor); | |
superClass && goog.inherits(cls, superClass); | |
delete def.constructor; | |
delete def.statics; | |
goog.defineClass.applyProperties_(cls.prototype, def); | |
null != statics && (statics instanceof Function ? statics(cls) : goog.defineClass.applyProperties_(cls, statics)); | |
return cls; | |
}; | |
goog.defineClass.SEAL_CLASS_INSTANCES = goog.DEBUG; | |
goog.defineClass.createSealingConstructor_ = function(ctr) { | |
if (goog.defineClass.SEAL_CLASS_INSTANCES && Object.seal instanceof Function) { | |
var wrappedCtr = function() { | |
var instance = ctr.apply(this, arguments) || this; | |
this.constructor === wrappedCtr && Object.seal(instance); | |
return instance; | |
}; | |
return wrappedCtr; | |
} | |
return ctr; | |
}; | |
goog.defineClass.OBJECT_PROTOTYPE_FIELDS_ = "constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "); | |
goog.defineClass.applyProperties_ = function(target, source) { | |
for (var key in source) { | |
Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); | |
} | |
for (var i = 0;i < goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length;i++) { | |
key = goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[i], Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); | |
} | |
}; | |
goog.disposable = {}; | |
goog.disposable.IDisposable = function() { | |
}; | |
goog.Disposable = function() { | |
goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF && (goog.Disposable.instances_[goog.getUid(this)] = this); | |
}; | |
goog.Disposable.MonitoringMode = {OFF:0, PERMANENT:1, INTERACTIVE:2}; | |
goog.Disposable.MONITORING_MODE = 0; | |
goog.Disposable.INCLUDE_STACK_ON_CREATION = !0; | |
goog.Disposable.instances_ = {}; | |
goog.Disposable.getUndisposedObjects = function() { | |
var ret = [], id; | |
for (id in goog.Disposable.instances_) { | |
goog.Disposable.instances_.hasOwnProperty(id) && ret.push(goog.Disposable.instances_[Number(id)]); | |
} | |
return ret; | |
}; | |
goog.Disposable.clearUndisposedObjects = function() { | |
goog.Disposable.instances_ = {}; | |
}; | |
goog.Disposable.prototype.disposed_ = !1; | |
goog.Disposable.prototype.isDisposed = function() { | |
return this.disposed_; | |
}; | |
goog.Disposable.prototype.dispose = function() { | |
if (!this.disposed_ && (this.disposed_ = !0, this.disposeInternal(), goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF)) { | |
var uid = goog.getUid(this); | |
if (goog.Disposable.MONITORING_MODE == goog.Disposable.MonitoringMode.PERMANENT && !goog.Disposable.instances_.hasOwnProperty(uid)) { | |
throw Error(this + " did not call the goog.Disposable base constructor or was disposed of after a clearUndisposedObjects call"); | |
} | |
delete goog.Disposable.instances_[uid]; | |
} | |
}; | |
goog.Disposable.prototype.disposeInternal = function() { | |
if (this.onDisposeCallbacks_) { | |
for (;this.onDisposeCallbacks_.length;) { | |
this.onDisposeCallbacks_.shift()(); | |
} | |
} | |
}; | |
goog.Disposable.isDisposed = function(obj) { | |
return obj && "function" == typeof obj.isDisposed ? obj.isDisposed() : !1; | |
}; | |
goog.dispose = function(obj) { | |
obj && "function" == typeof obj.dispose && obj.dispose(); | |
}; | |
goog.disposeAll = function(var_args) { | |
for (var i = 0, len = arguments.length;i < len;++i) { | |
var disposable = arguments[i]; | |
goog.isArrayLike(disposable) ? goog.disposeAll.apply(null, disposable) : goog.dispose(disposable); | |
} | |
}; | |
goog.debug = {}; | |
goog.debug.Error = function(opt_msg) { | |
if (Error.captureStackTrace) { | |
Error.captureStackTrace(this, goog.debug.Error); | |
} else { | |
var stack = Error().stack; | |
stack && (this.stack = stack); | |
} | |
opt_msg && (this.message = String(opt_msg)); | |
}; | |
goog.inherits(goog.debug.Error, Error); | |
goog.debug.Error.prototype.name = "CustomError"; | |
goog.dom = {}; | |
goog.dom.NodeType = {ELEMENT:1, ATTRIBUTE:2, TEXT:3, CDATA_SECTION:4, ENTITY_REFERENCE:5, ENTITY:6, PROCESSING_INSTRUCTION:7, COMMENT:8, DOCUMENT:9, DOCUMENT_TYPE:10, DOCUMENT_FRAGMENT:11, NOTATION:12}; | |
goog.string = {}; | |
goog.string.DETECT_DOUBLE_ESCAPING = !1; | |
goog.string.Unicode = {NBSP:"\u00a0"}; | |
goog.string.startsWith = function(str) { | |
return 0 == str.lastIndexOf("/", 0); | |
}; | |
goog.string.endsWith = function(str) { | |
var l = str.length - 1; | |
return 0 <= l && str.indexOf("/", l) == l; | |
}; | |
goog.string.caseInsensitiveStartsWith = function(str, prefix) { | |
return 0 == goog.string.caseInsensitiveCompare(prefix, str.substr(0, prefix.length)); | |
}; | |
goog.string.caseInsensitiveEndsWith = function(str, suffix) { | |
return 0 == goog.string.caseInsensitiveCompare(suffix, str.substr(str.length - suffix.length, suffix.length)); | |
}; | |
goog.string.caseInsensitiveEquals = function(str2) { | |
return goog.net.XhrIo.CONTENT_TYPE_HEADER.toLowerCase() == str2.toLowerCase(); | |
}; | |
goog.string.subs = function(str, var_args) { | |
for (var splitParts = str.split("%s"), returnString = "", subsArguments = Array.prototype.slice.call(arguments, 1);subsArguments.length && 1 < splitParts.length;) { | |
returnString += splitParts.shift() + subsArguments.shift(); | |
} | |
return returnString + splitParts.join("%s"); | |
}; | |
goog.string.collapseWhitespace = function(str) { | |
return str.replace(/[\s\xa0]+/g, " ").replace(/^\s+|\s+$/g, ""); | |
}; | |
goog.string.isEmpty = function(str) { | |
return/^[\s\xa0]*$/.test(str); | |
}; | |
goog.string.isEmptySafe = function(str) { | |
return goog.string.isEmpty(goog.string.makeSafe(str)); | |
}; | |
goog.string.isBreakingWhitespace = function(str) { | |
return!/[^\t\n\r ]/.test(str); | |
}; | |
goog.string.isAlpha = function(str) { | |
return!/[^a-zA-Z]/.test(str); | |
}; | |
goog.string.isNumeric = function(str) { | |
return!/[^0-9]/.test(str); | |
}; | |
goog.string.isAlphaNumeric = function(str) { | |
return!/[^a-zA-Z0-9]/.test(str); | |
}; | |
goog.string.isSpace = function(ch) { | |
return " " == ch; | |
}; | |
goog.string.isUnicodeChar = function(ch) { | |
return 1 == ch.length && " " <= ch && "~" >= ch || "\u0080" <= ch && "\ufffd" >= ch; | |
}; | |
goog.string.stripNewlines = function(str) { | |
return str.replace(/(\r\n|\r|\n)+/g, " "); | |
}; | |
goog.string.canonicalizeNewlines = function(str) { | |
return str.replace(/(\r\n|\r|\n)/g, "\n"); | |
}; | |
goog.string.normalizeWhitespace = function(str) { | |
return str.replace(/\xa0|\s/g, " "); | |
}; | |
goog.string.normalizeSpaces = function(str) { | |
return str.replace(/\xa0|[ \t]+/g, " "); | |
}; | |
goog.string.collapseBreakingSpaces = function(str) { | |
return str.replace(/[\t\r\n ]+/g, " ").replace(/^[\t\r\n ]+|[\t\r\n ]+$/g, ""); | |
}; | |
goog.string.trim = function(str) { | |
return str.replace(/^[\s\xa0]+|[\s\xa0]+$/g, ""); | |
}; | |
goog.string.trimLeft = function(str) { | |
return str.replace(/^[\s\xa0]+/, ""); | |
}; | |
goog.string.trimRight = function(str) { | |
return str.replace(/[\s\xa0]+$/, ""); | |
}; | |
goog.string.caseInsensitiveCompare = function(str1, str2) { | |
var test1 = String(str1).toLowerCase(), test2 = String(str2).toLowerCase(); | |
return test1 < test2 ? -1 : test1 == test2 ? 0 : 1; | |
}; | |
goog.string.numerateCompareRegExp_ = /(\.\d+)|(\d+)|(\D+)/g; | |
goog.string.numerateCompare = function(str1, str2) { | |
if (str1 == str2) { | |
return 0; | |
} | |
if (!str1) { | |
return-1; | |
} | |
if (!str2) { | |
return 1; | |
} | |
for (var tokens1 = str1.toLowerCase().match(goog.string.numerateCompareRegExp_), tokens2 = str2.toLowerCase().match(goog.string.numerateCompareRegExp_), count = Math.min(tokens1.length, tokens2.length), i = 0;i < count;i++) { | |
var a = tokens1[i], b = tokens2[i]; | |
if (a != b) { | |
var num1 = parseInt(a, 10); | |
if (!isNaN(num1)) { | |
var num2 = parseInt(b, 10); | |
if (!isNaN(num2) && num1 - num2) { | |
return num1 - num2; | |
} | |
} | |
return a < b ? -1 : 1; | |
} | |
} | |
return tokens1.length != tokens2.length ? tokens1.length - tokens2.length : str1 < str2 ? -1 : 1; | |
}; | |
goog.string.urlEncode = function(str) { | |
return encodeURIComponent(String(str)); | |
}; | |
goog.string.urlDecode = function(str) { | |
return decodeURIComponent(str.replace(/\+/g, " ")); | |
}; | |
goog.string.newLineToBr = function(str, opt_xml) { | |
return str.replace(/(\r\n|\r|\n)/g, opt_xml ? "<br />" : "<br>"); | |
}; | |
goog.string.htmlEscape = function(str) { | |
if (!goog.string.ALL_RE_.test(str)) { | |
return str; | |
} | |
-1 != str.indexOf("&") && (str = str.replace(goog.string.AMP_RE_, "&")); | |
-1 != str.indexOf("<") && (str = str.replace(goog.string.LT_RE_, "<")); | |
-1 != str.indexOf(">") && (str = str.replace(goog.string.GT_RE_, ">")); | |
-1 != str.indexOf('"') && (str = str.replace(goog.string.QUOT_RE_, """)); | |
-1 != str.indexOf("'") && (str = str.replace(goog.string.SINGLE_QUOTE_RE_, "'")); | |
-1 != str.indexOf("\x00") && (str = str.replace(goog.string.NULL_RE_, "�")); | |
goog.string.DETECT_DOUBLE_ESCAPING && -1 != str.indexOf("e") && (str = str.replace(goog.string.E_RE_, "e")); | |
return str; | |
}; | |
goog.string.AMP_RE_ = /&/g; | |
goog.string.LT_RE_ = /</g; | |
goog.string.GT_RE_ = />/g; | |
goog.string.QUOT_RE_ = /"/g; | |
goog.string.SINGLE_QUOTE_RE_ = /'/g; | |
goog.string.NULL_RE_ = /\x00/g; | |
goog.string.E_RE_ = /e/g; | |
goog.string.ALL_RE_ = goog.string.DETECT_DOUBLE_ESCAPING ? /[\x00&<>"'e]/ : /[\x00&<>"']/; | |
goog.string.unescapeEntities = function(str) { | |
return goog.string.contains(str, "&") ? "document" in goog.global ? goog.string.unescapeEntitiesUsingDom_(str) : goog.string.unescapePureXmlEntities_(str) : str; | |
}; | |
goog.string.unescapeEntitiesWithDocument = function(str, document) { | |
return goog.string.contains(str, "&") ? goog.string.unescapeEntitiesUsingDom_(str, document) : str; | |
}; | |
goog.string.unescapeEntitiesUsingDom_ = function(str, opt_document) { | |
var seen = {"&":"&", "<":"<", ">":">", """:'"'}, div; | |
div = opt_document ? opt_document.createElement("div") : goog.global.document.createElement("div"); | |
return str.replace(goog.string.HTML_ENTITY_PATTERN_, function(s, entity) { | |
var value = seen[s]; | |
if (value) { | |
return value; | |
} | |
if ("#" == entity.charAt(0)) { | |
var n = Number("0" + entity.substr(1)); | |
isNaN(n) || (value = String.fromCharCode(n)); | |
} | |
value || (div.innerHTML = s + " ", value = div.firstChild.nodeValue.slice(0, -1)); | |
return seen[s] = value; | |
}); | |
}; | |
goog.string.unescapePureXmlEntities_ = function(str) { | |
return str.replace(/&([^;]+);/g, function(s, entity) { | |
switch(entity) { | |
case "amp": | |
return "&"; | |
case "lt": | |
return "<"; | |
case "gt": | |
return ">"; | |
case "quot": | |
return'"'; | |
default: | |
if ("#" == entity.charAt(0)) { | |
var n = Number("0" + entity.substr(1)); | |
if (!isNaN(n)) { | |
return String.fromCharCode(n); | |
} | |
} | |
return s; | |
} | |
}); | |
}; | |
goog.string.HTML_ENTITY_PATTERN_ = /&([^;\s<&]+);?/g; | |
goog.string.whitespaceEscape = function(str, opt_xml) { | |
return goog.string.newLineToBr(str.replace(/ /g, "  "), opt_xml); | |
}; | |
goog.string.preserveSpaces = function(str) { | |
return str.replace(/(^|[\n ]) /g, "$1" + goog.string.Unicode.NBSP); | |
}; | |
goog.string.stripQuotes = function(str, quoteChars) { | |
for (var length = quoteChars.length, i = 0;i < length;i++) { | |
var quoteChar = 1 == length ? quoteChars : quoteChars.charAt(i); | |
if (str.charAt(0) == quoteChar && str.charAt(str.length - 1) == quoteChar) { | |
return str.substring(1, str.length - 1); | |
} | |
} | |
return str; | |
}; | |
goog.string.truncate = function(str, chars, opt_protectEscapedCharacters) { | |
opt_protectEscapedCharacters && (str = goog.string.unescapeEntities(str)); | |
str.length > chars && (str = str.substring(0, chars - 3) + "..."); | |
opt_protectEscapedCharacters && (str = goog.string.htmlEscape(str)); | |
return str; | |
}; | |
goog.string.truncateMiddle = function(str, chars, opt_protectEscapedCharacters, opt_trailingChars) { | |
opt_protectEscapedCharacters && (str = goog.string.unescapeEntities(str)); | |
if (opt_trailingChars && str.length > chars) { | |
opt_trailingChars > chars && (opt_trailingChars = chars), str = str.substring(0, chars - opt_trailingChars) + "..." + str.substring(str.length - opt_trailingChars); | |
} else { | |
if (str.length > chars) { | |
var half = Math.floor(chars / 2), endPos = str.length - half; | |
str = str.substring(0, half + chars % 2) + "..." + str.substring(endPos); | |
} | |
} | |
opt_protectEscapedCharacters && (str = goog.string.htmlEscape(str)); | |
return str; | |
}; | |
goog.string.specialEscapeChars_ = {"\x00":"\\0", "\b":"\\b", "\f":"\\f", "\n":"\\n", "\r":"\\r", "\t":"\\t", "\x0B":"\\x0B", '"':'\\"', "\\":"\\\\"}; | |
goog.string.jsEscapeCache_ = {"'":"\\'"}; | |
goog.string.quote = function(s) { | |
s = String(s); | |
if (s.quote) { | |
return s.quote(); | |
} | |
for (var sb = ['"'], i = 0;i < s.length;i++) { | |
var ch = s.charAt(i), cc = ch.charCodeAt(0); | |
sb[i + 1] = goog.string.specialEscapeChars_[ch] || (31 < cc && 127 > cc ? ch : goog.string.escapeChar(ch)); | |
} | |
sb.push('"'); | |
return sb.join(""); | |
}; | |
goog.string.escapeString = function(str) { | |
for (var sb = [], i = 0;i < str.length;i++) { | |
sb[i] = goog.string.escapeChar(str.charAt(i)); | |
} | |
return sb.join(""); | |
}; | |
goog.string.escapeChar = function(c) { | |
if (c in goog.string.jsEscapeCache_) { | |
return goog.string.jsEscapeCache_[c]; | |
} | |
if (c in goog.string.specialEscapeChars_) { | |
return goog.string.jsEscapeCache_[c] = goog.string.specialEscapeChars_[c]; | |
} | |
var rv = c, cc = c.charCodeAt(0); | |
if (31 < cc && 127 > cc) { | |
rv = c; | |
} else { | |
if (256 > cc) { | |
if (rv = "\\x", 16 > cc || 256 < cc) { | |
rv += "0"; | |
} | |
} else { | |
rv = "\\u", 4096 > cc && (rv += "0"); | |
} | |
rv += cc.toString(16).toUpperCase(); | |
} | |
return goog.string.jsEscapeCache_[c] = rv; | |
}; | |
goog.string.toMap = function(s) { | |
for (var rv = {}, i = 0;i < s.length;i++) { | |
rv[s.charAt(i)] = !0; | |
} | |
return rv; | |
}; | |
goog.string.contains = function(str, subString) { | |
return-1 != str.indexOf(subString); | |
}; | |
goog.string.caseInsensitiveContains = function() { | |
return goog.string.contains(goog.labs.userAgent.util.getUserAgent().toLowerCase(), "webkit"); | |
}; | |
goog.string.countOf = function(s, ss) { | |
return s && ss ? s.split(ss).length - 1 : 0; | |
}; | |
goog.string.removeAt = function(s, index, stringLength) { | |
var resultStr = s; | |
0 <= index && index < s.length && 0 < stringLength && (resultStr = s.substr(0, index) + s.substr(index + stringLength, s.length - index - stringLength)); | |
return resultStr; | |
}; | |
goog.string.remove = function(s, ss) { | |
var re = new RegExp(goog.string.regExpEscape(ss), ""); | |
return s.replace(re, ""); | |
}; | |
goog.string.removeAll = function(s, ss) { | |
var re = new RegExp(goog.string.regExpEscape(ss), "g"); | |
return s.replace(re, ""); | |
}; | |
goog.string.regExpEscape = function(s) { | |
return String(s).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, "\\$1").replace(/\x08/g, "\\x08"); | |
}; | |
goog.string.repeat = function(string, length) { | |
return Array(length + 1).join(string); | |
}; | |
goog.string.padNumber = function(num, length, opt_precision) { | |
var s = goog.isDef(opt_precision) ? num.toFixed(opt_precision) : String(num), index = s.indexOf("."); | |
-1 == index && (index = s.length); | |
return goog.string.repeat("0", Math.max(0, length - index)) + s; | |
}; | |
goog.string.makeSafe = function(obj) { | |
return null == obj ? "" : String(obj); | |
}; | |
goog.string.buildString = function(var_args) { | |
return Array.prototype.join.call(arguments, ""); | |
}; | |
goog.string.getRandomString = function() { | |
return Math.floor(2147483648 * Math.random()).toString(36) + Math.abs(Math.floor(2147483648 * Math.random()) ^ goog.now()).toString(36); | |
}; | |
goog.string.compareVersions = function(version1, version2) { | |
for (var order = 0, v1Subs = goog.string.trim(String(version1)).split("."), v2Subs = goog.string.trim(String(version2)).split("."), subCount = Math.max(v1Subs.length, v2Subs.length), subIdx = 0;0 == order && subIdx < subCount;subIdx++) { | |
var v1Sub = v1Subs[subIdx] || "", v2Sub = v2Subs[subIdx] || "", v1CompParser = /(\d*)(\D*)/g, v2CompParser = /(\d*)(\D*)/g; | |
do { | |
var v1Comp = v1CompParser.exec(v1Sub) || ["", "", ""], v2Comp = v2CompParser.exec(v2Sub) || ["", "", ""]; | |
if (0 == v1Comp[0].length && 0 == v2Comp[0].length) { | |
break; | |
} | |
order = goog.string.compareElements_(0 == v1Comp[1].length ? 0 : parseInt(v1Comp[1], 10), 0 == v2Comp[1].length ? 0 : parseInt(v2Comp[1], 10)) || goog.string.compareElements_(0 == v1Comp[2].length, 0 == v2Comp[2].length) || goog.string.compareElements_(v1Comp[2], v2Comp[2]); | |
} while (0 == order); | |
} | |
return order; | |
}; | |
goog.string.compareElements_ = function(left, right) { | |
return left < right ? -1 : left > right ? 1 : 0; | |
}; | |
goog.string.HASHCODE_MAX_ = 4294967296; | |
goog.string.hashCode = function(str) { | |
for (var result = 0, i = 0;i < str.length;++i) { | |
result = 31 * result + str.charCodeAt(i), result %= goog.string.HASHCODE_MAX_; | |
} | |
return result; | |
}; | |
goog.string.uniqueStringCounter_ = 2147483648 * Math.random() | 0; | |
goog.string.createUniqueString = function() { | |
return "goog_" + goog.string.uniqueStringCounter_++; | |
}; | |
goog.string.toNumber = function(str) { | |
var num = Number(str); | |
return 0 == num && goog.string.isEmpty(str) ? NaN : num; | |
}; | |
goog.string.isLowerCamelCase = function(str) { | |
return/^[a-z]+([A-Z][a-z]*)*$/.test(str); | |
}; | |
goog.string.isUpperCamelCase = function(str) { | |
return/^([A-Z][a-z]*)+$/.test(str); | |
}; | |
goog.string.toCamelCase = function(str) { | |
return String(str).replace(/\-([a-z])/g, function(all, match) { | |
return match.toUpperCase(); | |
}); | |
}; | |
goog.string.toSelectorCase = function(str) { | |
return String(str).replace(/([A-Z])/g, "-$1").toLowerCase(); | |
}; | |
goog.string.toTitleCase = function(str, opt_delimiters) { | |
var delimiters = goog.isString(opt_delimiters) ? goog.string.regExpEscape(opt_delimiters) : "\\s"; | |
return str.replace(new RegExp("(^" + (delimiters ? "|[" + delimiters + "]+" : "") + ")([a-z])", "g"), function(all, p1, p2) { | |
return p1 + p2.toUpperCase(); | |
}); | |
}; | |
goog.string.parseInt = function(value) { | |
isFinite(value) && (value = String(value)); | |
return goog.isString(value) ? /^\s*-?0x/i.test(value) ? parseInt(value, 16) : parseInt(value, 10) : NaN; | |
}; | |
goog.string.splitLimit = function(str, separator, limit) { | |
for (var parts = str.split(separator), returnVal = [];0 < limit && parts.length;) { | |
returnVal.push(parts.shift()), limit--; | |
} | |
parts.length && returnVal.push(parts.join(separator)); | |
return returnVal; | |
}; | |
goog.asserts = {}; | |
goog.asserts.ENABLE_ASSERTS = goog.DEBUG; | |
goog.asserts.AssertionError = function(messagePattern, messageArgs) { | |
messageArgs.unshift(messagePattern); | |
goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs)); | |
messageArgs.shift(); | |
}; | |
goog.inherits(goog.asserts.AssertionError, goog.debug.Error); | |
goog.asserts.AssertionError.prototype.name = "AssertionError"; | |
goog.asserts.DEFAULT_ERROR_HANDLER = function(e) { | |
throw e; | |
}; | |
goog.asserts.errorHandler_ = goog.asserts.DEFAULT_ERROR_HANDLER; | |
goog.asserts.doAssertFailure_ = function(defaultMessage, defaultArgs, givenMessage, givenArgs) { | |
var message = "Assertion failed"; | |
if (givenMessage) { | |
var message = message + (": " + givenMessage), args = givenArgs | |
} else { | |
defaultMessage && (message += ": " + defaultMessage, args = defaultArgs); | |
} | |
var e = new goog.asserts.AssertionError("" + message, args || []); | |
goog.asserts.errorHandler_(e); | |
}; | |
goog.asserts.setErrorHandler = function(errorHandler) { | |
goog.asserts.ENABLE_ASSERTS && (goog.asserts.errorHandler_ = errorHandler); | |
}; | |
goog.asserts.assert = function(condition, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !condition && goog.asserts.doAssertFailure_("", null, opt_message, Array.prototype.slice.call(arguments, 2)); | |
return condition; | |
}; | |
goog.asserts.fail = function(opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && goog.asserts.errorHandler_(new goog.asserts.AssertionError("Failure" + (opt_message ? ": " + opt_message : ""), Array.prototype.slice.call(arguments, 1))); | |
}; | |
goog.asserts.assertNumber = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value) && goog.asserts.doAssertFailure_("Expected number but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
}; | |
goog.asserts.assertString = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isString(value) && goog.asserts.doAssertFailure_("Expected string but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
return value; | |
}; | |
goog.asserts.assertFunction = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value) && goog.asserts.doAssertFailure_("Expected function but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
return value; | |
}; | |
goog.asserts.assertObject = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isObject(value) && goog.asserts.doAssertFailure_("Expected object but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
return value; | |
}; | |
goog.asserts.assertArray = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isArray(value) && goog.asserts.doAssertFailure_("Expected array but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
}; | |
goog.asserts.assertBoolean = function(value, opt_message, var_args) { | |
goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value) && goog.asserts.doAssertFailure_("Expected boolean but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
return value; | |
}; | |
goog.asserts.assertElement = function(value, opt_message, var_args) { | |
!goog.asserts.ENABLE_ASSERTS || goog.isObject(value) && value.nodeType == goog.dom.NodeType.ELEMENT || goog.asserts.doAssertFailure_("Expected Element but got %s: %s.", [goog.typeOf(value), value], opt_message, Array.prototype.slice.call(arguments, 2)); | |
return value; | |
}; | |
goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) { | |
!goog.asserts.ENABLE_ASSERTS || value instanceof type || goog.asserts.doAssertFailure_("instanceof check failed.", null, opt_message, Array.prototype.slice.call(arguments, 3)); | |
return value; | |
}; | |
goog.asserts.assertObjectPrototypeIsIntact = function() { | |
for (var key in Object.prototype) { | |
goog.asserts.fail(key + " should not be enumerable in Object.prototype."); | |
} | |
}; | |
goog.object = {}; | |
goog.object.forEach = function(obj, f, opt_obj) { | |
for (var key in obj) { | |
f.call(opt_obj, obj[key], key, obj); | |
} | |
}; | |
goog.object.filter = function(obj, f, opt_obj) { | |
var res = {}, key; | |
for (key in obj) { | |
f.call(opt_obj, obj[key], key, obj) && (res[key] = obj[key]); | |
} | |
return res; | |
}; | |
goog.object.map = function(obj, f, opt_obj) { | |
var res = {}, key; | |
for (key in obj) { | |
res[key] = f.call(opt_obj, obj[key], key, obj); | |
} | |
return res; | |
}; | |
goog.object.some = function(obj, f, opt_obj) { | |
for (var key in obj) { | |
if (f.call(opt_obj, obj[key], key, obj)) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
goog.object.every = function(obj, f, opt_obj) { | |
for (var key in obj) { | |
if (!f.call(opt_obj, obj[key], key, obj)) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.object.getCount = function(obj) { | |
var rv = 0, key; | |
for (key in obj) { | |
rv++; | |
} | |
return rv; | |
}; | |
goog.object.getAnyKey = function(obj) { | |
for (var key in obj) { | |
return key; | |
} | |
}; | |
goog.object.getAnyValue = function(obj) { | |
for (var key in obj) { | |
return obj[key]; | |
} | |
}; | |
goog.object.contains = function(obj, val) { | |
return goog.object.containsValue(obj, val); | |
}; | |
goog.object.getValues = function(obj) { | |
var res = [], i = 0, key; | |
for (key in obj) { | |
res[i++] = obj[key]; | |
} | |
return res; | |
}; | |
goog.object.getKeys = function(obj) { | |
var res = [], i = 0, key; | |
for (key in obj) { | |
res[i++] = key; | |
} | |
return res; | |
}; | |
goog.object.getValueByKeys = function(obj, var_args) { | |
for (var isArrayLike = goog.isArrayLike(var_args), keys = isArrayLike ? var_args : arguments, i = isArrayLike ? 0 : 1;i < keys.length && (obj = obj[keys[i]], goog.isDef(obj));i++) { | |
} | |
return obj; | |
}; | |
goog.object.containsKey = function(obj, key) { | |
return key in obj; | |
}; | |
goog.object.containsValue = function(obj, val) { | |
for (var key in obj) { | |
if (obj[key] == val) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
goog.object.findKey = function(obj, f, opt_this) { | |
for (var key in obj) { | |
if (f.call(opt_this, obj[key], key, obj)) { | |
return key; | |
} | |
} | |
}; | |
goog.object.findValue = function(obj, f, opt_this) { | |
var key = goog.object.findKey(obj, f, opt_this); | |
return key && obj[key]; | |
}; | |
goog.object.isEmpty = function(obj) { | |
for (var key in obj) { | |
return!1; | |
} | |
return!0; | |
}; | |
goog.object.clear = function(obj) { | |
for (var i in obj) { | |
delete obj[i]; | |
} | |
}; | |
goog.object.remove = function(obj, key) { | |
var rv; | |
(rv = key in obj) && delete obj[key]; | |
return rv; | |
}; | |
goog.object.add = function(obj, key, val) { | |
if (key in obj) { | |
throw Error('The object already contains the key "' + key + '"'); | |
} | |
goog.object.set(obj, key, val); | |
}; | |
goog.object.get = function(obj, key, opt_val) { | |
return key in obj ? obj[key] : opt_val; | |
}; | |
goog.object.set = function(obj, key, value) { | |
obj[key] = value; | |
}; | |
goog.object.setIfUndefined = function(obj, key, value) { | |
return key in obj ? obj[key] : obj[key] = value; | |
}; | |
goog.object.clone = function(obj) { | |
var res = {}, key; | |
for (key in obj) { | |
res[key] = obj[key]; | |
} | |
return res; | |
}; | |
goog.object.unsafeClone = function(obj) { | |
var type = goog.typeOf(obj); | |
if ("object" == type || "array" == type) { | |
if (obj.clone) { | |
return obj.clone(); | |
} | |
var clone = "array" == type ? [] : {}, key; | |
for (key in obj) { | |
clone[key] = goog.object.unsafeClone(obj[key]); | |
} | |
return clone; | |
} | |
return obj; | |
}; | |
goog.object.transpose = function(obj) { | |
var transposed = {}, key; | |
for (key in obj) { | |
transposed[obj[key]] = key; | |
} | |
return transposed; | |
}; | |
goog.object.PROTOTYPE_FIELDS_ = "constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "); | |
goog.object.extend = function(target, var_args) { | |
for (var key, source, i = 1;i < arguments.length;i++) { | |
source = arguments[i]; | |
for (key in source) { | |
target[key] = source[key]; | |
} | |
for (var j = 0;j < goog.object.PROTOTYPE_FIELDS_.length;j++) { | |
key = goog.object.PROTOTYPE_FIELDS_[j], Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); | |
} | |
} | |
}; | |
goog.object.create = function(var_args) { | |
var argLength = arguments.length; | |
if (1 == argLength && goog.isArray(arguments[0])) { | |
return goog.object.create.apply(null, arguments[0]); | |
} | |
if (argLength % 2) { | |
throw Error("Uneven number of arguments"); | |
} | |
for (var rv = {}, i = 0;i < argLength;i += 2) { | |
rv[arguments[i]] = arguments[i + 1]; | |
} | |
return rv; | |
}; | |
goog.object.createSet = function(var_args) { | |
var argLength = arguments.length; | |
if (1 == argLength && goog.isArray(arguments[0])) { | |
return goog.object.createSet.apply(null, arguments[0]); | |
} | |
for (var rv = {}, i = 0;i < argLength;i++) { | |
rv[arguments[i]] = !0; | |
} | |
return rv; | |
}; | |
goog.object.createImmutableView = function(obj) { | |
var result = obj; | |
Object.isFrozen && !Object.isFrozen(obj) && (result = Object.create(obj), Object.freeze(result)); | |
return result; | |
}; | |
goog.object.isImmutableView = function(obj) { | |
return!!Object.isFrozen && Object.isFrozen(obj); | |
}; | |
goog.events = {}; | |
goog.events.EventId = function(eventId) { | |
this.id = eventId; | |
}; | |
goog.events.EventId.prototype.toString = function() { | |
return this.id; | |
}; | |
goog.events.Event = function(type, opt_target) { | |
this.type = type instanceof goog.events.EventId ? String(type) : type; | |
this.currentTarget = this.target = opt_target; | |
this.defaultPrevented = this.propagationStopped_ = !1; | |
this.returnValue_ = !0; | |
}; | |
goog.events.Event.prototype.disposeInternal = function() { | |
}; | |
goog.events.Event.prototype.dispose = function() { | |
}; | |
goog.events.Event.prototype.stopPropagation = function() { | |
this.propagationStopped_ = !0; | |
}; | |
goog.events.Event.prototype.preventDefault = function() { | |
this.defaultPrevented = !0; | |
this.returnValue_ = !1; | |
}; | |
goog.events.Event.stopPropagation = function(e) { | |
e.stopPropagation(); | |
}; | |
goog.events.Event.preventDefault = function(e) { | |
e.preventDefault(); | |
}; | |
goog.debug.entryPointRegistry = {}; | |
goog.debug.EntryPointMonitor = function() { | |
}; | |
goog.debug.entryPointRegistry.refList_ = []; | |
goog.debug.entryPointRegistry.monitors_ = []; | |
goog.debug.entryPointRegistry.monitorsMayExist_ = !1; | |
goog.debug.entryPointRegistry.register = function(callback) { | |
goog.debug.entryPointRegistry.refList_[goog.debug.entryPointRegistry.refList_.length] = callback; | |
if (goog.debug.entryPointRegistry.monitorsMayExist_) { | |
for (var monitors = goog.debug.entryPointRegistry.monitors_, i = 0;i < monitors.length;i++) { | |
callback(goog.bind(monitors[i].wrap, monitors[i])); | |
} | |
} | |
}; | |
goog.debug.entryPointRegistry.monitorAll = function(monitor) { | |
goog.debug.entryPointRegistry.monitorsMayExist_ = !0; | |
for (var transformer = goog.bind(monitor.wrap, monitor), i = 0;i < goog.debug.entryPointRegistry.refList_.length;i++) { | |
goog.debug.entryPointRegistry.refList_[i](transformer); | |
} | |
goog.debug.entryPointRegistry.monitors_.push(monitor); | |
}; | |
goog.debug.entryPointRegistry.unmonitorAllIfPossible = function(monitor) { | |
var monitors = goog.debug.entryPointRegistry.monitors_; | |
goog.asserts.assert(monitor == monitors[monitors.length - 1], "Only the most recent monitor can be unwrapped."); | |
for (var transformer = goog.bind(monitor.unwrap, monitor), i = 0;i < goog.debug.entryPointRegistry.refList_.length;i++) { | |
goog.debug.entryPointRegistry.refList_[i](transformer); | |
} | |
monitors.length--; | |
}; | |
goog.reflect = {}; | |
goog.reflect.object = function(type, object) { | |
return object; | |
}; | |
goog.reflect.sinkValue = function(x) { | |
goog.reflect.sinkValue[" "](x); | |
return x; | |
}; | |
goog.reflect.sinkValue[" "] = goog.nullFunction; | |
goog.reflect.canAccessProperty = function(obj) { | |
try { | |
return goog.reflect.sinkValue(obj.nodeName), !0; | |
} catch (e) { | |
} | |
return!1; | |
}; | |
goog.array = {}; | |
goog.NATIVE_ARRAY_PROTOTYPES = goog.TRUSTED_SITE; | |
goog.array.ASSUME_NATIVE_FUNCTIONS = !1; | |
goog.array.peek = function(array) { | |
return array[array.length - 1]; | |
}; | |
goog.array.last = goog.array.peek; | |
goog.array.ARRAY_PROTOTYPE_ = Array.prototype; | |
goog.array.indexOf = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.indexOf) ? function(arr, obj, opt_fromIndex) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.indexOf.call(arr, obj, opt_fromIndex); | |
} : function(arr, obj, opt_fromIndex) { | |
var fromIndex = null == opt_fromIndex ? 0 : 0 > opt_fromIndex ? Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex; | |
if (goog.isString(arr)) { | |
return goog.isString(obj) && 1 == obj.length ? arr.indexOf(obj, fromIndex) : -1; | |
} | |
for (var i = fromIndex;i < arr.length;i++) { | |
if (i in arr && arr[i] === obj) { | |
return i; | |
} | |
} | |
return-1; | |
}; | |
goog.array.lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.lastIndexOf) ? function(arr, obj, opt_fromIndex) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.lastIndexOf.call(arr, obj, null == opt_fromIndex ? arr.length - 1 : opt_fromIndex); | |
} : function(arr, obj, opt_fromIndex) { | |
var fromIndex = null == opt_fromIndex ? arr.length - 1 : opt_fromIndex; | |
0 > fromIndex && (fromIndex = Math.max(0, arr.length + fromIndex)); | |
if (goog.isString(arr)) { | |
return goog.isString(obj) && 1 == obj.length ? arr.lastIndexOf(obj, fromIndex) : -1; | |
} | |
for (var i = fromIndex;0 <= i;i--) { | |
if (i in arr && arr[i] === obj) { | |
return i; | |
} | |
} | |
return-1; | |
}; | |
goog.array.forEach = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.forEach) ? function(arr, f, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
goog.array.ARRAY_PROTOTYPE_.forEach.call(arr, f, opt_obj); | |
} : function(arr, f, opt_obj) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
i in arr2 && f.call(opt_obj, arr2[i], i, arr); | |
} | |
}; | |
goog.array.forEachRight = function(arr, f) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = l - 1;0 <= i;--i) { | |
i in arr2 && f.call(void 0, arr2[i], i, arr); | |
} | |
}; | |
goog.array.filter = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.filter) ? function(arr, f, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.filter.call(arr, f, opt_obj); | |
} : function(arr, f, opt_obj) { | |
for (var l = arr.length, res = [], resLength = 0, arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
if (i in arr2) { | |
var val = arr2[i]; | |
f.call(opt_obj, val, i, arr) && (res[resLength++] = val); | |
} | |
} | |
return res; | |
}; | |
goog.array.map = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.map) ? function(arr, f, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.map.call(arr, f, opt_obj); | |
} : function(arr, f, opt_obj) { | |
for (var l = arr.length, res = Array(l), arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
i in arr2 && (res[i] = f.call(opt_obj, arr2[i], i, arr)); | |
} | |
return res; | |
}; | |
goog.array.reduce = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.reduce) ? function(arr, f, val, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
opt_obj && (f = goog.bind(f, opt_obj)); | |
return goog.array.ARRAY_PROTOTYPE_.reduce.call(arr, f, val); | |
} : function(arr, f, val$$0, opt_obj) { | |
var rval = val$$0; | |
goog.array.forEach(arr, function(val, index) { | |
rval = f.call(opt_obj, rval, val, index, arr); | |
}); | |
return rval; | |
}; | |
goog.array.reduceRight = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.reduceRight) ? function(arr, f, val, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
opt_obj && (f = goog.bind(f, opt_obj)); | |
return goog.array.ARRAY_PROTOTYPE_.reduceRight.call(arr, f, val); | |
} : function(arr, f, val$$0, opt_obj) { | |
var rval = val$$0; | |
goog.array.forEachRight(arr, function(val, index) { | |
rval = f.call(opt_obj, rval, val, index, arr); | |
}); | |
return rval; | |
}; | |
goog.array.some = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.some) ? function(arr, f, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.some.call(arr, f, opt_obj); | |
} : function(arr, f, opt_obj) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
goog.array.every = goog.NATIVE_ARRAY_PROTOTYPES && (goog.array.ASSUME_NATIVE_FUNCTIONS || goog.array.ARRAY_PROTOTYPE_.every) ? function(arr, f, opt_obj) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.every.call(arr, f, opt_obj); | |
} : function(arr, f, opt_obj) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.array.count = function(arr$$0, f, opt_obj) { | |
var count = 0; | |
goog.array.forEach(arr$$0, function(element, index, arr) { | |
f.call(opt_obj, element, index, arr) && ++count; | |
}, opt_obj); | |
return count; | |
}; | |
goog.array.find = function(arr, f, opt_obj) { | |
var i = goog.array.findIndex(arr, f, opt_obj); | |
return 0 > i ? null : goog.isString(arr) ? arr.charAt(i) : arr[i]; | |
}; | |
goog.array.findIndex = function(arr, f, opt_obj) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = 0;i < l;i++) { | |
if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { | |
return i; | |
} | |
} | |
return-1; | |
}; | |
goog.array.findRight = function(arr, f, opt_obj) { | |
var i = goog.array.findIndexRight(arr, f, opt_obj); | |
return 0 > i ? null : goog.isString(arr) ? arr.charAt(i) : arr[i]; | |
}; | |
goog.array.findIndexRight = function(arr, f, opt_obj) { | |
for (var l = arr.length, arr2 = goog.isString(arr) ? arr.split("") : arr, i = l - 1;0 <= i;i--) { | |
if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) { | |
return i; | |
} | |
} | |
return-1; | |
}; | |
goog.array.contains = function(arr, obj) { | |
return 0 <= goog.array.indexOf(arr, obj); | |
}; | |
goog.array.isEmpty = function(arr) { | |
return 0 == arr.length; | |
}; | |
goog.array.clear = function(arr) { | |
if (!goog.isArray(arr)) { | |
for (var i = arr.length - 1;0 <= i;i--) { | |
delete arr[i]; | |
} | |
} | |
arr.length = 0; | |
}; | |
goog.array.insert = function(arr, obj) { | |
goog.array.contains(arr, obj) || arr.push(obj); | |
}; | |
goog.array.insertAt = function(arr, obj, opt_i) { | |
goog.array.splice(arr, opt_i, 0, obj); | |
}; | |
goog.array.insertArrayAt = function(arr, elementsToAdd, opt_i) { | |
goog.partial(goog.array.splice, arr, opt_i, 0).apply(null, elementsToAdd); | |
}; | |
goog.array.insertBefore = function(arr, obj, opt_obj2) { | |
var i; | |
2 == arguments.length || 0 > (i = goog.array.indexOf(arr, opt_obj2)) ? arr.push(obj) : goog.array.insertAt(arr, obj, i); | |
}; | |
goog.array.remove = function(arr, obj) { | |
var i = goog.array.indexOf(arr, obj), rv; | |
(rv = 0 <= i) && goog.array.removeAt(arr, i); | |
return rv; | |
}; | |
goog.array.removeAt = function(arr, i) { | |
goog.asserts.assert(null != arr.length); | |
return 1 == goog.array.ARRAY_PROTOTYPE_.splice.call(arr, i, 1).length; | |
}; | |
goog.array.removeIf = function(arr, f, opt_obj) { | |
var i = goog.array.findIndex(arr, f, opt_obj); | |
return 0 <= i ? (goog.array.removeAt(arr, i), !0) : !1; | |
}; | |
goog.array.concat = function(var_args) { | |
return goog.array.ARRAY_PROTOTYPE_.concat.apply(goog.array.ARRAY_PROTOTYPE_, arguments); | |
}; | |
goog.array.join = function(var_args) { | |
return goog.array.ARRAY_PROTOTYPE_.concat.apply(goog.array.ARRAY_PROTOTYPE_, arguments); | |
}; | |
goog.array.toArray = function(object) { | |
var length = object.length; | |
if (0 < length) { | |
for (var rv = Array(length), i = 0;i < length;i++) { | |
rv[i] = object[i]; | |
} | |
return rv; | |
} | |
return[]; | |
}; | |
goog.array.clone = goog.array.toArray; | |
goog.array.extend = function(arr1, var_args) { | |
for (var i = 1;i < arguments.length;i++) { | |
var arr2 = arguments[i], isArrayLike; | |
if (goog.isArray(arr2) || (isArrayLike = goog.isArrayLike(arr2)) && Object.prototype.hasOwnProperty.call(arr2, "callee")) { | |
arr1.push.apply(arr1, arr2); | |
} else { | |
if (isArrayLike) { | |
for (var len1 = arr1.length, len2 = arr2.length, j = 0;j < len2;j++) { | |
arr1[len1 + j] = arr2[j]; | |
} | |
} else { | |
arr1.push(arr2); | |
} | |
} | |
} | |
}; | |
goog.array.splice = function(arr, index, howMany, var_args) { | |
goog.asserts.assert(null != arr.length); | |
return goog.array.ARRAY_PROTOTYPE_.splice.apply(arr, goog.array.slice(arguments, 1)); | |
}; | |
goog.array.slice = function(arr, start, opt_end) { | |
goog.asserts.assert(null != arr.length); | |
return 2 >= arguments.length ? goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start) : goog.array.ARRAY_PROTOTYPE_.slice.call(arr, start, opt_end); | |
}; | |
goog.array.removeDuplicates = function(arr, opt_rv) { | |
for (var returnArray = opt_rv || arr, hashFn = function() { | |
return goog.isObject(current) ? "o" + goog.getUid(current) : (typeof current).charAt(0) + current; | |
}, seen = {}, cursorInsert = 0, cursorRead = 0;cursorRead < arr.length;) { | |
var current = arr[cursorRead++], key = hashFn(); | |
Object.prototype.hasOwnProperty.call(seen, key) || (seen[key] = !0, returnArray[cursorInsert++] = current); | |
} | |
returnArray.length = cursorInsert; | |
}; | |
goog.array.binarySearch = function(arr, target, opt_compareFn) { | |
return goog.array.binarySearch_(arr, opt_compareFn || goog.array.defaultCompare, !1, target); | |
}; | |
goog.array.binarySelect = function(arr, evaluator, opt_obj) { | |
return goog.array.binarySearch_(arr, evaluator, !0, void 0, opt_obj); | |
}; | |
goog.array.binarySearch_ = function(arr, compareFn, isEvaluator, opt_target, opt_selfObj) { | |
for (var left = 0, right = arr.length, found;left < right;) { | |
var middle = left + right >> 1, compareResult; | |
compareResult = isEvaluator ? compareFn.call(opt_selfObj, arr[middle], middle, arr) : compareFn(opt_target, arr[middle]); | |
0 < compareResult ? left = middle + 1 : (right = middle, found = !compareResult); | |
} | |
return found ? left : ~left; | |
}; | |
goog.array.sort = function(arr, opt_compareFn) { | |
arr.sort(opt_compareFn || goog.array.defaultCompare); | |
}; | |
goog.array.stableSort = function(arr, opt_compareFn) { | |
for (var i = 0;i < arr.length;i++) { | |
arr[i] = {index:i, value:arr[i]}; | |
} | |
var valueCompareFn = opt_compareFn || goog.array.defaultCompare; | |
goog.array.sort(arr, function(obj1, obj2) { | |
return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index; | |
}); | |
for (i = 0;i < arr.length;i++) { | |
arr[i] = arr[i].value; | |
} | |
}; | |
goog.array.sortObjectsByKey = function(arr, key, opt_compareFn) { | |
var compare = opt_compareFn || goog.array.defaultCompare; | |
goog.array.sort(arr, function(a, b) { | |
return compare(a[key], b[key]); | |
}); | |
}; | |
goog.array.isSorted = function(arr) { | |
for (var compare = goog.array.defaultCompare, i = 1;i < arr.length;i++) { | |
if (0 < compare(arr[i - 1], arr[i])) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.array.equals = function(arr1, arr2, opt_equalsFn) { | |
if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || arr1.length != arr2.length) { | |
return!1; | |
} | |
for (var l = arr1.length, equalsFn = opt_equalsFn || goog.array.defaultCompareEquality, i = 0;i < l;i++) { | |
if (!equalsFn(arr1[i], arr2[i])) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.array.compare3 = function(arr1, arr2, opt_compareFn) { | |
for (var compare = opt_compareFn || goog.array.defaultCompare, l = Math.min(arr1.length, arr2.length), i = 0;i < l;i++) { | |
var result = compare(arr1[i], arr2[i]); | |
if (0 != result) { | |
return result; | |
} | |
} | |
return goog.array.defaultCompare(arr1.length, arr2.length); | |
}; | |
goog.array.defaultCompare = function(a, b) { | |
return a > b ? 1 : a < b ? -1 : 0; | |
}; | |
goog.array.defaultCompareEquality = function(a, b) { | |
return a === b; | |
}; | |
goog.array.binaryInsert = function(array, value, opt_compareFn) { | |
var index = goog.array.binarySearch(array, value, opt_compareFn); | |
return 0 > index ? (goog.array.insertAt(array, value, -(index + 1)), !0) : !1; | |
}; | |
goog.array.binaryRemove = function(array, value, opt_compareFn) { | |
var index = goog.array.binarySearch(array, value, opt_compareFn); | |
return 0 <= index ? goog.array.removeAt(array, index) : !1; | |
}; | |
goog.array.bucket = function(array, sorter, opt_obj) { | |
for (var buckets = {}, i = 0;i < array.length;i++) { | |
var value = array[i], key = sorter.call(opt_obj, value, i, array); | |
goog.isDef(key) && (buckets[key] || (buckets[key] = [])).push(value); | |
} | |
return buckets; | |
}; | |
goog.array.toObject = function(arr, keyFunc, opt_obj) { | |
var ret = {}; | |
goog.array.forEach(arr, function(element, index) { | |
ret[keyFunc.call(opt_obj, element, index, arr)] = element; | |
}); | |
return ret; | |
}; | |
goog.array.range = function(startOrEnd, opt_end, opt_step) { | |
var array = [], start = 0, end = startOrEnd, step = opt_step || 1; | |
void 0 !== opt_end && (start = startOrEnd, end = opt_end); | |
if (0 > step * (end - start)) { | |
return[]; | |
} | |
if (0 < step) { | |
for (var i = start;i < end;i += step) { | |
array.push(i); | |
} | |
} else { | |
for (i = start;i > end;i += step) { | |
array.push(i); | |
} | |
} | |
return array; | |
}; | |
goog.array.repeat = function(value, n) { | |
for (var array = [], i = 0;i < n;i++) { | |
array[i] = value; | |
} | |
return array; | |
}; | |
goog.array.flatten = function(var_args) { | |
for (var result = [], i = 0;i < arguments.length;i++) { | |
var element = arguments[i]; | |
goog.isArray(element) ? result.push.apply(result, goog.array.flatten.apply(null, element)) : result.push(element); | |
} | |
return result; | |
}; | |
goog.array.rotate = function(array, n) { | |
goog.asserts.assert(null != array.length); | |
array.length && (n %= array.length, 0 < n ? goog.array.ARRAY_PROTOTYPE_.unshift.apply(array, array.splice(-n, n)) : 0 > n && goog.array.ARRAY_PROTOTYPE_.push.apply(array, array.splice(0, -n))); | |
return array; | |
}; | |
goog.array.moveItem = function(arr, fromIndex, toIndex) { | |
goog.asserts.assert(0 <= fromIndex && fromIndex < arr.length); | |
goog.asserts.assert(0 <= toIndex && toIndex < arr.length); | |
var removedItems = goog.array.ARRAY_PROTOTYPE_.splice.call(arr, fromIndex, 1); | |
goog.array.ARRAY_PROTOTYPE_.splice.call(arr, toIndex, 0, removedItems[0]); | |
}; | |
goog.array.zip = function(var_args) { | |
if (!arguments.length) { | |
return[]; | |
} | |
for (var result = [], i = 0;;i++) { | |
for (var value = [], j = 0;j < arguments.length;j++) { | |
var arr = arguments[j]; | |
if (i >= arr.length) { | |
return result; | |
} | |
value.push(arr[i]); | |
} | |
result.push(value); | |
} | |
}; | |
goog.array.shuffle = function(arr, opt_randFn) { | |
for (var randFn = opt_randFn || Math.random, i = arr.length - 1;0 < i;i--) { | |
var j = Math.floor(randFn() * (i + 1)), tmp = arr[i]; | |
arr[i] = arr[j]; | |
arr[j] = tmp; | |
} | |
}; | |
goog.labs = {}; | |
goog.labs.userAgent = {}; | |
goog.labs.userAgent.util = {}; | |
goog.labs.userAgent.util.getNativeUserAgentString_ = function() { | |
var navigator = goog.labs.userAgent.util.getNavigator_(); | |
if (navigator) { | |
var userAgent = navigator.userAgent; | |
if (userAgent) { | |
return userAgent; | |
} | |
} | |
return ""; | |
}; | |
goog.labs.userAgent.util.getNavigator_ = function() { | |
return goog.global.navigator; | |
}; | |
goog.labs.userAgent.util.userAgent_ = goog.labs.userAgent.util.getNativeUserAgentString_(); | |
goog.labs.userAgent.util.setUserAgent = function(opt_userAgent) { | |
goog.labs.userAgent.util.userAgent_ = opt_userAgent || goog.labs.userAgent.util.getNativeUserAgentString_(); | |
}; | |
goog.labs.userAgent.util.getUserAgent = function() { | |
return goog.labs.userAgent.util.userAgent_; | |
}; | |
goog.labs.userAgent.util.matchUserAgent = function(str) { | |
return goog.string.contains(goog.labs.userAgent.util.getUserAgent(), str); | |
}; | |
goog.labs.userAgent.util.matchUserAgentIgnoreCase = function() { | |
return goog.string.caseInsensitiveContains(); | |
}; | |
goog.labs.userAgent.util.extractVersionTuples = function(userAgent) { | |
for (var versionRegExp = /(\w[\w ]+)\/([^\s]+)\s*(?:\((.*?)\))?/g, data = [], match;match = versionRegExp.exec(userAgent);) { | |
data.push([match[1], match[2], match[3] || void 0]); | |
} | |
return data; | |
}; | |
goog.labs.userAgent.browser = {}; | |
goog.labs.userAgent.browser.matchOpera_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Opera") || goog.labs.userAgent.util.matchUserAgent("OPR"); | |
}; | |
goog.labs.userAgent.browser.matchIE_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Trident") || goog.labs.userAgent.util.matchUserAgent("MSIE"); | |
}; | |
goog.labs.userAgent.browser.matchFirefox_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Firefox"); | |
}; | |
goog.labs.userAgent.browser.matchSafari_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Safari") && !goog.labs.userAgent.util.matchUserAgent("Chrome") && !goog.labs.userAgent.util.matchUserAgent("CriOS") && !goog.labs.userAgent.util.matchUserAgent("Android"); | |
}; | |
goog.labs.userAgent.browser.matchChrome_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Chrome") || goog.labs.userAgent.util.matchUserAgent("CriOS"); | |
}; | |
goog.labs.userAgent.browser.matchAndroidBrowser_ = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Android") && !goog.labs.userAgent.util.matchUserAgent("Chrome") && !goog.labs.userAgent.util.matchUserAgent("CriOS"); | |
}; | |
goog.labs.userAgent.browser.isOpera = goog.labs.userAgent.browser.matchOpera_; | |
goog.labs.userAgent.browser.isIE = goog.labs.userAgent.browser.matchIE_; | |
goog.labs.userAgent.browser.isFirefox = goog.labs.userAgent.browser.matchFirefox_; | |
goog.labs.userAgent.browser.isSafari = goog.labs.userAgent.browser.matchSafari_; | |
goog.labs.userAgent.browser.isChrome = goog.labs.userAgent.browser.matchChrome_; | |
goog.labs.userAgent.browser.isAndroidBrowser = goog.labs.userAgent.browser.matchAndroidBrowser_; | |
goog.labs.userAgent.browser.isSilk = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Silk"); | |
}; | |
goog.labs.userAgent.browser.getVersion = function() { | |
var userAgentString = goog.labs.userAgent.util.getUserAgent(); | |
if (goog.labs.userAgent.browser.isIE()) { | |
return goog.labs.userAgent.browser.getIEVersion_(userAgentString); | |
} | |
if (goog.labs.userAgent.browser.isOpera()) { | |
return goog.labs.userAgent.browser.getOperaVersion_(userAgentString); | |
} | |
var versionTuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString); | |
return goog.labs.userAgent.browser.getVersionFromTuples_(versionTuples); | |
}; | |
goog.labs.userAgent.browser.isVersionOrHigher = function(version) { | |
return 0 <= goog.string.compareVersions(goog.labs.userAgent.browser.getVersion(), version); | |
}; | |
goog.labs.userAgent.browser.getIEVersion_ = function(userAgent) { | |
var rv = /rv: *([\d\.]*)/.exec(userAgent); | |
if (rv && rv[1]) { | |
return rv[1]; | |
} | |
var version = "", msie = /MSIE +([\d\.]+)/.exec(userAgent); | |
if (msie && msie[1]) { | |
var tridentVersion = /Trident\/(\d.\d)/.exec(userAgent); | |
if ("7.0" == msie[1]) { | |
if (tridentVersion && tridentVersion[1]) { | |
switch(tridentVersion[1]) { | |
case "4.0": | |
version = "8.0"; | |
break; | |
case "5.0": | |
version = "9.0"; | |
break; | |
case "6.0": | |
version = "10.0"; | |
break; | |
case "7.0": | |
version = "11.0"; | |
} | |
} else { | |
version = "7.0"; | |
} | |
} else { | |
version = msie[1]; | |
} | |
} | |
return version; | |
}; | |
goog.labs.userAgent.browser.getOperaVersion_ = function(userAgent) { | |
var versionTuples = goog.labs.userAgent.util.extractVersionTuples(userAgent), lastTuple = goog.array.peek(versionTuples); | |
return "OPR" == lastTuple[0] && lastTuple[1] ? lastTuple[1] : goog.labs.userAgent.browser.getVersionFromTuples_(versionTuples); | |
}; | |
goog.labs.userAgent.browser.getVersionFromTuples_ = function(versionTuples) { | |
goog.asserts.assert(2 < versionTuples.length, "Couldn't extract version tuple from user agent string"); | |
return versionTuples[2] && versionTuples[2][1] ? versionTuples[2][1] : ""; | |
}; | |
goog.labs.userAgent.engine = {}; | |
goog.labs.userAgent.engine.isPresto = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Presto"); | |
}; | |
goog.labs.userAgent.engine.isTrident = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Trident") || goog.labs.userAgent.util.matchUserAgent("MSIE"); | |
}; | |
goog.labs.userAgent.engine.isWebKit = function() { | |
return goog.labs.userAgent.util.matchUserAgentIgnoreCase(); | |
}; | |
goog.labs.userAgent.engine.isGecko = function() { | |
return goog.labs.userAgent.util.matchUserAgent("Gecko") && !goog.labs.userAgent.engine.isWebKit() && !goog.labs.userAgent.engine.isTrident(); | |
}; | |
goog.labs.userAgent.engine.getVersion = function() { | |
var userAgentString = goog.labs.userAgent.util.getUserAgent(); | |
if (userAgentString) { | |
var tuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString), engineTuple = tuples[1]; | |
if (engineTuple) { | |
return "Gecko" == engineTuple[0] ? goog.labs.userAgent.engine.getVersionForKey_(tuples) : engineTuple[1]; | |
} | |
var browserTuple = tuples[0], info; | |
if (browserTuple && (info = browserTuple[2])) { | |
var match = /Trident\/([^\s;]+)/.exec(info); | |
if (match) { | |
return match[1]; | |
} | |
} | |
} | |
return ""; | |
}; | |
goog.labs.userAgent.engine.isVersionOrHigher = function(version) { | |
return 0 <= goog.string.compareVersions(goog.labs.userAgent.engine.getVersion(), version); | |
}; | |
goog.labs.userAgent.engine.getVersionForKey_ = function(tuples) { | |
var pair = goog.array.find(tuples, function(pair) { | |
return "Firefox" == pair[0]; | |
}); | |
return pair && pair[1] || ""; | |
}; | |
goog.userAgent = {}; | |
goog.userAgent.ASSUME_IE = !1; | |
goog.userAgent.ASSUME_GECKO = !1; | |
goog.userAgent.ASSUME_WEBKIT = !1; | |
goog.userAgent.ASSUME_MOBILE_WEBKIT = !1; | |
goog.userAgent.ASSUME_OPERA = !1; | |
goog.userAgent.ASSUME_ANY_VERSION = !1; | |
goog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE || goog.userAgent.ASSUME_GECKO || goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_OPERA; | |
goog.userAgent.getUserAgentString = function() { | |
return goog.labs.userAgent.util.getUserAgent(); | |
}; | |
goog.userAgent.getNavigator = function() { | |
return goog.global.navigator || null; | |
}; | |
goog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_OPERA : goog.labs.userAgent.browser.isOpera(); | |
goog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_IE : goog.labs.userAgent.browser.isIE(); | |
goog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_GECKO : goog.labs.userAgent.engine.isGecko(); | |
goog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ? goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT : goog.labs.userAgent.engine.isWebKit(); | |
goog.userAgent.isMobile_ = function() { | |
return goog.userAgent.WEBKIT && goog.labs.userAgent.util.matchUserAgent("Mobile"); | |
}; | |
goog.userAgent.MOBILE = goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_(); | |
goog.userAgent.SAFARI = goog.userAgent.WEBKIT; | |
goog.userAgent.determinePlatform_ = function() { | |
var navigator = goog.userAgent.getNavigator(); | |
return navigator && navigator.platform || ""; | |
}; | |
goog.userAgent.PLATFORM = goog.userAgent.determinePlatform_(); | |
goog.userAgent.ASSUME_MAC = !1; | |
goog.userAgent.ASSUME_WINDOWS = !1; | |
goog.userAgent.ASSUME_LINUX = !1; | |
goog.userAgent.ASSUME_X11 = !1; | |
goog.userAgent.ASSUME_ANDROID = !1; | |
goog.userAgent.ASSUME_IPHONE = !1; | |
goog.userAgent.ASSUME_IPAD = !1; | |
goog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC || goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX || goog.userAgent.ASSUME_X11 || goog.userAgent.ASSUME_ANDROID || goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD; | |
goog.userAgent.initPlatform_ = function() { | |
goog.userAgent.detectedMac_ = goog.string.contains(goog.userAgent.PLATFORM, "Mac"); | |
goog.userAgent.detectedWindows_ = goog.string.contains(goog.userAgent.PLATFORM, "Win"); | |
goog.userAgent.detectedLinux_ = goog.string.contains(goog.userAgent.PLATFORM, "Linux"); | |
goog.userAgent.detectedX11_ = !!goog.userAgent.getNavigator() && goog.string.contains(goog.userAgent.getNavigator().appVersion || "", "X11"); | |
var ua = goog.userAgent.getUserAgentString(); | |
goog.userAgent.detectedAndroid_ = !!ua && goog.string.contains(ua, "Android"); | |
goog.userAgent.detectedIPhone_ = !!ua && goog.string.contains(ua, "iPhone"); | |
goog.userAgent.detectedIPad_ = !!ua && goog.string.contains(ua, "iPad"); | |
}; | |
goog.userAgent.PLATFORM_KNOWN_ || goog.userAgent.initPlatform_(); | |
goog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_MAC : goog.userAgent.detectedMac_; | |
goog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_WINDOWS : goog.userAgent.detectedWindows_; | |
goog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_LINUX : goog.userAgent.detectedLinux_; | |
goog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_X11 : goog.userAgent.detectedX11_; | |
goog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_ANDROID : goog.userAgent.detectedAndroid_; | |
goog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_IPHONE : goog.userAgent.detectedIPhone_; | |
goog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ? goog.userAgent.ASSUME_IPAD : goog.userAgent.detectedIPad_; | |
goog.userAgent.determineVersion_ = function() { | |
var version = "", re; | |
if (goog.userAgent.OPERA && goog.global.opera) { | |
var operaVersion = goog.global.opera.version; | |
return goog.isFunction(operaVersion) ? operaVersion() : operaVersion; | |
} | |
goog.userAgent.GECKO ? re = /rv\:([^\);]+)(\)|;)/ : goog.userAgent.IE ? re = /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/ : goog.userAgent.WEBKIT && (re = /WebKit\/(\S+)/); | |
if (re) { | |
var arr = re.exec(goog.userAgent.getUserAgentString()), version = arr ? arr[1] : "" | |
} | |
if (goog.userAgent.IE) { | |
var docMode = goog.userAgent.getDocumentMode_(); | |
if (docMode > parseFloat(version)) { | |
return String(docMode); | |
} | |
} | |
return version; | |
}; | |
goog.userAgent.getDocumentMode_ = function() { | |
var doc = goog.global.document; | |
return doc ? doc.documentMode : void 0; | |
}; | |
goog.userAgent.VERSION = goog.userAgent.determineVersion_(); | |
goog.userAgent.compare = function(v1, v2) { | |
return goog.string.compareVersions(v1, v2); | |
}; | |
goog.userAgent.isVersionOrHigherCache_ = {}; | |
goog.userAgent.isVersionOrHigher = function(version) { | |
return goog.userAgent.ASSUME_ANY_VERSION || goog.userAgent.isVersionOrHigherCache_[version] || (goog.userAgent.isVersionOrHigherCache_[version] = 0 <= goog.string.compareVersions(goog.userAgent.VERSION, version)); | |
}; | |
goog.userAgent.isVersion = goog.userAgent.isVersionOrHigher; | |
goog.userAgent.isDocumentModeOrHigher = function(documentMode) { | |
return goog.userAgent.IE && goog.userAgent.DOCUMENT_MODE >= documentMode; | |
}; | |
goog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher; | |
goog.userAgent.DOCUMENT_MODE = function() { | |
var doc = goog.global.document; | |
return doc && goog.userAgent.IE ? goog.userAgent.getDocumentMode_() || ("CSS1Compat" == doc.compatMode ? parseInt(goog.userAgent.VERSION, 10) : 5) : void 0; | |
}(); | |
goog.events.BrowserFeature = {HAS_W3C_BUTTON:!goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9), HAS_W3C_EVENT_SUPPORT:!goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9), SET_KEY_CODE_TO_PREVENT_DEFAULT:goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("9"), HAS_NAVIGATOR_ONLINE_PROPERTY:!goog.userAgent.WEBKIT || goog.userAgent.isVersionOrHigher("528"), HAS_HTML5_NETWORK_EVENT_SUPPORT:goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher("1.9b") || goog.userAgent.IE && | |
goog.userAgent.isVersionOrHigher("8") || goog.userAgent.OPERA && goog.userAgent.isVersionOrHigher("9.5") || goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher("528"), HTML5_NETWORK_EVENTS_FIRE_ON_BODY:goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher("8") || goog.userAgent.IE && !goog.userAgent.isVersionOrHigher("9"), TOUCH_ENABLED:"ontouchstart" in goog.global || !!(goog.global.document && document.documentElement && "ontouchstart" in document.documentElement) || !(!goog.global.navigator || | |
!goog.global.navigator.msMaxTouchPoints)}; | |
goog.events.getVendorPrefixedName_ = function(eventName) { | |
return goog.userAgent.WEBKIT ? "webkit" + eventName : goog.userAgent.OPERA ? "o" + eventName.toLowerCase() : eventName.toLowerCase(); | |
}; | |
goog.events.EventType = {CLICK:"click", RIGHTCLICK:"rightclick", DBLCLICK:"dblclick", MOUSEDOWN:"mousedown", MOUSEUP:"mouseup", MOUSEOVER:"mouseover", MOUSEOUT:"mouseout", MOUSEMOVE:"mousemove", MOUSEENTER:"mouseenter", MOUSELEAVE:"mouseleave", SELECTSTART:"selectstart", KEYPRESS:"keypress", KEYDOWN:"keydown", KEYUP:"keyup", BLUR:"blur", FOCUS:"focus", DEACTIVATE:"deactivate", FOCUSIN:goog.userAgent.IE ? "focusin" : "DOMFocusIn", FOCUSOUT:goog.userAgent.IE ? "focusout" : "DOMFocusOut", CHANGE:"change", | |
SELECT:"select", SUBMIT:"submit", INPUT:"input", PROPERTYCHANGE:"propertychange", DRAGSTART:"dragstart", DRAG:"drag", DRAGENTER:"dragenter", DRAGOVER:"dragover", DRAGLEAVE:"dragleave", DROP:"drop", DRAGEND:"dragend", TOUCHSTART:"touchstart", TOUCHMOVE:"touchmove", TOUCHEND:"touchend", TOUCHCANCEL:"touchcancel", BEFOREUNLOAD:"beforeunload", CONSOLEMESSAGE:"consolemessage", CONTEXTMENU:"contextmenu", DOMCONTENTLOADED:"DOMContentLoaded", ERROR:"error", HELP:"help", LOAD:"load", LOSECAPTURE:"losecapture", | |
ORIENTATIONCHANGE:"orientationchange", READYSTATECHANGE:"readystatechange", RESIZE:"resize", SCROLL:"scroll", UNLOAD:"unload", HASHCHANGE:"hashchange", PAGEHIDE:"pagehide", PAGESHOW:"pageshow", POPSTATE:"popstate", COPY:"copy", PASTE:"paste", CUT:"cut", BEFORECOPY:"beforecopy", BEFORECUT:"beforecut", BEFOREPASTE:"beforepaste", ONLINE:"online", OFFLINE:"offline", MESSAGE:"message", CONNECT:"connect", ANIMATIONSTART:goog.events.getVendorPrefixedName_("AnimationStart"), ANIMATIONEND:goog.events.getVendorPrefixedName_("AnimationEnd"), | |
ANIMATIONITERATION:goog.events.getVendorPrefixedName_("AnimationIteration"), TRANSITIONEND:goog.events.getVendorPrefixedName_("TransitionEnd"), POINTERDOWN:"pointerdown", POINTERUP:"pointerup", POINTERCANCEL:"pointercancel", POINTERMOVE:"pointermove", POINTEROVER:"pointerover", POINTEROUT:"pointerout", POINTERENTER:"pointerenter", POINTERLEAVE:"pointerleave", GOTPOINTERCAPTURE:"gotpointercapture", LOSTPOINTERCAPTURE:"lostpointercapture", MSGESTURECHANGE:"MSGestureChange", MSGESTUREEND:"MSGestureEnd", | |
MSGESTUREHOLD:"MSGestureHold", MSGESTURESTART:"MSGestureStart", MSGESTURETAP:"MSGestureTap", MSGOTPOINTERCAPTURE:"MSGotPointerCapture", MSINERTIASTART:"MSInertiaStart", MSLOSTPOINTERCAPTURE:"MSLostPointerCapture", MSPOINTERCANCEL:"MSPointerCancel", MSPOINTERDOWN:"MSPointerDown", MSPOINTERENTER:"MSPointerEnter", MSPOINTERHOVER:"MSPointerHover", MSPOINTERLEAVE:"MSPointerLeave", MSPOINTERMOVE:"MSPointerMove", MSPOINTEROUT:"MSPointerOut", MSPOINTEROVER:"MSPointerOver", MSPOINTERUP:"MSPointerUp", TEXTINPUT:"textinput", | |
COMPOSITIONSTART:"compositionstart", COMPOSITIONUPDATE:"compositionupdate", COMPOSITIONEND:"compositionend", EXIT:"exit", LOADABORT:"loadabort", LOADCOMMIT:"loadcommit", LOADREDIRECT:"loadredirect", LOADSTART:"loadstart", LOADSTOP:"loadstop", RESPONSIVE:"responsive", SIZECHANGED:"sizechanged", UNRESPONSIVE:"unresponsive", VISIBILITYCHANGE:"visibilitychange", STORAGE:"storage", DOMSUBTREEMODIFIED:"DOMSubtreeModified", DOMNODEINSERTED:"DOMNodeInserted", DOMNODEREMOVED:"DOMNodeRemoved", DOMNODEREMOVEDFROMDOCUMENT:"DOMNodeRemovedFromDocument", | |
DOMNODEINSERTEDINTODOCUMENT:"DOMNodeInsertedIntoDocument", DOMATTRMODIFIED:"DOMAttrModified", DOMCHARACTERDATAMODIFIED:"DOMCharacterDataModified"}; | |
goog.events.BrowserEvent = function(opt_e, opt_currentTarget) { | |
goog.events.Event.call(this, opt_e ? opt_e.type : ""); | |
this.relatedTarget = this.currentTarget = this.target = null; | |
this.charCode = this.keyCode = this.button = this.screenY = this.screenX = this.clientY = this.clientX = this.offsetY = this.offsetX = 0; | |
this.metaKey = this.shiftKey = this.altKey = this.ctrlKey = !1; | |
this.event_ = this.state = null; | |
opt_e && this.init(opt_e, opt_currentTarget); | |
}; | |
goog.inherits(goog.events.BrowserEvent, goog.events.Event); | |
goog.events.BrowserEvent.MouseButton = {LEFT:0, MIDDLE:1, RIGHT:2}; | |
goog.events.BrowserEvent.IEButtonMap = [1, 4, 2]; | |
goog.events.BrowserEvent.prototype.init = function(e, opt_currentTarget) { | |
var type = this.type = e.type; | |
this.target = e.target || e.srcElement; | |
this.currentTarget = opt_currentTarget; | |
var relatedTarget = e.relatedTarget; | |
relatedTarget ? goog.userAgent.GECKO && (goog.reflect.canAccessProperty(relatedTarget) || (relatedTarget = null)) : type == goog.events.EventType.MOUSEOVER ? relatedTarget = e.fromElement : type == goog.events.EventType.MOUSEOUT && (relatedTarget = e.toElement); | |
this.relatedTarget = relatedTarget; | |
this.offsetX = goog.userAgent.WEBKIT || void 0 !== e.offsetX ? e.offsetX : e.layerX; | |
this.offsetY = goog.userAgent.WEBKIT || void 0 !== e.offsetY ? e.offsetY : e.layerY; | |
this.clientX = void 0 !== e.clientX ? e.clientX : e.pageX; | |
this.clientY = void 0 !== e.clientY ? e.clientY : e.pageY; | |
this.screenX = e.screenX || 0; | |
this.screenY = e.screenY || 0; | |
this.button = e.button; | |
this.keyCode = e.keyCode || 0; | |
this.charCode = e.charCode || ("keypress" == type ? e.keyCode : 0); | |
this.ctrlKey = e.ctrlKey; | |
this.altKey = e.altKey; | |
this.shiftKey = e.shiftKey; | |
this.metaKey = e.metaKey; | |
this.state = e.state; | |
this.event_ = e; | |
e.defaultPrevented && this.preventDefault(); | |
}; | |
goog.events.BrowserEvent.prototype.stopPropagation = function() { | |
goog.events.BrowserEvent.superClass_.stopPropagation.call(this); | |
this.event_.stopPropagation ? this.event_.stopPropagation() : this.event_.cancelBubble = !0; | |
}; | |
goog.events.BrowserEvent.prototype.preventDefault = function() { | |
goog.events.BrowserEvent.superClass_.preventDefault.call(this); | |
var be = this.event_; | |
if (be.preventDefault) { | |
be.preventDefault(); | |
} else { | |
if (be.returnValue = !1, goog.events.BrowserFeature.SET_KEY_CODE_TO_PREVENT_DEFAULT) { | |
try { | |
if (be.ctrlKey || 112 <= be.keyCode && 123 >= be.keyCode) { | |
be.keyCode = -1; | |
} | |
} catch (ex) { | |
} | |
} | |
} | |
}; | |
goog.events.BrowserEvent.prototype.disposeInternal = function() { | |
}; | |
goog.events.Listenable = function() { | |
}; | |
goog.events.Listenable.IMPLEMENTED_BY_PROP = "closure_listenable_" + (1E6 * Math.random() | 0); | |
goog.events.Listenable.addImplementation = function() { | |
goog.events.EventTarget.prototype[goog.events.Listenable.IMPLEMENTED_BY_PROP] = !0; | |
}; | |
goog.events.Listenable.isImplementedBy = function(obj) { | |
return!(!obj || !obj[goog.events.Listenable.IMPLEMENTED_BY_PROP]); | |
}; | |
goog.events.ListenableKey = function() { | |
}; | |
goog.events.ListenableKey.counter_ = 0; | |
goog.events.ListenableKey.reserveKey = function() { | |
return++goog.events.ListenableKey.counter_; | |
}; | |
goog.events.Listener = function(listener, proxy, src, type, capture, opt_handler) { | |
this.listener = listener; | |
this.proxy = proxy; | |
this.src = src; | |
this.type = type; | |
this.capture = !!capture; | |
this.handler = opt_handler; | |
this.key = goog.events.ListenableKey.reserveKey(); | |
this.removed = this.callOnce = !1; | |
}; | |
goog.events.Listener.ENABLE_MONITORING = !1; | |
var JSCompiler_StaticMethods_markAsRemoved = function(JSCompiler_StaticMethods_markAsRemoved$self) { | |
JSCompiler_StaticMethods_markAsRemoved$self.removed = !0; | |
JSCompiler_StaticMethods_markAsRemoved$self.listener = null; | |
JSCompiler_StaticMethods_markAsRemoved$self.proxy = null; | |
JSCompiler_StaticMethods_markAsRemoved$self.src = null; | |
JSCompiler_StaticMethods_markAsRemoved$self.handler = null; | |
}; | |
goog.events.ListenerMap = function(src) { | |
this.src = src; | |
this.listeners = {}; | |
this.typeCount_ = 0; | |
}; | |
var JSCompiler_StaticMethods_getTypeCount = function(JSCompiler_StaticMethods_getTypeCount$self) { | |
return JSCompiler_StaticMethods_getTypeCount$self.typeCount_; | |
}; | |
goog.events.ListenerMap.prototype.add = function(type, listener, callOnce, opt_useCapture, opt_listenerScope) { | |
var typeStr = type.toString(), listenerArray = this.listeners[typeStr]; | |
listenerArray || (listenerArray = this.listeners[typeStr] = [], this.typeCount_++); | |
var listenerObj, index = goog.events.ListenerMap.findListenerIndex_(listenerArray, listener, opt_useCapture, opt_listenerScope); | |
-1 < index ? (listenerObj = listenerArray[index], callOnce || (listenerObj.callOnce = !1)) : (listenerObj = new goog.events.Listener(listener, null, this.src, typeStr, !!opt_useCapture, opt_listenerScope), listenerObj.callOnce = callOnce, listenerArray.push(listenerObj)); | |
return listenerObj; | |
}; | |
goog.events.ListenerMap.prototype.remove = function(type, listener, opt_useCapture, opt_listenerScope) { | |
var typeStr = type.toString(); | |
if (!(typeStr in this.listeners)) { | |
return!1; | |
} | |
var listenerArray = this.listeners[typeStr], index = goog.events.ListenerMap.findListenerIndex_(listenerArray, listener, opt_useCapture, opt_listenerScope); | |
return-1 < index ? (JSCompiler_StaticMethods_markAsRemoved(listenerArray[index]), goog.array.removeAt(listenerArray, index), 0 == listenerArray.length && (delete this.listeners[typeStr], this.typeCount_--), !0) : !1; | |
}; | |
var JSCompiler_StaticMethods_removeByKey = function(JSCompiler_StaticMethods_removeByKey$self, listener) { | |
var type = listener.type; | |
if (!(type in JSCompiler_StaticMethods_removeByKey$self.listeners)) { | |
return!1; | |
} | |
var removed = goog.array.remove(JSCompiler_StaticMethods_removeByKey$self.listeners[type], listener); | |
removed && (JSCompiler_StaticMethods_markAsRemoved(listener), 0 == JSCompiler_StaticMethods_removeByKey$self.listeners[type].length && (delete JSCompiler_StaticMethods_removeByKey$self.listeners[type], JSCompiler_StaticMethods_removeByKey$self.typeCount_--)); | |
return removed; | |
}; | |
goog.events.ListenerMap.prototype.removeAll = function(opt_type) { | |
var typeStr = opt_type && opt_type.toString(), count = 0, type; | |
for (type in this.listeners) { | |
if (!typeStr || type == typeStr) { | |
for (var listenerArray = this.listeners[type], i = 0;i < listenerArray.length;i++) { | |
++count, JSCompiler_StaticMethods_markAsRemoved(listenerArray[i]); | |
} | |
delete this.listeners[type]; | |
this.typeCount_--; | |
} | |
} | |
return count; | |
}; | |
goog.events.ListenerMap.prototype.getListeners = function(type, capture) { | |
var listenerArray = this.listeners[type.toString()], rv = []; | |
if (listenerArray) { | |
for (var i = 0;i < listenerArray.length;++i) { | |
var listenerObj = listenerArray[i]; | |
listenerObj.capture == capture && rv.push(listenerObj); | |
} | |
} | |
return rv; | |
}; | |
goog.events.ListenerMap.prototype.getListener = function(type, listener, capture, opt_listenerScope) { | |
var listenerArray = this.listeners[type.toString()], i = -1; | |
listenerArray && (i = goog.events.ListenerMap.findListenerIndex_(listenerArray, listener, capture, opt_listenerScope)); | |
return-1 < i ? listenerArray[i] : null; | |
}; | |
goog.events.ListenerMap.prototype.hasListener = function(opt_type, opt_capture) { | |
var hasType = goog.isDef(opt_type), typeStr = hasType ? opt_type.toString() : "", hasCapture = goog.isDef(opt_capture); | |
return goog.object.some(this.listeners, function(listenerArray) { | |
for (var i = 0;i < listenerArray.length;++i) { | |
if (!(hasType && listenerArray[i].type != typeStr || hasCapture && listenerArray[i].capture != opt_capture)) { | |
return!0; | |
} | |
} | |
return!1; | |
}); | |
}; | |
goog.events.ListenerMap.findListenerIndex_ = function(listenerArray, listener, opt_useCapture, opt_listenerScope) { | |
for (var i = 0;i < listenerArray.length;++i) { | |
var listenerObj = listenerArray[i]; | |
if (!listenerObj.removed && listenerObj.listener == listener && listenerObj.capture == !!opt_useCapture && listenerObj.handler == opt_listenerScope) { | |
return i; | |
} | |
} | |
return-1; | |
}; | |
goog.events.listeners_ = {}; | |
goog.events.LISTENER_MAP_PROP_ = "closure_lm_" + (1E6 * Math.random() | 0); | |
goog.events.onString_ = "on"; | |
goog.events.onStringMap_ = {}; | |
goog.events.CaptureSimulationMode = {OFF_AND_FAIL:0, OFF_AND_SILENT:1, ON:2}; | |
goog.events.CAPTURE_SIMULATION_MODE = 2; | |
goog.events.listenerCountEstimate_ = 0; | |
goog.events.listen = function(src, type, listener, opt_capt, opt_handler) { | |
if (goog.isArray(type)) { | |
for (var i = 0;i < type.length;i++) { | |
goog.events.listen(src, type[i], listener, opt_capt, opt_handler); | |
} | |
return null; | |
} | |
listener = goog.events.wrapListener(listener); | |
return goog.events.Listenable.isImplementedBy(src) ? src.listen(type, listener, opt_capt, opt_handler) : goog.events.listen_(src, type, listener, !1, opt_capt, opt_handler); | |
}; | |
goog.events.listen_ = function(src, type, listener, callOnce, opt_capt, opt_handler) { | |
if (!type) { | |
throw Error("Invalid event type"); | |
} | |
var capture = !!opt_capt; | |
if (capture && !goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) { | |
if (goog.events.CAPTURE_SIMULATION_MODE == goog.events.CaptureSimulationMode.OFF_AND_FAIL) { | |
return goog.asserts.fail("Can not register capture listener in IE8-."), null; | |
} | |
if (goog.events.CAPTURE_SIMULATION_MODE == goog.events.CaptureSimulationMode.OFF_AND_SILENT) { | |
return null; | |
} | |
} | |
var listenerMap = goog.events.getListenerMap_(src); | |
listenerMap || (src[goog.events.LISTENER_MAP_PROP_] = listenerMap = new goog.events.ListenerMap(src)); | |
var listenerObj = listenerMap.add(type, listener, callOnce, opt_capt, opt_handler); | |
if (listenerObj.proxy) { | |
return listenerObj; | |
} | |
var proxy = goog.events.getProxy(); | |
listenerObj.proxy = proxy; | |
proxy.src = src; | |
proxy.listener = listenerObj; | |
src.addEventListener ? src.addEventListener(type.toString(), proxy, capture) : src.attachEvent(goog.events.getOnString_(type.toString()), proxy); | |
goog.events.listenerCountEstimate_++; | |
return listenerObj; | |
}; | |
goog.events.getProxy = function() { | |
var proxyCallbackFunction = goog.events.handleBrowserEvent_, f = goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT ? function(eventObject) { | |
return proxyCallbackFunction.call(f.src, f.listener, eventObject); | |
} : function(eventObject) { | |
var v = proxyCallbackFunction.call(f.src, f.listener, eventObject); | |
if (!v) { | |
return v; | |
} | |
}; | |
return f; | |
}; | |
goog.events.listenOnce = function(src, type, listener, opt_capt, opt_handler) { | |
if (goog.isArray(type)) { | |
for (var i = 0;i < type.length;i++) { | |
goog.events.listenOnce(src, type[i], listener, opt_capt, opt_handler); | |
} | |
return null; | |
} | |
listener = goog.events.wrapListener(listener); | |
return goog.events.Listenable.isImplementedBy(src) ? src.listenOnce(type, listener, opt_capt, opt_handler) : goog.events.listen_(src, type, listener, !0, opt_capt, opt_handler); | |
}; | |
goog.events.listenWithWrapper = function(src, wrapper, listener, opt_capt, opt_handler) { | |
wrapper.listen(src, listener, opt_capt, opt_handler); | |
}; | |
goog.events.unlisten = function(src, type, listener, opt_capt, opt_handler) { | |
if (goog.isArray(type)) { | |
for (var i = 0;i < type.length;i++) { | |
goog.events.unlisten(src, type[i], listener, opt_capt, opt_handler); | |
} | |
return null; | |
} | |
listener = goog.events.wrapListener(listener); | |
if (goog.events.Listenable.isImplementedBy(src)) { | |
return src.unlisten(type, listener, opt_capt, opt_handler); | |
} | |
if (!src) { | |
return!1; | |
} | |
var listenerMap = goog.events.getListenerMap_(src); | |
if (listenerMap) { | |
var listenerObj = listenerMap.getListener(type, listener, !!opt_capt, opt_handler); | |
if (listenerObj) { | |
return goog.events.unlistenByKey(listenerObj); | |
} | |
} | |
return!1; | |
}; | |
goog.events.unlistenByKey = function(key) { | |
if (goog.isNumber(key) || !key || key.removed) { | |
return!1; | |
} | |
var src = key.src; | |
if (goog.events.Listenable.isImplementedBy(src)) { | |
return src.unlistenByKey(key); | |
} | |
var type = key.type, proxy = key.proxy; | |
src.removeEventListener ? src.removeEventListener(type, proxy, key.capture) : src.detachEvent && src.detachEvent(goog.events.getOnString_(type), proxy); | |
goog.events.listenerCountEstimate_--; | |
var listenerMap = goog.events.getListenerMap_(src); | |
listenerMap ? (JSCompiler_StaticMethods_removeByKey(listenerMap, key), 0 == JSCompiler_StaticMethods_getTypeCount(listenerMap) && (listenerMap.src = null, src[goog.events.LISTENER_MAP_PROP_] = null)) : JSCompiler_StaticMethods_markAsRemoved(key); | |
return!0; | |
}; | |
goog.events.unlistenWithWrapper = function(src, wrapper, listener, opt_capt, opt_handler) { | |
wrapper.unlisten(src, listener, opt_capt, opt_handler); | |
}; | |
goog.events.removeAll = function(opt_obj, opt_type) { | |
if (!opt_obj) { | |
return 0; | |
} | |
if (goog.events.Listenable.isImplementedBy(opt_obj)) { | |
return JSCompiler_StaticMethods_removeAllListeners(opt_obj, opt_type); | |
} | |
var listenerMap = goog.events.getListenerMap_(opt_obj); | |
if (!listenerMap) { | |
return 0; | |
} | |
var count = 0, typeStr = opt_type && opt_type.toString(), type; | |
for (type in listenerMap.listeners) { | |
if (!typeStr || type == typeStr) { | |
for (var listeners = listenerMap.listeners[type].concat(), i = 0;i < listeners.length;++i) { | |
goog.events.unlistenByKey(listeners[i]) && ++count; | |
} | |
} | |
} | |
return count; | |
}; | |
goog.events.removeAllNativeListeners = function() { | |
return goog.events.listenerCountEstimate_ = 0; | |
}; | |
goog.events.getListeners = function(obj, type, capture) { | |
if (goog.events.Listenable.isImplementedBy(obj)) { | |
return obj.getListeners(type, capture); | |
} | |
if (!obj) { | |
return[]; | |
} | |
var listenerMap = goog.events.getListenerMap_(obj); | |
return listenerMap ? listenerMap.getListeners(type, capture) : []; | |
}; | |
goog.events.getListener = function(src, type, listener, opt_capt, opt_handler) { | |
listener = goog.events.wrapListener(listener); | |
var capture = !!opt_capt; | |
if (goog.events.Listenable.isImplementedBy(src)) { | |
return src.getListener(type, listener, capture, opt_handler); | |
} | |
if (!src) { | |
return null; | |
} | |
var listenerMap = goog.events.getListenerMap_(src); | |
return listenerMap ? listenerMap.getListener(type, listener, capture, opt_handler) : null; | |
}; | |
goog.events.hasListener = function(obj, opt_type, opt_capture) { | |
if (goog.events.Listenable.isImplementedBy(obj)) { | |
return obj.hasListener(opt_type, opt_capture); | |
} | |
var listenerMap = goog.events.getListenerMap_(obj); | |
return!!listenerMap && listenerMap.hasListener(opt_type, opt_capture); | |
}; | |
goog.events.expose = function(e) { | |
var str = [], key; | |
for (key in e) { | |
e[key] && e[key].id ? str.push(key + " = " + e[key] + " (" + e[key].id + ")") : str.push(key + " = " + e[key]); | |
} | |
return str.join("\n"); | |
}; | |
goog.events.getOnString_ = function(type) { | |
return type in goog.events.onStringMap_ ? goog.events.onStringMap_[type] : goog.events.onStringMap_[type] = goog.events.onString_ + type; | |
}; | |
goog.events.fireListeners = function(obj, type, capture, eventObject) { | |
return goog.events.Listenable.isImplementedBy(obj) ? obj.fireListeners(type, capture, eventObject) : goog.events.fireListeners_(obj, type, capture, eventObject); | |
}; | |
goog.events.fireListeners_ = function(obj, type, capture, eventObject) { | |
var retval = 1, listenerMap = goog.events.getListenerMap_(obj); | |
if (listenerMap) { | |
var listenerArray = listenerMap.listeners[type.toString()]; | |
if (listenerArray) { | |
for (var listenerArray = listenerArray.concat(), i = 0;i < listenerArray.length;i++) { | |
var listener = listenerArray[i]; | |
listener && listener.capture == capture && !listener.removed && (retval &= !1 !== goog.events.fireListener(listener, eventObject)); | |
} | |
} | |
} | |
return Boolean(retval); | |
}; | |
goog.events.fireListener = function(listener, eventObject) { | |
var listenerFn = listener.listener, listenerHandler = listener.handler || listener.src; | |
listener.callOnce && goog.events.unlistenByKey(listener); | |
return listenerFn.call(listenerHandler, eventObject); | |
}; | |
goog.events.getTotalListenerCount = function() { | |
return goog.events.listenerCountEstimate_; | |
}; | |
goog.events.dispatchEvent = function(src, e) { | |
goog.asserts.assert(goog.events.Listenable.isImplementedBy(src), "Can not use goog.events.dispatchEvent with non-goog.events.Listenable instance."); | |
return src.dispatchEvent(e); | |
}; | |
goog.events.protectBrowserEventEntryPoint = function(errorHandler) { | |
goog.events.handleBrowserEvent_ = errorHandler.protectEntryPoint(goog.events.handleBrowserEvent_); | |
}; | |
goog.events.handleBrowserEvent_ = function(listener, opt_evt) { | |
if (listener.removed) { | |
return!0; | |
} | |
if (!goog.events.BrowserFeature.HAS_W3C_EVENT_SUPPORT) { | |
var ieEvent = opt_evt || goog.getObjectByName("window.event"), evt = new goog.events.BrowserEvent(ieEvent, this), retval = !0; | |
if (goog.events.CAPTURE_SIMULATION_MODE == goog.events.CaptureSimulationMode.ON) { | |
if (!goog.events.isMarkedIeEvent_(ieEvent)) { | |
goog.events.markIeEvent_(ieEvent); | |
for (var ancestors = [], parent = evt.currentTarget;parent;parent = parent.parentNode) { | |
ancestors.push(parent); | |
} | |
for (var type = listener.type, i = ancestors.length - 1;!evt.propagationStopped_ && 0 <= i;i--) { | |
evt.currentTarget = ancestors[i], retval &= goog.events.fireListeners_(ancestors[i], type, !0, evt); | |
} | |
for (i = 0;!evt.propagationStopped_ && i < ancestors.length;i++) { | |
evt.currentTarget = ancestors[i], retval &= goog.events.fireListeners_(ancestors[i], type, !1, evt); | |
} | |
} | |
} else { | |
retval = goog.events.fireListener(listener, evt); | |
} | |
return retval; | |
} | |
return goog.events.fireListener(listener, new goog.events.BrowserEvent(opt_evt, this)); | |
}; | |
goog.events.markIeEvent_ = function(e) { | |
var useReturnValue = !1; | |
if (0 == e.keyCode) { | |
try { | |
e.keyCode = -1; | |
return; | |
} catch (ex) { | |
useReturnValue = !0; | |
} | |
} | |
if (useReturnValue || void 0 == e.returnValue) { | |
e.returnValue = !0; | |
} | |
}; | |
goog.events.isMarkedIeEvent_ = function(e) { | |
return 0 > e.keyCode || void 0 != e.returnValue; | |
}; | |
goog.events.uniqueIdCounter_ = 0; | |
goog.events.getUniqueId = function(identifier) { | |
return identifier + "_" + goog.events.uniqueIdCounter_++; | |
}; | |
goog.events.getListenerMap_ = function(src) { | |
var listenerMap = src[goog.events.LISTENER_MAP_PROP_]; | |
return listenerMap instanceof goog.events.ListenerMap ? listenerMap : null; | |
}; | |
goog.events.LISTENER_WRAPPER_PROP_ = "__closure_events_fn_" + (1E9 * Math.random() >>> 0); | |
goog.events.wrapListener = function(listener) { | |
goog.asserts.assert(listener, "Listener can not be null."); | |
if (goog.isFunction(listener)) { | |
return listener; | |
} | |
goog.asserts.assert(listener.handleEvent, "An object listener must have handleEvent method."); | |
return listener[goog.events.LISTENER_WRAPPER_PROP_] || (listener[goog.events.LISTENER_WRAPPER_PROP_] = function(e) { | |
return listener.handleEvent(e); | |
}); | |
}; | |
goog.debug.entryPointRegistry.register(function(transformer) { | |
goog.events.handleBrowserEvent_ = transformer(goog.events.handleBrowserEvent_); | |
}); | |
goog.events.EventTarget = function() { | |
goog.Disposable.call(this); | |
this.eventTargetListeners_ = new goog.events.ListenerMap(this); | |
this.actualEventTarget_ = this; | |
}; | |
goog.inherits(goog.events.EventTarget, goog.Disposable); | |
goog.events.Listenable.addImplementation(); | |
goog.events.EventTarget.MAX_ANCESTORS_ = 1E3; | |
goog.events.EventTarget.prototype.parentEventTarget_ = null; | |
var JSCompiler_StaticMethods_getParentEventTarget = function(JSCompiler_StaticMethods_getParentEventTarget$self) { | |
return JSCompiler_StaticMethods_getParentEventTarget$self.parentEventTarget_; | |
}; | |
goog.events.EventTarget.prototype.addEventListener = function(type, handler, opt_capture, opt_handlerScope) { | |
goog.events.listen(this, type, handler, opt_capture, opt_handlerScope); | |
}; | |
goog.events.EventTarget.prototype.removeEventListener = function(type, handler, opt_capture, opt_handlerScope) { | |
goog.events.unlisten(this, type, handler, opt_capture, opt_handlerScope); | |
}; | |
goog.events.EventTarget.prototype.dispatchEvent = function(e) { | |
JSCompiler_StaticMethods_assertInitialized_(this); | |
var ancestorsTree, ancestor = JSCompiler_StaticMethods_getParentEventTarget(this); | |
if (ancestor) { | |
ancestorsTree = []; | |
for (var ancestorCount = 1;ancestor;ancestor = JSCompiler_StaticMethods_getParentEventTarget(ancestor)) { | |
ancestorsTree.push(ancestor), goog.asserts.assert(++ancestorCount < goog.events.EventTarget.MAX_ANCESTORS_, "infinite loop"); | |
} | |
} | |
return goog.events.EventTarget.dispatchEventInternal_(this.actualEventTarget_, e, ancestorsTree); | |
}; | |
goog.events.EventTarget.prototype.disposeInternal = function() { | |
goog.events.EventTarget.superClass_.disposeInternal.call(this); | |
JSCompiler_StaticMethods_removeAllListeners(this); | |
this.parentEventTarget_ = null; | |
}; | |
goog.events.EventTarget.prototype.listen = function(type, listener, opt_useCapture, opt_listenerScope) { | |
JSCompiler_StaticMethods_assertInitialized_(this); | |
return this.eventTargetListeners_.add(String(type), listener, !1, opt_useCapture, opt_listenerScope); | |
}; | |
goog.events.EventTarget.prototype.listenOnce = function(type, listener, opt_useCapture, opt_listenerScope) { | |
return this.eventTargetListeners_.add(String(type), listener, !0, opt_useCapture, opt_listenerScope); | |
}; | |
goog.events.EventTarget.prototype.unlisten = function(type, listener, opt_useCapture, opt_listenerScope) { | |
return this.eventTargetListeners_.remove(String(type), listener, opt_useCapture, opt_listenerScope); | |
}; | |
goog.events.EventTarget.prototype.unlistenByKey = function(key) { | |
return JSCompiler_StaticMethods_removeByKey(this.eventTargetListeners_, key); | |
}; | |
var JSCompiler_StaticMethods_removeAllListeners = function(JSCompiler_StaticMethods_removeAllListeners$self, opt_type) { | |
return JSCompiler_StaticMethods_removeAllListeners$self.eventTargetListeners_ ? JSCompiler_StaticMethods_removeAllListeners$self.eventTargetListeners_.removeAll(opt_type) : 0; | |
}; | |
goog.events.EventTarget.prototype.fireListeners = function(type, capture, eventObject) { | |
var listenerArray = this.eventTargetListeners_.listeners[String(type)]; | |
if (!listenerArray) { | |
return!0; | |
} | |
for (var listenerArray = listenerArray.concat(), rv = !0, i = 0;i < listenerArray.length;++i) { | |
var listener = listenerArray[i]; | |
if (listener && !listener.removed && listener.capture == capture) { | |
var listenerFn = listener.listener, listenerHandler = listener.handler || listener.src; | |
listener.callOnce && this.unlistenByKey(listener); | |
rv = !1 !== listenerFn.call(listenerHandler, eventObject) && rv; | |
} | |
} | |
return rv && !1 != eventObject.returnValue_; | |
}; | |
goog.events.EventTarget.prototype.getListeners = function(type, capture) { | |
return this.eventTargetListeners_.getListeners(String(type), capture); | |
}; | |
goog.events.EventTarget.prototype.getListener = function(type, listener, capture, opt_listenerScope) { | |
return this.eventTargetListeners_.getListener(String(type), listener, capture, opt_listenerScope); | |
}; | |
goog.events.EventTarget.prototype.hasListener = function(opt_type, opt_capture) { | |
return this.eventTargetListeners_.hasListener(goog.isDef(opt_type) ? String(opt_type) : void 0, opt_capture); | |
}; | |
var JSCompiler_StaticMethods_assertInitialized_ = function(JSCompiler_StaticMethods_assertInitialized_$self) { | |
goog.asserts.assert(JSCompiler_StaticMethods_assertInitialized_$self.eventTargetListeners_, "Event target is not initialized. Did you call the superclass (goog.events.EventTarget) constructor?"); | |
}; | |
goog.events.EventTarget.dispatchEventInternal_ = function(target, e, opt_ancestorsTree) { | |
var type = e.type || e; | |
if (goog.isString(e)) { | |
e = new goog.events.Event(e, target); | |
} else { | |
if (e instanceof goog.events.Event) { | |
e.target = e.target || target; | |
} else { | |
var oldEvent = e; | |
e = new goog.events.Event(type, target); | |
goog.object.extend(e, oldEvent); | |
} | |
} | |
var rv = !0, currentTarget; | |
if (opt_ancestorsTree) { | |
for (var i = opt_ancestorsTree.length - 1;!e.propagationStopped_ && 0 <= i;i--) { | |
currentTarget = e.currentTarget = opt_ancestorsTree[i], rv = currentTarget.fireListeners(type, !0, e) && rv; | |
} | |
} | |
e.propagationStopped_ || (currentTarget = e.currentTarget = target, rv = currentTarget.fireListeners(type, !0, e) && rv, e.propagationStopped_ || (rv = currentTarget.fireListeners(type, !1, e) && rv)); | |
if (opt_ancestorsTree) { | |
for (i = 0;!e.propagationStopped_ && i < opt_ancestorsTree.length;i++) { | |
currentTarget = e.currentTarget = opt_ancestorsTree[i], rv = currentTarget.fireListeners(type, !1, e) && rv; | |
} | |
} | |
return rv; | |
}; | |
goog.Timer = function(opt_interval, opt_timerObject) { | |
goog.events.EventTarget.call(this); | |
this.interval_ = opt_interval || 1; | |
this.timerObject_ = opt_timerObject || goog.Timer.defaultTimerObject; | |
this.boundTick_ = goog.bind(this.tick_, this); | |
this.last_ = goog.now(); | |
}; | |
goog.inherits(goog.Timer, goog.events.EventTarget); | |
goog.Timer.MAX_TIMEOUT_ = 2147483647; | |
goog.Timer.prototype.enabled = !1; | |
goog.Timer.defaultTimerObject = goog.global; | |
goog.Timer.intervalScale = .8; | |
goog.Timer.prototype.timer_ = null; | |
goog.Timer.prototype.setInterval = function(interval) { | |
this.interval_ = interval; | |
this.timer_ && this.enabled ? (this.stop(), this.start()) : this.timer_ && this.stop(); | |
}; | |
goog.Timer.prototype.tick_ = function() { | |
if (this.enabled) { | |
var elapsed = goog.now() - this.last_; | |
0 < elapsed && elapsed < this.interval_ * goog.Timer.intervalScale ? this.timer_ = this.timerObject_.setTimeout(this.boundTick_, this.interval_ - elapsed) : (this.timer_ && (this.timerObject_.clearTimeout(this.timer_), this.timer_ = null), JSCompiler_StaticMethods_dispatchTick(this), this.enabled && (this.timer_ = this.timerObject_.setTimeout(this.boundTick_, this.interval_), this.last_ = goog.now())); | |
} | |
}; | |
var JSCompiler_StaticMethods_dispatchTick = function(JSCompiler_StaticMethods_dispatchTick$self) { | |
JSCompiler_StaticMethods_dispatchTick$self.dispatchEvent(goog.Timer.TICK); | |
}; | |
goog.Timer.prototype.start = function() { | |
this.enabled = !0; | |
this.timer_ || (this.timer_ = this.timerObject_.setTimeout(this.boundTick_, this.interval_), this.last_ = goog.now()); | |
}; | |
goog.Timer.prototype.stop = function() { | |
this.enabled = !1; | |
this.timer_ && (this.timerObject_.clearTimeout(this.timer_), this.timer_ = null); | |
}; | |
goog.Timer.prototype.disposeInternal = function() { | |
goog.Timer.superClass_.disposeInternal.call(this); | |
this.stop(); | |
delete this.timerObject_; | |
}; | |
goog.Timer.TICK = "tick"; | |
goog.Timer.callOnce = function(listener, opt_delay, opt_handler) { | |
if (goog.isFunction(listener)) { | |
opt_handler && (listener = goog.bind(listener, opt_handler)); | |
} else { | |
if (listener && "function" == typeof listener.handleEvent) { | |
listener = goog.bind(listener.handleEvent, listener); | |
} else { | |
throw Error("Invalid listener argument"); | |
} | |
} | |
return opt_delay > goog.Timer.MAX_TIMEOUT_ ? -1 : goog.Timer.defaultTimerObject.setTimeout(listener, opt_delay || 0); | |
}; | |
goog.Timer.clear = function(timerId) { | |
goog.Timer.defaultTimerObject.clearTimeout(timerId); | |
}; | |
goog.async = {}; | |
goog.async.Delay = function(listener, opt_interval, opt_handler) { | |
goog.Disposable.call(this); | |
this.listener_ = listener; | |
this.interval_ = opt_interval || 0; | |
this.handler_ = opt_handler; | |
this.callback_ = goog.bind(this.doAction_, this); | |
}; | |
goog.inherits(goog.async.Delay, goog.Disposable); | |
goog.Delay = goog.async.Delay; | |
goog.async.Delay.prototype.id_ = 0; | |
goog.async.Delay.prototype.disposeInternal = function() { | |
goog.async.Delay.superClass_.disposeInternal.call(this); | |
this.stop(); | |
delete this.listener_; | |
delete this.handler_; | |
}; | |
goog.async.Delay.prototype.start = function(opt_interval) { | |
this.stop(); | |
this.id_ = goog.Timer.callOnce(this.callback_, goog.isDef(opt_interval) ? opt_interval : this.interval_); | |
}; | |
goog.async.Delay.prototype.stop = function() { | |
this.isActive() && goog.Timer.clear(this.id_); | |
this.id_ = 0; | |
}; | |
goog.async.Delay.prototype.fire = function() { | |
this.stop(); | |
this.doAction_(); | |
}; | |
goog.async.Delay.prototype.isActive = function() { | |
return 0 != this.id_; | |
}; | |
goog.async.Delay.prototype.doAction_ = function() { | |
this.id_ = 0; | |
this.listener_ && this.listener_.call(this.handler_); | |
}; | |
goog.crypt = {}; | |
goog.crypt.BlockCipher = function() { | |
}; | |
goog.crypt.Aes = function(key) { | |
goog.crypt.Aes.assertKeyArray_(key); | |
this.key_ = key; | |
this.keyLength_ = this.key_.length / 4; | |
this.numberOfRounds_ = this.keyLength_ + 6; | |
this.state_ = [[], [], [], []]; | |
this.temp_ = [[], [], [], []]; | |
JSCompiler_StaticMethods_keyExpansion_(this); | |
}; | |
goog.crypt.Aes.ENABLE_TEST_MODE = !1; | |
goog.crypt.Aes.prototype.encrypt = function(input) { | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testKeySchedule_(0, this.keySchedule_, 0); | |
JSCompiler_StaticMethods_copyInput_(this, input); | |
JSCompiler_StaticMethods_addRoundKey_(this, 0); | |
for (var round = 1;round < this.numberOfRounds_;++round) { | |
goog.crypt.Aes.ENABLE_TEST_MODE && (this.testKeySchedule_(round, this.keySchedule_, round), this.testStartRound_(round, this.state_)), JSCompiler_StaticMethods_subBytes_(this, goog.crypt.Aes.SBOX_), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterSubBytes_(round, this.state_), JSCompiler_StaticMethods_shiftRows_(this), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterShiftRows_(round, this.state_), JSCompiler_StaticMethods_mixColumns_(this), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterMixColumns_(round, | |
this.state_), JSCompiler_StaticMethods_addRoundKey_(this, round); | |
} | |
JSCompiler_StaticMethods_subBytes_(this, goog.crypt.Aes.SBOX_); | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterSubBytes_(round, this.state_); | |
JSCompiler_StaticMethods_shiftRows_(this); | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterShiftRows_(round, this.state_); | |
JSCompiler_StaticMethods_addRoundKey_(this, this.numberOfRounds_); | |
return JSCompiler_StaticMethods_generateOutput_(this); | |
}; | |
goog.crypt.Aes.prototype.decrypt = function(input) { | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testKeySchedule_(0, this.keySchedule_, this.numberOfRounds_); | |
JSCompiler_StaticMethods_copyInput_(this, input); | |
JSCompiler_StaticMethods_addRoundKey_(this, this.numberOfRounds_); | |
for (var round = 1;round < this.numberOfRounds_;++round) { | |
goog.crypt.Aes.ENABLE_TEST_MODE && (this.testKeySchedule_(round, this.keySchedule_, this.numberOfRounds_ - round), this.testStartRound_(round, this.state_)), JSCompiler_StaticMethods_invShiftRows_(this), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterShiftRows_(round, this.state_), JSCompiler_StaticMethods_subBytes_(this, goog.crypt.Aes.INV_SBOX_), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterSubBytes_(round, this.state_), JSCompiler_StaticMethods_addRoundKey_(this, this.numberOfRounds_ - | |
round), goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterAddRoundKey_(round, this.state_), JSCompiler_StaticMethods_invMixColumns_(this); | |
} | |
JSCompiler_StaticMethods_invShiftRows_(this); | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterShiftRows_(round, this.state_); | |
JSCompiler_StaticMethods_subBytes_(this, goog.crypt.Aes.INV_SBOX_); | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testAfterSubBytes_(this.numberOfRounds_, this.state_); | |
goog.crypt.Aes.ENABLE_TEST_MODE && this.testKeySchedule_(this.numberOfRounds_, this.keySchedule_, 0); | |
JSCompiler_StaticMethods_addRoundKey_(this, 0); | |
return JSCompiler_StaticMethods_generateOutput_(this); | |
}; | |
goog.crypt.Aes.BLOCK_SIZE_ = 4; | |
goog.crypt.Aes.assertKeyArray_ = function(arr) { | |
if (goog.asserts.ENABLE_ASSERTS) { | |
goog.asserts.assert(16 == arr.length || 24 == arr.length || 32 == arr.length, "Key must have length 16, 24, or 32."); | |
for (var i = 0;i < arr.length;i++) { | |
goog.asserts.assertNumber(arr[i]), goog.asserts.assert(0 <= arr[i] && 255 >= arr[i]); | |
} | |
} | |
}; | |
goog.crypt.Aes.prototype.testStartRound_ = goog.nullFunction; | |
goog.crypt.Aes.prototype.testAfterSubBytes_ = goog.nullFunction; | |
goog.crypt.Aes.prototype.testAfterShiftRows_ = goog.nullFunction; | |
goog.crypt.Aes.prototype.testAfterMixColumns_ = goog.nullFunction; | |
goog.crypt.Aes.prototype.testAfterAddRoundKey_ = goog.nullFunction; | |
goog.crypt.Aes.prototype.testKeySchedule_ = goog.nullFunction; | |
var JSCompiler_StaticMethods_copyInput_ = function(JSCompiler_StaticMethods_copyInput_$self, input) { | |
var v, p; | |
goog.asserts.assert(input.length == 4 * goog.crypt.Aes.BLOCK_SIZE_, "Expecting input of 4 times block size."); | |
for (var r = 0;r < goog.crypt.Aes.BLOCK_SIZE_;r++) { | |
for (var c = 0;4 > c;c++) { | |
p = 4 * c + r, v = input[p], goog.asserts.assert(255 >= v && 0 <= v, "Invalid input. Value %s at position %s is not a byte.", v, p), JSCompiler_StaticMethods_copyInput_$self.state_[r][c] = v; | |
} | |
} | |
}, JSCompiler_StaticMethods_generateOutput_ = function(JSCompiler_StaticMethods_generateOutput_$self) { | |
for (var output = [], r = 0;r < goog.crypt.Aes.BLOCK_SIZE_;r++) { | |
for (var c = 0;4 > c;c++) { | |
output[4 * c + r] = JSCompiler_StaticMethods_generateOutput_$self.state_[r][c]; | |
} | |
} | |
return output; | |
}, JSCompiler_StaticMethods_addRoundKey_ = function(JSCompiler_StaticMethods_addRoundKey_$self, round) { | |
for (var r = 0;4 > r;r++) { | |
for (var c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_addRoundKey_$self.state_[r][c] ^= JSCompiler_StaticMethods_addRoundKey_$self.keySchedule_[4 * round + c][r]; | |
} | |
} | |
}, JSCompiler_StaticMethods_subBytes_ = function(JSCompiler_StaticMethods_subBytes_$self, box) { | |
for (var r = 0;4 > r;r++) { | |
for (var c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_subBytes_$self.state_[r][c] = box[JSCompiler_StaticMethods_subBytes_$self.state_[r][c]]; | |
} | |
} | |
}, JSCompiler_StaticMethods_shiftRows_ = function(JSCompiler_StaticMethods_shiftRows_$self) { | |
for (var r = 1;4 > r;r++) { | |
for (var c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_shiftRows_$self.temp_[r][c] = JSCompiler_StaticMethods_shiftRows_$self.state_[r][c]; | |
} | |
} | |
for (r = 1;4 > r;r++) { | |
for (c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_shiftRows_$self.state_[r][c] = JSCompiler_StaticMethods_shiftRows_$self.temp_[r][(c + r) % goog.crypt.Aes.BLOCK_SIZE_]; | |
} | |
} | |
}, JSCompiler_StaticMethods_invShiftRows_ = function(JSCompiler_StaticMethods_invShiftRows_$self) { | |
for (var r = 1;4 > r;r++) { | |
for (var c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_invShiftRows_$self.temp_[r][(c + r) % goog.crypt.Aes.BLOCK_SIZE_] = JSCompiler_StaticMethods_invShiftRows_$self.state_[r][c]; | |
} | |
} | |
for (r = 1;4 > r;r++) { | |
for (c = 0;4 > c;c++) { | |
JSCompiler_StaticMethods_invShiftRows_$self.state_[r][c] = JSCompiler_StaticMethods_invShiftRows_$self.temp_[r][c]; | |
} | |
} | |
}, JSCompiler_StaticMethods_mixColumns_ = function(JSCompiler_StaticMethods_mixColumns_$self) { | |
for (var s = JSCompiler_StaticMethods_mixColumns_$self.state_, t = JSCompiler_StaticMethods_mixColumns_$self.temp_[0], c = 0;4 > c;c++) { | |
t[0] = s[0][c], t[1] = s[1][c], t[2] = s[2][c], t[3] = s[3][c], s[0][c] = goog.crypt.Aes.MULT_2_[t[0]] ^ goog.crypt.Aes.MULT_3_[t[1]] ^ t[2] ^ t[3], s[1][c] = t[0] ^ goog.crypt.Aes.MULT_2_[t[1]] ^ goog.crypt.Aes.MULT_3_[t[2]] ^ t[3], s[2][c] = t[0] ^ t[1] ^ goog.crypt.Aes.MULT_2_[t[2]] ^ goog.crypt.Aes.MULT_3_[t[3]], s[3][c] = goog.crypt.Aes.MULT_3_[t[0]] ^ t[1] ^ t[2] ^ goog.crypt.Aes.MULT_2_[t[3]]; | |
} | |
}, JSCompiler_StaticMethods_invMixColumns_ = function(JSCompiler_StaticMethods_invMixColumns_$self) { | |
for (var s = JSCompiler_StaticMethods_invMixColumns_$self.state_, t = JSCompiler_StaticMethods_invMixColumns_$self.temp_[0], c = 0;4 > c;c++) { | |
t[0] = s[0][c], t[1] = s[1][c], t[2] = s[2][c], t[3] = s[3][c], s[0][c] = goog.crypt.Aes.MULT_E_[t[0]] ^ goog.crypt.Aes.MULT_B_[t[1]] ^ goog.crypt.Aes.MULT_D_[t[2]] ^ goog.crypt.Aes.MULT_9_[t[3]], s[1][c] = goog.crypt.Aes.MULT_9_[t[0]] ^ goog.crypt.Aes.MULT_E_[t[1]] ^ goog.crypt.Aes.MULT_B_[t[2]] ^ goog.crypt.Aes.MULT_D_[t[3]], s[2][c] = goog.crypt.Aes.MULT_D_[t[0]] ^ goog.crypt.Aes.MULT_9_[t[1]] ^ goog.crypt.Aes.MULT_E_[t[2]] ^ goog.crypt.Aes.MULT_B_[t[3]], s[3][c] = goog.crypt.Aes.MULT_B_[t[0]] ^ | |
goog.crypt.Aes.MULT_D_[t[1]] ^ goog.crypt.Aes.MULT_9_[t[2]] ^ goog.crypt.Aes.MULT_E_[t[3]]; | |
} | |
}, JSCompiler_StaticMethods_keyExpansion_ = function(JSCompiler_StaticMethods_keyExpansion_$self) { | |
JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_ = Array(goog.crypt.Aes.BLOCK_SIZE_ * (JSCompiler_StaticMethods_keyExpansion_$self.numberOfRounds_ + 1)); | |
for (var rowNum = 0;rowNum < JSCompiler_StaticMethods_keyExpansion_$self.keyLength_;rowNum++) { | |
JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum] = [JSCompiler_StaticMethods_keyExpansion_$self.key_[4 * rowNum], JSCompiler_StaticMethods_keyExpansion_$self.key_[4 * rowNum + 1], JSCompiler_StaticMethods_keyExpansion_$self.key_[4 * rowNum + 2], JSCompiler_StaticMethods_keyExpansion_$self.key_[4 * rowNum + 3]]; | |
} | |
for (var temp = Array(4), rowNum = JSCompiler_StaticMethods_keyExpansion_$self.keyLength_;rowNum < goog.crypt.Aes.BLOCK_SIZE_ * (JSCompiler_StaticMethods_keyExpansion_$self.numberOfRounds_ + 1);rowNum++) { | |
temp[0] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - 1][0], temp[1] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - 1][1], temp[2] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - 1][2], temp[3] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - 1][3], 0 == rowNum % JSCompiler_StaticMethods_keyExpansion_$self.keyLength_ ? (JSCompiler_StaticMethods_rotWord_(temp), JSCompiler_StaticMethods_subWord_(temp), temp[0] ^= | |
goog.crypt.Aes.RCON_[rowNum / JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][0], temp[1] ^= goog.crypt.Aes.RCON_[rowNum / JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][1], temp[2] ^= goog.crypt.Aes.RCON_[rowNum / JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][2], temp[3] ^= goog.crypt.Aes.RCON_[rowNum / JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][3]) : 6 < JSCompiler_StaticMethods_keyExpansion_$self.keyLength_ && 4 == rowNum % JSCompiler_StaticMethods_keyExpansion_$self.keyLength_ && | |
JSCompiler_StaticMethods_subWord_(temp), JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum] = Array(4), JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum][0] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][0] ^ temp[0], JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum][1] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][1] ^ | |
temp[1], JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum][2] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][2] ^ temp[2], JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum][3] = JSCompiler_StaticMethods_keyExpansion_$self.keySchedule_[rowNum - JSCompiler_StaticMethods_keyExpansion_$self.keyLength_][3] ^ temp[3]; | |
} | |
}, JSCompiler_StaticMethods_subWord_ = function(w) { | |
w[0] = goog.crypt.Aes.SBOX_[w[0]]; | |
w[1] = goog.crypt.Aes.SBOX_[w[1]]; | |
w[2] = goog.crypt.Aes.SBOX_[w[2]]; | |
w[3] = goog.crypt.Aes.SBOX_[w[3]]; | |
}, JSCompiler_StaticMethods_rotWord_ = function(w) { | |
var temp = w[0]; | |
w[0] = w[1]; | |
w[1] = w[2]; | |
w[2] = w[3]; | |
w[3] = temp; | |
}; | |
goog.crypt.Aes.SBOX_ = [99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, | |
249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, | |
14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22]; | |
goog.crypt.Aes.INV_SBOX_ = [82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, | |
10, 247, 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, | |
74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125]; | |
goog.crypt.Aes.RCON_ = [[0, 0, 0, 0], [1, 0, 0, 0], [2, 0, 0, 0], [4, 0, 0, 0], [8, 0, 0, 0], [16, 0, 0, 0], [32, 0, 0, 0], [64, 0, 0, 0], [128, 0, 0, 0], [27, 0, 0, 0], [54, 0, 0, 0]]; | |
goog.crypt.Aes.MULT_2_ = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, | |
212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 27, 25, 31, 29, 19, 17, 23, 21, 11, 9, 15, 13, 3, 1, 7, 5, 59, 57, 63, 61, 51, 49, 55, 53, 43, 41, 47, 45, 35, 33, 39, 37, 91, 89, 95, 93, 83, 81, 87, 85, 75, 73, 79, 77, 67, 65, 71, 69, 123, 121, 127, 125, 115, 113, 119, 117, 107, 105, 111, 109, 99, 97, 103, 101, 155, 153, 159, 157, 147, 145, 151, 149, 139, 137, 143, 141, 131, 129, 135, 133, 187, 185, 191, 189, 179, 177, 183, 181, 171, 169, | |
175, 173, 163, 161, 167, 165, 219, 217, 223, 221, 211, 209, 215, 213, 203, 201, 207, 205, 195, 193, 199, 197, 251, 249, 255, 253, 243, 241, 247, 245, 235, 233, 239, 237, 227, 225, 231, 229]; | |
goog.crypt.Aes.MULT_3_ = [0, 3, 6, 5, 12, 15, 10, 9, 24, 27, 30, 29, 20, 23, 18, 17, 48, 51, 54, 53, 60, 63, 58, 57, 40, 43, 46, 45, 36, 39, 34, 33, 96, 99, 102, 101, 108, 111, 106, 105, 120, 123, 126, 125, 116, 119, 114, 113, 80, 83, 86, 85, 92, 95, 90, 89, 72, 75, 78, 77, 68, 71, 66, 65, 192, 195, 198, 197, 204, 207, 202, 201, 216, 219, 222, 221, 212, 215, 210, 209, 240, 243, 246, 245, 252, 255, 250, 249, 232, 235, 238, 237, 228, 231, 226, 225, 160, 163, 166, 165, 172, 175, 170, 169, 184, 187, | |
190, 189, 180, 183, 178, 177, 144, 147, 150, 149, 156, 159, 154, 153, 136, 139, 142, 141, 132, 135, 130, 129, 155, 152, 157, 158, 151, 148, 145, 146, 131, 128, 133, 134, 143, 140, 137, 138, 171, 168, 173, 174, 167, 164, 161, 162, 179, 176, 181, 182, 191, 188, 185, 186, 251, 248, 253, 254, 247, 244, 241, 242, 227, 224, 229, 230, 239, 236, 233, 234, 203, 200, 205, 206, 199, 196, 193, 194, 211, 208, 213, 214, 223, 220, 217, 218, 91, 88, 93, 94, 87, 84, 81, 82, 67, 64, 69, 70, 79, 76, 73, 74, 107, 104, | |
109, 110, 103, 100, 97, 98, 115, 112, 117, 118, 127, 124, 121, 122, 59, 56, 61, 62, 55, 52, 49, 50, 35, 32, 37, 38, 47, 44, 41, 42, 11, 8, 13, 14, 7, 4, 1, 2, 19, 16, 21, 22, 31, 28, 25, 26]; | |
goog.crypt.Aes.MULT_9_ = [0, 9, 18, 27, 36, 45, 54, 63, 72, 65, 90, 83, 108, 101, 126, 119, 144, 153, 130, 139, 180, 189, 166, 175, 216, 209, 202, 195, 252, 245, 238, 231, 59, 50, 41, 32, 31, 22, 13, 4, 115, 122, 97, 104, 87, 94, 69, 76, 171, 162, 185, 176, 143, 134, 157, 148, 227, 234, 241, 248, 199, 206, 213, 220, 118, 127, 100, 109, 82, 91, 64, 73, 62, 55, 44, 37, 26, 19, 8, 1, 230, 239, 244, 253, 194, 203, 208, 217, 174, 167, 188, 181, 138, 131, 152, 145, 77, 68, 95, 86, 105, 96, 123, 114, 5, | |
12, 23, 30, 33, 40, 51, 58, 221, 212, 207, 198, 249, 240, 235, 226, 149, 156, 135, 142, 177, 184, 163, 170, 236, 229, 254, 247, 200, 193, 218, 211, 164, 173, 182, 191, 128, 137, 146, 155, 124, 117, 110, 103, 88, 81, 74, 67, 52, 61, 38, 47, 16, 25, 2, 11, 215, 222, 197, 204, 243, 250, 225, 232, 159, 150, 141, 132, 187, 178, 169, 160, 71, 78, 85, 92, 99, 106, 113, 120, 15, 6, 29, 20, 43, 34, 57, 48, 154, 147, 136, 129, 190, 183, 172, 165, 210, 219, 192, 201, 246, 255, 228, 237, 10, 3, 24, 17, 46, 39, | |
60, 53, 66, 75, 80, 89, 102, 111, 116, 125, 161, 168, 179, 186, 133, 140, 151, 158, 233, 224, 251, 242, 205, 196, 223, 214, 49, 56, 35, 42, 21, 28, 7, 14, 121, 112, 107, 98, 93, 84, 79, 70]; | |
goog.crypt.Aes.MULT_B_ = [0, 11, 22, 29, 44, 39, 58, 49, 88, 83, 78, 69, 116, 127, 98, 105, 176, 187, 166, 173, 156, 151, 138, 129, 232, 227, 254, 245, 196, 207, 210, 217, 123, 112, 109, 102, 87, 92, 65, 74, 35, 40, 53, 62, 15, 4, 25, 18, 203, 192, 221, 214, 231, 236, 241, 250, 147, 152, 133, 142, 191, 180, 169, 162, 246, 253, 224, 235, 218, 209, 204, 199, 174, 165, 184, 179, 130, 137, 148, 159, 70, 77, 80, 91, 106, 97, 124, 119, 30, 21, 8, 3, 50, 57, 36, 47, 141, 134, 155, 144, 161, 170, 183, 188, | |
213, 222, 195, 200, 249, 242, 239, 228, 61, 54, 43, 32, 17, 26, 7, 12, 101, 110, 115, 120, 73, 66, 95, 84, 247, 252, 225, 234, 219, 208, 205, 198, 175, 164, 185, 178, 131, 136, 149, 158, 71, 76, 81, 90, 107, 96, 125, 118, 31, 20, 9, 2, 51, 56, 37, 46, 140, 135, 154, 145, 160, 171, 182, 189, 212, 223, 194, 201, 248, 243, 238, 229, 60, 55, 42, 33, 16, 27, 6, 13, 100, 111, 114, 121, 72, 67, 94, 85, 1, 10, 23, 28, 45, 38, 59, 48, 89, 82, 79, 68, 117, 126, 99, 104, 177, 186, 167, 172, 157, 150, 139, 128, | |
233, 226, 255, 244, 197, 206, 211, 216, 122, 113, 108, 103, 86, 93, 64, 75, 34, 41, 52, 63, 14, 5, 24, 19, 202, 193, 220, 215, 230, 237, 240, 251, 146, 153, 132, 143, 190, 181, 168, 163]; | |
goog.crypt.Aes.MULT_D_ = [0, 13, 26, 23, 52, 57, 46, 35, 104, 101, 114, 127, 92, 81, 70, 75, 208, 221, 202, 199, 228, 233, 254, 243, 184, 181, 162, 175, 140, 129, 150, 155, 187, 182, 161, 172, 143, 130, 149, 152, 211, 222, 201, 196, 231, 234, 253, 240, 107, 102, 113, 124, 95, 82, 69, 72, 3, 14, 25, 20, 55, 58, 45, 32, 109, 96, 119, 122, 89, 84, 67, 78, 5, 8, 31, 18, 49, 60, 43, 38, 189, 176, 167, 170, 137, 132, 147, 158, 213, 216, 207, 194, 225, 236, 251, 246, 214, 219, 204, 193, 226, 239, 248, 245, | |
190, 179, 164, 169, 138, 135, 144, 157, 6, 11, 28, 17, 50, 63, 40, 37, 110, 99, 116, 121, 90, 87, 64, 77, 218, 215, 192, 205, 238, 227, 244, 249, 178, 191, 168, 165, 134, 139, 156, 145, 10, 7, 16, 29, 62, 51, 36, 41, 98, 111, 120, 117, 86, 91, 76, 65, 97, 108, 123, 118, 85, 88, 79, 66, 9, 4, 19, 30, 61, 48, 39, 42, 177, 188, 171, 166, 133, 136, 159, 146, 217, 212, 195, 206, 237, 224, 247, 250, 183, 186, 173, 160, 131, 142, 153, 148, 223, 210, 197, 200, 235, 230, 241, 252, 103, 106, 125, 112, 83, | |
94, 73, 68, 15, 2, 21, 24, 59, 54, 33, 44, 12, 1, 22, 27, 56, 53, 34, 47, 100, 105, 126, 115, 80, 93, 74, 71, 220, 209, 198, 203, 232, 229, 242, 255, 180, 185, 174, 163, 128, 141, 154, 151]; | |
goog.crypt.Aes.MULT_E_ = [0, 14, 28, 18, 56, 54, 36, 42, 112, 126, 108, 98, 72, 70, 84, 90, 224, 238, 252, 242, 216, 214, 196, 202, 144, 158, 140, 130, 168, 166, 180, 186, 219, 213, 199, 201, 227, 237, 255, 241, 171, 165, 183, 185, 147, 157, 143, 129, 59, 53, 39, 41, 3, 13, 31, 17, 75, 69, 87, 89, 115, 125, 111, 97, 173, 163, 177, 191, 149, 155, 137, 135, 221, 211, 193, 207, 229, 235, 249, 247, 77, 67, 81, 95, 117, 123, 105, 103, 61, 51, 33, 47, 5, 11, 25, 23, 118, 120, 106, 100, 78, 64, 82, 92, | |
6, 8, 26, 20, 62, 48, 34, 44, 150, 152, 138, 132, 174, 160, 178, 188, 230, 232, 250, 244, 222, 208, 194, 204, 65, 79, 93, 83, 121, 119, 101, 107, 49, 63, 45, 35, 9, 7, 21, 27, 161, 175, 189, 179, 153, 151, 133, 139, 209, 223, 205, 195, 233, 231, 245, 251, 154, 148, 134, 136, 162, 172, 190, 176, 234, 228, 246, 248, 210, 220, 206, 192, 122, 116, 102, 104, 66, 76, 94, 80, 10, 4, 22, 24, 50, 60, 46, 32, 236, 226, 240, 254, 212, 218, 200, 198, 156, 146, 128, 142, 164, 170, 184, 182, 12, 2, 16, 30, 52, | |
58, 40, 38, 124, 114, 96, 110, 68, 74, 88, 86, 55, 57, 43, 37, 15, 1, 19, 29, 71, 73, 91, 85, 127, 113, 99, 109, 215, 217, 203, 197, 239, 225, 243, 253, 167, 169, 187, 181, 159, 145, 131, 141]; | |
goog.crypt.stringToByteArray = function(str) { | |
for (var output = [], p = 0, i = 0;i < str.length;i++) { | |
for (var c = str.charCodeAt(i);255 < c;) { | |
output[p++] = c & 255, c >>= 8; | |
} | |
output[p++] = c; | |
} | |
return output; | |
}; | |
goog.crypt.byteArrayToString = function(bytes) { | |
if (8192 > bytes.length) { | |
return String.fromCharCode.apply(null, bytes); | |
} | |
for (var str = "", i = 0;i < bytes.length;i += 8192) { | |
var chunk = goog.array.slice(bytes, i, i + 8192), str = str + String.fromCharCode.apply(null, chunk) | |
} | |
return str; | |
}; | |
goog.crypt.byteArrayToHex = function(array) { | |
return goog.array.map(array, function(numByte) { | |
var hexByte = numByte.toString(16); | |
return 1 < hexByte.length ? hexByte : "0" + hexByte; | |
}).join(""); | |
}; | |
goog.crypt.hexToByteArray = function(hexString) { | |
goog.asserts.assert(0 == hexString.length % 2, "Key string length must be multiple of 2"); | |
for (var arr = [], i = 0;i < hexString.length;i += 2) { | |
arr.push(parseInt(hexString.substring(i, i + 2), 16)); | |
} | |
return arr; | |
}; | |
goog.crypt.stringToUtf8ByteArray = function(str) { | |
str = str.replace(/\r\n/g, "\n"); | |
for (var out = [], p = 0, i = 0;i < str.length;i++) { | |
var c = str.charCodeAt(i); | |
128 > c ? out[p++] = c : (2048 > c ? out[p++] = c >> 6 | 192 : (out[p++] = c >> 12 | 224, out[p++] = c >> 6 & 63 | 128), out[p++] = c & 63 | 128); | |
} | |
return out; | |
}; | |
goog.crypt.utf8ByteArrayToString = function(bytes) { | |
for (var out = [], pos = 0, c = 0;pos < bytes.length;) { | |
var c1 = bytes[pos++]; | |
if (128 > c1) { | |
out[c++] = String.fromCharCode(c1); | |
} else { | |
if (191 < c1 && 224 > c1) { | |
var c2 = bytes[pos++]; | |
out[c++] = String.fromCharCode((c1 & 31) << 6 | c2 & 63); | |
} else { | |
var c2 = bytes[pos++], c3 = bytes[pos++]; | |
out[c++] = String.fromCharCode((c1 & 15) << 12 | (c2 & 63) << 6 | c3 & 63); | |
} | |
} | |
} | |
return out.join(""); | |
}; | |
goog.crypt.xorByteArray = function(bytes1, bytes2) { | |
goog.asserts.assert(bytes1.length == bytes2.length, "XOR array lengths must match"); | |
for (var result = [], i = 0;i < bytes1.length;i++) { | |
result.push(bytes1[i] ^ bytes2[i]); | |
} | |
return result; | |
}; | |
goog.crypt.base64 = {}; | |
goog.crypt.base64.byteToCharMap_ = null; | |
goog.crypt.base64.charToByteMap_ = null; | |
goog.crypt.base64.byteToCharMapWebSafe_ = null; | |
goog.crypt.base64.charToByteMapWebSafe_ = null; | |
goog.crypt.base64.ENCODED_VALS_BASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; | |
goog.crypt.base64.ENCODED_VALS = goog.crypt.base64.ENCODED_VALS_BASE + "+/="; | |
goog.crypt.base64.ENCODED_VALS_WEBSAFE = goog.crypt.base64.ENCODED_VALS_BASE + "-_."; | |
goog.crypt.base64.HAS_NATIVE_SUPPORT = goog.userAgent.GECKO || goog.userAgent.WEBKIT || goog.userAgent.OPERA || "function" == typeof goog.global.atob; | |
goog.crypt.base64.encodeByteArray = function(input, opt_webSafe) { | |
if (!goog.isArrayLike(input)) { | |
throw Error("encodeByteArray takes an array as a parameter"); | |
} | |
goog.crypt.base64.init_(); | |
for (var byteToCharMap = opt_webSafe ? goog.crypt.base64.byteToCharMapWebSafe_ : goog.crypt.base64.byteToCharMap_, output = [], i = 0;i < input.length;i += 3) { | |
var byte1 = input[i], haveByte2 = i + 1 < input.length, byte2 = haveByte2 ? input[i + 1] : 0, haveByte3 = i + 2 < input.length, byte3 = haveByte3 ? input[i + 2] : 0, outByte1 = byte1 >> 2, outByte2 = (byte1 & 3) << 4 | byte2 >> 4, outByte3 = (byte2 & 15) << 2 | byte3 >> 6, outByte4 = byte3 & 63; | |
haveByte3 || (outByte4 = 64, haveByte2 || (outByte3 = 64)); | |
output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]); | |
} | |
return output.join(""); | |
}; | |
goog.crypt.base64.encodeString = function(input, opt_webSafe) { | |
return goog.crypt.base64.HAS_NATIVE_SUPPORT && !opt_webSafe ? goog.global.btoa(input) : goog.crypt.base64.encodeByteArray(goog.crypt.stringToByteArray(input), opt_webSafe); | |
}; | |
goog.crypt.base64.decodeString = function(input, opt_webSafe) { | |
return goog.crypt.base64.HAS_NATIVE_SUPPORT && !opt_webSafe ? goog.global.atob(input) : goog.crypt.byteArrayToString(goog.crypt.base64.decodeStringToByteArray(input, opt_webSafe)); | |
}; | |
goog.crypt.base64.decodeStringToByteArray = function(input, opt_webSafe) { | |
goog.crypt.base64.init_(); | |
for (var charToByteMap = opt_webSafe ? goog.crypt.base64.charToByteMapWebSafe_ : goog.crypt.base64.charToByteMap_, output = [], i = 0;i < input.length;) { | |
var byte1 = charToByteMap[input.charAt(i++)], byte2 = i < input.length ? charToByteMap[input.charAt(i)] : 0; | |
++i; | |
var byte3 = i < input.length ? charToByteMap[input.charAt(i)] : 64; | |
++i; | |
var byte4 = i < input.length ? charToByteMap[input.charAt(i)] : 64; | |
++i; | |
if (null == byte1 || null == byte2 || null == byte3 || null == byte4) { | |
throw Error(); | |
} | |
output.push(byte1 << 2 | byte2 >> 4); | |
64 != byte3 && (output.push(byte2 << 4 & 240 | byte3 >> 2), 64 != byte4 && output.push(byte3 << 6 & 192 | byte4)); | |
} | |
return output; | |
}; | |
goog.crypt.base64.init_ = function() { | |
if (!goog.crypt.base64.byteToCharMap_) { | |
goog.crypt.base64.byteToCharMap_ = {}; | |
goog.crypt.base64.charToByteMap_ = {}; | |
goog.crypt.base64.byteToCharMapWebSafe_ = {}; | |
goog.crypt.base64.charToByteMapWebSafe_ = {}; | |
for (var i = 0;i < goog.crypt.base64.ENCODED_VALS.length;i++) { | |
goog.crypt.base64.byteToCharMap_[i] = goog.crypt.base64.ENCODED_VALS.charAt(i), goog.crypt.base64.charToByteMap_[goog.crypt.base64.byteToCharMap_[i]] = i, goog.crypt.base64.byteToCharMapWebSafe_[i] = goog.crypt.base64.ENCODED_VALS_WEBSAFE.charAt(i), goog.crypt.base64.charToByteMapWebSafe_[goog.crypt.base64.byteToCharMapWebSafe_[i]] = i; | |
} | |
} | |
}; | |
goog.crypt.Cbc = function(cipher, opt_blockSize) { | |
this.cipher_ = cipher; | |
this.blockSize_ = opt_blockSize || 16; | |
}; | |
goog.crypt.Cbc.prototype.encrypt = function(plainText, initialVector) { | |
goog.asserts.assert(0 == plainText.length % this.blockSize_, "Data's length must be multiple of block size."); | |
goog.asserts.assert(initialVector.length == this.blockSize_, "Initial vector must be size of one block."); | |
for (var cipherText = [], vector = initialVector, blockStartIndex = 0;blockStartIndex < plainText.length;blockStartIndex += this.blockSize_) { | |
var plainTextBlock = goog.array.slice(plainText, blockStartIndex, blockStartIndex + this.blockSize_), input = goog.crypt.xorByteArray(plainTextBlock, vector), resultBlock = this.cipher_.encrypt(input); | |
goog.array.extend(cipherText, resultBlock); | |
vector = resultBlock; | |
} | |
return cipherText; | |
}; | |
goog.crypt.Cbc.prototype.decrypt = function(cipherText, initialVector) { | |
goog.asserts.assert(0 == cipherText.length % this.blockSize_, "Data's length must be multiple of block size."); | |
goog.asserts.assert(initialVector.length == this.blockSize_, "Initial vector must be size of one block."); | |
for (var plainText = [], blockStartIndex = 0, vector = initialVector;blockStartIndex < cipherText.length;) { | |
var cipherTextBlock = goog.array.slice(cipherText, blockStartIndex, blockStartIndex + this.blockSize_), resultBlock = this.cipher_.decrypt(cipherTextBlock), plainTextBlock = goog.crypt.xorByteArray(vector, resultBlock); | |
goog.array.extend(plainText, plainTextBlock); | |
vector = cipherTextBlock; | |
blockStartIndex += this.blockSize_; | |
} | |
return plainText; | |
}; | |
goog.json = {}; | |
goog.json.USE_NATIVE_JSON = !1; | |
goog.json.isValid_ = function(s) { | |
return/^\s*$/.test(s) ? !1 : /^[\],:{}\s\u2028\u2029]*$/.test(s.replace(/\\["\\\/bfnrtu]/g, "@").replace(/"[^"\\\n\r\u2028\u2029\x00-\x08\x0a-\x1f]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:[\s\u2028\u2029]*\[)+/g, "")); | |
}; | |
goog.json.parse = goog.json.USE_NATIVE_JSON ? goog.global.JSON.parse : function(s) { | |
var o = String(s); | |
if (goog.json.isValid_(o)) { | |
try { | |
return eval("(" + o + ")"); | |
} catch (ex) { | |
} | |
} | |
throw Error("Invalid JSON string: " + o); | |
}; | |
goog.json.unsafeParse = goog.json.USE_NATIVE_JSON ? goog.global.JSON.parse : function(s) { | |
return eval("(" + s + ")"); | |
}; | |
goog.json.serialize = goog.json.USE_NATIVE_JSON ? goog.global.JSON.stringify : function(object, opt_replacer) { | |
return(new goog.json.Serializer(opt_replacer)).serialize(object); | |
}; | |
goog.json.Serializer = function(opt_replacer) { | |
this.replacer_ = opt_replacer; | |
}; | |
goog.json.Serializer.prototype.serialize = function(object) { | |
var sb = []; | |
JSCompiler_StaticMethods_serializeInternal(this, object, sb); | |
return sb.join(""); | |
}; | |
var JSCompiler_StaticMethods_serializeInternal = function(JSCompiler_StaticMethods_serializeInternal$self, object, sb) { | |
switch(typeof object) { | |
case "string": | |
JSCompiler_StaticMethods_serializeString_(object, sb); | |
break; | |
case "number": | |
JSCompiler_StaticMethods_serializeNumber_(object, sb); | |
break; | |
case "boolean": | |
sb.push(object); | |
break; | |
case "undefined": | |
sb.push("null"); | |
break; | |
case "object": | |
if (null == object) { | |
sb.push("null"); | |
break; | |
} | |
if (goog.isArray(object)) { | |
JSCompiler_StaticMethods_serializeArray(JSCompiler_StaticMethods_serializeInternal$self, object, sb); | |
break; | |
} | |
JSCompiler_StaticMethods_serializeObject_(JSCompiler_StaticMethods_serializeInternal$self, object, sb); | |
break; | |
case "function": | |
break; | |
default: | |
throw Error("Unknown type: " + typeof object);; | |
} | |
}; | |
goog.json.Serializer.charToJsonCharCache_ = {'"':'\\"', "\\":"\\\\", "/":"\\/", "\b":"\\b", "\f":"\\f", "\n":"\\n", "\r":"\\r", "\t":"\\t", "\x0B":"\\u000b"}; | |
goog.json.Serializer.charsToReplace_ = /\uffff/.test("\uffff") ? /[\\\"\x00-\x1f\x7f-\uffff]/g : /[\\\"\x00-\x1f\x7f-\xff]/g; | |
var JSCompiler_StaticMethods_serializeString_ = function(s, sb) { | |
sb.push('"', s.replace(goog.json.Serializer.charsToReplace_, function(c) { | |
if (c in goog.json.Serializer.charToJsonCharCache_) { | |
return goog.json.Serializer.charToJsonCharCache_[c]; | |
} | |
var cc = c.charCodeAt(0), rv = "\\u"; | |
16 > cc ? rv += "000" : 256 > cc ? rv += "00" : 4096 > cc && (rv += "0"); | |
return goog.json.Serializer.charToJsonCharCache_[c] = rv + cc.toString(16); | |
}), '"'); | |
}, JSCompiler_StaticMethods_serializeNumber_ = function(n, sb) { | |
sb.push(isFinite(n) && !isNaN(n) ? n : "null"); | |
}, JSCompiler_StaticMethods_serializeArray = function(JSCompiler_StaticMethods_serializeArray$self, arr, sb) { | |
var l = arr.length; | |
sb.push("["); | |
for (var sep = "", i = 0;i < l;i++) { | |
sb.push(sep); | |
var value = arr[i]; | |
JSCompiler_StaticMethods_serializeInternal(JSCompiler_StaticMethods_serializeArray$self, JSCompiler_StaticMethods_serializeArray$self.replacer_ ? JSCompiler_StaticMethods_serializeArray$self.replacer_.call(arr, String(i), value) : value, sb); | |
sep = ","; | |
} | |
sb.push("]"); | |
}, JSCompiler_StaticMethods_serializeObject_ = function(JSCompiler_StaticMethods_serializeObject_$self, obj, sb) { | |
sb.push("{"); | |
var sep = "", key; | |
for (key in obj) { | |
if (Object.prototype.hasOwnProperty.call(obj, key)) { | |
var value = obj[key]; | |
"function" != typeof value && (sb.push(sep), JSCompiler_StaticMethods_serializeString_(key, sb), sb.push(":"), JSCompiler_StaticMethods_serializeInternal(JSCompiler_StaticMethods_serializeObject_$self, JSCompiler_StaticMethods_serializeObject_$self.replacer_ ? JSCompiler_StaticMethods_serializeObject_$self.replacer_.call(obj, key, value) : value, sb), sep = ","); | |
} | |
} | |
sb.push("}"); | |
}; | |
goog.structs = {}; | |
goog.structs.Collection = function() { | |
}; | |
goog.functions = {}; | |
goog.functions.constant = function(retValue) { | |
return function() { | |
return retValue; | |
}; | |
}; | |
goog.functions.FALSE = goog.functions.constant(!1); | |
goog.functions.TRUE = goog.functions.constant(!0); | |
goog.functions.NULL = goog.functions.constant(null); | |
goog.functions.identity = function(opt_returnValue) { | |
return opt_returnValue; | |
}; | |
goog.functions.error = function(message) { | |
return function() { | |
throw Error(message); | |
}; | |
}; | |
goog.functions.fail = function(err) { | |
return function() { | |
throw err; | |
}; | |
}; | |
goog.functions.lock = function(f, opt_numArgs) { | |
opt_numArgs = opt_numArgs || 0; | |
return function() { | |
return f.apply(this, Array.prototype.slice.call(arguments, 0, opt_numArgs)); | |
}; | |
}; | |
goog.functions.nth = function(n) { | |
return function() { | |
return arguments[n]; | |
}; | |
}; | |
goog.functions.withReturnValue = function(f, retValue) { | |
return goog.functions.sequence(f, goog.functions.constant(retValue)); | |
}; | |
goog.functions.compose = function(fn, var_args) { | |
var functions = arguments, length = functions.length; | |
return function() { | |
var result; | |
length && (result = functions[length - 1].apply(this, arguments)); | |
for (var i = length - 2;0 <= i;i--) { | |
result = functions[i].call(this, result); | |
} | |
return result; | |
}; | |
}; | |
goog.functions.sequence = function(var_args) { | |
var functions = arguments, length = functions.length; | |
return function() { | |
for (var result, i = 0;i < length;i++) { | |
result = functions[i].apply(this, arguments); | |
} | |
return result; | |
}; | |
}; | |
goog.functions.and = function(var_args) { | |
var functions = arguments, length = functions.length; | |
return function() { | |
for (var i = 0;i < length;i++) { | |
if (!functions[i].apply(this, arguments)) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
}; | |
goog.functions.or = function(var_args) { | |
var functions = arguments, length = functions.length; | |
return function() { | |
for (var i = 0;i < length;i++) { | |
if (functions[i].apply(this, arguments)) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
}; | |
goog.functions.not = function(f) { | |
return function() { | |
return!f.apply(this, arguments); | |
}; | |
}; | |
goog.functions.create = function(constructor, var_args) { | |
var temp = function() { | |
}; | |
temp.prototype = constructor.prototype; | |
var obj = new temp; | |
constructor.apply(obj, Array.prototype.slice.call(arguments, 1)); | |
return obj; | |
}; | |
goog.functions.CACHE_RETURN_VALUE = !0; | |
goog.functions.cacheReturnValue = function(fn) { | |
var called = !1, value; | |
return function() { | |
if (!goog.functions.CACHE_RETURN_VALUE) { | |
return fn(); | |
} | |
called || (value = fn(), called = !0); | |
return value; | |
}; | |
}; | |
goog.math = {}; | |
goog.math.randomInt = function(a) { | |
return Math.floor(Math.random() * a); | |
}; | |
goog.math.uniformRandom = function(a, b) { | |
return a + Math.random() * (b - a); | |
}; | |
goog.math.clamp = function(value, min, max) { | |
return Math.min(Math.max(value, min), max); | |
}; | |
goog.math.modulo = function(a, b) { | |
var r = a % b; | |
return 0 > r * b ? r + b : r; | |
}; | |
goog.math.lerp = function(a, b, x) { | |
return a + x * (b - a); | |
}; | |
goog.math.nearlyEquals = function(a, b, opt_tolerance) { | |
return Math.abs(a - b) <= (opt_tolerance || 1E-6); | |
}; | |
goog.math.standardAngle = function(angle) { | |
return goog.math.modulo(angle, 360); | |
}; | |
goog.math.standardAngleInRadians = function(angle) { | |
return goog.math.modulo(angle, 2 * Math.PI); | |
}; | |
goog.math.toRadians = function(angleDegrees) { | |
return angleDegrees * Math.PI / 180; | |
}; | |
goog.math.toDegrees = function(angleRadians) { | |
return 180 * angleRadians / Math.PI; | |
}; | |
goog.math.angleDx = function(degrees, radius) { | |
return radius * Math.cos(goog.math.toRadians(degrees)); | |
}; | |
goog.math.angleDy = function(degrees, radius) { | |
return radius * Math.sin(goog.math.toRadians(degrees)); | |
}; | |
goog.math.angle = function(x1, y1, x2, y2) { | |
return goog.math.standardAngle(goog.math.toDegrees(Math.atan2(y2 - y1, x2 - x1))); | |
}; | |
goog.math.angleDifference = function(startAngle, endAngle) { | |
var d = goog.math.standardAngle(endAngle) - goog.math.standardAngle(startAngle); | |
180 < d ? d -= 360 : -180 >= d && (d = 360 + d); | |
return d; | |
}; | |
goog.math.sign = function(x) { | |
return 0 == x ? 0 : 0 > x ? -1 : 1; | |
}; | |
goog.math.longestCommonSubsequence = function(array1, array2, opt_compareFn, opt_collectorFn) { | |
for (var compare = opt_compareFn || function(a, b) { | |
return a == b; | |
}, collect = opt_collectorFn || function(i1) { | |
return array1[i1]; | |
}, length1 = array1.length, length2 = array2.length, arr = [], i = 0;i < length1 + 1;i++) { | |
arr[i] = [], arr[i][0] = 0; | |
} | |
for (var j = 0;j < length2 + 1;j++) { | |
arr[0][j] = 0; | |
} | |
for (i = 1;i <= length1;i++) { | |
for (j = 1;j <= length2;j++) { | |
compare(array1[i - 1], array2[j - 1]) ? arr[i][j] = arr[i - 1][j - 1] + 1 : arr[i][j] = Math.max(arr[i - 1][j], arr[i][j - 1]); | |
} | |
} | |
for (var result = [], i = length1, j = length2;0 < i && 0 < j;) { | |
compare(array1[i - 1], array2[j - 1]) ? (result.unshift(collect(i - 1, j - 1)), i--, j--) : arr[i - 1][j] > arr[i][j - 1] ? i-- : j--; | |
} | |
return result; | |
}; | |
goog.math.sum = function(var_args) { | |
return goog.array.reduce(arguments, function(sum, value) { | |
return sum + value; | |
}, 0); | |
}; | |
goog.math.average = function(var_args) { | |
return goog.math.sum.apply(null, arguments) / arguments.length; | |
}; | |
goog.math.sampleVariance = function(var_args) { | |
var sampleSize = arguments.length; | |
if (2 > sampleSize) { | |
return 0; | |
} | |
var mean = goog.math.average.apply(null, arguments); | |
return goog.math.sum.apply(null, goog.array.map(arguments, function(val) { | |
return Math.pow(val - mean, 2); | |
})) / (sampleSize - 1); | |
}; | |
goog.math.standardDeviation = function(var_args) { | |
return Math.sqrt(goog.math.sampleVariance.apply(null, arguments)); | |
}; | |
goog.math.isInt = function(num) { | |
return isFinite(num) && 0 == num % 1; | |
}; | |
goog.math.isFiniteNumber = function(num) { | |
return isFinite(num) && !isNaN(num); | |
}; | |
goog.math.log10Floor = function(num) { | |
if (0 < num) { | |
var x = Math.round(Math.log(num) * Math.LOG10E); | |
return x - (parseFloat("1e" + x) > num); | |
} | |
return 0 == num ? -Infinity : NaN; | |
}; | |
goog.math.safeFloor = function(num, opt_epsilon) { | |
goog.asserts.assert(!goog.isDef(opt_epsilon) || 0 < opt_epsilon); | |
return Math.floor(num + (opt_epsilon || 2E-15)); | |
}; | |
goog.math.safeCeil = function(num, opt_epsilon) { | |
goog.asserts.assert(!goog.isDef(opt_epsilon) || 0 < opt_epsilon); | |
return Math.ceil(num - (opt_epsilon || 2E-15)); | |
}; | |
goog.iter = {}; | |
goog.iter.StopIteration = "StopIteration" in goog.global ? goog.global.StopIteration : Error("StopIteration"); | |
goog.iter.Iterator = function() { | |
}; | |
goog.iter.Iterator.prototype.next = function() { | |
throw goog.iter.StopIteration; | |
}; | |
goog.iter.Iterator.prototype.__iterator__ = function() { | |
return this; | |
}; | |
goog.iter.toIterator = function(iterable) { | |
if (iterable instanceof goog.iter.Iterator) { | |
return iterable; | |
} | |
if ("function" == typeof iterable.__iterator__) { | |
return iterable.__iterator__(!1); | |
} | |
if (goog.isArrayLike(iterable)) { | |
var i = 0, newIter = new goog.iter.Iterator; | |
newIter.next = function() { | |
for (;;) { | |
if (i >= iterable.length) { | |
throw goog.iter.StopIteration; | |
} | |
if (i in iterable) { | |
return iterable[i++]; | |
} | |
i++; | |
} | |
}; | |
return newIter; | |
} | |
throw Error("Not implemented"); | |
}; | |
goog.iter.forEach = function(iterable, f, opt_obj) { | |
if (goog.isArrayLike(iterable)) { | |
try { | |
goog.array.forEach(iterable, f, opt_obj); | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
} | |
} else { | |
iterable = goog.iter.toIterator(iterable); | |
try { | |
for (;;) { | |
f.call(opt_obj, iterable.next(), void 0, iterable); | |
} | |
} catch (ex$$0) { | |
if (ex$$0 !== goog.iter.StopIteration) { | |
throw ex$$0; | |
} | |
} | |
} | |
}; | |
goog.iter.filter = function(iterable, f, opt_obj) { | |
var iterator = goog.iter.toIterator(iterable), newIter = new goog.iter.Iterator; | |
newIter.next = function() { | |
for (;;) { | |
var val = iterator.next(); | |
if (f.call(opt_obj, val, void 0, iterator)) { | |
return val; | |
} | |
} | |
}; | |
return newIter; | |
}; | |
goog.iter.filterFalse = function(iterable, f, opt_obj) { | |
return goog.iter.filter(iterable, goog.functions.not(f), opt_obj); | |
}; | |
goog.iter.range = function(startOrStop, opt_stop, opt_step) { | |
var start = 0, stop = startOrStop, step = opt_step || 1; | |
1 < arguments.length && (start = startOrStop, stop = opt_stop); | |
if (0 == step) { | |
throw Error("Range step argument must not be zero"); | |
} | |
var newIter = new goog.iter.Iterator; | |
newIter.next = function() { | |
if (0 < step && start >= stop || 0 > step && start <= stop) { | |
throw goog.iter.StopIteration; | |
} | |
var rv = start; | |
start += step; | |
return rv; | |
}; | |
return newIter; | |
}; | |
goog.iter.join = function(iterable, deliminator) { | |
return goog.iter.toArray(iterable).join(deliminator); | |
}; | |
goog.iter.map = function(iterable, f, opt_obj) { | |
var iterator = goog.iter.toIterator(iterable), newIter = new goog.iter.Iterator; | |
newIter.next = function() { | |
var val = iterator.next(); | |
return f.call(opt_obj, val, void 0, iterator); | |
}; | |
return newIter; | |
}; | |
goog.iter.reduce = function(iterable, f, val$$0, opt_obj) { | |
var rval = val$$0; | |
goog.iter.forEach(iterable, function(val) { | |
rval = f.call(opt_obj, rval, val); | |
}); | |
return rval; | |
}; | |
goog.iter.some = function(iterable, f, opt_obj) { | |
iterable = goog.iter.toIterator(iterable); | |
try { | |
for (;;) { | |
if (f.call(opt_obj, iterable.next(), void 0, iterable)) { | |
return!0; | |
} | |
} | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
} | |
return!1; | |
}; | |
goog.iter.every = function(iterable, f, opt_obj) { | |
iterable = goog.iter.toIterator(iterable); | |
try { | |
for (;;) { | |
if (!f.call(opt_obj, iterable.next(), void 0, iterable)) { | |
return!1; | |
} | |
} | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
} | |
return!0; | |
}; | |
goog.iter.chain = function(var_args) { | |
var iterator = goog.iter.toIterator(arguments), iter = new goog.iter.Iterator, current = null; | |
iter.next = function() { | |
for (;;) { | |
if (null == current) { | |
var it = iterator.next(); | |
current = goog.iter.toIterator(it); | |
} | |
try { | |
return current.next(); | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
current = null; | |
} | |
} | |
}; | |
return iter; | |
}; | |
goog.iter.chainFromIterable = function(iterable) { | |
return goog.iter.chain.apply(void 0, iterable); | |
}; | |
goog.iter.dropWhile = function(iterable, f, opt_obj) { | |
var iterator = goog.iter.toIterator(iterable), newIter = new goog.iter.Iterator, dropping = !0; | |
newIter.next = function() { | |
for (;;) { | |
var val = iterator.next(); | |
if (!dropping || !f.call(opt_obj, val, void 0, iterator)) { | |
return dropping = !1, val; | |
} | |
} | |
}; | |
return newIter; | |
}; | |
goog.iter.takeWhile = function(iterable, f, opt_obj) { | |
var iterator = goog.iter.toIterator(iterable), newIter = new goog.iter.Iterator, taking = !0; | |
newIter.next = function() { | |
for (;;) { | |
if (taking) { | |
var val = iterator.next(); | |
if (f.call(opt_obj, val, void 0, iterator)) { | |
return val; | |
} | |
taking = !1; | |
} else { | |
throw goog.iter.StopIteration; | |
} | |
} | |
}; | |
return newIter; | |
}; | |
goog.iter.toArray = function(iterable) { | |
if (goog.isArrayLike(iterable)) { | |
return goog.array.toArray(iterable); | |
} | |
iterable = goog.iter.toIterator(iterable); | |
var array = []; | |
goog.iter.forEach(iterable, function(val) { | |
array.push(val); | |
}); | |
return array; | |
}; | |
goog.iter.equals = function(iterable1, iterable2) { | |
var pairs = goog.iter.zipLongest({}, iterable1, iterable2); | |
return goog.iter.every(pairs, function(pair) { | |
return pair[0] == pair[1]; | |
}); | |
}; | |
goog.iter.nextOrValue = function(iterable) { | |
try { | |
goog.iter.toIterator(iterable).next(); | |
} catch (e) { | |
if (e != goog.iter.StopIteration) { | |
throw e; | |
} | |
} | |
}; | |
goog.iter.product = function(var_args) { | |
if (goog.array.some(arguments, function(arr) { | |
return!arr.length; | |
}) || !arguments.length) { | |
return new goog.iter.Iterator; | |
} | |
var iter = new goog.iter.Iterator, arrays = arguments, indicies = goog.array.repeat(0, arrays.length); | |
iter.next = function() { | |
if (indicies) { | |
for (var retVal = goog.array.map(indicies, function(valueIndex, arrayIndex) { | |
return arrays[arrayIndex][valueIndex]; | |
}), i = indicies.length - 1;0 <= i;i--) { | |
goog.asserts.assert(indicies); | |
if (indicies[i] < arrays[i].length - 1) { | |
indicies[i]++; | |
break; | |
} | |
if (0 == i) { | |
indicies = null; | |
break; | |
} | |
indicies[i] = 0; | |
} | |
return retVal; | |
} | |
throw goog.iter.StopIteration; | |
}; | |
return iter; | |
}; | |
goog.iter.cycle = function(iterable) { | |
var baseIterator = goog.iter.toIterator(iterable), cache = [], cacheIndex = 0, iter = new goog.iter.Iterator, useCache = !1; | |
iter.next = function() { | |
var returnElement = null; | |
if (!useCache) { | |
try { | |
return returnElement = baseIterator.next(), cache.push(returnElement), returnElement; | |
} catch (e) { | |
if (e != goog.iter.StopIteration || goog.array.isEmpty(cache)) { | |
throw e; | |
} | |
useCache = !0; | |
} | |
} | |
returnElement = cache[cacheIndex]; | |
cacheIndex = (cacheIndex + 1) % cache.length; | |
return returnElement; | |
}; | |
return iter; | |
}; | |
goog.iter.count = function(opt_start, opt_step) { | |
var counter = opt_start || 0, step = goog.isDef(opt_step) ? opt_step : 1, iter = new goog.iter.Iterator; | |
iter.next = function() { | |
var returnValue = counter; | |
counter += step; | |
return returnValue; | |
}; | |
return iter; | |
}; | |
goog.iter.repeat = function(value) { | |
var iter = new goog.iter.Iterator; | |
iter.next = goog.functions.constant(value); | |
return iter; | |
}; | |
goog.iter.accumulate = function(iterable) { | |
var iterator = goog.iter.toIterator(iterable), total = 0, iter = new goog.iter.Iterator; | |
iter.next = function() { | |
return total += iterator.next(); | |
}; | |
return iter; | |
}; | |
goog.iter.zip = function(var_args) { | |
var args = arguments, iter = new goog.iter.Iterator; | |
if (0 < args.length) { | |
var iterators = goog.array.map(args, goog.iter.toIterator); | |
iter.next = function() { | |
return goog.array.map(iterators, function(it) { | |
return it.next(); | |
}); | |
}; | |
} | |
return iter; | |
}; | |
goog.iter.zipLongest = function(fillValue, var_args) { | |
var args = goog.array.slice(arguments, 1), iter = new goog.iter.Iterator; | |
if (0 < args.length) { | |
var iterators = goog.array.map(args, goog.iter.toIterator); | |
iter.next = function() { | |
var iteratorsHaveValues = !1, arr = goog.array.map(iterators, function(it) { | |
var returnValue; | |
try { | |
returnValue = it.next(), iteratorsHaveValues = !0; | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
returnValue = fillValue; | |
} | |
return returnValue; | |
}); | |
if (!iteratorsHaveValues) { | |
throw goog.iter.StopIteration; | |
} | |
return arr; | |
}; | |
} | |
return iter; | |
}; | |
goog.iter.compress = function(iterable, selectors) { | |
var selectorIterator = goog.iter.toIterator(selectors); | |
return goog.iter.filter(iterable, function() { | |
return!!selectorIterator.next(); | |
}); | |
}; | |
goog.iter.GroupByIterator_ = function(iterable, opt_keyFunc) { | |
this.iterator = goog.iter.toIterator(iterable); | |
this.keyFunc = opt_keyFunc || goog.functions.identity; | |
}; | |
goog.inherits(goog.iter.GroupByIterator_, goog.iter.Iterator); | |
goog.iter.GroupByIterator_.prototype.next = function() { | |
for (;this.currentKey == this.targetKey;) { | |
this.currentValue = this.iterator.next(), this.currentKey = this.keyFunc(this.currentValue); | |
} | |
this.targetKey = this.currentKey; | |
return[this.currentKey, JSCompiler_StaticMethods_groupItems_(this, this.targetKey)]; | |
}; | |
var JSCompiler_StaticMethods_groupItems_ = function(JSCompiler_StaticMethods_groupItems_$self, targetKey) { | |
for (var arr = [];JSCompiler_StaticMethods_groupItems_$self.currentKey == targetKey;) { | |
arr.push(JSCompiler_StaticMethods_groupItems_$self.currentValue); | |
try { | |
JSCompiler_StaticMethods_groupItems_$self.currentValue = JSCompiler_StaticMethods_groupItems_$self.iterator.next(); | |
} catch (ex) { | |
if (ex !== goog.iter.StopIteration) { | |
throw ex; | |
} | |
break; | |
} | |
JSCompiler_StaticMethods_groupItems_$self.currentKey = JSCompiler_StaticMethods_groupItems_$self.keyFunc(JSCompiler_StaticMethods_groupItems_$self.currentValue); | |
} | |
return arr; | |
}; | |
goog.iter.groupBy = function(iterable, opt_keyFunc) { | |
return new goog.iter.GroupByIterator_(iterable, opt_keyFunc); | |
}; | |
goog.iter.starMap = function(iterable, f, opt_obj) { | |
var iterator = goog.iter.toIterator(iterable), iter = new goog.iter.Iterator; | |
iter.next = function() { | |
var args = goog.iter.toArray(iterator.next()); | |
return f.apply(opt_obj, goog.array.concat(args, void 0, iterator)); | |
}; | |
return iter; | |
}; | |
goog.iter.tee = function(iterable, opt_num) { | |
var iterator = goog.iter.toIterator(iterable), buffers = goog.array.map(goog.array.range(goog.isNumber(opt_num) ? opt_num : 2), function() { | |
return[]; | |
}), addNextIteratorValueToBuffers = function() { | |
var val = iterator.next(); | |
goog.array.forEach(buffers, function(buffer) { | |
buffer.push(val); | |
}); | |
}; | |
return goog.array.map(buffers, function(buffer) { | |
var iter = new goog.iter.Iterator; | |
iter.next = function() { | |
goog.array.isEmpty(buffer) && addNextIteratorValueToBuffers(); | |
goog.asserts.assert(!goog.array.isEmpty(buffer)); | |
return buffer.shift(); | |
}; | |
return iter; | |
}); | |
}; | |
goog.iter.enumerate = function(iterable, opt_start) { | |
return goog.iter.zip(goog.iter.count(opt_start), iterable); | |
}; | |
goog.iter.limit = function(iterable, limitSize) { | |
goog.asserts.assert(goog.math.isInt(limitSize) && 0 <= limitSize); | |
var iterator = goog.iter.toIterator(iterable), iter = new goog.iter.Iterator, remaining = limitSize; | |
iter.next = function() { | |
if (0 < remaining--) { | |
return iterator.next(); | |
} | |
throw goog.iter.StopIteration; | |
}; | |
return iter; | |
}; | |
goog.iter.consume = function(iterable, count) { | |
goog.asserts.assert(goog.math.isInt(count) && 0 <= count); | |
for (var iterator = goog.iter.toIterator(iterable);0 < count--;) { | |
goog.iter.nextOrValue(iterator); | |
} | |
return iterator; | |
}; | |
goog.iter.slice = function(iterable, start, opt_end) { | |
goog.asserts.assert(goog.math.isInt(start) && 0 <= start); | |
var iterator = goog.iter.consume(iterable, start); | |
goog.isNumber(opt_end) && (goog.asserts.assert(goog.math.isInt(opt_end) && opt_end >= start), iterator = goog.iter.limit(iterator, opt_end - start)); | |
return iterator; | |
}; | |
goog.iter.hasDuplicates_ = function(arr) { | |
var deduped = []; | |
goog.array.removeDuplicates(arr, deduped); | |
return arr.length != deduped.length; | |
}; | |
goog.iter.permutations = function(iterable, opt_length) { | |
var elements = goog.iter.toArray(iterable), sets = goog.array.repeat(elements, goog.isNumber(opt_length) ? opt_length : elements.length), product = goog.iter.product.apply(void 0, sets); | |
return goog.iter.filter(product, function(arr) { | |
return!goog.iter.hasDuplicates_(arr); | |
}); | |
}; | |
goog.iter.combinations = function(iterable, length) { | |
function getIndexFromElements(index) { | |
return elements[index]; | |
} | |
var elements = goog.iter.toArray(iterable), indexes = goog.iter.range(elements.length), indexIterator = goog.iter.permutations(indexes, length), sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) { | |
return goog.array.isSorted(arr); | |
}), iter = new goog.iter.Iterator; | |
iter.next = function() { | |
return goog.array.map(sortedIndexIterator.next(), getIndexFromElements); | |
}; | |
return iter; | |
}; | |
goog.iter.combinationsWithReplacement = function(iterable, length) { | |
function getIndexFromElements(index) { | |
return elements[index]; | |
} | |
var elements = goog.iter.toArray(iterable), indexes = goog.array.range(elements.length), sets = goog.array.repeat(indexes, length), indexIterator = goog.iter.product.apply(void 0, sets), sortedIndexIterator = goog.iter.filter(indexIterator, function(arr) { | |
return goog.array.isSorted(arr); | |
}), iter = new goog.iter.Iterator; | |
iter.next = function() { | |
return goog.array.map(sortedIndexIterator.next(), getIndexFromElements); | |
}; | |
return iter; | |
}; | |
goog.structs.Map = function(opt_map, var_args) { | |
this.map_ = {}; | |
this.keys_ = []; | |
this.version_ = this.count_ = 0; | |
var argLength = arguments.length; | |
if (1 < argLength) { | |
if (argLength % 2) { | |
throw Error("Uneven number of arguments"); | |
} | |
for (var i = 0;i < argLength;i += 2) { | |
this.set(arguments[i], arguments[i + 1]); | |
} | |
} else { | |
opt_map && this.addAll(opt_map); | |
} | |
}; | |
goog.structs.Map.prototype.getCount = function() { | |
return this.count_; | |
}; | |
goog.structs.Map.prototype.getValues = function() { | |
JSCompiler_StaticMethods_cleanupKeysArray_(this); | |
for (var rv = [], i = 0;i < this.keys_.length;i++) { | |
rv.push(this.map_[this.keys_[i]]); | |
} | |
return rv; | |
}; | |
goog.structs.Map.prototype.getKeys = function() { | |
JSCompiler_StaticMethods_cleanupKeysArray_(this); | |
return this.keys_.concat(); | |
}; | |
goog.structs.Map.prototype.containsKey = function(key) { | |
return goog.structs.Map.hasKey_(this.map_, key); | |
}; | |
goog.structs.Map.prototype.containsValue = function(val) { | |
for (var i = 0;i < this.keys_.length;i++) { | |
var key = this.keys_[i]; | |
if (goog.structs.Map.hasKey_(this.map_, key) && this.map_[key] == val) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
goog.structs.Map.prototype.equals = function(otherMap, opt_equalityFn) { | |
if (this === otherMap) { | |
return!0; | |
} | |
if (this.count_ != otherMap.getCount()) { | |
return!1; | |
} | |
var equalityFn = opt_equalityFn || goog.structs.Map.defaultEquals; | |
JSCompiler_StaticMethods_cleanupKeysArray_(this); | |
for (var key, i = 0;key = this.keys_[i];i++) { | |
if (!equalityFn(this.get(key), otherMap.get(key))) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.structs.Map.defaultEquals = function(a, b) { | |
return a === b; | |
}; | |
goog.structs.Map.prototype.isEmpty = function() { | |
return 0 == this.count_; | |
}; | |
goog.structs.Map.prototype.clear = function() { | |
this.map_ = {}; | |
this.version_ = this.count_ = this.keys_.length = 0; | |
}; | |
goog.structs.Map.prototype.remove = function(key) { | |
return goog.structs.Map.hasKey_(this.map_, key) ? (delete this.map_[key], this.count_--, this.version_++, this.keys_.length > 2 * this.count_ && JSCompiler_StaticMethods_cleanupKeysArray_(this), !0) : !1; | |
}; | |
var JSCompiler_StaticMethods_cleanupKeysArray_ = function(JSCompiler_StaticMethods_cleanupKeysArray_$self) { | |
if (JSCompiler_StaticMethods_cleanupKeysArray_$self.count_ != JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length) { | |
for (var srcIndex = 0, destIndex = 0;srcIndex < JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length;) { | |
var key = JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_[srcIndex]; | |
goog.structs.Map.hasKey_(JSCompiler_StaticMethods_cleanupKeysArray_$self.map_, key) && (JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_[destIndex++] = key); | |
srcIndex++; | |
} | |
JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length = destIndex; | |
} | |
if (JSCompiler_StaticMethods_cleanupKeysArray_$self.count_ != JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length) { | |
for (var seen = {}, destIndex = srcIndex = 0;srcIndex < JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length;) { | |
key = JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_[srcIndex], goog.structs.Map.hasKey_(seen, key) || (JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_[destIndex++] = key, seen[key] = 1), srcIndex++; | |
} | |
JSCompiler_StaticMethods_cleanupKeysArray_$self.keys_.length = destIndex; | |
} | |
}; | |
goog.structs.Map.prototype.get = function(key, opt_val) { | |
return goog.structs.Map.hasKey_(this.map_, key) ? this.map_[key] : opt_val; | |
}; | |
goog.structs.Map.prototype.set = function(key, value) { | |
goog.structs.Map.hasKey_(this.map_, key) || (this.count_++, this.keys_.push(key), this.version_++); | |
this.map_[key] = value; | |
}; | |
goog.structs.Map.prototype.addAll = function(map) { | |
var keys, values; | |
map instanceof goog.structs.Map ? (keys = map.getKeys(), values = map.getValues()) : (keys = goog.object.getKeys(map), values = goog.object.getValues(map)); | |
for (var i = 0;i < keys.length;i++) { | |
this.set(keys[i], values[i]); | |
} | |
}; | |
goog.structs.Map.prototype.forEach = function(f, opt_obj) { | |
for (var keys = this.getKeys(), i = 0;i < keys.length;i++) { | |
var key = keys[i], value = this.get(key); | |
f.call(opt_obj, value, key, this); | |
} | |
}; | |
goog.structs.Map.prototype.clone = function() { | |
return new goog.structs.Map(this); | |
}; | |
goog.structs.Map.prototype.transpose = function() { | |
for (var transposed = new goog.structs.Map, i = 0;i < this.keys_.length;i++) { | |
var key = this.keys_[i]; | |
transposed.set(this.map_[key], key); | |
} | |
return transposed; | |
}; | |
goog.structs.Map.prototype.toObject = function() { | |
JSCompiler_StaticMethods_cleanupKeysArray_(this); | |
for (var obj = {}, i = 0;i < this.keys_.length;i++) { | |
var key = this.keys_[i]; | |
obj[key] = this.map_[key]; | |
} | |
return obj; | |
}; | |
goog.structs.Map.prototype.__iterator__ = function(opt_keys) { | |
JSCompiler_StaticMethods_cleanupKeysArray_(this); | |
var i = 0, keys = this.keys_, map = this.map_, version = this.version_, selfObj = this, newIter = new goog.iter.Iterator; | |
newIter.next = function() { | |
for (;;) { | |
if (version != selfObj.version_) { | |
throw Error("The map has changed since the iterator was created"); | |
} | |
if (i >= keys.length) { | |
throw goog.iter.StopIteration; | |
} | |
var key = keys[i++]; | |
return opt_keys ? key : map[key]; | |
} | |
}; | |
return newIter; | |
}; | |
goog.structs.Map.hasKey_ = function(obj, key) { | |
return Object.prototype.hasOwnProperty.call(obj, key); | |
}; | |
goog.structs.getCount = function(col) { | |
return "function" == typeof col.getCount ? col.getCount() : goog.isArrayLike(col) || goog.isString(col) ? col.length : goog.object.getCount(col); | |
}; | |
goog.structs.getValues = function(col) { | |
if ("function" == typeof col.getValues) { | |
return col.getValues(); | |
} | |
if (goog.isString(col)) { | |
return col.split(""); | |
} | |
if (goog.isArrayLike(col)) { | |
for (var rv = [], l = col.length, i = 0;i < l;i++) { | |
rv.push(col[i]); | |
} | |
return rv; | |
} | |
return goog.object.getValues(col); | |
}; | |
goog.structs.getKeys = function(col) { | |
if ("function" == typeof col.getKeys) { | |
return col.getKeys(); | |
} | |
if ("function" != typeof col.getValues) { | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
for (var rv = [], l = col.length, i = 0;i < l;i++) { | |
rv.push(i); | |
} | |
return rv; | |
} | |
return goog.object.getKeys(col); | |
} | |
}; | |
goog.structs.contains = function(col, val) { | |
return "function" == typeof col.contains ? col.contains(val) : "function" == typeof col.containsValue ? col.containsValue(val) : goog.isArrayLike(col) || goog.isString(col) ? goog.array.contains(col, val) : goog.object.containsValue(col, val); | |
}; | |
goog.structs.isEmpty = function(col) { | |
return "function" == typeof col.isEmpty ? col.isEmpty() : goog.isArrayLike(col) || goog.isString(col) ? goog.array.isEmpty(col) : goog.object.isEmpty(col); | |
}; | |
goog.structs.clear = function(col) { | |
"function" == typeof col.clear ? col.clear() : goog.isArrayLike(col) ? goog.array.clear(col) : goog.object.clear(col); | |
}; | |
goog.structs.forEach = function(col, f, opt_obj) { | |
if ("function" == typeof col.forEach) { | |
col.forEach(f, opt_obj); | |
} else { | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
goog.array.forEach(col, f, opt_obj); | |
} else { | |
for (var keys = goog.structs.getKeys(col), values = goog.structs.getValues(col), l = values.length, i = 0;i < l;i++) { | |
f.call(opt_obj, values[i], keys && keys[i], col); | |
} | |
} | |
} | |
}; | |
goog.structs.filter = function(col, f, opt_obj) { | |
if ("function" == typeof col.filter) { | |
return col.filter(f, opt_obj); | |
} | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
return goog.array.filter(col, f, opt_obj); | |
} | |
var rv, keys = goog.structs.getKeys(col), values = goog.structs.getValues(col), l = values.length; | |
if (keys) { | |
rv = {}; | |
for (var i = 0;i < l;i++) { | |
f.call(opt_obj, values[i], keys[i], col) && (rv[keys[i]] = values[i]); | |
} | |
} else { | |
for (rv = [], i = 0;i < l;i++) { | |
f.call(opt_obj, values[i], void 0, col) && rv.push(values[i]); | |
} | |
} | |
return rv; | |
}; | |
goog.structs.map = function(col, f, opt_obj) { | |
if ("function" == typeof col.map) { | |
return col.map(f, opt_obj); | |
} | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
return goog.array.map(col, f, opt_obj); | |
} | |
var rv, keys = goog.structs.getKeys(col), values = goog.structs.getValues(col), l = values.length; | |
if (keys) { | |
rv = {}; | |
for (var i = 0;i < l;i++) { | |
rv[keys[i]] = f.call(opt_obj, values[i], keys[i], col); | |
} | |
} else { | |
for (rv = [], i = 0;i < l;i++) { | |
rv[i] = f.call(opt_obj, values[i], void 0, col); | |
} | |
} | |
return rv; | |
}; | |
goog.structs.some = function(col, f, opt_obj) { | |
if ("function" == typeof col.some) { | |
return col.some(f, opt_obj); | |
} | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
return goog.array.some(col, f, opt_obj); | |
} | |
for (var keys = goog.structs.getKeys(col), values = goog.structs.getValues(col), l = values.length, i = 0;i < l;i++) { | |
if (f.call(opt_obj, values[i], keys && keys[i], col)) { | |
return!0; | |
} | |
} | |
return!1; | |
}; | |
goog.structs.every = function(col, f, opt_obj) { | |
if ("function" == typeof col.every) { | |
return col.every(f, opt_obj); | |
} | |
if (goog.isArrayLike(col) || goog.isString(col)) { | |
return goog.array.every(col, f, opt_obj); | |
} | |
for (var keys = goog.structs.getKeys(col), values = goog.structs.getValues(col), l = values.length, i = 0;i < l;i++) { | |
if (!f.call(opt_obj, values[i], keys && keys[i], col)) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
goog.structs.Set = function(opt_values) { | |
this.map_ = new goog.structs.Map; | |
opt_values && this.addAll(opt_values); | |
}; | |
goog.structs.Set.getKey_ = function(val) { | |
var type = typeof val; | |
return "object" == type && val || "function" == type ? "o" + goog.getUid(val) : type.substr(0, 1) + val; | |
}; | |
goog.structs.Set.prototype.getCount = function() { | |
return this.map_.getCount(); | |
}; | |
goog.structs.Set.prototype.add = function(element) { | |
this.map_.set(goog.structs.Set.getKey_(element), element); | |
}; | |
goog.structs.Set.prototype.addAll = function(col) { | |
for (var values = goog.structs.getValues(col), l = values.length, i = 0;i < l;i++) { | |
this.add(values[i]); | |
} | |
}; | |
goog.structs.Set.prototype.removeAll = function(col) { | |
for (var values = goog.structs.getValues(col), l = values.length, i = 0;i < l;i++) { | |
this.remove(values[i]); | |
} | |
}; | |
goog.structs.Set.prototype.remove = function(element) { | |
return this.map_.remove(goog.structs.Set.getKey_(element)); | |
}; | |
goog.structs.Set.prototype.clear = function() { | |
this.map_.clear(); | |
}; | |
goog.structs.Set.prototype.isEmpty = function() { | |
return this.map_.isEmpty(); | |
}; | |
goog.structs.Set.prototype.contains = function(element) { | |
return this.map_.containsKey(goog.structs.Set.getKey_(element)); | |
}; | |
goog.structs.Set.prototype.getValues = function() { | |
return this.map_.getValues(); | |
}; | |
goog.structs.Set.prototype.clone = function() { | |
return new goog.structs.Set(this); | |
}; | |
goog.structs.Set.prototype.equals = function(col) { | |
return this.getCount() == goog.structs.getCount(col) && JSCompiler_StaticMethods_isSubsetOf(this, col); | |
}; | |
var JSCompiler_StaticMethods_isSubsetOf = function(JSCompiler_StaticMethods_isSubsetOf$self, col) { | |
var colCount = goog.structs.getCount(col); | |
if (JSCompiler_StaticMethods_isSubsetOf$self.getCount() > colCount) { | |
return!1; | |
} | |
!(col instanceof goog.structs.Set) && 5 < colCount && (col = new goog.structs.Set(col)); | |
return goog.structs.every(JSCompiler_StaticMethods_isSubsetOf$self, function(value) { | |
return goog.structs.contains(col, value); | |
}); | |
}; | |
goog.structs.Set.prototype.__iterator__ = function() { | |
return this.map_.__iterator__(!1); | |
}; | |
goog.debug.LOGGING_ENABLED = goog.DEBUG; | |
goog.debug.catchErrors = function(logFunc, opt_cancel, opt_target) { | |
var target = opt_target || goog.global, oldErrorHandler = target.onerror, retVal = !!opt_cancel; | |
goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher("535.3") && (retVal = !retVal); | |
target.onerror = function(message, url, line, opt_col, opt_error) { | |
oldErrorHandler && oldErrorHandler(message, url, line, opt_col, opt_error); | |
logFunc({message:message, fileName:url, line:line, col:opt_col, error:opt_error}); | |
return retVal; | |
}; | |
}; | |
goog.debug.expose = function(obj, opt_showFn) { | |
if ("undefined" == typeof obj) { | |
return "undefined"; | |
} | |
if (null == obj) { | |
return "NULL"; | |
} | |
var str = [], x; | |
for (x in obj) { | |
if (opt_showFn || !goog.isFunction(obj[x])) { | |
var s = x + " = "; | |
try { | |
s += obj[x]; | |
} catch (e) { | |
s += "*** " + e + " ***"; | |
} | |
str.push(s); | |
} | |
} | |
return str.join("\n"); | |
}; | |
goog.debug.deepExpose = function(obj$$0, opt_showFn) { | |
var str$$0 = [], helper = function(obj, space, parentSeen) { | |
var nestspace = space + " ", seen = new goog.structs.Set(parentSeen), indentMultiline = function(str) { | |
return str.replace(/\n/g, "\n" + space); | |
}; | |
try { | |
if (goog.isDef(obj)) { | |
if (goog.isNull(obj)) { | |
str$$0.push("NULL"); | |
} else { | |
if (goog.isString(obj)) { | |
str$$0.push('"' + indentMultiline(obj) + '"'); | |
} else { | |
if (goog.isFunction(obj)) { | |
str$$0.push(indentMultiline(String(obj))); | |
} else { | |
if (goog.isObject(obj)) { | |
if (seen.contains(obj)) { | |
str$$0.push("*** reference loop detected ***"); | |
} else { | |
seen.add(obj); | |
str$$0.push("{"); | |
for (var x in obj) { | |
if (opt_showFn || !goog.isFunction(obj[x])) { | |
str$$0.push("\n"), str$$0.push(nestspace), str$$0.push(x + " = "), helper(obj[x], nestspace, seen); | |
} | |
} | |
str$$0.push("\n" + space + "}"); | |
} | |
} else { | |
str$$0.push(obj); | |
} | |
} | |
} | |
} | |
} else { | |
str$$0.push("undefined"); | |
} | |
} catch (e) { | |
str$$0.push("*** " + e + " ***"); | |
} | |
}; | |
helper(obj$$0, "", new goog.structs.Set); | |
return str$$0.join(""); | |
}; | |
goog.debug.exposeArray = function(arr) { | |
for (var str = [], i = 0;i < arr.length;i++) { | |
goog.isArray(arr[i]) ? str.push(goog.debug.exposeArray(arr[i])) : str.push(arr[i]); | |
} | |
return "[ " + str.join(", ") + " ]"; | |
}; | |
goog.debug.exposeException = function(err, opt_fn) { | |
try { | |
var e = goog.debug.normalizeErrorObject(err); | |
return "Message: " + goog.string.htmlEscape(e.message) + '\nUrl: <a href="view-source:' + e.fileName + '" target="_new">' + e.fileName + "</a>\nLine: " + e.lineNumber + "\n\nBrowser stack:\n" + goog.string.htmlEscape(e.stack + "-> ") + "[end]\n\nJS stack traversal:\n" + goog.string.htmlEscape(goog.debug.getStacktrace(opt_fn) + "-> "); | |
} catch (e2) { | |
return "Exception trying to expose exception! You win, we lose. " + e2; | |
} | |
}; | |
goog.debug.normalizeErrorObject = function(err) { | |
var href = goog.getObjectByName("window.location.href"); | |
if (goog.isString(err)) { | |
return{message:err, name:"Unknown error", lineNumber:"Not available", fileName:href, stack:"Not available"}; | |
} | |
var lineNumber, fileName, threwError = !1; | |
try { | |
lineNumber = err.lineNumber || err.line || "Not available"; | |
} catch (e) { | |
lineNumber = "Not available", threwError = !0; | |
} | |
try { | |
fileName = err.fileName || err.filename || err.sourceURL || goog.global.$googDebugFname || href; | |
} catch (e$$0) { | |
fileName = "Not available", threwError = !0; | |
} | |
return!threwError && err.lineNumber && err.fileName && err.stack && err.message && err.name ? err : {message:err.message || "Not available", name:err.name || "UnknownError", lineNumber:lineNumber, fileName:fileName, stack:err.stack || "Not available"}; | |
}; | |
goog.debug.enhanceError = function(err, opt_message) { | |
var error; | |
"string" == typeof err ? (error = Error(err), Error.captureStackTrace && Error.captureStackTrace(error, goog.debug.enhanceError)) : error = err; | |
error.stack || (error.stack = goog.debug.getStacktrace(goog.debug.enhanceError)); | |
if (opt_message) { | |
for (var x = 0;error["message" + x];) { | |
++x; | |
} | |
error["message" + x] = String(opt_message); | |
} | |
return error; | |
}; | |
goog.debug.getStacktraceSimple = function(opt_depth) { | |
if (goog.STRICT_MODE_COMPATIBLE) { | |
var stack = goog.debug.getNativeStackTrace_(goog.debug.getStacktraceSimple); | |
if (stack) { | |
return stack; | |
} | |
} | |
for (var sb = [], fn = arguments.callee.caller, depth = 0;fn && (!opt_depth || depth < opt_depth);) { | |
sb.push(goog.debug.getFunctionName(fn)); | |
sb.push("()\n"); | |
try { | |
fn = fn.caller; | |
} catch (e) { | |
sb.push("[exception trying to get caller]\n"); | |
break; | |
} | |
depth++; | |
if (depth >= goog.debug.MAX_STACK_DEPTH) { | |
sb.push("[...long stack...]"); | |
break; | |
} | |
} | |
opt_depth && depth >= opt_depth ? sb.push("[...reached max depth limit...]") : sb.push("[end]"); | |
return sb.join(""); | |
}; | |
goog.debug.MAX_STACK_DEPTH = 50; | |
goog.debug.getNativeStackTrace_ = function(fn) { | |
var tempErr = Error(); | |
if (Error.captureStackTrace) { | |
return Error.captureStackTrace(tempErr, fn), String(tempErr.stack); | |
} | |
try { | |
throw tempErr; | |
} catch (e) { | |
tempErr = e; | |
} | |
var stack = tempErr.stack; | |
return stack ? String(stack) : null; | |
}; | |
goog.debug.getStacktrace = function(opt_fn) { | |
var stack; | |
goog.STRICT_MODE_COMPATIBLE && (stack = goog.debug.getNativeStackTrace_(opt_fn || goog.debug.getStacktrace)); | |
stack || (stack = goog.debug.getStacktraceHelper_(opt_fn || arguments.callee.caller, [])); | |
return stack; | |
}; | |
goog.debug.getStacktraceHelper_ = function(fn, visited) { | |
var sb = []; | |
if (goog.array.contains(visited, fn)) { | |
sb.push("[...circular reference...]"); | |
} else { | |
if (fn && visited.length < goog.debug.MAX_STACK_DEPTH) { | |
sb.push(goog.debug.getFunctionName(fn) + "("); | |
for (var args = fn.arguments, i = 0;args && i < args.length;i++) { | |
0 < i && sb.push(", "); | |
var argDesc, arg = args[i]; | |
switch(typeof arg) { | |
case "object": | |
argDesc = arg ? "object" : "null"; | |
break; | |
case "string": | |
argDesc = arg; | |
break; | |
case "number": | |
argDesc = String(arg); | |
break; | |
case "boolean": | |
argDesc = arg ? "true" : "false"; | |
break; | |
case "function": | |
argDesc = (argDesc = goog.debug.getFunctionName(arg)) ? argDesc : "[fn]"; | |
break; | |
default: | |
argDesc = typeof arg; | |
} | |
40 < argDesc.length && (argDesc = argDesc.substr(0, 40) + "..."); | |
sb.push(argDesc); | |
} | |
visited.push(fn); | |
sb.push(")\n"); | |
try { | |
sb.push(goog.debug.getStacktraceHelper_(fn.caller, visited)); | |
} catch (e) { | |
sb.push("[exception trying to get caller]\n"); | |
} | |
} else { | |
fn ? sb.push("[...long stack...]") : sb.push("[end]"); | |
} | |
} | |
return sb.join(""); | |
}; | |
goog.debug.setFunctionResolver = function(resolver) { | |
goog.debug.fnNameResolver_ = resolver; | |
}; | |
goog.debug.getFunctionName = function(fn) { | |
if (goog.debug.fnNameCache_[fn]) { | |
return goog.debug.fnNameCache_[fn]; | |
} | |
if (goog.debug.fnNameResolver_) { | |
var name = goog.debug.fnNameResolver_(fn); | |
if (name) { | |
return goog.debug.fnNameCache_[fn] = name; | |
} | |
} | |
var functionSource = String(fn); | |
if (!goog.debug.fnNameCache_[functionSource]) { | |
var matches = /function ([^\(]+)/.exec(functionSource); | |
goog.debug.fnNameCache_[functionSource] = matches ? matches[1] : "[Anonymous]"; | |
} | |
return goog.debug.fnNameCache_[functionSource]; | |
}; | |
goog.debug.makeWhitespaceVisible = function(string) { | |
return string.replace(/ /g, "[_]").replace(/\f/g, "[f]").replace(/\n/g, "[n]\n").replace(/\r/g, "[r]").replace(/\t/g, "[t]"); | |
}; | |
goog.debug.fnNameCache_ = {}; | |
goog.debug.LogRecord = function(level, msg, loggerName, opt_time, opt_sequenceNumber) { | |
this.reset(level, msg, loggerName, opt_time, opt_sequenceNumber); | |
}; | |
goog.debug.LogRecord.prototype.exception_ = null; | |
goog.debug.LogRecord.prototype.exceptionText_ = null; | |
goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS = !0; | |
goog.debug.LogRecord.nextSequenceNumber_ = 0; | |
goog.debug.LogRecord.prototype.reset = function(level, msg, loggerName, opt_time, opt_sequenceNumber) { | |
goog.debug.LogRecord.ENABLE_SEQUENCE_NUMBERS && ("number" == typeof opt_sequenceNumber || goog.debug.LogRecord.nextSequenceNumber_++); | |
this.time_ = opt_time || goog.now(); | |
this.level_ = level; | |
this.msg_ = msg; | |
delete this.exception_; | |
delete this.exceptionText_; | |
}; | |
var JSCompiler_StaticMethods_setException = function(JSCompiler_StaticMethods_setException$self, exception) { | |
JSCompiler_StaticMethods_setException$self.exception_ = exception; | |
}, JSCompiler_StaticMethods_setExceptionText = function(JSCompiler_StaticMethods_setExceptionText$self, text) { | |
JSCompiler_StaticMethods_setExceptionText$self.exceptionText_ = text; | |
}; | |
goog.debug.LogRecord.prototype.setLevel = function(level) { | |
this.level_ = level; | |
}; | |
goog.debug.LogRecord.prototype.getMessage = function() { | |
return this.msg_; | |
}; | |
goog.debug.LogBuffer = function() { | |
goog.asserts.assert(goog.debug.LogBuffer.isBufferingEnabled(), "Cannot use goog.debug.LogBuffer without defining goog.debug.LogBuffer.CAPACITY."); | |
this.clear(); | |
}; | |
goog.debug.LogBuffer.getInstance = function() { | |
goog.debug.LogBuffer.instance_ || (goog.debug.LogBuffer.instance_ = new goog.debug.LogBuffer); | |
return goog.debug.LogBuffer.instance_; | |
}; | |
goog.debug.LogBuffer.CAPACITY = 0; | |
var JSCompiler_StaticMethods_addRecord = function(JSCompiler_StaticMethods_addRecord$self, level, msg, loggerName) { | |
var curIndex = (JSCompiler_StaticMethods_addRecord$self.curIndex_ + 1) % goog.debug.LogBuffer.CAPACITY; | |
JSCompiler_StaticMethods_addRecord$self.curIndex_ = curIndex; | |
if (JSCompiler_StaticMethods_addRecord$self.isFull_) { | |
var ret = JSCompiler_StaticMethods_addRecord$self.buffer_[curIndex]; | |
ret.reset(level, msg, loggerName); | |
return ret; | |
} | |
JSCompiler_StaticMethods_addRecord$self.isFull_ = curIndex == goog.debug.LogBuffer.CAPACITY - 1; | |
return JSCompiler_StaticMethods_addRecord$self.buffer_[curIndex] = new goog.debug.LogRecord(level, msg, loggerName); | |
}; | |
goog.debug.LogBuffer.isBufferingEnabled = function() { | |
return 0 < goog.debug.LogBuffer.CAPACITY; | |
}; | |
goog.debug.LogBuffer.prototype.clear = function() { | |
this.buffer_ = Array(goog.debug.LogBuffer.CAPACITY); | |
this.curIndex_ = -1; | |
this.isFull_ = !1; | |
}; | |
goog.debug.Logger = function(name) { | |
this.name_ = name; | |
this.handlers_ = this.children_ = this.level_ = this.parent_ = null; | |
}; | |
goog.debug.Logger.ROOT_LOGGER_NAME = ""; | |
goog.debug.Logger.ENABLE_HIERARCHY = !0; | |
goog.debug.Logger.ENABLE_HIERARCHY || (goog.debug.Logger.rootHandlers_ = []); | |
goog.debug.Logger.Level = function(name, value) { | |
this.name = name; | |
this.value = value; | |
}; | |
goog.debug.Logger.Level.prototype.toString = function() { | |
return this.name; | |
}; | |
goog.debug.Logger.Level.OFF = new goog.debug.Logger.Level("OFF", Infinity); | |
goog.debug.Logger.Level.SHOUT = new goog.debug.Logger.Level("SHOUT", 1200); | |
goog.debug.Logger.Level.SEVERE = new goog.debug.Logger.Level("SEVERE", 1E3); | |
goog.debug.Logger.Level.WARNING = new goog.debug.Logger.Level("WARNING", 900); | |
goog.debug.Logger.Level.INFO = new goog.debug.Logger.Level("INFO", 800); | |
goog.debug.Logger.Level.CONFIG = new goog.debug.Logger.Level("CONFIG", 700); | |
goog.debug.Logger.Level.FINE = new goog.debug.Logger.Level("FINE", 500); | |
goog.debug.Logger.Level.FINER = new goog.debug.Logger.Level("FINER", 400); | |
goog.debug.Logger.Level.FINEST = new goog.debug.Logger.Level("FINEST", 300); | |
goog.debug.Logger.Level.ALL = new goog.debug.Logger.Level("ALL", 0); | |
goog.debug.Logger.Level.PREDEFINED_LEVELS = [goog.debug.Logger.Level.OFF, goog.debug.Logger.Level.SHOUT, goog.debug.Logger.Level.SEVERE, goog.debug.Logger.Level.WARNING, goog.debug.Logger.Level.INFO, goog.debug.Logger.Level.CONFIG, goog.debug.Logger.Level.FINE, goog.debug.Logger.Level.FINER, goog.debug.Logger.Level.FINEST, goog.debug.Logger.Level.ALL]; | |
goog.debug.Logger.Level.predefinedLevelsCache_ = null; | |
goog.debug.Logger.Level.createPredefinedLevelsCache_ = function() { | |
goog.debug.Logger.Level.predefinedLevelsCache_ = {}; | |
for (var i = 0, level;level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i];i++) { | |
goog.debug.Logger.Level.predefinedLevelsCache_[level.value] = level, goog.debug.Logger.Level.predefinedLevelsCache_[level.name] = level; | |
} | |
}; | |
goog.debug.Logger.Level.getPredefinedLevel = function(name) { | |
goog.debug.Logger.Level.predefinedLevelsCache_ || goog.debug.Logger.Level.createPredefinedLevelsCache_(); | |
return goog.debug.Logger.Level.predefinedLevelsCache_[name] || null; | |
}; | |
goog.debug.Logger.Level.getPredefinedLevelByValue = function(value) { | |
goog.debug.Logger.Level.predefinedLevelsCache_ || goog.debug.Logger.Level.createPredefinedLevelsCache_(); | |
if (value in goog.debug.Logger.Level.predefinedLevelsCache_) { | |
return goog.debug.Logger.Level.predefinedLevelsCache_[value]; | |
} | |
for (var i = 0;i < goog.debug.Logger.Level.PREDEFINED_LEVELS.length;++i) { | |
var level = goog.debug.Logger.Level.PREDEFINED_LEVELS[i]; | |
if (level.value <= value) { | |
return level; | |
} | |
} | |
return null; | |
}; | |
goog.debug.Logger.getLogger = function(name) { | |
return goog.debug.LogManager.getLogger(name); | |
}; | |
goog.debug.Logger.logToProfilers = function(msg) { | |
goog.global.console && (goog.global.console.timeStamp ? goog.global.console.timeStamp(msg) : goog.global.console.markTimeline && goog.global.console.markTimeline(msg)); | |
goog.global.msWriteProfilerMark && goog.global.msWriteProfilerMark(msg); | |
}; | |
goog.debug.Logger.prototype.addHandler = function(handler) { | |
goog.debug.LOGGING_ENABLED && (goog.debug.Logger.ENABLE_HIERARCHY ? (this.handlers_ || (this.handlers_ = []), this.handlers_.push(handler)) : (goog.asserts.assert(!this.name_, "Cannot call addHandler on a non-root logger when goog.debug.Logger.ENABLE_HIERARCHY is false."), goog.debug.Logger.rootHandlers_.push(handler))); | |
}; | |
goog.debug.Logger.prototype.removeHandler = function(handler) { | |
if (goog.debug.LOGGING_ENABLED) { | |
var handlers = goog.debug.Logger.ENABLE_HIERARCHY ? this.handlers_ : goog.debug.Logger.rootHandlers_; | |
return!!handlers && goog.array.remove(handlers, handler); | |
} | |
return!1; | |
}; | |
goog.debug.Logger.prototype.getParent = function() { | |
return this.parent_; | |
}; | |
goog.debug.Logger.prototype.getChildren = function() { | |
this.children_ || (this.children_ = {}); | |
return this.children_; | |
}; | |
goog.debug.Logger.prototype.setLevel = function(level) { | |
goog.debug.LOGGING_ENABLED && (goog.debug.Logger.ENABLE_HIERARCHY ? this.level_ = level : (goog.asserts.assert(!this.name_, "Cannot call setLevel() on a non-root logger when goog.debug.Logger.ENABLE_HIERARCHY is false."), goog.debug.Logger.rootLevel_ = level)); | |
}; | |
var JSCompiler_StaticMethods_getEffectiveLevel = function(JSCompiler_StaticMethods_getEffectiveLevel$self) { | |
if (!goog.debug.LOGGING_ENABLED) { | |
return goog.debug.Logger.Level.OFF; | |
} | |
if (!goog.debug.Logger.ENABLE_HIERARCHY) { | |
return goog.debug.Logger.rootLevel_; | |
} | |
if (JSCompiler_StaticMethods_getEffectiveLevel$self.level_) { | |
return JSCompiler_StaticMethods_getEffectiveLevel$self.level_; | |
} | |
if (JSCompiler_StaticMethods_getEffectiveLevel$self.parent_) { | |
return JSCompiler_StaticMethods_getEffectiveLevel(JSCompiler_StaticMethods_getEffectiveLevel$self.parent_); | |
} | |
goog.asserts.fail("Root logger has no level set."); | |
return null; | |
}, JSCompiler_StaticMethods_isLoggable = function(JSCompiler_StaticMethods_isLoggable$self, level) { | |
return goog.debug.LOGGING_ENABLED && level.value >= JSCompiler_StaticMethods_getEffectiveLevel(JSCompiler_StaticMethods_isLoggable$self).value; | |
}; | |
goog.debug.Logger.prototype.log = function(level, msg, opt_exception) { | |
goog.debug.LOGGING_ENABLED && JSCompiler_StaticMethods_isLoggable(this, level) && (goog.isFunction(msg) && (msg = msg()), JSCompiler_StaticMethods_doLogRecord_(this, this.getLogRecord(level, msg, opt_exception, goog.debug.Logger.prototype.log))); | |
}; | |
goog.debug.Logger.prototype.getLogRecord = function(level, msg, opt_exception, opt_fnStackContext) { | |
var logRecord = goog.debug.LogBuffer.isBufferingEnabled() ? JSCompiler_StaticMethods_addRecord(goog.debug.LogBuffer.getInstance(), level, msg, this.name_) : new goog.debug.LogRecord(level, String(msg), this.name_); | |
opt_exception && (JSCompiler_StaticMethods_setException(logRecord, opt_exception), JSCompiler_StaticMethods_setExceptionText(logRecord, goog.debug.exposeException(opt_exception, opt_fnStackContext || goog.debug.Logger.prototype.getLogRecord))); | |
return logRecord; | |
}; | |
var JSCompiler_StaticMethods_severe = function(JSCompiler_StaticMethods_severe$self, msg, opt_exception) { | |
goog.debug.LOGGING_ENABLED && JSCompiler_StaticMethods_severe$self.log(goog.debug.Logger.Level.SEVERE, msg, opt_exception); | |
}; | |
goog.debug.Logger.prototype.warning = function(msg, opt_exception) { | |
goog.debug.LOGGING_ENABLED && this.log(goog.debug.Logger.Level.WARNING, msg, opt_exception); | |
}; | |
goog.debug.Logger.prototype.info = function(msg, opt_exception) { | |
goog.debug.LOGGING_ENABLED && this.log(goog.debug.Logger.Level.INFO, msg, opt_exception); | |
}; | |
goog.debug.Logger.prototype.fine = function(msg, opt_exception) { | |
goog.debug.LOGGING_ENABLED && this.log(goog.debug.Logger.Level.FINE, msg, opt_exception); | |
}; | |
var JSCompiler_StaticMethods_doLogRecord_ = function(JSCompiler_StaticMethods_doLogRecord_$self, logRecord) { | |
goog.debug.Logger.logToProfilers("log:" + logRecord.getMessage()); | |
if (goog.debug.Logger.ENABLE_HIERARCHY) { | |
for (var target = JSCompiler_StaticMethods_doLogRecord_$self;target;) { | |
JSCompiler_StaticMethods_callPublish_(target, logRecord), target = target.getParent(); | |
} | |
} else { | |
for (var i = 0, handler;handler = goog.debug.Logger.rootHandlers_[i++];) { | |
handler(logRecord); | |
} | |
} | |
}, JSCompiler_StaticMethods_callPublish_ = function(JSCompiler_StaticMethods_callPublish_$self, logRecord) { | |
if (JSCompiler_StaticMethods_callPublish_$self.handlers_) { | |
for (var i = 0, handler;handler = JSCompiler_StaticMethods_callPublish_$self.handlers_[i];i++) { | |
handler(logRecord); | |
} | |
} | |
}, JSCompiler_StaticMethods_setParent_ = function(JSCompiler_StaticMethods_setParent_$self, parent) { | |
JSCompiler_StaticMethods_setParent_$self.parent_ = parent; | |
}, JSCompiler_StaticMethods_addChild_ = function(JSCompiler_StaticMethods_addChild_$self, name, logger) { | |
JSCompiler_StaticMethods_addChild_$self.getChildren()[name] = logger; | |
}; | |
goog.debug.LogManager = {}; | |
goog.debug.LogManager.loggers_ = {}; | |
goog.debug.LogManager.rootLogger_ = null; | |
goog.debug.LogManager.initialize = function() { | |
goog.debug.LogManager.rootLogger_ || (goog.debug.LogManager.rootLogger_ = new goog.debug.Logger(goog.debug.Logger.ROOT_LOGGER_NAME), goog.debug.LogManager.loggers_[goog.debug.Logger.ROOT_LOGGER_NAME] = goog.debug.LogManager.rootLogger_, goog.debug.LogManager.rootLogger_.setLevel(goog.debug.Logger.Level.CONFIG)); | |
}; | |
goog.debug.LogManager.getLoggers = function() { | |
return goog.debug.LogManager.loggers_; | |
}; | |
goog.debug.LogManager.getRoot = function() { | |
goog.debug.LogManager.initialize(); | |
return goog.debug.LogManager.rootLogger_; | |
}; | |
goog.debug.LogManager.getLogger = function(name) { | |
goog.debug.LogManager.initialize(); | |
return goog.debug.LogManager.loggers_[name] || goog.debug.LogManager.createLogger_(name); | |
}; | |
goog.debug.LogManager.createFunctionForCatchErrors = function(opt_logger) { | |
return function(info) { | |
JSCompiler_StaticMethods_severe(opt_logger || goog.debug.LogManager.getRoot(), "Error: " + info.message + " (" + info.fileName + " @ Line: " + info.line + ")"); | |
}; | |
}; | |
goog.debug.LogManager.createLogger_ = function(name) { | |
var logger = new goog.debug.Logger(name); | |
if (goog.debug.Logger.ENABLE_HIERARCHY) { | |
var lastDotIndex = name.lastIndexOf("."), leafName = name.substr(lastDotIndex + 1), parentLogger = goog.debug.LogManager.getLogger(name.substr(0, lastDotIndex)); | |
JSCompiler_StaticMethods_addChild_(parentLogger, leafName, logger); | |
JSCompiler_StaticMethods_setParent_(logger, parentLogger); | |
} | |
return goog.debug.LogManager.loggers_[name] = logger; | |
}; | |
goog.log = {}; | |
goog.log.ENABLED = goog.debug.LOGGING_ENABLED; | |
goog.log.ROOT_LOGGER_NAME = goog.debug.Logger.ROOT_LOGGER_NAME; | |
goog.log.Logger = goog.debug.Logger; | |
goog.log.Level = goog.debug.Logger.Level; | |
goog.log.LogRecord = goog.debug.LogRecord; | |
goog.log.getLogger = function(name, opt_level) { | |
if (goog.log.ENABLED) { | |
var logger = goog.debug.LogManager.getLogger(name); | |
opt_level && logger && logger.setLevel(opt_level); | |
return logger; | |
} | |
return null; | |
}; | |
goog.log.addHandler = function(logger, handler) { | |
goog.log.ENABLED && logger && logger.addHandler(handler); | |
}; | |
goog.log.removeHandler = function(logger, handler) { | |
return goog.log.ENABLED && logger ? logger.removeHandler(handler) : !1; | |
}; | |
goog.log.log = function(logger, level, msg, opt_exception) { | |
goog.log.ENABLED && logger && logger.log(level, msg, opt_exception); | |
}; | |
goog.log.error = function(logger, msg, opt_exception) { | |
goog.log.ENABLED && logger && JSCompiler_StaticMethods_severe(logger, msg, opt_exception); | |
}; | |
goog.log.warning = function(logger, msg, opt_exception) { | |
goog.log.ENABLED && logger && logger.warning(msg, opt_exception); | |
}; | |
goog.log.info = function(logger, msg, opt_exception) { | |
goog.log.ENABLED && logger && logger.info(msg, opt_exception); | |
}; | |
goog.log.fine = function(logger, msg, opt_exception) { | |
goog.log.ENABLED && logger && logger.fine(msg, opt_exception); | |
}; | |
goog.uri = {}; | |
goog.uri.utils = {}; | |
goog.uri.utils.CharCode_ = {AMPERSAND:38, EQUAL:61, HASH:35, QUESTION:63}; | |
goog.uri.utils.buildFromEncodedParts = function(opt_scheme, opt_userInfo, opt_domain, opt_port, opt_path, opt_queryData, opt_fragment) { | |
var out = ""; | |
opt_scheme && (out += opt_scheme + ":"); | |
opt_domain && (out += "//", opt_userInfo && (out += opt_userInfo + "@"), out += opt_domain, opt_port && (out += ":" + opt_port)); | |
opt_path && (out += opt_path); | |
opt_queryData && (out += "?" + opt_queryData); | |
opt_fragment && (out += "#" + opt_fragment); | |
return out; | |
}; | |
goog.uri.utils.splitRe_ = RegExp("^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#(.*))?$"); | |
goog.uri.utils.ComponentIndex = {SCHEME:1, USER_INFO:2, DOMAIN:3, PORT:4, PATH:5, QUERY_DATA:6, FRAGMENT:7}; | |
goog.uri.utils.split = function(uri) { | |
goog.uri.utils.phishingProtection_(); | |
return uri.match(goog.uri.utils.splitRe_); | |
}; | |
goog.uri.utils.needsPhishingProtection_ = goog.userAgent.WEBKIT; | |
goog.uri.utils.phishingProtection_ = function() { | |
if (goog.uri.utils.needsPhishingProtection_) { | |
goog.uri.utils.needsPhishingProtection_ = !1; | |
var location = goog.global.location; | |
if (location) { | |
var href = location.href; | |
if (href) { | |
var domain = goog.uri.utils.getDomain(href); | |
if (domain && domain != location.hostname) { | |
throw goog.uri.utils.needsPhishingProtection_ = !0, Error(); | |
} | |
} | |
} | |
} | |
}; | |
goog.uri.utils.decodeIfPossible_ = function(uri) { | |
return uri && decodeURIComponent(uri); | |
}; | |
goog.uri.utils.getComponentByIndex_ = function(componentIndex, uri) { | |
return goog.uri.utils.split(uri)[componentIndex] || null; | |
}; | |
goog.uri.utils.getScheme = function(uri) { | |
return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.SCHEME, uri); | |
}; | |
goog.uri.utils.getEffectiveScheme = function(uri) { | |
var scheme = goog.uri.utils.getScheme(uri); | |
if (!scheme && self.location) { | |
var protocol = self.location.protocol, scheme = protocol.substr(0, protocol.length - 1) | |
} | |
return scheme ? scheme.toLowerCase() : ""; | |
}; | |
goog.uri.utils.getUserInfoEncoded = function(uri) { | |
return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.USER_INFO, uri); | |
}; | |
goog.uri.utils.getUserInfo = function(uri) { | |
return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getUserInfoEncoded(uri)); | |
}; | |
goog.uri.utils.getDomainEncoded = function(uri) { | |
return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.DOMAIN, uri); | |
}; | |
goog.uri.utils.getDomain = function(uri) { | |
return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getDomainEncoded(uri)); | |
}; | |
goog.uri.utils.getPort = function(uri) { | |
return Number(goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.PORT, uri)) || null; | |
}; | |
goog.uri.utils.getPathEncoded = function(uri) { | |
return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.PATH, uri); | |
}; | |
goog.uri.utils.getPath = function(uri) { | |
return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getPathEncoded(uri)); | |
}; | |
goog.uri.utils.getQueryData = function(uri) { | |
return goog.uri.utils.getComponentByIndex_(goog.uri.utils.ComponentIndex.QUERY_DATA, uri); | |
}; | |
goog.uri.utils.getFragmentEncoded = function(uri) { | |
var hashIndex = uri.indexOf("#"); | |
return 0 > hashIndex ? null : uri.substr(hashIndex + 1); | |
}; | |
goog.uri.utils.setFragmentEncoded = function(uri, fragment) { | |
return goog.uri.utils.removeFragment(uri) + (fragment ? "#" + fragment : ""); | |
}; | |
goog.uri.utils.getFragment = function(uri) { | |
return goog.uri.utils.decodeIfPossible_(goog.uri.utils.getFragmentEncoded(uri)); | |
}; | |
goog.uri.utils.getHost = function(uri) { | |
var pieces = goog.uri.utils.split(uri); | |
return goog.uri.utils.buildFromEncodedParts(pieces[goog.uri.utils.ComponentIndex.SCHEME], pieces[goog.uri.utils.ComponentIndex.USER_INFO], pieces[goog.uri.utils.ComponentIndex.DOMAIN], pieces[goog.uri.utils.ComponentIndex.PORT]); | |
}; | |
goog.uri.utils.getPathAndAfter = function(uri) { | |
var pieces = goog.uri.utils.split(uri); | |
return goog.uri.utils.buildFromEncodedParts(null, null, null, null, pieces[goog.uri.utils.ComponentIndex.PATH], pieces[goog.uri.utils.ComponentIndex.QUERY_DATA], pieces[goog.uri.utils.ComponentIndex.FRAGMENT]); | |
}; | |
goog.uri.utils.removeFragment = function(uri) { | |
var hashIndex = uri.indexOf("#"); | |
return 0 > hashIndex ? uri : uri.substr(0, hashIndex); | |
}; | |
goog.uri.utils.haveSameDomain = function(uri1, uri2) { | |
var pieces1 = goog.uri.utils.split(uri1), pieces2 = goog.uri.utils.split(uri2); | |
return pieces1[goog.uri.utils.ComponentIndex.DOMAIN] == pieces2[goog.uri.utils.ComponentIndex.DOMAIN] && pieces1[goog.uri.utils.ComponentIndex.SCHEME] == pieces2[goog.uri.utils.ComponentIndex.SCHEME] && pieces1[goog.uri.utils.ComponentIndex.PORT] == pieces2[goog.uri.utils.ComponentIndex.PORT]; | |
}; | |
goog.uri.utils.assertNoFragmentsOrQueries_ = function(uri) { | |
if (goog.DEBUG && (0 <= uri.indexOf("#") || 0 <= uri.indexOf("?"))) { | |
throw Error("goog.uri.utils: Fragment or query identifiers are not supported: [" + uri + "]"); | |
} | |
}; | |
goog.uri.utils.appendQueryData_ = function(buffer) { | |
if (buffer[1]) { | |
var baseUri = buffer[0], hashIndex = baseUri.indexOf("#"); | |
0 <= hashIndex && (buffer.push(baseUri.substr(hashIndex)), buffer[0] = baseUri = baseUri.substr(0, hashIndex)); | |
var questionIndex = baseUri.indexOf("?"); | |
0 > questionIndex ? buffer[1] = "?" : questionIndex == baseUri.length - 1 && (buffer[1] = void 0); | |
} | |
return buffer.join(""); | |
}; | |
goog.uri.utils.appendKeyValuePairs_ = function(key, value, pairs) { | |
if (goog.isArray(value)) { | |
goog.asserts.assertArray(value); | |
for (var j = 0;j < value.length;j++) { | |
goog.uri.utils.appendKeyValuePairs_(key, String(value[j]), pairs); | |
} | |
} else { | |
null != value && pairs.push("&", key, "" === value ? "" : "=", goog.string.urlEncode(value)); | |
} | |
}; | |
goog.uri.utils.buildQueryDataBuffer_ = function(buffer, keysAndValues, opt_startIndex) { | |
goog.asserts.assert(0 == Math.max(keysAndValues.length - (opt_startIndex || 0), 0) % 2, "goog.uri.utils: Key/value lists must be even in length."); | |
for (var i = opt_startIndex || 0;i < keysAndValues.length;i += 2) { | |
goog.uri.utils.appendKeyValuePairs_(keysAndValues[i], keysAndValues[i + 1], buffer); | |
} | |
return buffer; | |
}; | |
goog.uri.utils.buildQueryData = function(keysAndValues, opt_startIndex) { | |
var buffer = goog.uri.utils.buildQueryDataBuffer_([], keysAndValues, opt_startIndex); | |
buffer[0] = ""; | |
return buffer.join(""); | |
}; | |
goog.uri.utils.buildQueryDataBufferFromMap_ = function(buffer, map) { | |
for (var key in map) { | |
goog.uri.utils.appendKeyValuePairs_(key, map[key], buffer); | |
} | |
return buffer; | |
}; | |
goog.uri.utils.buildQueryDataFromMap = function(map) { | |
var buffer = goog.uri.utils.buildQueryDataBufferFromMap_([], map); | |
buffer[0] = ""; | |
return buffer.join(""); | |
}; | |
goog.uri.utils.appendParams = function(uri, var_args) { | |
return goog.uri.utils.appendQueryData_(2 == arguments.length ? goog.uri.utils.buildQueryDataBuffer_([uri], arguments[1], 0) : goog.uri.utils.buildQueryDataBuffer_([uri], arguments, 1)); | |
}; | |
goog.uri.utils.appendParamsFromMap = function(uri, map) { | |
return goog.uri.utils.appendQueryData_(goog.uri.utils.buildQueryDataBufferFromMap_([uri], map)); | |
}; | |
goog.uri.utils.appendParam = function(uri, key, opt_value) { | |
var paramArr = [uri, "&", key]; | |
goog.isDefAndNotNull(opt_value) && paramArr.push("=", goog.string.urlEncode(opt_value)); | |
return goog.uri.utils.appendQueryData_(paramArr); | |
}; | |
goog.uri.utils.findParam_ = function(uri, startIndex, keyEncoded, hashOrEndIndex) { | |
for (var index = startIndex, keyLength = keyEncoded.length;0 <= (index = uri.indexOf(keyEncoded, index)) && index < hashOrEndIndex;) { | |
var precedingChar = uri.charCodeAt(index - 1); | |
if (precedingChar == goog.uri.utils.CharCode_.AMPERSAND || precedingChar == goog.uri.utils.CharCode_.QUESTION) { | |
var followingChar = uri.charCodeAt(index + keyLength); | |
if (!followingChar || followingChar == goog.uri.utils.CharCode_.EQUAL || followingChar == goog.uri.utils.CharCode_.AMPERSAND || followingChar == goog.uri.utils.CharCode_.HASH) { | |
return index; | |
} | |
} | |
index += keyLength + 1; | |
} | |
return-1; | |
}; | |
goog.uri.utils.hashOrEndRe_ = /#|$/; | |
goog.uri.utils.hasParam = function(uri, keyEncoded) { | |
return 0 <= goog.uri.utils.findParam_(uri, 0, keyEncoded, uri.search(goog.uri.utils.hashOrEndRe_)); | |
}; | |
goog.uri.utils.getParamValue = function(uri, keyEncoded) { | |
var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_), foundIndex = goog.uri.utils.findParam_(uri, 0, keyEncoded, hashOrEndIndex); | |
if (0 > foundIndex) { | |
return null; | |
} | |
var endPosition = uri.indexOf("&", foundIndex); | |
if (0 > endPosition || endPosition > hashOrEndIndex) { | |
endPosition = hashOrEndIndex; | |
} | |
foundIndex += keyEncoded.length + 1; | |
return goog.string.urlDecode(uri.substr(foundIndex, endPosition - foundIndex)); | |
}; | |
goog.uri.utils.getParamValues = function(uri, keyEncoded) { | |
for (var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_), position = 0, foundIndex, result = [];0 <= (foundIndex = goog.uri.utils.findParam_(uri, position, keyEncoded, hashOrEndIndex));) { | |
position = uri.indexOf("&", foundIndex); | |
if (0 > position || position > hashOrEndIndex) { | |
position = hashOrEndIndex; | |
} | |
foundIndex += keyEncoded.length + 1; | |
result.push(goog.string.urlDecode(uri.substr(foundIndex, position - foundIndex))); | |
} | |
return result; | |
}; | |
goog.uri.utils.trailingQueryPunctuationRe_ = /[?&]($|#)/; | |
goog.uri.utils.removeParam = function(uri, keyEncoded) { | |
for (var hashOrEndIndex = uri.search(goog.uri.utils.hashOrEndRe_), position = 0, foundIndex, buffer = [];0 <= (foundIndex = goog.uri.utils.findParam_(uri, position, keyEncoded, hashOrEndIndex));) { | |
buffer.push(uri.substring(position, foundIndex)), position = Math.min(uri.indexOf("&", foundIndex) + 1 || hashOrEndIndex, hashOrEndIndex); | |
} | |
buffer.push(uri.substr(position)); | |
return buffer.join("").replace(goog.uri.utils.trailingQueryPunctuationRe_, "$1"); | |
}; | |
goog.uri.utils.setParam = function(uri, keyEncoded, value) { | |
return goog.uri.utils.appendParam(goog.uri.utils.removeParam(uri, keyEncoded), keyEncoded, value); | |
}; | |
goog.uri.utils.appendPath = function(baseUri, path) { | |
goog.uri.utils.assertNoFragmentsOrQueries_(baseUri); | |
goog.string.endsWith(baseUri) && (baseUri = baseUri.substr(0, baseUri.length - 1)); | |
goog.string.startsWith(path) && (path = path.substr(1)); | |
return goog.string.buildString(baseUri, "/", path); | |
}; | |
goog.uri.utils.setPath = function(uri, path) { | |
goog.string.startsWith(path) || (path = "/" + path); | |
var parts = goog.uri.utils.split(uri); | |
return goog.uri.utils.buildFromEncodedParts(parts[goog.uri.utils.ComponentIndex.SCHEME], parts[goog.uri.utils.ComponentIndex.USER_INFO], parts[goog.uri.utils.ComponentIndex.DOMAIN], parts[goog.uri.utils.ComponentIndex.PORT], path, parts[goog.uri.utils.ComponentIndex.QUERY_DATA], parts[goog.uri.utils.ComponentIndex.FRAGMENT]); | |
}; | |
goog.uri.utils.StandardQueryParam = {RANDOM:"zx"}; | |
goog.uri.utils.makeUnique = function(uri) { | |
return goog.uri.utils.setParam(uri, goog.uri.utils.StandardQueryParam.RANDOM, goog.string.getRandomString()); | |
}; | |
goog.net = {}; | |
goog.net.ErrorCode = {NO_ERROR:0, ACCESS_DENIED:1, FILE_NOT_FOUND:2, FF_SILENT_ERROR:3, CUSTOM_ERROR:4, EXCEPTION:5, HTTP_ERROR:6, ABORT:7, TIMEOUT:8, OFFLINE:9}; | |
goog.net.ErrorCode.getDebugMessage = function(errorCode) { | |
switch(errorCode) { | |
case goog.net.ErrorCode.NO_ERROR: | |
return "No Error"; | |
case goog.net.ErrorCode.ACCESS_DENIED: | |
return "Access denied to content document"; | |
case goog.net.ErrorCode.FILE_NOT_FOUND: | |
return "File not found"; | |
case goog.net.ErrorCode.FF_SILENT_ERROR: | |
return "Firefox silently errored"; | |
case goog.net.ErrorCode.CUSTOM_ERROR: | |
return "Application custom error"; | |
case goog.net.ErrorCode.EXCEPTION: | |
return "An exception occurred"; | |
case goog.net.ErrorCode.HTTP_ERROR: | |
return "Http response at 400 or 500 level"; | |
case goog.net.ErrorCode.ABORT: | |
return "Request was aborted"; | |
case goog.net.ErrorCode.TIMEOUT: | |
return "Request timed out"; | |
case goog.net.ErrorCode.OFFLINE: | |
return "The resource is not available offline"; | |
default: | |
return "Unrecognized error code"; | |
} | |
}; | |
goog.net.EventType = {COMPLETE:"complete", SUCCESS:"success", ERROR:"error", ABORT:"abort", READY:"ready", READY_STATE_CHANGE:"readystatechange", TIMEOUT:"timeout", INCREMENTAL_DATA:"incrementaldata", PROGRESS:"progress"}; | |
goog.net.HttpStatus = {CONTINUE:100, SWITCHING_PROTOCOLS:101, OK:200, CREATED:201, ACCEPTED:202, NON_AUTHORITATIVE_INFORMATION:203, NO_CONTENT:204, RESET_CONTENT:205, PARTIAL_CONTENT:206, MULTIPLE_CHOICES:300, MOVED_PERMANENTLY:301, FOUND:302, SEE_OTHER:303, NOT_MODIFIED:304, USE_PROXY:305, TEMPORARY_REDIRECT:307, BAD_REQUEST:400, UNAUTHORIZED:401, PAYMENT_REQUIRED:402, FORBIDDEN:403, NOT_FOUND:404, METHOD_NOT_ALLOWED:405, NOT_ACCEPTABLE:406, PROXY_AUTHENTICATION_REQUIRED:407, REQUEST_TIMEOUT:408, | |
CONFLICT:409, GONE:410, LENGTH_REQUIRED:411, PRECONDITION_FAILED:412, REQUEST_ENTITY_TOO_LARGE:413, REQUEST_URI_TOO_LONG:414, UNSUPPORTED_MEDIA_TYPE:415, REQUEST_RANGE_NOT_SATISFIABLE:416, EXPECTATION_FAILED:417, INTERNAL_SERVER_ERROR:500, NOT_IMPLEMENTED:501, BAD_GATEWAY:502, SERVICE_UNAVAILABLE:503, GATEWAY_TIMEOUT:504, HTTP_VERSION_NOT_SUPPORTED:505, QUIRK_IE_NO_CONTENT:1223}; | |
goog.net.HttpStatus.isSuccess = function(status) { | |
switch(status) { | |
case goog.net.HttpStatus.OK: | |
; | |
case goog.net.HttpStatus.CREATED: | |
; | |
case goog.net.HttpStatus.ACCEPTED: | |
; | |
case goog.net.HttpStatus.NO_CONTENT: | |
; | |
case goog.net.HttpStatus.PARTIAL_CONTENT: | |
; | |
case goog.net.HttpStatus.NOT_MODIFIED: | |
; | |
case goog.net.HttpStatus.QUIRK_IE_NO_CONTENT: | |
return!0; | |
default: | |
return!1; | |
} | |
}; | |
goog.net.XhrLike = function() { | |
}; | |
goog.net.XhrLike.prototype.open = function() { | |
}; | |
goog.net.XhrLike.prototype.send = function() { | |
}; | |
goog.net.XhrLike.prototype.abort = function() { | |
}; | |
goog.net.XhrLike.prototype.setRequestHeader = function() { | |
}; | |
goog.net.XmlHttpFactory = function() { | |
}; | |
goog.net.XmlHttpFactory.prototype.cachedOptions_ = null; | |
goog.net.XmlHttpFactory.prototype.getOptions = function() { | |
return this.cachedOptions_ || (this.cachedOptions_ = JSCompiler_StaticMethods_internalGetOptions(this)); | |
}; | |
goog.net.WrapperXmlHttpFactory = function(xhrFactory, optionsFactory) { | |
this.xhrFactory_ = xhrFactory; | |
this.optionsFactory_ = optionsFactory; | |
}; | |
goog.inherits(goog.net.WrapperXmlHttpFactory, goog.net.XmlHttpFactory); | |
goog.net.WrapperXmlHttpFactory.prototype.createInstance = function() { | |
return this.xhrFactory_(); | |
}; | |
goog.net.WrapperXmlHttpFactory.prototype.getOptions = function() { | |
return this.optionsFactory_(); | |
}; | |
goog.net.XmlHttp = function() { | |
return goog.net.XmlHttp.factory_.createInstance(); | |
}; | |
goog.net.XmlHttp.ASSUME_NATIVE_XHR = !1; | |
goog.net.XmlHttpDefines = {}; | |
goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR = !1; | |
goog.net.XmlHttp.getOptions = function() { | |
return goog.net.XmlHttp.factory_.getOptions(); | |
}; | |
goog.net.XmlHttp.OptionType = {USE_NULL_FUNCTION:0, LOCAL_REQUEST_ERROR:1}; | |
goog.net.XmlHttp.ReadyState = {UNINITIALIZED:0, LOADING:1, LOADED:2, INTERACTIVE:3, COMPLETE:4}; | |
goog.net.XmlHttp.setFactory = function(factory, optionsFactory) { | |
goog.net.XmlHttp.setGlobalFactory(new goog.net.WrapperXmlHttpFactory(goog.asserts.assert(factory), goog.asserts.assert(optionsFactory))); | |
}; | |
goog.net.XmlHttp.setGlobalFactory = function(factory) { | |
goog.net.XmlHttp.factory_ = factory; | |
}; | |
goog.net.DefaultXmlHttpFactory = function() { | |
}; | |
goog.inherits(goog.net.DefaultXmlHttpFactory, goog.net.XmlHttpFactory); | |
goog.net.DefaultXmlHttpFactory.prototype.createInstance = function() { | |
var progId = JSCompiler_StaticMethods_getProgId_(this); | |
return progId ? new ActiveXObject(progId) : new XMLHttpRequest; | |
}; | |
var JSCompiler_StaticMethods_internalGetOptions = function(JSCompiler_StaticMethods_internalGetOptions$self) { | |
var options = {}; | |
JSCompiler_StaticMethods_getProgId_(JSCompiler_StaticMethods_internalGetOptions$self) && (options[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] = !0, options[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] = !0); | |
return options; | |
}, JSCompiler_StaticMethods_getProgId_ = function(JSCompiler_StaticMethods_getProgId_$self) { | |
if (goog.net.XmlHttp.ASSUME_NATIVE_XHR || goog.net.XmlHttpDefines.ASSUME_NATIVE_XHR) { | |
return ""; | |
} | |
if (!JSCompiler_StaticMethods_getProgId_$self.ieProgId_ && "undefined" == typeof XMLHttpRequest && "undefined" != typeof ActiveXObject) { | |
for (var ACTIVE_X_IDENTS = ["MSXML2.XMLHTTP.6.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"], i = 0;i < ACTIVE_X_IDENTS.length;i++) { | |
var candidate = ACTIVE_X_IDENTS[i]; | |
try { | |
return new ActiveXObject(candidate), JSCompiler_StaticMethods_getProgId_$self.ieProgId_ = candidate; | |
} catch (e) { | |
} | |
} | |
throw Error("Could not create ActiveXObject. ActiveX might be disabled, or MSXML might not be installed"); | |
} | |
return JSCompiler_StaticMethods_getProgId_$self.ieProgId_; | |
}; | |
goog.net.XmlHttp.setGlobalFactory(new goog.net.DefaultXmlHttpFactory); | |
goog.net.XhrIo = function(opt_xmlHttpFactory) { | |
goog.events.EventTarget.call(this); | |
this.headers = new goog.structs.Map; | |
this.xmlHttpFactory_ = opt_xmlHttpFactory || null; | |
this.active_ = !1; | |
this.xhrOptions_ = this.xhr_ = null; | |
this.lastError_ = this.lastMethod_ = this.lastUri_ = ""; | |
this.inAbort_ = this.inOpen_ = this.inSend_ = this.errorDispatched_ = !1; | |
this.timeoutInterval_ = 0; | |
this.timeoutId_ = null; | |
this.responseType_ = goog.net.XhrIo.ResponseType.DEFAULT; | |
this.useXhr2Timeout_ = this.withCredentials_ = !1; | |
}; | |
goog.inherits(goog.net.XhrIo, goog.events.EventTarget); | |
goog.net.XhrIo.ResponseType = {DEFAULT:"", TEXT:"text", DOCUMENT:"document", BLOB:"blob", ARRAY_BUFFER:"arraybuffer"}; | |
goog.net.XhrIo.prototype.logger_ = goog.log.getLogger("goog.net.XhrIo"); | |
goog.net.XhrIo.CONTENT_TYPE_HEADER = "Content-Type"; | |
goog.net.XhrIo.HTTP_SCHEME_PATTERN = /^https?$/i; | |
goog.net.XhrIo.METHODS_WITH_FORM_DATA = ["POST", "PUT"]; | |
goog.net.XhrIo.FORM_CONTENT_TYPE = "application/x-www-form-urlencoded;charset=utf-8"; | |
goog.net.XhrIo.XHR2_TIMEOUT_ = "timeout"; | |
goog.net.XhrIo.XHR2_ON_TIMEOUT_ = "ontimeout"; | |
goog.net.XhrIo.sendInstances_ = []; | |
goog.net.XhrIo.send = function(url, opt_callback, opt_method, opt_content, opt_headers, opt_timeoutInterval, opt_withCredentials) { | |
var x = new goog.net.XhrIo; | |
goog.net.XhrIo.sendInstances_.push(x); | |
opt_callback && x.listen(goog.net.EventType.COMPLETE, opt_callback); | |
x.listenOnce(goog.net.EventType.READY, x.cleanupSend_); | |
opt_timeoutInterval && JSCompiler_StaticMethods_setTimeoutInterval(x, opt_timeoutInterval); | |
opt_withCredentials && JSCompiler_StaticMethods_setWithCredentials(x, opt_withCredentials); | |
x.send(url, opt_method, opt_content, opt_headers); | |
}; | |
goog.net.XhrIo.cleanup = function() { | |
for (var instances = goog.net.XhrIo.sendInstances_;instances.length;) { | |
instances.pop().dispose(); | |
} | |
}; | |
goog.net.XhrIo.protectEntryPoints = function(errorHandler) { | |
goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = errorHandler.protectEntryPoint(goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_); | |
}; | |
goog.net.XhrIo.prototype.cleanupSend_ = function() { | |
this.dispose(); | |
goog.array.remove(goog.net.XhrIo.sendInstances_, this); | |
}; | |
var JSCompiler_StaticMethods_setTimeoutInterval = function(JSCompiler_StaticMethods_setTimeoutInterval$self, ms) { | |
JSCompiler_StaticMethods_setTimeoutInterval$self.timeoutInterval_ = Math.max(0, ms); | |
}, JSCompiler_StaticMethods_setWithCredentials = function(JSCompiler_StaticMethods_setWithCredentials$self, withCredentials) { | |
JSCompiler_StaticMethods_setWithCredentials$self.withCredentials_ = withCredentials; | |
}; | |
goog.net.XhrIo.prototype.send = function(url, opt_method, opt_content, opt_headers) { | |
if (this.xhr_) { | |
throw Error("[goog.net.XhrIo] Object is active with another request=" + this.lastUri_ + "; newUri=" + url); | |
} | |
var method = opt_method ? opt_method.toUpperCase() : "GET"; | |
this.lastUri_ = url; | |
this.lastError_ = ""; | |
this.lastMethod_ = method; | |
this.errorDispatched_ = !1; | |
this.active_ = !0; | |
this.xhr_ = JSCompiler_StaticMethods_createXhr(this); | |
this.xhrOptions_ = this.xmlHttpFactory_ ? this.xmlHttpFactory_.getOptions() : goog.net.XmlHttp.getOptions(); | |
this.xhr_.onreadystatechange = goog.bind(this.onReadyStateChange_, this); | |
try { | |
goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Opening Xhr")), this.inOpen_ = !0, this.xhr_.open(method, String(url), !0), this.inOpen_ = !1; | |
} catch (err) { | |
goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Error opening Xhr: " + err.message)); | |
JSCompiler_StaticMethods_error_(this, err); | |
return; | |
} | |
var content = opt_content || "", headers = this.headers.clone(); | |
opt_headers && goog.structs.forEach(opt_headers, function(value, key) { | |
headers.set(key, value); | |
}); | |
var contentTypeKey = goog.array.find(headers.getKeys(), goog.net.XhrIo.isContentTypeHeader_), contentIsFormData = goog.global.FormData && content instanceof goog.global.FormData; | |
!goog.array.contains(goog.net.XhrIo.METHODS_WITH_FORM_DATA, method) || contentTypeKey || contentIsFormData || headers.set(goog.net.XhrIo.CONTENT_TYPE_HEADER, goog.net.XhrIo.FORM_CONTENT_TYPE); | |
headers.forEach(function(value, key) { | |
this.xhr_.setRequestHeader(key, value); | |
}, this); | |
this.responseType_ && (this.xhr_.responseType = this.responseType_); | |
goog.object.containsKey(this.xhr_, "withCredentials") && (this.xhr_.withCredentials = this.withCredentials_); | |
try { | |
JSCompiler_StaticMethods_cleanUpTimeoutTimer_(this), 0 < this.timeoutInterval_ && (this.useXhr2Timeout_ = goog.net.XhrIo.shouldUseXhr2Timeout_(this.xhr_), goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Will abort after " + this.timeoutInterval_ + "ms if incomplete, xhr2 " + this.useXhr2Timeout_)), this.useXhr2Timeout_ ? (this.xhr_[goog.net.XhrIo.XHR2_TIMEOUT_] = this.timeoutInterval_, this.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] = goog.bind(this.timeout_, this)) : this.timeoutId_ = | |
goog.Timer.callOnce(this.timeout_, this.timeoutInterval_, this)), goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Sending request")), this.inSend_ = !0, this.xhr_.send(content), this.inSend_ = !1; | |
} catch (err$$0) { | |
goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Send error: " + err$$0.message)), JSCompiler_StaticMethods_error_(this, err$$0); | |
} | |
}; | |
goog.net.XhrIo.shouldUseXhr2Timeout_ = function(xhr) { | |
return goog.userAgent.IE && goog.userAgent.isVersionOrHigher(9) && goog.isNumber(xhr[goog.net.XhrIo.XHR2_TIMEOUT_]) && goog.isDef(xhr[goog.net.XhrIo.XHR2_ON_TIMEOUT_]); | |
}; | |
goog.net.XhrIo.isContentTypeHeader_ = function(header) { | |
return goog.string.caseInsensitiveEquals(header); | |
}; | |
var JSCompiler_StaticMethods_createXhr = function(JSCompiler_StaticMethods_createXhr$self) { | |
return JSCompiler_StaticMethods_createXhr$self.xmlHttpFactory_ ? JSCompiler_StaticMethods_createXhr$self.xmlHttpFactory_.createInstance() : goog.net.XmlHttp(); | |
}; | |
goog.net.XhrIo.prototype.timeout_ = function() { | |
"undefined" != typeof goog && this.xhr_ && (this.lastError_ = "Timed out after " + this.timeoutInterval_ + "ms, aborting", goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, this.lastError_)), this.dispatchEvent(goog.net.EventType.TIMEOUT), this.abort(goog.net.ErrorCode.TIMEOUT)); | |
}; | |
var JSCompiler_StaticMethods_error_ = function(JSCompiler_StaticMethods_error_$self, err) { | |
JSCompiler_StaticMethods_error_$self.active_ = !1; | |
JSCompiler_StaticMethods_error_$self.xhr_ && (JSCompiler_StaticMethods_error_$self.inAbort_ = !0, JSCompiler_StaticMethods_error_$self.xhr_.abort(), JSCompiler_StaticMethods_error_$self.inAbort_ = !1); | |
JSCompiler_StaticMethods_error_$self.lastError_ = err; | |
JSCompiler_StaticMethods_dispatchErrors_(JSCompiler_StaticMethods_error_$self); | |
JSCompiler_StaticMethods_cleanUpXhr_(JSCompiler_StaticMethods_error_$self); | |
}, JSCompiler_StaticMethods_dispatchErrors_ = function(JSCompiler_StaticMethods_dispatchErrors_$self) { | |
JSCompiler_StaticMethods_dispatchErrors_$self.errorDispatched_ || (JSCompiler_StaticMethods_dispatchErrors_$self.errorDispatched_ = !0, JSCompiler_StaticMethods_dispatchErrors_$self.dispatchEvent(goog.net.EventType.COMPLETE), JSCompiler_StaticMethods_dispatchErrors_$self.dispatchEvent(goog.net.EventType.ERROR)); | |
}; | |
goog.net.XhrIo.prototype.abort = function() { | |
this.xhr_ && this.active_ && (goog.log.fine(this.logger_, JSCompiler_StaticMethods_formatMsg_(this, "Aborting")), this.active_ = !1, this.inAbort_ = !0, this.xhr_.abort(), this.inAbort_ = !1, this.dispatchEvent(goog.net.EventType.COMPLETE), this.dispatchEvent(goog.net.EventType.ABORT), JSCompiler_StaticMethods_cleanUpXhr_(this)); | |
}; | |
goog.net.XhrIo.prototype.disposeInternal = function() { | |
this.xhr_ && (this.active_ && (this.active_ = !1, this.inAbort_ = !0, this.xhr_.abort(), this.inAbort_ = !1), JSCompiler_StaticMethods_cleanUpXhr_(this, !0)); | |
goog.net.XhrIo.superClass_.disposeInternal.call(this); | |
}; | |
goog.net.XhrIo.prototype.onReadyStateChange_ = function() { | |
if (!this.isDisposed()) { | |
if (this.inOpen_ || this.inSend_ || this.inAbort_) { | |
JSCompiler_StaticMethods_onReadyStateChangeHelper_(this); | |
} else { | |
this.onReadyStateChangeEntryPoint_(); | |
} | |
} | |
}; | |
goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = function() { | |
JSCompiler_StaticMethods_onReadyStateChangeHelper_(this); | |
}; | |
var JSCompiler_StaticMethods_onReadyStateChangeHelper_ = function(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self) { | |
if (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.active_ && "undefined" != typeof goog) { | |
if (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.xhrOptions_[goog.net.XmlHttp.OptionType.LOCAL_REQUEST_ERROR] && JSCompiler_StaticMethods_getReadyState(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self) == goog.net.XmlHttp.ReadyState.COMPLETE && 2 == JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.getStatus()) { | |
goog.log.fine(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.logger_, JSCompiler_StaticMethods_formatMsg_(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self, "Local request error detected and ignored")); | |
} else { | |
if (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.inSend_ && JSCompiler_StaticMethods_getReadyState(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self) == goog.net.XmlHttp.ReadyState.COMPLETE) { | |
goog.Timer.callOnce(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.onReadyStateChange_, 0, JSCompiler_StaticMethods_onReadyStateChangeHelper_$self); | |
} else { | |
if (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.dispatchEvent(goog.net.EventType.READY_STATE_CHANGE), JSCompiler_StaticMethods_isComplete(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self)) { | |
goog.log.fine(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.logger_, JSCompiler_StaticMethods_formatMsg_(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self, "Request complete")); | |
JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.active_ = !1; | |
try { | |
JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.isSuccess() ? (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.dispatchEvent(goog.net.EventType.COMPLETE), JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.dispatchEvent(goog.net.EventType.SUCCESS)) : (JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.lastError_ = JSCompiler_StaticMethods_getStatusText(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self) + " [" + JSCompiler_StaticMethods_onReadyStateChangeHelper_$self.getStatus() + | |
"]", JSCompiler_StaticMethods_dispatchErrors_(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self)); | |
} finally { | |
JSCompiler_StaticMethods_cleanUpXhr_(JSCompiler_StaticMethods_onReadyStateChangeHelper_$self); | |
} | |
} | |
} | |
} | |
} | |
}, JSCompiler_StaticMethods_cleanUpXhr_ = function(JSCompiler_StaticMethods_cleanUpXhr_$self, opt_fromDispose) { | |
if (JSCompiler_StaticMethods_cleanUpXhr_$self.xhr_) { | |
JSCompiler_StaticMethods_cleanUpTimeoutTimer_(JSCompiler_StaticMethods_cleanUpXhr_$self); | |
var xhr = JSCompiler_StaticMethods_cleanUpXhr_$self.xhr_, clearedOnReadyStateChange = JSCompiler_StaticMethods_cleanUpXhr_$self.xhrOptions_[goog.net.XmlHttp.OptionType.USE_NULL_FUNCTION] ? goog.nullFunction : null; | |
JSCompiler_StaticMethods_cleanUpXhr_$self.xhr_ = null; | |
JSCompiler_StaticMethods_cleanUpXhr_$self.xhrOptions_ = null; | |
opt_fromDispose || JSCompiler_StaticMethods_cleanUpXhr_$self.dispatchEvent(goog.net.EventType.READY); | |
try { | |
xhr.onreadystatechange = clearedOnReadyStateChange; | |
} catch (e) { | |
goog.log.error(JSCompiler_StaticMethods_cleanUpXhr_$self.logger_, "Problem encountered resetting onreadystatechange: " + e.message); | |
} | |
} | |
}, JSCompiler_StaticMethods_cleanUpTimeoutTimer_ = function(JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self) { | |
JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.xhr_ && JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.useXhr2Timeout_ && (JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.xhr_[goog.net.XhrIo.XHR2_ON_TIMEOUT_] = null); | |
goog.isNumber(JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.timeoutId_) && (goog.Timer.clear(JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.timeoutId_), JSCompiler_StaticMethods_cleanUpTimeoutTimer_$self.timeoutId_ = null); | |
}; | |
goog.net.XhrIo.prototype.isActive = function() { | |
return!!this.xhr_; | |
}; | |
var JSCompiler_StaticMethods_isComplete = function(JSCompiler_StaticMethods_isComplete$self) { | |
return JSCompiler_StaticMethods_getReadyState(JSCompiler_StaticMethods_isComplete$self) == goog.net.XmlHttp.ReadyState.COMPLETE; | |
}; | |
goog.net.XhrIo.prototype.isSuccess = function() { | |
var status = this.getStatus(); | |
return goog.net.HttpStatus.isSuccess(status) || 0 === status && !JSCompiler_StaticMethods_isLastUriEffectiveSchemeHttp_(this); | |
}; | |
var JSCompiler_StaticMethods_isLastUriEffectiveSchemeHttp_ = function(JSCompiler_StaticMethods_isLastUriEffectiveSchemeHttp_$self) { | |
var scheme = goog.uri.utils.getEffectiveScheme(String(JSCompiler_StaticMethods_isLastUriEffectiveSchemeHttp_$self.lastUri_)); | |
return goog.net.XhrIo.HTTP_SCHEME_PATTERN.test(scheme); | |
}, JSCompiler_StaticMethods_getReadyState = function(JSCompiler_StaticMethods_getReadyState$self) { | |
return JSCompiler_StaticMethods_getReadyState$self.xhr_ ? JSCompiler_StaticMethods_getReadyState$self.xhr_.readyState : goog.net.XmlHttp.ReadyState.UNINITIALIZED; | |
}; | |
goog.net.XhrIo.prototype.getStatus = function() { | |
try { | |
return JSCompiler_StaticMethods_getReadyState(this) > goog.net.XmlHttp.ReadyState.LOADED ? this.xhr_.status : -1; | |
} catch (e) { | |
return-1; | |
} | |
}; | |
var JSCompiler_StaticMethods_getStatusText = function(JSCompiler_StaticMethods_getStatusText$self) { | |
try { | |
return JSCompiler_StaticMethods_getReadyState(JSCompiler_StaticMethods_getStatusText$self) > goog.net.XmlHttp.ReadyState.LOADED ? JSCompiler_StaticMethods_getStatusText$self.xhr_.statusText : ""; | |
} catch (e) { | |
return goog.log.fine(JSCompiler_StaticMethods_getStatusText$self.logger_, "Can not get status: " + e.message), ""; | |
} | |
}, JSCompiler_StaticMethods_getResponseText = function(JSCompiler_StaticMethods_getResponseText$self) { | |
try { | |
return JSCompiler_StaticMethods_getResponseText$self.xhr_ ? JSCompiler_StaticMethods_getResponseText$self.xhr_.responseText : ""; | |
} catch (e) { | |
return goog.log.fine(JSCompiler_StaticMethods_getResponseText$self.logger_, "Can not get responseText: " + e.message), ""; | |
} | |
}, JSCompiler_StaticMethods_formatMsg_ = function(JSCompiler_StaticMethods_formatMsg_$self, msg) { | |
return msg + " [" + JSCompiler_StaticMethods_formatMsg_$self.lastMethod_ + " " + JSCompiler_StaticMethods_formatMsg_$self.lastUri_ + " " + JSCompiler_StaticMethods_formatMsg_$self.getStatus() + "]"; | |
}; | |
goog.debug.entryPointRegistry.register(function(transformer) { | |
goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_ = transformer(goog.net.XhrIo.prototype.onReadyStateChangeEntryPoint_); | |
}); | |
var easyUnlock = {Delay:function() { | |
}}; | |
easyUnlock.Delay.prototype.start = function() { | |
}; | |
easyUnlock.Delay.prototype.stop = function() { | |
}; | |
easyUnlock.Delay.prototype.fire = function() { | |
}; | |
easyUnlock.Timer = function() { | |
}; | |
easyUnlock.Timer.prototype.getTime = function() { | |
}; | |
easyUnlock.Timer.prototype.createDelay = function() { | |
}; | |
easyUnlock.TimerImpl = function() { | |
}; | |
easyUnlock.TimerImpl.prototype.getTime = function() { | |
return(new Date).getTime() / 1E3; | |
}; | |
easyUnlock.TimerImpl.prototype.createDelay = function(callback, delaySecs) { | |
return new easyUnlock.DelayImpl(callback, delaySecs); | |
}; | |
easyUnlock.DelayImpl = function(callback, delaySecs) { | |
this.delay_ = new goog.async.Delay(callback, 1E3 * delaySecs); | |
}; | |
easyUnlock.DelayImpl.prototype.start = function() { | |
this.delay_.start(); | |
}; | |
easyUnlock.DelayImpl.prototype.stop = function() { | |
this.delay_.stop(); | |
}; | |
easyUnlock.DelayImpl.prototype.fire = function() { | |
this.delay_.fire(); | |
}; | |
easyUnlock.FakeTimer = function(initialTime) { | |
this.time_ = initialTime; | |
this.delays_ = []; | |
}; | |
easyUnlock.FakeTimer.prototype.getTime = function() { | |
return this.time_; | |
}; | |
easyUnlock.FakeTimer.prototype.createDelay = function(callback) { | |
var delay = new easyUnlock.FakeDelay(this, callback); | |
this.delays_.push(delay); | |
return delay; | |
}; | |
easyUnlock.FakeDelay = function(timer, callback) { | |
this.timer_ = timer; | |
this.callback_ = callback; | |
}; | |
easyUnlock.FakeDelay.prototype.start = function() { | |
}; | |
easyUnlock.FakeDelay.prototype.stop = function() { | |
}; | |
easyUnlock.FakeDelay.prototype.fire = function() { | |
this.stop(); | |
this.callback_(); | |
}; | |
var permit = {crypto:{}}; | |
permit.crypto.BLOCK_SIZE = 16; | |
permit.crypto.KEY_SIZE = 32; | |
permit.crypto.NONCE_SIZE = 32; | |
permit.crypto.IV_SIZE = 16; | |
function getRandomBytes(length) { | |
var array = new Uint8Array(length); | |
window.crypto.getRandomValues(array); | |
return array; | |
} | |
function padBytes(bytes) { | |
var blockSize = permit.crypto.BLOCK_SIZE, paddingLen = blockSize - bytes.length % blockSize; | |
if (0 == paddingLen) { | |
return bytes; | |
} | |
var result = new Uint8Array(bytes.length + paddingLen); | |
result.set(bytes); | |
for (var i = 0;i < paddingLen;i++) { | |
result[bytes.length + i] = paddingLen; | |
} | |
return result; | |
} | |
function unpadBytes(bytes) { | |
var paddingLen = bytes[bytes.length - 1]; | |
return 0 == paddingLen ? bytes : bytes.subarray(0, bytes.length - paddingLen); | |
} | |
permit.crypto.createInitializationVector = function() { | |
return getRandomBytes(permit.crypto.IV_SIZE); | |
}; | |
permit.crypto.createKey = function() { | |
return getRandomBytes(permit.crypto.KEY_SIZE); | |
}; | |
permit.crypto.createNonce = function() { | |
return getRandomBytes(permit.crypto.NONCE_SIZE); | |
}; | |
permit.crypto.encrypt = function(inputBytes, initializationVector, keyBytes) { | |
inputBytes = padBytes(inputBytes); | |
var aes = new goog.crypt.Aes(Array.apply([], keyBytes)); | |
return new Uint8Array((new goog.crypt.Cbc(aes)).encrypt(Array.apply([], inputBytes), Array.apply([], initializationVector))); | |
}; | |
permit.crypto.decrypt = function(inputBytes, initializationVector, keyBytes) { | |
var aes = new goog.crypt.Aes(Array.apply([], keyBytes)), decryptedBytes = (new goog.crypt.Cbc(aes)).decrypt(Array.apply([], inputBytes), Array.apply([], initializationVector)); | |
return unpadBytes(new Uint8Array(decryptedBytes)); | |
}; | |
permit.crypto.base64Encode = function(data) { | |
return goog.crypt.base64.encodeByteArray(data, !0).replace(/\./g, "="); | |
}; | |
permit.crypto.base64Decode = function(data) { | |
data = data.replace(/=/g, "."); | |
try { | |
var decoded = goog.crypt.base64.decodeStringToByteArray(data, !0); | |
return new Uint8Array(decoded); | |
} catch (e) { | |
return console.error("Failed to decode Base64 encoded data:\n" + data + "\n" + e), null; | |
} | |
}; | |
permit.PermitRecord = function(permitId, id, type, data) { | |
this.permitId = permitId; | |
this.id = id; | |
this.type = type; | |
this.data = data || new Uint8Array([]); | |
}; | |
permit.PermitRecord.Type = {ACCESS:"access", LICENSE:"license"}; | |
permit.PermitRecord.prototype.toJSON = function() { | |
return{permitId:this.permitId, id:this.id, type:this.type, data:permit.crypto.base64Encode(this.data)}; | |
}; | |
permit.PermitRecord.fromJSON = function(obj) { | |
var permitId = obj.permitId || null, id = obj.id || null, type = obj.type || null, data = permit.crypto.base64Decode(obj.data); | |
return null == permitId ? null : new permit.PermitRecord(permitId, id, type, data); | |
}; | |
easyUnlock.EasyUnlockDevice = function(bluetoothAddress, name, permitRecord) { | |
this.bluetoothAddress = bluetoothAddress; | |
this.name = name; | |
this.permitRecord = permitRecord || null; | |
}; | |
easyUnlock.EasyUnlockDevice.prototype.toJSON = function() { | |
return{bluetoothAddress:this.bluetoothAddress, name:this.name, permitRecord:this.permitRecord.toJSON()}; | |
}; | |
easyUnlock.EasyUnlockDevice.fromJSON = function(obj) { | |
var address = obj.bluetoothAddress || null, name = obj.name || null, permitRecord = permit.PermitRecord.fromJSON(obj.permitRecord); | |
return null == address || null == name ? null : new easyUnlock.EasyUnlockDevice(address, name, permitRecord); | |
}; | |
permit.util = {}; | |
permit.util.uint8ArrayConcatenate = function(array1, array2) { | |
var result = new Uint8Array(array1.length + array2.length); | |
result.set(array1); | |
result.set(array2, array1.length); | |
return result; | |
}; | |
permit.util.uint8ArrayToString = function(array) { | |
if (!array) { | |
return "<null>"; | |
} | |
for (var str = "[ ", i = 0;i < array.length;i++) { | |
str += array[i], i < array.length - 1 && (str += ", "); | |
} | |
return str + " ]"; | |
}; | |
permit.util.stringToUint8Array = function(string) { | |
return new Uint8Array(goog.crypt.stringToByteArray(string)); | |
}; | |
permit.util.uint8ArrayEquals = function(array1, array2) { | |
if (array1.length != array2.length) { | |
return!1; | |
} | |
for (var i = 0;i < array1.length;++i) { | |
if (array1[i] != array2[i]) { | |
return!1; | |
} | |
} | |
return!0; | |
}; | |
permit.edata = {}; | |
permit.edata.fromBytes = function(bytes, key) { | |
return 16 > bytes.length ? (console.error("Cannot read IV from bytes."), null) : permit.crypto.decrypt(bytes.subarray(16), bytes.subarray(0, 16), key); | |
}; | |
permit.edata.toBytes = function(data, key, iv) { | |
iv = iv || permit.crypto.createInitializationVector(); | |
var encrypted = permit.crypto.encrypt(data, iv, key); | |
return null == encrypted ? null : permit.util.uint8ArrayConcatenate(iv, encrypted); | |
}; | |
permit.Message = function(permitId, permitRecordId, permitRecordType, data, extraFields) { | |
this.permitId = permitId || null; | |
this.permitRecordId = permitRecordId || null; | |
this.permitRecordType = permitRecordType || permit.PermitRecord.Type.ACCESS; | |
this.data = data || new Uint8Array([]); | |
this.extraFields = extraFields || {}; | |
}; | |
permit.Message.HEADER_LENGTH = 3; | |
permit.Message.readVersionFromHeader = function(bytes) { | |
return 1 > bytes.length ? null : bytes[0]; | |
}; | |
permit.Message.readLengthFromHeader = function(bytes) { | |
return 3 > bytes.length ? null : bytes[1] << 8 | bytes[2]; | |
}; | |
permit.Message.fromBytes = function(messageBytes) { | |
if (3 > messageBytes.length) { | |
return console.error("Expected header when deserializing message, got " + messageBytes.length + " bytes."), null; | |
} | |
var messageVersion = permit.Message.readVersionFromHeader(messageBytes); | |
if (1 != messageVersion) { | |
return console.error("Expected message version 1, got " + messageVersion + " instead."), null; | |
} | |
var bodyLength = permit.Message.readLengthFromHeader(messageBytes), bodyBytes = messageBytes.subarray(3); | |
if (bodyLength != bodyBytes.length) { | |
return console.error("Invalid body length, got " + bodyBytes.length + " expected " + bodyLength), null; | |
} | |
var jsonString = goog.crypt.byteArrayToString(Array.apply([], bodyBytes)), jsonObj = null; | |
try { | |
jsonObj = JSON.parse(jsonString); | |
} catch (e) { | |
return console.error("Failed to parse message content: '" + jsonString + "'"), null; | |
} | |
return permit.Message.fromJSON(jsonObj); | |
}; | |
permit.Message.fromJSON = function(obj) { | |
var expectedFields = {}; | |
expectedFields.permit_id = obj.permit_id; | |
expectedFields.permit_access_id = obj.permit_access_id; | |
expectedFields.permit_license_id = obj.permit_license_id; | |
expectedFields.data = obj.data; | |
var permitRecordId = expectedFields.permit_access_id || expectedFields.permit_license_id, permitRecordType = void 0 != expectedFields.permit_access_id ? permit.PermitRecord.Type.ACCESS : permit.PermitRecord.Type.LICENSE, b64EncodedData = obj.data, data = b64EncodedData ? permit.crypto.base64Decode(b64EncodedData) : b64EncodedData, extraFields = {}, key; | |
for (key in obj) { | |
void 0 == expectedFields[key] && (extraFields[key] = obj[key]); | |
} | |
return new permit.Message(expectedFields.permit_id, permitRecordId, permitRecordType, data, extraFields); | |
}; | |
permit.Message.prototype.toBytes = function() { | |
var jsonString = JSON.stringify(this.toJSON()), bytes = new Uint8Array(goog.crypt.stringToByteArray(jsonString)), bodyLength = bytes.length, header = new Uint8Array([1, bodyLength >> 8, bodyLength & 255]); | |
return permit.util.uint8ArrayConcatenate(header, bytes); | |
}; | |
permit.Message.prototype.toJSON = function() { | |
var b64EncodedData = permit.crypto.base64Encode(this.data), recordIdKey = this.permitRecordType == permit.PermitRecord.Type.ACCESS ? "permit_access_id" : "permit_license_id", obj = {}; | |
obj.permit_id = this.permitId; | |
obj[recordIdKey] = this.permitRecordId; | |
obj.data = b64EncodedData; | |
for (var key in this.extraFields) { | |
obj[key] = this.extraFields[key]; | |
} | |
return obj; | |
}; | |
easyUnlock.ConnectionObserver = function() { | |
}; | |
easyUnlock.ConnectionObserver.prototype.onConnectionStatusChanged = function() { | |
}; | |
easyUnlock.ConnectionObserver.prototype.onMessageReceived = function() { | |
}; | |
easyUnlock.ConnectionObserver.prototype.onSendCompleted = function() { | |
}; | |
easyUnlock.Connection = function(easyUnlockDevice) { | |
this.easyUnlockDevice_ = easyUnlockDevice; | |
this.connectionStatus_ = easyUnlock.Connection.Status.DISCONNECTED; | |
this.observers_ = []; | |
this.buffer_ = new Uint8Array(0); | |
this.messageInProgress_ = null; | |
}; | |
easyUnlock.Connection.Status = {DISCONNECTED:0, IN_PROGRESS:1, CONNECTED:2}; | |
easyUnlock.Connection.prototype.getStatus = function() { | |
return this.connectionStatus_; | |
}; | |
var JSCompiler_StaticMethods_setStatus = function(JSCompiler_StaticMethods_setStatus$self, connectionStatus) { | |
if (JSCompiler_StaticMethods_setStatus$self.connectionStatus_ != connectionStatus) { | |
var oldStatus = JSCompiler_StaticMethods_setStatus$self.connectionStatus_; | |
JSCompiler_StaticMethods_setStatus$self.connectionStatus_ = connectionStatus; | |
JSCompiler_StaticMethods_setStatus$self.buffer_ = new Uint8Array(0); | |
for (var i = 0;i < JSCompiler_StaticMethods_setStatus$self.observers_.length;++i) { | |
JSCompiler_StaticMethods_setStatus$self.observers_[i].onConnectionStatusChanged(oldStatus, JSCompiler_StaticMethods_setStatus$self.connectionStatus_); | |
} | |
} | |
}; | |
easyUnlock.Connection.prototype.isConnected = function() { | |
return this.connectionStatus_ == easyUnlock.Connection.Status.CONNECTED; | |
}; | |
var JSCompiler_StaticMethods_getRemoteDevice = function(JSCompiler_StaticMethods_getRemoteDevice$self) { | |
return JSCompiler_StaticMethods_getRemoteDevice$self.easyUnlockDevice_; | |
}; | |
easyUnlock.Connection.prototype.sendMessage = function(message) { | |
null != this.messageInProgress_ ? console.error("Another message is currently in progress.") : (this.messageInProgress_ = message, this.sendBytes(message.toBytes())); | |
}; | |
var JSCompiler_StaticMethods_cancelSendMessage = function(JSCompiler_StaticMethods_cancelSendMessage$self) { | |
JSCompiler_StaticMethods_cancelSendMessage$self.messageInProgress_ && (JSCompiler_StaticMethods_cancelSendMessage$self.messageInProgress_ = null); | |
}, JSCompiler_StaticMethods_addObserver = function(JSCompiler_StaticMethods_addObserver$self, observer) { | |
JSCompiler_StaticMethods_addObserver$self.observers_.push(observer); | |
}, JSCompiler_StaticMethods_removeObserver = function(JSCompiler_StaticMethods_removeObserver$self, observer) { | |
var idx = JSCompiler_StaticMethods_removeObserver$self.observers_.indexOf(observer); | |
-1 == idx ? console.warn("Observer was not added.") : JSCompiler_StaticMethods_removeObserver$self.observers_.splice(idx, 1); | |
}; | |
easyUnlock.Connection.prototype.setPaused = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.connect = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.disconnect = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.startDiscovery = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.stopDiscovery = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.sendBytes = function() { | |
throw "Not Implemented"; | |
}; | |
easyUnlock.Connection.prototype.onSendCompleted = function(success) { | |
if (null == this.messageInProgress_) { | |
console.error("Send completed, but no message in progress."); | |
} else { | |
for (var i = 0;i < this.observers_.length;++i) { | |
this.observers_[i].onSendCompleted(this.messageInProgress_, success); | |
} | |
this.messageInProgress_ = null; | |
} | |
}; | |
var JSCompiler_StaticMethods_onBytesReceived = function(JSCompiler_StaticMethods_onBytesReceived$self, bytes) { | |
if (JSCompiler_StaticMethods_onBytesReceived$self.isConnected()) { | |
JSCompiler_StaticMethods_onBytesReceived$self.buffer_ = permit.util.uint8ArrayConcatenate(JSCompiler_StaticMethods_onBytesReceived$self.buffer_, bytes); | |
var messageLength = permit.Message.readLengthFromHeader(JSCompiler_StaticMethods_onBytesReceived$self.buffer_) + permit.Message.HEADER_LENGTH; | |
if (messageLength && JSCompiler_StaticMethods_onBytesReceived$self.buffer_.length >= messageLength) { | |
var message = permit.Message.fromBytes(JSCompiler_StaticMethods_onBytesReceived$self.buffer_.subarray(0, messageLength)); | |
if (message) { | |
JSCompiler_StaticMethods_onBytesReceived$self.buffer_ = JSCompiler_StaticMethods_onBytesReceived$self.buffer_.subarray(messageLength); | |
for (var i = 0;i < JSCompiler_StaticMethods_onBytesReceived$self.observers_.length;++i) { | |
JSCompiler_StaticMethods_onBytesReceived$self.observers_[i].onMessageReceived(message); | |
} | |
} else { | |
console.error("Error: Unable to parse message."); | |
} | |
} | |
} else { | |
console.error("Received bytes, but not connected."); | |
} | |
}; | |
easyUnlock.AuthenticatorDelegate = function() { | |
}; | |
easyUnlock.AuthenticatorDelegate.prototype.onAuthenticationChanged = function() { | |
}; | |
easyUnlock.AuthenticatorDelegate.prototype.onAuthenticationRefreshed = function() { | |
}; | |
easyUnlock.AuthenticatorDelegate.prototype.onAuthenticationFailed = function() { | |
}; | |
easyUnlock.AuthenticatorDelegate.prototype.onAuthenticatorConnnectionChanged = function() { | |
}; | |
easyUnlock.Authenticator = function(connection, permitAccess, delegate, timer) { | |
this.connection_ = connection; | |
this.permitAccess_ = permitAccess; | |
this.delegate_ = delegate; | |
this.timer_ = timer; | |
this.requestContext_ = this.lastSuccessTimestamp_ = null; | |
this.retryQueued_ = !1; | |
this.reauthDelay_ = this.timer_.createDelay(this.reauthTimeout_.bind(this), easyUnlock.Authenticator.AUTHENTICATION_TIME_SECS - easyUnlock.Authenticator.REAUTH_BEFORE_TIMEOUT_SECS); | |
this.deauthDelay_ = this.timer_.createDelay(this.deauthTimeout_.bind(this), easyUnlock.Authenticator.AUTHENTICATION_TIME_SECS); | |
}; | |
easyUnlock.Authenticator.RequestContext = function(nonce, request) { | |
this.nonce = nonce; | |
this.request = request; | |
}; | |
easyUnlock.Authenticator.AUTHENTICATION_TIME_SECS = 600; | |
easyUnlock.Authenticator.REAUTH_BEFORE_TIMEOUT_SECS = 30; | |
easyUnlock.Authenticator.STATUS_SUCCESS = "success"; | |
easyUnlock.Authenticator.STATUS_FAILURE = "failure"; | |
easyUnlock.Authenticator.STATUS_RETRY = "retry"; | |
easyUnlock.Authenticator.prototype.start = function() { | |
JSCompiler_StaticMethods_addObserver(this.connection_, this); | |
this.connection_.setPaused(!1); | |
this.connection_.isConnected() ? JSCompiler_StaticMethods_requestAuthentication(this) : this.connection_.startDiscovery(); | |
}; | |
easyUnlock.Authenticator.prototype.stop = function() { | |
this.isAuthenticated() && JSCompiler_StaticMethods_deauthenticate(this); | |
JSCompiler_StaticMethods_removeObserver(this.connection_, this); | |
}; | |
easyUnlock.Authenticator.prototype.isAuthenticated = function() { | |
return null == this.lastSuccessTimestamp_ ? !1 : this.connection_.isConnected() && this.timer_.getTime() - this.lastSuccessTimestamp_ <= easyUnlock.Authenticator.AUTHENTICATION_TIME_SECS; | |
}; | |
easyUnlock.Authenticator.prototype.isConnected = function() { | |
return this.connection_.isConnected(); | |
}; | |
var JSCompiler_StaticMethods_deauthenticate = function(JSCompiler_StaticMethods_deauthenticate$self) { | |
var wasAuthenticated = null != JSCompiler_StaticMethods_deauthenticate$self.lastSuccessTimestamp_; | |
JSCompiler_StaticMethods_deauthenticate$self.lastSuccessTimestamp_ = null; | |
JSCompiler_StaticMethods_deauthenticate$self.requestContext_ = null; | |
JSCompiler_StaticMethods_cancelSendMessage(JSCompiler_StaticMethods_deauthenticate$self.connection_); | |
JSCompiler_StaticMethods_deauthenticate$self.reauthDelay_.stop(); | |
JSCompiler_StaticMethods_deauthenticate$self.deauthDelay_.stop(); | |
if (wasAuthenticated) { | |
JSCompiler_StaticMethods_deauthenticate$self.delegate_.onAuthenticationChanged(!1); | |
} | |
JSCompiler_StaticMethods_deauthenticate$self.retryQueued_ && (JSCompiler_StaticMethods_deauthenticate$self.retryQueued_ = !1, JSCompiler_StaticMethods_requestAuthentication(JSCompiler_StaticMethods_deauthenticate$self)); | |
}, JSCompiler_StaticMethods_authenticate_ = function(JSCompiler_StaticMethods_authenticate_$self) { | |
var wasAuthenticated = JSCompiler_StaticMethods_authenticate_$self.isAuthenticated(); | |
JSCompiler_StaticMethods_authenticate_$self.lastSuccessTimestamp_ = JSCompiler_StaticMethods_authenticate_$self.timer_.getTime(); | |
JSCompiler_StaticMethods_authenticate_$self.requestContext_ = null; | |
JSCompiler_StaticMethods_authenticate_$self.reauthDelay_.start(); | |
JSCompiler_StaticMethods_authenticate_$self.deauthDelay_.start(); | |
if (wasAuthenticated) { | |
JSCompiler_StaticMethods_authenticate_$self.delegate_.onAuthenticationRefreshed(); | |
} else { | |
JSCompiler_StaticMethods_authenticate_$self.delegate_.onAuthenticationChanged(!0); | |
} | |
JSCompiler_StaticMethods_authenticate_$self.retryQueued_ && (JSCompiler_StaticMethods_authenticate_$self.retryQueued_ = !1, JSCompiler_StaticMethods_requestAuthentication(JSCompiler_StaticMethods_authenticate_$self)); | |
}, JSCompiler_StaticMethods_requestAuthentication = function(JSCompiler_StaticMethods_requestAuthentication$self) { | |
JSCompiler_StaticMethods_requestAuthentication$self.connection_.isConnected() ? JSCompiler_StaticMethods_requestAuthentication$self.requestContext_ ? console.warn("[Auth] Already handling another request.") : (console.log("[Auth] Requesting authentication..."), JSCompiler_StaticMethods_requestAuthentication$self.reauthDelay_.stop(), JSCompiler_StaticMethods_requestAuthentication$self.requestContext_ = JSCompiler_StaticMethods_createRequestContext_(JSCompiler_StaticMethods_requestAuthentication$self), | |
JSCompiler_StaticMethods_requestAuthentication$self.connection_.sendMessage(JSCompiler_StaticMethods_requestAuthentication$self.requestContext_.request)) : console.warn("[Auth] Requesting authentication, but not connected."); | |
}, JSCompiler_StaticMethods_createRequestContext_ = function(JSCompiler_StaticMethods_createRequestContext_$self) { | |
var permitId = JSCompiler_StaticMethods_createRequestContext_$self.permitAccess_.permitId, nonce = permit.crypto.createNonce(), permitIdBytes = permit.util.stringToUint8Array(permitId), payload = permit.edata.toBytes(permit.util.uint8ArrayConcatenate(nonce, permitIdBytes), JSCompiler_StaticMethods_createRequestContext_$self.permitAccess_.data), requestMessage = new permit.Message(permitId, JSCompiler_StaticMethods_createRequestContext_$self.permitAccess_.id, permit.PermitRecord.Type.ACCESS, payload); | |
return new easyUnlock.Authenticator.RequestContext(nonce, requestMessage); | |
}, JSCompiler_StaticMethods_verifyAuthResponse_ = function(JSCompiler_StaticMethods_verifyAuthResponse_$self, message) { | |
if (null == JSCompiler_StaticMethods_verifyAuthResponse_$self.requestContext_ || !JSCompiler_StaticMethods_verifyAuthResponse_$self.connection_.isConnected() || message.permitId != JSCompiler_StaticMethods_verifyAuthResponse_$self.permitAccess_.permitId) { | |
return!1; | |
} | |
var permitLicense = JSCompiler_StaticMethods_getRemoteDevice(JSCompiler_StaticMethods_verifyAuthResponse_$self.connection_).permitRecord; | |
if (message.permitRecordType != permitLicense.type || message.permitRecordId != permitLicense.id || message.extraFields.status != easyUnlock.Authenticator.STATUS_SUCCESS) { | |
return!1; | |
} | |
var decrypted = permit.edata.fromBytes(message.data, permitLicense.data); | |
if (null == decrypted) { | |
return!1; | |
} | |
var nonce = JSCompiler_StaticMethods_verifyAuthResponse_$self.requestContext_.nonce, permitIdBytes = permit.util.stringToUint8Array(JSCompiler_StaticMethods_verifyAuthResponse_$self.permitAccess_.permitId), expectedData = permit.util.uint8ArrayConcatenate(nonce, permitIdBytes); | |
return permit.util.uint8ArrayEquals(expectedData, decrypted); | |
}; | |
easyUnlock.Authenticator.prototype.onConnectionStatusChanged = function(oldStatus, newStatus) { | |
newStatus == easyUnlock.Connection.Status.CONNECTED ? JSCompiler_StaticMethods_requestAuthentication(this) : (JSCompiler_StaticMethods_deauthenticate(this), newStatus == easyUnlock.Connection.Status.DISCONNECTED && this.connection_.startDiscovery()); | |
this.delegate_.onAuthenticatorConnnectionChanged(); | |
}; | |
easyUnlock.Authenticator.prototype.onMessageReceived = function(message) { | |
var status = message.extraFields.status; | |
status == easyUnlock.Authenticator.STATUS_SUCCESS ? JSCompiler_StaticMethods_processSuccess_(this, message) : status == easyUnlock.Authenticator.STATUS_FAILURE ? JSCompiler_StaticMethods_processFailure_(this) : status == easyUnlock.Authenticator.STATUS_RETRY ? JSCompiler_StaticMethods_processRetry_(this) : (console.error("[Auth] Received invalid message:"), console.error(message), JSCompiler_StaticMethods_deauthenticate(this)); | |
}; | |
easyUnlock.Authenticator.prototype.onSendCompleted = function(message, success) { | |
if (success) { | |
if (null == this.requestContext_ || this.requestContext_.request != message) { | |
console.error("[Auth] Sent message successfully, but no request in progress."), JSCompiler_StaticMethods_deauthenticate(this); | |
} | |
} else { | |
console.log("[Auth] Request failed, deauthenticating."), JSCompiler_StaticMethods_deauthenticate(this); | |
} | |
}; | |
var JSCompiler_StaticMethods_processSuccess_ = function(JSCompiler_StaticMethods_processSuccess_$self, message) { | |
JSCompiler_StaticMethods_processSuccess_$self.requestContext_ ? JSCompiler_StaticMethods_verifyAuthResponse_(JSCompiler_StaticMethods_processSuccess_$self, message) && JSCompiler_StaticMethods_authenticate_(JSCompiler_StaticMethods_processSuccess_$self) : console.warn("[Auth] Got success response, but no request in progress."); | |
}, JSCompiler_StaticMethods_processFailure_ = function(JSCompiler_StaticMethods_processFailure_$self) { | |
console.log("[Auth] Authentication request failed."); | |
JSCompiler_StaticMethods_deauthenticate(JSCompiler_StaticMethods_processFailure_$self); | |
JSCompiler_StaticMethods_processFailure_$self.delegate_.onAuthenticationFailed(); | |
}, JSCompiler_StaticMethods_processRetry_ = function(JSCompiler_StaticMethods_processRetry_$self) { | |
JSCompiler_StaticMethods_processRetry_$self.requestContext_ ? (console.warn("[Auth] Got retry message, but request currently in progress. Queueing retry..."), JSCompiler_StaticMethods_processRetry_$self.retryQueued_ = !0) : (console.log("[Auth] Retry message received..."), JSCompiler_StaticMethods_requestAuthentication(JSCompiler_StaticMethods_processRetry_$self)); | |
}; | |
easyUnlock.Authenticator.prototype.reauthTimeout_ = function() { | |
console.log("[Auth] Reauthentication timeout..."); | |
JSCompiler_StaticMethods_requestAuthentication(this); | |
}; | |
easyUnlock.Authenticator.prototype.deauthTimeout_ = function() { | |
console.log("[Auth] Deauthentication timeout..."); | |
JSCompiler_StaticMethods_deauthenticate(this); | |
}; | |
easyUnlock.MessageBuffer = function() { | |
this.messages_ = []; | |
}; | |
easyUnlock.MessageBuffer.prototype.onMessageReceived = function() { | |
}; | |
easyUnlock.MessageBuffer.prototype.onConnectionStatusChanged = function() { | |
}; | |
easyUnlock.MessageBuffer.prototype.onSendCompleted = function(message) { | |
this.messages_.push(message); | |
}; | |
easyUnlock.FakeConnection = function(easyUnlockDevice) { | |
easyUnlock.Connection.call(this, easyUnlockDevice); | |
this.remoteInRange_ = !1; | |
this.remoteBytes_ = new Uint8Array([]); | |
}; | |
goog.inherits(easyUnlock.FakeConnection, easyUnlock.Connection); | |
easyUnlock.FakeConnection.prototype.setPaused = function(paused) { | |
!paused && 0 < this.remoteBytes_.length && (JSCompiler_StaticMethods_onBytesReceived(this, this.remoteBytes_), this.remoteBytes_ = new Uint8Array([])); | |
}; | |
easyUnlock.FakeConnection.prototype.connect = function() { | |
if (this.getStatus() != easyUnlock.Connection.Status.DISCONNECTED) { | |
throw "Connect called but not disconnected."; | |
} | |
this.remoteInRange_ && JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.CONNECTED); | |
}; | |
easyUnlock.FakeConnection.prototype.disconnect = function() { | |
if (this.getStatus() != easyUnlock.Connection.Status.CONNECTED) { | |
throw "Disconnect called but not connected."; | |
} | |
JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.DISCONNECTED); | |
}; | |
easyUnlock.FakeConnection.prototype.startDiscovery = function() { | |
this.remoteInRange_ && this.connect(); | |
}; | |
easyUnlock.FakeConnection.prototype.stopDiscovery = function() { | |
}; | |
easyUnlock.FakeConnection.prototype.sendBytes = function() { | |
if (this.getStatus() != easyUnlock.Connection.Status.CONNECTED) { | |
throw "Can not send bytes when not connected."; | |
} | |
this.onSendCompleted(!0); | |
}; | |
easyUnlock.SetupFlowDelegate = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.getPermitAccess = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.setPermitAccess = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.getBluetoothAddress = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.getUserGaiaId = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.pingUserDevices = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.scanForDevices = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.onSetupCompleted = function() { | |
}; | |
easyUnlock.SetupFlowDelegate.prototype.onSetupFailed = function() { | |
}; | |
easyUnlock.SetupFlow = function(delegate, timer) { | |
this.delegate_ = delegate; | |
this.timer_ = timer; | |
this.state_ = easyUnlock.SetupFlow.State.NOT_STARTED; | |
this.tmpKey_ = null; | |
this.pairingDelay_ = this.timer_.createDelay(this.onPairingTimedOut_.bind(this), easyUnlock.SetupFlow.PAIRING_TIMEOUT_SECS); | |
this.pairingHandlers_ = []; | |
this.pairedDevices_ = null; | |
}; | |
easyUnlock.SetupFlow.PAIRING_TIMEOUT_SECS = 5; | |
easyUnlock.SetupFlow.EASY_UNLOCK_PERMIT_ID_PREFIX = "permit://google.com/easyunlock/v1/"; | |
easyUnlock.SetupFlow.State = {NOT_STARTED:0, PINGING_DEVICES:1, SCANNING_DEVICES:2, PAIRING_DEVICES:3, FAILED:4}; | |
easyUnlock.SetupFlow.prototype.start = function() { | |
if (this.state_ != easyUnlock.SetupFlow.State.NOT_STARTED) { | |
throw "Flow has already started."; | |
} | |
var permitAccess = this.delegate_.getPermitAccess(); | |
null == permitAccess && (permitAccess = JSCompiler_StaticMethods_generatePermitAccess_(this), this.delegate_.setPermitAccess(permitAccess)); | |
this.tmpKey_ = permit.crypto.createKey(); | |
var pingData = JSCompiler_StaticMethods_createPingData_(this, permitAccess); | |
this.state_ = easyUnlock.SetupFlow.State.PINGING_DEVICES; | |
this.delegate_.pingUserDevices(pingData, this.onPingCompleted_.bind(this)); | |
}; | |
var JSCompiler_StaticMethods_generatePermitAccess_ = function(JSCompiler_StaticMethods_generatePermitAccess_$self) { | |
var permitId = easyUnlock.SetupFlow.EASY_UNLOCK_PERMIT_ID_PREFIX + JSCompiler_StaticMethods_generatePermitAccess_$self.delegate_.getUserGaiaId(), randomId = "[" + JSCompiler_StaticMethods_generatePermitAccess_$self.delegate_.getUserGaiaId() + "-" + Math.random() + "]"; | |
return new permit.PermitRecord(permitId, randomId, permit.PermitRecord.Type.ACCESS, permit.crypto.createKey()); | |
}, JSCompiler_StaticMethods_createPingData_ = function(JSCompiler_StaticMethods_createPingData_$self, permitAccess) { | |
return{bluetooth_address:JSCompiler_StaticMethods_createPingData_$self.delegate_.getBluetoothAddress(), permit_access_id:permitAccess.id, permit_access_data:permit.crypto.base64Encode(permitAccess.data), tmp_key:permit.crypto.base64Encode(JSCompiler_StaticMethods_createPingData_$self.tmpKey_)}; | |
}; | |
easyUnlock.SetupFlow.prototype.onPingCompleted_ = function(success) { | |
if (this.state_ != easyUnlock.SetupFlow.State.PINGING_DEVICES) { | |
throw "Expected state PINGING_DEVICES."; | |
} | |
success ? (this.state_ = easyUnlock.SetupFlow.State.SCANNING_DEVICES, this.delegate_.scanForDevices(this.onScanCompleted_.bind(this))) : JSCompiler_StaticMethods_fail_(this); | |
}; | |
easyUnlock.SetupFlow.prototype.onScanCompleted_ = function(connections) { | |
if (this.state_ != easyUnlock.SetupFlow.State.SCANNING_DEVICES) { | |
throw "Expected state SCANNING_DEVICES."; | |
} | |
if (0 == connections.length) { | |
JSCompiler_StaticMethods_fail_(this); | |
} else { | |
this.state_ = easyUnlock.SetupFlow.State.PAIRING_DEVICES; | |
this.pairedDevices_ = []; | |
this.pairingDelay_.start(); | |
this.pairingHandlers_ = []; | |
for (var i = 0;i < connections.length;++i) { | |
var handler = new easyUnlock.PairingHandler(connections[i], this.tmpKey_, this.delegate_.getPermitAccess(), this); | |
this.pairingHandlers_.push(handler); | |
handler.start(); | |
} | |
} | |
}; | |
easyUnlock.SetupFlow.prototype.onPairingTimedOut_ = function() { | |
if (this.state_ != easyUnlock.SetupFlow.State.PAIRING_DEVICES) { | |
throw "Expected state PAIRING_DEVICES."; | |
} | |
for (var i = 0;i < this.pairingHandlers_.length;++i) { | |
this.pairingHandlers_[i].stop(); | |
} | |
}; | |
var JSCompiler_StaticMethods_onPairingHandlerCompleted = function(JSCompiler_StaticMethods_onPairingHandlerCompleted$self, handler, device) { | |
null != device && JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairedDevices_.push(device); | |
var idx = JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairingHandlers_.indexOf(handler); | |
JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairingHandlers_.splice(idx, 1); | |
if (0 == JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairingHandlers_.length) { | |
if (0 < JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairedDevices_.length) { | |
JSCompiler_StaticMethods_onPairingHandlerCompleted$self.delegate_.onSetupCompleted(JSCompiler_StaticMethods_onPairingHandlerCompleted$self.pairedDevices_); | |
} else { | |
JSCompiler_StaticMethods_onPairingHandlerCompleted$self.delegate_.onSetupFailed(); | |
} | |
} | |
}, JSCompiler_StaticMethods_fail_ = function(JSCompiler_StaticMethods_fail_$self) { | |
JSCompiler_StaticMethods_fail_$self.state_ = easyUnlock.SetupFlow.State.FAILED; | |
JSCompiler_StaticMethods_fail_$self.delegate_.onSetupFailed(); | |
}; | |
easyUnlock.PairingHandler = function(connection, tmpKey, permitAccess, setupFlow) { | |
this.connection_ = connection; | |
this.tmpKey_ = tmpKey; | |
this.permitAccess_ = permitAccess; | |
this.setupFlow_ = setupFlow; | |
this.device_ = JSCompiler_StaticMethods_getRemoteDevice(connection); | |
}; | |
easyUnlock.PairingHandler.prototype.start = function() { | |
JSCompiler_StaticMethods_addObserver(this.connection_, this); | |
this.connection_.isConnected() || this.stop(); | |
this.connection_.setPaused(!1); | |
}; | |
easyUnlock.PairingHandler.prototype.stop = function() { | |
JSCompiler_StaticMethods_removeObserver(this.connection_, this); | |
JSCompiler_StaticMethods_onPairingHandlerCompleted(this.setupFlow_, this, null); | |
}; | |
var JSCompiler_StaticMethods_sendAck_ = function(JSCompiler_StaticMethods_sendAck_$self) { | |
var permitIdBytes = permit.util.stringToUint8Array(JSCompiler_StaticMethods_sendAck_$self.permitAccess_.permitId), edata = permit.edata.toBytes(permitIdBytes, JSCompiler_StaticMethods_sendAck_$self.permitAccess_.data), ack = new permit.Message(JSCompiler_StaticMethods_sendAck_$self.permitAccess_.permitId, JSCompiler_StaticMethods_sendAck_$self.permitAccess_.id, permit.PermitRecord.Type.ACCESS, edata); | |
JSCompiler_StaticMethods_sendAck_$self.connection_.sendMessage(ack); | |
}; | |
easyUnlock.PairingHandler.prototype.onMessageReceived = function(message) { | |
var permitId = message.permitId, permitLicenseId = message.permitRecordId; | |
if (permitId != this.permitAccess_.permitId || null == permitLicenseId || message.permitRecordType != permit.PermitRecord.Type.LICENSE) { | |
console.warn("Invalid permit identifier information in response."), JSCompiler_StaticMethods_onPairingHandlerCompleted(this.setupFlow_, this, null); | |
} else { | |
var payload = permit.edata.fromBytes(message.data, this.tmpKey_), permitIdBytes = permit.util.stringToUint8Array(permitId); | |
if (permit.util.uint8ArrayEquals(permitIdBytes, payload.subarray(0, permitIdBytes.length))) { | |
var licenseData = payload.subarray(permitIdBytes.length); | |
if (licenseData.length != permit.crypto.KEY_SIZE) { | |
console.warn("Invalid key length in response payload."), JSCompiler_StaticMethods_onPairingHandlerCompleted(this.setupFlow_, this, null); | |
} else { | |
var permitLicense = new permit.PermitRecord(permitId, permitLicenseId, permit.PermitRecord.Type.LICENSE, licenseData); | |
this.device_.permitRecord = permitLicense; | |
JSCompiler_StaticMethods_sendAck_(this); | |
} | |
} else { | |
console.warn("Permit id not found in response payload."), JSCompiler_StaticMethods_onPairingHandlerCompleted(this.setupFlow_, this, null); | |
} | |
} | |
}; | |
easyUnlock.PairingHandler.prototype.onConnectionStatusChanged = function(oldStatus, newStatus) { | |
newStatus != easyUnlock.Connection.Status.CONNECTED && this.stop(); | |
}; | |
easyUnlock.PairingHandler.prototype.onSendCompleted = function(message) { | |
message.permitId == this.permitAccess_.permitId ? (JSCompiler_StaticMethods_removeObserver(this.connection_, this), JSCompiler_StaticMethods_onPairingHandlerCompleted(this.setupFlow_, this, this.device_)) : (console.error("Sent unexpected message:"), console.error(message)); | |
}; | |
easyUnlock.FakeSetupFlowDelegate = function(bluetoothAddress, gaiaId) { | |
this.bluetoothAddress_ = bluetoothAddress; | |
this.gaiaId_ = gaiaId; | |
this.permitAccess_ = null; | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.getPermitAccess = function() { | |
return this.permitAccess_; | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.setPermitAccess = function(permitAccess) { | |
this.permitAccess_ = permitAccess; | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.getBluetoothAddress = function() { | |
return this.bluetoothAddress_; | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.getUserGaiaId = function() { | |
return this.gaiaId_; | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.pingUserDevices = function() { | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.scanForDevices = function() { | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.onSetupCompleted = function() { | |
}; | |
easyUnlock.FakeSetupFlowDelegate.prototype.onSetupFailed = function() { | |
}; | |
var app = {Bluetooth:{}}; | |
app.Bluetooth.UNLOCK_PROFILE = {uuid:"0000AB34-0000-1000-8000-00805F9B34FB", name:"Easy Unlock", channel:14, requireAuthorization:!1, requireAuthentication:!1, autoConnect:!0}; | |
app.Bluetooth.SETUP_PROFILE = {uuid:"29422880-D56D-11E3-9C1A-0800200C9A66", name:"Easy Unlock Registration", channel:13, requireAuthorization:!1, requireAuthentication:!1, autoConnect:!0}; | |
app.Bluetooth.adapterState = null; | |
app.Bluetooth.connectionCallback = null; | |
app.Bluetooth.profile = null; | |
app.Bluetooth.refreshAdapterState = function(callback) { | |
chrome.bluetooth.getAdapterState(function(adapterStateParam) { | |
app.Bluetooth.adapterState = adapterStateParam; | |
callback(app.Bluetooth.adapterState); | |
}); | |
}; | |
app.Bluetooth.registerProfile = function(profile) { | |
null != app.Bluetooth.profile ? console.log("[BT] Another profile is already registered: " + app.Bluetooth.profile.uuid + ".") : (chrome.bluetooth.addProfile(profile, function() { | |
chrome.runtime.lastError ? console.error("[BT] Could not add profile: " + chrome.runtime.lastError.message) : console.log("[BT] Profile added channel=" + profile.channel); | |
}), app.Bluetooth.profile = profile); | |
}; | |
app.Bluetooth.unregisterProfile = function() { | |
var profile = app.Bluetooth.SETUP_PROFILE; | |
null == app.Bluetooth.profile ? console.log("[BT] Profile not found: " + profile.uuid + ".") : chrome.bluetooth.removeProfile(profile, function() { | |
chrome.runtime.lastError ? console.log("[BT] Could not unregister profile: " + chrome.runtime.lastError.message) : (console.log("[BT] Profile unregistered."), app.Bluetooth.profile = null); | |
}); | |
}; | |
app.Bluetooth.writeToSocket = function(socket, data, callback) { | |
app.Bluetooth.stopListeningOverBluetooth(); | |
chrome.bluetoothSocket.send(socket.id, data, function(bytesWritten) { | |
var success = !0; | |
chrome.runtime.lastError ? (success = !1, console.log("[BT] Failed to write to BT socket: " + chrome.runtime.lastError.message)) : console.log("[BT] Successfully wrote " + bytesWritten + " bytes."); | |
callback(success); | |
}); | |
}; | |
app.Bluetooth.readFromSocket = function(socket, callback) { | |
var onRead = null, timeoutGuard = new goog.async.Delay(function() { | |
console.error("[BT] Timeout while waiting to read from socket"); | |
if (null == onRead) { | |
throw "Callback expected to be non-null"; | |
} | |
chrome.bluetoothSocket.onReceive.removeListener(onRead); | |
chrome.bluetoothSocket.setPaused(socket.id, !0); | |
callback(!0, new Uint8Array([])); | |
}, 5E3); | |
timeoutGuard.start(); | |
onRead = function(info) { | |
var data = info.data; | |
timeoutGuard.stop(); | |
if (chrome.runtime.lastError) { | |
console.error("[BT] Failed to read from Bluetooth socket " + chrome.runtime.lastError.message), callback(!1, null); | |
} else { | |
if (data && 0 != data.byteLength) { | |
var buffer = data ? new Uint8Array(data) : new Uint8Array([]); | |
console.log("[BT] Read " + buffer.byteLength + " bytes from Bluetooth socket."); | |
callback(!0, buffer); | |
if (null == onRead) { | |
throw "Callback expected to be non-null"; | |
} | |
chrome.bluetoothSocket.onReceive.removeListener(onRead); | |
chrome.bluetoothSocket.setPaused(socket.id, !0); | |
} else { | |
callback(!0, new Uint8Array([])); | |
} | |
} | |
}; | |
chrome.bluetoothSocket.onReceive.addListener(onRead); | |
chrome.bluetoothSocket.setPaused(socket.id, !1); | |
}; | |
app.Bluetooth.onConnectionListenerForReading_ = function(socket) { | |
console.log("[BT] Connection received for reading."); | |
app.Bluetooth.isListening ? app.Bluetooth.connectionCallback(socket) : console.error("[BT] bluetooth.onConnection event listener called when not listening"); | |
}; | |
app.Bluetooth.startListeningOverBluetooth = function(callback) { | |
app.Bluetooth.isListening && app.Bluetooth.stopListeningOverBluetooth(); | |
app.Bluetooth.isListening = !0; | |
app.Bluetooth.connectionCallback = callback; | |
chrome.bluetooth.onConnection.addListener(app.Bluetooth.onConnectionListenerForReading_); | |
}; | |
app.Bluetooth.stopListeningOverBluetooth = function() { | |
app.Bluetooth.isListening = !1; | |
app.Bluetooth.connectionCallback = null; | |
chrome.bluetooth.onConnection.removeListener(app.Bluetooth.onConnectionListenerForReading_); | |
}; | |
app.Bluetooth.openConnection = function(deviceInfo, callback) { | |
if (app.Bluetooth.isListening) { | |
console.error("[BT] Cannot open connection while listening."), callback(null); | |
} else { | |
if (null == app.Bluetooth.profile) { | |
console.error("[BT] No profile registered."), callback(null); | |
} else { | |
var guard = null, onConnectionListener = function(socket) { | |
console.log("[BT] Bluetooth connection established with " + socket.device.address); | |
callback(socket); | |
chrome.bluetooth.onConnection.removeListener(onConnectionListener); | |
window.clearTimeout(guard); | |
}, guard = window.setTimeout(function() { | |
console.log("[BT] Bluetooth connection timed out."); | |
chrome.bluetooth.onConnection.removeListener(onConnectionListener); | |
guard = null; | |
callback(null); | |
}, 1E4); | |
chrome.bluetooth.onConnection.addListener(onConnectionListener); | |
chrome.bluetooth.connect({device:{address:deviceInfo.bluetoothAddress, deviceClass:10390323}, profile:{uuid:app.Bluetooth.profile.uuid}}, function() { | |
null == guard ? console.error("[BT] Connection already timed out, error: " + chrome.runtime.lastError) : chrome.runtime.lastError && (console.error("[BT] Could not connect to device: " + chrome.runtime.lastError.message), "No such file or directory" == chrome.runtime.lastError.message && chrome.runtime.reload(), chrome.bluetooth.onConnection.removeListener(onConnectionListener), window.clearTimeout(guard), callback(null)); | |
}); | |
} | |
} | |
}; | |
app.Bluetooth.closeConnection = function(socket) { | |
socket ? chrome.bluetoothSocket.close(socket.id, function() { | |
chrome.runtime.lastError && console.warn("[BT] Failed to close socket " + chrome.runtime.lastError.message); | |
}) : console.warn("[BT] Attempting to close null socket."); | |
}; | |
app.Bluetooth.startAuthorizingPairingRequests = function() { | |
chrome.bluetoothPrivate && (console.log("[BT] Start authorizing pairing requests..."), chrome.bluetoothPrivate.onPairing.addListener(app.Bluetooth.handlePairingEvent_)); | |
}; | |
app.Bluetooth.stopAuthorizePairingRequests = function() { | |
chrome.bluetoothPrivate && (console.log("[BT] Stop authorizing pairing requests..."), chrome.bluetoothPrivate.onPairing.removeListener(app.Bluetooth.handlePairingEvent_)); | |
}; | |
app.Bluetooth.handlePairingEvent_ = function(pairingEvent) { | |
console.log("[BT] Receive pairing request from " + pairingEvent.device.address + ": " + pairingEvent.pairing); | |
console.log(pairingEvent); | |
"requestAuthorization" == pairingEvent.pairing && chrome.bluetoothPrivate.setPairingResponse({device:pairingEvent.device, response:"confirm"}, function() { | |
console.log("[BT] Authorized pairing request"); | |
}); | |
}; | |
app.Bluetooth.refreshAdapterState(function(adapterState) { | |
app.Bluetooth.adapterState = adapterState; | |
}); | |
app.BluetoothConnection = function(device, opt_socket) { | |
easyUnlock.Connection.call(this, device); | |
this.socket_ = opt_socket || null; | |
this.pollingTimeMs_ = app.BluetoothConnection.DEFAULT_POLLING_TIME_MS; | |
this.onReceiveListener_ = this.pollingOverrideDelay_ = this.connectInterval_ = null; | |
if (null != this.socket_) { | |
this.onConnected_(this.socket_, !0); | |
} | |
}; | |
goog.inherits(app.BluetoothConnection, easyUnlock.Connection); | |
app.BluetoothConnection.DEFAULT_POLLING_TIME_MS = 3E3; | |
app.BluetoothConnection.prototype.getBluetoothAddress = function() { | |
return JSCompiler_StaticMethods_getRemoteDevice(this).bluetoothAddress; | |
}; | |
var JSCompiler_StaticMethods_overridePollingTime = function(JSCompiler_StaticMethods_overridePollingTime$self, pollingTimeMs) { | |
console.log("[BC] Applying polling override of " + pollingTimeMs + "ms for 5000ms."); | |
null != JSCompiler_StaticMethods_overridePollingTime$self.pollingOverrideDelay_ && (JSCompiler_StaticMethods_overridePollingTime$self.pollingOverrideDelay_.fire(), JSCompiler_StaticMethods_overridePollingTime$self.pollingOverrideDelay_ = null); | |
var resetInterval = function() { | |
null != this.connectInterval_ && (window.clearInterval(this.connectInterval_), this.connectInterval_ = window.setInterval(this.pollConnect_.bind(this), this.pollingTimeMs_)); | |
}.bind(JSCompiler_StaticMethods_overridePollingTime$self); | |
JSCompiler_StaticMethods_overridePollingTime$self.pollingTimeMs_ = pollingTimeMs; | |
resetInterval(); | |
JSCompiler_StaticMethods_overridePollingTime$self.pollingOverrideDelay_ = new easyUnlock.DelayImpl(function() { | |
console.log("[BC] Restoring polling override: " + this.pollingTimeMs_ + "ms."); | |
this.pollingTimeMs_ = app.BluetoothConnection.DEFAULT_POLLING_TIME_MS; | |
this.pollingOverrideDelay_ = null; | |
resetInterval(); | |
}.bind(JSCompiler_StaticMethods_overridePollingTime$self), 5); | |
JSCompiler_StaticMethods_overridePollingTime$self.pollingOverrideDelay_.start(); | |
}, JSCompiler_StaticMethods_hasPollingOverride = function(JSCompiler_StaticMethods_hasPollingOverride$self) { | |
return null != JSCompiler_StaticMethods_hasPollingOverride$self.pollingOverrideDelay_; | |
}; | |
app.BluetoothConnection.prototype.setPaused = function(paused) { | |
this.getStatus() == easyUnlock.Connection.Status.CONNECTED && chrome.bluetoothSocket.setPaused(this.socket_.id, paused); | |
}; | |
app.BluetoothConnection.prototype.connect = function() { | |
if (this.getStatus() != easyUnlock.Connection.Status.DISCONNECTED) { | |
throw "Connect called but not disconnected."; | |
} | |
JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.IN_PROGRESS); | |
app.Bluetooth.openConnection({bluetoothAddress:this.getBluetoothAddress()}, this.onConnected_.bind(this)); | |
}; | |
app.BluetoothConnection.prototype.onConnected_ = function(socket, opt_paused) { | |
if (this.getStatus() == easyUnlock.Connection.Status.CONNECTED) { | |
throw "Expected disconnected or in progress"; | |
} | |
socket ? (this.socket_ = socket, null != this.connectInterval_ && this.stopDiscovery(), this.onReceiveListener_ = this.onReceive_.bind(this), chrome.bluetoothSocket.onReceive.addListener(this.onReceiveListener_), JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.CONNECTED), this.setPaused(opt_paused || !1), chrome.bluetoothSocket.update(this.socket_.id, {persistent:!0})) : JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.DISCONNECTED); | |
}; | |
app.BluetoothConnection.prototype.disconnect = function() { | |
if (this.getStatus() != easyUnlock.Connection.Status.CONNECTED) { | |
throw "Disconnect called but not connected."; | |
} | |
app.Bluetooth.closeConnection(this.socket_); | |
this.socket_ = null; | |
null != this.connectInterval_ && this.stopDiscovery(); | |
null != this.onReceiveListener_ && (chrome.bluetoothSocket.onReceive.removeListener(this.onReceiveListener_), this.onReceiveListener_ = null); | |
JSCompiler_StaticMethods_setStatus(this, easyUnlock.Connection.Status.DISCONNECTED); | |
}; | |
app.BluetoothConnection.prototype.startDiscovery = function() { | |
null == this.connectInterval_ && (console.log("[BC] Discovery started..."), this.connectInterval_ = window.setInterval(this.pollConnect_.bind(this), this.pollingTimeMs_)); | |
}; | |
app.BluetoothConnection.prototype.stopDiscovery = function() { | |
console.log("[BC] Discovery stopped..."); | |
null == this.connectInterval_ ? console.error("Not polling.") : (window.clearInterval(this.connectInterval_), this.connectInterval_ = null); | |
}; | |
app.BluetoothConnection.prototype.sendBytes = function(bytes) { | |
if (this.getStatus() != easyUnlock.Connection.Status.CONNECTED) { | |
throw "Can not send bytes when not connected."; | |
} | |
app.Bluetooth.writeToSocket(this.socket_, bytes.buffer, this.onBytesSent_.bind(this)); | |
}; | |
app.BluetoothConnection.prototype.pollConnect_ = function() { | |
this.getStatus() == easyUnlock.Connection.Status.DISCONNECTED && this.connect(); | |
}; | |
app.BluetoothConnection.prototype.onBytesSent_ = function(success) { | |
this.onSendCompleted(success); | |
success || this.disconnect(); | |
}; | |
app.BluetoothConnection.prototype.onReceive_ = function(info) { | |
if (info.socketId == this.socket_.id) { | |
var bytes = info.data ? new Uint8Array(info.data) : new Uint8Array([]); | |
console.log("[BC] Received " + bytes.length + " bytes."); | |
0 < bytes.length ? JSCompiler_StaticMethods_onBytesReceived(this, bytes) : console.error("[BC] No data received."); | |
} | |
}; | |
app.DeviceManager = function() { | |
this.devices_ = []; | |
this.localDevice_ = null; | |
this.userEmail_ = ""; | |
}; | |
app.DeviceManager.prototype.init = function(callback) { | |
var initEmail = function() { | |
chrome.feedbackPrivate.getUserEmail(function(email) { | |
this.userEmail_ = email; | |
callback(); | |
}.bind(this)); | |
}.bind(this), initDevices = function() { | |
JSCompiler_StaticMethods_loadDevices_(this, initEmail); | |
}.bind(this); | |
app.Bluetooth.refreshAdapterState(initDevices); | |
}; | |
var JSCompiler_StaticMethods_loadDevices_ = function(JSCompiler_StaticMethods_loadDevices_$self, callback) { | |
JSCompiler_StaticMethods_loadDevices_$self.localDevice_ = new easyUnlock.EasyUnlockDevice(app.Bluetooth.adapterState.address, app.Bluetooth.adapterState.name); | |
var storageCallback = function(items) { | |
if (chrome.runtime.lastError) { | |
console.error("Error loading paired device: " + chrome.runtime.lastError), callback(!1); | |
} else { | |
if (void 0 != items.permitAccess) { | |
var permitAccess = permit.PermitRecord.fromJSON(items.permitAccess); | |
this.localDevice_.permitRecord = permitAccess; | |
} | |
for (var devicesJSON = items.easyUnlockDevices || [], i = 0;i < devicesJSON.length;++i) { | |
var device = easyUnlock.EasyUnlockDevice.fromJSON(devicesJSON[i]); | |
null != device && this.devices_.push(device); | |
} | |
callback(!0); | |
} | |
}.bind(JSCompiler_StaticMethods_loadDevices_$self); | |
chrome.storage.local.get(["easyUnlockDevices", "permitAccess"], storageCallback); | |
}; | |
app.DeviceManager.prototype.getUserEmail = function() { | |
return this.userEmail_; | |
}; | |
var JSCompiler_StaticMethods_getLocalDevice = function(JSCompiler_StaticMethods_getLocalDevice$self) { | |
return JSCompiler_StaticMethods_getLocalDevice$self.localDevice_; | |
}, JSCompiler_StaticMethods_getRemoteDevices = function(JSCompiler_StaticMethods_getRemoteDevices$self) { | |
return Array.apply([], JSCompiler_StaticMethods_getRemoteDevices$self.devices_); | |
}, JSCompiler_StaticMethods_addRemoteDevice = function(JSCompiler_StaticMethods_addRemoteDevice$self, device) { | |
JSCompiler_StaticMethods_addRemoteDevice$self.devices_.push(device); | |
var json = JSCompiler_StaticMethods_addRemoteDevice$self.devices_.map(function(value) { | |
return value.toJSON(); | |
}), obj = {}; | |
obj.easyUnlockDevices = json; | |
chrome.storage.local.set(obj, function() { | |
chrome.runtime.lastError && console.error("Error saving paired device: " + chrome.runtime.lastError); | |
}); | |
}; | |
app.DeviceManager.prototype.setPermitAccess = function(permitAccess) { | |
this.localDevice_.permitRecord = permitAccess; | |
if (null == permitAccess) { | |
chrome.storage.local.remove("permitAccess"); | |
} else { | |
var obj = {}; | |
obj.permitAccess = permitAccess.toJSON(); | |
chrome.storage.local.set(obj, function() { | |
chrome.runtime.lastError && console.error("Error saving permit access: " + chrome.runtime.lastError); | |
}); | |
} | |
}; | |
app.Launcher = {WINDOW_ID:"easy_unlock_pairing", WINDOW_URL:"pairing.html", WINDOW_WIDTH:420, WINDOW_HEIGHT:335}; | |
app.Launcher.launchPairingDialog = function() { | |
var screenWidth = screen.availWidth, screenHeight = screen.availHeight, expectedHeight = app.Launcher.WINDOW_HEIGHT, width = Math.min(screenWidth, app.Launcher.WINDOW_WIDTH), height = Math.min(screenHeight, expectedHeight); | |
chrome.app.window.create(app.Launcher.WINDOW_URL, {id:"easyunlock", width:width, height:height, minWidth:width, minHeight:height, maxWidth:width, maxHeight:height, frame:"none", bounds:{left:Math.floor((screenWidth - width) / 2), top:Math.floor((screenHeight - height) / 2), width:width, height:height}}); | |
}; | |
app.Metrics = function() { | |
}; | |
app.Metrics.HistogramNamespace_ = "EasyUnlock"; | |
app.Metrics.NotificationEvent = {SHOWN_SET_UP:"notification-shown-set-up", CLICKED_SET_UP:"notification-clicked-set-up", SHOWN_DONE:"notification-shown-done", CLICKED_DONE:"notification-shown-done"}; | |
app.Metrics.NotificationsHistogramName_ = "NotificationEvent"; | |
app.Metrics.NotificationsHistogramValues_ = [app.Metrics.NotificationEvent.SHOWN_SET_UP, app.Metrics.NotificationEvent.CLICKED_SET_UP, app.Metrics.NotificationEvent.SHOWN_DONE, app.Metrics.NotificationEvent.CLICKED_DONE]; | |
app.Metrics.ButtonClick = {APP_LAUNCHED:"app-launched", FIND:"button-click-find", PAIR:"button-click-pair", TRY_OUT:"button-click-try-out", ENABLE:"button-click-enable", DISABLE:"button-click-disable"}; | |
app.Metrics.ButtonClickHistogramName_ = "ClickedButton"; | |
app.Metrics.ButtonClickHistogramValues_ = [app.Metrics.ButtonClick.APP_LAUNCHED, app.Metrics.ButtonClick.FIND, app.Metrics.ButtonClick.PAIR, app.Metrics.ButtonClick.TRY_OUT, app.Metrics.ButtonClick.ENABLE, app.Metrics.ButtonClick.DISABLE]; | |
app.Metrics.SetupStateOnClose = {SUCCESS:"success", SCAN_INITIAL:"scan-initial", SCAN_IN_PROGRESS:"scan-in-progress", SCAN_ERROR:"scan-error", PAIRING_INITIAL:"pairing-initial", PAIRING_IN_PROGRESS:"pairing-in-progress", PAIRING_ERROR:"pairing-error", HELP:"help"}; | |
app.Metrics.SetupStateOnCloseHistogramName_ = "SetupStateOnClose"; | |
app.Metrics.SetupStateOnCloseHistogramValues_ = [app.Metrics.SetupStateOnClose.SUCCESS, app.Metrics.SetupStateOnClose.SCAN_INITIAL, app.Metrics.SetupStateOnClose.SCAN_IN_PROGRESS, app.Metrics.SetupStateOnClose.SCAN_ERROR, app.Metrics.SetupStateOnClose.PAIRING_INITIAL, app.Metrics.SetupStateOnClose.PAIRING_IN_PROGRESS, app.Metrics.SetupStateOnClose.PAIRING_ERROR, app.Metrics.SetupStateOnClose.HELP]; | |
app.Metrics.UnlockEvent = {UNLOCKED:"screen-unlocked", UNLOCKED_EASY_UNLOCK:"screen-unlocked-easy-unlock"}; | |
app.Metrics.UnlockEventHistogramName_ = "UnlockEvent"; | |
app.Metrics.UnlockEventHistogramValues_ = [app.Metrics.UnlockEvent.UNLOCKED, app.Metrics.UnlockEvent.UNLOCKED_EASY_UNLOCK]; | |
app.Metrics.StartupTimeHistogramName_ = "StartupTimeFromSuspend"; | |
app.Metrics.recordNotificationEvent = function() { | |
app.Metrics.recordEnum_(app.Metrics.NotificationsHistogramName_, app.Metrics.NotificationEvent.CLICKED_SET_UP, app.Metrics.NotificationsHistogramValues_); | |
}; | |
app.Metrics.recordButtonClick = function(event) { | |
app.Metrics.recordEnum_(app.Metrics.ButtonClickHistogramName_, event, app.Metrics.ButtonClickHistogramValues_); | |
}; | |
app.Metrics.recordSetupStateOnClose = function() { | |
var state = JSCompiler_StaticMethods_getSetupStateForMetrics(); | |
state && app.Metrics.recordEnum_(app.Metrics.SetupStateOnCloseHistogramName_, state, app.Metrics.SetupStateOnCloseHistogramValues_); | |
}; | |
app.Metrics.recordUnlockEvent = function(event) { | |
app.Metrics.recordEnum_(app.Metrics.UnlockEventHistogramName_, event, app.Metrics.UnlockEventHistogramValues_); | |
}; | |
app.Metrics.recordStartupTimeFromSuspend = function(timeMs) { | |
var metricName = app.Metrics.getFullMetricName_(app.Metrics.StartupTimeHistogramName_); | |
chrome.metricsPrivate.recordMediumTime(metricName, timeMs); | |
}; | |
app.Metrics.getFullMetricName_ = function(metricName) { | |
return[app.Metrics.HistogramNamespace_, metricName].join("."); | |
}; | |
app.Metrics.recordEnum_ = function(name, value, enumValues) { | |
var enumSize = enumValues.length, valueIndex = enumValues.indexOf(value); | |
0 > valueIndex && (valueIndex = enumSize); | |
var enumConfiguration = {metricName:app.Metrics.getFullMetricName_(name), type:"histogram-linear", min:1, max:enumSize, buckets:enumSize + 1}; | |
try { | |
chrome.metricsPrivate.recordValue(enumConfiguration, valueIndex); | |
} catch (e) { | |
console.warn("Failed to record enum value " + value + " in " + name); | |
} | |
}; | |
app.ProxAuth = {}; | |
app.ProxAuth.MESSAGE_DEVICES_FOR_PAIRING_URL = "https://www-googleapis-staging.sandbox.google.com/cryptauth/sandbox/proximityAuth/messageuserdevicesforpairing?alt=JSON"; | |
app.ProxAuth.messageUserDevicesForPairing = function(params, callback) { | |
chrome.identity.getAuthToken({interactive:!0}, function(token) { | |
if (chrome.runtime.lastError) { | |
console.log("Could not get OAuth token :-( " + chrome.runtime.lastError.message); | |
} else { | |
var paramsBytes = permit.util.stringToUint8Array(JSON.stringify(params)), postContent = {payload:{additionalMetadata:permit.crypto.base64Encode(paramsBytes), contactOnlyAuthDevices:!1}}; | |
goog.net.XhrIo.send(app.ProxAuth.MESSAGE_DEVICES_FOR_PAIRING_URL, function(e) { | |
var xhr = e.target; | |
console.log("Proxy Auth server replied: " + JSCompiler_StaticMethods_getResponseText(xhr)); | |
callback(JSON.parse(JSCompiler_StaticMethods_getResponseText(xhr))); | |
}, "POST", JSON.stringify(postContent), {authorization:"Bearer " + token, "Content-Type":"application/json"}); | |
} | |
}); | |
}; | |
app.AppSetupFlowDelegate = function(deviceManager, connectionCallback) { | |
this.deviceManager_ = deviceManager; | |
this.pendingPermitAccess_ = null; | |
this.scanning_ = !1; | |
this.connectionCallback_ = connectionCallback; | |
this.completionCallback_ = this.scanCompletedCallback_ = null; | |
}; | |
var JSCompiler_StaticMethods_stopScan = function(JSCompiler_StaticMethods_stopScan$self) { | |
JSCompiler_StaticMethods_stopScan$self.scanning_ && (app.Bluetooth.stopAuthorizePairingRequests(), app.Bluetooth.unregisterProfile(), app.Bluetooth.stopListeningOverBluetooth(), JSCompiler_StaticMethods_stopScan$self.scanning_ = !1); | |
}, JSCompiler_StaticMethods_pairDevices = function(JSCompiler_StaticMethods_pairDevices$self, connections, callback) { | |
JSCompiler_StaticMethods_stopScan(JSCompiler_StaticMethods_pairDevices$self); | |
JSCompiler_StaticMethods_pairDevices$self.completionCallback_ = callback; | |
JSCompiler_StaticMethods_pairDevices$self.scanCompletedCallback_(connections); | |
}; | |
app.AppSetupFlowDelegate.prototype.getPermitAccess = function() { | |
return null != this.pendingPermitAccess_ ? this.pendingPermitAccess_ : JSCompiler_StaticMethods_getLocalDevice(this.deviceManager_).permitRecord; | |
}; | |
app.AppSetupFlowDelegate.prototype.setPermitAccess = function(permitAccess) { | |
this.pendingPermitAccess_ = permitAccess; | |
}; | |
app.AppSetupFlowDelegate.prototype.getBluetoothAddress = function() { | |
return JSCompiler_StaticMethods_getLocalDevice(this.deviceManager_).bluetoothAddress; | |
}; | |
app.AppSetupFlowDelegate.prototype.getUserGaiaId = function() { | |
return this.deviceManager_.getUserEmail(); | |
}; | |
app.AppSetupFlowDelegate.prototype.pingUserDevices = function(data, callback) { | |
app.ProxAuth.messageUserDevicesForPairing(data, function(response) { | |
callback(0 < response.numGcmDevicesSucceeded); | |
}); | |
}; | |
app.AppSetupFlowDelegate.prototype.scanForDevices = function(callback) { | |
this.scanning_ = !0; | |
this.scanCompletedCallback_ = callback; | |
app.Bluetooth.registerProfile(app.Bluetooth.SETUP_PROFILE); | |
app.Bluetooth.startAuthorizingPairingRequests(); | |
app.Bluetooth.startListeningOverBluetooth(this.onIncomingConnection_.bind(this)); | |
}; | |
app.AppSetupFlowDelegate.prototype.onIncomingConnection_ = function(socket) { | |
if (null != socket) { | |
var connection = new app.BluetoothConnection(new easyUnlock.EasyUnlockDevice(socket.device.address, socket.device.name), socket); | |
null != this.connectionCallback_ && this.connectionCallback_(connection); | |
} | |
}; | |
app.AppSetupFlowDelegate.prototype.onSetupCompleted = function(devices) { | |
for (var i = 0;i < devices.length;++i) { | |
JSCompiler_StaticMethods_addRemoteDevice(this.deviceManager_, devices[i]); | |
} | |
0 < devices.length && (this.completionCallback_(!0), null != this.pendingPermitAccess_ && this.deviceManager_.setPermitAccess(this.pendingPermitAccess_)); | |
}; | |
app.AppSetupFlowDelegate.prototype.onSetupFailed = function() { | |
null != this.completionCallback_ && this.completionCallback_(!1); | |
}; | |
app.ResourceUtil = {}; | |
app.ResourceUtil.ROOT_DIR_100_ = "assets/100/"; | |
app.ResourceUtil.ROOT_DIR_200_ = "assets/200/"; | |
app.ResourceUtil.THROBBER_STEPS = 36; | |
app.ResourceUtil.Icon = {NOTIFICATION_START_SETUP:{path:"magic_auth.png", supports2xAssets:!0}, NOTIFICATION_ALL_SET:{path:"magic_auth_set.png", supports2xAssets:!0}, SCREEN_LOCK_LOCKED:{path:"locked.png", supports2xAssets:!1}, SCREEN_LOCK_UNLOCKED:{path:"unlocked.png", supports2xAssets:!1}, SCREEN_LOCK_LOCKED_OPAQUE:{path:"locked_opaque.png", supports2xAssets:!1}}; | |
app.ResourceUtil.getIconPath = function(icon) { | |
return(1 < window.devicePixelRatio && icon.supports2xAssets ? app.ResourceUtil.ROOT_DIR_200_ : app.ResourceUtil.ROOT_DIR_100_).concat(icon.path); | |
}; | |
app.ResourceUtil.getThrobberPath = function(step) { | |
step = Math.floor(step) % app.ResourceUtil.THROBBER_STEPS; | |
return "assets/throbber/throbber_" + (10 > step ? "0" : "") + step + ".png"; | |
}; | |
app.NotificationController = function() { | |
var that = this; | |
chrome.notifications.onClicked.addListener(function(notificationId) { | |
that.handleButtonClicked_(notificationId); | |
}); | |
chrome.notifications.onButtonClicked.addListener(this.handleButtonClicked_.bind(this)); | |
chrome.notifications.onClosed.addListener(this.handleClosed_.bind(this)); | |
}; | |
app.NotificationController.NOTIFICATION_SETUP_ID = "easy_unlock_setup"; | |
app.NotificationController.NOTIFICATION_ALL_SET_ID = "easy_unlock_all_set"; | |
var JSCompiler_StaticMethods_saveDismissed_ = function() { | |
chrome.storage.local.set({notificationDismissed:!0}, function() { | |
console.log("saved dismissed: true"); | |
}); | |
}; | |
app.NotificationController.prototype.handleButtonClicked_ = function(notificationId) { | |
notificationId == app.NotificationController.NOTIFICATION_SETUP_ID ? (app.Metrics.recordNotificationEvent(), app.Launcher.launchPairingDialog()) : console.error("Unknown notification id: " + notificationId); | |
}; | |
app.NotificationController.prototype.handleClosed_ = function(notificationId, byUser) { | |
notificationId == app.NotificationController.NOTIFICATION_SETUP_ID ? byUser && JSCompiler_StaticMethods_saveDismissed_() : notificationId != app.NotificationController.NOTIFICATION_ALL_SET_ID && console.error("Unknown notification id: " + notificationId); | |
}; | |
app.SleepDetector = function(onResumeCallback) { | |
this.onResumeCallback_ = onResumeCallback; | |
this.interval_ = null; | |
this.lastSampleMs_ = 0; | |
}; | |
app.SleepDetector.prototype.start = function() { | |
null != this.interval_ ? console.warn("SleepDetector already started") : (this.interval_ = window.setInterval(this.sample_.bind(this), 500), this.lastSampleMs_ = (new Date).getTime()); | |
}; | |
app.SleepDetector.prototype.stop = function() { | |
null == this.interval_ ? console.warn("SleepDetector not started") : window.clearInterval(this.interval_); | |
}; | |
app.SleepDetector.prototype.sample_ = function() { | |
var timeMs = (new Date).getTime(); | |
if (5E3 <= timeMs - this.lastSampleMs_) { | |
this.onResumeCallback_(); | |
} | |
this.lastSampleMs_ = timeMs; | |
}; | |
app.UnlockManager = function(deviceManager, opt_autolock) { | |
this.deviceManager_ = deviceManager; | |
this.connections_ = []; | |
this.authenticators_ = []; | |
this.locked_ = !1; | |
this.autolock_ = opt_autolock || !1; | |
this.throbberAnimator_ = null; | |
this.sleepDetector_ = new app.SleepDetector(this.onResumeFromSleep_.bind(this)); | |
this.resumeFromSleepTimestampMs_ = null; | |
}; | |
app.UnlockManager.ThrobberAnimator = function() { | |
this.animationDelay_ = this.interval_ = null; | |
}; | |
app.UnlockManager.ThrobberAnimator.CYCLE_DURATION_MS = 1E3; | |
var JSCompiler_StaticMethods_animate = function(JSCompiler_StaticMethods_animate$self, opt_callback) { | |
if (null != JSCompiler_StaticMethods_animate$self.interval_) { | |
console.log("[Unlock] Throbber animation already started."); | |
} else { | |
var tickMs = app.UnlockManager.ThrobberAnimator.CYCLE_DURATION_MS / app.ResourceUtil.THROBBER_STEPS; | |
JSCompiler_StaticMethods_animate$self.interval_ = window.setInterval(JSCompiler_StaticMethods_animate$self.step_.bind(JSCompiler_StaticMethods_animate$self), tickMs); | |
var completionFunction = function() { | |
this.stop(); | |
void 0 != opt_callback && opt_callback(); | |
}.bind(JSCompiler_StaticMethods_animate$self); | |
JSCompiler_StaticMethods_animate$self.animationDelay_ = new easyUnlock.DelayImpl(completionFunction, 7); | |
JSCompiler_StaticMethods_animate$self.animationDelay_.start(); | |
} | |
}; | |
app.UnlockManager.ThrobberAnimator.prototype.step_ = function() { | |
var cycleDuration = app.UnlockManager.ThrobberAnimator.CYCLE_DURATION_MS, maxSteps = app.ResourceUtil.THROBBER_STEPS, step = Math.floor(Date.now() % cycleDuration * maxSteps / cycleDuration); | |
chrome.screenlockPrivate.showButton(app.ResourceUtil.getThrobberPath(step)); | |
}; | |
app.UnlockManager.ThrobberAnimator.prototype.stop = function() { | |
null != this.interval_ && (window.clearInterval(this.interval_), this.interval_ = null); | |
null != this.animationDelay_ && (this.animationDelay_.stop(), this.animationDelay_ = null); | |
}; | |
app.UnlockManager.prototype.isAuthenticated = function() { | |
return this.authenticators_.reduce(function(prev, authenticator) { | |
return prev || authenticator.isAuthenticated(); | |
}, !1); | |
}; | |
app.UnlockManager.prototype.isConnected = function() { | |
return this.authenticators_.reduce(function(prev, authenticator) { | |
return prev || authenticator.isConnected(); | |
}, !1); | |
}; | |
app.UnlockManager.prototype.init = function() { | |
app.Bluetooth.registerProfile(app.Bluetooth.UNLOCK_PROFILE); | |
var devices = JSCompiler_StaticMethods_getRemoteDevices(this.deviceManager_), permitAccess = JSCompiler_StaticMethods_getLocalDevice(this.deviceManager_).permitRecord; | |
if (null == permitAccess) { | |
throw "Expected a permit access for the local device."; | |
} | |
this.connections_ = devices.map(function(device) { | |
return new app.BluetoothConnection(device); | |
}); | |
this.authenticators_ = this.connections_.map(function(connection) { | |
return new easyUnlock.Authenticator(connection, permitAccess, this, new easyUnlock.TimerImpl); | |
}, this); | |
chrome.screenlockPrivate.onChanged.addListener(this.onLockStateChanged_.bind(this)); | |
chrome.screenlockPrivate.onAuthAttempted.addListener(this.onAuthAttempted_.bind(this)); | |
chrome.bluetooth.onDeviceChanged.addListener(this.onDeviceChanged_.bind(this)); | |
chrome.screenlockPrivate.getLocked(this.onLockStateChanged_.bind(this)); | |
this.sleepDetector_.start(); | |
this.authenticators_.forEach(function(authenticator) { | |
authenticator.start(); | |
}); | |
this.connections_.forEach(function(conn) { | |
conn.connect(); | |
}); | |
}; | |
app.UnlockManager.prototype.updateLockScreenUI_ = function() { | |
null != this.throbberAnimator_ && (this.throbberAnimator_.stop(), this.throbberAnimator_ = null); | |
if (this.locked_) { | |
var icon = this.isAuthenticated() ? app.ResourceUtil.Icon.SCREEN_LOCK_UNLOCKED : this.isConnected() ? app.ResourceUtil.Icon.SCREEN_LOCK_LOCKED : app.ResourceUtil.Icon.SCREEN_LOCK_LOCKED_OPAQUE; | |
chrome.screenlockPrivate.showButton(app.ResourceUtil.getIconPath(icon)); | |
this.isAuthenticated() ? chrome.screenlockPrivate.setAuthType("userClick", "Click to unlock") : chrome.screenlockPrivate.setAuthType("offlinePassword"); | |
} | |
}; | |
app.UnlockManager.prototype.onLockStateChanged_ = function(locked) { | |
this.locked_ && !locked && app.Metrics.recordUnlockEvent(app.Metrics.UnlockEvent.UNLOCKED); | |
this.locked_ = locked; | |
this.updateLockScreenUI_(); | |
}; | |
app.UnlockManager.prototype.onAuthAttempted_ = function(authType) { | |
"userClick" == authType && (this.isAuthenticated() ? (app.Metrics.recordUnlockEvent(app.Metrics.UnlockEvent.UNLOCKED_EASY_UNLOCK), chrome.screenlockPrivate.acceptAuthAttempt(!0)) : (chrome.screenlockPrivate.setAuthType("offlinePassword"), chrome.screenlockPrivate.acceptAuthAttempt(!1))); | |
}; | |
app.UnlockManager.prototype.onDeviceChanged_ = function(device) { | |
this.connections_.forEach(function(connection) { | |
device.address == connection.getBluetoothAddress() && !device.connected && connection.isConnected() && (console.log("[Unlock] Device disconnected..."), JSCompiler_StaticMethods_hasPollingOverride(connection) || (console.log("[Unlock] Applying cooldown."), JSCompiler_StaticMethods_overridePollingTime(connection, 1E5)), connection.disconnect()); | |
}, this); | |
}; | |
app.UnlockManager.prototype.onResumeFromSleep_ = function() { | |
console.log("[Unlock] Resume from sleep detected..."); | |
this.authenticators_.forEach(function(authenticator) { | |
JSCompiler_StaticMethods_deauthenticate(authenticator); | |
}); | |
this.connections_.forEach(function(conn) { | |
JSCompiler_StaticMethods_overridePollingTime(conn, 500); | |
}); | |
this.locked_ && (null != this.throbberAnimator_ && this.throbberAnimator_.stop(), this.throbberAnimator_ = new app.UnlockManager.ThrobberAnimator, JSCompiler_StaticMethods_animate(this.throbberAnimator_, this.updateLockScreenUI_.bind(this))); | |
this.resumeFromSleepTimestampMs_ = Date.now(); | |
}; | |
var JSCompiler_StaticMethods_recordStartupTimeFromSuspend_ = function(JSCompiler_StaticMethods_recordStartupTimeFromSuspend_$self) { | |
if (null != JSCompiler_StaticMethods_recordStartupTimeFromSuspend_$self.resumeFromSleepTimestampMs_) { | |
var elapsedTimeMs = Date.now() - JSCompiler_StaticMethods_recordStartupTimeFromSuspend_$self.resumeFromSleepTimestampMs_; | |
app.Metrics.recordStartupTimeFromSuspend(elapsedTimeMs); | |
JSCompiler_StaticMethods_recordStartupTimeFromSuspend_$self.resumeFromSleepTimestampMs_ = null; | |
} | |
}; | |
app.UnlockManager.prototype.onAuthenticationChanged = function(authenticated) { | |
console.log("[Unlock] Auth changed: " + authenticated); | |
JSCompiler_StaticMethods_recordStartupTimeFromSuspend_(this); | |
this.locked_ ? this.updateLockScreenUI_() : !authenticated && this.autolock_ && (chrome.screenlockPrivate.setLocked(!0), chrome.screenlockPrivate.showMessage("Phone lost")); | |
}; | |
app.UnlockManager.prototype.onAuthenticationRefreshed = function() { | |
console.log("[Unlock] Auth refreshed"); | |
JSCompiler_StaticMethods_recordStartupTimeFromSuspend_(this); | |
}; | |
app.UnlockManager.prototype.onAuthenticationFailed = function() { | |
console.log("[Unlock] Auth failed"); | |
this.updateLockScreenUI_(); | |
JSCompiler_StaticMethods_recordStartupTimeFromSuspend_(this); | |
}; | |
app.UnlockManager.prototype.onAuthenticatorConnnectionChanged = function() { | |
null == this.throbberAnimator_ && this.updateLockScreenUI_(); | |
}; | |
var ui = {}; | |
function $(id) { | |
return document.getElementById(id); | |
} | |
function headerTitleElement() { | |
return $("header-title"); | |
} | |
function headerTextElement() { | |
return $("header-text"); | |
} | |
function pairingTitleElement() { | |
return $("pairing-title"); | |
} | |
function pairingButtonElement() { | |
return $("pairing-button"); | |
} | |
function pairingLinkElement() { | |
return $("pairing-link"); | |
} | |
ui.PairingDialog = function(deviceManager) { | |
this.deviceManager_ = deviceManager; | |
this.state_ = new ui.FindPhoneState(this); | |
this.progress_ = 0; | |
}; | |
ui.PairingDialog.ANIMATED_ELLIPSIS_HTML_ = '<span class="animated-ellipsis-component0">.</span><span class="animated-ellipsis-component1">.</span><span class="animated-ellipsis-component2">.</span>'; | |
ui.PairingDialog.decorateWithAnimatedElipsis = function(template) { | |
pairingButtonElement().innerHTML = template.replace("$ELLIPSIS", ui.PairingDialog.ANIMATED_ELLIPSIS_HTML_); | |
}; | |
var JSCompiler_StaticMethods_getDeviceManager = function(JSCompiler_StaticMethods_getDeviceManager$self) { | |
return JSCompiler_StaticMethods_getDeviceManager$self.deviceManager_; | |
}; | |
ui.PairingDialog.prototype.start = function() { | |
var devices = JSCompiler_StaticMethods_getRemoteDevices(this.deviceManager_); | |
0 < devices.length && (this.state_ = new ui.HelpState(this, devices[0])); | |
this.state_.start(); | |
JSCompiler_StaticMethods_increaseProgress_(this); | |
app.Metrics.recordButtonClick(app.Metrics.ButtonClick.APP_LAUNCHED); | |
}; | |
var JSCompiler_StaticMethods_transitionToState = function(JSCompiler_StaticMethods_transitionToState$self, nextState, opt_resetProgress) { | |
JSCompiler_StaticMethods_transitionToState$self.state_ && JSCompiler_StaticMethods_transitionToState$self.state_.cleanUp(); | |
JSCompiler_StaticMethods_transitionToState$self.state_ = nextState; | |
JSCompiler_StaticMethods_transitionToState$self.state_.start(); | |
if (!0 === opt_resetProgress) { | |
for (;0 < JSCompiler_StaticMethods_transitionToState$self.progress_;) { | |
document.getElementById("progress-img-" + JSCompiler_StaticMethods_transitionToState$self.progress_).src = "assets/gray_circle.png", JSCompiler_StaticMethods_transitionToState$self.progress_--; | |
} | |
} | |
JSCompiler_StaticMethods_increaseProgress_(JSCompiler_StaticMethods_transitionToState$self); | |
}, JSCompiler_StaticMethods_getSetupStateForMetrics = function() { | |
var JSCompiler_StaticMethods_getSetupStateForMetrics$self = pairingDialog; | |
switch(JSCompiler_StaticMethods_getSetupStateForMetrics$self.state_.stateId) { | |
case ui.PairingDialogState.ID.SCAN: | |
switch(JSCompiler_StaticMethods_getSetupStateForMetrics$self.state_.substateId) { | |
case ui.PairingDialogState.SubID.IDLE: | |
return app.Metrics.SetupStateOnClose.SCAN_INITIAL; | |
case ui.PairingDialogState.SubID.IN_PROGRESS: | |
return app.Metrics.SetupStateOnClose.SCAN_IN_PROGRESS; | |
case ui.PairingDialogState.SubID.ERROR: | |
return app.Metrics.SetupStateOnClose.SCAN_ERROR; | |
default: | |
return null; | |
} | |
; | |
case ui.PairingDialogState.ID.PAIR: | |
switch(JSCompiler_StaticMethods_getSetupStateForMetrics$self.state_.substateId) { | |
case ui.PairingDialogState.SubID.IDLE: | |
return app.Metrics.SetupStateOnClose.PAIRING_INITIAL; | |
case ui.PairingDialogState.SubID.IN_PROGRESS: | |
return app.Metrics.SetupStateOnClose.PAIRING_IN_PROGRESS; | |
case ui.PairingDialogState.SubID.ERROR: | |
return app.Metrics.SetupStateOnClose.PAIRING_ERROR; | |
default: | |
return null; | |
} | |
; | |
case ui.PairingDialogState.ID.COMPLETE: | |
return app.Metrics.SetupStateOnClose.SUCCESS; | |
case ui.PairingDialogState.ID.HELP: | |
return app.Metrics.SetupStateOnClose.HELP; | |
default: | |
return null; | |
} | |
}, JSCompiler_StaticMethods_increaseProgress_ = function(JSCompiler_StaticMethods_increaseProgress_$self) { | |
JSCompiler_StaticMethods_increaseProgress_$self.progress_++; | |
3 < JSCompiler_StaticMethods_increaseProgress_$self.progress_ && (JSCompiler_StaticMethods_increaseProgress_$self.progress_ = 3); | |
var img = document.getElementById("progress-img-" + JSCompiler_StaticMethods_increaseProgress_$self.progress_); | |
img.classList.remove("progress-image-empty"); | |
img.classList.add("progress-image-full"); | |
}; | |
ui.PairingDialogState = function(pairingDialog) { | |
this.stateId = ui.PairingDialogState.ID.ABSTRACT; | |
this.substateId = ui.PairingDialogState.SubID.IDLE; | |
this.pairingDialog = pairingDialog; | |
this.deviceManager = JSCompiler_StaticMethods_getDeviceManager(pairingDialog); | |
}; | |
ui.PairingDialogState.ID = {ABSTRACT:"abstract", SCAN:"scan", PAIR:"pair", COMPLETE:"complete", HELP:"help"}; | |
ui.PairingDialogState.SubID = {IDLE:"idle", IN_PROGRESS:"in-progress", ERROR:"error"}; | |
ui.PairingDialogState.prototype.start = function() { | |
document.body.setAttribute("step", this.stateId); | |
this.initializeUI(); | |
}; | |
ui.PairingDialogState.prototype.initializeUI = function() { | |
console.error("Not Implemented"); | |
}; | |
ui.PairingDialogState.prototype.cleanUp = function() { | |
}; | |
ui.FindPhoneState = function(pairingDialog) { | |
ui.PairingDialogState.call(this, pairingDialog); | |
this.stateId = ui.PairingDialogState.ID.SCAN; | |
this.substateId = ui.PairingDialogState.SubID.IDLE; | |
this.delegate_ = null; | |
this.scanDelay_ = new easyUnlock.DelayImpl(this.onScanTimeout_.bind(this), 15); | |
this.tryCount_ = 0; | |
}; | |
goog.inherits(ui.FindPhoneState, ui.PairingDialogState); | |
ui.FindPhoneState.prototype.initializeUI = function() { | |
headerTitleElement().textContent = "Your phone can Easy Unlock all your devices"; | |
headerTextElement().innerHTML = "<p>With Easy Unlock you can instantly unlock your Chromebook when you and your phone are nearby, no password necessary.</p> <p>Let's find your phone to start using Easy Unlock.</p>"; | |
pairingLinkElement().href = "http://goo.gl/s7pRSP"; | |
pairingLinkElement().setAttribute("target", "_blank"); | |
this.setInitialPairingUI_(); | |
this.clickListener_ = this.startScan_.bind(this); | |
pairingButtonElement().addEventListener("click", this.clickListener_); | |
}; | |
ui.FindPhoneState.prototype.cleanUp = function() { | |
pairingButtonElement().removeEventListener("click", this.clickListener_); | |
pairingButtonElement().removeAttribute("disabled"); | |
}; | |
ui.FindPhoneState.prototype.startScan_ = function() { | |
this.substateId = ui.PairingDialogState.SubID.IN_PROGRESS; | |
app.Metrics.recordButtonClick(app.Metrics.ButtonClick.FIND); | |
0 < this.tryCount_ && this.setInitialPairingUI_(); | |
ui.PairingDialog.decorateWithAnimatedElipsis("Finding your phone$ELLIPSIS"); | |
pairingButtonElement().setAttribute("disabled", ""); | |
this.scanDelay_.start(); | |
chrome.bluetoothPrivate.setAdapterState({powered:!0}, function() { | |
this.delegate_ = new app.AppSetupFlowDelegate(this.deviceManager, this.onConnection_.bind(this)); | |
(new easyUnlock.SetupFlow(this.delegate_, new easyUnlock.TimerImpl)).start(); | |
}.bind(this)); | |
}; | |
ui.FindPhoneState.prototype.onConnection_ = function(connection) { | |
this.substateId = ui.PairingDialogState.SubID.IDLE; | |
this.scanDelay_.stop(); | |
JSCompiler_StaticMethods_stopScan(this.delegate_); | |
JSCompiler_StaticMethods_transitionToState(this.pairingDialog, new ui.PairPhoneState(this.pairingDialog, connection, this.delegate_)); | |
}; | |
ui.FindPhoneState.prototype.onScanTimeout_ = function() { | |
this.substateId = ui.PairingDialogState.SubID.ERROR; | |
JSCompiler_StaticMethods_stopScan(this.delegate_); | |
this.delegate_ = null; | |
this.setErrorPairingUI_(); | |
}; | |
ui.FindPhoneState.prototype.setErrorPairingUI_ = function() { | |
document.body.setAttribute("error", "true"); | |
pairingButtonElement().removeAttribute("disabled"); | |
++this.tryCount_; | |
pairingTitleElement().innerHTML = "Hmm... your phone isn't showing up.<br/>Please make sure your phone is nearby and turned on."; | |
pairingButtonElement().textContent = "Retry"; | |
}; | |
ui.FindPhoneState.prototype.setInitialPairingUI_ = function() { | |
document.body.setAttribute("error", "false"); | |
pairingButtonElement().removeAttribute("disabled"); | |
pairingTitleElement().innerHTML = ""; | |
pairingButtonElement().textContent = "Find your phone"; | |
pairingLinkElement().textContent = "How is it more secure?"; | |
}; | |
ui.PairPhoneState = function(pairingDialog, connection, delegate) { | |
ui.PairingDialogState.call(this, pairingDialog); | |
this.stateId = ui.PairingDialogState.ID.PAIR; | |
this.substateId = ui.PairingDialogState.SubID.IDLE; | |
this.connection_ = connection; | |
this.delegate_ = delegate; | |
}; | |
goog.inherits(ui.PairPhoneState, ui.PairingDialogState); | |
ui.PairPhoneState.prototype.initializeUI = function() { | |
null == this.connection_ ? console.error("Scanned device expected in this state!") : (headerTitleElement().textContent = "Use " + JSCompiler_StaticMethods_getRemoteDevice(this.connection_).name + " to Easy Unlock?", headerTextElement().innerHTML = "<p>This phone will unlock this Chromebook when it's nearby.</p> <p>You'll need to be there too, of course.</p>", this.setInitialPairingUI_(), this.clickListener = this.confirmPair_.bind(this), pairingButtonElement().addEventListener("click", this.clickListener)); | |
}; | |
ui.PairPhoneState.prototype.cleanUp = function() { | |
pairingButtonElement().removeEventListener("click", this.clickListener); | |
pairingButtonElement().removeAttribute("disabled"); | |
}; | |
ui.PairPhoneState.prototype.confirmPair_ = function() { | |
this.substateId = ui.PairingDialogState.SubID.IN_PROGRESS; | |
app.Metrics.recordButtonClick(app.Metrics.ButtonClick.PAIR); | |
ui.PairingDialog.decorateWithAnimatedElipsis("Use this phone$ELLIPSIS"); | |
pairingButtonElement().setAttribute("disabled", ""); | |
JSCompiler_StaticMethods_pairDevices(this.delegate_, [this.connection_], this.onDevicePaired_.bind(this)); | |
}; | |
ui.PairPhoneState.prototype.onDevicePaired_ = function(success) { | |
pairingButtonElement().removeAttribute("disabled"); | |
this.connection_.isConnected() && this.connection_.disconnect(); | |
success ? (this.substateId = ui.PairingDialogState.SubID.IDLE, chrome.runtime.sendMessage("pairingCompleted"), chrome.storage.local.set({easyUnlockEnabled:!0}, function() { | |
JSCompiler_StaticMethods_transitionToState(this.pairingDialog, new ui.PairCompleteState(this.pairingDialog, JSCompiler_StaticMethods_getRemoteDevice(this.connection_))); | |
}.bind(this))) : (this.substateId = ui.PairingDialogState.SubID.ERROR, this.setErrorPairingUI_()); | |
}; | |
ui.PairPhoneState.prototype.setErrorPairingUI_ = function() { | |
document.body.setAttribute("error", "true"); | |
pairingTitleElement().textContent = "Your phone didn't connect properly. Let's try that again."; | |
pairingButtonElement().textContent = "Restart"; | |
pairingButtonElement().removeEventListener("click", this.clickListener); | |
this.clickListener = this.restartSetup_.bind(this); | |
pairingButtonElement().addEventListener("click", this.clickListener); | |
}; | |
ui.PairPhoneState.prototype.restartSetup_ = function() { | |
this.connection_.isConnected() && this.connection_.disconnect(); | |
JSCompiler_StaticMethods_transitionToState(this.pairingDialog, new ui.FindPhoneState(this.pairingDialog), !0); | |
}; | |
ui.PairPhoneState.prototype.setInitialPairingUI_ = function() { | |
document.body.setAttribute("error", "false"); | |
pairingTitleElement().textContent = JSCompiler_StaticMethods_getRemoteDevice(this.connection_).name; | |
pairingButtonElement().textContent = "Use this phone"; | |
pairingLinkElement().textContent = ""; | |
pairingLinkElement().classList.add("invisible"); | |
}; | |
ui.PairCompleteState = function(pairingDialog, device) { | |
ui.PairingDialogState.call(this, pairingDialog); | |
this.stateId = ui.PairingDialogState.ID.COMPLETE; | |
this.substateId = ui.PairingDialogState.SubID.IDLE; | |
this.device_ = device; | |
this.gotStrings_ = !1; | |
this.givenName_ = "dogfooder"; | |
}; | |
goog.inherits(ui.PairCompleteState, ui.PairingDialogState); | |
ui.PairCompleteState.prototype.initializeUI = function() { | |
var deviceName = this.device_.name; | |
if (!this.gotStrings_ && chrome.easyUnlockPrivate) { | |
chrome.easyUnlockPrivate.getStrings(function(values) { | |
var givenName = values.givenName; | |
givenName && (this.givenName_ = givenName); | |
this.gotStrings_ = !0; | |
this.initializeUI(); | |
}.bind(this)); | |
} else { | |
this.gotStrings_ = !0; | |
headerTitleElement().textContent = "You're all set, " + this.givenName_ + "!"; | |
var headerText = headerTextElement(); | |
headerText.innerHTML = '<p>This Chromebook will Easy Unlock whenever you and <b class="device-name"></b> are nearby.</p><p>You can also enable Easy Unlock on other devices. <a target="_blank" href="http://goo.gl/s7pRSP">Learn more</a></p>'; | |
headerText.getElementsByClassName("device-name")[0].textContent = deviceName; | |
pairingTitleElement().textContent = ""; | |
pairingButtonElement().textContent = "Try it out"; | |
pairingLinkElement().textContent = "Easy Unlock settings"; | |
pairingLinkElement().href = "http://goo.gl/s7pRSP"; | |
pairingLinkElement().setAttribute("target", "_blank"); | |
this.clickListener = function() { | |
app.Metrics.recordButtonClick(app.Metrics.ButtonClick.TRY_OUT); | |
chrome.runtime.sendMessage(null, "showTutorial"); | |
chrome.easyUnlockPrivate ? chrome.easyUnlockPrivate.setPreference("showTutorial", !0, function() { | |
chrome.app.window.current().close(); | |
}) : chrome.app.window.current().close(); | |
}; | |
pairingButtonElement().addEventListener("click", this.clickListener); | |
} | |
}; | |
ui.PairCompleteState.prototype.cleanUp = function() { | |
pairingButtonElement().removeEventListener("click", this.clickListener); | |
}; | |
ui.HelpState = function(pairingDialog, device) { | |
ui.PairingDialogState.call(this, pairingDialog); | |
this.stateId = ui.PairingDialogState.ID.HELP; | |
this.substateId = ui.PairingDialogState.SubID.IDLE; | |
this.device_ = device; | |
this.enabledGot_ = !1; | |
this.easyUnlockEnabled_ = !0; | |
}; | |
goog.inherits(ui.HelpState, ui.PairingDialogState); | |
ui.HelpState.prototype.initializeUI = function() { | |
this.enabledGot_ ? (document.getElementById("pair-progress").style.visibility = "hidden", headerTitleElement().textContent = "Easy Unlock is set up.", headerTextElement().innerHTML = "This is a TEMPORARY screen. Do not click the blue button multiple times in quick succession. By clearing all data, you will need to go through the setup flow again.<br/>Easy Unlock is currently " + (this.easyUnlockEnabled_ ? "enabled" : "disabled") + ".", pairingButtonElement().textContent = (this.easyUnlockEnabled_ ? | |
"Disable" : "Enable") + " Easy Unlock.", this.buttonClickListener = function() { | |
app.Metrics.recordButtonClick(this.easyUnlockEnabled ? app.Metrics.ButtonClick.DISABLE : app.Metrics.ButtonClick.ENABLE); | |
chrome.storage.local.set({easyUnlockEnabled:!this.easyUnlockEnabled_}, function() { | |
chrome.runtime.reload(); | |
}); | |
}.bind(this), pairingLinkElement().textContent = "Clear All Data", this.linkClickListener = function() { | |
chrome.storage.local.clear(function() { | |
chrome.runtime.reload(); | |
}); | |
}.bind(this), pairingButtonElement().addEventListener("click", this.buttonClickListener), pairingLinkElement().addEventListener("click", this.linkClickListener)) : chrome.storage.local.get(["easyUnlockEnabled"], function(items) { | |
chrome.runtime.lastError ? (console.error("Error loading easyUnlockEnabled, defaulting true"), this.easyUnlockEnabled_ = !0) : this.easyUnlockEnabled_ = items.easyUnlockEnabled; | |
this.enabledGot_ = !0; | |
this.initializeUI(); | |
}.bind(this)); | |
}; | |
ui.HelpState.prototype.cleanUp = function() { | |
pairingButtonElement().removeEventListener("click", this.buttonClickListener); | |
pairingLinkElement().removeEventListener("click", this.linkClickListener); | |
document.getElementById("pair-progress").style.visibility = "visible"; | |
}; | |
var pairingDialog = null; | |
document.addEventListener("DOMContentLoaded", function() { | |
document.getElementById("close-button").onclick = function() { | |
pairingDialog && app.Metrics.recordSetupStateOnClose(); | |
chrome.app.window.current().close(); | |
}; | |
var deviceManager = new app.DeviceManager; | |
deviceManager.init(function() { | |
pairingDialog = new ui.PairingDialog(deviceManager); | |
pairingDialog.start(); | |
}); | |
}); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
margin: 0; | |
font-size: 12px; | |
line-height: 18px; | |
font-family: 'Noto Sans', sans-serif; | |
text-align: left; | |
} | |
button { | |
font: normal 12px/29px "Noto Sans"; | |
display: block; | |
height: 29px; | |
background: #5d9aff; | |
border: 1px solid #518afc; | |
border-radius: 2px; | |
box-sizing: content-box; | |
color: #fff; | |
margin: 0; | |
padding: 0; | |
text-align: center; | |
cursor: pointer; | |
} | |
button[disabled] { | |
opacity: 0.5; | |
} | |
.disabled-overlay { | |
position: absolute; | |
z-index: 1; | |
width: 100%; | |
height: 100%; | |
background: rgba(255,255,255,0.5); | |
} | |
[hidden] { | |
display: none !important; | |
} | |
#dialog-header { | |
background: #485f6a; | |
padding: 23px 20px 0px; | |
height: 117px; | |
} | |
#drag-region { | |
position: absolute; | |
width: 100%; | |
top: 0; | |
left: 0; | |
right: 0; | |
-webkit-app-region: drag; | |
display: -webkit-box; | |
-webkit-box-pack: end; | |
} | |
#dialog-header p { | |
margin: 0; | |
padding: 0; | |
} | |
#close-button { | |
-webkit-app-region: no-drag; | |
width: 32px; | |
height: 32px; | |
cursor: pointer; | |
background-position: center center; | |
background-repeat: no-repeat; | |
color: #ffffff; | |
background-image: -webkit-image-set( | |
url(../assets/100/black_topbar_button_close.png) 1x, | |
url(../assets/200/black_topbar_button_close.png) 2x); | |
margin-top: 5px; | |
-webkit-margin-end: 5px; | |
} | |
#close-button:hover { | |
opacity: 0.5; | |
} | |
#header-title { | |
color: #ffffff; | |
font-size: 15px; | |
margin-bottom: 20px; | |
} | |
#header-text, | |
#header-text a { | |
color: #a9c8d7; | |
} | |
#dialog-contents { | |
display: -webkit-flex; | |
} | |
#pairing-image { | |
margin-top: 25px; | |
width: 170px; | |
} | |
body[step='complete'] #pairing-image, | |
body[step='help'] #pairing-image { | |
background-image: -webkit-image-set( | |
url(../assets/100/all_set.png) 1x, | |
url(../assets/200/all_set.png) 2x); | |
background-repeat: no-repeat; | |
background-position: 29px 21px; | |
} | |
#pairing-image-screen { | |
margin-left: 24px; | |
position: relative; | |
width: 102px; | |
height: 170px; | |
background-repeat: no-repeat; | |
} | |
#pairing-image-hand { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
background-repeat: no-repeat; | |
} | |
body[step='pair'] #pairing-image-hand, | |
body[step='scan'] #pairing-image-hand { | |
background-image: -webkit-image-set( | |
url(../assets/100/hand_holder.png) 1x, | |
url(../assets/200/hand_holder.png) 2x); | |
} | |
#pairing-image-screen { | |
background-position: 27px 9px; | |
} | |
body[step='scan'] #pairing-image-screen { | |
background-image: -webkit-image-set( | |
url(../assets/100/held_key.png) 1x, | |
url(../assets/200/held_key.png) 2x); | |
} | |
body[step='pair'] #pairing-image-screen { | |
/* TODO(tengs): Use wallpaper from phone */ | |
background-image: -webkit-image-set( | |
url(../assets/100/wallpaper.png) 1x, | |
url(../assets/200/wallpaper.png) 2x); | |
} | |
#pairing-step-wrapper { | |
-webkit-flex: 1; | |
-webkit-padding-end: 32px; | |
padding-top: 35px; | |
} | |
body[error="true"] #pairing-step-wrapper { | |
padding-top: 17px; | |
} | |
#pairing-step { | |
text-align: center; | |
} | |
#pairing-title { | |
color: #525252; | |
min-height: 18px; | |
visibility: hidden; | |
} | |
body[step="pair"] #pairing-title, | |
body[error="true"] #pairing-title { | |
visibility: visible; | |
} | |
body[error="false"] #pairing-title { | |
font-size: 15px; | |
} | |
.invisible { | |
visibility: hidden; | |
} | |
.device-name { | |
whitespace: no-wrap; | |
} | |
#pairing-link { | |
color: #5595fe; | |
text-decoration: none; | |
} | |
body[step='scan'] #pairing-link, | |
body[step='complete'] #pairing-link, | |
body[step='help'] #pairing-link { | |
visibility: visible; | |
} | |
#pairing-link:active { | |
border: none; | |
} | |
#pair-progress { | |
-webkit-margin-start: 32px; | |
bottom: 5px; | |
position: absolute; | |
} | |
.progress-image-empty, | |
.progress-image-full { | |
background-repeat: no-repeat; | |
display: inline-block; | |
height: 10px; | |
width: 10px; | |
} | |
.progress-image-empty { | |
background-image: -webkit-image-set( | |
url(../assets/100/gray_circle.png) 1x, | |
url(../assets/200/gray_circle.png) 2x); | |
} | |
.progress-image-full { | |
background-image: -webkit-image-set( | |
url(../assets/100/gray_dot.png) 1x, | |
url(../assets/200/gray_dot.png) 2x); | |
} | |
#pairing-button { | |
margin: 7px auto; | |
width: 140px; | |
} | |
/* Animations for the animated ellipsis: */ | |
.animated-ellipsis-component0 { | |
-webkit-animation: ellipsis-component0 1.5s infinite; | |
} | |
@-webkit-keyframes ellipsis-component0 { | |
0% { opacity: 0; } | |
25% { opacity: 1; } | |
50% { opacity: 1; } | |
75% { opacity: 1; } | |
100% { opacity: 0; } | |
} | |
.animated-ellipsis-component1 { | |
-webkit-animation: ellipsis-component1 1.5s infinite; | |
} | |
@-webkit-keyframes ellipsis-component1 { | |
0% { opacity: 0; } | |
25% { opacity: 0; } | |
50% { opacity: 1; } | |
75% { opacity: 1; } | |
100% { opacity: 0; } | |
} | |
.animated-ellipsis-component2 { | |
-webkit-animation: ellipsis-component2 1.5s infinite; | |
} | |
@-webkit-keyframes ellipsis-component2 { | |
0% { opacity: 0; } | |
25% { opacity: 0; } | |
50% { opacity: 0; } | |
75% { opacity: 1; } | |
100% { opacity: 0; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<link rel="stylesheet" type="text/css" href="styles/pairing.css"> | |
</head> | |
<body step="completion" error="false"> | |
<div id="dialog-header"> | |
<div id="drag-region"> | |
<div id="close-button"></div> | |
</div> | |
<div id="header-title"></div> | |
<div id="header-text"></div> | |
</div> | |
<div id="dialog-contents"> | |
<div id="pairing-image"> | |
<div id="pairing-image-screen"> | |
<div id="pairing-image-hand"></div> | |
</div> | |
</div> | |
<div id="pairing-step-wrapper"> | |
<div id="pairing-step"> | |
<div id="pairing-title"></div> | |
<button id="pairing-button"></button> | |
<a id="pairing-link" class="invisible" href="#"></a> | |
<div id="pair-progress"> | |
<div id="progress-img-1" class="progress-image-empty"></div> | |
<div id="progress-img-2" class="progress-image-empty"></div> | |
<div id="progress-img-3" class="progress-image-empty"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script src="easy_unlock_pairing.js" type="text/javascript"></script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment