# lib/goog/base.js

    1// Copyright 2006 The Closure Library Authors. All Rights Reserved.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7//      http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS-IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.1415/**16 * @fileoverview Bootstrap for the Google JS Library (Closure).17 *18 * In uncompiled mode base.js will write out Closure's deps file, unless the19 * global <code>CLOSURE_NO_DEPS</code> is set to true.  This allows projects to20 * include their own deps file(s) from different locations.21 *22 *23 * @provideGoog24 */252627/**28 * @define {boolean} Overridden to true by the compiler when --closure_pass29 *     or --mark_as_compiled is specified.30 */31var COMPILED = false;323334/**35 * Base namespace for the Closure library.  Checks to see goog is36 * already defined in the current scope before assigning to prevent37 * clobbering if base.js is loaded more than once.38 *39 * @const40 */41var goog = goog || {};424344/**45 * Reference to the global context.  In most cases this will be 'window'.46 */47goog.global = this;484950/**51 * A hook for overriding the define values in uncompiled mode.52 *53 * In uncompiled mode, {@code CLOSURE_DEFINES} may be defined before loading54 * base.js.  If a key is defined in {@code CLOSURE_DEFINES}, {@code goog.define}55 * will use the value instead of the default value.  This allows flags to be56 * overwritten without compilation (this is normally accomplished with the57 * compiler's "define" flag).58 *59 * Example:60 * <pre>61 *   var CLOSURE_DEFINES = {'goog.DEBUG', false};62 * </pre>63 *64 * @type {Object.<string, (string|number|boolean)>|undefined}65 */66goog.global.CLOSURE_DEFINES;676869/**70 * Builds an object structure for the provided namespace path,71 * ensuring that names that already exist are not overwritten. For72 * example:73 * "a.b.c" -> a = {};a.b={};a.b.c={};74 * Used by goog.provide and goog.exportSymbol.75 * @param {string} name name of the object that this file defines.76 * @param {*=} opt_object the object to expose at the end of the path.77 * @param {Object=} opt_objectToExportTo The object to add the path to; default78 *     is |goog.global|.79 * @private80 */81goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {82  var parts = name.split('.');83  var cur = opt_objectToExportTo || goog.global;8485  // Internet Explorer exhibits strange behavior when throwing errors from86  // methods externed in this manner.  See the testExportSymbolExceptions in87  // base_test.html for an example.88  if (!(parts[0] in cur) && cur.execScript) {89    cur.execScript('var ' + parts[0]);90  }9192  // Certain browsers cannot parse code in the form for((a in b); c;);93  // This pattern is produced by the JSCompiler when it collapses the94  // statement above into the conditional loop below. To prevent this from95  // happening, use a for-loop and reserve the init logic as below.9697  // Parentheses added to eliminate strict JS warning in Firefox.98  for (var part; parts.length && (part = parts.shift());) {99    if (!parts.length && opt_object !== undefined) {100      // last part and we have an object; use it101      cur[part] = opt_object;102    } else if (cur[part]) {103      cur = cur[part];104    } else {105      cur = cur[part] = {};106    }107  }108};109110111/**112 * Defines a named value. In uncompiled mode, the value is retreived from113 * CLOSURE_DEFINES if the object is defined and has the property specified,114 * and otherwise used the defined defaultValue. When compiled, the default115 * can be overridden using compiler command-line options.116 *117 * @param {string} name The distinguished name to provide.118 * @param {string|number|boolean} defaultValue119 */120goog.define = function(name, defaultValue) {121  var value = defaultValue;122  if (!COMPILED) {123    if (goog.global.CLOSURE_DEFINES && Object.prototype.hasOwnProperty.call(124        goog.global.CLOSURE_DEFINES, name)) {125      value = goog.global.CLOSURE_DEFINES[name];126    }127  }128  goog.exportPath_(name, value);129};130131132/**133 * @define {boolean} DEBUG is provided as a convenience so that debugging code134 * that should not be included in a production js_binary can be easily stripped135 * by specifying --define goog.DEBUG=false to the JSCompiler. For example, most136 * toString() methods should be declared inside an "if (goog.DEBUG)" conditional137 * because they are generally used for debugging purposes and it is difficult138 * for the JSCompiler to statically determine whether they are used.139 */140goog.DEBUG = true;141142143/**144 * @define {string} LOCALE defines the locale being used for compilation. It is145 * used to select locale specific data to be compiled in js binary. BUILD rule146 * can specify this value by "--define goog.LOCALE=<locale_name>" as JSCompiler147 * option.148 *149 * Take into account that the locale code format is important. You should use150 * the canonical Unicode format with hyphen as a delimiter. Language must be151 * lowercase, Language Script - Capitalized, Region - UPPERCASE.152 * There are few examples: pt-BR, en, en-US, sr-Latin-BO, zh-Hans-CN.153 *154 * See more info about locale codes here:155 * http://www.unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers156 *157 * For language codes you should use values defined by ISO 693-1. See it here158 * http://www.w3.org/WAI/ER/IG/ert/iso639.htm. There is only one exception from159 * this rule: the Hebrew language. For legacy reasons the old code (iw) should160 * be used instead of the new code (he), see http://wiki/Main/IIISynonyms.161 */162goog.define('goog.LOCALE', 'en');  // default to en163164165/**166 * @define {boolean} Whether this code is running on trusted sites.167 *168 * On untrusted sites, several native functions can be defined or overridden by169 * external libraries like Prototype, Datejs, and JQuery and setting this flag170 * to false forces closure to use its own implementations when possible.171 *172 * If your javascript can be loaded by a third party site and you are wary about173 * relying on non-standard implementations, specify174 * "--define goog.TRUSTED_SITE=false" to the JSCompiler.175 */176goog.define('goog.TRUSTED_SITE', true);177178179/**180 * Creates object stubs for a namespace.  The presence of one or more181 * goog.provide() calls indicate that the file defines the given182 * objects/namespaces.  Build tools also scan for provide/require statements183 * to discern dependencies, build dependency files (see deps.js), etc.184 * @see goog.require185 * @param {string} name Namespace provided by this file in the form186 *     "goog.package.part".187 */188goog.provide = function(name) {189  if (!COMPILED) {190    // Ensure that the same namespace isn't provided twice. This is intended191    // to teach new developers that 'goog.provide' is effectively a variable192    // declaration. And when JSCompiler transforms goog.provide into a real193    // variable declaration, the compiled JS should work the same as the raw194    // JS--even when the raw JS uses goog.provide incorrectly.195    if (goog.isProvided_(name)) {196      throw Error('Namespace "' + name + '" already declared.');197    }198    delete goog.implicitNamespaces_[name];199200    var namespace = name;201    while ((namespace = namespace.substring(0, namespace.lastIndexOf('.')))) {202      if (goog.getObjectByName(namespace)) {203        break;204      }205      goog.implicitNamespaces_[namespace] = true;206    }207  }208209  goog.exportPath_(name);210};211212213/**214 * Marks that the current file should only be used for testing, and never for215 * live code in production.216 *217 * In the case of unit tests, the message may optionally be an exact218 * namespace for the test (e.g. 'goog.stringTest'). The linter will then219 * ignore the extra provide (if not explicitly defined in the code).220 *221 * @param {string=} opt_message Optional message to add to the error that's222 *     raised when used in production code.223 */224goog.setTestOnly = function(opt_message) {225  if (COMPILED && !goog.DEBUG) {226    opt_message = opt_message || '';227    throw Error('Importing test-only code into non-debug environment' +228                opt_message ? ': ' + opt_message : '.');229  }230};231232233if (!COMPILED) {234235  /**236   * Check if the given name has been goog.provided. This will return false for237   * names that are available only as implicit namespaces.238   * @param {string} name name of the object to look for.239   * @return {boolean} Whether the name has been provided.240   * @private241   */242  goog.isProvided_ = function(name) {243    return !goog.implicitNamespaces_[name] && !!goog.getObjectByName(name);244  };245246  /**247   * Namespaces implicitly defined by goog.provide. For example,248   * goog.provide('goog.events.Event') implicitly declares249   * that 'goog' and 'goog.events' must be namespaces.250   *251   * @type {Object}252   * @private253   */254  goog.implicitNamespaces_ = {};255}256257258/**259 * Returns an object based on its fully qualified external name.  If you are260 * using a compilation pass that renames property names beware that using this261 * function will not find renamed properties.262 *263 * @param {string} name The fully qualified name.264 * @param {Object=} opt_obj The object within which to look; default is265 *     |goog.global|.266 * @return {?} The value (object or primitive) or, if not found, null.267 */268goog.getObjectByName = function(name, opt_obj) {269  var parts = name.split('.');270  var cur = opt_obj || goog.global;271  for (var part; part = parts.shift(); ) {272    if (goog.isDefAndNotNull(cur[part])) {273      cur = cur[part];274    } else {275      return null;276    }277  }278  return cur;279};280281282/**283 * Globalizes a whole namespace, such as goog or goog.lang.284 *285 * @param {Object} obj The namespace to globalize.286 * @param {Object=} opt_global The object to add the properties to.287 * @deprecated Properties may be explicitly exported to the global scope, but288 *     this should no longer be done in bulk.289 */290goog.globalize = function(obj, opt_global) {291  var global = opt_global || goog.global;292  for (var x in obj) {293    global[x] = obj[x];294  }295};296297298/**299 * Adds a dependency from a file to the files it requires.300 * @param {string} relPath The path to the js file.301 * @param {Array} provides An array of strings with the names of the objects302 *                         this file provides.303 * @param {Array} requires An array of strings with the names of the objects304 *                         this file requires.305 */306goog.addDependency = function(relPath, provides, requires) {307  if (goog.DEPENDENCIES_ENABLED) {308    var provide, require;309    var path = relPath.replace(/\\/g, '/');310    var deps = goog.dependencies_;311    for (var i = 0; provide = provides[i]; i++) {312      deps.nameToPath[provide] = path;313      if (!(path in deps.pathToNames)) {314        deps.pathToNames[path] = {};315      }316      deps.pathToNames[path][provide] = true;317    }318    for (var j = 0; require = requires[j]; j++) {319      if (!(path in deps.requires)) {320        deps.requires[path] = {};321      }322      deps.requires[path][require] = true;323    }324  }325};326327328329330// NOTE(nnaze): The debug DOM loader was included in base.js as an orignal331// way to do "debug-mode" development.  The dependency system can sometimes332// be confusing, as can the debug DOM loader's asyncronous nature.333//334// With the DOM loader, a call to goog.require() is not blocking -- the335// script will not load until some point after the current script.  If a336// namespace is needed at runtime, it needs to be defined in a previous337// script, or loaded via require() with its registered dependencies.338// User-defined namespaces may need their own deps file.  See http://go/js_deps,339// http://go/genjsdeps, or, externally, DepsWriter.340// http://code.google.com/closure/library/docs/depswriter.html341//342// Because of legacy clients, the DOM loader can't be easily removed from343// base.js.  Work is being done to make it disableable or replaceable for344// different environments (DOM-less JavaScript interpreters like Rhino or V8,345// for example). See bootstrap/ for more information.346347348/**349 * @define {boolean} Whether to enable the debug loader.350 *351 * If enabled, a call to goog.require() will attempt to load the namespace by352 * appending a script tag to the DOM (if the namespace has been registered).353 *354 * If disabled, goog.require() will simply assert that the namespace has been355 * provided (and depend on the fact that some outside tool correctly ordered356 * the script).357 */358goog.define('goog.ENABLE_DEBUG_LOADER', true);359360361/**362 * Implements a system for the dynamic resolution of dependencies363 * that works in parallel with the BUILD system. Note that all calls364 * to goog.require will be stripped by the JSCompiler when the365 * --closure_pass option is used.366 * @see goog.provide367 * @param {string} name Namespace to include (as was given in goog.provide())368 *     in the form "goog.package.part".369 */370goog.require = function(name) {371372  // if the object already exists we do not need do do anything373  // TODO(arv): If we start to support require based on file name this has374  //            to change375  // TODO(arv): If we allow goog.foo.* this has to change376  // TODO(arv): If we implement dynamic load after page load we should probably377  //            not remove this code for the compiled output378  if (!COMPILED) {379    if (goog.isProvided_(name)) {380      return;381    }382383    if (goog.ENABLE_DEBUG_LOADER) {384      var path = goog.getPathFromDeps_(name);385      if (path) {386        goog.included_[path] = true;387        goog.writeScripts_();388        return;389      }390    }391392    var errorMessage = 'goog.require could not find: ' + name;393    if (goog.global.console) {394      goog.global.console['error'](errorMessage);395    }396397398      throw Error(errorMessage);399400  }401};402403404/**405 * Path for included scripts406 * @type {string}407 */408goog.basePath = '';409410411/**412 * A hook for overriding the base path.413 * @type {string|undefined}414 */415goog.global.CLOSURE_BASE_PATH;416417418/**419 * Whether to write out Closure's deps file. By default,420 * the deps are written.421 * @type {boolean|undefined}422 */423goog.global.CLOSURE_NO_DEPS;424425426/**427 * A function to import a single script. This is meant to be overridden when428 * Closure is being run in non-HTML contexts, such as web workers. It's defined429 * in the global scope so that it can be set before base.js is loaded, which430 * allows deps.js to be imported properly.431 *432 * The function is passed the script source, which is a relative URI. It should433 * return true if the script was imported, false otherwise.434 */435goog.global.CLOSURE_IMPORT_SCRIPT;436437438/**439 * Null function used for default values of callbacks, etc.440 * @return {void} Nothing.441 */442goog.nullFunction = function() {};443444445/**446 * The identity function. Returns its first argument.447 *448 * @param {*=} opt_returnValue The single value that will be returned.449 * @param {...*} var_args Optional trailing arguments. These are ignored.450 * @return {?} The first argument. We can't know the type -- just pass it along451 *      without type.452 * @deprecated Use goog.functions.identity instead.453 */454goog.identityFunction = function(opt_returnValue, var_args) {455  return opt_returnValue;456};457458459/**460 * When defining a class Foo with an abstract method bar(), you can do:461 *462 * Foo.prototype.bar = goog.abstractMethod463 *464 * Now if a subclass of Foo fails to override bar(), an error465 * will be thrown when bar() is invoked.466 *467 * Note: This does not take the name of the function to override as468 * an argument because that would make it more difficult to obfuscate469 * our JavaScript code.470 *471 * @type {!Function}472 * @throws {Error} when invoked to indicate the method should be473 *   overridden.474 */475goog.abstractMethod = function() {476  throw Error('unimplemented abstract method');477};478479480/**481 * Adds a {@code getInstance} static method that always return the same instance482 * object.483 * @param {!Function} ctor The constructor for the class to add the static484 *     method to.485 */486goog.addSingletonGetter = function(ctor) {487  ctor.getInstance = function() {488    if (ctor.instance_) {489      return ctor.instance_;490    }491    if (goog.DEBUG) {492      // NOTE: JSCompiler can't optimize away Array#push.493      goog.instantiatedSingletons_[goog.instantiatedSingletons_.length] = ctor;494    }495    return ctor.instance_ = new ctor;496  };497};498499500/**501 * All singleton classes that have been instantiated, for testing. Don't read502 * it directly, use the {@code goog.testing.singleton} module. The compiler503 * removes this variable if unused.504 * @type {!Array.<!Function>}505 * @private506 */507goog.instantiatedSingletons_ = [];508509510/**511 * True if goog.dependencies_ is available.512 * @const {boolean}513 */514goog.DEPENDENCIES_ENABLED = !COMPILED && goog.ENABLE_DEBUG_LOADER;515516517if (goog.DEPENDENCIES_ENABLED) {518  /**519   * Object used to keep track of urls that have already been added. This520   * record allows the prevention of circular dependencies.521   * @type {Object}522   * @private523   */524  goog.included_ = {};525526527  /**528   * This object is used to keep track of dependencies and other data that is529   * used for loading scripts530   * @private531   * @type {Object}532   */533  goog.dependencies_ = {534    pathToNames: {}, // 1 to many535    nameToPath: {}, // 1 to 1536    requires: {}, // 1 to many537    // used when resolving dependencies to prevent us from538    // visiting the file twice539    visited: {},540    written: {} // used to keep track of script files we have written541  };542543544  /**545   * Tries to detect whether is in the context of an HTML document.546   * @return {boolean} True if it looks like HTML document.547   * @private548   */549  goog.inHtmlDocument_ = function() {550    var doc = goog.global.document;551    return typeof doc != 'undefined' &&552           'write' in doc;  // XULDocument misses write.553  };554555556  /**557   * Tries to detect the base path of the base.js script that bootstraps Closure558   * @private559   */560  goog.findBasePath_ = function() {561    if (goog.global.CLOSURE_BASE_PATH) {562      goog.basePath = goog.global.CLOSURE_BASE_PATH;563      return;564    } else if (!goog.inHtmlDocument_()) {565      return;566    }567    var doc = goog.global.document;568    var scripts = doc.getElementsByTagName('script');569    // Search backwards since the current script is in almost all cases the one570    // that has base.js.571    for (var i = scripts.length - 1; i >= 0; --i) {572      var src = scripts[i].src;573      var qmark = src.lastIndexOf('?');574      var l = qmark == -1 ? src.length : qmark;575      if (src.substr(l - 7, 7) == 'base.js') {576        goog.basePath = src.substr(0, l - 7);577        return;578      }579    }580  };581582583  /**584   * Imports a script if, and only if, that script hasn't already been imported.585   * (Must be called at execution time)586   * @param {string} src Script source.587   * @private588   */589  goog.importScript_ = function(src) {590    var importScript = goog.global.CLOSURE_IMPORT_SCRIPT ||591        goog.writeScriptTag_;592    if (!goog.dependencies_.written[src] && importScript(src)) {593      goog.dependencies_.written[src] = true;594    }595  };596597598  /**599   * The default implementation of the import function. Writes a script tag to600   * import the script.601   *602   * @param {string} src The script source.603   * @return {boolean} True if the script was imported, false otherwise.604   * @private605   */606  goog.writeScriptTag_ = function(src) {607    if (goog.inHtmlDocument_()) {608      var doc = goog.global.document;609610      // If the user tries to require a new symbol after document load,611      // something has gone terribly wrong. Doing a document.write would612      // wipe out the page.613      if (doc.readyState == 'complete') {614        // Certain test frameworks load base.js multiple times, which tries615        // to write deps.js each time. If that happens, just fail silently.616        // These frameworks wipe the page between each load of base.js, so this617        // is OK.618        var isDeps = /\bdeps.js$/.test(src);619        if (isDeps) {620          return false;621        } else {622          throw Error('Cannot write "' + src + '" after document load');623        }624      }625626      doc.write(627          '<script type="text/javascript" src="' + src + '"></' + 'script>');628      return true;629    } else {630      return false;631    }632  };633634635  /**636   * Resolves dependencies based on the dependencies added using addDependency637   * and calls importScript_ in the correct order.638   * @private639   */640  goog.writeScripts_ = function() {641    // the scripts we need to write this time642    var scripts = [];643    var seenScript = {};644    var deps = goog.dependencies_;645646    function visitNode(path) {647      if (path in deps.written) {648        return;649      }650651      // we have already visited this one. We can get here if we have cyclic652      // dependencies653      if (path in deps.visited) {654        if (!(path in seenScript)) {655          seenScript[path] = true;656          scripts.push(path);657        }658        return;659      }660661      deps.visited[path] = true;662663      if (path in deps.requires) {664        for (var requireName in deps.requires[path]) {665          // If the required name is defined, we assume that it was already666          // bootstrapped by other means.667          if (!goog.isProvided_(requireName)) {668            if (requireName in deps.nameToPath) {669              visitNode(deps.nameToPath[requireName]);670            } else {671              throw Error('Undefined nameToPath for ' + requireName);672            }673          }674        }675      }676677      if (!(path in seenScript)) {678        seenScript[path] = true;679        scripts.push(path);680      }681    }682683    for (var path in goog.included_) {684      if (!deps.written[path]) {685        visitNode(path);686      }687    }688689    for (var i = 0; i < scripts.length; i++) {690      if (scripts[i]) {691        goog.importScript_(goog.basePath + scripts[i]);692      } else {693        throw Error('Undefined script input');694      }695    }696  };697698699  /**700   * Looks at the dependency rules and tries to determine the script file that701   * fulfills a particular rule.702   * @param {string} rule In the form goog.namespace.Class or project.script.703   * @return {?string} Url corresponding to the rule, or null.704   * @private705   */706  goog.getPathFromDeps_ = function(rule) {707    if (rule in goog.dependencies_.nameToPath) {708      return goog.dependencies_.nameToPath[rule];709    } else {710      return null;711    }712  };713714  goog.findBasePath_();715716  // Allow projects to manage the deps files themselves.717  if (!goog.global.CLOSURE_NO_DEPS) {718    goog.importScript_(goog.basePath + 'deps.js');719  }720}721722723724//==============================================================================725// Language Enhancements726//==============================================================================727728729/**730 * This is a "fixed" version of the typeof operator.  It differs from the typeof731 * operator in such a way that null returns 'null' and arrays return 'array'.732 * @param {*} value The value to get the type of.733 * @return {string} The name of the type.734 */735goog.typeOf = function(value) {736  var s = typeof value;737  if (s == 'object') {738    if (value) {739      // Check these first, so we can avoid calling Object.prototype.toString if740      // possible.741      //742      // IE improperly marshals tyepof across execution contexts, but a743      // cross-context object will still return false for "instanceof Object".744      if (value instanceof Array) {745        return 'array';746      } else if (value instanceof Object) {747        return s;748      }749750      // HACK: In order to use an Object prototype method on the arbitrary751      //   value, the compiler requires the value be cast to type Object,752      //   even though the ECMA spec explicitly allows it.753      var className = Object.prototype.toString.call(754          /** @type {Object} */ (value));755      // In Firefox 3.6, attempting to access iframe window objects' length756      // property throws an NS_ERROR_FAILURE, so we need to special-case it757      // here.758      if (className == '[object Window]') {759        return 'object';760      }761762      // We cannot always use constructor == Array or instanceof Array because763      // different frames have different Array objects. In IE6, if the iframe764      // where the array was created is destroyed, the array loses its765      // prototype. Then dereferencing val.splice here throws an exception, so766      // we can't use goog.isFunction. Calling typeof directly returns 'unknown'767      // so that will work. In this case, this function will return false and768      // most array functions will still work because the array is still769      // array-like (supports length and []) even though it has lost its770      // prototype.771      // Mark Miller noticed that Object.prototype.toString772      // allows access to the unforgeable [[Class]] property.773      //  15.2.4.2 Object.prototype.toString ( )774      //  When the toString method is called, the following steps are taken:775      //      1. Get the [[Class]] property of this object.776      //      2. Compute a string value by concatenating the three strings777      //         "[object ", Result(1), and "]".778      //      3. Return Result(2).779      // and this behavior survives the destruction of the execution context.780      if ((className == '[object Array]' ||781           // In IE all non value types are wrapped as objects across window782           // boundaries (not iframe though) so we have to do object detection783           // for this edge case784           typeof value.length == 'number' &&785           typeof value.splice != 'undefined' &&786           typeof value.propertyIsEnumerable != 'undefined' &&787           !value.propertyIsEnumerable('splice')788789          )) {790        return 'array';791      }792      // HACK: There is still an array case that fails.793      //     function ArrayImpostor() {}794      //     ArrayImpostor.prototype = [];795      //     var impostor = new ArrayImpostor;796      // this can be fixed by getting rid of the fast path797      // (value instanceof Array) and solely relying on798      // (value && Object.prototype.toString.vall(value) === '[object Array]')799      // but that would require many more function calls and is not warranted800      // unless closure code is receiving objects from untrusted sources.801802      // IE in cross-window calls does not correctly marshal the function type803      // (it appears just as an object) so we cannot use just typeof val ==804      // 'function'. However, if the object has a call property, it is a805      // function.806      if ((className == '[object Function]' ||807          typeof value.call != 'undefined' &&808          typeof value.propertyIsEnumerable != 'undefined' &&809          !value.propertyIsEnumerable('call'))) {810        return 'function';811      }812813814    } else {815      return 'null';816    }817818  } else if (s == 'function' && typeof value.call == 'undefined') {819    // In Safari typeof nodeList returns 'function', and on Firefox820    // typeof behaves similarly for HTML{Applet,Embed,Object}Elements821    // and RegExps.  We would like to return object for those and we can822    // detect an invalid function by making sure that the function823    // object has a call method.824    return 'object';825  }826  return s;827};828829830/**831 * Returns true if the specified value is not |undefined|.832 * WARNING: Do not use this to test if an object has a property. Use the in833 * operator instead.  Additionally, this function assumes that the global834 * undefined variable has not been redefined.835 * @param {*} val Variable to test.836 * @return {boolean} Whether variable is defined.837 */838goog.isDef = function(val) {839  return val !== undefined;840};841842843/**844 * Returns true if the specified value is |null|845 * @param {*} val Variable to test.846 * @return {boolean} Whether variable is null.847 */848goog.isNull = function(val) {849  return val === null;850};851852853/**854 * Returns true if the specified value is defined and not null855 * @param {*} val Variable to test.856 * @return {boolean} Whether variable is defined and not null.857 */858goog.isDefAndNotNull = function(val) {859  // Note that undefined == null.860  return val != null;861};862863864/**865 * Returns true if the specified value is an array866 * @param {*} val Variable to test.867 * @return {boolean} Whether variable is an array.868 */869goog.isArray = function(val) {870  return goog.typeOf(val) == 'array';871};872873874/**875 * Returns true if the object looks like an array. To qualify as array like876 * the value needs to be either a NodeList or an object with a Number length877 * property.878 * @param {*} val Variable to test.879 * @return {boolean} Whether variable is an array.880 */881goog.isArrayLike = function(val) {882  var type = goog.typeOf(val);883  return type == 'array' || type == 'object' && typeof val.length == 'number';884};885886887/**888 * Returns true if the object looks like a Date. To qualify as Date-like889 * the value needs to be an object and have a getFullYear() function.890 * @param {*} val Variable to test.891 * @return {boolean} Whether variable is a like a Date.892 */893goog.isDateLike = function(val) {894  return goog.isObject(val) && typeof val.getFullYear == 'function';895};896897898/**899 * Returns true if the specified value is a string900 * @param {*} val Variable to test.901 * @return {boolean} Whether variable is a string.902 */903goog.isString = function(val) {904  return typeof val == 'string';905};906907908/**909 * Returns true if the specified value is a boolean910 * @param {*} val Variable to test.911 * @return {boolean} Whether variable is boolean.912 */913goog.isBoolean = function(val) {914  return typeof val == 'boolean';915};916917918/**919 * Returns true if the specified value is a number920 * @param {*} val Variable to test.921 * @return {boolean} Whether variable is a number.922 */923goog.isNumber = function(val) {924  return typeof val == 'number';925};926927928/**929 * Returns true if the specified value is a function930 * @param {*} val Variable to test.931 * @return {boolean} Whether variable is a function.932 */933goog.isFunction = function(val) {934  return goog.typeOf(val) == 'function';935};936937938/**939 * Returns true if the specified value is an object.  This includes arrays940 * and functions.941 * @param {*} val Variable to test.942 * @return {boolean} Whether variable is an object.943 */944goog.isObject = function(val) {945  var type = typeof val;946  return type == 'object' && val != null || type == 'function';947  // return Object(val) === val also works, but is slower, especially if val is948  // not an object.949};950951952/**953 * Gets a unique ID for an object. This mutates the object so that further954 * calls with the same object as a parameter returns the same value. The unique955 * ID is guaranteed to be unique across the current session amongst objects that956 * are passed into {@code getUid}. There is no guarantee that the ID is unique957 * or consistent across sessions. It is unsafe to generate unique ID for958 * function prototypes.959 *960 * @param {Object} obj The object to get the unique ID for.961 * @return {number} The unique ID for the object.962 */963goog.getUid = function(obj) {964  // TODO(arv): Make the type stricter, do not accept null.965966  // In Opera window.hasOwnProperty exists but always returns false so we avoid967  // using it. As a consequence the unique ID generated for BaseClass.prototype968  // and SubClass.prototype will be the same.969  return obj[goog.UID_PROPERTY_] ||970      (obj[goog.UID_PROPERTY_] = ++goog.uidCounter_);971};972973974/**975 * Removes the unique ID from an object. This is useful if the object was976 * previously mutated using {@code goog.getUid} in which case the mutation is977 * undone.978 * @param {Object} obj The object to remove the unique ID field from.979 */980goog.removeUid = function(obj) {981  // TODO(arv): Make the type stricter, do not accept null.982983  // DOM nodes in IE are not instance of Object and throws exception984  // for delete. Instead we try to use removeAttribute985  if ('removeAttribute' in obj) {986    obj.removeAttribute(goog.UID_PROPERTY_);987  }988  /** @preserveTry */989  try {990    delete obj[goog.UID_PROPERTY_];991  } catch (ex) {992  }993};994995996/**997 * Name for unique ID property. Initialized in a way to help avoid collisions998 * with other closure javascript on the same page.999 * @type {string}1000 * @private1001 */1002goog.UID_PROPERTY_ = 'closure_uid_' + ((Math.random() * 1e9) >>> 0);100310041005/**1006 * Counter for UID.1007 * @type {number}1008 * @private1009 */1010goog.uidCounter_ = 0;101110121013/**1014 * Adds a hash code field to an object. The hash code is unique for the1015 * given object.1016 * @param {Object} obj The object to get the hash code for.1017 * @return {number} The hash code for the object.1018 * @deprecated Use goog.getUid instead.1019 */1020goog.getHashCode = goog.getUid;102110221023/**1024 * Removes the hash code field from an object.1025 * @param {Object} obj The object to remove the field from.1026 * @deprecated Use goog.removeUid instead.1027 */1028goog.removeHashCode = goog.removeUid;102910301031/**1032 * Clones a value. The input may be an Object, Array, or basic type. Objects and1033 * arrays will be cloned recursively.1034 *1035 * WARNINGS:1036 * <code>goog.cloneObject</code> does not detect reference loops. Objects that1037 * refer to themselves will cause infinite recursion.1038 *1039 * <code>goog.cloneObject</code> is unaware of unique identifiers, and copies1040 * UIDs created by <code>getUid</code> into cloned results.1041 *1042 * @param {*} obj The value to clone.1043 * @return {*} A clone of the input value.1044 * @deprecated goog.cloneObject is unsafe. Prefer the goog.object methods.1045 */1046goog.cloneObject = function(obj) {1047  var type = goog.typeOf(obj);1048  if (type == 'object' || type == 'array') {1049    if (obj.clone) {1050      return obj.clone();1051    }1052    var clone = type == 'array' ? [] : {};1053    for (var key in obj) {1054      clone[key] = goog.cloneObject(obj[key]);1055    }1056    return clone;1057  }10581059  return obj;1060};106110621063/**1064 * A native implementation of goog.bind.1065 * @param {Function} fn A function to partially apply.1066 * @param {Object|undefined} selfObj Specifies the object which |this| should1067 *     point to when the function is run.1068 * @param {...*} var_args Additional arguments that are partially1069 *     applied to the function.1070 * @return {!Function} A partially-applied form of the function bind() was1071 *     invoked as a method of.1072 * @private1073 * @suppress {deprecated} The compiler thinks that Function.prototype.bind1074 *     is deprecated because some people have declared a pure-JS version.1075 *     Only the pure-JS version is truly deprecated.1076 */1077goog.bindNative_ = function(fn, selfObj, var_args) {1078  return /** @type {!Function} */ (fn.call.apply(fn.bind, arguments));1079};108010811082/**1083 * A pure-JS implementation of goog.bind.1084 * @param {Function} fn A function to partially apply.1085 * @param {Object|undefined} selfObj Specifies the object which |this| should1086 *     point to when the function is run.1087 * @param {...*} var_args Additional arguments that are partially1088 *     applied to the function.1089 * @return {!Function} A partially-applied form of the function bind() was1090 *     invoked as a method of.1091 * @private1092 */1093goog.bindJs_ = function(fn, selfObj, var_args) {1094  if (!fn) {1095    throw new Error();1096  }10971098  if (arguments.length > 2) {1099    var boundArgs = Array.prototype.slice.call(arguments, 2);1100    return function() {1101      // Prepend the bound arguments to the current arguments.1102      var newArgs = Array.prototype.slice.call(arguments);1103      Array.prototype.unshift.apply(newArgs, boundArgs);1104      return fn.apply(selfObj, newArgs);1105    };11061107  } else {1108    return function() {1109      return fn.apply(selfObj, arguments);1110    };1111  }1112};111311141115/**1116 * Partially applies this function to a particular 'this object' and zero or1117 * more arguments. The result is a new function with some arguments of the first1118 * function pre-filled and the value of |this| 'pre-specified'.<br><br>1119 *1120 * Remaining arguments specified at call-time are appended to the pre-1121 * specified ones.<br><br>1122 *1123 * Also see: {@link #partial}.<br><br>1124 *1125 * Usage:1126 * <pre>var barMethBound = bind(myFunction, myObj, 'arg1', 'arg2');1127 * barMethBound('arg3', 'arg4');</pre>1128 *1129 * @param {?function(this:T, ...)} fn A function to partially apply.1130 * @param {T} selfObj Specifies the object which |this| should1131 *     point to when the function is run.1132 * @param {...*} var_args Additional arguments that are partially1133 *     applied to the function.1134 * @return {!Function} A partially-applied form of the function bind() was1135 *     invoked as a method of.1136 * @template T1137 * @suppress {deprecated} See above.1138 */1139goog.bind = function(fn, selfObj, var_args) {1140  // TODO(nicksantos): narrow the type signature.1141  if (Function.prototype.bind &&1142      // NOTE(nicksantos): Somebody pulled base.js into the default1143      // Chrome extension environment. This means that for Chrome extensions,1144      // they get the implementation of Function.prototype.bind that1145      // calls goog.bind instead of the native one. Even worse, we don't want1146      // to introduce a circular dependency between goog.bind and1147      // Function.prototype.bind, so we have to hack this to make sure it1148      // works correctly.1149      Function.prototype.bind.toString().indexOf('native code') != -1) {1150    goog.bind = goog.bindNative_;1151  } else {1152    goog.bind = goog.bindJs_;1153  }1154  return goog.bind.apply(null, arguments);1155};115611571158/**1159 * Like bind(), except that a 'this object' is not required. Useful when the1160 * target function is already bound.1161 *1162 * Usage:1163 * var g = partial(f, arg1, arg2);1164 * g(arg3, arg4);1165 *1166 * @param {Function} fn A function to partially apply.1167 * @param {...*} var_args Additional arguments that are partially1168 *     applied to fn.1169 * @return {!Function} A partially-applied form of the function bind() was1170 *     invoked as a method of.1171 */1172goog.partial = function(fn, var_args) {1173  var args = Array.prototype.slice.call(arguments, 1);1174  return function() {1175    // Prepend the bound arguments to the current arguments.1176    var newArgs = Array.prototype.slice.call(arguments);1177    newArgs.unshift.apply(newArgs, args);1178    return fn.apply(this, newArgs);1179  };1180};118111821183/**1184 * Copies all the members of a source object to a target object. This method1185 * does not work on all browsers for all objects that contain keys such as1186 * toString or hasOwnProperty. Use goog.object.extend for this purpose.1187 * @param {Object} target Target.1188 * @param {Object} source Source.1189 */1190goog.mixin = function(target, source) {1191  for (var x in source) {1192    target[x] = source[x];1193  }11941195  // For IE7 or lower, the for-in-loop does not contain any properties that are1196  // not enumerable on the prototype object (for example, isPrototypeOf from1197  // Object.prototype) but also it will not include 'replace' on objects that1198  // extend String and change 'replace' (not that it is common for anyone to1199  // extend anything except Object).1200};120112021203/**1204 * @return {number} An integer value representing the number of milliseconds1205 *     between midnight, January 1, 1970 and the current time.1206 */1207goog.now = (goog.TRUSTED_SITE && Date.now) || (function() {1208  // Unary plus operator converts its operand to a number which in the case of1209  // a date is done by calling getTime().1210  return +new Date();1211});121212131214/**1215 * Evals javascript in the global scope.  In IE this uses execScript, other1216 * browsers use goog.global.eval. If goog.global.eval does not evaluate in the1217 * global scope (for example, in Safari), appends a script tag instead.1218 * Throws an exception if neither execScript or eval is defined.1219 * @param {string} script JavaScript string.1220 */1221goog.globalEval = function(script) {1222  if (goog.global.execScript) {1223    goog.global.execScript(script, 'JavaScript');1224  } else if (goog.global.eval) {1225    // Test to see if eval works1226    if (goog.evalWorksForGlobals_ == null) {1227      goog.global.eval('var _et_ = 1;');1228      if (typeof goog.global['_et_'] != 'undefined') {1229        delete goog.global['_et_'];1230        goog.evalWorksForGlobals_ = true;1231      } else {1232        goog.evalWorksForGlobals_ = false;1233      }1234    }12351236    if (goog.evalWorksForGlobals_) {1237      goog.global.eval(script);1238    } else {1239      var doc = goog.global.document;1240      var scriptElt = doc.createElement('script');1241      scriptElt.type = 'text/javascript';1242      scriptElt.defer = false;1243      // Note(user): can't use .innerHTML since "t('<test>')" will fail and1244      // .text doesn't work in Safari 2.  Therefore we append a text node.1245      scriptElt.appendChild(doc.createTextNode(script));1246      doc.body.appendChild(scriptElt);1247      doc.body.removeChild(scriptElt);1248    }1249  } else {1250    throw Error('goog.globalEval not available');1251  }1252};125312541255/**1256 * Indicates whether or not we can call 'eval' directly to eval code in the1257 * global scope. Set to a Boolean by the first call to goog.globalEval (which1258 * empirically tests whether eval works for globals). @see goog.globalEval1259 * @type {?boolean}1260 * @private1261 */1262goog.evalWorksForGlobals_ = null;126312641265/**1266 * Optional map of CSS class names to obfuscated names used with1267 * goog.getCssName().1268 * @type {Object|undefined}1269 * @private1270 * @see goog.setCssNameMapping1271 */1272goog.cssNameMapping_;127312741275/**1276 * Optional obfuscation style for CSS class names. Should be set to either1277 * 'BY_WHOLE' or 'BY_PART' if defined.1278 * @type {string|undefined}1279 * @private1280 * @see goog.setCssNameMapping1281 */1282goog.cssNameMappingStyle_;128312841285/**1286 * Handles strings that are intended to be used as CSS class names.1287 *1288 * This function works in tandem with @see goog.setCssNameMapping.1289 *1290 * Without any mapping set, the arguments are simple joined with a1291 * hyphen and passed through unaltered.1292 *1293 * When there is a mapping, there are two possible styles in which1294 * these mappings are used. In the BY_PART style, each part (i.e. in1295 * between hyphens) of the passed in css name is rewritten according1296 * to the map. In the BY_WHOLE style, the full css name is looked up in1297 * the map directly. If a rewrite is not specified by the map, the1298 * compiler will output a warning.1299 *1300 * When the mapping is passed to the compiler, it will replace calls1301 * to goog.getCssName with the strings from the mapping, e.g.1302 *     var x = goog.getCssName('foo');1303 *     var y = goog.getCssName(this.baseClass, 'active');1304 *  becomes:1305 *     var x= 'foo';1306 *     var y = this.baseClass + '-active';1307 *1308 * If one argument is passed it will be processed, if two are passed1309 * only the modifier will be processed, as it is assumed the first1310 * argument was generated as a result of calling goog.getCssName.1311 *1312 * @param {string} className The class name.1313 * @param {string=} opt_modifier A modifier to be appended to the class name.1314 * @return {string} The class name or the concatenation of the class name and1315 *     the modifier.1316 */1317goog.getCssName = function(className, opt_modifier) {1318  var getMapping = function(cssName) {1319    return goog.cssNameMapping_[cssName] || cssName;1320  };13211322  var renameByParts = function(cssName) {1323    // Remap all the parts individually.1324    var parts = cssName.split('-');1325    var mapped = [];1326    for (var i = 0; i < parts.length; i++) {1327      mapped.push(getMapping(parts[i]));1328    }1329    return mapped.join('-');1330  };13311332  var rename;1333  if (goog.cssNameMapping_) {1334    rename = goog.cssNameMappingStyle_ == 'BY_WHOLE' ?1335        getMapping : renameByParts;1336  } else {1337    rename = function(a) {1338      return a;1339    };1340  }13411342  if (opt_modifier) {1343    return className + '-' + rename(opt_modifier);1344  } else {1345    return rename(className);1346  }1347};134813491350/**1351 * Sets the map to check when returning a value from goog.getCssName(). Example:1352 * <pre>1353 * goog.setCssNameMapping({1354 *   "goog": "a",1355 *   "disabled": "b",1356 * });1357 *1358 * var x = goog.getCssName('goog');1359 * // The following evaluates to: "a a-b".1360 * goog.getCssName('goog') + ' ' + goog.getCssName(x, 'disabled')1361 * </pre>1362 * When declared as a map of string literals to string literals, the JSCompiler1363 * will replace all calls to goog.getCssName() using the supplied map if the1364 * --closure_pass flag is set.1365 *1366 * @param {!Object} mapping A map of strings to strings where keys are possible1367 *     arguments to goog.getCssName() and values are the corresponding values1368 *     that should be returned.1369 * @param {string=} opt_style The style of css name mapping. There are two valid1370 *     options: 'BY_PART', and 'BY_WHOLE'.1371 * @see goog.getCssName for a description.1372 */1373goog.setCssNameMapping = function(mapping, opt_style) {1374  goog.cssNameMapping_ = mapping;1375  goog.cssNameMappingStyle_ = opt_style;1376};137713781379/**1380 * To use CSS renaming in compiled mode, one of the input files should have a1381 * call to goog.setCssNameMapping() with an object literal that the JSCompiler1382 * can extract and use to replace all calls to goog.getCssName(). In uncompiled1383 * mode, JavaScript code should be loaded before this base.js file that declares1384 * a global variable, CLOSURE_CSS_NAME_MAPPING, which is used below. This is1385 * to ensure that the mapping is loaded before any calls to goog.getCssName()1386 * are made in uncompiled mode.1387 *1388 * A hook for overriding the CSS name mapping.1389 * @type {Object|undefined}1390 */1391goog.global.CLOSURE_CSS_NAME_MAPPING;139213931394if (!COMPILED && goog.global.CLOSURE_CSS_NAME_MAPPING) {1395  // This does not call goog.setCssNameMapping() because the JSCompiler1396  // requires that goog.setCssNameMapping() be called with an object literal.1397  goog.cssNameMapping_ = goog.global.CLOSURE_CSS_NAME_MAPPING;1398}139914001401/**1402 * Gets a localized message.1403 *1404 * This function is a compiler primitive. If you give the compiler a localized1405 * message bundle, it will replace the string at compile-time with a localized1406 * version, and expand goog.getMsg call to a concatenated string.1407 *1408 * Messages must be initialized in the form:1409 * <code>1410 * var MSG_NAME = goog.getMsg('Hello {$placeholder}', {'placeholder': 'world'});1411 * </code>1412 *1413 * @param {string} str Translatable string, places holders in the form {$foo}.1414 * @param {Object=} opt_values Map of place holder name to value.1415 * @return {string} message with placeholders filled.1416 */1417goog.getMsg = function(str, opt_values) {1418  var values = opt_values || {};1419  for (var key in values) {1420    var value = ('' + values[key]).replace(/\$/g, '$$$$');1421    str = str.replace(new RegExp('\\{\\$' + key + '\\}', 'gi'), value);1422  }1423  return str;1424};142514261427/**1428 * Gets a localized message. If the message does not have a translation, gives a1429 * fallback message.1430 *1431 * This is useful when introducing a new message that has not yet been1432 * translated into all languages.1433 *1434 * This function is a compiler primtive. Must be used in the form:1435 * <code>var x = goog.getMsgWithFallback(MSG_A, MSG_B);</code>1436 * where MSG_A and MSG_B were initialized with goog.getMsg.1437 *1438 * @param {string} a The preferred message.1439 * @param {string} b The fallback message.1440 * @return {string} The best translated message.1441 */1442goog.getMsgWithFallback = function(a, b) {1443  return a;1444};144514461447/**1448 * Exposes an unobfuscated global namespace path for the given object.1449 * Note that fields of the exported object *will* be obfuscated,1450 * unless they are exported in turn via this function or1451 * goog.exportProperty1452 *1453 * <p>Also handy for making public items that are defined in anonymous1454 * closures.1455 *1456 * ex. goog.exportSymbol('public.path.Foo', Foo);1457 *1458 * ex. goog.exportSymbol('public.path.Foo.staticFunction',1459 *                       Foo.staticFunction);1460 *     public.path.Foo.staticFunction();1461 *1462 * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',1463 *                       Foo.prototype.myMethod);1464 *     new public.path.Foo().myMethod();1465 *1466 * @param {string} publicPath Unobfuscated name to export.1467 * @param {*} object Object the name should point to.1468 * @param {Object=} opt_objectToExportTo The object to add the path to; default1469 *     is |goog.global|.1470 */1471goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {1472  goog.exportPath_(publicPath, object, opt_objectToExportTo);1473};147414751476/**1477 * Exports a property unobfuscated into the object's namespace.1478 * ex. goog.exportProperty(Foo, 'staticFunction', Foo.staticFunction);1479 * ex. goog.exportProperty(Foo.prototype, 'myMethod', Foo.prototype.myMethod);1480 * @param {Object} object Object whose static property is being exported.1481 * @param {string} publicName Unobfuscated name to export.1482 * @param {*} symbol Object the name should point to.1483 */1484goog.exportProperty = function(object, publicName, symbol) {1485  object[publicName] = symbol;1486};148714881489/**1490 * Inherit the prototype methods from one constructor into another.1491 *1492 * Usage:1493 * <pre>1494 * function ParentClass(a, b) { }1495 * ParentClass.prototype.foo = function(a) { }1496 *1497 * function ChildClass(a, b, c) {1498 *   goog.base(this, a, b);1499 * }1500 * goog.inherits(ChildClass, ParentClass);1501 *1502 * var child = new ChildClass('a', 'b', 'see');1503 * child.foo(); // works1504 * </pre>1505 *1506 * In addition, a superclass' implementation of a method can be invoked1507 * as follows:1508 *1509 * <pre>1510 * ChildClass.prototype.foo = function(a) {1511 *   ChildClass.superClass_.foo.call(this, a);1512 *   // other code1513 * };1514 * </pre>1515 *1516 * @param {Function} childCtor Child class.1517 * @param {Function} parentCtor Parent class.1518 */1519goog.inherits = function(childCtor, parentCtor) {1520  /** @constructor */1521  function tempCtor() {};1522  tempCtor.prototype = parentCtor.prototype;1523  childCtor.superClass_ = parentCtor.prototype;1524  childCtor.prototype = new tempCtor();1525  /** @override */1526  childCtor.prototype.constructor = childCtor;1527};152815291530/**1531 * Call up to the superclass.1532 *1533 * If this is called from a constructor, then this calls the superclass1534 * contructor with arguments 1-N.1535 *1536 * If this is called from a prototype method, then you must pass1537 * the name of the method as the second argument to this function. If1538 * you do not, you will get a runtime error. This calls the superclass'1539 * method with arguments 2-N.1540 *1541 * This function only works if you use goog.inherits to express1542 * inheritance relationships between your classes.1543 *1544 * This function is a compiler primitive. At compile-time, the1545 * compiler will do macro expansion to remove a lot of1546 * the extra overhead that this function introduces. The compiler1547 * will also enforce a lot of the assumptions that this function1548 * makes, and treat it as a compiler error if you break them.1549 *1550 * @param {!Object} me Should always be "this".1551 * @param {*=} opt_methodName The method name if calling a super method.1552 * @param {...*} var_args The rest of the arguments.1553 * @return {*} The return value of the superclass method.1554 */1555goog.base = function(me, opt_methodName, var_args) {1556  var caller = arguments.callee.caller;15571558  if (goog.DEBUG) {1559    if (!caller) {1560      throw Error('arguments.caller not defined.  goog.base() expects not ' +1561                  'to be running in strict mode. See ' +1562                  'http://www.ecma-international.org/ecma-262/5.1/#sec-C');1563    }1564  }15651566  if (caller.superClass_) {1567    // This is a constructor. Call the superclass constructor.1568    return caller.superClass_.constructor.apply(1569        me, Array.prototype.slice.call(arguments, 1));1570  }15711572  var args = Array.prototype.slice.call(arguments, 2);1573  var foundCaller = false;1574  for (var ctor = me.constructor;1575       ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) {1576    if (ctor.prototype[opt_methodName] === caller) {1577      foundCaller = true;1578    } else if (foundCaller) {1579      return ctor.prototype[opt_methodName].apply(me, args);1580    }1581  }15821583  // If we did not find the caller in the prototype chain,1584  // then one of two things happened:1585  // 1) The caller is an instance method.1586  // 2) This method was not called by the right caller.1587  if (me[opt_methodName] === caller) {1588    return me.constructor.prototype[opt_methodName].apply(me, args);1589  } else {1590    throw Error(1591        'goog.base called from a method of one name ' +1592        'to a method of a different name');1593  }1594};159515961597/**1598 * Allow for aliasing within scope functions.  This function exists for1599 * uncompiled code - in compiled code the calls will be inlined and the1600 * aliases applied.  In uncompiled code the function is simply run since the1601 * aliases as written are valid JavaScript.1602 * @param {function()} fn Function to call.  This function can contain aliases1603 *     to namespaces (e.g. "var dom = goog.dom") or classes1604 *    (e.g. "var Timer = goog.Timer").1605 */1606goog.scope = function(fn) {1607  fn.call(goog.global);1608};16091610