toolkit/devtools/sourcemap/SourceMap.jsm

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: js; js-indent-level: 2; -*- */
     2 /*
     3  * Copyright 2011 Mozilla Foundation and contributors
     4  * Licensed under the New BSD license. See LICENSE or:
     5  * http://opensource.org/licenses/BSD-3-Clause
     6  */
     8 /*
     9  * WARNING!
    10  *
    11  * Do not edit this file directly, it is built from the sources at
    12  * https://github.com/mozilla/source-map/
    13  */
    15 ///////////////////////////////////////////////////////////////////////////////
    18 this.EXPORTED_SYMBOLS = [ "SourceMapConsumer", "SourceMapGenerator", "SourceNode" ];
    20 Components.utils.import('resource://gre/modules/devtools/Require.jsm');
    21 /* -*- Mode: js; js-indent-level: 2; -*- */
    22 /*
    23  * Copyright 2011 Mozilla Foundation and contributors
    24  * Licensed under the New BSD license. See LICENSE or:
    25  * http://opensource.org/licenses/BSD-3-Clause
    26  */
    27 define('source-map/source-map-consumer', ['require', 'exports', 'module' ,  'source-map/util', 'source-map/binary-search', 'source-map/array-set', 'source-map/base64-vlq'], function(require, exports, module) {
    29   var util = require('source-map/util');
    30   var binarySearch = require('source-map/binary-search');
    31   var ArraySet = require('source-map/array-set').ArraySet;
    32   var base64VLQ = require('source-map/base64-vlq');
    34   /**
    35    * A SourceMapConsumer instance represents a parsed source map which we can
    36    * query for information about the original file positions by giving it a file
    37    * position in the generated source.
    38    *
    39    * The only parameter is the raw source map (either as a JSON string, or
    40    * already parsed to an object). According to the spec, source maps have the
    41    * following attributes:
    42    *
    43    *   - version: Which version of the source map spec this map is following.
    44    *   - sources: An array of URLs to the original source files.
    45    *   - names: An array of identifiers which can be referrenced by individual mappings.
    46    *   - sourceRoot: Optional. The URL root from which all sources are relative.
    47    *   - sourcesContent: Optional. An array of contents of the original source files.
    48    *   - mappings: A string of base64 VLQs which contain the actual mappings.
    49    *   - file: The generated file this source map is associated with.
    50    *
    51    * Here is an example source map, taken from the source map spec[0]:
    52    *
    53    *     {
    54    *       version : 3,
    55    *       file: "out.js",
    56    *       sourceRoot : "",
    57    *       sources: ["foo.js", "bar.js"],
    58    *       names: ["src", "maps", "are", "fun"],
    59    *       mappings: "AA,AB;;ABCDE;"
    60    *     }
    61    *
    62    * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
    63    */
    64   function SourceMapConsumer(aSourceMap) {
    65     var sourceMap = aSourceMap;
    66     if (typeof aSourceMap === 'string') {
    67       sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
    68     }
    70     var version = util.getArg(sourceMap, 'version');
    71     var sources = util.getArg(sourceMap, 'sources');
    72     // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
    73     // requires the array) to play nice here.
    74     var names = util.getArg(sourceMap, 'names', []);
    75     var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
    76     var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
    77     var mappings = util.getArg(sourceMap, 'mappings');
    78     var file = util.getArg(sourceMap, 'file', null);
    80     // Once again, Sass deviates from the spec and supplies the version as a
    81     // string rather than a number, so we use loose equality checking here.
    82     if (version != this._version) {
    83       throw new Error('Unsupported version: ' + version);
    84     }
    86     // Pass `true` below to allow duplicate names and sources. While source maps
    87     // are intended to be compressed and deduplicated, the TypeScript compiler
    88     // sometimes generates source maps with duplicates in them. See Github issue
    89     // #72 and bugzil.la/889492.
    90     this._names = ArraySet.fromArray(names, true);
    91     this._sources = ArraySet.fromArray(sources, true);
    93     this.sourceRoot = sourceRoot;
    94     this.sourcesContent = sourcesContent;
    95     this._mappings = mappings;
    96     this.file = file;
    97   }
    99   /**
   100    * Create a SourceMapConsumer from a SourceMapGenerator.
   101    *
   102    * @param SourceMapGenerator aSourceMap
   103    *        The source map that will be consumed.
   104    * @returns SourceMapConsumer
   105    */
   106   SourceMapConsumer.fromSourceMap =
   107     function SourceMapConsumer_fromSourceMap(aSourceMap) {
   108       var smc = Object.create(SourceMapConsumer.prototype);
   110       smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
   111       smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
   112       smc.sourceRoot = aSourceMap._sourceRoot;
   113       smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
   114                                                               smc.sourceRoot);
   115       smc.file = aSourceMap._file;
   117       smc.__generatedMappings = aSourceMap._mappings.slice()
   118         .sort(util.compareByGeneratedPositions);
   119       smc.__originalMappings = aSourceMap._mappings.slice()
   120         .sort(util.compareByOriginalPositions);
   122       return smc;
   123     };
   125   /**
   126    * The version of the source mapping spec that we are consuming.
   127    */
   128   SourceMapConsumer.prototype._version = 3;
   130   /**
   131    * The list of original sources.
   132    */
   133   Object.defineProperty(SourceMapConsumer.prototype, 'sources', {
   134     get: function () {
   135       return this._sources.toArray().map(function (s) {
   136         return this.sourceRoot ? util.join(this.sourceRoot, s) : s;
   137       }, this);
   138     }
   139   });
   141   // `__generatedMappings` and `__originalMappings` are arrays that hold the
   142   // parsed mapping coordinates from the source map's "mappings" attribute. They
   143   // are lazily instantiated, accessed via the `_generatedMappings` and
   144   // `_originalMappings` getters respectively, and we only parse the mappings
   145   // and create these arrays once queried for a source location. We jump through
   146   // these hoops because there can be many thousands of mappings, and parsing
   147   // them is expensive, so we only want to do it if we must.
   148   //
   149   // Each object in the arrays is of the form:
   150   //
   151   //     {
   152   //       generatedLine: The line number in the generated code,
   153   //       generatedColumn: The column number in the generated code,
   154   //       source: The path to the original source file that generated this
   155   //               chunk of code,
   156   //       originalLine: The line number in the original source that
   157   //                     corresponds to this chunk of generated code,
   158   //       originalColumn: The column number in the original source that
   159   //                       corresponds to this chunk of generated code,
   160   //       name: The name of the original symbol which generated this chunk of
   161   //             code.
   162   //     }
   163   //
   164   // All properties except for `generatedLine` and `generatedColumn` can be
   165   // `null`.
   166   //
   167   // `_generatedMappings` is ordered by the generated positions.
   168   //
   169   // `_originalMappings` is ordered by the original positions.
   171   SourceMapConsumer.prototype.__generatedMappings = null;
   172   Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
   173     get: function () {
   174       if (!this.__generatedMappings) {
   175         this.__generatedMappings = [];
   176         this.__originalMappings = [];
   177         this._parseMappings(this._mappings, this.sourceRoot);
   178       }
   180       return this.__generatedMappings;
   181     }
   182   });
   184   SourceMapConsumer.prototype.__originalMappings = null;
   185   Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
   186     get: function () {
   187       if (!this.__originalMappings) {
   188         this.__generatedMappings = [];
   189         this.__originalMappings = [];
   190         this._parseMappings(this._mappings, this.sourceRoot);
   191       }
   193       return this.__originalMappings;
   194     }
   195   });
   197   /**
   198    * Parse the mappings in a string in to a data structure which we can easily
   199    * query (the ordered arrays in the `this.__generatedMappings` and
   200    * `this.__originalMappings` properties).
   201    */
   202   SourceMapConsumer.prototype._parseMappings =
   203     function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
   204       var generatedLine = 1;
   205       var previousGeneratedColumn = 0;
   206       var previousOriginalLine = 0;
   207       var previousOriginalColumn = 0;
   208       var previousSource = 0;
   209       var previousName = 0;
   210       var mappingSeparator = /^[,;]/;
   211       var str = aStr;
   212       var mapping;
   213       var temp;
   215       while (str.length > 0) {
   216         if (str.charAt(0) === ';') {
   217           generatedLine++;
   218           str = str.slice(1);
   219           previousGeneratedColumn = 0;
   220         }
   221         else if (str.charAt(0) === ',') {
   222           str = str.slice(1);
   223         }
   224         else {
   225           mapping = {};
   226           mapping.generatedLine = generatedLine;
   228           // Generated column.
   229           temp = base64VLQ.decode(str);
   230           mapping.generatedColumn = previousGeneratedColumn + temp.value;
   231           previousGeneratedColumn = mapping.generatedColumn;
   232           str = temp.rest;
   234           if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {
   235             // Original source.
   236             temp = base64VLQ.decode(str);
   237             mapping.source = this._sources.at(previousSource + temp.value);
   238             previousSource += temp.value;
   239             str = temp.rest;
   240             if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {
   241               throw new Error('Found a source, but no line and column');
   242             }
   244             // Original line.
   245             temp = base64VLQ.decode(str);
   246             mapping.originalLine = previousOriginalLine + temp.value;
   247             previousOriginalLine = mapping.originalLine;
   248             // Lines are stored 0-based
   249             mapping.originalLine += 1;
   250             str = temp.rest;
   251             if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {
   252               throw new Error('Found a source and line, but no column');
   253             }
   255             // Original column.
   256             temp = base64VLQ.decode(str);
   257             mapping.originalColumn = previousOriginalColumn + temp.value;
   258             previousOriginalColumn = mapping.originalColumn;
   259             str = temp.rest;
   261             if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {
   262               // Original name.
   263               temp = base64VLQ.decode(str);
   264               mapping.name = this._names.at(previousName + temp.value);
   265               previousName += temp.value;
   266               str = temp.rest;
   267             }
   268           }
   270           this.__generatedMappings.push(mapping);
   271           if (typeof mapping.originalLine === 'number') {
   272             this.__originalMappings.push(mapping);
   273           }
   274         }
   275       }
   277       this.__originalMappings.sort(util.compareByOriginalPositions);
   278     };
   280   /**
   281    * Find the mapping that best matches the hypothetical "needle" mapping that
   282    * we are searching for in the given "haystack" of mappings.
   283    */
   284   SourceMapConsumer.prototype._findMapping =
   285     function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,
   286                                            aColumnName, aComparator) {
   287       // To return the position we are searching for, we must first find the
   288       // mapping for the given position and then return the opposite position it
   289       // points to. Because the mappings are sorted, we can use binary search to
   290       // find the best mapping.
   292       if (aNeedle[aLineName] <= 0) {
   293         throw new TypeError('Line must be greater than or equal to 1, got '
   294                             + aNeedle[aLineName]);
   295       }
   296       if (aNeedle[aColumnName] < 0) {
   297         throw new TypeError('Column must be greater than or equal to 0, got '
   298                             + aNeedle[aColumnName]);
   299       }
   301       return binarySearch.search(aNeedle, aMappings, aComparator);
   302     };
   304   /**
   305    * Returns the original source, line, and column information for the generated
   306    * source's line and column positions provided. The only argument is an object
   307    * with the following properties:
   308    *
   309    *   - line: The line number in the generated source.
   310    *   - column: The column number in the generated source.
   311    *
   312    * and an object is returned with the following properties:
   313    *
   314    *   - source: The original source file, or null.
   315    *   - line: The line number in the original source, or null.
   316    *   - column: The column number in the original source, or null.
   317    *   - name: The original identifier, or null.
   318    */
   319   SourceMapConsumer.prototype.originalPositionFor =
   320     function SourceMapConsumer_originalPositionFor(aArgs) {
   321       var needle = {
   322         generatedLine: util.getArg(aArgs, 'line'),
   323         generatedColumn: util.getArg(aArgs, 'column')
   324       };
   326       var mapping = this._findMapping(needle,
   327                                       this._generatedMappings,
   328                                       "generatedLine",
   329                                       "generatedColumn",
   330                                       util.compareByGeneratedPositions);
   332       if (mapping) {
   333         var source = util.getArg(mapping, 'source', null);
   334         if (source && this.sourceRoot) {
   335           source = util.join(this.sourceRoot, source);
   336         }
   337         return {
   338           source: source,
   339           line: util.getArg(mapping, 'originalLine', null),
   340           column: util.getArg(mapping, 'originalColumn', null),
   341           name: util.getArg(mapping, 'name', null)
   342         };
   343       }
   345       return {
   346         source: null,
   347         line: null,
   348         column: null,
   349         name: null
   350       };
   351     };
   353   /**
   354    * Returns the original source content. The only argument is the url of the
   355    * original source file. Returns null if no original source content is
   356    * availible.
   357    */
   358   SourceMapConsumer.prototype.sourceContentFor =
   359     function SourceMapConsumer_sourceContentFor(aSource) {
   360       if (!this.sourcesContent) {
   361         return null;
   362       }
   364       if (this.sourceRoot) {
   365         aSource = util.relative(this.sourceRoot, aSource);
   366       }
   368       if (this._sources.has(aSource)) {
   369         return this.sourcesContent[this._sources.indexOf(aSource)];
   370       }
   372       var url;
   373       if (this.sourceRoot
   374           && (url = util.urlParse(this.sourceRoot))) {
   375         // XXX: file:// URIs and absolute paths lead to unexpected behavior for
   376         // many users. We can help them out when they expect file:// URIs to
   377         // behave like it would if they were running a local HTTP server. See
   378         // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
   379         var fileUriAbsPath = aSource.replace(/^file:\/\//, "");
   380         if (url.scheme == "file"
   381             && this._sources.has(fileUriAbsPath)) {
   382           return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
   383         }
   385         if ((!url.path || url.path == "/")
   386             && this._sources.has("/" + aSource)) {
   387           return this.sourcesContent[this._sources.indexOf("/" + aSource)];
   388         }
   389       }
   391       throw new Error('"' + aSource + '" is not in the SourceMap.');
   392     };
   394   /**
   395    * Returns the generated line and column information for the original source,
   396    * line, and column positions provided. The only argument is an object with
   397    * the following properties:
   398    *
   399    *   - source: The filename of the original source.
   400    *   - line: The line number in the original source.
   401    *   - column: The column number in the original source.
   402    *
   403    * and an object is returned with the following properties:
   404    *
   405    *   - line: The line number in the generated source, or null.
   406    *   - column: The column number in the generated source, or null.
   407    */
   408   SourceMapConsumer.prototype.generatedPositionFor =
   409     function SourceMapConsumer_generatedPositionFor(aArgs) {
   410       var needle = {
   411         source: util.getArg(aArgs, 'source'),
   412         originalLine: util.getArg(aArgs, 'line'),
   413         originalColumn: util.getArg(aArgs, 'column')
   414       };
   416       if (this.sourceRoot) {
   417         needle.source = util.relative(this.sourceRoot, needle.source);
   418       }
   420       var mapping = this._findMapping(needle,
   421                                       this._originalMappings,
   422                                       "originalLine",
   423                                       "originalColumn",
   424                                       util.compareByOriginalPositions);
   426       if (mapping) {
   427         return {
   428           line: util.getArg(mapping, 'generatedLine', null),
   429           column: util.getArg(mapping, 'generatedColumn', null)
   430         };
   431       }
   433       return {
   434         line: null,
   435         column: null
   436       };
   437     };
   439   SourceMapConsumer.GENERATED_ORDER = 1;
   440   SourceMapConsumer.ORIGINAL_ORDER = 2;
   442   /**
   443    * Iterate over each mapping between an original source/line/column and a
   444    * generated line/column in this source map.
   445    *
   446    * @param Function aCallback
   447    *        The function that is called with each mapping.
   448    * @param Object aContext
   449    *        Optional. If specified, this object will be the value of `this` every
   450    *        time that `aCallback` is called.
   451    * @param aOrder
   452    *        Either `SourceMapConsumer.GENERATED_ORDER` or
   453    *        `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
   454    *        iterate over the mappings sorted by the generated file's line/column
   455    *        order or the original's source/line/column order, respectively. Defaults to
   456    *        `SourceMapConsumer.GENERATED_ORDER`.
   457    */
   458   SourceMapConsumer.prototype.eachMapping =
   459     function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
   460       var context = aContext || null;
   461       var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
   463       var mappings;
   464       switch (order) {
   465       case SourceMapConsumer.GENERATED_ORDER:
   466         mappings = this._generatedMappings;
   467         break;
   468       case SourceMapConsumer.ORIGINAL_ORDER:
   469         mappings = this._originalMappings;
   470         break;
   471       default:
   472         throw new Error("Unknown order of iteration.");
   473       }
   475       var sourceRoot = this.sourceRoot;
   476       mappings.map(function (mapping) {
   477         var source = mapping.source;
   478         if (source && sourceRoot) {
   479           source = util.join(sourceRoot, source);
   480         }
   481         return {
   482           source: source,
   483           generatedLine: mapping.generatedLine,
   484           generatedColumn: mapping.generatedColumn,
   485           originalLine: mapping.originalLine,
   486           originalColumn: mapping.originalColumn,
   487           name: mapping.name
   488         };
   489       }).forEach(aCallback, context);
   490     };
   492   exports.SourceMapConsumer = SourceMapConsumer;
   494 });
   495 /* -*- Mode: js; js-indent-level: 2; -*- */
   496 /*
   497  * Copyright 2011 Mozilla Foundation and contributors
   498  * Licensed under the New BSD license. See LICENSE or:
   499  * http://opensource.org/licenses/BSD-3-Clause
   500  */
   501 define('source-map/util', ['require', 'exports', 'module' , ], function(require, exports, module) {
   503   /**
   504    * This is a helper function for getting values from parameter/options
   505    * objects.
   506    *
   507    * @param args The object we are extracting values from
   508    * @param name The name of the property we are getting.
   509    * @param defaultValue An optional value to return if the property is missing
   510    * from the object. If this is not specified and the property is missing, an
   511    * error will be thrown.
   512    */
   513   function getArg(aArgs, aName, aDefaultValue) {
   514     if (aName in aArgs) {
   515       return aArgs[aName];
   516     } else if (arguments.length === 3) {
   517       return aDefaultValue;
   518     } else {
   519       throw new Error('"' + aName + '" is a required argument.');
   520     }
   521   }
   522   exports.getArg = getArg;
   524   var urlRegexp = /([\w+\-.]+):\/\/((\w+:\w+)@)?([\w.]+)?(:(\d+))?(\S+)?/;
   525   var dataUrlRegexp = /^data:.+\,.+/;
   527   function urlParse(aUrl) {
   528     var match = aUrl.match(urlRegexp);
   529     if (!match) {
   530       return null;
   531     }
   532     return {
   533       scheme: match[1],
   534       auth: match[3],
   535       host: match[4],
   536       port: match[6],
   537       path: match[7]
   538     };
   539   }
   540   exports.urlParse = urlParse;
   542   function urlGenerate(aParsedUrl) {
   543     var url = aParsedUrl.scheme + "://";
   544     if (aParsedUrl.auth) {
   545       url += aParsedUrl.auth + "@"
   546     }
   547     if (aParsedUrl.host) {
   548       url += aParsedUrl.host;
   549     }
   550     if (aParsedUrl.port) {
   551       url += ":" + aParsedUrl.port
   552     }
   553     if (aParsedUrl.path) {
   554       url += aParsedUrl.path;
   555     }
   556     return url;
   557   }
   558   exports.urlGenerate = urlGenerate;
   560   function join(aRoot, aPath) {
   561     var url;
   563     if (aPath.match(urlRegexp) || aPath.match(dataUrlRegexp)) {
   564       return aPath;
   565     }
   567     if (aPath.charAt(0) === '/' && (url = urlParse(aRoot))) {
   568       url.path = aPath;
   569       return urlGenerate(url);
   570     }
   572     return aRoot.replace(/\/$/, '') + '/' + aPath;
   573   }
   574   exports.join = join;
   576   /**
   577    * Because behavior goes wacky when you set `__proto__` on objects, we
   578    * have to prefix all the strings in our set with an arbitrary character.
   579    *
   580    * See https://github.com/mozilla/source-map/pull/31 and
   581    * https://github.com/mozilla/source-map/issues/30
   582    *
   583    * @param String aStr
   584    */
   585   function toSetString(aStr) {
   586     return '$' + aStr;
   587   }
   588   exports.toSetString = toSetString;
   590   function fromSetString(aStr) {
   591     return aStr.substr(1);
   592   }
   593   exports.fromSetString = fromSetString;
   595   function relative(aRoot, aPath) {
   596     aRoot = aRoot.replace(/\/$/, '');
   598     var url = urlParse(aRoot);
   599     if (aPath.charAt(0) == "/" && url && url.path == "/") {
   600       return aPath.slice(1);
   601     }
   603     return aPath.indexOf(aRoot + '/') === 0
   604       ? aPath.substr(aRoot.length + 1)
   605       : aPath;
   606   }
   607   exports.relative = relative;
   609   function strcmp(aStr1, aStr2) {
   610     var s1 = aStr1 || "";
   611     var s2 = aStr2 || "";
   612     return (s1 > s2) - (s1 < s2);
   613   }
   615   /**
   616    * Comparator between two mappings where the original positions are compared.
   617    *
   618    * Optionally pass in `true` as `onlyCompareGenerated` to consider two
   619    * mappings with the same original source/line/column, but different generated
   620    * line and column the same. Useful when searching for a mapping with a
   621    * stubbed out mapping.
   622    */
   623   function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
   624     var cmp;
   626     cmp = strcmp(mappingA.source, mappingB.source);
   627     if (cmp) {
   628       return cmp;
   629     }
   631     cmp = mappingA.originalLine - mappingB.originalLine;
   632     if (cmp) {
   633       return cmp;
   634     }
   636     cmp = mappingA.originalColumn - mappingB.originalColumn;
   637     if (cmp || onlyCompareOriginal) {
   638       return cmp;
   639     }
   641     cmp = strcmp(mappingA.name, mappingB.name);
   642     if (cmp) {
   643       return cmp;
   644     }
   646     cmp = mappingA.generatedLine - mappingB.generatedLine;
   647     if (cmp) {
   648       return cmp;
   649     }
   651     return mappingA.generatedColumn - mappingB.generatedColumn;
   652   };
   653   exports.compareByOriginalPositions = compareByOriginalPositions;
   655   /**
   656    * Comparator between two mappings where the generated positions are
   657    * compared.
   658    *
   659    * Optionally pass in `true` as `onlyCompareGenerated` to consider two
   660    * mappings with the same generated line and column, but different
   661    * source/name/original line and column the same. Useful when searching for a
   662    * mapping with a stubbed out mapping.
   663    */
   664   function compareByGeneratedPositions(mappingA, mappingB, onlyCompareGenerated) {
   665     var cmp;
   667     cmp = mappingA.generatedLine - mappingB.generatedLine;
   668     if (cmp) {
   669       return cmp;
   670     }
   672     cmp = mappingA.generatedColumn - mappingB.generatedColumn;
   673     if (cmp || onlyCompareGenerated) {
   674       return cmp;
   675     }
   677     cmp = strcmp(mappingA.source, mappingB.source);
   678     if (cmp) {
   679       return cmp;
   680     }
   682     cmp = mappingA.originalLine - mappingB.originalLine;
   683     if (cmp) {
   684       return cmp;
   685     }
   687     cmp = mappingA.originalColumn - mappingB.originalColumn;
   688     if (cmp) {
   689       return cmp;
   690     }
   692     return strcmp(mappingA.name, mappingB.name);
   693   };
   694   exports.compareByGeneratedPositions = compareByGeneratedPositions;
   696 });
   697 /* -*- Mode: js; js-indent-level: 2; -*- */
   698 /*
   699  * Copyright 2011 Mozilla Foundation and contributors
   700  * Licensed under the New BSD license. See LICENSE or:
   701  * http://opensource.org/licenses/BSD-3-Clause
   702  */
   703 define('source-map/binary-search', ['require', 'exports', 'module' , ], function(require, exports, module) {
   705   /**
   706    * Recursive implementation of binary search.
   707    *
   708    * @param aLow Indices here and lower do not contain the needle.
   709    * @param aHigh Indices here and higher do not contain the needle.
   710    * @param aNeedle The element being searched for.
   711    * @param aHaystack The non-empty array being searched.
   712    * @param aCompare Function which takes two elements and returns -1, 0, or 1.
   713    */
   714   function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare) {
   715     // This function terminates when one of the following is true:
   716     //
   717     //   1. We find the exact element we are looking for.
   718     //
   719     //   2. We did not find the exact element, but we can return the next
   720     //      closest element that is less than that element.
   721     //
   722     //   3. We did not find the exact element, and there is no next-closest
   723     //      element which is less than the one we are searching for, so we
   724     //      return null.
   725     var mid = Math.floor((aHigh - aLow) / 2) + aLow;
   726     var cmp = aCompare(aNeedle, aHaystack[mid], true);
   727     if (cmp === 0) {
   728       // Found the element we are looking for.
   729       return aHaystack[mid];
   730     }
   731     else if (cmp > 0) {
   732       // aHaystack[mid] is greater than our needle.
   733       if (aHigh - mid > 1) {
   734         // The element is in the upper half.
   735         return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare);
   736       }
   737       // We did not find an exact match, return the next closest one
   738       // (termination case 2).
   739       return aHaystack[mid];
   740     }
   741     else {
   742       // aHaystack[mid] is less than our needle.
   743       if (mid - aLow > 1) {
   744         // The element is in the lower half.
   745         return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare);
   746       }
   747       // The exact needle element was not found in this haystack. Determine if
   748       // we are in termination case (2) or (3) and return the appropriate thing.
   749       return aLow < 0
   750         ? null
   751         : aHaystack[aLow];
   752     }
   753   }
   755   /**
   756    * This is an implementation of binary search which will always try and return
   757    * the next lowest value checked if there is no exact hit. This is because
   758    * mappings between original and generated line/col pairs are single points,
   759    * and there is an implicit region between each of them, so a miss just means
   760    * that you aren't on the very start of a region.
   761    *
   762    * @param aNeedle The element you are looking for.
   763    * @param aHaystack The array that is being searched.
   764    * @param aCompare A function which takes the needle and an element in the
   765    *     array and returns -1, 0, or 1 depending on whether the needle is less
   766    *     than, equal to, or greater than the element, respectively.
   767    */
   768   exports.search = function search(aNeedle, aHaystack, aCompare) {
   769     return aHaystack.length > 0
   770       ? recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare)
   771       : null;
   772   };
   774 });
   775 /* -*- Mode: js; js-indent-level: 2; -*- */
   776 /*
   777  * Copyright 2011 Mozilla Foundation and contributors
   778  * Licensed under the New BSD license. See LICENSE or:
   779  * http://opensource.org/licenses/BSD-3-Clause
   780  */
   781 define('source-map/array-set', ['require', 'exports', 'module' ,  'source-map/util'], function(require, exports, module) {
   783   var util = require('source-map/util');
   785   /**
   786    * A data structure which is a combination of an array and a set. Adding a new
   787    * member is O(1), testing for membership is O(1), and finding the index of an
   788    * element is O(1). Removing elements from the set is not supported. Only
   789    * strings are supported for membership.
   790    */
   791   function ArraySet() {
   792     this._array = [];
   793     this._set = {};
   794   }
   796   /**
   797    * Static method for creating ArraySet instances from an existing array.
   798    */
   799   ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
   800     var set = new ArraySet();
   801     for (var i = 0, len = aArray.length; i < len; i++) {
   802       set.add(aArray[i], aAllowDuplicates);
   803     }
   804     return set;
   805   };
   807   /**
   808    * Add the given string to this set.
   809    *
   810    * @param String aStr
   811    */
   812   ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
   813     var isDuplicate = this.has(aStr);
   814     var idx = this._array.length;
   815     if (!isDuplicate || aAllowDuplicates) {
   816       this._array.push(aStr);
   817     }
   818     if (!isDuplicate) {
   819       this._set[util.toSetString(aStr)] = idx;
   820     }
   821   };
   823   /**
   824    * Is the given string a member of this set?
   825    *
   826    * @param String aStr
   827    */
   828   ArraySet.prototype.has = function ArraySet_has(aStr) {
   829     return Object.prototype.hasOwnProperty.call(this._set,
   830                                                 util.toSetString(aStr));
   831   };
   833   /**
   834    * What is the index of the given string in the array?
   835    *
   836    * @param String aStr
   837    */
   838   ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
   839     if (this.has(aStr)) {
   840       return this._set[util.toSetString(aStr)];
   841     }
   842     throw new Error('"' + aStr + '" is not in the set.');
   843   };
   845   /**
   846    * What is the element at the given index?
   847    *
   848    * @param Number aIdx
   849    */
   850   ArraySet.prototype.at = function ArraySet_at(aIdx) {
   851     if (aIdx >= 0 && aIdx < this._array.length) {
   852       return this._array[aIdx];
   853     }
   854     throw new Error('No element indexed by ' + aIdx);
   855   };
   857   /**
   858    * Returns the array representation of this set (which has the proper indices
   859    * indicated by indexOf). Note that this is a copy of the internal array used
   860    * for storing the members so that no one can mess with internal state.
   861    */
   862   ArraySet.prototype.toArray = function ArraySet_toArray() {
   863     return this._array.slice();
   864   };
   866   exports.ArraySet = ArraySet;
   868 });
   869 /* -*- Mode: js; js-indent-level: 2; -*- */
   870 /*
   871  * Copyright 2011 Mozilla Foundation and contributors
   872  * Licensed under the New BSD license. See LICENSE or:
   873  * http://opensource.org/licenses/BSD-3-Clause
   874  *
   875  * Based on the Base 64 VLQ implementation in Closure Compiler:
   876  * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
   877  *
   878  * Copyright 2011 The Closure Compiler Authors. All rights reserved.
   879  * Redistribution and use in source and binary forms, with or without
   880  * modification, are permitted provided that the following conditions are
   881  * met:
   882  *
   883  *  * Redistributions of source code must retain the above copyright
   884  *    notice, this list of conditions and the following disclaimer.
   885  *  * Redistributions in binary form must reproduce the above
   886  *    copyright notice, this list of conditions and the following
   887  *    disclaimer in the documentation and/or other materials provided
   888  *    with the distribution.
   889  *  * Neither the name of Google Inc. nor the names of its
   890  *    contributors may be used to endorse or promote products derived
   891  *    from this software without specific prior written permission.
   892  *
   893  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   894  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   895  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   896  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   897  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   898  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   899  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   900  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   901  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   902  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   903  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   904  */
   905 define('source-map/base64-vlq', ['require', 'exports', 'module' ,  'source-map/base64'], function(require, exports, module) {
   907   var base64 = require('source-map/base64');
   909   // A single base 64 digit can contain 6 bits of data. For the base 64 variable
   910   // length quantities we use in the source map spec, the first bit is the sign,
   911   // the next four bits are the actual value, and the 6th bit is the
   912   // continuation bit. The continuation bit tells us whether there are more
   913   // digits in this value following this digit.
   914   //
   915   //   Continuation
   916   //   |    Sign
   917   //   |    |
   918   //   V    V
   919   //   101011
   921   var VLQ_BASE_SHIFT = 5;
   923   // binary: 100000
   924   var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
   926   // binary: 011111
   927   var VLQ_BASE_MASK = VLQ_BASE - 1;
   929   // binary: 100000
   930   var VLQ_CONTINUATION_BIT = VLQ_BASE;
   932   /**
   933    * Converts from a two-complement value to a value where the sign bit is
   934    * is placed in the least significant bit.  For example, as decimals:
   935    *   1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
   936    *   2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
   937    */
   938   function toVLQSigned(aValue) {
   939     return aValue < 0
   940       ? ((-aValue) << 1) + 1
   941       : (aValue << 1) + 0;
   942   }
   944   /**
   945    * Converts to a two-complement value from a value where the sign bit is
   946    * is placed in the least significant bit.  For example, as decimals:
   947    *   2 (10 binary) becomes 1, 3 (11 binary) becomes -1
   948    *   4 (100 binary) becomes 2, 5 (101 binary) becomes -2
   949    */
   950   function fromVLQSigned(aValue) {
   951     var isNegative = (aValue & 1) === 1;
   952     var shifted = aValue >> 1;
   953     return isNegative
   954       ? -shifted
   955       : shifted;
   956   }
   958   /**
   959    * Returns the base 64 VLQ encoded value.
   960    */
   961   exports.encode = function base64VLQ_encode(aValue) {
   962     var encoded = "";
   963     var digit;
   965     var vlq = toVLQSigned(aValue);
   967     do {
   968       digit = vlq & VLQ_BASE_MASK;
   969       vlq >>>= VLQ_BASE_SHIFT;
   970       if (vlq > 0) {
   971         // There are still more digits in this value, so we must make sure the
   972         // continuation bit is marked.
   973         digit |= VLQ_CONTINUATION_BIT;
   974       }
   975       encoded += base64.encode(digit);
   976     } while (vlq > 0);
   978     return encoded;
   979   };
   981   /**
   982    * Decodes the next base 64 VLQ value from the given string and returns the
   983    * value and the rest of the string.
   984    */
   985   exports.decode = function base64VLQ_decode(aStr) {
   986     var i = 0;
   987     var strLen = aStr.length;
   988     var result = 0;
   989     var shift = 0;
   990     var continuation, digit;
   992     do {
   993       if (i >= strLen) {
   994         throw new Error("Expected more digits in base 64 VLQ value.");
   995       }
   996       digit = base64.decode(aStr.charAt(i++));
   997       continuation = !!(digit & VLQ_CONTINUATION_BIT);
   998       digit &= VLQ_BASE_MASK;
   999       result = result + (digit << shift);
  1000       shift += VLQ_BASE_SHIFT;
  1001     } while (continuation);
  1003     return {
  1004       value: fromVLQSigned(result),
  1005       rest: aStr.slice(i)
  1006     };
  1007   };
  1009 });
  1010 /* -*- Mode: js; js-indent-level: 2; -*- */
  1011 /*
  1012  * Copyright 2011 Mozilla Foundation and contributors
  1013  * Licensed under the New BSD license. See LICENSE or:
  1014  * http://opensource.org/licenses/BSD-3-Clause
  1015  */
  1016 define('source-map/base64', ['require', 'exports', 'module' , ], function(require, exports, module) {
  1018   var charToIntMap = {};
  1019   var intToCharMap = {};
  1021   'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
  1022     .split('')
  1023     .forEach(function (ch, index) {
  1024       charToIntMap[ch] = index;
  1025       intToCharMap[index] = ch;
  1026     });
  1028   /**
  1029    * Encode an integer in the range of 0 to 63 to a single base 64 digit.
  1030    */
  1031   exports.encode = function base64_encode(aNumber) {
  1032     if (aNumber in intToCharMap) {
  1033       return intToCharMap[aNumber];
  1035     throw new TypeError("Must be between 0 and 63: " + aNumber);
  1036   };
  1038   /**
  1039    * Decode a single base 64 digit to an integer.
  1040    */
  1041   exports.decode = function base64_decode(aChar) {
  1042     if (aChar in charToIntMap) {
  1043       return charToIntMap[aChar];
  1045     throw new TypeError("Not a valid base 64 digit: " + aChar);
  1046   };
  1048 });
  1049 /* -*- Mode: js; js-indent-level: 2; -*- */
  1050 /*
  1051  * Copyright 2011 Mozilla Foundation and contributors
  1052  * Licensed under the New BSD license. See LICENSE or:
  1053  * http://opensource.org/licenses/BSD-3-Clause
  1054  */
  1055 define('source-map/source-map-generator', ['require', 'exports', 'module' ,  'source-map/base64-vlq', 'source-map/util', 'source-map/array-set'], function(require, exports, module) {
  1057   var base64VLQ = require('source-map/base64-vlq');
  1058   var util = require('source-map/util');
  1059   var ArraySet = require('source-map/array-set').ArraySet;
  1061   /**
  1062    * An instance of the SourceMapGenerator represents a source map which is
  1063    * being built incrementally. To create a new one, you must pass an object
  1064    * with the following properties:
  1066    *   - file: The filename of the generated source.
  1067    *   - sourceRoot: An optional root for all URLs in this source map.
  1068    */
  1069   function SourceMapGenerator(aArgs) {
  1070     this._file = util.getArg(aArgs, 'file');
  1071     this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
  1072     this._sources = new ArraySet();
  1073     this._names = new ArraySet();
  1074     this._mappings = [];
  1075     this._sourcesContents = null;
  1078   SourceMapGenerator.prototype._version = 3;
  1080   /**
  1081    * Creates a new SourceMapGenerator based on a SourceMapConsumer
  1083    * @param aSourceMapConsumer The SourceMap.
  1084    */
  1085   SourceMapGenerator.fromSourceMap =
  1086     function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
  1087       var sourceRoot = aSourceMapConsumer.sourceRoot;
  1088       var generator = new SourceMapGenerator({
  1089         file: aSourceMapConsumer.file,
  1090         sourceRoot: sourceRoot
  1091       });
  1092       aSourceMapConsumer.eachMapping(function (mapping) {
  1093         var newMapping = {
  1094           generated: {
  1095             line: mapping.generatedLine,
  1096             column: mapping.generatedColumn
  1098         };
  1100         if (mapping.source) {
  1101           newMapping.source = mapping.source;
  1102           if (sourceRoot) {
  1103             newMapping.source = util.relative(sourceRoot, newMapping.source);
  1106           newMapping.original = {
  1107             line: mapping.originalLine,
  1108             column: mapping.originalColumn
  1109           };
  1111           if (mapping.name) {
  1112             newMapping.name = mapping.name;
  1116         generator.addMapping(newMapping);
  1117       });
  1118       aSourceMapConsumer.sources.forEach(function (sourceFile) {
  1119         var content = aSourceMapConsumer.sourceContentFor(sourceFile);
  1120         if (content) {
  1121           generator.setSourceContent(sourceFile, content);
  1123       });
  1124       return generator;
  1125     };
  1127   /**
  1128    * Add a single mapping from original source line and column to the generated
  1129    * source's line and column for this source map being created. The mapping
  1130    * object should have the following properties:
  1132    *   - generated: An object with the generated line and column positions.
  1133    *   - original: An object with the original line and column positions.
  1134    *   - source: The original source file (relative to the sourceRoot).
  1135    *   - name: An optional original token name for this mapping.
  1136    */
  1137   SourceMapGenerator.prototype.addMapping =
  1138     function SourceMapGenerator_addMapping(aArgs) {
  1139       var generated = util.getArg(aArgs, 'generated');
  1140       var original = util.getArg(aArgs, 'original', null);
  1141       var source = util.getArg(aArgs, 'source', null);
  1142       var name = util.getArg(aArgs, 'name', null);
  1144       this._validateMapping(generated, original, source, name);
  1146       if (source && !this._sources.has(source)) {
  1147         this._sources.add(source);
  1150       if (name && !this._names.has(name)) {
  1151         this._names.add(name);
  1154       this._mappings.push({
  1155         generatedLine: generated.line,
  1156         generatedColumn: generated.column,
  1157         originalLine: original != null && original.line,
  1158         originalColumn: original != null && original.column,
  1159         source: source,
  1160         name: name
  1161       });
  1162     };
  1164   /**
  1165    * Set the source content for a source file.
  1166    */
  1167   SourceMapGenerator.prototype.setSourceContent =
  1168     function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
  1169       var source = aSourceFile;
  1170       if (this._sourceRoot) {
  1171         source = util.relative(this._sourceRoot, source);
  1174       if (aSourceContent !== null) {
  1175         // Add the source content to the _sourcesContents map.
  1176         // Create a new _sourcesContents map if the property is null.
  1177         if (!this._sourcesContents) {
  1178           this._sourcesContents = {};
  1180         this._sourcesContents[util.toSetString(source)] = aSourceContent;
  1181       } else {
  1182         // Remove the source file from the _sourcesContents map.
  1183         // If the _sourcesContents map is empty, set the property to null.
  1184         delete this._sourcesContents[util.toSetString(source)];
  1185         if (Object.keys(this._sourcesContents).length === 0) {
  1186           this._sourcesContents = null;
  1189     };
  1191   /**
  1192    * Applies the mappings of a sub-source-map for a specific source file to the
  1193    * source map being generated. Each mapping to the supplied source file is
  1194    * rewritten using the supplied source map. Note: The resolution for the
  1195    * resulting mappings is the minimium of this map and the supplied map.
  1197    * @param aSourceMapConsumer The source map to be applied.
  1198    * @param aSourceFile Optional. The filename of the source file.
  1199    *        If omitted, SourceMapConsumer's file property will be used.
  1200    */
  1201   SourceMapGenerator.prototype.applySourceMap =
  1202     function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile) {
  1203       // If aSourceFile is omitted, we will use the file property of the SourceMap
  1204       if (!aSourceFile) {
  1205         aSourceFile = aSourceMapConsumer.file;
  1207       var sourceRoot = this._sourceRoot;
  1208       // Make "aSourceFile" relative if an absolute Url is passed.
  1209       if (sourceRoot) {
  1210         aSourceFile = util.relative(sourceRoot, aSourceFile);
  1212       // Applying the SourceMap can add and remove items from the sources and
  1213       // the names array.
  1214       var newSources = new ArraySet();
  1215       var newNames = new ArraySet();
  1217       // Find mappings for the "aSourceFile"
  1218       this._mappings.forEach(function (mapping) {
  1219         if (mapping.source === aSourceFile && mapping.originalLine) {
  1220           // Check if it can be mapped by the source map, then update the mapping.
  1221           var original = aSourceMapConsumer.originalPositionFor({
  1222             line: mapping.originalLine,
  1223             column: mapping.originalColumn
  1224           });
  1225           if (original.source !== null) {
  1226             // Copy mapping
  1227             if (sourceRoot) {
  1228               mapping.source = util.relative(sourceRoot, original.source);
  1229             } else {
  1230               mapping.source = original.source;
  1232             mapping.originalLine = original.line;
  1233             mapping.originalColumn = original.column;
  1234             if (original.name !== null && mapping.name !== null) {
  1235               // Only use the identifier name if it's an identifier
  1236               // in both SourceMaps
  1237               mapping.name = original.name;
  1242         var source = mapping.source;
  1243         if (source && !newSources.has(source)) {
  1244           newSources.add(source);
  1247         var name = mapping.name;
  1248         if (name && !newNames.has(name)) {
  1249           newNames.add(name);
  1252       }, this);
  1253       this._sources = newSources;
  1254       this._names = newNames;
  1256       // Copy sourcesContents of applied map.
  1257       aSourceMapConsumer.sources.forEach(function (sourceFile) {
  1258         var content = aSourceMapConsumer.sourceContentFor(sourceFile);
  1259         if (content) {
  1260           if (sourceRoot) {
  1261             sourceFile = util.relative(sourceRoot, sourceFile);
  1263           this.setSourceContent(sourceFile, content);
  1265       }, this);
  1266     };
  1268   /**
  1269    * A mapping can have one of the three levels of data:
  1271    *   1. Just the generated position.
  1272    *   2. The Generated position, original position, and original source.
  1273    *   3. Generated and original position, original source, as well as a name
  1274    *      token.
  1276    * To maintain consistency, we validate that any new mapping being added falls
  1277    * in to one of these categories.
  1278    */
  1279   SourceMapGenerator.prototype._validateMapping =
  1280     function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
  1281                                                 aName) {
  1282       if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
  1283           && aGenerated.line > 0 && aGenerated.column >= 0
  1284           && !aOriginal && !aSource && !aName) {
  1285         // Case 1.
  1286         return;
  1288       else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
  1289                && aOriginal && 'line' in aOriginal && 'column' in aOriginal
  1290                && aGenerated.line > 0 && aGenerated.column >= 0
  1291                && aOriginal.line > 0 && aOriginal.column >= 0
  1292                && aSource) {
  1293         // Cases 2 and 3.
  1294         return;
  1296       else {
  1297         throw new Error('Invalid mapping: ' + JSON.stringify({
  1298           generated: aGenerated,
  1299           source: aSource,
  1300           original: aOriginal,
  1301           name: aName
  1302         }));
  1304     };
  1306   /**
  1307    * Serialize the accumulated mappings in to the stream of base 64 VLQs
  1308    * specified by the source map format.
  1309    */
  1310   SourceMapGenerator.prototype._serializeMappings =
  1311     function SourceMapGenerator_serializeMappings() {
  1312       var previousGeneratedColumn = 0;
  1313       var previousGeneratedLine = 1;
  1314       var previousOriginalColumn = 0;
  1315       var previousOriginalLine = 0;
  1316       var previousName = 0;
  1317       var previousSource = 0;
  1318       var result = '';
  1319       var mapping;
  1321       // The mappings must be guaranteed to be in sorted order before we start
  1322       // serializing them or else the generated line numbers (which are defined
  1323       // via the ';' separators) will be all messed up. Note: it might be more
  1324       // performant to maintain the sorting as we insert them, rather than as we
  1325       // serialize them, but the big O is the same either way.
  1326       this._mappings.sort(util.compareByGeneratedPositions);
  1328       for (var i = 0, len = this._mappings.length; i < len; i++) {
  1329         mapping = this._mappings[i];
  1331         if (mapping.generatedLine !== previousGeneratedLine) {
  1332           previousGeneratedColumn = 0;
  1333           while (mapping.generatedLine !== previousGeneratedLine) {
  1334             result += ';';
  1335             previousGeneratedLine++;
  1338         else {
  1339           if (i > 0) {
  1340             if (!util.compareByGeneratedPositions(mapping, this._mappings[i - 1])) {
  1341               continue;
  1343             result += ',';
  1347         result += base64VLQ.encode(mapping.generatedColumn
  1348                                    - previousGeneratedColumn);
  1349         previousGeneratedColumn = mapping.generatedColumn;
  1351         if (mapping.source) {
  1352           result += base64VLQ.encode(this._sources.indexOf(mapping.source)
  1353                                      - previousSource);
  1354           previousSource = this._sources.indexOf(mapping.source);
  1356           // lines are stored 0-based in SourceMap spec version 3
  1357           result += base64VLQ.encode(mapping.originalLine - 1
  1358                                      - previousOriginalLine);
  1359           previousOriginalLine = mapping.originalLine - 1;
  1361           result += base64VLQ.encode(mapping.originalColumn
  1362                                      - previousOriginalColumn);
  1363           previousOriginalColumn = mapping.originalColumn;
  1365           if (mapping.name) {
  1366             result += base64VLQ.encode(this._names.indexOf(mapping.name)
  1367                                        - previousName);
  1368             previousName = this._names.indexOf(mapping.name);
  1373       return result;
  1374     };
  1376   SourceMapGenerator.prototype._generateSourcesContent =
  1377     function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
  1378       return aSources.map(function (source) {
  1379         if (!this._sourcesContents) {
  1380           return null;
  1382         if (aSourceRoot) {
  1383           source = util.relative(aSourceRoot, source);
  1385         var key = util.toSetString(source);
  1386         return Object.prototype.hasOwnProperty.call(this._sourcesContents,
  1387                                                     key)
  1388           ? this._sourcesContents[key]
  1389           : null;
  1390       }, this);
  1391     };
  1393   /**
  1394    * Externalize the source map.
  1395    */
  1396   SourceMapGenerator.prototype.toJSON =
  1397     function SourceMapGenerator_toJSON() {
  1398       var map = {
  1399         version: this._version,
  1400         file: this._file,
  1401         sources: this._sources.toArray(),
  1402         names: this._names.toArray(),
  1403         mappings: this._serializeMappings()
  1404       };
  1405       if (this._sourceRoot) {
  1406         map.sourceRoot = this._sourceRoot;
  1408       if (this._sourcesContents) {
  1409         map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
  1412       return map;
  1413     };
  1415   /**
  1416    * Render the source map being generated to a string.
  1417    */
  1418   SourceMapGenerator.prototype.toString =
  1419     function SourceMapGenerator_toString() {
  1420       return JSON.stringify(this);
  1421     };
  1423   exports.SourceMapGenerator = SourceMapGenerator;
  1425 });
  1426 /* -*- Mode: js; js-indent-level: 2; -*- */
  1427 /*
  1428  * Copyright 2011 Mozilla Foundation and contributors
  1429  * Licensed under the New BSD license. See LICENSE or:
  1430  * http://opensource.org/licenses/BSD-3-Clause
  1431  */
  1432 define('source-map/source-node', ['require', 'exports', 'module' ,  'source-map/source-map-generator', 'source-map/util'], function(require, exports, module) {
  1434   var SourceMapGenerator = require('source-map/source-map-generator').SourceMapGenerator;
  1435   var util = require('source-map/util');
  1437   /**
  1438    * SourceNodes provide a way to abstract over interpolating/concatenating
  1439    * snippets of generated JavaScript source code while maintaining the line and
  1440    * column information associated with the original source code.
  1442    * @param aLine The original line number.
  1443    * @param aColumn The original column number.
  1444    * @param aSource The original source's filename.
  1445    * @param aChunks Optional. An array of strings which are snippets of
  1446    *        generated JS, or other SourceNodes.
  1447    * @param aName The original identifier.
  1448    */
  1449   function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
  1450     this.children = [];
  1451     this.sourceContents = {};
  1452     this.line = aLine === undefined ? null : aLine;
  1453     this.column = aColumn === undefined ? null : aColumn;
  1454     this.source = aSource === undefined ? null : aSource;
  1455     this.name = aName === undefined ? null : aName;
  1456     if (aChunks != null) this.add(aChunks);
  1459   /**
  1460    * Creates a SourceNode from generated code and a SourceMapConsumer.
  1462    * @param aGeneratedCode The generated code
  1463    * @param aSourceMapConsumer The SourceMap for the generated code
  1464    */
  1465   SourceNode.fromStringWithSourceMap =
  1466     function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer) {
  1467       // The SourceNode we want to fill with the generated code
  1468       // and the SourceMap
  1469       var node = new SourceNode();
  1471       // The generated code
  1472       // Processed fragments are removed from this array.
  1473       var remainingLines = aGeneratedCode.split('\n');
  1475       // We need to remember the position of "remainingLines"
  1476       var lastGeneratedLine = 1, lastGeneratedColumn = 0;
  1478       // The generate SourceNodes we need a code range.
  1479       // To extract it current and last mapping is used.
  1480       // Here we store the last mapping.
  1481       var lastMapping = null;
  1483       aSourceMapConsumer.eachMapping(function (mapping) {
  1484         if (lastMapping === null) {
  1485           // We add the generated code until the first mapping
  1486           // to the SourceNode without any mapping.
  1487           // Each line is added as separate string.
  1488           while (lastGeneratedLine < mapping.generatedLine) {
  1489             node.add(remainingLines.shift() + "\n");
  1490             lastGeneratedLine++;
  1492           if (lastGeneratedColumn < mapping.generatedColumn) {
  1493             var nextLine = remainingLines[0];
  1494             node.add(nextLine.substr(0, mapping.generatedColumn));
  1495             remainingLines[0] = nextLine.substr(mapping.generatedColumn);
  1496             lastGeneratedColumn = mapping.generatedColumn;
  1498         } else {
  1499           // We add the code from "lastMapping" to "mapping":
  1500           // First check if there is a new line in between.
  1501           if (lastGeneratedLine < mapping.generatedLine) {
  1502             var code = "";
  1503             // Associate full lines with "lastMapping"
  1504             do {
  1505               code += remainingLines.shift() + "\n";
  1506               lastGeneratedLine++;
  1507               lastGeneratedColumn = 0;
  1508             } while (lastGeneratedLine < mapping.generatedLine);
  1509             // When we reached the correct line, we add code until we
  1510             // reach the correct column too.
  1511             if (lastGeneratedColumn < mapping.generatedColumn) {
  1512               var nextLine = remainingLines[0];
  1513               code += nextLine.substr(0, mapping.generatedColumn);
  1514               remainingLines[0] = nextLine.substr(mapping.generatedColumn);
  1515               lastGeneratedColumn = mapping.generatedColumn;
  1517             // Create the SourceNode.
  1518             addMappingWithCode(lastMapping, code);
  1519           } else {
  1520             // There is no new line in between.
  1521             // Associate the code between "lastGeneratedColumn" and
  1522             // "mapping.generatedColumn" with "lastMapping"
  1523             var nextLine = remainingLines[0];
  1524             var code = nextLine.substr(0, mapping.generatedColumn -
  1525                                           lastGeneratedColumn);
  1526             remainingLines[0] = nextLine.substr(mapping.generatedColumn -
  1527                                                 lastGeneratedColumn);
  1528             lastGeneratedColumn = mapping.generatedColumn;
  1529             addMappingWithCode(lastMapping, code);
  1532         lastMapping = mapping;
  1533       }, this);
  1534       // We have processed all mappings.
  1535       // Associate the remaining code in the current line with "lastMapping"
  1536       // and add the remaining lines without any mapping
  1537       addMappingWithCode(lastMapping, remainingLines.join("\n"));
  1539       // Copy sourcesContent into SourceNode
  1540       aSourceMapConsumer.sources.forEach(function (sourceFile) {
  1541         var content = aSourceMapConsumer.sourceContentFor(sourceFile);
  1542         if (content) {
  1543           node.setSourceContent(sourceFile, content);
  1545       });
  1547       return node;
  1549       function addMappingWithCode(mapping, code) {
  1550         if (mapping === null || mapping.source === undefined) {
  1551           node.add(code);
  1552         } else {
  1553           node.add(new SourceNode(mapping.originalLine,
  1554                                   mapping.originalColumn,
  1555                                   mapping.source,
  1556                                   code,
  1557                                   mapping.name));
  1560     };
  1562   /**
  1563    * Add a chunk of generated JS to this source node.
  1565    * @param aChunk A string snippet of generated JS code, another instance of
  1566    *        SourceNode, or an array where each member is one of those things.
  1567    */
  1568   SourceNode.prototype.add = function SourceNode_add(aChunk) {
  1569     if (Array.isArray(aChunk)) {
  1570       aChunk.forEach(function (chunk) {
  1571         this.add(chunk);
  1572       }, this);
  1574     else if (aChunk instanceof SourceNode || typeof aChunk === "string") {
  1575       if (aChunk) {
  1576         this.children.push(aChunk);
  1579     else {
  1580       throw new TypeError(
  1581         "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
  1582       );
  1584     return this;
  1585   };
  1587   /**
  1588    * Add a chunk of generated JS to the beginning of this source node.
  1590    * @param aChunk A string snippet of generated JS code, another instance of
  1591    *        SourceNode, or an array where each member is one of those things.
  1592    */
  1593   SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
  1594     if (Array.isArray(aChunk)) {
  1595       for (var i = aChunk.length-1; i >= 0; i--) {
  1596         this.prepend(aChunk[i]);
  1599     else if (aChunk instanceof SourceNode || typeof aChunk === "string") {
  1600       this.children.unshift(aChunk);
  1602     else {
  1603       throw new TypeError(
  1604         "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
  1605       );
  1607     return this;
  1608   };
  1610   /**
  1611    * Walk over the tree of JS snippets in this node and its children. The
  1612    * walking function is called once for each snippet of JS and is passed that
  1613    * snippet and the its original associated source's line/column location.
  1615    * @param aFn The traversal function.
  1616    */
  1617   SourceNode.prototype.walk = function SourceNode_walk(aFn) {
  1618     var chunk;
  1619     for (var i = 0, len = this.children.length; i < len; i++) {
  1620       chunk = this.children[i];
  1621       if (chunk instanceof SourceNode) {
  1622         chunk.walk(aFn);
  1624       else {
  1625         if (chunk !== '') {
  1626           aFn(chunk, { source: this.source,
  1627                        line: this.line,
  1628                        column: this.column,
  1629                        name: this.name });
  1633   };
  1635   /**
  1636    * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
  1637    * each of `this.children`.
  1639    * @param aSep The separator.
  1640    */
  1641   SourceNode.prototype.join = function SourceNode_join(aSep) {
  1642     var newChildren;
  1643     var i;
  1644     var len = this.children.length;
  1645     if (len > 0) {
  1646       newChildren = [];
  1647       for (i = 0; i < len-1; i++) {
  1648         newChildren.push(this.children[i]);
  1649         newChildren.push(aSep);
  1651       newChildren.push(this.children[i]);
  1652       this.children = newChildren;
  1654     return this;
  1655   };
  1657   /**
  1658    * Call String.prototype.replace on the very right-most source snippet. Useful
  1659    * for trimming whitespace from the end of a source node, etc.
  1661    * @param aPattern The pattern to replace.
  1662    * @param aReplacement The thing to replace the pattern with.
  1663    */
  1664   SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
  1665     var lastChild = this.children[this.children.length - 1];
  1666     if (lastChild instanceof SourceNode) {
  1667       lastChild.replaceRight(aPattern, aReplacement);
  1669     else if (typeof lastChild === 'string') {
  1670       this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
  1672     else {
  1673       this.children.push(''.replace(aPattern, aReplacement));
  1675     return this;
  1676   };
  1678   /**
  1679    * Set the source content for a source file. This will be added to the SourceMapGenerator
  1680    * in the sourcesContent field.
  1682    * @param aSourceFile The filename of the source file
  1683    * @param aSourceContent The content of the source file
  1684    */
  1685   SourceNode.prototype.setSourceContent =
  1686     function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
  1687       this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
  1688     };
  1690   /**
  1691    * Walk over the tree of SourceNodes. The walking function is called for each
  1692    * source file content and is passed the filename and source content.
  1694    * @param aFn The traversal function.
  1695    */
  1696   SourceNode.prototype.walkSourceContents =
  1697     function SourceNode_walkSourceContents(aFn) {
  1698       for (var i = 0, len = this.children.length; i < len; i++) {
  1699         if (this.children[i] instanceof SourceNode) {
  1700           this.children[i].walkSourceContents(aFn);
  1704       var sources = Object.keys(this.sourceContents);
  1705       for (var i = 0, len = sources.length; i < len; i++) {
  1706         aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
  1708     };
  1710   /**
  1711    * Return the string representation of this source node. Walks over the tree
  1712    * and concatenates all the various snippets together to one string.
  1713    */
  1714   SourceNode.prototype.toString = function SourceNode_toString() {
  1715     var str = "";
  1716     this.walk(function (chunk) {
  1717       str += chunk;
  1718     });
  1719     return str;
  1720   };
  1722   /**
  1723    * Returns the string representation of this source node along with a source
  1724    * map.
  1725    */
  1726   SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
  1727     var generated = {
  1728       code: "",
  1729       line: 1,
  1730       column: 0
  1731     };
  1732     var map = new SourceMapGenerator(aArgs);
  1733     var sourceMappingActive = false;
  1734     var lastOriginalSource = null;
  1735     var lastOriginalLine = null;
  1736     var lastOriginalColumn = null;
  1737     var lastOriginalName = null;
  1738     this.walk(function (chunk, original) {
  1739       generated.code += chunk;
  1740       if (original.source !== null
  1741           && original.line !== null
  1742           && original.column !== null) {
  1743         if(lastOriginalSource !== original.source
  1744            || lastOriginalLine !== original.line
  1745            || lastOriginalColumn !== original.column
  1746            || lastOriginalName !== original.name) {
  1747           map.addMapping({
  1748             source: original.source,
  1749             original: {
  1750               line: original.line,
  1751               column: original.column
  1752             },
  1753             generated: {
  1754               line: generated.line,
  1755               column: generated.column
  1756             },
  1757             name: original.name
  1758           });
  1760         lastOriginalSource = original.source;
  1761         lastOriginalLine = original.line;
  1762         lastOriginalColumn = original.column;
  1763         lastOriginalName = original.name;
  1764         sourceMappingActive = true;
  1765       } else if (sourceMappingActive) {
  1766         map.addMapping({
  1767           generated: {
  1768             line: generated.line,
  1769             column: generated.column
  1771         });
  1772         lastOriginalSource = null;
  1773         sourceMappingActive = false;
  1775       chunk.split('').forEach(function (ch) {
  1776         if (ch === '\n') {
  1777           generated.line++;
  1778           generated.column = 0;
  1779         } else {
  1780           generated.column++;
  1782       });
  1783     });
  1784     this.walkSourceContents(function (sourceFile, sourceContent) {
  1785       map.setSourceContent(sourceFile, sourceContent);
  1786     });
  1788     return { code: generated.code, map: map };
  1789   };
  1791   exports.SourceNode = SourceNode;
  1793 });
  1794 /* -*- Mode: js; js-indent-level: 2; -*- */
  1795 ///////////////////////////////////////////////////////////////////////////////
  1797 this.SourceMapConsumer = require('source-map/source-map-consumer').SourceMapConsumer;
  1798 this.SourceMapGenerator = require('source-map/source-map-generator').SourceMapGenerator;
  1799 this.SourceNode = require('source-map/source-node').SourceNode;

mercurial