PageSourceSearch

https://wormbuilder.org/crispr/

html wormbuilder.org collected 2026-09-24 12:34:19 UTC 2,348,323 bytes, 67,783 lines download raw bytes

1<!DOCTYPE html>
2<html>
3<head>
4  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5  
5<script type="application/shiny-singletons"></script>
5
6  
6<script type="application/html-dependencies">json2[2014.02.04];jquery[3.5.1];shiny[1.4.0.2];selectize[0.11.2];htmlwidgets[1.5.4];datatables-css[0.0.0];datatables-binding[0.13];crosstalk[1.2.0];bootstrap[3.4.1]</script>
vendor: 1 bytes, line 6
6
7<script src="shared/json2-min.js"></script>
vendor: 1 bytes, line 7
7
8<script src="jquery-3.5.1/jquery.min.js"></script>
8
9<link href="shared/shiny.css" rel="stylesheet" />
10<script src="shared/shiny.min.js"></script>
10
11<link href="shared/selectize/css/selectize.bootstrap3.css" rel="stylesheet" />
12<!--[if lt IE 9]>
13<script src="shared/selectize/js/es5-shim.min.js"></script>
13
14<![endif]-->
15<script src="shared/selectize/js/selectize.min.js"></script>
vendor: 1 bytes, line 15
15
16<script src="htmlwidgets-1.5.4/htmlwidgets.js"></script>
16
17<link href="datatables-css-0.0.0/datatables-crosstalk.css" rel="stylesheet" />
18<script src="datatables-binding-0.13/datatables.js"></script>
18
19<link href="crosstalk-1.2.0/css/crosstalk.min.css" rel="stylesheet" />
20<script src="crosstalk-1.2.0/js/crosstalk.min.js"></script>
20
21<meta name="viewport" content="width=device-width, initial-scale=1" />
22<link href="shared/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
23<script src="shared/bootstrap/js/bootstrap.min.js"></script>
vendor: 1 bytes, line 23
23
24<script src="shared/bootstrap/shim/html5shiv.min.js"></script>
vendor: 1 bytes, line 24
24
25<script src="shared/bootstrap/shim/respond.min.js"></script>
25  <link rel="stylesheet" type="text/css" href="bootstrap.min.css"/>
26  <title>C. elegans CRISPR-Cas9 library</title>
27<script src="__assets__/sockjs-0.3.4.min.js"></script>
vendor: 1 bytes, line 27
27
28<script src="__assets__/shiny-server-client.min.js"></script>
vendor: 1 bytes, line 28
28
29<script>preShinyInit({reconnect:true,disableProtocols:[]});</script>
29
30<link rel="stylesheet" type="text/css" href="__assets__/shiny-server.css"/>
31
32</head>
33<body>
34  <div class="container-fluid">
35    <style type="text/css">.js-irs-none .irs-single, .js-irs-none .irs-bar-edge, .js-irs-none .irs-bar {
36                          background: transparent;
37                          border-top-color: transparent;
38                          border-bottom-color: transparent;
39                          border-left-color: transparent;
40                          border-right-color: transparent}
41               .navbar-default .navbar-brand:hover {color: #ffffff;}
42               </style>
43    
43<script>
44                     Shiny.addCustomMessageHandler('igvstat-change', function(panel) {
45                     igv.visibilityChange()
46                     });
47                                 </script>
47
48    
48<script>
49                     Shiny.addCustomMessageHandler("downloadApe64", function(params) {
50                     var namas = params[0];
51                     var b64 = params[1];
52                     const a = document.createElement("a");
53                     document.body.append(a);
54                     //a.download = "oligo.gb";
55                     //a.download = b64.mime;
56                     a.download = namas;
57                     a.href = b64;
58                     a.click();
59                     a.remove();
60                    });
61                                 </script>
61
62    <nav class="navbar navbar-default navbar-static-top" role="navigation">
63      <div class="container-fluid">
64        <div class="navbar-header">
65          <span class="navbar-brand">
66            <a id="link_to_tabpanel_title" href="#" class="action-button"><b><i>C. elegans</i> CRISPR-Cas9 library</b></a>
67          </span>
68        </div>
69        <ul class="nav navbar-nav shiny-tab-input" id="panels" data-tabsetid="3862">
70          <li class="active">
71            <a href="#tab-3862-1" data-toggle="tab" data-value="Query">Query</a>
72          </li>
73          <li>
74            <a href="#tab-3862-2" data-toggle="tab" data-value="Browse">Browse</a>
75          </li>
76          <li>
77            <a href="#tab-3862-3" data-toggle="tab" data-value="Basket">Basket</a>
78          </li>
79          <li>
80            <a href="#tab-3862-4" data-toggle="tab" data-value="Downloads">Downloads</a>
81          </li>
82          <li>
83            <a href="#tab-3862-5" data-toggle="tab" data-value="About">About</a>
84          </li>
85        </ul>
86      </div>
87    </nav>
88    <div class="container-fluid">
89      <div class="tab-content" data-tabsetid="3862">
90        <div class="tab-pane active" data-value="Query" id="tab-3862-1">
91          <div class="row">
92            <h2>Search for gene targets</h2>
93            <div class="tab-pane span7" data-value="Gene search" title="Gene search">
94              <br/>
95              <div class="form-group shiny-input-container">
96                <label class="control-label" for="MultipleGeness">List of genes</label>
97                <textarea id="MultipleGeness" class="form-control" placeholder="Wormbase IDs, transcript or gene names separated by newlines or commas" style="width: 600px;  " rows="5" cols="100"></textarea>
98              </div>
99              <div class="form-group shiny-input-container">
100                <label class="control-label" for="crRNA_multiplegenes_type"><b>Type (location)</b></label>
101                <div>
102                  <select id="crRNA_multiplegenes_type"><option value="All">All</option>
103<option value="500 bp promoter">500 bp promoter</option>
104<option value="250 bp promoter">250 bp promoter</option>
105<option value="ATG">ATG</option>
106<option value="CDS">CDS</option>
107<option value="Stop">Stop</option></select>
108                  
108<script type="application/json" data-for="crRNA_multiplegenes_type" data-nonempty="">{}</script>
108
109                </div>
110              </div>
111              <button id="actionmultiplesearch" type="button" class="btn btn-default action-button">Search</button>
112              <hr/>
113              <pre id="ErrorMessageMultiple" class="shiny-text-output noplaceholder"></pre>
114              <div id="crRNAMultipleTab" style="width:100%; height:auto; " class="datatables html-widget html-widget-output"></div>
115              <div id="MultipleExtraoui" class="shiny-html-output"></div>
116            </div>
117          </div>
118        </div>
119        <div class="tab-pane" data-value="Browse" id="tab-3862-2">
120          <div class="row">
121            <h3>Browse your favorite location</h3>
122            
122<script>(function (global, factory) {
123    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
124    typeof define === 'function' && define.amd ? define(factory) :
125    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.igv = factory());
126})(this, (function () { 'use strict';
127
128    /*!
129     * jQuery JavaScript Library v3.3.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector
130     * https://jquery.com/
131     *
132     * Includes Sizzle.js
133     * https://sizzlejs.com/
134     *
135     * Copyright JS Foundation and other contributors
136     * Released under the MIT license
137     * https://jquery.org/license
138     *
139     * Date: 2018-01-20T17:24Z
140     */
141
142    var arr = [];
143    var document$2 = window.document;
144    var getProto = Object.getPrototypeOf;
145    var slice = arr.slice;
146    var concat$1 = arr.concat;
147    var push$1 = arr.push;
148    var indexOf$1 = arr.indexOf;
149    var class2type = {};
150    var toString$3 = class2type.toString;
151    var hasOwn = class2type.hasOwnProperty;
152    var fnToString = hasOwn.toString;
153    var ObjectFunctionString = fnToString.call(Object);
154    var support = {};
155
156    var isFunction = function isFunction(obj) {
157      // Support: Chrome <=57, Firefox <=52
158      // In some browsers, typeof returns "function" for HTML <object> elements
159      // (i.e., `typeof document.createElement( "object" ) === "function"`).
160      // We don't want to classify *any* DOM node as a function.
161      return typeof obj === "function" && typeof obj.nodeType !== "number";
162    };
163
164    var isWindow = function isWindow(obj) {
165      return obj != null && obj === obj.window;
166    };
167
168    var preservedScriptAttributes = {
169      type: true,
170      src: true,
171      noModule: true
172    };
173
174    function DOMEval(code, doc, node) {
175      doc = doc || document$2;
176      var i,
177          script = doc.createElement("script");
178      script.text = code;
179
180      if (node) {
181        for (i in preservedScriptAttributes) {
182          if (node[i]) {
183            script[i] = node[i];
184          }
185        }
186      }
187
188      doc.head.appendChild(script).parentNode.removeChild(script);
189    }
190
191    function toType(obj) {
192      if (obj == null) {
193        return obj + "";
194      } // Support: Android <=2.3 only (functionish RegExp)
195
196
197      return typeof obj === "object" || typeof obj === "function" ? class2type[toString$3.call(obj)] || "object" : typeof obj;
198    } // global Symbol
199    // Defining this global in .eslintrc.json would create a danger of using the global
200    // unguarded in another place, it seems safer to define global only for this module
201
202
203    var version$2 = "3.3.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector",
204        // Define a local copy of jQuery
205    jQuery = function (selector, context) {
206      // The jQuery object is actually just the init constructor 'enhanced'
207      // Need init if jQuery is called (just allow error to be thrown if not included)
208      return new jQuery.fn.init(selector, context);
209    },
210        // Support: Android <=4.0 only
211    // Make sure we trim BOM and NBSP
212    rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
213
214    jQuery.fn = jQuery.prototype = {
215      // The current version of jQuery being used
216      jquery: version$2,
217      constructor: jQuery,
218      // The default length of a jQuery object is 0
219      length: 0,
220      toArray: function () {
221        return slice.call(this);
222      },
223      // Get the Nth element in the matched element set OR
224      // Get the whole matched element set as a clean array
225      get: function (num) {
226        // Return all the elements in a clean array
227        if (num == null) {
228          return slice.call(this);
229        } // Return just the one element from the set
230
231
232        return num < 0 ? this[num + this.length] : this[num];
233      },
234      // Take an array of elements and push it onto the stack
235      // (returning the new matched element set)
236      pushStack: function (elems) {
237        // Build a new jQuery matched element set
238        var ret = jQuery.merge(this.constructor(), elems); // Add the old object onto the stack (as a reference)
239
vendor: 13,225 bytes, lines 240-633
240        ret.prevObject = this; // Return the newly-formed element set
241
242        return ret;
243      },
244      // Execute a callback for every element in the matched set.
245      each: function (callback) {
246        return jQuery.each(this, callback);
247      },
248      map: function (callback) {
249        return this.pushStack(jQuery.map(this, function (elem, i) {
250          return callback.call(elem, i, elem);
251        }));
252      },
253      slice: function () {
254        return this.pushStack(slice.apply(this, arguments));
255      },
256      first: function () {
257        return this.eq(0);
258      },
259      last: function () {
260        return this.eq(-1);
261      },
262      eq: function (i) {
263        var len = this.length,
264            j = +i + (i < 0 ? len : 0);
265        return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
266      },
267      end: function () {
268        return this.prevObject || this.constructor();
269      },
270      // For internal use only.
271      // Behaves like an Array's method, not like a jQuery method.
272      push: push$1,
273      sort: arr.sort,
274      splice: arr.splice
275    };
276
277    jQuery.extend = jQuery.fn.extend = function () {
278      var options,
279          name,
280          src,
281          copy,
282          copyIsArray,
283          clone,
284          target = arguments[0] || {},
285          i = 1,
286          length = arguments.length,
287          deep = false; // Handle a deep copy situation
288
289      if (typeof target === "boolean") {
290        deep = target; // Skip the boolean and the target
291
292        target = arguments[i] || {};
293        i++;
294      } // Handle case when target is a string or something (possible in deep copy)
295
296
297      if (typeof target !== "object" && !isFunction(target)) {
298        target = {};
299      } // Extend jQuery itself if only one argument is passed
300
301
302      if (i === length) {
303        target = this;
304        i--;
305      }
306
307      for (; i < length; i++) {
308        // Only deal with non-null/undefined values
309        if ((options = arguments[i]) != null) {
310          // Extend the base object
311          for (name in options) {
312            src = target[name];
313            copy = options[name]; // Prevent never-ending loop
314
315            if (target === copy) {
316              continue;
317            } // Recurse if we're merging plain objects or arrays
318
319
320            if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {
321              if (copyIsArray) {
322                copyIsArray = false;
323                clone = src && Array.isArray(src) ? src : [];
324              } else {
325                clone = src && jQuery.isPlainObject(src) ? src : {};
326              } // Never move original objects, clone them
327
328
329              target[name] = jQuery.extend(deep, clone, copy); // Don't bring in undefined values
330            } else if (copy !== undefined) {
331              target[name] = copy;
332            }
333          }
334        }
335      } // Return the modified object
336
337
338      return target;
339    };
340
341    jQuery.extend({
342      // Unique for each copy of jQuery on the page
343      expando: "jQuery" + (version$2 + Math.random()).replace(/\D/g, ""),
344      // Assume jQuery is ready without the ready module
345      isReady: true,
346      error: function (msg) {
347        throw new Error(msg);
348      },
349      noop: function () {},
350      isPlainObject: function (obj) {
351        var proto, Ctor; // Detect obvious negatives
352        // Use toString instead of jQuery.type to catch host objects
353
354        if (!obj || toString$3.call(obj) !== "[object Object]") {
355          return false;
356        }
357
358        proto = getProto(obj); // Objects with no prototype (e.g., `Object.create( null )`) are plain
359
360        if (!proto) {
361          return true;
362        } // Objects with prototype are plain iff they were constructed by a global Object function
363
364
365        Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
366        return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
367      },
368      isEmptyObject: function (obj) {
369        /* eslint-disable no-unused-vars */
370        // See https://github.com/eslint/eslint/issues/6125
371        var name;
372
373        for (name in obj) {
374          return false;
375        }
376
377        return true;
378      },
379      // Evaluates a script in a global context
380      globalEval: function (code) {
381        DOMEval(code);
382      },
383      each: function (obj, callback) {
384        var length,
385            i = 0;
386
387        if (isArrayLike(obj)) {
388          length = obj.length;
389
390          for (; i < length; i++) {
391            if (callback.call(obj[i], i, obj[i]) === false) {
392              break;
393            }
394          }
395        } else {
396          for (i in obj) {
397            if (callback.call(obj[i], i, obj[i]) === false) {
398              break;
399            }
400          }
401        }
402
403        return obj;
404      },
405      // Support: Android <=4.0 only
406      trim: function (text) {
407        return text == null ? "" : (text + "").replace(rtrim, "");
408      },
409      // results is for internal usage only
410      makeArray: function (arr, results) {
411        var ret = results || [];
412
413        if (arr != null) {
414          if (isArrayLike(Object(arr))) {
415            jQuery.merge(ret, typeof arr === "string" ? [arr] : arr);
416          } else {
417            push$1.call(ret, arr);
418          }
419        }
420
421        return ret;
422      },
423      inArray: function (elem, arr, i) {
424        return arr == null ? -1 : indexOf$1.call(arr, elem, i);
425      },
426      // Support: Android <=4.0 only, PhantomJS 1 only
427      // push.apply(_, arraylike) throws on ancient WebKit
428      merge: function (first, second) {
429        var len = +second.length,
430            j = 0,
431            i = first.length;
432
433        for (; j < len; j++) {
434          first[i++] = second[j];
435        }
436
437        first.length = i;
438        return first;
439      },
440      grep: function (elems, callback, invert) {
441        var callbackInverse,
442            matches = [],
443            i = 0,
444            length = elems.length,
445            callbackExpect = !invert; // Go through the array, only saving the items
446        // that pass the validator function
447
448        for (; i < length; i++) {
449          callbackInverse = !callback(elems[i], i);
450
451          if (callbackInverse !== callbackExpect) {
452            matches.push(elems[i]);
453          }
454        }
455
456        return matches;
457      },
458      // arg is for internal usage only
459      map: function (elems, callback, arg) {
460        var length,
461            value,
462            i = 0,
463            ret = []; // Go through the array, translating each of the items to their new values
464
465        if (isArrayLike(elems)) {
466          length = elems.length;
467
468          for (; i < length; i++) {
469            value = callback(elems[i], i, arg);
470
471            if (value != null) {
472              ret.push(value);
473            }
474          } // Go through every key on the object,
475
476        } else {
477          for (i in elems) {
478            value = callback(elems[i], i, arg);
479
480            if (value != null) {
481              ret.push(value);
482            }
483          }
484        } // Flatten any nested arrays
485
486
487        return concat$1.apply([], ret);
488      },
489      // A global GUID counter for objects
490      guid: 1,
491      // jQuery.support is not used in Core but other projects attach their
492      // properties to it so it needs to exist.
493      support: support
494    });
495
496    if (typeof Symbol === "function") {
497      jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];
498    } // Populate the class2type map
499
500
501    jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (i, name) {
502      class2type["[object " + name + "]"] = name.toLowerCase();
503    });
504
505    function isArrayLike(obj) {
506      // Support: real iOS 8.2 only (not reproducible in simulator)
507      // `in` check used to prevent JIT error (gh-2145)
508      // hasOwn isn't used here due to false negatives
509      // regarding Nodelist length in IE
510      var length = !!obj && "length" in obj && obj.length,
511          type = toType(obj);
512
513      if (isFunction(obj) || isWindow(obj)) {
514        return false;
515      }
516
517      return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj;
518    }
519
520    var Sizzle =
521    /*!
522    * Sizzle CSS Selector Engine v2.3.3
523    * https://sizzlejs.com/
524    *
525    * Copyright jQuery Foundation and other contributors
526    * Released under the MIT license
527    * http://jquery.org/license
528    *
529    * Date: 2016-08-08
530    */
531    function (window) {
532      var i,
533          support,
534          Expr,
535          getText,
536          isXML,
537          tokenize,
538          compile,
539          select,
540          outermostContext,
541          sortInput,
542          hasDuplicate,
543          // Local document vars
544      setDocument,
545          document,
546          docElem,
547          documentIsHTML,
548          rbuggyQSA,
549          rbuggyMatches,
550          matches,
551          contains,
552          // Instance-specific data
553      expando = "sizzle" + 1 * new Date(),
554          preferredDoc = window.document,
555          dirruns = 0,
556          done = 0,
557          classCache = createCache(),
558          tokenCache = createCache(),
559          compilerCache = createCache(),
560          sortOrder = function (a, b) {
561        if (a === b) {
562          hasDuplicate = true;
563        }
564
565        return 0;
566      },
567          // Instance methods
568      hasOwn = {}.hasOwnProperty,
569          arr = [],
570          pop = arr.pop,
571          push_native = arr.push,
572          push = arr.push,
573          slice = arr.slice,
574          // Use a stripped-down indexOf as it's faster than native
575      // https://jsperf.com/thor-indexof-vs-for/5
576      indexOf = function (list, elem) {
577        var i = 0,
578            len = list.length;
579
580        for (; i < len; i++) {
581          if (list[i] === elem) {
582            return i;
583          }
584        }
585
586        return -1;
587      },
588          booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
589          // Regular expressions
590      // http://www.w3.org/TR/css3-selectors/#whitespace
591      whitespace = "[\\x20\\t\\r\\n\\f]",
592          // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
593      identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
594          // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
595      attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2)
596      "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
597      "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]",
598          pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
599      // 1. quoted (capture 3; capture 4 or capture 5)
600      "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + // 2. simple (capture 6)
601      "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2)
602      ".*" + ")\\)|)",
603          // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
604      rwhitespace = new RegExp(whitespace + "+", "g"),
605          rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"),
606          rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
607          rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
608          rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"),
609          rpseudo = new RegExp(pseudos),
610          ridentifier = new RegExp("^" + identifier + "$"),
611          matchExpr = {
612        "ID": new RegExp("^#(" + identifier + ")"),
613        "CLASS": new RegExp("^\\.(" + identifier + ")"),
614        "TAG": new RegExp("^(" + identifier + "|[*])"),
615        "ATTR": new RegExp("^" + attributes),
616        "PSEUDO": new RegExp("^" + pseudos),
617        "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
618        "bool": new RegExp("^(?:" + booleans + ")$", "i"),
619        // For use in libraries implementing .is()
620        // We use this for POS matching in `select`
621        "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
622      },
623          rinputs = /^(?:input|select|textarea|button)$/i,
624          rheader = /^h\d$/i,
625          rnative = /^[^{]+\{\s*\[native \w/,
626          // Easily-parseable/retrievable ID or TAG or CLASS selectors
627      rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
628          rsibling = /[+~]/,
629          // CSS escapes
630      // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
631      runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"),
632          funescape = function (_, escaped, escapedWhitespace) {
633        var high = "0x" + escaped - 0x10000; // NaN means non-codepoint
634        // Support: Firefox<24
635        // Workaround erroneous numeric interpretation of +"0x"
636
637        return high !== high || escapedWhitespace ? escaped : high < 0 ? // BMP codepoint
638        String.fromCharCode(high + 0x10000) : // Supplemental Plane codepoint (surrogate pair)
639        String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
640      },
641          // CSS string/identifier serialization
642      // https://drafts.csswg.org/cssom/#common-serializing-idioms
643      // eslint-disable-next-line no-control-regex
644      rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
645          fcssescape = function (ch, asCodePoint) {
646        if (asCodePoint) {
647          // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
648          if (ch === "\0") {
649            return "\uFFFD";
650          } // Control characters and (dependent upon position) numbers get escaped as code points
651
652
653          return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
654        } // Other potentially-special ASCII characters get backslash-escaped
655
656
657        return "\\" + ch;
658      },
659          // Used for iframes
660      // See setDocument()
661      // Removing the function wrapper causes a "Permission Denied"
662      // error in IE
663      unloadHandler = function () {
664        setDocument();
665      },
666          disabledAncestor = addCombinator(function (elem) {
667        return elem.disabled === true && ("form" in elem || "label" in elem);
668      }, {
669        dir: "parentNode",
670        next: "legend"
671      }); // Optimize for push.apply( _, NodeList )
672
673
674      try {
675        push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes); // Support: Android<4.0
676        // Detect silently failing push.apply
677
678        arr[preferredDoc.childNodes.length].nodeType;
679      } catch (e) {
680        push = {
681          apply: arr.length ? // Leverage slice if possible
682          function (target, els) {
683            push_native.apply(target, slice.call(els));
684          } : // Support: IE<9
685          // Otherwise append directly
686          function (target, els) {
687            var j = target.length,
688                i = 0; // Can't trust NodeList.length
689
690            while (target[j++] = els[i++]) {}
691
692            target.length = j - 1;
693          }
694        };
695      }
696
697      function Sizzle(selector, context, results, seed) {
698        var m,
699            i,
700            elem,
701            nid,
702            match,
703            groups,
704            newSelector,
705            newContext = context && context.ownerDocument,
706            // nodeType defaults to 9, since context defaults to document
707        nodeType = context ? context.nodeType : 9;
708        results = results || []; // Return early from calls with invalid selector or context
709
710        if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
711          return results;
712        } // Try to shortcut find operations (as opposed to filters) in HTML documents
713
714
715        if (!seed) {
716          if ((context ? context.ownerDocument || context : preferredDoc) !== document) {
717            setDocument(context);
718          }
719
720          context = context || document;
721
722          if (documentIsHTML) {
723            // If the selector is sufficiently simple, try using a "get*By*" DOM method
724            // (excepting DocumentFragment context, where the methods don't exist)
725            if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
726              // ID selector
727              if (m = match[1]) {
728                // Document context
729                if (nodeType === 9) {
730                  if (elem = context.getElementById(m)) {
731                    // Support: IE, Opera, Webkit
732                    // TODO: identify versions
733                    // getElementById can match elements by name instead of ID
734                    if (elem.id === m) {
735                      results.push(elem);
736                      return results;
737                    }
738                  } else {
739                    return results;
740                  } // Element context
741
742                } else {
743                  // Support: IE, Opera, Webkit
744                  // TODO: identify versions
745                  // getElementById can match elements by name instead of ID
746                  if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) {
747                    results.push(elem);
748                    return results;
749                  }
750                } // Type selector
751
752              } else if (match[2]) {
753                push.apply(results, context.getElementsByTagName(selector));
754                return results; // Class selector
755              } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) {
756                push.apply(results, context.getElementsByClassName(m));
757                return results;
758              }
759            } // Take advantage of querySelectorAll
760
761
762            if (support.qsa && !compilerCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
763              if (nodeType !== 1) {
764                newContext = context;
765                newSelector = selector; // qSA looks outside Element context, which is not what we want
766                // Thanks to Andrew Dupont for this workaround technique
767                // Support: IE <=8
768                // Exclude object elements
769              } else if (context.nodeName.toLowerCase() !== "object") {
770                // Capture the context ID, setting it first if necessary
771                if (nid = context.getAttribute("id")) {
772                  nid = nid.replace(rcssescape, fcssescape);
773                } else {
774                  context.setAttribute("id", nid = expando);
775                } // Prefix every selector in the list
776
777
778                groups = tokenize(selector);
779                i = groups.length;
780
781                while (i--) {
782                  groups[i] = "#" + nid + " " + toSelector(groups[i]);
783                }
784
785                newSelector = groups.join(","); // Expand context for sibling selectors
786
787                newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
788              }
789
790              if (newSelector) {
791                try {
792                  push.apply(results, newContext.querySelectorAll(newSelector));
793                  return results;
794                } catch (qsaError) {} finally {
795                  if (nid === expando) {
796                    context.removeAttribute("id");
797                  }
798                }
799              }
800            }
801          }
802        } // All others
803
804
805        return select(selector.replace(rtrim, "$1"), context, results, seed);
806      }
807      /**
808       * Create key-value caches of limited size
809       * @returns {function(string, object)} Returns the Object data after storing it on itself with
810       *    property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
811       *    deleting the oldest entry
812       */
813
814
815      function createCache() {
816        var keys = [];
817
818        function cache(key, value) {
819          // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
820          if (keys.push(key + " ") > Expr.cacheLength) {
821            // Only keep the most recent entries
822            delete cache[keys.shift()];
823          }
824
825          return cache[key + " "] = value;
826        }
827
828        return cache;
829      }
830      /**
831       * Mark a function for special use by Sizzle
832       * @param {Function} fn The function to mark
833       */
834
835
836      function markFunction(fn) {
837        fn[expando] = true;
838        return fn;
839      }
840      /**
841       * Support testing using an element
842       * @param {Function} fn Passed the created element and returns a boolean result
843       */
844
845
846      function assert(fn) {
847        var el = document.createElement("fieldset");
848
849        try {
850          return !!fn(el);
851        } catch (e) {
852          return false;
853        } finally {
854          // Remove from its parent by default
855          if (el.parentNode) {
856            el.parentNode.removeChild(el);
857          } // release memory in IE
858
859
860          el = null;
861        }
862      }
863      /**
864       * Checks document order of two siblings
865       * @param {Element} a
866       * @param {Element} b
867       * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
868       */
869
870
871      function siblingCheck(a, b) {
872        var cur = b && a,
873            diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes
874
875        if (diff) {
876          return diff;
877        } // Check if b follows a
878
879
880        if (cur) {
881          while (cur = cur.nextSibling) {
882            if (cur === b) {
883              return -1;
884            }
885          }
886        }
887
888        return a ? 1 : -1;
889      }
890      /**
891       * Returns a function to use in pseudos for input types
892       * @param {String} type
893       */
894
895
896      function createInputPseudo(type) {
897        return function (elem) {
898          var name = elem.nodeName.toLowerCase();
899          return name === "input" && elem.type === type;
900        };
901      }
902      /**
903       * Returns a function to use in pseudos for buttons
904       * @param {String} type
905       */
906
907
908      function createButtonPseudo(type) {
909        return function (elem) {
910          var name = elem.nodeName.toLowerCase();
911          return (name === "input" || name === "button") && elem.type === type;
912        };
913      }
914      /**
915       * Returns a function to use in pseudos for :enabled/:disabled
916       * @param {Boolean} disabled true for :disabled; false for :enabled
917       */
918
919
920      function createDisabledPseudo(disabled) {
921        // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
922        return function (elem) {
923          // Only certain elements can match :enabled or :disabled
924          // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
925          // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
926          if ("form" in elem) {
927            // Check for inherited disabledness on relevant non-disabled elements:
928            // * listed form-associated elements in a disabled fieldset
929            //   https://html.spec.whatwg.org/multipage/forms.html#category-listed
930            //   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
931            // * option elements in a disabled optgroup
932            //   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
933            // All such elements have a "form" property.
934            if (elem.parentNode && elem.disabled === false) {
935              // Option elements defer to a parent optgroup if present
936              if ("label" in elem) {
937                if ("label" in elem.parentNode) {
938                  return elem.parentNode.disabled === disabled;
939                } else {
940                  return elem.disabled === disabled;
941                }
942              } // Support: IE 6 - 11
943              // Use the isDisabled shortcut property to check for disabled fieldset ancestors
944
945
946              return elem.isDisabled === disabled || // Where there is no isDisabled, check manually
947
948              /* jshint -W018 */
949              elem.isDisabled !== !disabled && disabledAncestor(elem) === disabled;
950            }
951
952            return elem.disabled === disabled; // Try to winnow out elements that can't be disabled before trusting the disabled property.
953            // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
954            // even exist on them, let alone have a boolean value.
955          } else if ("label" in elem) {
956            return elem.disabled === disabled;
957          } // Remaining elements are neither :enabled nor :disabled
958
959
960          return false;
vendor: 5,066 bytes, lines 961-1091
961        };
962      }
963      /**
964       * Returns a function to use in pseudos for positionals
965       * @param {Function} fn
966       */
967
968
969      function createPositionalPseudo(fn) {
970        return markFunction(function (argument) {
971          argument = +argument;
972          return markFunction(function (seed, matches) {
973            var j,
974                matchIndexes = fn([], seed.length, argument),
975                i = matchIndexes.length; // Match elements found at the specified indexes
976
977            while (i--) {
978              if (seed[j = matchIndexes[i]]) {
979                seed[j] = !(matches[j] = seed[j]);
980              }
981            }
982          });
983        });
984      }
985      /**
986       * Checks a node for validity as a Sizzle context
987       * @param {Element|Object=} context
988       * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
989       */
990
991
992      function testContext(context) {
993        return context && typeof context.getElementsByTagName !== "undefined" && context;
994      } // Expose support vars for convenience
995
996
997      support = Sizzle.support = {};
998      /**
999       * Detects XML nodes
1000       * @param {Element|Object} elem An element or a document
1001       * @returns {Boolean} True iff elem is a non-HTML XML node
1002       */
1003
1004      isXML = Sizzle.isXML = function (elem) {
1005        // documentElement is verified for cases where it doesn't yet exist
1006        // (such as loading iframes in IE - #4833)
1007        var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1008        return documentElement ? documentElement.nodeName !== "HTML" : false;
1009      };
1010      /**
1011       * Sets document-related variables once based on the current document
1012       * @param {Element|Object} [doc] An element or document object to use to set the document
1013       * @returns {Object} Returns the current document
1014       */
1015
1016
1017      setDocument = Sizzle.setDocument = function (node) {
1018        var hasCompare,
1019            subWindow,
1020            doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected
1021
1022        if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
1023          return document;
1024        } // Update global variables
1025
1026
1027        document = doc;
1028        docElem = document.documentElement;
1029        documentIsHTML = !isXML(document); // Support: IE 9-11, Edge
1030        // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1031
1032        if (preferredDoc !== document && (subWindow = document.defaultView) && subWindow.top !== subWindow) {
1033          // Support: IE 11, Edge
1034          if (subWindow.addEventListener) {
1035            subWindow.addEventListener("unload", unloadHandler, false); // Support: IE 9 - 10 only
1036          } else if (subWindow.attachEvent) {
1037            subWindow.attachEvent("onunload", unloadHandler);
1038          }
1039        }
1040        /* Attributes
1041        ---------------------------------------------------------------------- */
1042        // Support: IE<8
1043        // Verify that getAttribute really returns attributes and not properties
1044        // (excepting IE8 booleans)
1045
1046
1047        support.attributes = assert(function (el) {
1048          el.className = "i";
1049          return !el.getAttribute("className");
1050        });
1051        /* getElement(s)By*
1052        ---------------------------------------------------------------------- */
1053        // Check if getElementsByTagName("*") returns only elements
1054
1055        support.getElementsByTagName = assert(function (el) {
1056          el.appendChild(document.createComment(""));
1057          return !el.getElementsByTagName("*").length;
1058        }); // Support: IE<9
1059
1060        support.getElementsByClassName = rnative.test(document.getElementsByClassName); // Support: IE<10
1061        // Check if getElementById returns elements by name
1062        // The broken getElementById methods don't pick up programmatically-set names,
1063        // so use a roundabout getElementsByName test
1064
1065        support.getById = assert(function (el) {
1066          docElem.appendChild(el).id = expando;
1067          return !document.getElementsByName || !document.getElementsByName(expando).length;
1068        }); // ID filter and find
1069
1070        if (support.getById) {
1071          Expr.filter["ID"] = function (id) {
1072            var attrId = id.replace(runescape, funescape);
1073            return function (elem) {
1074              return elem.getAttribute("id") === attrId;
1075            };
1076          };
1077
1078          Expr.find["ID"] = function (id, context) {
1079            if (typeof context.getElementById !== "undefined" && documentIsHTML) {
1080              var elem = context.getElementById(id);
1081              return elem ? [elem] : [];
1082            }
1083          };
1084        } else {
1085          Expr.filter["ID"] = function (id) {
1086            var attrId = id.replace(runescape, funescape);
1087            return function (elem) {
1088              var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
1089              return node && node.value === attrId;
1090            };
1091          };
1091 // Support: IE 6 - 7 only
1092          // getElementById is not reliable as a find shortcut
1093
1094
1095          Expr.find["ID"] = function (id, context) {
1096            if (typeof context.getElementById !== "undefined" && documentIsHTML) {
1097              var node,
1098                  i,
1099                  elems,
1100                  elem = context.getElementById(id);
1101
1102              if (elem) {
1103                // Verify the id attribute
1104                node = elem.getAttributeNode("id");
1105
1106                if (node && node.value === id) {
1107                  return [elem];
1108                } // Fall back on getElementsByName
1109
1110
1111                elems = context.getElementsByName(id);
1112                i = 0;
1113
1114                while (elem = elems[i++]) {
1115                  node = elem.getAttributeNode("id");
1116
1117                  if (node && node.value === id) {
1118                    return [elem];
1119                  }
1120                }
1121              }
1122
1123              return [];
1124            }
1125          };
1126        } // Tag
1127
1128
1129        Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) {
1130          if (typeof context.getElementsByTagName !== "undefined") {
1131            return context.getElementsByTagName(tag); // DocumentFragment nodes don't have gEBTN
1132          } else if (support.qsa) {
1133            return context.querySelectorAll(tag);
1134          }
1135        } : function (tag, context) {
1136          var elem,
1137              tmp = [],
1138              i = 0,
1139              // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1140          results = context.getElementsByTagName(tag); // Filter out possible comments
1141
1142          if (tag === "*") {
1143            while (elem = results[i++]) {
1144              if (elem.nodeType === 1) {
1145                tmp.push(elem);
1146              }
1147            }
1148
1149            return tmp;
1150          }
1151
1152          return results;
1153        }; // Class
1154
1155        Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) {
1156          if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {
1157            return context.getElementsByClassName(className);
1158          }
1159        };
1160        /* QSA/matchesSelector
1161        ---------------------------------------------------------------------- */
1162        // QSA and matchesSelector support
1163        // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1164
1165
1166        rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21)
1167        // We allow this because of a bug in IE8/9 that throws an error
1168        // whenever `document.activeElement` is accessed on an iframe
1169        // So, we allow :focus to pass through QSA all the time to avoid the IE error
1170        // See https://bugs.jquery.com/ticket/13378
1171
1172        rbuggyQSA = [];
1173
1174        if (support.qsa = rnative.test(document.querySelectorAll)) {
1175          // Build QSA regex
1176          // Regex strategy adopted from Diego Perini
1177          assert(function (el) {
1178            // Select is set to empty string on purpose
1179            // This is to test IE's treatment of not explicitly
1180            // setting a boolean content attribute,
1181            // since its presence should be enough
1182            // https://bugs.jquery.com/ticket/12359
1183            docElem.appendChild(el).innerHTML = "<a id='" + expando + "'></a>" + "<select id='" + expando + "-\r\\' msallowcapture=''>" + "<option selected=''></option></select>"; // Support: IE8, Opera 11-12.16
1184            // Nothing should be selected when empty strings follow ^= or $= or *=
1185            // The test attribute must be unknown in Opera but "safe" for WinRT
1186            // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1187
1188            if (el.querySelectorAll("[msallowcapture^='']").length) {
1189              rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")");
1190            } // Support: IE8
1191            // Boolean attributes and "value" are not treated correctly
1192
1193
1194            if (!el.querySelectorAll("[selected]").length) {
1195              rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
1196            } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1197
1198
1199            if (!el.querySelectorAll("[id~=" + expando + "-]").length) {
1200              rbuggyQSA.push("~=");
1201            } // Webkit/Opera - :checked should return selected option elements
1202            // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#
vendor: 15,262 bytes, lines 1202-1609
1202checked
1203            // IE8 throws error here and will not see later tests
1204
1205
1206            if (!el.querySelectorAll(":checked").length) {
1207              rbuggyQSA.push(":checked");
1208            } // Support: Safari 8+, iOS 8+
1209            // https://bugs.webkit.org/show_bug.cgi?id=136851
1210            // In-page `selector#id sibling-combinator selector` fails
1211
1212
1213            if (!el.querySelectorAll("a#" + expando + "+*").length) {
1214              rbuggyQSA.push(".#.+[+~]");
1215            }
1216          });
1217          assert(function (el) {
1218            el.innerHTML = "<a href='' disabled='disabled'></a>" + "<select disabled='disabled'><option/></select>"; // Support: Windows 8 Native Apps
1219            // The type and name attributes are restricted during .innerHTML assignment
1220
1221            var input = document.createElement("input");
1222            input.setAttribute("type", "hidden");
1223            el.appendChild(input).setAttribute("name", "D"); // Support: IE8
1224            // Enforce case-sensitivity of name attribute
1225
1226            if (el.querySelectorAll("[name=d]").length) {
1227              rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?=");
1228            } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1229            // IE8 throws error here and will not see later tests
1230
1231
1232            if (el.querySelectorAll(":enabled").length !== 2) {
1233              rbuggyQSA.push(":enabled", ":disabled");
1234            } // Support: IE9-11+
1235            // IE's :disabled selector does not pick up the children of disabled fieldsets
1236
1237
1238            docElem.appendChild(el).disabled = true;
1239
1240            if (el.querySelectorAll(":disabled").length !== 2) {
1241              rbuggyQSA.push(":enabled", ":disabled");
1242            } // Opera 10-11 does not throw on post-comma invalid pseudos
1243
1244
1245            el.querySelectorAll("*,:x");
1246            rbuggyQSA.push(",.*:");
1247          });
1248        }
1249
1250        if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) {
1251          assert(function (el) {
1252            // Check to see if it's possible to do matchesSelector
1253            // on a disconnected node (IE 9)
1254            support.disconnectedMatch = matches.call(el, "*"); // This should fail with an exception
1255            // Gecko does not error, returns false instead
1256
1257            matches.call(el, "[s!='']:x");
1258            rbuggyMatches.push("!=", pseudos);
1259          });
1260        }
1261
1262        rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
1263        rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));
1264        /* Contains
1265        ---------------------------------------------------------------------- */
1266
1267        hasCompare = rnative.test(docElem.compareDocumentPosition); // Element contains another
1268        // Purposefully self-exclusive
1269        // As in, an element does not contain itself
1270
1271        contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) {
1272          var adown = a.nodeType === 9 ? a.documentElement : a,
1273              bup = b && b.parentNode;
1274          return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
1275        } : function (a, b) {
1276          if (b) {
1277            while (b = b.parentNode) {
1278              if (b === a) {
1279                return true;
1280              }
1281            }
1282          }
1283
1284          return false;
1285        };
1286        /* Sorting
1287        ---------------------------------------------------------------------- */
1288        // Document order sorting
1289
1290        sortOrder = hasCompare ? function (a, b) {
1291          // Flag for duplicate removal
1292          if (a === b) {
1293            hasDuplicate = true;
1294            return 0;
1295          } // Sort on method existence if only one input has compareDocumentPosition
1296
1297
1298          var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1299
1300          if (compare) {
1301            return compare;
1302          } // Calculate position if both inputs belong to the same document
1303
1304
1305          compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : // Otherwise we know they are disconnected
1306          1; // Disconnected nodes
1307
1308          if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {
1309            // Choose the first element that is related to our preferred document
1310            if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) {
1311              return -1;
1312            }
1313
1314            if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) {
1315              return 1;
1316            } // Maintain original order
1317
1318
1319            return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0;
1320          }
1321
1322          return compare & 4 ? -1 : 1;
1323        } : function (a, b) {
1324          // Exit early if the nodes are identical
1325          if (a === b) {
1326            hasDuplicate = true;
1327            return 0;
1328          }
1329
1330          var cur,
1331              i = 0,
1332              aup = a.parentNode,
1333              bup = b.parentNode,
1334              ap = [a],
1335              bp = [b]; // Parentless nodes are either documents or disconnected
1336
1337          if (!aup || !bup) {
1338            return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; // If the nodes are siblings, we can do a quick check
1339          } else if (aup === bup) {
1340            return siblingCheck(a, b);
1341          } // Otherwise we need full lists of their ancestors for comparison
1342
1343
1344          cur = a;
1345
1346          while (cur = cur.parentNode) {
1347            ap.unshift(cur);
1348          }
1349
1350          cur = b;
1351
1352          while (cur = cur.parentNode) {
1353            bp.unshift(cur);
1354          } // Walk down the tree looking for a discrepancy
1355
1356
1357          while (ap[i] === bp[i]) {
1358            i++;
1359          }
1360
1361          return i ? // Do a sibling check if the nodes have a common ancestor
1362          siblingCheck(ap[i], bp[i]) : // Otherwise nodes in our document sort first
1363          ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0;
1364        };
1365        return document;
1366      };
1367
1368      Sizzle.matches = function (expr, elements) {
1369        return Sizzle(expr, null, null, elements);
1370      };
1371
1372      Sizzle.matchesSelector = function (elem, expr) {
1373        // Set document vars if needed
1374        if ((elem.ownerDocument || elem) !== document) {
1375          setDocument(elem);
1376        } // Make sure that attribute selectors are quoted
1377
1378
1379        expr = expr.replace(rattributeQuotes, "='$1']");
1380
1381        if (support.matchesSelector && documentIsHTML && !compilerCache[expr + " "] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
1382          try {
1383            var ret = matches.call(elem, expr); // IE 9's matchesSelector returns false on disconnected nodes
1384
1385            if (ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document
1386            // fragment in IE 9
1387            elem.document && elem.document.nodeType !== 11) {
1388              return ret;
1389            }
1390          } catch (e) {}
1391        }
1392
1393        return Sizzle(expr, document, null, [elem]).length > 0;
1394      };
1395
1396      Sizzle.contains = function (context, elem) {
1397        // Set document vars if needed
1398        if ((context.ownerDocument || context) !== document) {
1399          setDocument(context);
1400        }
1401
1402        return contains(context, elem);
1403      };
1404
1405      Sizzle.attr = function (elem, name) {
1406        // Set document vars if needed
1407        if ((elem.ownerDocument || elem) !== document) {
1408          setDocument(elem);
1409        }
1410
1411        var fn = Expr.attrHandle[name.toLowerCase()],
1412            // Don't get fooled by Object.prototype properties (jQuery #13807)
1413        val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;
1414        return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
1415      };
1416
1417      Sizzle.escape = function (sel) {
1418        return (sel + "").replace(rcssescape, fcssescape);
1419      };
1420
1421      Sizzle.error = function (msg) {
1422        throw new Error("Syntax error, unrecognized expression: " + msg);
1423      };
1424      /**
1425       * Document sorting and removing duplicates
1426       * @param {ArrayLike} results
1427       */
1428
1429
1430      Sizzle.uniqueSort = function (results) {
1431        var elem,
1432            duplicates = [],
1433            j = 0,
1434            i = 0; // Unless we *know* we can detect duplicates, assume their presence
1435
1436        hasDuplicate = !support.detectDuplicates;
1437        sortInput = !support.sortStable && results.slice(0);
1438        results.sort(sortOrder);
1439
1440        if (hasDuplicate) {
1441          while (elem = results[i++]) {
1442            if (elem === results[i]) {
1443              j = duplicates.push(i);
1444            }
1445          }
1446
1447          while (j--) {
1448            results.splice(duplicates[j], 1);
1449          }
1450        } // Clear input after sorting to release objects
1451        // See https://github.com/jquery/sizzle/pull/225
1452
1453
1454        sortInput = null;
1455        return results;
1456      };
1457      /**
1458       * Utility function for retrieving the text value of an array of DOM nodes
1459       * @param {Array|Element} elem
1460       */
1461
1462
1463      getText = Sizzle.getText = function (elem) {
1464        var node,
1465            ret = "",
1466            i = 0,
1467            nodeType = elem.nodeType;
1468
1469        if (!nodeType) {
1470          // If no nodeType, this is expected to be an array
1471          while (node = elem[i++]) {
1472            // Do not traverse comment nodes
1473            ret += getText(node);
1474          }
1475        } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
1476          // Use textContent for elements
1477          // innerText usage removed for consistency of new lines (jQuery #11153)
1478          if (typeof elem.textContent === "string") {
1479            return elem.textContent;
1480          } else {
1481            // Traverse its children
1482            for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
1483              ret += getText(elem);
1484            }
1485          }
1486        } else if (nodeType === 3 || nodeType === 4) {
1487          return elem.nodeValue;
1488        } // Do not include comment or processing instruction nodes
1489
1490
1491        return ret;
1492      };
1493
1494      Expr = Sizzle.selectors = {
1495        // Can be adjusted by the user
1496        cacheLength: 50,
1497        createPseudo: markFunction,
1498        match: matchExpr,
1499        attrHandle: {},
1500        find: {},
1501        relative: {
1502          ">": {
1503            dir: "parentNode",
1504            first: true
1505          },
1506          " ": {
1507            dir: "parentNode"
1508          },
1509          "+": {
1510            dir: "previousSibling",
1511            first: true
1512          },
1513          "~": {
1514            dir: "previousSibling"
1515          }
1516        },
1517        preFilter: {
1518          "ATTR": function (match) {
1519            match[1] = match[1].replace(runescape, funescape); // Move the given value to match[3] whether quoted or unquoted
1520
1521            match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape);
1522
1523            if (match[2] === "~=") {
1524              match[3] = " " + match[3] + " ";
1525            }
1526
1527            return match.slice(0, 4);
1528          },
1529          "CHILD": function (match) {
1530            /* matches from matchExpr["CHILD"]
1531            1 type (only|nth|...)
1532            2 what (child|of-type)
1533            3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1534            4 xn-component of xn+y argument ([+-]?\d*n|)
1535            5 sign of xn-component
1536            6 x of xn-component
1537            7 sign of y-component
1538            8 y of y-component
1539            */
1540            match[1] = match[1].toLowerCase();
1541
1542            if (match[1].slice(0, 3) === "nth") {
1543              // nth-* requires argument
1544              if (!match[3]) {
1545                Sizzle.error(match[0]);
1546              } // numeric x and y parameters for Expr.filter.CHILD
1547              // remember that false/true cast respectively to 0/1
1548
1549
1550              match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
1551              match[5] = +(match[7] + match[8] || match[3] === "odd"); // other types prohibit arguments
1552            } else if (match[3]) {
1553              Sizzle.error(match[0]);
1554            }
1555
1556            return match;
1557          },
1558          "PSEUDO": function (match) {
1559            var excess,
1560                unquoted = !match[6] && match[2];
1561
1562            if (matchExpr["CHILD"].test(match[0])) {
1563              return null;
1564            } // Accept quoted arguments as-is
1565
1566
1567            if (match[3]) {
1568              match[2] = match[4] || match[5] || ""; // Strip excess characters from unquoted arguments
1569            } else if (unquoted && rpseudo.test(unquoted) && ( // Get excess from tokenize (recursively)
1570            excess = tokenize(unquoted, true)) && ( // advance to the next closing parenthesis
1571            excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
1572              // excess is a negative index
1573              match[0] = match[0].slice(0, excess);
1574              match[2] = unquoted.slice(0, excess);
1575            } // Return only captures needed by the pseudo filter method (type and argument)
1576
1577
1578            return match.slice(0, 3);
1579          }
1580        },
1581        filter: {
1582          "TAG": function (nodeNameSelector) {
1583            var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
1584            return nodeNameSelector === "*" ? function () {
1585              return true;
1586            } : function (elem) {
1587              return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1588            };
1589          },
1590          "CLASS": function (className) {
1591            var pattern = classCache[className + " "];
1592            return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) {
1593              return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "");
1594            });
1595          },
1596          "ATTR": function (name, operator, check) {
1597            return function (elem) {
1598              var result = Sizzle.attr(elem, name);
1599
1600              if (result == null) {
1601                return operator === "!=";
1602              }
1603
1604              if (!operator) {
1605                return true;
1606              }
1607
1608              result += "";
1609              return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf(check) === 0 : operator === "*=" ? check && result.indexOf(check) > -1 : operator === "$=" ? check && result.slice(-check.length) === check : operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 : operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : false;
1610            };
1611          },
1612          "CHILD": function (type, what, argument, first, last) {
1613            var simple = type.slice(0, 3) !== "nth",
1614                forward = type.slice(-4) !== "last",
1615                ofType = what === "of-type";
1616            return first === 1 && last === 0 ? // Shortcut for :nth-*(n)
1617            function (elem) {
1618              return !!elem.parentNode;
1619            } : function (elem, context, xml) {
1620              var cache,
1621                  uniqueCache,
1622                  outerCache,
1623                  node,
1624                  nodeIndex,
1625                  start,
1626                  dir = simple !== forward ? "nextSibling" : "previousSibling",
1627                  parent = elem.parentNode,
1628                  name = ofType && elem.nodeName.toLowerCase(),
1629                  useCache = !xml && !ofType,
1630                  diff = false;
1631
1632              if (parent) {
1633                // :(first|last|only)-(child|of-type)
1634                if (simple) {
1635                  while (dir) {
1636                    node = elem;
1637
1638                    while (node = node[dir]) {
1639                      if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {
1640                        return false;
1641                      }
1642                    } // Reverse direction for :only-* (if we haven't yet done so)
1643
1644
1645                    start = dir = type === "only" && !start && "nextSibling";
1646                  }
1647
1648                  return true;
1649                }
1650
1651                start = [forward ? parent.firstChild : parent.lastChild]; // non-xml :nth-child(...) stores cache data on `parent`
1652
1653                if (forward && useCache) {
1654                  // Seek `elem` from a previously-cached index
1655                  // ...in a gzip-friendly way
1656                  node = parent;
1657                  outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only
1658                  // Defend against cloned attroperties (jQuery gh-1709)
1659
1660                  uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
1661                  cache = uniqueCache[type] || [];
1662                  nodeIndex = cache[0] === dirruns && cache[1];
1663                  diff = nodeIndex && cache[2];
1664                  node = nodeIndex && parent.childNodes[nodeIndex];
1665
1666                  while (node = ++nodeIndex && node && node[dir] || ( // Fallback to seeking `elem` from the start
1667                  diff = nodeIndex = 0) || start.pop()) {
1668                    // When found, cache indexes on `parent` and break
1669                    if (node.nodeType === 1 && ++diff && node === elem) {
1670                      uniqueCache[type] = [dirruns, nodeIndex, diff];
1671                      break;
1672                    }
1673                  }
1674                } else {
1675                  // Use previously-cached element index if available
1676                  if (useCache) {
1677                    // ...in a gzip-friendly way
1678                    node = elem;
1679                    outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only
1680                    // Defend against cloned attroperties (jQuery gh-1709)
1681
1682                    uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
1683                    cache = uniqueCache[type] || [];
1684                    nodeIndex = cache[0] === dirruns && cache[1];
1685                    diff = nodeIndex;
1686                  } // xml :nth-child(...)
1687                  // or :nth-last-child(...) or :nth(-last)?-of-type(...)
1688
1689
1690                  if (diff === false) {
1691                    // Use the same loop as above to seek `elem` from the start
1692                    while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
1693                      if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {
1694                        // Cache the index of each encountered element
1695                        if (useCache) {
1696                          outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only
1697                          // Defend against cloned attroperties (jQuery gh-1709)
1698
1699                          uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
1700                          uniqueCache[type] = [dirruns, diff];
1701                        }
1702
1703                        if (node === elem) {
1704                          break;
1705                        }
1706                      }
1707                    }
1708                  }
1709                } // Incorporate the offset, then check against cycle size
1710
1711
1712                diff -= last;
1713                return diff === first || diff % first === 0 && diff / first >= 0;
1714              }
1715            };
1716          },
1717          "PSEUDO": function (pseudo, argument) {
1718            // pseudo-class names are case-insensitive
vendor: 9,072 bytes, lines 1719-1959
1719            // http://www.w3.org/TR/selectors/#pseudo-classes
1720            // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1721            // Remember that setFilters inherits from pseudos
1722            var args,
1723                fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo); // The user may use createPseudo to indicate that
1724            // arguments are needed to create the filter function
1725            // just as Sizzle does
1726
1727            if (fn[expando]) {
1728              return fn(argument);
1729            } // But maintain support for old signatures
1730
1731
1732            if (fn.length > 1) {
1733              args = [pseudo, pseudo, "", argument];
1734              return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {
1735                var idx,
1736                    matched = fn(seed, argument),
1737                    i = matched.length;
1738
1739                while (i--) {
1740                  idx = indexOf(seed, matched[i]);
1741                  seed[idx] = !(matches[idx] = matched[i]);
1742                }
1743              }) : function (elem) {
1744                return fn(elem, 0, args);
1745              };
1746            }
1747
1748            return fn;
1749          }
1750        },
1751        pseudos: {
1752          // Potentially complex pseudos
1753          "not": markFunction(function (selector) {
1754            // Trim the selector passed to compile
1755            // to avoid treating leading and trailing
1756            // spaces as combinators
1757            var input = [],
1758                results = [],
1759                matcher = compile(selector.replace(rtrim, "$1"));
1760            return matcher[expando] ? markFunction(function (seed, matches, context, xml) {
1761              var elem,
1762                  unmatched = matcher(seed, null, xml, []),
1763                  i = seed.length; // Match elements unmatched by `matcher`
1764
1765              while (i--) {
1766                if (elem = unmatched[i]) {
1767                  seed[i] = !(matches[i] = elem);
1768                }
1769              }
1770            }) : function (elem, context, xml) {
1771              input[0] = elem;
1772              matcher(input, null, xml, results); // Don't keep the element (issue #299)
1773
1774              input[0] = null;
1775              return !results.pop();
1776            };
1777          }),
1778          "has": markFunction(function (selector) {
1779            return function (elem) {
1780              return Sizzle(selector, elem).length > 0;
1781            };
1782          }),
1783          "contains": markFunction(function (text) {
1784            text = text.replace(runescape, funescape);
1785            return function (elem) {
1786              return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
1787            };
1788          }),
1789          // "Whether an element is represented by a :lang() selector
1790          // is based solely on the element's language value
1791          // being equal to the identifier C,
1792          // or beginning with the identifier C immediately followed by "-".
1793          // The matching of C against the element's language value is performed case-insensitively.
1794          // The identifier C does not have to be a valid language name."
1795          // http://www.w3.org/TR/selectors/#lang-pseudo
1796          "lang": markFunction(function (lang) {
1797            // lang value must be a valid identifier
1798            if (!ridentifier.test(lang || "")) {
1799              Sizzle.error("unsupported lang: " + lang);
1800            }
1801
1802            lang = lang.replace(runescape, funescape).toLowerCase();
1803            return function (elem) {
1804              var elemLang;
1805
1806              do {
1807                if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {
1808                  elemLang = elemLang.toLowerCase();
1809                  return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
1810                }
1811              } while ((elem = elem.parentNode) && elem.nodeType === 1);
1812
1813              return false;
1814            };
1815          }),
1816          // Miscellaneous
1817          "target": function (elem) {
1818            var hash = window.location && window.location.hash;
1819            return hash && hash.slice(1) === elem.id;
1820          },
1821          "root": function (elem) {
1822            return elem === docElem;
1823          },
1824          "focus": function (elem) {
1825            return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1826          },
1827          // Boolean properties
1828          "enabled": createDisabledPseudo(false),
1829          "disabled": createDisabledPseudo(true),
1830          "checked": function (elem) {
1831            // In CSS3, :checked should return both checked and selected elements
1832            // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1833            var nodeName = elem.nodeName.toLowerCase();
1834            return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected;
1835          },
1836          "selected": function (elem) {
1837            // Accessing this property makes selected-by-default
1838            // options in Safari work properly
1839            if (elem.parentNode) {
1840              elem.parentNode.selectedIndex;
1841            }
1842
1843            return elem.selected === true;
1844          },
1845          // Contents
1846          "empty": function (elem) {
1847            // http://www.w3.org/TR/selectors/#empty-pseudo
1848            // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1849            //   but not by others (comment: 8; processing instruction: 7; etc.)
1850            // nodeType < 6 works because attributes (2) do not appear as children
1851            for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
1852              if (elem.nodeType < 6) {
1853                return false;
1854              }
1855            }
1856
1857            return true;
1858          },
1859          "parent": function (elem) {
1860            return !Expr.pseudos["empty"](elem);
1861          },
1862          // Element/input types
1863          "header": function (elem) {
1864            return rheader.test(elem.nodeName);
1865          },
1866          "input": function (elem) {
1867            return rinputs.test(elem.nodeName);
1868          },
1869          "button": function (elem) {
1870            var name = elem.nodeName.toLowerCase();
1871            return name === "input" && elem.type === "button" || name === "button";
1872          },
1873          "text": function (elem) {
1874            var attr;
1875            return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( // Support: IE<8
1876            // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1877            (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text");
1878          },
1879          // Position-in-collection
1880          "first": createPositionalPseudo(function () {
1881            return [0];
1882          }),
1883          "last": createPositionalPseudo(function (matchIndexes, length) {
1884            return [length - 1];
1885          }),
1886          "eq": createPositionalPseudo(function (matchIndexes, length, argument) {
1887            return [argument < 0 ? argument + length : argument];
1888          }),
1889          "even": createPositionalPseudo(function (matchIndexes, length) {
1890            var i = 0;
1891
1892            for (; i < length; i += 2) {
1893              matchIndexes.push(i);
1894            }
1895
1896            return matchIndexes;
1897          }),
1898          "odd": createPositionalPseudo(function (matchIndexes, length) {
1899            var i = 1;
1900
1901            for (; i < length; i += 2) {
1902              matchIndexes.push(i);
1903            }
1904
1905            return matchIndexes;
1906          }),
1907          "lt": createPositionalPseudo(function (matchIndexes, length, argument) {
1908            var i = argument < 0 ? argument + length : argument;
1909
1910            for (; --i >= 0;) {
1911              matchIndexes.push(i);
1912            }
1913
1914            return matchIndexes;
1915          }),
1916          "gt": createPositionalPseudo(function (matchIndexes, length, argument) {
1917            var i = argument < 0 ? argument + length : argument;
1918
1919            for (; ++i < length;) {
1920              matchIndexes.push(i);
1921            }
1922
1923            return matchIndexes;
1924          })
1925        }
1926      };
1927      Expr.pseudos["nth"] = Expr.pseudos["eq"]; // Add button/input type pseudos
1928
1929      for (i in {
1930        radio: true,
1931        checkbox: true,
1932        file: true,
1933        password: true,
1934        image: true
1935      }) {
1936        Expr.pseudos[i] = createInputPseudo(i);
1937      }
1938
1939      for (i in {
1940        submit: true,
1941        reset: true
1942      }) {
1943        Expr.pseudos[i] = createButtonPseudo(i);
1944      } // Easy API for creating new setFilters
1945
1946
1947      function setFilters() {}
1948
1949      setFilters.prototype = Expr.filters = Expr.pseudos;
1950      Expr.setFilters = new setFilters();
1951
1952      tokenize = Sizzle.tokenize = function (selector, parseOnly) {
1953        var matched,
1954            match,
1955            tokens,
1956            type,
1957            soFar,
1958            groups,
1959            preFilters,
1960            cached = tokenCache[selector + " "];
1961
1962        if (cached) {
1963          return parseOnly ? 0 : cached.slice(0);
1964        }
1965
1966        soFar = selector;
1967        groups = [];
1968        preFilters = Expr.preFilter;
1969
1970        while (soFar) {
1971          // Comma and first run
1972          if (!matched || (match = rcomma.exec(soFar))) {
1973            if (match) {
1974              // Don't consume trailing commas as valid
1975              soFar = soFar.slice(match[0].length) || soFar;
1976            }
1977
1978            groups.push(tokens = []);
1979          }
1980
1981          matched = false; // Combinators
1982
1983          if (match = rcombinators.exec(soFar)) {
1984            matched = match.shift();
1985            tokens.push({
1986              value: matched,
1987              // Cast descendant combinators to space
1988              type: match[0].replace(rtrim, " ")
1989            });
1990            soFar = soFar.slice(matched.length);
1991          } // Filters
1992
1993
1994          for (type in Expr.filter) {
1995            if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
1996              matched = match.shift();
1997              tokens.push({
1998                value: matched,
1999                type: type,
2000                matches: match
2001              });
2002              soFar = soFar.slice(matched.length);
2003            }
2004          }
2005
2006          if (!matched) {
2007            break;
2008          }
2009        } // Return the length of the invalid excess
2010        // if we're just parsing
2011        // Otherwise, throw an error or return tokens
2012
2013
2014        return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : // Cache the tokens
2015        tokenCache(selector, groups).slice(0);
2016      };
2017
2018      function toSelector(tokens) {
2019        var i = 0,
2020            len = tokens.length,
2021            selector = "";
2022
2023        for (; i < len; i++) {
2024          selector += tokens[i].value;
2025        }
2026
2027        return selector;
2028      }
2029
2030      function addCombinator(matcher, combinator, base) {
2031        var dir = combinator.dir,
2032            skip = combinator.next,
2033            key = skip || dir,
2034            checkNonElements = base && key === "parentNode",
2035            doneName = done++;
2036        return combinator.first ? // Check against closest ancestor/preceding element
2037        function (elem, context, xml) {
2038          while (elem = elem[dir]) {
2039            if (elem.nodeType === 1 || checkNonElements) {
2040              return matcher(elem, context, xml);
2041            }
2042          }
2043
2044          return false;
2045        } : // Check against all ancestor/preceding elements
2046        function (elem, context, xml) {
2047          var oldCache,
2048              uniqueCache,
2049              outerCache,
2050              newCache = [dirruns, doneName]; // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2051
2052          if (xml) {
2053            while (elem = elem[dir]) {
2054              if (elem.nodeType === 1 || checkNonElements) {
2055                if (matcher(elem, context, xml)) {
2056                  return true;
2057                }
2058              }
2059            }
2060          } else {
2061            while (elem = elem[dir]) {
2062              if (elem.nodeType === 1 || checkNonElements) {
2063                outerCache = elem[expando] || (elem[expando] = {}); // Support: IE <9 only
2064                // Defend against cloned attroperties (jQuery gh-1709)
2065
2066                uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {});
2067
2068                if (skip && skip === elem.nodeName.toLowerCase()) {
2069                  elem = elem[dir] || elem;
2070                } else if ((oldCache = uniqueCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) {
2071                  // Assign to newCache so results back-propagate to previous elements
2072                  return newCache[2] = oldCache[2];
2073                } else {
2074                  // Reuse newcache so results back-propagate to previous elements
2075                  uniqueCache[key] = newCache; // A match means we're done; a fail means we have to keep checking
2076
2077                  if (newCache[2] = matcher(elem, context, xml)) {
2078                    return true;
2079                  }
2080                }
2081              }
2082            }
2083          }
2084
2085          return false;
vendor: 4,526 bytes, lines 2086-2224
2086        };
2087      }
2088
2089      function elementMatcher(matchers) {
2090        return matchers.length > 1 ? function (elem, context, xml) {
2091          var i = matchers.length;
2092
2093          while (i--) {
2094            if (!matchers[i](elem, context, xml)) {
2095              return false;
2096            }
2097          }
2098
2099          return true;
2100        } : matchers[0];
2101      }
2102
2103      function multipleContexts(selector, contexts, results) {
2104        var i = 0,
2105            len = contexts.length;
2106
2107        for (; i < len; i++) {
2108          Sizzle(selector, contexts[i], results);
2109        }
2110
2111        return results;
2112      }
2113
2114      function condense(unmatched, map, filter, context, xml) {
2115        var elem,
2116            newUnmatched = [],
2117            i = 0,
2118            len = unmatched.length,
2119            mapped = map != null;
2120
2121        for (; i < len; i++) {
2122          if (elem = unmatched[i]) {
2123            if (!filter || filter(elem, context, xml)) {
2124              newUnmatched.push(elem);
2125
2126              if (mapped) {
2127                map.push(i);
2128              }
2129            }
2130          }
2131        }
2132
2133        return newUnmatched;
2134      }
2135
2136      function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
2137        if (postFilter && !postFilter[expando]) {
2138          postFilter = setMatcher(postFilter);
2139        }
2140
2141        if (postFinder && !postFinder[expando]) {
2142          postFinder = setMatcher(postFinder, postSelector);
2143        }
2144
2145        return markFunction(function (seed, results, context, xml) {
2146          var temp,
2147              i,
2148              elem,
2149              preMap = [],
2150              postMap = [],
2151              preexisting = results.length,
2152              // Get initial elements from seed or context
2153          elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),
2154              // Prefilter to get matcher input, preserving a map for seed-results synchronization
2155          matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems,
2156              matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2157          postFinder || (seed ? preFilter : preexisting || postFilter) ? // ...intermediate processing is necessary
2158          [] : // ...otherwise use results directly
2159          results : matcherIn; // Find primary matches
2160
2161          if (matcher) {
2162            matcher(matcherIn, matcherOut, context, xml);
2163          } // Apply postFilter
2164
2165
2166          if (postFilter) {
2167            temp = condense(matcherOut, postMap);
2168            postFilter(temp, [], context, xml); // Un-match failing elements by moving them back to matcherIn
2169
2170            i = temp.length;
2171
2172            while (i--) {
2173              if (elem = temp[i]) {
2174                matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
2175              }
2176            }
2177          }
2178
2179          if (seed) {
2180            if (postFinder || preFilter) {
2181              if (postFinder) {
2182                // Get the final matcherOut by condensing this intermediate into postFinder contexts
2183                temp = [];
2184                i = matcherOut.length;
2185
2186                while (i--) {
2187                  if (elem = matcherOut[i]) {
2188                    // Restore matcherIn since elem is not yet a final match
2189                    temp.push(matcherIn[i] = elem);
2190                  }
2191                }
2192
2193                postFinder(null, matcherOut = [], temp, xml);
2194              } // Move matched elements from seed to results to keep them synchronized
2195
2196
2197              i = matcherOut.length;
2198
2199              while (i--) {
2200                if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) {
2201                  seed[temp] = !(results[temp] = elem);
2202                }
2203              }
2204            } // Add elements to results, through postFinder if defined
2205
2206          } else {
2207            matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
2208
2209            if (postFinder) {
2210              postFinder(null, results, matcherOut, xml);
2211            } else {
2212              push.apply(results, matcherOut);
2213            }
2214          }
2215        });
2216      }
2217
2218      function matcherFromTokens(tokens) {
2219        var checkContext,
2220            matcher,
2221            j,
2222            len = tokens.length,
2223            leadingRelative = Expr.relative[tokens[0].type],
2224            implicitRelative = leadingRelative || Expr.relative[" "],
2225            i = leadingRelative ? 1 : 0,
2226            // The foundational matcher ensures that elements are reachable from top-level context(s)
2227        matchContext = addCombinator(function (elem) {
2228          return elem === checkContext;
2229        }, implicitRelative, true),
2230            matchAnyContext = addCombinator(function (elem) {
2231          return indexOf(checkContext, elem) > -1;
2232        }, implicitRelative, true),
2233            matchers = [function (elem, context, xml) {
2234          var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml)); // Avoid hanging onto element (issue #299)
2235
2236          checkContext = null;
2237          return ret;
2238        }];
2239
2240        for (; i < len; i++) {
2241          if (matcher = Expr.relative[tokens[i].type]) {
2242            matchers = [addCombinator(elementMatcher(matchers), matcher)];
2243          } else {
2244            matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); // Return special upon seeing a positional matcher
2245
2246            if (matcher[expando]) {
2247              // Find the next relative operator (if any) for proper handling
2248              j = ++i;
2249
2250              for (; j < len; j++) {
2251                if (Expr.relative[tokens[j].type]) {
2252                  break;
2253                }
2254              }
2255
2256              return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector( // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2257              tokens.slice(0, i - 1).concat({
2258                value: tokens[i - 2].type === " " ? "*" : ""
2259              })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));
2260            }
2261
2262            matchers.push(matcher);
2263          }
2264        }
2265
2266        return elementMatcher(matchers);
2267      }
2268
2269      function matcherFromGroupMatchers(elementMatchers, setMatchers) {
2270        var bySet = setMatchers.length > 0,
2271            byElement = elementMatchers.length > 0,
2272            superMatcher = function (seed, context, xml, results, outermost) {
2273          var elem,
2274              j,
2275              matcher,
2276              matchedCount = 0,
2277              i = "0",
2278              unmatched = seed && [],
2279              setMatched = [],
2280              contextBackup = outermostContext,
2281              // We must always have either seed elements or outermost context
2282          elems = seed || byElement && Expr.find["TAG"]("*", outermost),
2283              // Use integer dirruns iff this is the outermost matcher
2284          dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1,
2285              len = elems.length;
2286
2287          if (outermost) {
2288            outermostContext = context === document || context || outermost;
2289          } // Add elements passing elementMatchers directly to results
2290          // Support: IE<9, Safari
2291          // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2292
2293
2294          for (; i !== len && (elem = elems[i]) != null; i++) {
2295            if (byElement && elem) {
2296              j = 0;
2297
2298              if (!context && elem.ownerDocument !== document) {
2299                setDocument(elem);
2300                xml = !documentIsHTML;
2301              }
2302
2303              while (matcher = elementMatchers[j++]) {
2304                if (matcher(elem, context || document, xml)) {
2305                  results.push(elem);
2306                  break;
2307                }
2308              }
2309
2310              if (outermost) {
2311                dirruns = dirrunsUnique;
2312              }
2313            } // Track unmatched elements for set filters
2314
2315
2316            if (bySet) {
2317              // They will have gone through all possible matchers
2318              if (elem = !matcher && elem) {
2319                matchedCount--;
2320              } // Lengthen the array for every element, matched or not
2321
2322
2323              if (seed) {
2324                unmatched.push(elem);
2325              }
2326            }
2327          } // `i` is now the count of elements visited above, and adding it to `matchedCount`
2328          // makes the latter nonnegative.
2329
2330
2331          matchedCount += i; // Apply set filters to unmatched elements
2332          // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2333          // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2334          // no element matchers and no seed.
2335          // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2336          // case, which will result in a "00" `matchedCount` that differs from `i` but is also
2337          // numerically zero.
2338
2339          if (bySet && i !== matchedCount) {
2340            j = 0;
2341
2342            while (matcher = setMatchers[j++]) {
2343              matcher(unmatched, setMatched, context, xml);
2344            }
2345
2346            if (seed) {
2347              // Reintegrate element matches to eliminate the need for sorting
2348              if (matchedCount > 0) {
2349                while (i--) {
2350                  if (!(unmatched[i] || setMatched[i])) {
2351                    setMatched[i] = pop.call(results);
2352                  }
2353                }
2354              } // Discard index placeholder values to get only actual matches
2355
2356
2357              setMatched = condense(setMatched);
2358            } // Add matches to results
2359
2360
2361            push.apply(results, setMatched); // Seedless set matches succeeding multiple successful matchers stipulate sorting
2362
2363            if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
2364              Sizzle.uniqueSort(results);
2365            }
2366          } // Override manipulation of globals by nested matchers
2367
2368
2369          if (outermost) {
2370            dirruns = dirrunsUnique;
2371            outermostContext = contextBackup;
2372          }
2373
2374          return unmatched;
2375        };
2376
2377        return bySet ? markFunction(superMatcher) : superMatcher;
2378      }
2379
2380      compile = Sizzle.compile = function (selector, match
2381      /* Internal Use Only */
2382      ) {
2383        var i,
2384            setMatchers = [],
2385            elementMatchers = [],
2386            cached = compilerCache[selector + " "];
2387
2388        if (!cached) {
2389          // Generate a function of recursive functions that can be used to check each element
2390          if (!match) {
2391            match = tokenize(selector);
2392          }
2393
2394          i = match.length;
2395
2396          while (i--) {
2397            cached = matcherFromTokens(match[i]);
2398
2399            if (cached[expando]) {
2400              setMatchers.push(cached);
2401            } else {
2402              elementMatchers.push(cached);
2403            }
2404          } // Cache the compiled function
2405
2406
2407          cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); // Save selector and tokenization
2408
2409          cached.selector = selector;
2410        }
2411
2412        return cached;
2413      };
2414      /**
2415       * A low-level selection function that works with Sizzle's compiled
2416       *  selector functions
2417       * @param {String|Function} selector A selector or a pre-compiled
2418       *  selector function built with Sizzle.compile
2419       * @param {Element} context
2420       * @param {Array} [results]
2421       * @param {Array} [seed] A set of elements to match against
2422       */
2423
2424
2425      select = Sizzle.select = function (selector, context, results, seed) {
2426        var i,
2427            tokens,
2428            token,
2429            type,
2430            find,
2431            compiled = typeof selector === "function" && selector,
2432            match = !seed && tokenize(selector = compiled.selector || selector);
2433        results = results || []; // Try to minimize operations if there is only one selector in the list and no seed
2434        // (the latter of which guarantees us context)
2435
2436        if (match.length === 1) {
2437          // Reduce context if the leading compound selector is an ID
2438          tokens = match[0] = match[0].slice(0);
2439
2440          if (tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
2441            context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0];
2442
2443            if (!context) {
2444              return results; // Precompiled matchers will still verify ancestry, so step up a level
2445            } else if (compiled) {
2446              context = context.parentNode;
2447            }
2448
2449            selector = selector.slice(tokens.shift().value.length);
2450          } // Fetch a seed set for right-to-left matching
2451
2452
2453          i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length;
2454
2455          while (i--) {
2456            token = tokens[i]; // Abort if we hit a combinator
2457
2458            if (Expr.relative[type = token.type]) {
2459              break;
2460            }
2461
2462            if (find = Expr.find[type]) {
2463              // Search, expanding context for leading sibling combinators
2464              if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testC
2464ontext(context.parentNode) || context)) {
2465                // If seed is empty or no tokens remain, we can return early
2466                tokens.splice(i, 1);
2467                selector = seed.length && toSelector(tokens);
2468
2469                if (!selector) {
2470                  push.apply(results, seed);
2471                  return results;
2472                }
2473
2474                break;
2475              }
2476            }
2477          }
2478        } // Compile and execute a filtering function if one is not provided
2479        // Provide `match` to avoid retokenization if we modified the selector above
2480
2481
2482        (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context);
2483        return results;
2484      }; // One-time assignments
2485      // Sort stability
2486
2487
2488      support.sortStable = expando.split("").sort(sortOrder).join("") === expando; // Support: Chrome 14-35+
2489      // Always assume duplicates if they aren't passed to the comparison function
2490
2491      support.detectDuplicates = !!hasDuplicate; // Initialize against the default document
2492
2493      setDocument();
2494      return Sizzle;
2495    }(window);
2496
2497    jQuery.find = Sizzle;
2498    jQuery.expr = Sizzle.selectors; // Deprecated
2499
2500    jQuery.expr[":"] = jQuery.expr.pseudos;
2501    jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2502    jQuery.text = Sizzle.getText;
2503    jQuery.isXMLDoc = Sizzle.isXML;
2504    jQuery.contains = Sizzle.contains;
2505    jQuery.escapeSelector = Sizzle.escape;
2506
2507    var dir = function (elem, dir, until) {
2508      var matched = [],
2509          truncate = until !== undefined;
2510
2511      while ((elem = elem[dir]) && elem.nodeType !== 9) {
2512        if (elem.nodeType === 1) {
2513          if (truncate && jQuery(elem).is(until)) {
2514            break;
2515          }
2516
2517          matched.push(elem);
2518        }
2519      }
2520
2521      return matched;
2522    };
2523
2524    var siblings = function (n, elem) {
2525      var matched = [];
2526
2527      for (; n; n = n.nextSibling) {
2528        if (n.nodeType === 1 && n !== elem) {
2529          matched.push(n);
2530        }
2531      }
2532
2533      return matched;
2534    };
2535
2536    var rneedsContext = jQuery.expr.match.needsContext;
2537
2538    function nodeName(elem, name) {
2539      return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
2540    }
2541
2542    var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i; // Implement the identical functionality for filter and not
2543
2544    function winnow(elements, qualifier, not) {
2545      if (isFunction(qualifier)) {
2546        return jQuery.grep(elements, function (elem, i) {
2547          return !!qualifier.call(elem, i, elem) !== not;
2548        });
2549      } // Single element
2550
2551
2552      if (qualifier.nodeType) {
2553        return jQuery.grep(elements, function (elem) {
2554          return elem === qualifier !== not;
2555        });
2556      } // Arraylike of elements (jQuery, arguments, Array)
2557
2558
2559      if (typeof qualifier !== "string") {
2560        return jQuery.grep(elements, function (elem) {
2561          return indexOf$1.call(qualifier, elem) > -1 !== not;
2562        });
2563      } // Filtered directly for both simple and complex selectors
2564
2565
2566      return jQuery.filter(qualifier, elements, not);
2567    }
2568
2569    jQuery.filter = function (expr, elems, not) {
2570      var elem = elems[0];
2571
2572      if (not) {
2573        expr = ":not(" + expr + ")";
2574      }
2575
2576      if (elems.length === 1 && elem.nodeType === 1) {
2577        return jQuery.find.matchesSelector(elem, expr) ? [elem] : [];
2578      }
2579
2580      return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {
2581        return elem.nodeType === 1;
2582      }));
2583    };
2584
2585    jQuery.fn.extend({
2586      find: function (selector) {
2587        var i,
2588            ret,
2589            len = this.length,
2590            self = this;
2591
2592        if (typeof selector !== "string") {
2593          return this.pushStack(jQuery(selector).filter(function () {
2594            for (i = 0; i < len; i++) {
2595              if (jQuery.contains(self[i], this)) {
2596                return true;
2597              }
2598            }
2599          }));
2600        }
2601
2602        ret = this.pushStack([]);
2603
2604        for (i = 0; i < len; i++) {
2605          jQuery.find(selector, self[i], ret);
2606        }
2607
2608        return len > 1 ? jQuery.uniqueSort(ret) : ret;
2609      },
2610      filter: function (selector) {
2611        return this.pushStack(winnow(this, selector || [], false));
2612      },
2613      not: function (selector) {
2614        return this.pushStack(winnow(this, selector || [], true));
2615      },
2616      is: function (selector) {
2617        return !!winnow(this, // If this is a positional/relative selector, check membership in the returned set
2618        // so $("p:first").is("p:last") won't return true for a doc with two "p".
2619        typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length;
2620      }
2621    }); // Initialize a jQuery object
2622    // A central reference to the root jQuery(document)
2623
2624    var rootjQuery,
2625        // A simple way to check for HTML strings
2626    // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2627    // Strict HTML recognition (#11290: must start with <)
2628    // Shortcut simple #id case for speed
2629    rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
2630        init$2 = jQuery.fn.init = function (selector, context, root) {
2631      var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false)
2632
2633      if (!selector) {
2634        return this;
2635      } // Method init() accepts an alternate rootjQuery
vendor: 4,597 bytes, lines 2636-2760
2636      // so migrate can support jQuery.sub (gh-2101)
2637
2638
2639      root = root || rootjQuery; // Handle HTML strings
2640
2641      if (typeof selector === "string") {
2642        if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
2643          // Assume that strings that start and end with <> are HTML and skip the regex check
2644          match = [null, selector, null];
2645        } else {
2646          match = rquickExpr.exec(selector);
2647        } // Match html or make sure no context is specified for #id
2648
2649
2650        if (match && (match[1] || !context)) {
2651          // HANDLE: $(html) -> $(array)
2652          if (match[1]) {
2653            context = context instanceof jQuery ? context[0] : context; // Option to run scripts is true for back-compat
2654            // Intentionally let the error be thrown if parseHTML is not present
2655
2656            jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document$2, true)); // HANDLE: $(html, props)
2657
2658            if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
2659              for (match in context) {
2660                // Properties of context are called as methods if possible
2661                if (isFunction(this[match])) {
2662                  this[match](context[match]); // ...and otherwise set as attributes
2663                } else {
2664                  this.attr(match, context[match]);
2665                }
2666              }
2667            }
2668
2669            return this; // HANDLE: $(#id)
2670          } else {
2671            elem = document$2.getElementById(match[2]);
2672
2673            if (elem) {
2674              // Inject the element directly into the jQuery object
2675              this[0] = elem;
2676              this.length = 1;
2677            }
2678
2679            return this;
2680          } // HANDLE: $(expr, $(...))
2681
2682        } else if (!context || context.jquery) {
2683          return (context || root).find(selector); // HANDLE: $(expr, context)
2684          // (which is just equivalent to: $(context).find(expr)
2685        } else {
2686          return this.constructor(context).find(selector);
2687        } // HANDLE: $(DOMElement)
2688
2689      } else if (selector.nodeType) {
2690        this[0] = selector;
2691        this.length = 1;
2692        return this; // HANDLE: $(function)
2693        // Shortcut for document ready
2694      } else if (isFunction(selector)) {
2695        return root.ready !== undefined ? root.ready(selector) : // Execute immediately if ready is not present
2696        selector(jQuery);
2697      }
2698
2699      return jQuery.makeArray(selector, this);
2700    }; // Give the init function the jQuery prototype for later instantiation
2701
2702
2703    init$2.prototype = jQuery.fn; // Initialize central reference
2704
2705    rootjQuery = jQuery(document$2);
2706    var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2707        // Methods guaranteed to produce a unique set when starting from a unique set
2708    guaranteedUnique = {
2709      children: true,
2710      contents: true,
2711      next: true,
2712      prev: true
2713    };
2714    jQuery.fn.extend({
2715      has: function (target) {
2716        var targets = jQuery(target, this),
2717            l = targets.length;
2718        return this.filter(function () {
2719          var i = 0;
2720
2721          for (; i < l; i++) {
2722            if (jQuery.contains(this, targets[i])) {
2723              return true;
2724            }
2725          }
2726        });
2727      },
2728      closest: function (selectors, context) {
2729        var cur,
2730            i = 0,
2731            l = this.length,
2732            matched = [],
2733            targets = typeof selectors !== "string" && jQuery(selectors); // Positional selectors never match, since there's no _selection_ context
2734
2735        if (!rneedsContext.test(selectors)) {
2736          for (; i < l; i++) {
2737            for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
2738              // Always skip document fragments
2739              if (cur.nodeType < 11 && (targets ? targets.index(cur) > -1 : // Don't pass non-elements to Sizzle
2740              cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) {
2741                matched.push(cur);
2742                break;
2743              }
2744            }
2745          }
2746        }
2747
2748        return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched);
2749      },
2750      // Determine the position of an element within the set
2751      index: function (elem) {
2752        // No argument, return index in parent
2753        if (!elem) {
2754          return this[0] && this[0].parentNode ? this.first().prevAll().length : -1;
2755        } // Index in selector
2756
2757
2758        if (typeof elem === "string") {
2759          return indexOf$1.call(jQuery(elem), this[0]);
2760        }
vendor: 5,478 bytes, lines 2760-2924
2760 // Locate the position of the desired element
2761
2762
2763        return indexOf$1.call(this, // If it receives a jQuery object, the first element is used
2764        elem.jquery ? elem[0] : elem);
2765      },
2766      add: function (selector, context) {
2767        return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context))));
2768      },
2769      addBack: function (selector) {
2770        return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector));
2771      }
2772    });
2773
2774    function sibling(cur, dir) {
2775      while ((cur = cur[dir]) && cur.nodeType !== 1) {}
2776
2777      return cur;
2778    }
2779
2780    jQuery.each({
2781      parent: function (elem) {
2782        var parent = elem.parentNode;
2783        return parent && parent.nodeType !== 11 ? parent : null;
2784      },
2785      parents: function (elem) {
2786        return dir(elem, "parentNode");
2787      },
2788      parentsUntil: function (elem, i, until) {
2789        return dir(elem, "parentNode", until);
2790      },
2791      next: function (elem) {
2792        return sibling(elem, "nextSibling");
2793      },
2794      prev: function (elem) {
2795        return sibling(elem, "previousSibling");
2796      },
2797      nextAll: function (elem) {
2798        return dir(elem, "nextSibling");
2799      },
2800      prevAll: function (elem) {
2801        return dir(elem, "previousSibling");
2802      },
2803      nextUntil: function (elem, i, until) {
2804        return dir(elem, "nextSibling", until);
2805      },
2806      prevUntil: function (elem, i, until) {
2807        return dir(elem, "previousSibling", until);
2808      },
2809      siblings: function (elem) {
2810        return siblings((elem.parentNode || {}).firstChild, elem);
2811      },
2812      children: function (elem) {
2813        return siblings(elem.firstChild);
2814      },
2815      contents: function (elem) {
2816        if (nodeName(elem, "iframe")) {
2817          return elem.contentDocument;
2818        } // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
2819        // Treat the template element as a regular one in browsers that
2820        // don't support it.
2821
2822
2823        if (nodeName(elem, "template")) {
2824          elem = elem.content || elem;
2825        }
2826
2827        return jQuery.merge([], elem.childNodes);
2828      }
2829    }, function (name, fn) {
2830      jQuery.fn[name] = function (until, selector) {
2831        var matched = jQuery.map(this, fn, until);
2832
2833        if (name.slice(-5) !== "Until") {
2834          selector = until;
2835        }
2836
2837        if (selector && typeof selector === "string") {
2838          matched = jQuery.filter(selector, matched);
2839        }
2840
2841        if (this.length > 1) {
2842          // Remove duplicates
2843          if (!guaranteedUnique[name]) {
2844            jQuery.uniqueSort(matched);
2845          } // Reverse order for parents* and prev-derivatives
2846
2847
2848          if (rparentsprev.test(name)) {
2849            matched.reverse();
2850          }
2851        }
2852
2853        return this.pushStack(matched);
2854      };
2855    });
2856    var rnothtmlwhite = /[^\x20\t\r\n\f]+/g; // Convert String-formatted options into Object-formatted ones
2857
2858    function createOptions(options) {
2859      var object = {};
2860      jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) {
2861        object[flag] = true;
2862      });
2863      return object;
2864    }
2865    /*
2866     * Create a callback list using the following parameters:
2867     *
2868     *	options: an optional list of space-separated options that will change how
2869     *			the callback list behaves or a more traditional option object
2870     *
2871     * By default a callback list will act like an event callback list and can be
2872     * "fired" multiple times.
2873     *
2874     * Possible options:
2875     *
2876     *	once:			will ensure the callback list can only be fired once (like a Deferred)
2877     *
2878     *	memory:			will keep track of previous values and will call any callback added
2879     *					after the list has been fired right away with the latest "memorized"
2880     *					values (like a Deferred)
2881     *
2882     *	unique:			will ensure a callback can only be added once (no duplicate in the list)
2883     *
2884     *	stopOnFalse:	interrupt callings when a callback returns false
2885     *
2886     */
2887
2888
2889    jQuery.Callbacks = function (options) {
2890      // Convert options from String-formatted to Object-formatted if needed
2891      // (we check in cache first)
2892      options = typeof options === "string" ? createOptions(options) : jQuery.extend({}, options);
2893
2894      var // Flag to know if list is currently firing
2895      firing,
2896          // Last fire value for non-forgettable lists
2897      memory,
2898          // Flag to know if list was already fired
2899      fired,
2900          // Flag to prevent firing
2901      locked,
2902          // Actual callback list
2903      list = [],
2904          // Queue of execution data for repeatable lists
2905      queue = [],
2906          // Index of currently firing callback (modified by add/remove as needed)
2907      firingIndex = -1,
2908          // Fire callbacks
2909      fire = function () {
2910        // Enforce single-firing
2911        locked = locked || options.once; // Execute callbacks for all pending executions,
2912        // respecting firingIndex overrides and runtime changes
2913
2914        fired = firing = true;
2915
2916        for (; queue.length; firingIndex = -1) {
2917          memory = queue.shift();
2918
2919          while (++firingIndex < list.length) {
2920            // Run callback and check for early termination
2921            if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) {
2922              // Jump to end and forget the data so .add doesn't re-fire
2923              firingIndex = list.length;
2924              memory = false;
vendor: 19,859 bytes, lines 2925-3474
2925            }
2926          }
2927        } // Forget the data if we're done with it
2928
2929
2930        if (!options.memory) {
2931          memory = false;
2932        }
2933
2934        firing = false; // Clean up if we're done firing for good
2935
2936        if (locked) {
2937          // Keep an empty list if we have data for future add calls
2938          if (memory) {
2939            list = []; // Otherwise, this object is spent
2940          } else {
2941            list = "";
2942          }
2943        }
2944      },
2945          // Actual Callbacks object
2946      self = {
2947        // Add a callback or a collection of callbacks to the list
2948        add: function () {
2949          if (list) {
2950            // If we have memory from a past run, we should fire after adding
2951            if (memory && !firing) {
2952              firingIndex = list.length - 1;
2953              queue.push(memory);
2954            }
2955
2956            (function add(args) {
2957              jQuery.each(args, function (_, arg) {
2958                if (isFunction(arg)) {
2959                  if (!options.unique || !self.has(arg)) {
2960                    list.push(arg);
2961                  }
2962                } else if (arg && arg.length && toType(arg) !== "string") {
2963                  // Inspect recursively
2964                  add(arg);
2965                }
2966              });
2967            })(arguments);
2968
2969            if (memory && !firing) {
2970              fire();
2971            }
2972          }
2973
2974          return this;
2975        },
2976        // Remove a callback from the list
2977        remove: function () {
2978          jQuery.each(arguments, function (_, arg) {
2979            var index;
2980
2981            while ((index = jQuery.inArray(arg, list, index)) > -1) {
2982              list.splice(index, 1); // Handle firing indexes
2983
2984              if (index <= firingIndex) {
2985                firingIndex--;
2986              }
2987            }
2988          });
2989          return this;
2990        },
2991        // Check if a given callback is in the list.
2992        // If no argument is given, return whether or not list has callbacks attached.
2993        has: function (fn) {
2994          return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0;
2995        },
2996        // Remove all callbacks from the list
2997        empty: function () {
2998          if (list) {
2999            list = [];
3000          }
3001
3002          return this;
3003        },
3004        // Disable .fire and .add
3005        // Abort any current/pending executions
3006        // Clear all callbacks and values
3007        disable: function () {
3008          locked = queue = [];
3009          list = memory = "";
3010          return this;
3011        },
3012        disabled: function () {
3013          return !list;
3014        },
3015        // Disable .fire
3016        // Also disable .add unless we have memory (since it would have no effect)
3017        // Abort any pending executions
3018        lock: function () {
3019          locked = queue = [];
3020
3021          if (!memory && !firing) {
3022            list = memory = "";
3023          }
3024
3025          return this;
3026        },
3027        locked: function () {
3028          return !!locked;
3029        },
3030        // Call all callbacks with the given context and arguments
3031        fireWith: function (context, args) {
3032          if (!locked) {
3033            args = args || [];
3034            args = [context, args.slice ? args.slice() : args];
3035            queue.push(args);
3036
3037            if (!firing) {
3038              fire();
3039            }
3040          }
3041
3042          return this;
3043        },
3044        // Call all the callbacks with the given arguments
3045        fire: function () {
3046          self.fireWith(this, arguments);
3047          return this;
3048        },
3049        // To know if the callbacks have already been called at least once
3050        fired: function () {
3051          return !!fired;
3052        }
3053      };
3054
3055      return self;
3056    };
3057
3058    function Identity(v) {
3059      return v;
3060    }
3061
3062    function Thrower(ex) {
3063      throw ex;
3064    }
3065
3066    function adoptValue(value, resolve, reject, noValue) {
3067      var method;
3068
3069      try {
3070        // Check for promise aspect first to privilege synchronous behavior
3071        if (value && isFunction(method = value.promise)) {
3072          method.call(value).done(resolve).fail(reject); // Other thenables
3073        } else if (value && isFunction(method = value.then)) {
3074          method.call(value, resolve, reject); // Other non-thenables
3075        } else {
3076          // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
3077          // * false: [ value ].slice( 0 ) => resolve( value )
3078          // * true: [ value ].slice( 1 ) => resolve()
3079          resolve.apply(undefined, [value].slice(noValue));
3080        } // For Promises/A+, convert exceptions into rejections
3081        // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
3082        // Deferred#then to conditionally suppress rejection.
3083
3084      } catch (value) {
3085        // Support: Android 4.0 only
3086        // Strict mode functions invoked without .call/.apply get global-object context
3087        reject.apply(undefined, [value]);
3088      }
3089    }
3090
3091    jQuery.extend({
3092      Deferred: function (func) {
3093        var tuples = [// action, add listener, callbacks,
3094        // ... .then handlers, argument index, [final state]
3095        ["notify", "progress", jQuery.Callbacks("memory"), jQuery.Callbacks("memory"), 2], ["resolve", "done", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 0, "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 1, "rejected"]],
3096            state = "pending",
3097            promise = {
3098          state: function () {
3099            return state;
3100          },
3101          always: function () {
3102            deferred.done(arguments).fail(arguments);
3103            return this;
3104          },
3105          "catch": function (fn) {
3106            return promise.then(null, fn);
3107          },
3108          // Keep pipe for back-compat
3109          pipe: function
3110            /* fnDone, fnFail, fnProgress */
3111          () {
3112            var fns = arguments;
3113            return jQuery.Deferred(function (newDefer) {
3114              jQuery.each(tuples, function (i, tuple) {
3115                // Map tuples (progress, done, fail) to arguments (done, fail, progress)
3116                var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]]; // deferred.progress(function() { bind to newDefer or newDefer.notify })
3117                // deferred.done(function() { bind to newDefer or newDefer.resolve })
3118                // deferred.fail(function() { bind to newDefer or newDefer.reject })
3119
3120                deferred[tuple[1]](function () {
3121                  var returned = fn && fn.apply(this, arguments);
3122
3123                  if (returned && isFunction(returned.promise)) {
3124                    returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject);
3125                  } else {
3126                    newDefer[tuple[0] + "With"](this, fn ? [returned] : arguments);
3127                  }
3128                });
3129              });
3130              fns = null;
3131            }).promise();
3132          },
3133          then: function (onFulfilled, onRejected, onProgress) {
3134            var maxDepth = 0;
3135
3136            function resolve(depth, deferred, handler, special) {
3137              return function () {
3138                var that = this,
3139                    args = arguments,
3140                    mightThrow = function () {
3141                  var returned, then; // Support: Promises/A+ section 2.3.3.3.3
3142                  // https://promisesaplus.com/#point-59
3143                  // Ignore double-resolution attempts
3144
3145                  if (depth < maxDepth) {
3146                    return;
3147                  }
3148
3149                  returned = handler.apply(that, args); // Support: Promises/A+ section 2.3.1
3150                  // https://promisesaplus.com/#point-48
3151
3152                  if (returned === deferred.promise()) {
3153                    throw new TypeError("Thenable self-resolution");
3154                  } // Support: Promises/A+ sections 2.3.3.1, 3.5
3155                  // https://promisesaplus.com/#point-54
3156                  // https://promisesaplus.com/#point-75
3157                  // Retrieve `then` only once
3158
3159
3160                  then = returned && ( // Support: Promises/A+ section 2.3.4
3161                  // https://promisesaplus.com/#point-64
3162                  // Only check objects and functions for thenability
3163                  typeof returned === "object" || typeof returned === "function") && returned.then; // Handle a returned thenable
3164
3165                  if (isFunction(then)) {
3166                    // Special processors (notify) just wait for resolution
3167                    if (special) {
3168                      then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special)); // Normal processors (resolve) also hook into progress
3169                    } else {
3170                      // ...and disregard older resolution values
3171                      maxDepth++;
3172                      then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special), resolve(maxDepth, deferred, Identity, deferred.notifyWith));
3173                    } // Handle all other returned values
3174
3175                  } else {
3176                    // Only substitute handlers pass on context
3177                    // and multiple values (non-spec behavior)
3178                    if (handler !== Identity) {
3179                      that = undefined;
3180                      args = [returned];
3181                    } // Process the value(s)
3182                    // Default process is resolve
3183
3184
3185                    (special || deferred.resolveWith)(that, args);
3186                  }
3187                },
3188                    // Only normal processors (resolve) catch and reject exceptions
3189                process = special ? mightThrow : function () {
3190                  try {
3191                    mightThrow();
3192                  } catch (e) {
3193                    if (jQuery.Deferred.exceptionHook) {
3194                      jQuery.Deferred.exceptionHook(e, process.stackTrace);
3195                    } // Support: Promises/A+ section 2.3.3.3.4.1
3196                    // https://promisesaplus.com/#point-61
3197                    // Ignore post-resolution exceptions
3198
3199
3200                    if (depth + 1 >= maxDepth) {
3201                      // Only substitute handlers pass on context
3202                      // and multiple values (non-spec behavior)
3203                      if (handler !== Thrower) {
3204                        that = undefined;
3205                        args = [e];
3206                      }
3207
3208                      deferred.rejectWith(that, args);
3209                    }
3210                  }
3211                }; // Support: Promises/A+ section 2.3.3.3.1
3212                // https://promisesaplus.com/#point-57
3213                // Re-resolve promises immediately to dodge false rejection from
3214                // subsequent errors
3215
3216
3217                if (depth) {
3218                  process();
3219                } else {
3220                  // Call an optional hook to record the stack, in case of exception
3221                  // since it's otherwise lost when execution goes async
3222                  if (jQuery.Deferred.getStackHook) {
3223                    process.stackTrace = jQuery.Deferred.getStackHook();
3224                  }
3225
3226                  window.setTimeout(process);
3227                }
3228              };
3229            }
3230
3231            return jQuery.Deferred(function (newDefer) {
3232              // progress_handlers.add( ... )
3233              tuples[0][3].add(resolve(0, newDefer, isFunction(onProgress) ? onProgress : Identity, newDefer.notifyWith)); // fulfilled_handlers.add( ... )
3234
3235              tuples[1][3].add(resolve(0, newDefer, isFunction(onFulfilled) ? onFulfilled : Identity)); // rejected_handlers.add( ... )
3236
3237              tuples[2][3].add(resolve(0, newDefer, isFunction(onRejected) ? onRejected : Thrower));
3238            }).promise();
3239          },
3240          // Get a promise for this deferred
3241          // If obj is provided, the promise aspect is added to the object
3242          promise: function (obj) {
3243            return obj != null ? jQuery.extend(obj, promise) : promise;
3244          }
3245        },
3246            deferred = {}; // Add list-specific methods
3247
3248        jQuery.each(tuples, function (i, tuple) {
3249          var list = tuple[2],
3250              stateString = tuple[5]; // promise.progress = list.add
3251          // promise.done = list.add
3252          // promise.fail = list.add
3253
3254          promise[tuple[1]] = list.add; // Handle state
3255
3256          if (stateString) {
3257            list.add(function () {
3258              // state = "resolved" (i.e., fulfilled)
3259              // state = "rejected"
3260              state = stateString;
3261            }, // rejected_callbacks.disable
3262            // fulfilled_callbacks.disable
3263            tuples[3 - i][2].disable, // rejected_handlers.disable
3264            // fulfilled_handlers.disable
3265            tuples[3 - i][3].disable, // progress_callbacks.lock
3266            tuples[0][2].lock, // progress_handlers.lock
3267            tuples[0][3].lock);
3268          } // progress_handlers.fire
3269          // fulfilled_handlers.fire
3270          // rejected_handlers.fire
3271
3272
3273          list.add(tuple[3].fire); // deferred.notify = function() { deferred.notifyWith(...) }
3274          // deferred.resolve = function() { deferred.resolveWith(...) }
3275          // deferred.reject = function() { deferred.rejectWith(...) }
3276
3277          deferred[tuple[0]] = function () {
3278            deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments);
3279            return this;
3280          }; // deferred.notifyWith = list.fireWith
3281          // deferred.resolveWith = list.fireWith
3282          // deferred.rejectWith = list.fireWith
3283
3284
3285          deferred[tuple[0] + "With"] = list.fireWith;
3286        }); // Make the deferred a promise
3287
3288        promise.promise(deferred); // Call given func if any
3289
3290        if (func) {
3291          func.call(deferred, deferred);
3292        } // All done!
3293
3294
3295        return deferred;
3296      },
3297      // Deferred helper
3298      when: function (singleValue) {
3299        var // count of uncompleted subordinates
3300        remaining = arguments.length,
3301            // count of unprocessed arguments
3302        i = remaining,
3303            // subordinate fulfillment data
3304        resolveContexts = Array(i),
3305            resolveValues = slice.call(arguments),
3306            // the master Deferred
3307        master = jQuery.Deferred(),
3308            // subordinate callback factory
3309        updateFunc = function (i) {
3310          return function (value) {
3311            resolveContexts[i] = this;
3312            resolveValues[i] = arguments.length > 1 ? slice.call(arguments) : value;
3313
3314            if (! --remaining) {
3315              master.resolveWith(resolveContexts, resolveValues);
3316            }
3317          };
3318        }; // Single- and empty arguments are adopted like Promise.resolve
3319
3320
3321        if (remaining <= 1) {
3322          adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject, !remaining); // Use .then() to unwrap secondary thenables (cf. gh-3000)
3323
3324          if (master.state() === "pending" || isFunction(resolveValues[i] && resolveValues[i].then)) {
3325            return master.then();
3326          }
3327        } // Multiple arguments are aggregated like Promise.all array elements
3328
3329
3330        while (i--) {
3331          adoptValue(resolveValues[i], updateFunc(i), master.reject);
3332        }
3333
3334        return master.promise();
3335      }
3336    }); // These usually indicate a programmer mistake during development,
3337    // warn about them ASAP rather than swallowing them by default.
3338
3339    var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
3340
3341    jQuery.Deferred.exceptionHook = function (error, stack) {
3342      // Support: IE 8 - 9 only
3343      // Console exists when dev tools are open, which can happen at any time
3344      if (window.console && window.console.warn && error && rerrorNames.test(error.name)) {
3345        window.console.warn("jQuery.Deferred exception: " + error.message, error.stack, stack);
3346      }
3347    };
3348
3349    jQuery.readyException = function (error) {
3350      window.setTimeout(function () {
3351        throw error;
3352      });
3353    }; // The deferred used on DOM ready
3354
3355
3356    var readyList = jQuery.Deferred();
3357
3358    jQuery.fn.ready = function (fn) {
3359      readyList.then(fn) // Wrap jQuery.readyException in a function so that the lookup
3360      // happens at the time of error handling instead of callback
3361      // registration.
3362      .catch(function (error) {
3363        jQuery.readyException(error);
3364      });
3365      return this;
3366    };
3367
3368    jQuery.extend({
3369      // Is the DOM ready to be used? Set to true once it occurs.
3370      isReady: false,
3371      // A counter to track how many items to wait for before
3372      // the ready event fires. See #6781
3373      readyWait: 1,
3374      // Handle when the DOM is ready
3375      ready: function (wait) {
3376        // Abort if there are pending holds or we're already ready
3377        if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
3378          return;
3379        } // Remember that the DOM is ready
3380
3381
3382        jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be
3383
3384        if (wait !== true && --jQuery.readyWait > 0) {
3385          return;
3386        } // If there are functions bound, to execute
3387
3388
3389        readyList.resolveWith(document$2, [jQuery]);
3390      }
3391    });
3392    jQuery.ready.then = readyList.then; // The ready event handler and self cleanup method
3393
3394    function completed() {
3395      document$2.removeEventListener("DOMContentLoaded", completed);
3396      window.removeEventListener("load", completed);
3397      jQuery.ready();
3398    } // Catch cases where $(document).ready() is called
3399    // after the browser event has already occurred.
3400    // Support: IE <=9 - 10 only
3401    // Older IE sometimes signals "interactive" too soon
3402
3403
3404    if (document$2.readyState === "complete" || document$2.readyState !== "loading" && !document$2.documentElement.doScroll) {
3405      // Handle it asynchronously to allow scripts the opportunity to delay ready
3406      window.setTimeout(jQuery.ready);
3407    } else {
3408      // Use the handy event callback
3409      document$2.addEventListener("DOMContentLoaded", completed); // A fallback to window.onload, that will always work
3410
3411      window.addEventListener("load", completed);
3412    } // Multifunctional method to get and set values of a collection
3413    // The value/s can optionally be executed if it's a function
3414
3415
3416    var access = function (elems, fn, key, value, chainable, emptyGet, raw) {
3417      var i = 0,
3418          len = elems.length,
3419          bulk = key == null; // Sets many values
3420
3421      if (toType(key) === "object") {
3422        chainable = true;
3423
3424        for (i in key) {
3425          access(elems, fn, i, key[i], true, emptyGet, raw);
3426        } // Sets one value
3427
3428      } else if (value !== undefined) {
3429        chainable = true;
3430
3431        if (!isFunction(value)) {
3432          raw = true;
3433        }
3434
3435        if (bulk) {
3436          // Bulk operations run against the entire set
3437          if (raw) {
3438            fn.call(elems, value);
3439            fn = null; // ...except when executing function values
3440          } else {
3441            bulk = fn;
3442
3443            fn = function (elem, key, value) {
3444              return bulk.call(jQuery(elem), value);
3445            };
3446          }
3447        }
3448
3449        if (fn) {
3450          for (; i < len; i++) {
3451            fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));
3452          }
3453        }
3454      }
3455
3456      if (chainable) {
3457        return elems;
3458      } // Gets
3459
3460
3461      if (bulk) {
3462        return fn.call(elems);
3463      }
3464
3465      return len ? fn(elems[0], key) : emptyGet;
3466    }; // Matches dashed string for camelizing
3467
3468
3469    var rmsPrefix = /^-ms-/,
3470        rdashAlpha = /-([a-z])/g; // Used by camelCase as callback to replace()
3471
3472    function fcamelCase(all, letter) {
3473      return letter.toUpperCase();
3474    } // Convert dashed to camelCase; used by the css and data modules
3475    // Support: IE <=9 - 11, Edge 12 - 15
3476    // Microsoft forgot to hump their vendor prefix (#9572)
3477
3478
3479    function camelCase(string) {
3480      return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
3481    }
3482
3483    var acceptData = function (owner) {
3484      // Accepts only:
3485      //  - Node
3486      //    - Node.ELEMENT_NODE
3487      //    - Node.DOCUMENT_NODE
3488      //  - Object
3489      //    - Any
3490      return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType;
3491    };
3492
3493    function Data() {
3494      this.expando = jQuery.expando + Data.uid++;
3495    }
3496
3497    Data.uid = 1;
3498    Data.prototype = {
3499      cache: function (owner) {
3500        // Check if the owner object already has a cache
3501        var value = owner[this.expando]; // If not, create one
3502
3503        if (!value) {
3504          value = {}; // We can accept data for non-element nodes in modern browsers,
3505          // but we should not, see #8335.
3506          // Always return an empty object.
3507
3508          if (acceptData(owner)) {
3509            // If it is a node unlikely to be stringify-ed or looped over
3510            // use plain assignment
3511            if (owner.nodeType) {
3512              owner[this.expando] = value; // Otherwise secure it in a non-enumerable property
3513              // configurable must be true to allow the property to be
3514              // deleted when data is removed
3515            } else {
3516              Object.defineProperty(owner, this.expando, {
3517                value: value,
3518                configurable: true
3519              });
3520            }
3521          }
3522        }
3523
3524        return value;
3525      },
3526      set: function (owner, data, value) {
3527        var prop,
3528            cache = this.cache(owner); // Handle: [ owner, key, value ] args
3529        // Always use camelCase key (gh-2257)
3530
3531        if (typeof data === "string") {
3532          cache[camelCase(data)] = value; // Handle: [ owner, { properties } ] args
3533        } else {
3534          // Copy the properties one-by-one to the cache object
3535          for (prop in data) {
3536            cache[camelCase(prop)] = data[prop];
3537          }
3538        }
3539
3540        return cache;
3541      },
3542      get: function (owner, key) {
3543        return key === undefined ? this.cache(owner) : // Always use camelCase key (gh-2257)
3544        owner[this.expando] && owner[this.expando][camelCase(key)];
3545      },
3546      access: function (owner, key, value) {
3547        // In cases where either:
3548        //
3549        //   1. No key was specified
3550        //   2. A string key was specified, but no value provided
3551        //
3552        // Take the "read" path and allow the get method to determine
3553        // which value to return, respectively either:
3554        //
3555        //   1. The entire cache object
3556        //   2. The data stored at the key
3557        //
3558        if (key === undefined || key && typeof key === "string" && value === undefined) {
3559          return this.get(owner, key);
3560        } // When the key is not a string, or both a key and value
3561        // are specified, set or extend (existing objects) with either:
3562        //
3563        //   1. An object of properties
3564        //   2. A key and value
3565        //
3566
3567
3568        this.set(owner, key, value); // Since the "set" path can have two possible entry points
3569        // return the expected data based on which path was taken[*]
3570
3571        return value !== undefined ? value : key;
3572      },
3573      remove: function (owner, key) {
3574        var i,
3575            cache = owner[this.expando];
3576
3577        if (cache === undefined) {
3578          return;
3579        }
3580
3581        if (key !== undefined) {
3582          // Support array or space separated string of keys
3583          if (Array.isArray(key)) {
3584            // If key is an array of keys...
3585            // We always set camelCase keys, so remove that.
3586            key = key.map(camelCase);
3587          } else {
3588            key = camelCase(key); // If a key with the spaces exists, use it.
3589            // Otherwise, create an array by matching non-whitespace
3590
3591            key = key in cache ? [key] : key.match(rnothtmlwhite) || [];
3592          }
3593
3594          i = key.length;
3595
3596          while (i--) {
3597            delete cache[key[i]];
3598          }
3599        } // Remove the expando if there's no more data
3600
3601
3602        if (key === undefined || jQuery.isEmptyObject(cache)) {
vendor: 9,050 bytes, lines 3603-3911
3603          // Support: Chrome <=35 - 45
3604          // Webkit & Blink performance suffers when deleting properties
3605          // from DOM nodes, so set to undefined instead
3606          // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
3607          if (owner.nodeType) {
3608            owner[this.expando] = undefined;
3609          } else {
3610            delete owner[this.expando];
3611          }
3612        }
3613      },
3614      hasData: function (owner) {
3615        var cache = owner[this.expando];
3616        return cache !== undefined && !jQuery.isEmptyObject(cache);
3617      }
3618    };
3619    var dataPriv = new Data();
3620    var dataUser = new Data(); //	Implementation Summary
3621    //
3622    //	1. Enforce API surface and semantic compatibility with 1.9.x branch
3623    //	2. Improve the module's maintainability by reducing the storage
3624    //		paths to a single mechanism.
3625    //	3. Use the same single mechanism to support "private" and "user" data.
3626    //	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
3627    //	5. Avoid exposing implementation details on user objects (eg. expando properties)
3628    //	6. Provide a clear path for implementation upgrade to WeakMap in 2014
3629
3630    var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3631        rmultiDash = /[A-Z]/g;
3632
3633    function getData(data) {
3634      if (data === "true") {
3635        return true;
3636      }
3637
3638      if (data === "false") {
3639        return false;
3640      }
3641
3642      if (data === "null") {
3643        return null;
3644      } // Only convert to a number if it doesn't change the string
3645
3646
3647      if (data === +data + "") {
3648        return +data;
3649      }
3650
3651      if (rbrace.test(data)) {
3652        return JSON.parse(data);
3653      }
3654
3655      return data;
3656    }
3657
3658    function dataAttr(elem, key, data) {
3659      var name; // If nothing was found internally, try to fetch any
3660      // data from the HTML5 data-* attribute
3661
3662      if (data === undefined && elem.nodeType === 1) {
3663        name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase();
3664        data = elem.getAttribute(name);
3665
3666        if (typeof data === "string") {
3667          try {
3668            data = getData(data);
3669          } catch (e) {} // Make sure we set the data so it isn't changed later
3670
3671
3672          dataUser.set(elem, key, data);
3673        } else {
3674          data = undefined;
3675        }
3676      }
3677
3678      return data;
3679    }
3680
3681    jQuery.extend({
3682      hasData: function (elem) {
3683        return dataUser.hasData(elem) || dataPriv.hasData(elem);
3684      },
3685      data: function (elem, name, data) {
3686        return dataUser.access(elem, name, data);
3687      },
3688      removeData: function (elem, name) {
3689        dataUser.remove(elem, name);
3690      },
3691      // TODO: Now that all calls to _data and _removeData have been replaced
3692      // with direct calls to dataPriv methods, these can be deprecated.
3693      _data: function (elem, name, data) {
3694        return dataPriv.access(elem, name, data);
3695      },
3696      _removeData: function (elem, name) {
3697        dataPriv.remove(elem, name);
3698      }
3699    });
3700    jQuery.fn.extend({
3701      data: function (key, value) {
3702        var i,
3703            name,
3704            data,
3705            elem = this[0],
3706            attrs = elem && elem.attributes; // Gets all values
3707
3708        if (key === undefined) {
3709          if (this.length) {
3710            data = dataUser.get(elem);
3711
3712            if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) {
3713              i = attrs.length;
3714
3715              while (i--) {
3716                // Support: IE 11 only
3717                // The attrs elements can be null (#14894)
3718                if (attrs[i]) {
3719                  name = attrs[i].name;
3720
3721                  if (name.indexOf("data-") === 0) {
3722                    name = camelCase(name.slice(5));
3723                    dataAttr(elem, name, data[name]);
3724                  }
3725                }
3726              }
3727
3728              dataPriv.set(elem, "hasDataAttrs", true);
3729            }
3730          }
3731
3732          return data;
3733        } // Sets multiple values
3734
3735
3736        if (typeof key === "object") {
3737          return this.each(function () {
3738            dataUser.set(this, key);
3739          });
3740        }
3741
3742        return access(this, function (value) {
3743          var data; // The calling jQuery object (element matches) is not empty
3744          // (and therefore has an element appears at this[ 0 ]) and the
3745          // `value` parameter was not undefined. An empty jQuery object
3746          // will result in `undefined` for elem = this[ 0 ] which will
3747          // throw an exception if an attempt to read a data cache is made.
3748
3749          if (elem && value === undefined) {
3750            // Attempt to get data from the cache
3751            // The key will always be camelCased in Data
3752            data = dataUser.get(elem, key);
3753
3754            if (data !== undefined) {
3755              return data;
3756            } // Attempt to "discover" the data in
3757            // HTML5 custom data-* attrs
3758
3759
3760            data = dataAttr(elem, key);
3761
3762            if (data !== undefined) {
3763              return data;
3764            } // We tried really hard, but the data doesn't exist.
3765
3766
3767            return;
3768          } // Set the data...
3769
3770
3771          this.each(function () {
3772            // We always store the camelCased key
3773            dataUser.set(this, key, value);
3774          });
3775        }, null, value, arguments.length > 1, null, true);
3776      },
3777      removeData: function (key) {
3778        return this.each(function () {
3779          dataUser.remove(this, key);
3780        });
3781      }
3782    });
3783    jQuery.extend({
3784      queue: function (elem, type, data) {
3785        var queue;
3786
3787        if (elem) {
3788          type = (type || "fx") + "queue";
3789          queue = dataPriv.get(elem, type); // Speed up dequeue by getting out quickly if this is just a lookup
3790
3791          if (data) {
3792            if (!queue || Array.isArray(data)) {
3793              queue = dataPriv.access(elem, type, jQuery.makeArray(data));
3794            } else {
3795              queue.push(data);
3796            }
3797          }
3798
3799          return queue || [];
3800        }
3801      },
3802      dequeue: function (elem, type) {
3803        type = type || "fx";
3804
3805        var queue = jQuery.queue(elem, type),
3806            startLength = queue.length,
3807            fn = queue.shift(),
3808            hooks = jQuery._queueHooks(elem, type),
3809            next = function () {
3810          jQuery.dequeue(elem, type);
3811        }; // If the fx queue is dequeued, always remove the progress sentinel
3812
3813
3814        if (fn === "inprogress") {
3815          fn = queue.shift();
3816          startLength--;
3817        }
3818
3819        if (fn) {
3820          // Add a progress sentinel to prevent the fx queue from being
3821          // automatically dequeued
3822          if (type === "fx") {
3823            queue.unshift("inprogress");
3824          } // Clear up the last queue stop function
3825
3826
3827          delete hooks.stop;
3828          fn.call(elem, next, hooks);
3829        }
3830
3831        if (!startLength && hooks) {
3832          hooks.empty.fire();
3833        }
3834      },
3835      // Not public - generate a queueHooks object, or return the current one
3836      _queueHooks: function (elem, type) {
3837        var key = type + "queueHooks";
3838        return dataPriv.get(elem, key) || dataPriv.access(elem, key, {
3839          empty: jQuery.Callbacks("once memory").add(function () {
3840            dataPriv.remove(elem, [type + "queue", key]);
3841          })
3842        });
3843      }
3844    });
3845    jQuery.fn.extend({
3846      queue: function (type, data) {
3847        var setter = 2;
3848
3849        if (typeof type !== "string") {
3850          data = type;
3851          type = "fx";
3852          setter--;
3853        }
3854
3855        if (arguments.length < setter) {
3856          return jQuery.queue(this[0], type);
3857        }
3858
3859        return data === undefined ? this : this.each(function () {
3860          var queue = jQuery.queue(this, type, data); // Ensure a hooks for this queue
3861
3862          jQuery._queueHooks(this, type);
3863
3864          if (type === "fx" && queue[0] !== "inprogress") {
3865            jQuery.dequeue(this, type);
3866          }
3867        });
3868      },
3869      dequeue: function (type) {
3870        return this.each(function () {
3871          jQuery.dequeue(this, type);
3872        });
3873      },
3874      clearQueue: function (type) {
3875        return this.queue(type || "fx", []);
3876      },
3877      // Get a promise resolved when queues of a certain type
3878      // are emptied (fx is the type by default)
3879      promise: function (type, obj) {
3880        var tmp,
3881            count = 1,
3882            defer = jQuery.Deferred(),
3883            elements = this,
3884            i = this.length,
3885            resolve = function () {
3886          if (! --count) {
3887            defer.resolveWith(elements, [elements]);
3888          }
3889        };
3890
3891        if (typeof type !== "string") {
3892          obj = type;
3893          type = undefined;
3894        }
3895
3896        type = type || "fx";
3897
3898        while (i--) {
3899          tmp = dataPriv.get(elements[i], type + "queueHooks");
3900
3901          if (tmp && tmp.empty) {
3902            count++;
3903            tmp.empty.add(resolve);
3904          }
3905        }
3906
3907        resolve();
3908        return defer.promise(obj);
3909      }
3910    });
3911    var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source;
3912    var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i");
3913    var cssExpand = ["Top", "Right", "Bottom", "Left"];
3914
3915    var isHiddenWithinTree = function (elem, el) {
3916      // isHiddenWithinTree might be called from jQuery#filter function;
3917      // in that case, element will be second argument
3918      elem = el || elem; // Inline style trumps all
3919
3920      return elem.style.display === "none" || elem.style.display === "" && // Otherwise, check computed style
3921      // Support: Firefox <=43 - 45
3922      // Disconnected elements can have computed display: none, so first confirm that elem is
3923      // in the document.
3924      jQuery.contains(elem.ownerDocument, elem) && jQuery.css(elem, "display") === "none";
3925    };
3926
3927    var swap = function (elem, options, callback, args) {
3928      var ret,
3929          name,
3930          old = {}; // Remember the old values, and insert the new ones
3931
3932      for (name in options) {
3933        old[name] = elem.style[name];
3934        elem.style[name] = options[name];
3935      }
3936
3937      ret = callback.apply(elem, args || []); // Revert the old values
3938
3939      for (name in options) {
3940        elem.style[name] = old[name];
3941      }
3942
3943      return ret;
3944    };
3945
3946    function adjustCSS(elem, prop, valueParts, tween) {
3947      var adjusted,
3948          scale,
3949          maxIterations = 20,
3950          currentValue = tween ? function () {
3951        return tween.cur();
3952      } : function () {
3953        return jQuery.css(elem, prop, "");
3954      },
3955          initial = currentValue(),
3956          unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"),
3957          // Starting value computation is required for potential unit mismatches
3958      initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial) && rcssNum.exec(jQuery.css(elem, prop));
3959
3960      if (initialInUnit && initialInUnit[3] !== unit) {
3961        // Support: Firefox <=54
3962        // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
3963        initial = initial / 2; // Trust units reported by jQuery.css
3964
3965        unit = unit || initialInUnit[3]; // Iteratively approximate from a nonzero starting point
3966
3967        initialInUnit = +initial || 1;
3968
3969        while (maxIterations--) {
3970          // Evaluate and update our best guess (doubling guesses that zero out).
3971          // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
3972          jQuery.style(elem, prop, initialInUnit + unit);
3973
3974          if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) {
3975            maxIterations = 0;
3976          }
3977
3978          initialInUnit = initialInUnit / scale;
3979        }
3980
3981        initialInUnit = initialInUnit * 2;
3982        jQuery.style(elem, prop, initialInUnit + unit); // Make sure we update the tween properties later on
3983
3984        valueParts = valueParts || [];
3985      }
3986
3987      if (valueParts) {
3988        initialInUnit = +initialInUnit || +initial || 0; // Apply relative offset (+=/-=) if specified
3989
3990        adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2];
3991
3992        if (tween) {
3993          tween.unit = unit;
3994          tween.start = initialInUnit;
3995          tween.end = adjusted;
3996        }
3997      }
3998
3999      return adjusted;
4000    }
4001
4002    var defaultDisplayMap = {};
4003
4004    function getDefaultDisplay(elem) {
4005      var temp,
4006          doc = elem.ownerDocument,
4007          nodeName = elem.nodeName,
4008          display = defaultDisplayMap[nodeName];
4009
4010      if (display) {
4011        return display;
4012      }
4013
4014      temp = doc.body.appendChild(doc.createElement(nodeName));
4015      display = jQuery.css(temp, "display");
4016      temp.parentNode.removeChild(temp);
4017
4018      if (display === "none") {
4019        display = "block";
4020      }
4021
4022      defaultDisplayMap[nodeName] = display;
4023      return display;
4024    }
4025
4026    function showHide(elements, show) {
4027      var display,
4028          elem,
4029          values = [],
4030          index = 0,
4031          length = elements.length; // Determine new display value for elements that need to change
4032
4033      for (; index < length; index++) {
4034        elem = elements[index];
4035
4036        if (!elem.style) {
4037          continue;
4038        }
4039
4040        display = elem.style.display;
4041
4042        if (show) {
vendor: 6,155 bytes, lines 4043-4237
4043          // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
4044          // check is required in this first loop unless we have a nonempty display value (either
4045          // inline or about-to-be-restored)
4046          if (display === "none") {
4047            values[index] = dataPriv.get(elem, "display") || null;
4048
4049            if (!values[index]) {
4050              elem.style.display = "";
4051            }
4052          }
4053
4054          if (elem.style.display === "" && isHiddenWithinTree(elem)) {
4055            values[index] = getDefaultDisplay(elem);
4056          }
4057        } else {
4058          if (display !== "none") {
4059            values[index] = "none"; // Remember what we're overwriting
4060
4061            dataPriv.set(elem, "display", display);
4062          }
4063        }
4064      } // Set the display of the elements in a second loop to avoid constant reflow
4065
4066
4067      for (index = 0; index < length; index++) {
4068        if (values[index] != null) {
4069          elements[index].style.display = values[index];
4070        }
4071      }
4072
4073      return elements;
4074    }
4075
4076    jQuery.fn.extend({
4077      show: function () {
4078        return showHide(this, true);
4079      },
4080      hide: function () {
4081        return showHide(this);
4082      },
4083      toggle: function (state) {
4084        if (typeof state === "boolean") {
4085          return state ? this.show() : this.hide();
4086        }
4087
4088        return this.each(function () {
4089          if (isHiddenWithinTree(this)) {
4090            jQuery(this).show();
4091          } else {
4092            jQuery(this).hide();
4093          }
4094        });
4095      }
4096    });
4097    var rcheckableType = /^(?:checkbox|radio)$/i;
4098    var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]+)/i;
4099    var rscriptType = /^$|^module$|\/(?:java|ecma)script/i; // We have to close these tags to support XHTML (#13200)
4100
4101    var wrapMap = {
4102      // Support: IE <=9 only
4103      option: [1, "<select multiple='multiple'>", "</select>"],
4104      // XHTML parsers do not magically insert elements in the
4105      // same way that tag soup parsers do. So we cannot shorten
4106      // this by omitting <tbody> or other required elements.
4107      thead: [1, "<table>", "</table>"],
4108      col: [2, "<table><colgroup>", "</colgroup></table>"],
4109      tr: [2, "<table><tbody>", "</tbody></table>"],
4110      td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
4111      _default: [0, "", ""]
4112    }; // Support: IE <=9 only
4113
4114    wrapMap.optgroup = wrapMap.option;
4115    wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4116    wrapMap.th = wrapMap.td;
4117
4118    function getAll(context, tag) {
4119      // Support: IE <=9 - 11 only
4120      // Use typeof to avoid zero-argument method invocation on host objects (#15151)
4121      var ret;
4122
4123      if (typeof context.getElementsByTagName !== "undefined") {
4124        ret = context.getElementsByTagName(tag || "*");
4125      } else if (typeof context.querySelectorAll !== "undefined") {
4126        ret = context.querySelectorAll(tag || "*");
4127      } else {
4128        ret = [];
4129      }
4130
4131      if (tag === undefined || tag && nodeName(context, tag)) {
4132        return jQuery.merge([context], ret);
4133      }
4134
4135      return ret;
4136    } // Mark scripts as having already been evaluated
4137
4138
4139    function setGlobalEval(elems, refElements) {
4140      var i = 0,
4141          l = elems.length;
4142
4143      for (; i < l; i++) {
4144        dataPriv.set(elems[i], "globalEval", !refElements || dataPriv.get(refElements[i], "globalEval"));
4145      }
4146    }
4147
4148    var rhtml = /<|&#?\w+;/;
4149
4150    function buildFragment(elems, context, scripts, selection, ignored) {
4151      var elem,
4152          tmp,
4153          tag,
4154          wrap,
4155          contains,
4156          j,
4157          fragment = context.createDocumentFragment(),
4158          nodes = [],
4159          i = 0,
4160          l = elems.length;
4161
4162      for (; i < l; i++) {
4163        elem = elems[i];
4164
4165        if (elem || elem === 0) {
4166          // Add nodes directly
4167          if (toType(elem) === "object") {
4168            // Support: Android <=4.0 only, PhantomJS 1 only
4169            // push.apply(_, arraylike) throws on ancient WebKit
4170            jQuery.merge(nodes, elem.nodeType ? [elem] : elem); // Convert non-html into a text node
4171          } else if (!rhtml.test(elem)) {
4172            nodes.push(context.createTextNode(elem)); // Convert html into DOM nodes
4173          } else {
4174            tmp = tmp || fragment.appendChild(context.createElement("div")); // Deserialize a standard representation
4175
4176            tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
4177            wrap = wrapMap[tag] || wrapMap._default;
4178            tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; // Descend through wrappers to the right content
4179
4180            j = wrap[0];
4181
4182            while (j--) {
4183              tmp = tmp.lastChild;
4184            } // Support: Android <=4.0 only, PhantomJS 1 only
4185            // push.apply(_, arraylike) throws on ancient WebKit
4186
4187
4188            jQuery.merge(nodes, tmp.childNodes); // Remember the top-level container
4189
4190            tmp = fragment.firstChild; // Ensure the created nodes are orphaned (#12392)
4191
4192            tmp.textContent = "";
4193          }
4194        }
4195      } // Remove wrapper from fragment
4196
4197
4198      fragment.textContent = "";
4199      i = 0;
4200
4201      while (elem = nodes[i++]) {
4202        // Skip elements already in the context collection (trac-4087)
4203        if (selection && jQuery.inArray(elem, selection) > -1) {
4204          if (ignored) {
4205            ignored.push(elem);
4206          }
4207
4208          continue;
4209        }
4210
4211        contains = jQuery.contains(elem.ownerDocument, elem); // Append to fragment
4212
4213        tmp = getAll(fragment.appendChild(elem), "script"); // Preserve script evaluation history
4214
4215        if (contains) {
4216          setGlobalEval(tmp);
4217        } // Capture executables
4218
4219
4220        if (scripts) {
4221          j = 0;
4222
4223          while (elem = tmp[j++]) {
4224            if (rscriptType.test(elem.type || "")) {
4225              scripts.push(elem);
4226            }
4227          }
4228        }
4229      }
4230
4231      return fragment;
4232    }
4233
4234    (function () {
4235      var fragment = document$2.createDocumentFragment(),
4236          div = fragment.appendChild(document$2.createElement("div")),
4237          input = document$2.createElement("input");
vendor: 12,157 bytes, lines 4237-4595
4237 // Support: Android 4.0 - 4.3 only
4238      // Check state lost if the name is set (#11217)
4239      // Support: Windows Web Apps (WWA)
4240      // `name` and `type` must use .setAttribute for WWA (#14901)
4241
4242      input.setAttribute("type", "radio");
4243      input.setAttribute("checked", "checked");
4244      input.setAttribute("name", "t");
4245      div.appendChild(input); // Support: Android <=4.1 only
4246      // Older WebKit doesn't clone checked state correctly in fragments
4247
4248      support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; // Support: IE <=11 only
4249      // Make sure textarea (and checkbox) defaultValue is properly cloned
4250
4251      div.innerHTML = "<textarea>x</textarea>";
4252      support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;
4253    })();
4254
4255    var documentElement = document$2.documentElement;
4256    var rkeyEvent = /^key/,
4257        rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4258        rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4259
4260    function returnTrue() {
4261      return true;
4262    }
4263
4264    function returnFalse() {
4265      return false;
4266    } // Support: IE <=9 only
4267    // See #13393 for more info
4268
4269
4270    function safeActiveElement() {
4271      try {
4272        return document$2.activeElement;
4273      } catch (err) {}
4274    }
4275
4276    function on(elem, types, selector, data, fn, one) {
4277      var origFn, type; // Types can be a map of types/handlers
4278
4279      if (typeof types === "object") {
4280        // ( types-Object, selector, data )
4281        if (typeof selector !== "string") {
4282          // ( types-Object, data )
4283          data = data || selector;
4284          selector = undefined;
4285        }
4286
4287        for (type in types) {
4288          on(elem, type, selector, data, types[type], one);
4289        }
4290
4291        return elem;
4292      }
4293
4294      if (data == null && fn == null) {
4295        // ( types, fn )
4296        fn = selector;
4297        data = selector = undefined;
4298      } else if (fn == null) {
4299        if (typeof selector === "string") {
4300          // ( types, selector, fn )
4301          fn = data;
4302          data = undefined;
4303        } else {
4304          // ( types, data, fn )
4305          fn = data;
4306          data = selector;
4307          selector = undefined;
4308        }
4309      }
4310
4311      if (fn === false) {
4312        fn = returnFalse;
4313      } else if (!fn) {
4314        return elem;
4315      }
4316
4317      if (one === 1) {
4318        origFn = fn;
4319
4320        fn = function (event) {
4321          // Can use an empty set, since event contains the info
4322          jQuery().off(event);
4323          return origFn.apply(this, arguments);
4324        }; // Use same guid so caller can remove using origFn
4325
4326
4327        fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
4328      }
4329
4330      return elem.each(function () {
4331        jQuery.event.add(this, types, fn, data, selector);
4332      });
4333    }
4334    /*
4335     * Helper functions for managing events -- not part of the public interface.
4336     * Props to Dean Edwards' addEvent library for many of the ideas.
4337     */
4338
4339
4340    jQuery.event = {
4341      global: {},
4342      add: function (elem, types, handler, data, selector) {
4343        var handleObjIn,
4344            eventHandle,
4345            tmp,
4346            events,
4347            t,
4348            handleObj,
4349            special,
4350            handlers,
4351            type,
4352            namespaces,
4353            origType,
4354            elemData = dataPriv.get(elem); // Don't attach events to noData or text/comment nodes (but allow plain objects)
4355
4356        if (!elemData) {
4357          return;
4358        } // Caller can pass in an object of custom data in lieu of the handler
4359
4360
4361        if (handler.handler) {
4362          handleObjIn = handler;
4363          handler = handleObjIn.handler;
4364          selector = handleObjIn.selector;
4365        } // Ensure that invalid selectors throw exceptions at attach time
4366        // Evaluate against documentElement in case elem is a non-element node (e.g., document)
4367
4368
4369        if (selector) {
4370          jQuery.find.matchesSelector(documentElement, selector);
4371        } // Make sure that the handler has a unique ID, used to find/remove it later
4372
4373
4374        if (!handler.guid) {
4375          handler.guid = jQuery.guid++;
4376        } // Init the element's event structure and main handler, if this is the first
4377
4378
4379        if (!(events = elemData.events)) {
4380          events = elemData.events = {};
4381        }
4382
4383        if (!(eventHandle = elemData.handle)) {
4384          eventHandle = elemData.handle = function (e) {
4385            // Discard the second event of a jQuery.event.trigger() and
4386            // when an event is called after a page has unloaded
4387            return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply(elem, arguments) : undefined;
4388          };
4389        } // Handle multiple events separated by a space
4390
4391
4392        types = (types || "").match(rnothtmlwhite) || [""];
4393        t = types.length;
4394
4395        while (t--) {
4396          tmp = rtypenamespace.exec(types[t]) || [];
4397          type = origType = tmp[1];
4398          namespaces = (tmp[2] || "").split(".").sort(); // There *must* be a type, no attaching namespace-only handlers
4399
4400          if (!type) {
4401            continue;
4402          } // If event changes its type, use the special event handlers for the changed type
4403
4404
4405          special = jQuery.event.special[type] || {}; // If selector defined, determine special event api type, otherwise given type
4406
4407          type = (selector ? special.delegateType : special.bindType) || type; // Update special based on newly reset type
4408
4409          special = jQuery.event.special[type] || {}; // handleObj is passed to all event handlers
4410
4411          handleObj = jQuery.extend({
4412            type: type,
4413            origType: origType,
4414            data: data,
4415            handler: handler,
4416            guid: handler.guid,
4417            selector: selector,
4418            needsContext: selector && jQuery.expr.match.needsContext.test(selector),
4419            namespace: namespaces.join(".")
4420          }, handleObjIn); // Init the event handler queue if we're the first
4421
4422          if (!(handlers = events[type])) {
4423            handlers = events[type] = [];
4424            handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false
4425
4426            if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
4427              if (elem.addEventListener) {
4428                elem.addEventListener(type, eventHandle);
4429              }
4430            }
4431          }
4432
4433          if (special.add) {
4434            special.add.call(elem, handleObj);
4435
4436            if (!handleObj.handler.guid) {
4437              handleObj.handler.guid = handler.guid;
4438            }
4439          } // Add to the element's handler list, delegates in front
4440
4441
4442          if (selector) {
4443            handlers.splice(handlers.delegateCount++, 0, handleObj);
4444          } else {
4445            handlers.push(handleObj);
4446          } // Keep track of which events have ever been used, for event optimization
4447
4448
4449          jQuery.event.global[type] = true;
4450        }
4451      },
4452      // Detach an event or set of events from an element
4453      remove: function (elem, types, handler, selector, mappedTypes) {
4454        var j,
4455            origCount,
4456            tmp,
4457            events,
4458            t,
4459            handleObj,
4460            special,
4461            handlers,
4462            type,
4463            namespaces,
4464            origType,
4465            elemData = dataPriv.hasData(elem) && dataPriv.get(elem);
4466
4467        if (!elemData || !(events = elemData.events)) {
4468          return;
4469        } // Once for each type.namespace in types; type may be omitted
4470
4471
4472        types = (types || "").match(rnothtmlwhite) || [""];
4473        t = types.length;
4474
4475        while (t--) {
4476          tmp = rtypenamespace.exec(types[t]) || [];
4477          type = origType = tmp[1];
4478          namespaces = (tmp[2] || "").split(".").sort(); // Unbind all events (on this namespace, if provided) for the element
4479
4480          if (!type) {
4481            for (type in events) {
4482              jQuery.event.remove(elem, type + types[t], handler, selector, true);
4483            }
4484
4485            continue;
4486          }
4487
4488          special = jQuery.event.special[type] || {};
4489          type = (selector ? special.delegateType : special.bindType) || type;
4490          handlers = events[type] || [];
4491          tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)"); // Remove matching events
4492
4493          origCount = j = handlers.length;
4494
4495          while (j--) {
4496            handleObj = handlers[j];
4497
4498            if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {
4499              handlers.splice(j, 1);
4500
4501              if (handleObj.selector) {
4502                handlers.delegateCount--;
4503              }
4504
4505              if (special.remove) {
4506                special.remove.call(elem, handleObj);
4507              }
4508            }
4509          } // Remove generic event handler if we removed something and no more handlers exist
4510          // (avoids potential for endless recursion during removal of special event handlers)
4511
4512
4513          if (origCount && !handlers.length) {
4514            if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {
4515              jQuery.removeEvent(elem, type, elemData.handle);
4516            }
4517
4518            delete events[type];
4519          }
4520        } // Remove data and the expando if it's no longer used
4521
4522
4523        if (jQuery.isEmptyObject(events)) {
4524          dataPriv.remove(elem, "handle events");
4525        }
4526      },
4527      dispatch: function (nativeEvent) {
4528        // Make a writable jQuery.Event from the native event object
4529        var event = jQuery.event.fix(nativeEvent);
4530        var i,
4531            j,
4532            ret,
4533            matched,
4534            handleObj,
4535            handlerQueue,
4536            args = new Array(arguments.length),
4537            handlers = (dataPriv.get(this, "events") || {})[event.type] || [],
4538            special = jQuery.event.special[event.type] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event
4539
4540        args[0] = event;
4541
4542        for (i = 1; i < arguments.length; i++) {
4543          args[i] = arguments[i];
4544        }
4545
4546        event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired
4547
4548        if (special.preDispatch && special.preDispatch.call(this, event) === false) {
4549          return;
4550        } // Determine handlers
4551
4552
4553        handlerQueue = jQuery.event.handlers.call(this, event, handlers); // Run delegates first; they may want to stop propagation beneath us
4554
4555        i = 0;
4556
4557        while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
4558          event.currentTarget = matched.elem;
4559          j = 0;
4560
4561          while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
4562            // Triggered event must either 1) have no namespace, or 2) have namespace(s)
4563            // a subset or equal to those in the bound event (both can have no namespace).
4564            if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) {
4565              event.handleObj = handleObj;
4566              event.data = handleObj.data;
4567              ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args);
4568
4569              if (ret !== undefined) {
4570                if ((event.result = ret) === false) {
4571                  event.preventDefault();
4572                  event.stopPropagation();
4573                }
4574              }
4575            }
4576          }
4577        } // Call the postDispatch hook for the mapped type
4578
4579
4580        if (special.postDispatch) {
4581          special.postDispatch.call(this, event);
4582        }
4583
4584        return event.result;
4585      },
4586      handlers: function (event, handlers) {
4587        var i,
4588            handleObj,
4589            sel,
4590            matchedHandlers,
4591            matchedSelectors,
4592            handlerQueue = [],
4593            delegateCount = handlers.delegateCount,
4594            cur = event.target; // Find delegate handlers
4595
4596        if (delegateCount && // Support: IE <=9
4597        // Black-hole SVG <use> instance trees (trac-13180)
4598        cur.nodeType && // Support: Firefox <=42
4599        // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
4600        // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
4601        // Support: IE 11 only
4602        // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
4603        !(event.type === "click" && event.button >= 1)) {
4604          for (; cur !== this; cur = cur.parentNode || this) {
4605            // Don't check non-elements (#13208)
4606            // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4607            if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) {
4608              matchedHandlers = [];
4609              matchedSelectors = {};
4610
4611              for (i = 0; i < delegateCount; i++) {
4612                handleObj = handlers[i]; // Don't conflict with Object.prototype properties (#13203)
4613
4614                sel = handleObj.selector + " ";
4615
4616                if (matchedSelectors[sel] === undefined) {
4617                  matchedSelectors[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length;
4618                }
4619
4620                if (matchedSelectors[sel]) {
4621                  matchedHandlers.push(handleObj);
4622                }
4623              }
4624
4625              if (matchedHandlers.length) {
4626                handlerQueue.push({
4627                  elem: cur,
4628                  handlers: matchedHandlers
4629                });
4630              }
4631            }
4632          }
4633        } // Add the remaining (directly-bound) handlers
4634
4635
4636        cur = this;
4637
4638        if (delegateCount < handlers.length) {
4639          handlerQueue.push({
4640            elem: cur,
4641            handlers: handlers.slice(delegateCount)
4642          });
4643        }
4644
4645        return handlerQueue;
4646      },
4647      addProp: function (name, hook) {
4648        Object.defineProperty(jQuery.Event.prototype, name, {
4649          enumerable: true,
4650          configurable: true,
4651          get: isFunction(hook) ? function () {
4652            if (this.originalEvent) {
4653              return hook(this.originalEvent);
4654            }
4655          } : function () {
4656            if (this.originalEvent) {
4657              return this.originalEvent[name];
4658            }
4659          },
4660          set: function (value) {
4661            Object.defineProperty(this, name, {
4662              enumerable: true,
4663              configurable: true,
4664              writable: true,
4665              value: value
4666            });
4667          }
4668        });
4669      },
4670      fix: function (originalEvent) {
4671        return originalEvent[jQuery.expando] ? originalEvent : new jQuery.Event(originalEvent);
4672      },
4673      special: {
4674        load: {
4675          // Prevent triggered image.load events from bubbling to window.load
4676          noBubble: true
4677        },
4678        focus: {
4679          // Fire native event if possible so blur/focus sequence is correct
4680          trigger: function () {
4681            if (this !== safeActiveElement() && this.focus) {
4682              this.focus();
4683              return false;
4684            }
4685          },
4686          delegateType: "focusin"
4687        },
4688        blur: {
4689          trigger: function () {
4690            if (this === safeActiveElement() && this.blur) {
4691              this.blur();
4692              return false;
4693            }
4694          },
4695          delegateType: "focusout"
4696        },
4697        click: {
4698          // For checkbox, fire native event so checked state will be right
4699          trigger: function () {
4700            if (this.type === "checkbox" && this.click && nodeName(this, "input")) {
4701              this.click();
4702              return false;
4703            }
4704          },
4705          // For cross-browser consistency, don't fire native .click() on links
4706          _default: function (event) {
4707            return nodeName(event.target, "a");
4708          }
4709        },
4710        beforeunload: {
4711          postDispatch: function (event) {
4712            // Support: Firefox 20+
4713            // Firefox doesn't alert if the returnValue field is not set.
4714            if (event.result !== undefined && event.originalEvent) {
4715              event.originalEvent.returnValue = event.result;
4716            }
4717          }
4718        }
4719      }
4720    };
4721
4722    jQuery.removeEvent = function (elem, type, handle) {
4723      // This "if" is needed for plain objects
4724      if (elem.removeEventListener) {
4725        elem.removeEventListener(type, handle);
4726      }
4727    };
4728
4729    jQuery.Event = function (src, props) {
4730      // Allow instantiation without the 'new' keyword
4731      if (!(this instanceof jQuery.Event)) {
4732        return new jQuery.Event(src, props);
4733      } // Event object
4734
4735
4736      if (src && src.type) {
4737        this.originalEvent = src;
4738        this.type = src.type; // Events bubbling up the document may have been marked as prevented
4739        // by a handler lower down the tree; reflect the correct value.
4740
4741        this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && // Supp
4741ort: Android <=2.3 only
4742        src.returnValue === false ? returnTrue : returnFalse; // Create target properties
4743        // Support: Safari <=6 - 7 only
4744        // Target should not be a text node (#504, #13143)
4745
4746        this.target = src.target && src.target.nodeType === 3 ? src.target.parentNode : src.target;
4747        this.currentTarget = src.currentTarget;
4748        this.relatedTarget = src.relatedTarget; // Event type
4749      } else {
4750        this.type = src;
4751      } // Put explicitly provided properties onto the event object
4752
4753
4754      if (props) {
4755        jQuery.extend(this, props);
4756      } // Create a timestamp if incoming event doesn't have one
4757
4758
4759      this.timeStamp = src && src.timeStamp || Date.now(); // Mark it as fixed
4760
4761      this[jQuery.expando] = true;
4762    }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
4763    // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
4764
4765
4766    jQuery.Event.prototype = {
4767      constructor: jQuery.Event,
4768      isDefaultPrevented: returnFalse,
4769      isPropagationStopped: returnFalse,
4770      isImmediatePropagationStopped: returnFalse,
4771      isSimulated: false,
4772      preventDefault: function () {
4773        var e = this.originalEvent;
4774        this.isDefaultPrevented = returnTrue;
4775
4776        if (e && !this.isSimulated) {
4777          e.preventDefault();
4778        }
4779      },
4780      stopPropagation: function () {
4781        var e = this.originalEvent;
4782        this.isPropagationStopped = returnTrue;
4783
4784        if (e && !this.isSimulated) {
4785          e.stopPropagation();
4786        }
4787      },
4788      stopImmediatePropagation: function () {
4789        var e = this.originalEvent;
4790        this.isImmediatePropagationStopped = returnTrue;
4791
4792        if (e && !this.isSimulated) {
4793          e.stopImmediatePropagation();
4794        }
4795
4796        this.stopPropagation();
4797      }
4798    }; // Includes all common event props including KeyEvent and MouseEvent specific props
4799
4800    jQuery.each({
4801      altKey: true,
4802      bubbles: true,
4803      cancelable: true,
4804      changedTouches: true,
4805      ctrlKey: true,
4806      detail: true,
4807      eventPhase: true,
4808      metaKey: true,
4809      pageX: true,
4810      pageY: true,
4811      shiftKey: true,
4812      view: true,
4813      "char": true,
4814      charCode: true,
4815      key: true,
4816      keyCode: true,
4817      button: true,
4818      buttons: true,
4819      clientX: true,
4820      clientY: true,
4821      offsetX: true,
4822      offsetY: true,
4823      pointerId: true,
4824      pointerType: true,
4825      screenX: true,
4826      screenY: true,
4827      targetTouches: true,
4828      toElement: true,
4829      touches: true,
4830      which: function (event) {
4831        var button = event.button; // Add which for key events
4832
4833        if (event.which == null && rkeyEvent.test(event.type)) {
4834          return event.charCode != null ? event.charCode : event.keyCode;
4835        } // Add which for click: 1 === left; 2 === middle; 3 === right
4836
4837
4838        if (!event.which && button !== undefined && rmouseEvent.test(event.type)) {
4839          if (button & 1) {
4840            return 1;
4841          }
4842
4843          if (button & 2) {
4844            return 3;
4845          }
4846
4847          if (button & 4) {
4848            return 2;
4849          }
4850
4851          return 0;
4852        }
4853
4854        return event.which;
4855      }
4856    }, jQuery.event.addProp); // Create mouseenter/leave events using mouseover/out and event-time checks
4857    // so that event delegation works in jQuery.
4858    // Do the same for pointerenter/pointerleave and pointerover/pointerout
4859    //
4860    // Support: Safari 7 only
4861    // Safari sends mouseenter too often; see:
4862    // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
4863    // for the description of the bug (it existed in older Chrome versions as well).
4864
4865    jQuery.each({
4866      mouseenter: "mouseover",
4867      mouseleave: "mouseout",
4868      pointerenter: "pointerover",
4869      pointerleave: "pointerout"
4870    }, function (orig, fix) {
4871      jQuery.event.special[orig] = {
4872        delegateType: fix,
4873        bindType: fix,
4874        handle: function (event) {
4875          var ret,
4876              target = this,
4877              related = event.relatedTarget,
4878              handleObj = event.handleObj; // For mouseenter/leave call the handler if related is outside the target.
4879          // NB: No relatedTarget if the mouse left/entered the browser window
4880
4881          if (!related || related !== target && !jQuery.contains(target, related)) {
4882            event.type = handleObj.origType;
4883            ret = handleObj.handler.apply(this, arguments);
4884            event.type = fix;
4885          }
4886
4887          return ret;
4888        }
4889      };
4890    });
4891    jQuery.fn.extend({
4892      on: function (types, selector, data, fn) {
4893        return on(this, types, selector, data, fn);
4894      },
4895      one: function (types, selector, data, fn) {
4896        return on(this, types, selector, data, fn, 1);
4897      },
4898      off: function (types, selector, fn) {
4899        var handleObj, type;
4900
4901        if (types && types.preventDefault && types.handleObj) {
4902          // ( event )  dispatched jQuery.Event
4903          handleObj = types.handleObj;
4904          jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler);
4905          return this;
4906        }
4907
4908        if (typeof types === "object") {
4909          // ( types-object [, selector] )
4910          for (type in types) {
4911            this.off(type, selector, types[type]);
4912          }
4913
4914          return this;
4915        }
4916
4917        if (selector === false || typeof selector === "function") {
4918          // ( types [, fn] )
4919          fn = selector;
4920          selector = undefined;
4921        }
4922
4923        if (fn === false) {
4924          fn = returnFalse;
4925        }
4926
4927        return this.each(function () {
4928          jQuery.event.remove(this, types, fn, selector);
4929        });
4930      }
4931    });
4932    var
4933    /* eslint-disable max-len */
4934    // See https://github.com/eslint/eslint/issues/3229
4935    rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
4936
4937    /* eslint-enable */
4938    // Support: IE <=10 - 11, Edge 12 - 13 only
4939    // In IE/Edge using regex groups here causes severe slowdowns.
4940    // See https://connect.microsoft.com/IE/feedback/details/1736512/
4941    rnoInnerhtml = /
vendor: 4,855 bytes, lines 4941-5081
4941<script|<style|<link/i,
4942        // checked="checked" or checked
4943    rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
4944        rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; // Prefer a tbody over its parent table for containing new rows
4945
4946    function manipulationTarget(elem, content) {
4947      if (nodeName(elem, "table") && nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr")) {
4948        return jQuery(elem).children("tbody")[0] || elem;
4949      }
4950
4951      return elem;
4952    } // Replace/restore the type attribute of script elements for safe DOM manipulation
4953
4954
4955    function disableScript(elem) {
4956      elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
4957      return elem;
4958    }
4959
4960    function restoreScript(elem) {
4961      if ((elem.type || "").slice(0, 5) === "true/") {
4962        elem.type = elem.type.slice(5);
4963      } else {
4964        elem.removeAttribute("type");
4965      }
4966
4967      return elem;
4968    }
4969
4970    function cloneCopyEvent(src, dest) {
4971      var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
4972
4973      if (dest.nodeType !== 1) {
4974        return;
4975      } // 1. Copy private data: events, handlers, etc.
4976
4977
4978      if (dataPriv.hasData(src)) {
4979        pdataOld = dataPriv.access(src);
4980        pdataCur = dataPriv.set(dest, pdataOld);
4981        events = pdataOld.events;
4982
4983        if (events) {
4984          delete pdataCur.handle;
4985          pdataCur.events = {};
4986
4987          for (type in events) {
4988            for (i = 0, l = events[type].length; i < l; i++) {
4989              jQuery.event.add(dest, type, events[type][i]);
4990            }
4991          }
4992        }
4993      } // 2. Copy user data
4994
4995
4996      if (dataUser.hasData(src)) {
4997        udataOld = dataUser.access(src);
4998        udataCur = jQuery.extend({}, udataOld);
4999        dataUser.set(dest, udataCur);
5000      }
5001    } // Fix IE bugs, see support tests
5002
5003
5004    function fixInput(src, dest) {
5005      var nodeName = dest.nodeName.toLowerCase(); // Fails to persist the checked state of a cloned checkbox or radio button.
5006
5007      if (nodeName === "input" && rcheckableType.test(src.type)) {
5008        dest.checked = src.checked; // Fails to return the selected option to the default selected state when cloning options
5009      } else if (nodeName === "input" || nodeName === "textarea") {
5010        dest.defaultValue = src.defaultValue;
5011      }
5012    }
5013
5014    function domManip(collection, args, callback, ignored) {
5015      // Flatten any nested arrays
5016      args = concat$1.apply([], args);
5017      var fragment,
5018          first,
5019          scripts,
5020          hasScripts,
5021          node,
5022          doc,
5023          i = 0,
5024          l = collection.length,
5025          iNoClone = l - 1,
5026          value = args[0],
5027          valueIsFunction = isFunction(value); // We can't cloneNode fragments that contain checked, in WebKit
5028
5029      if (valueIsFunction || l > 1 && typeof value === "string" && !support.checkClone && rchecked.test(value)) {
5030        return collection.each(function (index) {
5031          var self = collection.eq(index);
5032
5033          if (valueIsFunction) {
5034            args[0] = value.call(this, index, self.html());
5035          }
5036
5037          domManip(self, args, callback, ignored);
5038        });
5039      }
5040
5041      if (l) {
5042        fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored);
5043        first = fragment.firstChild;
5044
5045        if (fragment.childNodes.length === 1) {
5046          fragment = first;
5047        } // Require either new content or an interest in ignored elements to invoke the callback
5048
5049
5050        if (first || ignored) {
5051          scripts = jQuery.map(getAll(fragment, "script"), disableScript);
5052          hasScripts = scripts.length; // Use the original fragment for the last item
5053          // instead of the first because it can end up
5054          // being emptied incorrectly in certain situations (#8070).
5055
5056          for (; i < l; i++) {
5057            node = fragment;
5058
5059            if (i !== iNoClone) {
5060              node = jQuery.clone(node, true, true); // Keep references to cloned scripts for later restoration
5061
5062              if (hasScripts) {
5063                // Support: Android <=4.0 only, PhantomJS 1 only
5064                // push.apply(_, arraylike) throws on ancient WebKit
5065                jQuery.merge(scripts, getAll(node, "script"));
5066              }
5067            }
5068
5069            callback.call(collection[i], node, i);
5070          }
5071
5072          if (hasScripts) {
5073            doc = scripts[scripts.length - 1].ownerDocument; // Reenable scripts
5074
5075            jQuery.map(scripts, restoreScript); // Evaluate executable scripts on first document insertion
5076
5077            for (i = 0; i < hasScripts; i++) {
5078              node = scripts[i];
5079
5080              if (rscriptType.test(node.type || "") && !dataPriv.access(node, "globalEval") && jQuery.contains(doc, node)) {
5081                if (node.src && (node.type || "").toLowerCase() !== "module") {
vendor: 6,351 bytes, lines 5082-5279
5082                  // Optional AJAX dependency, but won't run scripts if not present
5083                  if (jQuery._evalUrl) {
5084                    jQuery._evalUrl(node.src);
5085                  }
5086                } else {
5087                  DOMEval(node.textContent.replace(rcleanScript, ""), doc, node);
5088                }
5089              }
5090            }
5091          }
5092        }
5093      }
5094
5095      return collection;
5096    }
5097
5098    function remove(elem, selector, keepData) {
5099      var node,
5100          nodes = selector ? jQuery.filter(selector, elem) : elem,
5101          i = 0;
5102
5103      for (; (node = nodes[i]) != null; i++) {
5104        if (!keepData && node.nodeType === 1) {
5105          jQuery.cleanData(getAll(node));
5106        }
5107
5108        if (node.parentNode) {
5109          if (keepData && jQuery.contains(node.ownerDocument, node)) {
5110            setGlobalEval(getAll(node, "script"));
5111          }
5112
5113          node.parentNode.removeChild(node);
5114        }
5115      }
5116
5117      return elem;
5118    }
5119
5120    jQuery.extend({
5121      htmlPrefilter: function (html) {
5122        return html.replace(rxhtmlTag, "<$1></$2>");
5123      },
5124      clone: function (elem, dataAndEvents, deepDataAndEvents) {
5125        var i,
5126            l,
5127            srcElements,
5128            destElements,
5129            clone = elem.cloneNode(true),
5130            inPage = jQuery.contains(elem.ownerDocument, elem); // Fix IE cloning issues
5131
5132        if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) {
5133          // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
5134          destElements = getAll(clone);
5135          srcElements = getAll(elem);
5136
5137          for (i = 0, l = srcElements.length; i < l; i++) {
5138            fixInput(srcElements[i], destElements[i]);
5139          }
5140        } // Copy the events from the original to the clone
5141
5142
5143        if (dataAndEvents) {
5144          if (deepDataAndEvents) {
5145            srcElements = srcElements || getAll(elem);
5146            destElements = destElements || getAll(clone);
5147
5148            for (i = 0, l = srcElements.length; i < l; i++) {
5149              cloneCopyEvent(srcElements[i], destElements[i]);
5150            }
5151          } else {
5152            cloneCopyEvent(elem, clone);
5153          }
5154        } // Preserve script evaluation history
5155
5156
5157        destElements = getAll(clone, "script");
5158
5159        if (destElements.length > 0) {
5160          setGlobalEval(destElements, !inPage && getAll(elem, "script"));
5161        } // Return the cloned set
5162
5163
5164        return clone;
5165      },
5166      cleanData: function (elems) {
5167        var data,
5168            elem,
5169            type,
5170            special = jQuery.event.special,
5171            i = 0;
5172
5173        for (; (elem = elems[i]) !== undefined; i++) {
5174          if (acceptData(elem)) {
5175            if (data = elem[dataPriv.expando]) {
5176              if (data.events) {
5177                for (type in data.events) {
5178                  if (special[type]) {
5179                    jQuery.event.remove(elem, type); // This is a shortcut to avoid jQuery.event.remove's overhead
5180                  } else {
5181                    jQuery.removeEvent(elem, type, data.handle);
5182                  }
5183                }
5184              } // Support: Chrome <=35 - 45+
5185              // Assign undefined instead of using delete, see Data#remove
5186
5187
5188              elem[dataPriv.expando] = undefined;
5189            }
5190
5191            if (elem[dataUser.expando]) {
5192              // Support: Chrome <=35 - 45+
5193              // Assign undefined instead of using delete, see Data#remove
5194              elem[dataUser.expando] = undefined;
5195            }
5196          }
5197        }
5198      }
5199    });
5200    jQuery.fn.extend({
5201      detach: function (selector) {
5202        return remove(this, selector, true);
5203      },
5204      remove: function (selector) {
5205        return remove(this, selector);
5206      },
5207      text: function (value) {
5208        return access(this, function (value) {
5209          return value === undefined ? jQuery.text(this) : this.empty().each(function () {
5210            if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
5211              this.textContent = value;
5212            }
5213          });
5214        }, null, value, arguments.length);
5215      },
5216      append: function () {
5217        return domManip(this, arguments, function (elem) {
5218          if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
5219            var target = manipulationTarget(this, elem);
5220            target.appendChild(elem);
5221          }
5222        });
5223      },
5224      prepend: function () {
5225        return domManip(this, arguments, function (elem) {
5226          if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
5227            var target = manipulationTarget(this, elem);
5228            target.insertBefore(elem, target.firstChild);
5229          }
5230        });
5231      },
5232      before: function () {
5233        return domManip(this, arguments, function (elem) {
5234          if (this.parentNode) {
5235            this.parentNode.insertBefore(elem, this);
5236          }
5237        });
5238      },
5239      after: function () {
5240        return domManip(this, arguments, function (elem) {
5241          if (this.parentNode) {
5242            this.parentNode.insertBefore(elem, this.nextSibling);
5243          }
5244        });
5245      },
5246      empty: function () {
5247        var elem,
5248            i = 0;
5249
5250        for (; (elem = this[i]) != null; i++) {
5251          if (elem.nodeType === 1) {
5252            // Prevent memory leaks
5253            jQuery.cleanData(getAll(elem, false)); // Remove any remaining nodes
5254
5255            elem.textContent = "";
5256          }
5257        }
5258
5259        return this;
5260      },
5261      clone: function (dataAndEvents, deepDataAndEvents) {
5262        dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5263        deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5264        return this.map(function () {
5265          return jQuery.clone(this, dataAndEvents, deepDataAndEvents);
5266        });
5267      },
5268      html: function (value) {
5269        return access(this, function (value) {
5270          var elem = this[0] || {},
5271              i = 0,
5272              l = this.length;
5273
5274          if (value === undefined && elem.nodeType === 1) {
5275            return elem.innerHTML;
5276          } // See if we can take a shortcut and just use innerHTML
5277
5278
5279          if (typeof value === "string" && !rnoInnerhtml.test(value) && !wrapMap[
vendor: 4,584 bytes, lines 5279-5403
5279(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {
5280            value = jQuery.htmlPrefilter(value);
5281
5282            try {
5283              for (; i < l; i++) {
5284                elem = this[i] || {}; // Remove element nodes and prevent memory leaks
5285
5286                if (elem.nodeType === 1) {
5287                  jQuery.cleanData(getAll(elem, false));
5288                  elem.innerHTML = value;
5289                }
5290              }
5291
5292              elem = 0; // If using innerHTML throws an exception, use the fallback method
5293            } catch (e) {}
5294          }
5295
5296          if (elem) {
5297            this.empty().append(value);
5298          }
5299        }, null, value, arguments.length);
5300      },
5301      replaceWith: function () {
5302        var ignored = []; // Make the changes, replacing each non-ignored context element with the new content
5303
5304        return domManip(this, arguments, function (elem) {
5305          var parent = this.parentNode;
5306
5307          if (jQuery.inArray(this, ignored) < 0) {
5308            jQuery.cleanData(getAll(this));
5309
5310            if (parent) {
5311              parent.replaceChild(elem, this);
5312            }
5313          } // Force callback invocation
5314
5315        }, ignored);
5316      }
5317    });
5318    jQuery.each({
5319      appendTo: "append",
5320      prependTo: "prepend",
5321      insertBefore: "before",
5322      insertAfter: "after",
5323      replaceAll: "replaceWith"
5324    }, function (name, original) {
5325      jQuery.fn[name] = function (selector) {
5326        var elems,
5327            ret = [],
5328            insert = jQuery(selector),
5329            last = insert.length - 1,
5330            i = 0;
5331
5332        for (; i <= last; i++) {
5333          elems = i === last ? this : this.clone(true);
5334          jQuery(insert[i])[original](elems); // Support: Android <=4.0 only, PhantomJS 1 only
5335          // .get() because push.apply(_, arraylike) throws on ancient WebKit
5336
5337          push$1.apply(ret, elems.get());
5338        }
5339
5340        return this.pushStack(ret);
5341      };
5342    });
5343    var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i");
5344
5345    var getStyles = function (elem) {
5346      // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
5347      // IE throws on elements created in popups
5348      // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
5349      var view = elem.ownerDocument.defaultView;
5350
5351      if (!view || !view.opener) {
5352        view = window;
5353      }
5354
5355      return view.getComputedStyle(elem);
5356    };
5357
5358    var rboxStyle = new RegExp(cssExpand.join("|"), "i");
5359
5360    (function () {
5361      // Executing both pixelPosition & boxSizingReliable tests require only one layout
5362      // so they're executed at the same time to save the second computation.
5363      function computeStyleTests() {
5364        // This is a singleton, we need to execute it only once
5365        if (!div) {
5366          return;
5367        }
5368
5369        container.style.cssText = "position:absolute;left:-11111px;width:60px;" + "margin-top:1px;padding:0;border:0";
5370        div.style.cssText = "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + "margin:auto;border:1px;padding:1px;" + "width:60%;top:1%";
5371        documentElement.appendChild(container).appendChild(div);
5372        var divStyle = window.getComputedStyle(div);
5373        pixelPositionVal = divStyle.top !== "1%"; // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
5374
5375        reliableMarginLeftVal = roundPixelMeasures(divStyle.marginLeft) === 12; // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
5376        // Some styles come back with percentage values, even though they shouldn't
5377
5378        div.style.right = "60%";
5379        pixelBoxStylesVal = roundPixelMeasures(divStyle.right) === 36; // Support: IE 9 - 11 only
5380        // Detect misreporting of content dimensions for box-sizing:border-box elements
5381
5382        boxSizingReliableVal = roundPixelMeasures(divStyle.width) === 36; // Support: IE 9 only
5383        // Detect overflow:scroll screwiness (gh-3699)
5384
5385        div.style.position = "absolute";
5386        scrollboxSizeVal = div.offsetWidth === 36 || "absolute";
5387        documentElement.removeChild(container); // Nullify the div so it wouldn't be stored in the memory and
5388        // it will also be a sign that checks already performed
5389
5390        div = null;
5391      }
5392
5393      function roundPixelMeasures(measure) {
5394        return Math.round(parseFloat(measure));
5395      }
5396
5397      var pixelPositionVal,
5398          boxSizingReliableVal,
5399          scrollboxSizeVal,
5400          pixelBoxStylesVal,
5401          reliableMarginLeftVal,
5402          container = document$2.createElement("div"),
5403          div = document$2.createElement("div");
5403 // Finish early in limited (non-browser) environments
5404
5405      if (!div.style) {
5406        return;
5407      } // Support: IE <=9 - 11 only
5408      // Style of cloned element affects source element cloned (#8908)
5409
5410
5411      div.style.backgroundClip = "content-box";
5412      div.cloneNode(true).style.backgroundClip = "";
5413      support.clearCloneStyle = div.style.backgroundClip === "content-box";
5414      jQuery.extend(support, {
5415        boxSizingReliable: function () {
5416          computeStyleTests();
5417          return boxSizingReliableVal;
5418        },
5419        pixelBoxStyles: function () {
5420          computeStyleTests();
5421          return pixelBoxStylesVal;
5422        },
5423        pixelPosition: function () {
5424          computeStyleTests();
5425          return pixelPositionVal;
5426        },
5427        reliableMarginLeft: function () {
5428          computeStyleTests();
5429          return reliableMarginLeftVal;
5430        },
5431        scrollboxSize: function () {
5432          computeStyleTests();
5433          return scrollboxSizeVal;
5434        }
5435      });
5436    })();
5437
5438    function curCSS(elem, name, computed) {
5439      var width,
5440          minWidth,
5441          maxWidth,
5442          ret,
5443          // Support: Firefox 51+
5444      // Retrieving style before computed somehow
5445      // fixes an issue with getting wrong values
5446      // on detached elements
5447      style = elem.style;
5448      computed = computed || getStyles(elem); // getPropertyValue is needed for:
5449      //   .css('filter') (IE 9 only, #12537)
5450      //   .css('--customProperty) (#3144)
5451
5452      if (computed) {
5453        ret = computed.getPropertyValue(name) || computed[name];
5454
5455        if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) {
5456          ret = jQuery.style(elem, name);
5457        } // A tribute to the "awesome hack by Dean Edwards"
5458        // Android Browser returns percentage for some values,
5459        // but width seems to be reliably pixels.
5460        // This is against the CSSOM draft spec:
5461        // https://drafts.csswg.org/cssom/#resolved-values
5462
5463
5464        if (!support.pixelBoxStyles() && rnumnonpx.test(ret) && rboxStyle.test(name)) {
5465          // Remember the original values
5466          width = style.width;
5467          minWidth = style.minWidth;
5468          maxWidth = style.maxWidth; // Put in the new values to get a computed value out
5469
5470          style.minWidth = style.maxWidth = style.width = ret;
5471          ret = computed.width; // Revert the changed values
5472
5473          style.width = width;
5474          style.minWidth = minWidth;
5475          style.maxWidth = maxWidth;
5476        }
5477      }
5478
5479      return ret !== undefined ? // Support: IE <=9 - 11 only
5480      // IE returns zIndex value as an integer.
5481      ret + "" : ret;
5482    }
5483
5484    function addGetHookIf(conditionFn, hookFn) {
5485      // Define the hook, we'll check on the first run if it's really needed.
5486      return {
5487        get: function () {
5488          if (conditionFn()) {
5489            // Hook not needed (or it's not possible to use it due
5490            // to missing dependency), remove it.
5491            delete this.get;
5492            return;
5493          } // Hook needed; redefine it so that the support test is not executed again.
5494
5495
5496          return (this.get = hookFn).apply(this, arguments);
5497        }
5498      };
5499    }
5500
5501    var // Swappable if display is none or starts with table
5502    // except "table", "table-cell", or "table-caption"
5503    // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
5504    rdisplayswap = /^(none|table(?!-c[ea]).+)/,
5505        rcustomProp = /^--/,
5506        cssShow = {
5507      position: "absolute",
5508      visibility: "hidden",
5509      display: "block"
5510    },
5511        cssNormalTransform = {
5512      letterSpacing: "0",
5513      fontWeight: "400"
5514    },
5515        cssPrefixes = ["Webkit", "Moz", "ms"],
5516        emptyStyle = document$2.createElement("div").style; // Return a css property mapped to a potentially vendor prefixed property
5517
5518    function vendorPropName(name) {
5519      // Shortcut for names that are not vendor prefixed
5520      if (name in emptyStyle) {
5521        return name;
5522      } // Check for vendor prefixed names
5523
5524
5525      var capName = name[0].toUpperCase() + name.slice(1),
5526          i = cssPrefixes.length;
5527
5528      while (i--) {
5529        name = cssPrefixes[i] + capName;
5530
5531        if (name in emptyStyle) {
5532          return name;
5533        }
5534      }
5535    } // Return a property mapped along what jQuery.cssProps suggests or to
5536    // a vendor prefixed property.
5537
5538
5539    function finalPropName(name) {
5540      var ret = jQuery.cssProps[name];
5541
5542      if (!ret) {
5543        ret = jQuery.cssProps[name] = vendorPropName(name) || name;
5544      }
5545
5546      return ret;
5547    }
5548
5549    function setPositiveNumber(elem, value, subtract) {
5550      // Any relative (+/-) values have already been
5551      // normalized at this point
5552      var matches = rcssNum.exec(value);
5553      return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks
5554      Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") : value;
5555    }
5556
5557    function boxModelAdjustment(elem, dimension, box, isBorderBox, styles, computedVal) {
5558      var i = dimension === "width" ? 1 : 0,
5559          extra = 0,
5560          delta = 0; // Adjustment may not be necessary
5561
5562      if (box === (isBorderBox ? "border" : "content")) {
5563        return 0;
5564      }
5565
5566      for (; i < 4; i += 2) {
5567        // Both box models exclude margin
5568        if (box === "margin") {
5569          delta += jQuery.css(elem, box + cssExpand[i], true, styles);
5570        } // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
5571
5572
5573        if (!isBorderBox) {
5574          // Add padding
5575          delta += jQuery.css(elem, "padding" + cssExpand[i], true, styles); // For "border" or "margin", add border
5576
5577          if (box !== "padding") {
5578            delta += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles); // But still keep track of it otherwise
5579          } else {
5580            extra += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
5581          } // If we get here with a border-box (content + padding + border), we're seeking "content" or
5582          // "padding" or "margin"
5583
5584        } else {
5585          // For "content", subtract padding
5586          if (box === "content") {
5587            delta -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
5588          } // For "content" or "padding", subtract border
5589
5590
5591          if (box !== "margin") {
5592            delta -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
5593          }
5594        }
5595      } // Account for positive content-box scroll gutter when requested by providing computedVal
5596
5597
5598      if (!isBorderBox && computedVal >= 0) {
5599        // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
5600        // Assuming integer scroll gutter, subtract the rest and round down
5601        delta += Math.max(0, Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - computedVal - delta - extra - 0.5));
5602      }
5603
5604      return delta;
5605    }
5606
5607    function getWidthOrHeight(elem, dimension, extra) {
5608      // Start with computed style
5609      var styles = getStyles(elem),
5610          val = curCSS(elem, dimension, styles),
5611          isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box",
5612          valueIsBorderBox = isBorderBox;
5612 // Support: Firefox <=54
5613      // Return a confounding non-pixel value or feign ignorance, as appropriate.
5614
5615      if (rnumnonpx.test(val)) {
5616        if (!extra) {
5617          return val;
5618        }
5619
5620        val = "auto";
5621      } // Check for style in case a browser which returns unreliable values
5622      // for getComputedStyle silently falls back to the reliable elem.style
5623
5624
5625      valueIsBorderBox = valueIsBorderBox && (support.boxSizingReliable() || val === elem.style[dimension]); // Fall back to offsetWidth/offsetHeight when value is "auto"
5626      // This happens for inline elements with no explicit setting (gh-3571)
5627      // Support: Android <=4.1 - 4.3 only
5628      // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
5629
5630      if (val === "auto" || !parseFloat(val) && jQuery.css(elem, "display", false, styles) === "inline") {
5631        val = elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)]; // offsetWidth/offsetHeight provide border-box values
5632
5633        valueIsBorderBox = true;
5634      } // Normalize "" and auto
5635
5636
5637      val = parseFloat(val) || 0; // Adjust for the element's box model
5638
5639      return val + boxModelAdjustment(elem, dimension, extra || (isBorderBox ? "border" : "content"), valueIsBorderBox, styles, // Provide the current computed size to request scroll gutter calculation (gh-3589)
5640      val) + "px";
5641    }
5642
5643    jQuery.extend({
5644      // Add in style property hooks for overriding the default
5645      // behavior of getting and setting a style property
5646      cssHooks: {
5647        opacity: {
5648          get: function (elem, computed) {
5649            if (computed) {
5650              // We should always get a number back from opacity
5651              var ret = curCSS(elem, "opacity");
5652              return ret === "" ? "1" : ret;
5653            }
5654          }
5655        }
5656      },
5657      // Don't automatically add "px" to these possibly-unitless properties
5658      cssNumber: {
5659        "animationIterationCount": true,
5660        "columnCount": true,
5661        "fillOpacity": true,
5662        "flexGrow": true,
5663        "flexShrink": true,
5664        "fontWeight": true,
5665        "lineHeight": true,
5666        "opacity": true,
5667        "order": true,
5668        "orphans": true,
5669        "widows": true,
5670        "zIndex": true,
5671        "zoom": true
5672      },
5673      // Add in properties whose names you wish to fix before
5674      // setting or getting the value
5675      cssProps: {},
5676      // Get and set the style property on a DOM Node
5677      style: function (elem, name, value, extra) {
5678        // Don't set styles on text and comment nodes
5679        if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
5680          return;
5681        } // Make sure that we're working with the right name
5682
5683
5684        var ret,
5685            type,
5686            hooks,
5687            origName = camelCase(name),
5688            isCustomProp = rcustomProp.test(name),
5689            style = elem.style; // Make sure that we're working with the right name. We don't
5690        // want to query the value if it is a CSS custom property
5691        // since they are user-defined.
5692
5693        if (!isCustomProp) {
5694          name = finalPropName(origName);
5695        } // Gets hook for the prefixed version, then unprefixed version
5696
5697
5698        hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; // Check if we're setting a value
5699
5700        if (value !== undefined) {
5701          type = typeof value; // Convert "+=" or "-=" to relative numbers (#7345)
5702
5703          if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) {
5704            value = adjustCSS(elem, name, ret); // Fixes bug #9237
5705
5706            type = "number";
5707          } // Make sure that null and NaN values aren't set (#7116)
5708
5709
5710          if (value == null || value !== value) {
5711            return;
5712          } // If a number was passed in, add the unit (except for certain CSS properties)
5713
5714
5715          if (type === "number") {
5716            value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px");
5717          } // background-* props affect original clone's values
5718
5719
5720          if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
5721            style[name] = "inherit";
5722          } // If a hook was provided, use that value, otherwise just set the specified value
5723
5724
5725          if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) {
5726            if (isCustomProp) {
5727              style.setProperty(name, value);
5728            } else {
5729              style[name] = value;
5730            }
5731          }
5732        } else {
5733          // If a hook was provided get the non-computed value from there
5734          if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) {
5735            return ret;
5736          } // Otherwise just get the value from the style object
5737
5738
5739          return style[name];
5740        }
5741      },
5742      css: function (elem, name, extra, styles) {
5743        var val,
5744            num,
5745            hooks,
5746            origName = camelCase(name),
5747            isCustomProp = rcustomProp.test(name); // Make sure that we're working with the right name. We don't
5748        // want to modify the value if it is a CSS custom property
5749        // since they are user-defined.
5750
5751        if (!isCustomProp) {
5752          name = finalPropName(origName);
5753        } // Try prefixed name followed by the unprefixed name
5754
5755
5756        hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; // If a hook was provided get the computed value from there
5757
5758        if (hooks && "get" in hooks) {
5759          val = hooks.get(elem, true, extra);
5760        } // Otherwise, if a way to get the computed value exists, use that
5761
5762
5763        if (val === undefined) {
5764          val = curCSS(elem, name, styles);
5765        } // Convert "normal" to computed value
5766
5767
5768        if (val === "normal" && name in cssNormalTransform) {
5769          val = cssNormalTransform[name];
5770        } // Make numeric if forced or a qualifier was provided and val looks numeric
5771
5772
5773        if (extra === "" || extra) {
5774          num = parseFloat(val);
5775          return extra === true || isFinite(num) ? num || 0 : val;
5776        }
5777
5778        return val;
5779      }
5780    });
5781    jQuery.each(["height", "width"], function (i, dimension) {
5782      jQuery.cssHooks[dimension] = {
5783        get: function (elem, computed, extra) {
5784          if (computed) {
5785            // Certain elements can have dimension info if we invisibly show them
5786            // but it must have a current display style that would benefit
vendor: 9,588 bytes, lines 5787-6070
5787            return rdisplayswap.test(jQuery.css(elem, "display")) && ( // Support: Safari 8+
5788            // Table columns in Safari have non-zero offsetWidth & zero
5789            // getBoundingClientRect().width unless display is changed.
5790            // Support: IE <=11 only
5791            // Running getBoundingClientRect on a disconnected node
5792            // in IE throws an error.
5793            !elem.getClientRects().length || !elem.getBoundingClientRect().width) ? swap(elem, cssShow, function () {
5794              return getWidthOrHeight(elem, dimension, extra);
5795            }) : getWidthOrHeight(elem, dimension, extra);
5796          }
5797        },
5798        set: function (elem, value, extra) {
5799          var matches,
5800              styles = getStyles(elem),
5801              isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box",
5802              subtract = extra && boxModelAdjustment(elem, dimension, extra, isBorderBox, styles); // Account for unreliable border-box dimensions by comparing offset* to computed and
5803          // faking a content-box to get border and padding (gh-3699)
5804
5805          if (isBorderBox && support.scrollboxSize() === styles.position) {
5806            subtract -= Math.ceil(elem["offset" + dimension[0].toUpperCase() + dimension.slice(1)] - parseFloat(styles[dimension]) - boxModelAdjustment(elem, dimension, "border", false, styles) - 0.5);
5807          } // Convert to pixels if value adjustment is needed
5808
5809
5810          if (subtract && (matches = rcssNum.exec(value)) && (matches[3] || "px") !== "px") {
5811            elem.style[dimension] = value;
5812            value = jQuery.css(elem, dimension);
5813          }
5814
5815          return setPositiveNumber(elem, value, subtract);
5816        }
5817      };
5818    });
5819    jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) {
5820      if (computed) {
5821        return (parseFloat(curCSS(elem, "marginLeft")) || elem.getBoundingClientRect().left - swap(elem, {
5822          marginLeft: 0
5823        }, function () {
5824          return elem.getBoundingClientRect().left;
5825        })) + "px";
5826      }
5827    }); // These hooks are used by animate to expand properties
5828
5829    jQuery.each({
5830      margin: "",
5831      padding: "",
5832      border: "Width"
5833    }, function (prefix, suffix) {
5834      jQuery.cssHooks[prefix + suffix] = {
5835        expand: function (value) {
5836          var i = 0,
5837              expanded = {},
5838              // Assumes a single number if not a string
5839          parts = typeof value === "string" ? value.split(" ") : [value];
5840
5841          for (; i < 4; i++) {
5842            expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0];
5843          }
5844
5845          return expanded;
5846        }
5847      };
5848
5849      if (prefix !== "margin") {
5850        jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
5851      }
5852    });
5853    jQuery.fn.extend({
5854      css: function (name, value) {
5855        return access(this, function (elem, name, value) {
5856          var styles,
5857              len,
5858              map = {},
5859              i = 0;
5860
5861          if (Array.isArray(name)) {
5862            styles = getStyles(elem);
5863            len = name.length;
5864
5865            for (; i < len; i++) {
5866              map[name[i]] = jQuery.css(elem, name[i], false, styles);
5867            }
5868
5869            return map;
5870          }
5871
5872          return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name);
5873        }, name, value, arguments.length > 1);
5874      }
5875    }); // Based off of the plugin by Clint Helfers, with permission.
5876    // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
5877
5878    jQuery.fn.delay = function (time, type) {
5879      time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
5880      type = type || "fx";
5881      return this.queue(type, function (next, hooks) {
5882        var timeout = window.setTimeout(next, time);
5883
5884        hooks.stop = function () {
5885          window.clearTimeout(timeout);
5886        };
5887      });
5888    };
5889
5890    (function () {
5891      var input = document$2.createElement("input"),
5892          select = document$2.createElement("select"),
5893          opt = select.appendChild(document$2.createElement("option"));
5894      input.type = "checkbox"; // Support: Android <=4.3 only
5895      // Default value for a checkbox should be "on"
5896
5897      support.checkOn = input.value !== ""; // Support: IE <=11 only
5898      // Must access selectedIndex to make default options select
5899
5900      support.optSelected = opt.selected; // Support: IE <=11 only
5901      // An input loses its value after becoming a radio
5902
5903      input = document$2.createElement("input");
5904      input.value = "t";
5905      input.type = "radio";
5906      support.radioValue = input.value === "t";
5907    })();
5908
5909    var boolHook,
5910        attrHandle = jQuery.expr.attrHandle;
5911    jQuery.fn.extend({
5912      attr: function (name, value) {
5913        return access(this, jQuery.attr, name, value, arguments.length > 1);
5914      },
5915      removeAttr: function (name) {
5916        return this.each(function () {
5917          jQuery.removeAttr(this, name);
5918        });
5919      }
5920    });
5921    jQuery.extend({
5922      attr: function (elem, name, value) {
5923        var ret,
5924            hooks,
5925            nType = elem.nodeType; // Don't get/set attributes on text, comment and attribute nodes
5926
5927        if (nType === 3 || nType === 8 || nType === 2) {
5928          return;
5929        } // Fallback to prop when attributes are not supported
5930
5931
5932        if (typeof elem.getAttribute === "undefined") {
5933          return jQuery.prop(elem, name, value);
5934        } // Attribute hooks are determined by the lowercase version
5935        // Grab necessary hook if one is defined
5936
5937
5938        if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
5939          hooks = jQuery.attrHooks[name.toLowerCase()] || (jQuery.expr.match.bool.test(name) ? boolHook : undefined);
5940        }
5941
5942        if (value !== undefined) {
5943          if (value === null) {
5944            jQuery.removeAttr(elem, name);
5945            return;
5946          }
5947
5948          if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
5949            return ret;
5950          }
5951
5952          elem.setAttribute(name, value + "");
5953          return value;
5954        }
5955
5956        if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
5957          return ret;
5958        }
5959
5960        ret = jQuery.find.attr(elem, name); // Non-existent attributes return null, we normalize to undefined
5961
5962        return ret == null ? undefined : ret;
5963      },
5964      attrHooks: {
5965        type: {
5966          set: function (elem, value) {
5967            if (!support.radioValue && value === "radio" && nodeName(elem, "input")) {
5968              var val = elem.value;
5969              elem.setAttribute("type", value);
5970
5971              if (val) {
5972                elem.value = val;
5973              }
5974
5975              return value;
5976            }
5977          }
5978        }
5979      },
5980      removeAttr: function (elem, value) {
5981        var name,
5982            i = 0,
5983            // Attribute names can contain non-HTML whitespace characters
5984        // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
5985        attrNames = value && value.match(rnothtmlwhite);
5986
5987        if (attrNames && elem.nodeType === 1) {
5988          while (name = attrNames[i++]) {
5989            elem.removeAttribute(name);
5990          }
5991        }
5992      }
5993    }); // Hooks for boolean attributes
5994
5995    boolHook = {
5996      set: function (elem, value, name) {
5997        if (value === false) {
5998          // Remove boolean attributes when set to false
5999          jQuery.removeAttr(elem, name);
6000        } else {
6001          elem.setAttribute(name, name);
6002        }
6003
6004        return name;
6005      }
6006    };
6007    jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) {
6008      var getter = attrHandle[name] || jQuery.find.attr;
6009
6010      attrHandle[name] = function (elem, name, isXML) {
6011        var ret,
6012            handle,
6013            lowercaseName = name.toLowerCase();
6014
6015        if (!isXML) {
6016          // Avoid an infinite loop by temporarily removing this function from the getter
6017          handle = attrHandle[lowercaseName];
6018          attrHandle[lowercaseName] = ret;
6019          ret = getter(elem, name, isXML) != null ? lowercaseName : null;
6020          attrHandle[lowercaseName] = handle;
6021        }
6022
6023        return ret;
6024      };
6025    });
6026    var rfocusable = /^(?:input|select|textarea|button)$/i,
6027        rclickable = /^(?:a|area)$/i;
6028    jQuery.fn.extend({
6029      prop: function (name, value) {
6030        return access(this, jQuery.prop, name, value, arguments.length > 1);
6031      },
6032      removeProp: function (name) {
6033        return this.each(function () {
6034          delete this[jQuery.propFix[name] || name];
6035        });
6036      }
6037    });
6038    jQuery.extend({
6039      prop: function (elem, name, value) {
6040        var ret,
6041            hooks,
6042            nType = elem.nodeType; // Don't get/set properties on text, comment and attribute nodes
6043
6044        if (nType === 3 || nType === 8 || nType === 2) {
6045          return;
6046        }
6047
6048        if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
6049          // Fix name and attach hooks
6050          name = jQuery.propFix[name] || name;
6051          hooks = jQuery.propHooks[name];
6052        }
6053
6054        if (value !== undefined) {
6055          if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
6056            return ret;
6057          }
6058
6059          return elem[name] = value;
6060        }
6061
6062        if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
6063          return ret;
6064        }
6065
6066        return elem[name];
6067      },
6068      propHooks: {
6069        tabIndex: {
6070          get: function (elem) {
6071            // Support: IE <=9 - 11 only
6072            // elem.tabIndex doesn't always return the
6073            // correct value when it hasn't been explicitly set
6074            // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
6075            // Use proper attribute retrieval(#12072)
6076            var tabindex = jQuery.find.attr(elem, "tabindex");
6077
6078            if (tabindex) {
6079              return parseInt(tabindex, 10);
6080            }
6081
6082            if (rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href) {
6083              return 0;
6084            }
6085
6086            return -1;
6087          }
6088        }
6089      },
6090      propFix: {
6091        "for": "htmlFor",
6092        "class": "className"
6093      }
6094    }); // Support: IE <=11 only
6095    // Accessing the selectedIndex property
6096    // forces the browser to respect setting selected
6097    // on the option
6098    // The getter ensures a default option is selected
6099    // when in an optgroup
6100    // eslint rule "no-unused-expressions" is disabled for this code
6101    // since it considers such accessions noop
6102
6103    if (!support.optSelected) {
6104      jQuery.propHooks.selected = {
6105        get: function (elem) {
6106          /* eslint no-unused-expressions: "off" */
6107          var parent = elem.parentNode;
6108
6109          if (parent && parent.parentNode) {
6110            parent.parentNode.selectedIndex;
6111          }
6112
6113          return null;
6114        },
6115        set: function (elem) {
6116          /* eslint no-unused-expressions: "off" */
6117          var parent = elem.parentNode;
6118
6119          if (parent) {
6120            parent.selectedIndex;
6121
6122            if (parent.parentNode) {
6123              parent.parentNode.selectedIndex;
6124            }
6125          }
6126        }
6127      };
6128    }
6129
6130    jQuery.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () {
6131      jQuery.propFix[this.toLowerCase()] = this;
6132    }); // Strip and collapse whitespace according to HTML spec
6133    // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
6134
6135    function stripAndCollapse(value) {
6136      var tokens = value.match(rnothtmlwhite) || [];
6137      return tokens.join(" ");
6138    }
6139
6140    function getClass(elem) {
6141      return elem.getAttribute && elem.getAttribute("class") || "";
6142    }
6143
6144    function classesToArray(value) {
6145      if (Array.isArray(value)) {
6146        return value;
6147      }
6148
6149      if (typeof value === "string") {
6150        return value.match(rnothtmlwhite) || [];
6151      }
6152
6153      return [];
6154    }
6155
6156    jQuery.fn.extend({
6157      addClass: function (value) {
6158        var classes,
6159            elem,
6160            cur,
6161            curValue,
6162            clazz,
6163            j,
6164            finalValue,
6165            i = 0;
6166
6167        if (isFunction(value)) {
6168          return this.each(function (j) {
6169            jQuery(this).addClass(value.call(this, j, getClass(this)));
6170          });
6171        }
6172
6173        classes = classesToArray(value);
6174
6175        if (classes.length) {
6176          while (elem = this[i++]) {
6177            curValue = getClass(elem);
6178            cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " ";
6179
6180            if (cur) {
6181              j = 0;
6182
6183              while (clazz = classes[j++]) {
6184                if (cur.indexOf(" " + clazz + " ") < 0) {
6185                  cur += clazz + " ";
6186                }
6187              } // Only assign if different to avoid unneeded rendering.
6188
6189
6190              finalValue = stripAndCollapse(cur);
6191
6192              if (curValue !== finalValue) {
6193                elem.setAttribute("class", finalValue);
6194              }
6195            }
6196          }
6197        }
6198
6199        return this;
6200      },
6201      removeClass: function (value) {
6202        var classes,
6203            elem,
6204            cur,
6205            curValue,
6206            clazz,
6207            j,
6208            finalValue,
6209            i = 0;
6210
6211        if (isFunction(value)) {
6212          return this.each(function (j) {
6213            jQuery(this).removeClass(value.call(this, j, getClass(this)));
6214          });
6215        }
6216
6217        if (!arguments.length) {
6218          return this.attr("class", "");
6219        }
6220
6221        classes = classesToArray(value);
6222
6223        if (classes.length) {
6224          while (elem = this[i++]) {
6225            curValue = getClass(elem); // This expression is here for better compressibility (see addClass)
6226
6227            cur = elem.nodeType === 1 && " " + stripAndCollapse(curValue) + " ";
6228
6229            if (cur) {
6230              j = 0;
6231
6232              while (clazz = classes[j++]) {
6233                // Remove *all* instances
6234                while (cur.indexOf(" " + clazz + " ") > -1) {
6235                  cur = cur.replace(" " + clazz + " ", " ");
6236                }
6237              } // Only assign if different to avoid unneeded rendering.
6238
6239
6240              finalValue = stripAndCollapse(cur);
6241
6242              if (curValue !== finalValue) {
6243                elem.setAttribute("class", finalValue);
6244              }
6245            }
6246          }
6247        }
6248
6249        return this;
6250      },
6251      toggleClass: function (value, stateVal) {
6252        var type = typeof value,
6253            isValidValue = type === "string" || Array.isArray(value);
6254
6255        if (typeof stateVal === "boolean" && isValidValue) {
6256          return stateVal ? this.addClass(value) : this.removeClass(value);
6257        }
6258
6259        if (isFunction(value)) {
6260          return this.each(function (i) {
6261            jQuery(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal);
6262          });
6263        }
6264
6265        return this.each(function () {
6266          var className, i, self, classNames;
6267
6268          if (isValidValue) {
6269            // Toggle individual class names
6270            i = 0;
6271            self = jQuery(this);
6272            classNames = classesToArray(value);
6273
6274            while (className = classNames[i++]) {
6275              // Check each className given, space separated list
6276              if (self.hasClass(className)) {
6277                self.removeClass(className);
6278              } else {
6279                self.addClass(className);
6280              }
6281            } // Toggle whole class name
6282
6283          } else if (value === undefined || type === "boolean") {
6284            className = getClass(this);
6285
6286            if (className) {
6287              // Store className if set
6288              dataPriv.set(this, "__className__", className);
6289            } // If the element has a class name or if we're passed `false`,
6290            // then remove the whole classname (if there was one, the above saved it).
6291            // Otherwise bring back whatever was previously saved (if anything),
6292            // falling back to the empty string if nothing was stored.
6293
6294
6295            if (this.setAttribute) {
6296              this.setAttribute("class", className || value === false ? "" : dataPriv.get(this, "__className__") || "");
6297            }
6298          }
6299        });
6300      },
6301      hasClass: function (selector) {
6302        var className,
6303            elem,
6304            i = 0;
6305        className = " " + selector + " ";
6306
6307        while (elem = this[i++]) {
6308          if (elem.nodeType === 1 && (" " + stripAndCollapse(getClass(elem)) + " ").indexOf(className) > -1) {
6309            return true;
6310          }
6311        }
6312
6313        return false;
6314      }
6315    });
6316    var rreturn = /\r/g;
6317    jQuery.fn.extend({
6318      val: function (value) {
6319        var hooks,
6320            ret,
6321            valueIsFunction,
6322            elem = this[0];
6323
6324        if (!arguments.length) {
6325          if (elem) {
6326            hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()];
6327
6328            if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) {
6329              return ret;
6330            }
6331
6332            ret = elem.value; // Handle most common string cases
6333
6334            if (typeof ret === "string") {
6335              return ret.replace(rreturn, "");
6336            } // Handle cases where value is null/undef or number
6337
6338
6339            return ret == null ? "" : ret;
6340          }
6341
6342          return;
6343        }
6344
6345        valueIsFunction = isFunction(value);
6346        return this.each(function (i) {
6347          var val;
6348
6349          if (this.nodeType !== 1) {
6350            return;
6351          }
6352
6353          if (valueIsFunction) {
6354            val = value.call(this, i, jQuery(this).val());
6355          } else {
6356            val = value;
6357          } // Treat null/undefined as ""; convert numbers to string
6358
6359
6360          if (val == null) {
6361            val = "";
6362          } else if (typeof val === "number") {
6363            val += "";
6364          } else if (Array.isArray(val)) {
6365            val = jQuery.map(val, function (value) {
6366              return value == null ? "" : value + "";
6367            });
6368          }
6369
6370          hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()]; // If set returns undefined, fall back to normal setting
6371
6372          if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
6373            this.value = val;
6374          }
6375        });
6376      }
6377    });
6378    jQuery.extend({
6379      valHooks: {
6380        option: {
6381          get: function (elem) {
6382            var val = jQuery.find.attr(elem, "value");
6383            return val != null ? val : // Support: IE <=10 - 11 only
6384            // option.text throws exceptions (#14686, #14858)
6385            // Strip and collapse whitespace
6386            // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
vendor: 8,494 bytes, lines 6387-6640
6387            stripAndCollapse(jQuery.text(elem));
6388          }
6389        },
6390        select: {
6391          get: function (elem) {
6392            var value,
6393                option,
6394                i,
6395                options = elem.options,
6396                index = elem.selectedIndex,
6397                one = elem.type === "select-one",
6398                values = one ? null : [],
6399                max = one ? index + 1 : options.length;
6400
6401            if (index < 0) {
6402              i = max;
6403            } else {
6404              i = one ? index : 0;
6405            } // Loop through all the selected options
6406
6407
6408            for (; i < max; i++) {
6409              option = options[i]; // Support: IE <=9 only
6410              // IE8-9 doesn't update selected after form reset (#2551)
6411
6412              if ((option.selected || i === index) && // Don't return options that are disabled or in a disabled optgroup
6413              !option.disabled && (!option.parentNode.disabled || !nodeName(option.parentNode, "optgroup"))) {
6414                // Get the specific value for the option
6415                value = jQuery(option).val(); // We don't need an array for one selects
6416
6417                if (one) {
6418                  return value;
6419                } // Multi-Selects return an array
6420
6421
6422                values.push(value);
6423              }
6424            }
6425
6426            return values;
6427          },
6428          set: function (elem, value) {
6429            var optionSet,
6430                option,
6431                options = elem.options,
6432                values = jQuery.makeArray(value),
6433                i = options.length;
6434
6435            while (i--) {
6436              option = options[i];
6437              /* eslint-disable no-cond-assign */
6438
6439              if (option.selected = jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) {
6440                optionSet = true;
6441              }
6442              /* eslint-enable no-cond-assign */
6443
6444            } // Force browsers to behave consistently when non-matching value is set
6445
6446
6447            if (!optionSet) {
6448              elem.selectedIndex = -1;
6449            }
6450
6451            return values;
6452          }
6453        }
6454      }
6455    }); // Radios and checkboxes getter/setter
6456
6457    jQuery.each(["radio", "checkbox"], function () {
6458      jQuery.valHooks[this] = {
6459        set: function (elem, value) {
6460          if (Array.isArray(value)) {
6461            return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1;
6462          }
6463        }
6464      };
6465
6466      if (!support.checkOn) {
6467        jQuery.valHooks[this].get = function (elem) {
6468          return elem.getAttribute("value") === null ? "on" : elem.value;
6469        };
6470      }
6471    }); // Return jQuery for attributes-only inclusion
6472
6473    support.focusin = "onfocusin" in window;
6474
6475    var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
6476        stopPropagationCallback = function (e) {
6477      e.stopPropagation();
6478    };
6479
6480    jQuery.extend(jQuery.event, {
6481      trigger: function (event, data, elem, onlyHandlers) {
6482        var i,
6483            cur,
6484            tmp,
6485            bubbleType,
6486            ontype,
6487            handle,
6488            special,
6489            lastElement,
6490            eventPath = [elem || document$2],
6491            type = hasOwn.call(event, "type") ? event.type : event,
6492            namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
6493        cur = lastElement = tmp = elem = elem || document$2; // Don't do events on text and comment nodes
6494
6495        if (elem.nodeType === 3 || elem.nodeType === 8) {
6496          return;
6497        } // focus/blur morphs to focusin/out; ensure we're not firing them right now
6498
6499
6500        if (rfocusMorph.test(type + jQuery.event.triggered)) {
6501          return;
6502        }
6503
6504        if (type.indexOf(".") > -1) {
6505          // Namespaced trigger; create a regexp to match event type in handle()
6506          namespaces = type.split(".");
6507          type = namespaces.shift();
6508          namespaces.sort();
6509        }
6510
6511        ontype = type.indexOf(":") < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string
6512
6513        event = event[jQuery.expando] ? event : new jQuery.Event(type, typeof event === "object" && event); // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
6514
6515        event.isTrigger = onlyHandlers ? 2 : 3;
6516        event.namespace = namespaces.join(".");
6517        event.rnamespace = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; // Clean up the event in case it is being reused
6518
6519        event.result = undefined;
6520
6521        if (!event.target) {
6522          event.target = elem;
6523        } // Clone any incoming data and prepend the event, creating the handler arg list
6524
6525
6526        data = data == null ? [event] : jQuery.makeArray(data, [event]); // Allow special events to draw outside the lines
6527
6528        special = jQuery.event.special[type] || {};
6529
6530        if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
6531          return;
6532        } // Determine event propagation path in advance, per W3C events spec (#9951)
6533        // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
6534
6535
6536        if (!onlyHandlers && !special.noBubble && !isWindow(elem)) {
6537          bubbleType = special.delegateType || type;
6538
6539          if (!rfocusMorph.test(bubbleType + type)) {
6540            cur = cur.parentNode;
6541          }
6542
6543          for (; cur; cur = cur.parentNode) {
6544            eventPath.push(cur);
6545            tmp = cur;
6546          } // Only add window if we got to document (e.g., not plain obj or detached DOM)
6547
6548
6549          if (tmp === (elem.ownerDocument || document$2)) {
6550            eventPath.push(tmp.defaultView || tmp.parentWindow || window);
6551          }
6552        } // Fire handlers on the event path
6553
6554
6555        i = 0;
6556
6557        while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
6558          lastElement = cur;
6559          event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler
6560
6561          handle = (dataPriv.get(cur, "events") || {})[event.type] && dataPriv.get(cur, "handle");
6562
6563          if (handle) {
6564            handle.apply(cur, data);
6565          } // Native handler
6566
6567
6568          handle = ontype && cur[ontype];
6569
6570          if (handle && handle.apply && acceptData(cur)) {
6571            event.result = handle.apply(cur, data);
6572
6573            if (event.result === false) {
6574              event.preventDefault();
6575            }
6576          }
6577        }
6578
6579        event.type = type; // If nobody prevented the default action, do it now
6580
6581        if (!onlyHandlers && !event.isDefaultPrevented()) {
6582          if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) {
6583            // Call a native DOM method on the target with the same name as the event.
6584            // Don't do default actions on window, that's where global variables be (#6170)
6585            if (ontype && isFunction(elem[type]) && !isWindow(elem)) {
6586              // Don't re-trigger an onFOO event when we call its FOO() method
6587              tmp = elem[ontype];
6588
6589              if (tmp) {
6590                elem[ontype] = null;
6591              } // Prevent re-triggering of the same event, since we already bubbled it above
6592
6593
6594              jQuery.event.triggered = type;
6595
6596              if (event.isPropagationStopped()) {
6597                lastElement.addEventListener(type, stopPropagationCallback);
6598              }
6599
6600              elem[type]();
6601
6602              if (event.isPropagationStopped()) {
6603                lastElement.removeEventListener(type, stopPropagationCallback);
6604              }
6605
6606              jQuery.event.triggered = undefined;
6607
6608              if (tmp) {
6609                elem[ontype] = tmp;
6610              }
6611            }
6612          }
6613        }
6614
6615        return event.result;
6616      },
6617      // Piggyback on a donor event to simulate a different one
6618      // Used only for `focus(in | out)` events
6619      simulate: function (type, elem, event) {
6620        var e = jQuery.extend(new jQuery.Event(), event, {
6621          type: type,
6622          isSimulated: true
6623        });
6624        jQuery.event.trigger(e, null, elem);
6625      }
6626    });
6627    jQuery.fn.extend({
6628      trigger: function (type, data) {
6629        return this.each(function () {
6630          jQuery.event.trigger(type, data, this);
6631        });
6632      },
6633      triggerHandler: function (type, data) {
6634        var elem = this[0];
6635
6636        if (elem) {
6637          return jQuery.event.trigger(type, data, elem, true);
6638        }
6639      }
6640    });
vendor: 1,466 bytes, lines 6640-6677
6640 // Support: Firefox <=44
6641    // Firefox doesn't have focus(in | out) events
6642    // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
6643    //
6644    // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
6645    // focus(in | out) events fire after focus & blur events,
6646    // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
6647    // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
6648
6649    if (!support.focusin) {
6650      jQuery.each({
6651        focus: "focusin",
6652        blur: "focusout"
6653      }, function (orig, fix) {
6654        // Attach a single capturing handler on the document while someone wants focusin/focusout
6655        var handler = function (event) {
6656          jQuery.event.simulate(fix, event.target, jQuery.event.fix(event));
6657        };
6658
6659        jQuery.event.special[fix] = {
6660          setup: function () {
6661            var doc = this.ownerDocument || this,
6662                attaches = dataPriv.access(doc, fix);
6663
6664            if (!attaches) {
6665              doc.addEventListener(orig, handler, true);
6666            }
6667
6668            dataPriv.access(doc, fix, (attaches || 0) + 1);
6669          },
6670          teardown: function () {
6671            var doc = this.ownerDocument || this,
6672                attaches = dataPriv.access(doc, fix) - 1;
6673
6674            if (!attaches) {
6675              doc.removeEventListener(orig, handler, true);
6676              dataPriv.remove(doc, fix);
6677            } else {
vendor: 13,806 bytes, lines 6678-7092
6678              dataPriv.access(doc, fix, attaches);
6679            }
6680          }
6681        };
6682      });
6683    }
6684
6685    var rbracket = /\[\]$/,
6686        rCRLF = /\r?\n/g,
6687        rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
6688        rsubmittable = /^(?:input|select|textarea|keygen)/i;
6689
6690    function buildParams(prefix, obj, traditional, add) {
6691      var name;
6692
6693      if (Array.isArray(obj)) {
6694        // Serialize array item.
6695        jQuery.each(obj, function (i, v) {
6696          if (traditional || rbracket.test(prefix)) {
6697            // Treat each array item as a scalar.
6698            add(prefix, v);
6699          } else {
6700            // Item is non-scalar (array or object), encode its numeric index.
6701            buildParams(prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", v, traditional, add);
6702          }
6703        });
6704      } else if (!traditional && toType(obj) === "object") {
6705        // Serialize object item.
6706        for (name in obj) {
6707          buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
6708        }
6709      } else {
6710        // Serialize scalar item.
6711        add(prefix, obj);
6712      }
6713    } // Serialize an array of form elements or a set of
6714    // key/values into a query string
6715
6716
6717    jQuery.param = function (a, traditional) {
6718      var prefix,
6719          s = [],
6720          add = function (key, valueOrFunction) {
6721        // If value is a function, invoke it and use its return value
6722        var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction;
6723        s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value);
6724      }; // If an array was passed in, assume that it is an array of form elements.
6725
6726
6727      if (Array.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) {
6728        // Serialize the form elements
6729        jQuery.each(a, function () {
6730          add(this.name, this.value);
6731        });
6732      } else {
6733        // If traditional, encode the "old" way (the way 1.3.2 or older
6734        // did it), otherwise encode params recursively.
6735        for (prefix in a) {
6736          buildParams(prefix, a[prefix], traditional, add);
6737        }
6738      } // Return the resulting serialization
6739
6740
6741      return s.join("&");
6742    };
6743
6744    jQuery.fn.extend({
6745      serialize: function () {
6746        return jQuery.param(this.serializeArray());
6747      },
6748      serializeArray: function () {
6749        return this.map(function () {
6750          // Can add propHook for "elements" to filter or add form elements
6751          var elements = jQuery.prop(this, "elements");
6752          return elements ? jQuery.makeArray(elements) : this;
6753        }).filter(function () {
6754          var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works
6755
6756          return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type));
6757        }).map(function (i, elem) {
6758          var val = jQuery(this).val();
6759
6760          if (val == null) {
6761            return null;
6762          }
6763
6764          if (Array.isArray(val)) {
6765            return jQuery.map(val, function (val) {
6766              return {
6767                name: elem.name,
6768                value: val.replace(rCRLF, "\r\n")
6769              };
6770            });
6771          }
6772
6773          return {
6774            name: elem.name,
6775            value: val.replace(rCRLF, "\r\n")
6776          };
6777        }).get();
6778      }
6779    });
6780    jQuery.fn.extend({
6781      wrapAll: function (html) {
6782        var wrap;
6783
6784        if (this[0]) {
6785          if (isFunction(html)) {
6786            html = html.call(this[0]);
6787          } // The elements to wrap the target around
6788
6789
6790          wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);
6791
6792          if (this[0].parentNode) {
6793            wrap.insertBefore(this[0]);
6794          }
6795
6796          wrap.map(function () {
6797            var elem = this;
6798
6799            while (elem.firstElementChild) {
6800              elem = elem.firstElementChild;
6801            }
6802
6803            return elem;
6804          }).append(this);
6805        }
6806
6807        return this;
6808      },
6809      wrapInner: function (html) {
6810        if (isFunction(html)) {
6811          return this.each(function (i) {
6812            jQuery(this).wrapInner(html.call(this, i));
6813          });
6814        }
6815
6816        return this.each(function () {
6817          var self = jQuery(this),
6818              contents = self.contents();
6819
6820          if (contents.length) {
6821            contents.wrapAll(html);
6822          } else {
6823            self.append(html);
6824          }
6825        });
6826      },
6827      wrap: function (html) {
6828        var htmlIsFunction = isFunction(html);
6829        return this.each(function (i) {
6830          jQuery(this).wrapAll(htmlIsFunction ? html.call(this, i) : html);
6831        });
6832      },
6833      unwrap: function (selector) {
6834        this.parent(selector).not("body").each(function () {
6835          jQuery(this).replaceWith(this.childNodes);
6836        });
6837        return this;
6838      }
6839    });
6840
6841    jQuery.expr.pseudos.hidden = function (elem) {
6842      return !jQuery.expr.pseudos.visible(elem);
6843    };
6844
6845    jQuery.expr.pseudos.visible = function (elem) {
6846      return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
6847    }; // Support: Safari 8 only
6848    // In Safari 8 documents created via document.implementation.createHTMLDocument
6849    // collapse sibling forms: the second one becomes a child of the first one.
6850    // Because of that, this security measure has to be disabled in Safari 8.
6851    // https://bugs.webkit.org/show_bug.cgi?id=137337
6852
6853
6854    support.createHTMLDocument = function () {
6855      var body = document$2.implementation.createHTMLDocument("").body;
6856      body.innerHTML = "<form></form><form></form>";
6857      return body.childNodes.length === 2;
6858    }(); // Argument "data" should be string of html
6859    // context (optional): If specified, the fragment will be created in this context,
6860    // defaults to document
6861    // keepScripts (optional): If true, will include scripts passed in the html string
6862
6863
6864    jQuery.parseHTML = function (data, context, keepScripts) {
6865      if (typeof data !== "string") {
6866        return [];
6867      }
6868
6869      if (typeof context === "boolean") {
6870        keepScripts = context;
6871        context = false;
6872      }
6873
6874      var base, parsed, scripts;
6875
6876      if (!context) {
6877        // Stop scripts or inline event handlers from being executed immediately
6878        // by using document.implementation
6879        if (support.createHTMLDocument) {
6880          context = document$2.implementation.createHTMLDocument(""); // Set the base href for the created document
6881          // so any parsed elements with URLs
6882          // are based on the document's URL (gh-2965)
6883
6884          base = context.createElement("base");
6885          base.href = document$2.location.href;
6886          context.head.appendChild(base);
6887        } else {
6888          context = document$2;
6889        }
6890      }
6891
6892      parsed = rsingleTag.exec(data);
6893      scripts = !keepScripts && []; // Single tag
6894
6895      if (parsed) {
6896        return [context.createElement(parsed[1])];
6897      }
6898
6899      parsed = buildFragment([data], context, scripts);
6900
6901      if (scripts && scripts.length) {
6902        jQuery(scripts).remove();
6903      }
6904
6905      return jQuery.merge([], parsed.childNodes);
6906    };
6907
6908    jQuery.offset = {
6909      setOffset: function (elem, options, i) {
6910        var curPosition,
6911            curLeft,
6912            curCSSTop,
6913            curTop,
6914            curOffset,
6915            curCSSLeft,
6916            calculatePosition,
6917            position = jQuery.css(elem, "position"),
6918            curElem = jQuery(elem),
6919            props = {}; // Set position first, in-case top/left are set even on static elem
6920
6921        if (position === "static") {
6922          elem.style.position = "relative";
6923        }
6924
6925        curOffset = curElem.offset();
6926        curCSSTop = jQuery.css(elem, "top");
6927        curCSSLeft = jQuery.css(elem, "left");
6928        calculatePosition = (position === "absolute" || position === "fixed") && (curCSSTop + curCSSLeft).indexOf("auto") > -1; // Need to be able to calculate position if either
6929        // top or left is auto and position is either absolute or fixed
6930
6931        if (calculatePosition) {
6932          curPosition = curElem.position();
6933          curTop = curPosition.top;
6934          curLeft = curPosition.left;
6935        } else {
6936          curTop = parseFloat(curCSSTop) || 0;
6937          curLeft = parseFloat(curCSSLeft) || 0;
6938        }
6939
6940        if (isFunction(options)) {
6941          // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
6942          options = options.call(elem, i, jQuery.extend({}, curOffset));
6943        }
6944
6945        if (options.top != null) {
6946          props.top = options.top - curOffset.top + curTop;
6947        }
6948
6949        if (options.left != null) {
6950          props.left = options.left - curOffset.left + curLeft;
6951        }
6952
6953        if ("using" in options) {
6954          options.using.call(elem, props);
6955        } else {
6956          curElem.css(props);
6957        }
6958      }
6959    };
6960    jQuery.fn.extend({
6961      // offset() relates an element's border box to the document origin
6962      offset: function (options) {
6963        // Preserve chaining for setter
6964        if (arguments.length) {
6965          return options === undefined ? this : this.each(function (i) {
6966            jQuery.offset.setOffset(this, options, i);
6967          });
6968        }
6969
6970        var rect,
6971            win,
6972            elem = this[0];
6973
6974        if (!elem) {
6975          return;
6976        } // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
6977        // Support: IE <=11 only
6978        // Running getBoundingClientRect on a
6979        // disconnected node in IE throws an error
6980
6981
6982        if (!elem.getClientRects().length) {
6983          return {
6984            top: 0,
6985            left: 0
6986          };
6987        } // Get document-relative position by adding viewport scroll to viewport-relative gBCR
6988
6989
6990        rect = elem.getBoundingClientRect();
6991        win = elem.ownerDocument.defaultView;
6992        return {
6993          top: rect.top + win.pageYOffset,
6994          left: rect.left + win.pageXOffset
6995        };
6996      },
6997      // position() relates an element's margin box to its offset parent's padding box
6998      // This corresponds to the behavior of CSS absolute positioning
6999      position: function () {
7000        if (!this[0]) {
7001          return;
7002        }
7003
7004        var offsetParent,
7005            offset,
7006            doc,
7007            elem = this[0],
7008            parentOffset = {
7009          top: 0,
7010          left: 0
7011        }; // position:fixed elements are offset from the viewport, which itself always has zero offset
7012
7013        if (jQuery.css(elem, "position") === "fixed") {
7014          // Assume position:fixed implies availability of getBoundingClientRect
7015          offset = elem.getBoundingClientRect();
7016        } else {
7017          offset = this.offset(); // Account for the *real* offset parent, which can be the document or its root element
7018          // when a statically positioned element is identified
7019
7020          doc = elem.ownerDocument;
7021          offsetParent = elem.offsetParent || doc.documentElement;
7022
7023          while (offsetParent && (offsetParent === doc.body || offsetParent === doc.documentElement) && jQuery.css(offsetParent, "position") === "static") {
7024            offsetParent = offsetParent.parentNode;
7025          }
7026
7027          if (offsetParent && offsetParent !== elem && offsetParent.nodeType === 1) {
7028            // Incorporate borders into its offset, since they are outside its content origin
7029            parentOffset = jQuery(offsetParent).offset();
7030            parentOffset.top += jQuery.css(offsetParent, "borderTopWidth", true);
7031            parentOffset.left += jQuery.css(offsetParent, "borderLeftWidth", true);
7032          }
7033        } // Subtract parent offsets and element margins
7034
7035
7036        return {
7037          top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
7038          left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
7039        };
7040      },
7041      // This method will return documentElement in the following cases:
7042      // 1) For the element inside the iframe without offsetParent, this method will return
7043      //    documentElement of the parent window
7044      // 2) For the hidden or detached element
7045      // 3) For body or html element, i.e. in case of the html node - it will return itself
7046      //
7047      // but those exceptions were never presented as a real life use-cases
7048      // and might be considered as more preferable results.
7049      //
7050      // This logic, however, is not guaranteed and can change at any point in the future
7051      offsetParent: function () {
7052        return this.map(function () {
7053          var offsetParent = this.offsetParent;
7054
7055          while (offsetParent && jQuery.css(offsetParent, "position") === "static") {
7056            offsetParent = offsetParent.offsetParent;
7057          }
7058
7059          return offsetParent || documentElement;
7060        });
7061      }
7062    }); // Create scrollLeft and scrollTop methods
7063
7064    jQuery.each({
7065      scrollLeft: "pageXOffset",
7066      scrollTop: "pageYOffset"
7067    }, function (method, prop) {
7068      var top = "pageYOffset" === prop;
7069
7070      jQuery.fn[method] = function (val) {
7071        return access(this, function (elem, method, val) {
7072          // Coalesce documents and windows
7073          var win;
7074
7075          if (isWindow(elem)) {
7076            win = elem;
7077          } else if (elem.nodeType === 9) {
7078            win = elem.defaultView;
7079          }
7080
7081          if (val === undefined) {
7082            return win ? win[prop] : elem[method];
7083          }
7084
7085          if (win) {
7086            win.scrollTo(!top ? val : win.pageXOffset, top ? val : win.pageYOffset);
7087          } else {
7088            elem[method] = val;
7089          }
7090        }, method, val, arguments.length);
7091      };
7092    });
7092 // Support: Safari <=7 - 9.1, Chrome <=37 - 49
7093    // Add the top/left cssHooks using jQuery.fn.position
7094    // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
7095    // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
7096    // getComputedStyle returns percent when specified for top/left/bottom/right;
7097    // rather than make the css module depend on the offset module, just check for it here
7098
7099    jQuery.each(["top", "left"], function (i, prop) {
7100      jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition, function (elem, computed) {
7101        if (computed) {
7102          computed = curCSS(elem, prop); // If curCSS returns percentage, fallback to offset
7103
7104          return rnumnonpx.test(computed) ? jQuery(elem).position()[prop] + "px" : computed;
7105        }
7106      });
7107    }); // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
7108
7109    jQuery.each({
7110      Height: "height",
7111      Width: "width"
7112    }, function (name, type) {
7113      jQuery.each({
7114        padding: "inner" + name,
7115        content: type,
7116        "": "outer" + name
7117      }, function (defaultExtra, funcName) {
7118        // Margin is only for outerHeight, outerWidth
7119        jQuery.fn[funcName] = function (margin, value) {
7120          var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
7121              extra = defaultExtra || (margin === true || value === true ? "margin" : "border");
7122          return access(this, function (elem, type, value) {
7123            var doc;
7124
7125            if (isWindow(elem)) {
7126              // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
7127              return funcName.indexOf("outer") === 0 ? elem["inner" + name] : elem.document.documentElement["client" + name];
7128            } // Get document width or height
7129
7130
7131            if (elem.nodeType === 9) {
7132              doc = elem.documentElement; // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
7133              // whichever is greatest
7134
7135              return Math.max(elem.body["scroll" + name], doc["scroll" + name], elem.body["offset" + name], doc["offset" + name], doc["client" + name]);
7136            }
7137
7138            return value === undefined ? // Get width or height on the element, requesting but not forcing parseFloat
7139            jQuery.css(elem, type, extra) : // Set width or height on the element
7140            jQuery.style(elem, type, value, extra);
7141          }, type, chainable ? margin : undefined, chainable);
7142        };
7143      });
7144    });
7145    jQuery.each(("blur focus focusin focusout resize scroll click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup contextmenu").split(" "), function (i, name) {
7146      // Handle event binding
7147      jQuery.fn[name] = function (data, fn) {
7148        return arguments.length > 0 ? this.on(name, null, data, fn) : this.trigger(name);
7149      };
7150    });
7151    jQuery.fn.extend({
7152      hover: function (fnOver, fnOut) {
7153        return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);
7154      }
7155    });
7156    jQuery.fn.extend({
7157      bind: function (types, data, fn) {
7158        return this.on(types, null, data, fn);
7159      },
7160      unbind: function (types, fn) {
7161        return this.off(types, null, fn);
7162      },
7163      delegate: function (selector, types, data, fn) {
7164        return this.on(types, selector, data, fn);
7165      },
7166      undelegate: function (selector, types, fn) {
7167        // ( namespace ) or ( selector, types [, fn] )
7168        return arguments.length === 1 ? this.off(selector, "**") : this.off(types, selector || "**", fn);
7169      }
7170    }); // Bind a function to a context, optionally partially applying any
7171    // arguments.
7172    // jQuery.proxy is deprecated to promote standards (specifically Function#bind)
7173    // However, it is not slated for removal any time soon
7174
7175    jQuery.proxy = function (fn, context) {
7176      var tmp, args, proxy;
7177
7178      if (typeof context === "string") {
7179        tmp = fn[context];
7180        context = fn;
7181        fn = tmp;
7182      } // Quick check to determine if target is callable, in the spec
7183      // this throws a TypeError, but we will just return undefined.
7184
7185
7186      if (!isFunction(fn)) {
7187        return undefined;
7188      } // Simulated bind
7189
7190
7191      args = slice.call(arguments, 2);
7192
7193      proxy = function () {
7194        return fn.apply(context || this, args.concat(slice.call(arguments)));
7195      }; // Set the guid of unique handler to the same of original handler, so it can be removed
7196
7197
7198      proxy.guid = fn.guid = fn.guid || jQuery.guid++;
7199      return proxy;
7200    };
7201
7202    jQuery.holdReady = function (hold) {
7203      if (hold) {
7204        jQuery.readyWait++;
7205      } else {
7206        jQuery.ready(true);
7207      }
7208    };
7209
7210    jQuery.isArray = Array.isArray;
7211    jQuery.parseJSON = JSON.parse;
7212    jQuery.nodeName = nodeName;
7213    jQuery.isFunction = isFunction;
7214    jQuery.isWindow = isWindow;
7215    jQuery.camelCase = camelCase;
7216    jQuery.type = toType;
7217    jQuery.now = Date.now;
7218
7219    jQuery.isNumeric = function (obj) {
7220      // As of jQuery 3.0, isNumeric is limited to
7221      // strings and numbers (primitives or objects)
7222      // that can be coerced to finite numbers (gh-2662)
7223      var type = jQuery.type(obj);
7224      return (type === "number" || type === "string") && // parseFloat NaNs numeric-cast false positives ("")
7225      // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
7226      // subtraction forces infinities to NaN
7227      !isNaN(obj - parseFloat(obj));
7228    };
7229
7230    const $$1 = jQuery;
7231
7232    function div$1(options) {
7233      return create$1("div", options);
7234    }
7235
7236    function create$1(tag, options) {
7237      const elem = document.createElement(tag);
7238
7239      if (options) {
7240        if (options.class) {
7241          elem.classList.add(options.class);
7242        }
7243
7244        if (options.id) {
7245          elem.id = options.id;
7246        }
7247
7248        if (options.style) {
7249          applyStyle$1(elem, options.style);
7250        }
7251      }
7252
7253      return elem;
7254    }
7255
7256    function hide$1(elem) {
7257      const cssStyle = getComputedStyle(elem);
7258
7259      if (cssStyle.display !== "none") {
7260        elem._initialDisplay = cssStyle.display;
7261      }
7262
7263      elem.style.display = "none";
7264    }
7265
7266    function offset$1(elem) {
7267      // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
7268      // Support: IE <=11 only
7269      // Running getBoundingClientRect on a
7270      // disconnected node in IE throws an error
7271      if (!elem.getClientRects().length) {
7272        return {
7273          top: 0,
7274          left: 0
7275        };
7276      } // Get document-relative position by adding viewport scroll to viewport-relative gBCR
7277
7278
7279      const rect = elem.getBoundingClientRect();
7280      const win = elem.ownerDocument.defaultView;
7281      return {
7282        top: rect.top + win.pageYOffset,
7283        left: rect.left + win.pageXOffset
7284      };
7285    }
7286
7287    function pageCoordinates$1(e) {
7288      if (e.type.startsWith("touch")) {
7289        const touch = e.touches[0];
7290        return {
7291          x: touch.pageX,
7292          y: touch.pageY
7293        };
7294      } else {
7295        return {
7296          x: e.pageX,
7297          y: e.pageY
7298        };
7299      }
7300    }
7301
7302    const relativeDOMBBox = (parentElement, childElement) => {
7303      const {
7304        x: x_p,
7305        y: y_p,
7306        width: width_p,
7307        height: height_p
7308      } = parentElement.getBoundingClientRect();
7309      const {
7310        x: x_c,
7311        y: y_c,
7312        width: width_c,
7313        height: height_c
7314      } = childElement.getBoundingClientRect();
7315      return {
7316        x: x_c - x_p,
7317        y: y_c - y_p,
7318        width: width_c,
7319        height: height_c
7320      };
7321    };
7322
7323    function applyStyle$1(elem, style) {
7324      for (let key of Object.keys(style)) {
7325        elem.style[key] = style[key];
7326      }
7327    }
7328
7329    function guid$1() {
7330      return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4);
7331    }
7332
7333    let getMouseXY$1 = (domElement, {
7334      clientX,
7335      clientY
7336    }) => {
7337      // DOMRect object with eight properties: left, top, right, bottom, x, y, width, height
7338      const {
7339        left,
7340        top,
7341        width,
7342        height
7343      } = domElement.getBoundingClientRect();
7344      const x = clientX - left;
7345      const y = clientY - top;
7346      return {
7347        x,
7348        y,
7349        xNormalized: x / width,
7350        yNormalized: y / height,
7351        width,
7352        height
7353      };
7354    };
7355    /**
7356     * Translate the mouse coordinates for the event to the coordinates for the given target element
7357     * @param event
7358     * @param domElement
7359     * @returns {{x: number, y: number}}
7360     */
7361
7362
7363    function translateMouseCoordinates$1(event, domElement) {
7364      const {
7365        clientX,
7366        clientY
7367      } = event;
7368      return getMouseXY$1(domElement, {
7369        clientX,
7370        clientY
7371      });
7372    }
7373
7374    function createIcon$1(name, color) {
7375      return iconMarkup$1(name, color);
7376    }
7377
7378    function iconMarkup$1(name, color) {
7379      color = color || "currentColor";
7380      let icon = icons$1[name];
7381
7382      if (!icon) {
7383        console.error(`No icon named: ${name}`);
7384        icon = icons$1["question"];
7385      }
7386
7387      const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
7388      svg.setAttributeNS(null, 'viewBox', '0 0 ' + icon[0] + ' ' + icon[1]);
7389      const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
7390      path.setAttributeNS(null, 'fill', color);
7391      path.setAttributeNS(null, 'd', icon[4]);
7392      svg.appendChild(path);
7393      return svg;
7394    }
7395
7396    const icons$1 = {
7397      "check": [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"],
7398      "cog": [512, 512, [], "f013", "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"],
7399      "exclamation": [192, 512, [], "f12a", "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"],
7400      "exclamation-circle": [512, 512, [], "f06a", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418
7400-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],
7401      "exclamation-triangle": [576, 512, [], "f071", "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],
7402      "minus": [448, 512, [], "f068", "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"],
7403      "minus-circle": [512, 512, [], "f056", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"],
7404      "minus-square": [448, 512, [], "f146", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"],
7405      "plus": [448, 512, [], "f067", "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"],
7406      "plus-circle": [512, 512, [], "f055", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],
7407      "plus-square": [448, 512, [], "f0fe", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],
7408      "question": [384, 512, [], "f128", "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"],
7409      "save": [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"],
7410      "search": [512, 512, [], "f002", "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"],
7411      "share": [512, 512, [], "f064", "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"],
7412      "spinner": [512, 512, [], "f110", "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"],
7413      "square": [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"],
7414      "square-full": [512, 512, [], "f45c", "M512 512H0V0h512v512z"],
7415      "times": [384, 512, [], "f00d", "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"],
7416      "times-circle": [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"],
7417      "wrench": [512, 512, [], "f0ad", "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"]
7418    };
7419
7420    function attachDialogCloseHandlerWithParent$1(parent, closeHandler) {
7421      var container = document.createElement("div");
7422      parent.appendChild(container);
7423      container.appendChild(createIcon$1("times"));
7424      container.addEventListener('click', function (e) {
7425        e.preventDefault();
7426        e.stopPropagation();
7427        closeHandler();
7428      });
7429    }
7430
7431    /**
7432     * Covers string literals and String objects
7433     * @param x
7434     * @returns {boolean}
7435     */
7436    function isString$3(x) {
7437      return typeof x === "string" || x instanceof String;
7438    } // StackOverflow: http://stackoverflow.com/a/10810674/116169
7439
7440
7441    function numberFormatter$1(rawNumber) {
7442      var dec = String(rawNumber).split(/[.,]/),
7443          sep = ',',
7444          decsep = '.';
7445      return dec[0].split('').reverse().reduce(function (prev, now, i) {
7446        return i % 3 === 0 ? prev + sep + now : prev + now;
7447      }).split('').reverse().join('') + (dec[1] ? decsep + dec[1] : '');
7448    }
7449
7450    const splitLines$5 = function (string) {
7451      return string.split(/\n|\r\n|\r/g);
7452    };
7453
7454    function splitStringRespectingQuotes(string, delim) {
7455      var tokens = [],
7456          len = string.length,
7457          i,
7458          n = 0,
7459          quote = false,
7460          c;
7461
7462      if (len > 0) {
7463        tokens[n] = string.charAt(0);
7464
7465        for (i = 1; i < len; i++) {
7466          c = string.charAt(i);
7467
7468          if (c === '"') {
7469            quote = !quote;
7470          } else if (!quote && c === delim) {
7471            n++;
7472            tokens[n] = "";
7473          } else {
7474            tokens[n] += c;
7475          }
7476        }
7477      }
7478
7479      return tokens;
7480    }
7481
7482    function stripQuotes$1(str) {
7483      if (str === undefined) {
7484        return str;
7485      }
7486
7487      if (str.startsWith("'") || str.startsWith('"')) {
7488        str = str.substring(1);
7489      }
7490
7491      if (str.endsWith("'") || str.endsWith('"')) {
7492        str = str.substring(0, str.length - 1);
7493      }
7494
7495      return str;
7496    }
7497
7498    function hashCode$1(s) {
7499      return s.split("").reduce(function (a, b) {
7500        a = (a << 5) - a + b.charCodeAt(0);
7501        return a & a;
7502      }, 0);
7503    }
7504
7505    function capitalize(str) {
7506      return str.length > 0 ? str.charAt(0).toUpperCase() + str.slice(1) : str;
7507    }
7508    /**
7509     * Parse a locus string and return a range object.  Locus string is of the form chr:start-end.  End is optional
7510     *
7511     */
7512
7513
7514    function parseLocusString$1(string) {
7515      const t1 = string.split(":");
7516      const t2 = t1[1].split("-");
7517      const range = {
7518        chr: t1[0],
7519        start: Number.parseInt(t2[0].replace(/,/g, '')) - 1
7520      };
7521
7522      if (t2.length > 1) {
7523        range.end = Number.parseInt(t2[1].replace(/,/g, ''));
7524      } else {
7525        range.end = range.start + 1;
7526      }
7527
7528      return range;
7529    }
7530
7531    function isGoogleURL(url) {
7532      return url.includes("googleapis") && !url.includes("urlshortener") || isGoogleStorageURL(url) || isGoogleDriveURL(url);
7533    }
7534
7535    function isGoogleStorageURL(url) {
7536      return url.startsWith("gs://") || url.startsWith("https://www.googleapis.com/storage") || url.startsWith("https://storage.cloud.google.com") || url.startsWith("https://storage.googleapis.com");
7537    }
7538
7539    function isGoogleDriveURL(url) {
7540      return url.indexOf("drive.google.com") >= 0 || url.indexOf("www.googleapis.com/drive") > 0;
7541    }
7542    /**
7543     * Translate gs:// urls to https
7544     * See https://cloud.google.com/storage/docs/json_api/v1
7545     * @param gsUrl
7546     * @returns {string|*}
7547     */
7548
7549
7550    function translateGoogleCloudURL(gsUrl) {
7551      let {
7552        bucket,
7553        object
7554      } = parseBucketName(gsUrl);
7555      object = encode(object);
7556      const qIdx = gsUrl.indexOf('?');
7557      const paramString = qIdx > 0 ? gsUrl.substring(qIdx) + "&alt=media" : "?alt=media";
7558      return `https://storage.googleapis.com/storage/v1/b/${bucket}/o/${object}${paramString}`;
7559    }
7560    /**
7561     * Parse a google bucket and object name from a google storage URL.  Known forms include
7562     *
7563     * gs://BUCKET_NAME/OBJECT_NAME
7564     * https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME
7565     * https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME
7566     * https://www.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME"
7567     * https://storage.googleapis.com/download/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME
7568     *
7569     * @param url
7570     */
7571
7572
7573    function parseBucketName(url) {
7574      let bucket;
7575      let object;
7576
7577      if (url.startsWith("gs://")) {
7578        const i = url.indexOf('/', 5);
7579
7580        if (i >= 0) {
7581          bucket = url.substring(5, i);
7582          const qIdx = url.indexOf('?');
7583          object = qIdx < 0 ? url.substring(i + 1) : url.substring(i + 1, qIdx);
7584        }
7585      } else if (url.startsWith("https://storage.googleapis.com") || url.startsWith("https://storage.cloud.google.com")) {
7586        const bucketIdx = url.indexOf("/v1/b/", 8);
7587
7588        if (bucketIdx > 0) {
7589          const objIdx = url.indexOf("/o/", bucketIdx);
7590
7591          if (objIdx > 0) {
7592            const queryIdx = url.indexOf("?", objIdx);
7593            bucket = url.substring(bucketIdx + 6, objIdx);
7594            object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3);
7595          }
7596        } else {
7597          const idx1 = url.indexOf("/", 8);
7598          const idx2 = url.indexOf("/", idx1 + 1);
7599          const idx3 = url.indexOf("?", idx2);
7600
7601          if (idx2 > 0) {
7602            bucket = url.substring(idx1 + 1, idx2);
7603            object = idx3 < 0 ? url.substring(idx2 + 1) : url.substring(idx2 + 1, idx3);
7604          }
7605        }
7606      } else if (url.startsWith("https://www.googleapis.com/storage/v1/b")) {
7607        const bucketIdx = url.indexOf("/v1/b/", 8);
7608        const objIdx = url.indexOf("/o/", bucketIdx);
7609
7610        if (objIdx > 0) {
7611          const queryIdx = url.indexOf("?", objIdx);
7612          bucket = url.substring(bucketIdx + 6, objIdx);
7613          object = queryIdx > 0 ? url.substring(objIdx + 3, queryIdx) : url.substring(objIdx + 3);
7614        }
7615      }
7616
7617      if (bucket && object) {
7618        return {
7619          bucket,
7620          object
7621        };
7622      } else {
7623        throw Error(`Unrecognized Google Storage URI: ${url}`);
7624      }
7625    }
7626
7627    function driveDownloadURL(link) {
7628      // Return a google drive download url for the sharable link
7629      //https://drive.google.com/open?id=0B-lleX9c2pZFbDJ4VVRxakJzVGM
7630      //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing
7631      var id = getGoogleDriveFileID(link);
7632      return id ? "https://www.googleapis.com/drive/v3/files/" + id + "?alt=media&supportsTeamDrives=true" : link;
7633    }
7634
7635    function getGoogleDriveFileID(link) {
7636      //https://drive.google.com/file/d/1_FC4kCeO8E3V4dJ1yIW7A0sn1yURKIX-/view?usp=sharing
7637      //https://www.googleapis.com/drive/v3/files/1w-tvo6p1SH4p1OaQSVxpkV_EJgGIstWF?alt=media&supportsTeamDrives=true"
7638      if (link.includes("/open?id=")) {
7639        const i1 = link.indexOf("/open?id=") + 9;
7640        const i2 = link.indexOf("&");
7641
7642        if (i1 > 0 && i2 > i1) {
7643          return link.substring(i1, i2);
7644        } else if (i1 > 0) {
7645          return link.substring(i1);
7646        }
7647      } else if (link.includes("/file/d/")) {
7648        const i1 = link.indexOf("/file/d/") + 8;
7649        const i2 = link.lastIndexOf("/");
7650        return link.substring(i1, i2);
7651      } else if (link.startsWith("https://www.googleapis.com/drive")) {
7652        let i1 = link.indexOf("/files/");
7653        const i2 = link.indexOf("?");
7654
7655        if (i1 > 0) {
7656          i1 += 7;
7657          return i2 > 0 ? link.substring(i1, i2) : link.substring(i1);
7658        }
7659      }
7660
7661      throw Error("Unknown Google Drive url format: " + link);
7662    }
7663    /**
7664     * Percent a GCS object name.  See https://cloud.google.com/storage/docs/request-endpoints
7665     * Specific characters to encode:
7666     *   !, #, $, &, ', (, ), *, +, ,, /, :, ;, =, ?, @, [, ], and space characters.
7667     * @param obj
7668     */
7669
7670
7671    function encode(objectName) {
7672      let result = '';
7673      objectName.split('').forEach(function (letter) {
7674        if (encodings.has(letter)) {
7675          result += encodings.get(letter);
7676        } else {
7677          result += letter;
7678        }
7679      });
7680      return result;
7681    } //	%23	%24	%25	%26	%27	%28	%29	%2A	%2B	%2C	%2F	%3A	%3B	%3D	%3F	%40	%5B	%5D
7682
7683
7684    const encodings = new Map();
7685    encodings.set("!", "%21");
7686    encodings.set("#", "%23");
7687    encodings.set("$", "%24");
7688    encodings.set("%", "%25");
7689    encodings.set("&", "%26");
7690    encodings.set("'", "%27");
7691    encodings.set("(", "%28");
7692    encodings.set(")", "%29");
7693    encodings.set("*", "%2A");
7694    encodings.set("+", "%2B");
7695    encodings.set(",", "%2C");
7696    encodings.set("/", "%2F");
7697    encodings.set(":", "%3A");
7698    encodings.set(";", "%3B");
7699    encodings.set("=", "%3D");
7700    encodings.set("?", "%3F");
7701    encodings.set("@", "%40");
7702    encodings.set("[", "%5B");
7703    encodings.set("]", "%5D");
7704    encodings.set(" ", "%20"); // For testing
7705
7706    // Convenience functions for the gapi oAuth library.
7707    const FIVE_MINUTES = 5 * 60 * 1000;
7708
7709    async function load$1(library) {
7710      return new Promise(function (resolve, reject) {
7711        gapi.load(library, {
7712          callback: resolve,
7713          onerror: reject
7714        });
7715      });
7716    }
7717
7718    async function init$1(config) {
7719      if (isInitialized()) {
7720        console.warn("oAuth has already been initialized");
7721        return;
7722      }
7723
7724      gapi.apiKey = config.apiKey; // copy config, gapi will modify it
7725
7726      const configCopy = Object.assign({}, config);
7727
7728      if (!configCopy.scope) {
7729        configCopy.scope = 'profile';
7730      }
7731
7732      if (!config.client_id) {
7733        config.client_id = config.clientId;
7734      }
7735
7736      await load$1("auth2");
7737      return new Promise(function (resolve, reject) {
7738        gapi.auth2.init(configCopy).then(resolve, reject);
7739      });
7740    }
7741
7742    function isInitialized() {
7743      return typeof gapi !== "undefined" && gapi.auth2 && gapi.auth2.getAuthInstance();
7744    }
7745
7746    let inProgress = false;
7747
7748    async function getAccessToken(scope) {
7749      if (typeof gapi === "undefined") {
7750        throw Error("Google authentication requires the 'gapi' library");
7751      }
7752
7753      if (!gapi.auth2) {
7754        throw Error("Google 'auth2' has not been initialized");
7755      }
7756
7757      if (inProgress) {
7758        return new Promise(function (resolve, reject) {
7759          let intervalID;
7760
7761          const checkForToken = () => {
7762            // Wait for inProgress to equal "false"
7763            try {
7764              if (inProgress === false) {
7765                //console.log("Delayed resolution for " + scope);
7766                resolve(getAccessToken(scope));
7767                clearInterval(intervalID);
7768              }
7769            } catch (e) {
7770              clearInterval(intervalID);
7771              reject(e);
7772            }
7773          };
7774
7775          intervalID = setInterval(checkForToken, 100);
7776        });
7777      } else {
7778        inProgress = true;
7779
7780        try {
7781          let currentUser = gapi.auth2.getAuthInstance().currentUser.get();
7782          let token;
7783
7784          if (currentUser.isSignedIn()) {
7785            if (!currentUser.hasGrantedScopes(scope)) {
7786              await currentUser.grant({
7787                scope
7788              });
7789            }
7790
7791            const {
7792              access_token,
7793              expires_at
7794            } = currentUser.getAuthResponse();
7795
7796            if (Date.now() < expires_at - FIVE_MINUTES) {
7797              token = {
7798                access_token,
7799                expires_at
7800              };
7801            } else {
7802              const {
7803                access_token,
7804                expires_at
7805              } = currentUser.reloadAuthResponse();
7806              token = {
7807                access_token,
7808                expires_at
7809              };
7810            }
7811          } else {
7812            currentUser = await signIn(scope);
7813            const {
7814              access_token,
7815              expires_at
7816            } = currentUser.getAuthResponse();
7817            token = {
7818              access_token,
7819              expires_at
7820            };
7821          }
7822
7823          return token;
7824        } finally {
7825          inProgress = false;
7826        }
7827      }
7828    }
7829    /**
7830     * Return the current access token if the user is signed in, or undefined otherwise.  This function does not
7831     * attempt a signIn or request any specfic scopes.
7832     *
7833     * @returns access_token || undefined
7834     */
7835
7836
7837    function getCurrentAccessToken() {
7838      let currentUser = gapi.auth2.getAuthInstance().currentUser.get();
7839
7840      if (currentUser && currentUser.isSignedIn()) {
7841        const {
7842          access_token,
7843          expires_at
7844        } = currentUser.getAuthResponse();
7845        return {
7846          access_token,
7847          expires_at
7848        };
7849      } else {
7850        return undefined;
7851      }
7852    }
7853
7854    async function signIn(scope) {
7855      const options = new gapi.auth2.SigninOptionsBuilder();
7856      options.setPrompt('select_account');
7857      options.setScope(scope);
7858      return gapi.auth2.getAuthInstance().signIn(options);
7859    }
7860
7861    function getScopeForURL(url) {
7862      if (isGoogleDriveURL(url)) {
7863        return "https://www.googleapis.com/auth/drive.file";
7864      } else if (isGoogleStorageURL(url)) {
7865        return "https://www.googleapis.com/auth/devstorage.read_only";
7866      } else {
7867        return 'https://www.googleapis.com/auth/userinfo.profile';
7868      }
7869    }
7870
7871    function getApiKey() {
7872      return gapi.apiKey;
7873    }
7874
7875    async function getDriveFileInfo(googleDriveURL) {
7876      const id = getGoogleDriveFileID(googleDriveURL);
7877      let endPoint = "https://www.googleapis.com/drive/v3/files/" + id + "?supportsTeamDrives=true";
7878      const apiKey = getApiKey();
7879
7880      if (apiKey) {
7881        endPoint += "&key=" + apiKey;
7882      }
7883
7884      const response = await fetch(endPoint);
7885      let json = await response.json();
7886
7887      if (json.error && json.error.code === 404) {
7888        const {
7889          access_token
7890        } = await getAccessToken("https://www.googleapis.com/auth/drive.readonly");
7891
7892        if (access_token) {
7893          const response = await fetch(endPoint, {
7894            headers: {
7895              'Authorization': `Bearer ${access_token}`
7896            }
7897          });
7898          json = await response.json();
7899
7900          if (json.error) {
7901            throw Error(json.error);
7902          }
7903        } else {
7904          throw Error(json.error);
7905        }
7906      }
7907
7908      return json;
7909    }
7910
7911    if (typeof process === 'object' && typeof window === 'undefined') {
7912      global.atob = function (str) {
7913        return Buffer.from(str, 'base64').toString('binary');
7914      };
7915    }
7916
7917    function parseUri(str) {
7918      var o = options,
7919          m = o.parser["loose"].exec(str),
7920          uri = {},
7921          i = 14;
7922
7923      while (i--) uri[o.key[i]] = m[i] || "";
7924
7925      uri[o.q.name] = {};
7926      uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
7927        if ($1) uri[o.q.name][$1] = $2;
7928      });
7929      return uri;
7930    }
7931
7932    const options = {
7933      strictMode: false,
7934      key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"],
7935      q: {
7936        name: "queryKey",
7937        parser: /(?:^|&)([^&=]*)=?([^&]*)/g
7938      },
7939      parser: {
7940        strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
7941        loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
7942      }
7943    };
7944    /**
7945     * Resolve a url, which might be a string, function (that returns a string or Promse), or Promise (that resolves to a string)
7946     *
7947     * @param url
7948     * @returns {Promise<*>}
7949     */
7950
7951
7952    async function resolveURL(url) {
7953      return typeof url === 'function' ? url() : url;
7954    }
7955
7956    /**
7957     * Return the filename from the path.   Example
7958     *   https://foo.com/bar.bed?param=2   => bar.bed
7959     * @param urlOrFile
7960     */
7961
7962
7963    function getFilename$1(urlOrFile) {
7964      if (isFile(urlOrFile)) {
7965        return urlOrFile.name;
7966      } else if (isString$3(urlOrFile)) {
7967        let index = urlOrFile.lastIndexOf("/");
7968        let filename = index < 0 ? urlOrFile : urlOrFile.substr(index + 1); //Strip parameters -- handle local files later
7969
7970        index = filename.indexOf("?");
7971
7972        if (index > 0) {
7973          filename = filename.substr(0, index);
7974        }
7975
7976        return filename;
7977      } else {
7978        throw Error(`Expected File or string, got ${typeof urlOrFile}`);
7979      }
7980    }
7981    /**
7982     * Test if object is a File or File-like object by testing for the "name" property.   This is not a robust test,
7983     * but the purpose is to distinguish the object from url strings
7984     *
7985     * @param object
7986     */
7987
7988
7989    function isFile(object) {
7990      return object !== undefined && (object instanceof File || typeof object !== "function" && object.hasOwnProperty("name") && object.hasOwnProperty("size") && object.hasOwnProperty("type"));
7991    }
7992
7993    const isFilePath = isFile; // deprecated
7994
7995    function download(filename, data) {
7996      const element = document.createElement('a');
7997      element.setAttribute('href', data);
7998      element.setAttribute('download', filename);
7999      element.style.display = 'none';
8000      document.body.appendChild(element);
8001      element.click();
8002      document.body.removeChild(element);
8003    }
8004
8005    // Ths file is a modification of the pako distribution https://github.com/nodeca/pako.   The modifications
8006    // consists of simple changes to create an ES6 module, specifically commenting out the function wrapper and
8007    // adding an ES6 export statement.
8008    // **************  COMMENTED OUT BY JTR ******************//
8009
8010    /*! pako 2.0.4 https://github.com/nodeca/pako @license (MIT AND Zlib) */
8011    // (function (global, factory) {
8012    //   typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
8013    //   typeof define === 'function' && define.amd ? define(['exports'], factory) :
8014    //   (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pako = {}));
8015    // }(this, (function (exports) { 'use strict';
8016    // **************  COMMENTED OUT BY JTR ******************//
8017    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
8018    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
8019    //
8020    // This software is provided 'as-is', without any express or implied
8021    // warranty. In no event will the authors be held liable for any damages
8022    // arising from the use of this software.
8023    //
8024    // Permission is granted to anyone to use this software for any purpose,
8025    // including commercial applications, and to alter it and redistribute it
8026    // freely, subject to the following restrictions:
8027    //
8028    // 1. The origin of this software must not be misrepresented; you must not
8029    //   claim that you wrote the original software. If you use this software
8030    //   in a product, an acknowledgment in the product documentation would be
8031    //   appreciated but is not required.
8032    // 2. Altered source versions must be plainly marked as such, and must not be
8033    //   misrepresented as being the original software.
8034    // 3. This notice may not be removed or altered from any source distribution.
8035
8036    /* eslint-disable space-unary-ops */
8037
8038    /* Public constants ==========================================================*/
8039
8040    /* ===========================================================================*/
8041    //const Z_FILTERED          = 1;
8042    //const Z_HUFFMAN_ONLY      = 2;
8043    //const Z_RLE               = 3;
8044    const Z_FIXED$1 = 4; //const Z_DEFAULT_STRATEGY  = 0;
8045
8046    /* Possible values of the data_type field (though see inflate()) */
8047
8048    const Z_BINARY = 0;
8049    const Z_TEXT = 1; //const Z_ASCII             = 1; // = Z_TEXT
8050
8051    const Z_UNKNOWN$1 = 2;
8052    /*============================================================================*/
8053
8054    function zero$1(buf) {
8055      let len = buf.length;
8056
8057      while (--len >= 0) {
8058        buf[len] = 0;
8059      }
8060    } // From zutil.h
8061
8062
8063    const STORED_BLOCK = 0;
8064    const STATIC_TREES = 1;
8065    const DYN_TREES = 2;
8066    /* The three kinds of block type */
8067
8068    const MIN_MATCH$1 = 3;
8069    const MAX_MATCH$1 = 258;
8070    /* The minimum and maximum match lengths */
8071    // From deflate.h
8072
8073    /* ===========================================================================
vendor: 10,135 bytes, lines 8074-8416
8074     * Internal compression state.
8075     */
8076
8077    const LENGTH_CODES$1 = 29;
8078    /* number of length codes, not counting the special END_BLOCK code */
8079
8080    const LITERALS$1 = 256;
8081    /* number of literal bytes 0..255 */
8082
8083    const L_CODES$1 = LITERALS$1 + 1 + LENGTH_CODES$1;
8084    /* number of Literal or Length codes, including the END_BLOCK code */
8085
8086    const D_CODES$1 = 30;
8087    /* number of distance codes */
8088
8089    const BL_CODES$1 = 19;
8090    /* number of codes used to transfer the bit lengths */
8091
8092    const HEAP_SIZE$1 = 2 * L_CODES$1 + 1;
8093    /* maximum heap size */
8094
8095    const MAX_BITS$1 = 15;
8096    /* All codes must not exceed MAX_BITS bits */
8097
8098    const Buf_size = 16;
8099    /* size of bit buffer in bi_buf */
8100
8101    /* ===========================================================================
8102     * Constants
8103     */
8104
8105    const MAX_BL_BITS = 7;
8106    /* Bit length codes must not exceed MAX_BL_BITS bits */
8107
8108    const END_BLOCK = 256;
8109    /* end of block literal code */
8110
8111    const REP_3_6 = 16;
8112    /* repeat previous bit length 3-6 times (2 bits of repeat count) */
8113
8114    const REPZ_3_10 = 17;
8115    /* repeat a zero length 3-10 times  (3 bits of repeat count) */
8116
8117    const REPZ_11_138 = 18;
8118    /* repeat a zero length 11-138 times  (7 bits of repeat count) */
8119
8120    /* eslint-disable comma-spacing,array-bracket-spacing */
8121
8122    const extra_lbits =
8123    /* extra bits for each length code */
8124    new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0]);
8125    const extra_dbits =
8126    /* extra bits for each distance code */
8127    new Uint8Array([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13]);
8128    const extra_blbits =
8129    /* extra bits for each bit length code */
8130    new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7]);
8131    const bl_order = new Uint8Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
8132    /* eslint-enable comma-spacing,array-bracket-spacing */
8133
8134    /* The lengths of the bit length codes are sent in order of decreasing
8135     * probability, to avoid transmitting the lengths for unused bit length codes.
8136     */
8137
8138    /* ===========================================================================
8139     * Local data. These are initialized only once.
8140     */
8141    // We pre-fill arrays with 0 to avoid uninitialized gaps
8142
8143    const DIST_CODE_LEN = 512;
8144    /* see definition of array dist_code below */
8145    // !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1
8146
8147    const static_ltree = new Array((L_CODES$1 + 2) * 2);
8148    zero$1(static_ltree);
8149    /* The static literal tree. Since the bit lengths are imposed, there is no
8150     * need for the L_CODES extra codes used during heap construction. However
8151     * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
8152     * below).
8153     */
8154
8155    const static_dtree = new Array(D_CODES$1 * 2);
8156    zero$1(static_dtree);
8157    /* The static distance tree. (Actually a trivial tree since all codes use
8158     * 5 bits.)
8159     */
8160
8161    const _dist_code = new Array(DIST_CODE_LEN);
8162
8163    zero$1(_dist_code);
8164    /* Distance codes. The first 256 values correspond to the distances
8165     * 3 .. 258, the last 256 values correspond to the top 8 bits of
8166     * the 15 bit distances.
8167     */
8168
8169    const _length_code = new Array(MAX_MATCH$1 - MIN_MATCH$1 + 1);
8170
8171    zero$1(_length_code);
8172    /* length code for each normalized match length (0 == MIN_MATCH) */
8173
8174    const base_length = new Array(LENGTH_CODES$1);
8175    zero$1(base_length);
8176    /* First normalized length for each code (0 = MIN_MATCH) */
8177
8178    const base_dist = new Array(D_CODES$1);
8179    zero$1(base_dist);
8180    /* First normalized distance for each code (0 = distance of 1) */
8181
8182    function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {
8183      this.static_tree = static_tree;
8184      /* static tree or NULL */
8185
8186      this.extra_bits = extra_bits;
8187      /* extra bits for each code or NULL */
8188
8189      this.extra_base = extra_base;
8190      /* base index for extra_bits */
8191
8192      this.elems = elems;
8193      /* max number of elements in the tree */
8194
8195      this.max_length = max_length;
8196      /* max bit length for the codes */
8197      // show if `static_tree` has data or dummy - needed for monomorphic objects
8198
8199      this.has_stree = static_tree && static_tree.length;
8200    }
8201
8202    let static_l_desc;
8203    let static_d_desc;
8204    let static_bl_desc;
8205
8206    function TreeDesc(dyn_tree, stat_desc) {
8207      this.dyn_tree = dyn_tree;
8208      /* the dynamic tree */
8209
8210      this.max_code = 0;
8211      /* largest code with non zero frequency */
8212
8213      this.stat_desc = stat_desc;
8214      /* the corresponding static tree */
8215    }
8216
8217    const d_code = dist => {
8218      return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
8219    };
8220    /* ===========================================================================
8221     * Output a short LSB first on the stream.
8222     * IN assertion: there is enough room in pendingBuf.
8223     */
8224
8225
8226    const put_short = (s, w) => {
8227      //    put_byte(s, (uch)((w) & 0xff));
8228      //    put_byte(s, (uch)((ush)(w) >> 8));
8229      s.pending_buf[s.pending++] = w & 0xff;
8230      s.pending_buf[s.pending++] = w >>> 8 & 0xff;
8231    };
8232    /* ===========================================================================
8233     * Send a value on a given number of bits.
8234     * IN assertion: length <= 16 and value fits in length bits.
8235     */
8236
8237
8238    const send_bits = (s, value, length) => {
8239      if (s.bi_valid > Buf_size - length) {
8240        s.bi_buf |= value << s.bi_valid & 0xffff;
8241        put_short(s, s.bi_buf);
8242        s.bi_buf = value >> Buf_size - s.bi_valid;
8243        s.bi_valid += length - Buf_size;
8244      } else {
8245        s.bi_buf |= value << s.bi_valid & 0xffff;
8246        s.bi_valid += length;
8247      }
8248    };
8249
8250    const send_code = (s, c, tree) => {
8251      send_bits(s, tree[c * 2]
8252      /*.Code*/
8253      , tree[c * 2 + 1]
8254      /*.Len*/
8255      );
8256    };
8257    /* ===========================================================================
8258     * Reverse the first len bits of a code, using straightforward code (a faster
8259     * method would use a table)
8260     * IN assertion: 1 <= len <= 15
8261     */
8262
8263
8264    const bi_reverse = (code, len) => {
8265      let res = 0;
8266
8267      do {
8268        res |= code & 1;
8269        code >>>= 1;
8270        res <<= 1;
8271      } while (--len > 0);
8272
8273      return res >>> 1;
8274    };
8275    /* ===========================================================================
8276     * Flush the bit buffer, keeping at most 7 bits in it.
8277     */
8278
8279
8280    const bi_flush = s => {
8281      if (s.bi_valid === 16) {
8282        put_short(s, s.bi_buf);
8283        s.bi_buf = 0;
8284        s.bi_valid = 0;
8285      } else if (s.bi_valid >= 8) {
8286        s.pending_buf[s.pending++] = s.bi_buf & 0xff;
8287        s.bi_buf >>= 8;
8288        s.bi_valid -= 8;
8289      }
8290    };
8291    /* ===========================================================================
8292     * Compute the optimal bit lengths for a tree and update the total bit length
8293     * for the current block.
8294     * IN assertion: the fields freq and dad are set, heap[heap_max] and
8295     *    above are the tree nodes sorted by increasing frequency.
8296     * OUT assertions: the field len is set to the optimal bit length, the
8297     *     array bl_count contains the frequencies for each bit length.
8298     *     The length opt_len is updated; static_len is also updated if stree is
8299     *     not null.
8300     */
8301
8302
8303    const gen_bitlen = (s, desc) => //    deflate_state *s;
8304    //    tree_desc *desc;    /* the tree descriptor */
8305    {
8306      const tree = desc.dyn_tree;
8307      const max_code = desc.max_code;
8308      const stree = desc.stat_desc.static_tree;
8309      const has_stree = desc.stat_desc.has_stree;
8310      const extra = desc.stat_desc.extra_bits;
8311      const base = desc.stat_desc.extra_base;
8312      const max_length = desc.stat_desc.max_length;
8313      let h;
8314      /* heap index */
8315
8316      let n, m;
8317      /* iterate over the tree elements */
8318
8319      let bits;
8320      /* bit length */
8321
8322      let xbits;
8323      /* extra bits */
8324
8325      let f;
8326      /* frequency */
8327
8328      let overflow = 0;
8329      /* number of elements with bit length too large */
8330
8331      for (bits = 0; bits <= MAX_BITS$1; bits++) {
8332        s.bl_count[bits] = 0;
8333      }
8334      /* In a first pass, compute the optimal bit lengths (which may
8335       * overflow in the case of the bit length tree).
8336       */
8337
8338
8339      tree[s.heap[s.heap_max] * 2 + 1]
8340      /*.Len*/
8341      = 0;
8342      /* root of the heap */
8343
8344      for (h = s.heap_max + 1; h < HEAP_SIZE$1; h++) {
8345        n = s.heap[h];
8346        bits = tree[tree[n * 2 + 1]
8347        /*.Dad*/
8348        * 2 + 1]
8349        /*.Len*/
8350        + 1;
8351
8352        if (bits > max_length) {
8353          bits = max_length;
8354          overflow++;
8355        }
8356
8357        tree[n * 2 + 1]
8358        /*.Len*/
8359        = bits;
8360        /* We overwrite tree[n].Dad which is no longer needed */
8361
8362        if (n > max_code) {
8363          continue;
8364        }
8365        /* not a leaf node */
8366
8367
8368        s.bl_count[bits]++;
8369        xbits = 0;
8370
8371        if (n >= base) {
8372          xbits = extra[n - base];
8373        }
8374
8375        f = tree[n * 2]
8376        /*.Freq*/
8377        ;
8378        s.opt_len += f * (bits + xbits);
8379
8380        if (has_stree) {
8381          s.static_len += f * (stree[n * 2 + 1]
8382          /*.Len*/
8383          + xbits);
8384        }
8385      }
8386
8387      if (overflow === 0) {
8388        return;
8389      } // Trace((stderr,"\nbit length overflow\n"));
8390
8391      /* This happens for example on obj2 and pic of the Calgary corpus */
8392
8393      /* Find the first bit length which could increase: */
8394
8395
8396      do {
8397        bits = max_length - 1;
8398
8399        while (s.bl_count[bits] === 0) {
8400          bits--;
8401        }
8402
8403        s.bl_count[bits]--;
8404        /* move one leaf down the tree */
8405
8406        s.bl_count[bits + 1] += 2;
8407        /* move one overflow item as its brother */
8408
8409        s.bl_count[max_length]--;
8410        /* The brother of the overflow item also moves one step up,
8411         * but this does not affect bl_count[max_length]
8412         */
8413
8414        overflow -= 2;
8415      } while (overflow > 0);
8416      /* Now recompute all bit lengths, scanning in increasing frequency.
8417       * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
8418       * lengths instead of fixing only the wrong ones. This idea is taken
8419       * from 'ar' written by Haruhiko Okumura.)
8420       */
8421
8422
8423      for (bits = max_length; bits !== 0; bits--) {
8424        n = s.bl_count[bits];
8425
8426        while (n !== 0) {
8427          m = s.heap[--h];
8428
8429          if (m > max_code) {
8430            continue;
8431          }
8432
8433          if (tree[m * 2 + 1]
8434          /*.Len*/
8435          !== bits) {
8436            // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
8437            s.opt_len += (bits - tree[m * 2 + 1]
8438            /*.Len*/
8439            ) * tree[m * 2]
8440            /*.Freq*/
8441            ;
8442            tree[m * 2 + 1]
8443            /*.Len*/
8444            = bits;
8445          }
8446
8447          n--;
8448        }
8449      }
8450    };
8451    /* ===========================================================================
8452     * Generate the codes for a given tree and bit counts (which need not be
8453     * optimal).
8454     * IN assertion: the array bl_count contains the bit length statistics for
8455     * the given tree and the field len is set for all tree elements.
8456     * OUT assertion: the field code is set for all tree elements of non
8457     *     zero code length.
8458     */
8459
8460
8461    const gen_codes = (tree, max_code, bl_count) => //    ct_data *tree;             /* the tree to decorate */
8462    //    int max_code;              /* largest code with non zero frequency */
8463    //    ushf *bl_count;            /* number of codes at each bit length */
8464    {
8465      const next_code = new Array(MAX_BITS$1 + 1);
8466      /* next code value for each bit length */
8467
8468      let code = 0;
8469      /* running code value */
8470
8471      let bits;
8472      /* bit index */
8473
8474      let n;
8475      /* code index */
8476
8477      /* The distribution counts are first used to generate the code values
8478       * without bit reversal.
8479       */
8480
8481      for (bits = 1; bits <= MAX_BITS$1; bits++) {
8482        next_code[bits] = code = code + bl_count[bits - 1] << 1;
8483      }
8484      /* Check that the bit counts in bl_count are consistent. The last code
8485       * must be all ones.
8486       */
8487      //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
8488      //        "inconsistent bit counts");
8489      //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
8490
8491
8492      for (n = 0; n <= max_code; n++) {
8493        let len = tree[n * 2 + 1]
8494        /*.Len*/
8495        ;
8496
8497        if (len === 0) {
8498          continue;
8499        }
8500        /* Now reverse the bits */
8501
8502
8503        tree[n * 2]
8504        /*.Code*/
8505        = bi_reverse(next_code[len]++, len); //Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
8506        //     n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
8507      }
8508    };
8509    /* ===========================================================================
8510     * Initialize the various 'constant' tables.
8511     */
8512
8513
8514    const tr_static_init = () => {
8515      let n;
8516      /* iterates over tree elements */
8517
8518      let bits;
8519      /* bit counter */
8520
8521      let length;
8522      /* length value */
8523
8524      let code;
8525      /* code value */
8526
8527      let dist;
8528      /* distance index */
8529
8530      const bl_count = new Array(MAX_BITS$1 + 1);
8531      /* number of codes at each bit length for an optimal tree */
8532      // do check in _tr_init()
8533      //if (static_init_done) return;
8534
8535      /* For some embedded targets, global variables are not initialized: */
8536
8537      /*#ifdef NO_INIT_GLOBAL_POINTERS
8538        static_l_desc.static_tree = static_ltree;
8539        static_l_desc.extra_bits = extra_lbits;
8540        static_d_desc.static_tree = static_dtree;
8541        static_d_desc.extra_bits = extra_dbits;
8542        static_bl_desc.extra_bits = extra_blbits;
8543      #endif*/
8544
8545      /* Initialize the mapping length (0..255) -> length code (0..28) */
8546
8547      length = 0;
8548
8549      for (code = 0; code < LENGTH_CODES$1 - 1; code++) {
8550        base_length[code] = length;
8551
8552        for (n = 0; n < 1 << extra_lbits[code]; n++) {
8553          _length_code[length++] = code;
8554        }
8555      } //Assert (length == 256, "tr_static_init: length != 256");
8556
8557      /* Note that the length 255 (match length 258) can be represented
8558       * in two different ways: code 284 + 5 bits or code 285, so we
8559       * overwrite length_code[255] to use the best encoding:
8560       */
8561
8562
8563      _length_code[length - 1] = code;
8564      /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
8565
8566      dist = 0;
8567
8568      for (code = 0;
vendor: 26,440 bytes, lines 8568-9469
8568 code < 16; code++) {
8569        base_dist[code] = dist;
8570
8571        for (n = 0; n < 1 << extra_dbits[code]; n++) {
8572          _dist_code[dist++] = code;
8573        }
8574      } //Assert (dist == 256, "tr_static_init: dist != 256");
8575
8576
8577      dist >>= 7;
8578      /* from now on, all distances are divided by 128 */
8579
8580      for (; code < D_CODES$1; code++) {
8581        base_dist[code] = dist << 7;
8582
8583        for (n = 0; n < 1 << extra_dbits[code] - 7; n++) {
8584          _dist_code[256 + dist++] = code;
8585        }
8586      } //Assert (dist == 256, "tr_static_init: 256+dist != 512");
8587
8588      /* Construct the codes of the static literal tree */
8589
8590
8591      for (bits = 0; bits <= MAX_BITS$1; bits++) {
8592        bl_count[bits] = 0;
8593      }
8594
8595      n = 0;
8596
8597      while (n <= 143) {
8598        static_ltree[n * 2 + 1]
8599        /*.Len*/
8600        = 8;
8601        n++;
8602        bl_count[8]++;
8603      }
8604
8605      while (n <= 255) {
8606        static_ltree[n * 2 + 1]
8607        /*.Len*/
8608        = 9;
8609        n++;
8610        bl_count[9]++;
8611      }
8612
8613      while (n <= 279) {
8614        static_ltree[n * 2 + 1]
8615        /*.Len*/
8616        = 7;
8617        n++;
8618        bl_count[7]++;
8619      }
8620
8621      while (n <= 287) {
8622        static_ltree[n * 2 + 1]
8623        /*.Len*/
8624        = 8;
8625        n++;
8626        bl_count[8]++;
8627      }
8628      /* Codes 286 and 287 do not exist, but we must include them in the
8629       * tree construction to get a canonical Huffman tree (longest code
8630       * all ones)
8631       */
8632
8633
8634      gen_codes(static_ltree, L_CODES$1 + 1, bl_count);
8635      /* The static distance tree is trivial: */
8636
8637      for (n = 0; n < D_CODES$1; n++) {
8638        static_dtree[n * 2 + 1]
8639        /*.Len*/
8640        = 5;
8641        static_dtree[n * 2]
8642        /*.Code*/
8643        = bi_reverse(n, 5);
8644      } // Now data ready and we can init static trees
8645
8646
8647      static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS$1 + 1, L_CODES$1, MAX_BITS$1);
8648      static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES$1, MAX_BITS$1);
8649      static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES$1, MAX_BL_BITS); //static_init_done = true;
8650    };
8651    /* ===========================================================================
8652     * Initialize a new block.
8653     */
8654
8655
8656    const init_block = s => {
8657      let n;
8658      /* iterates over tree elements */
8659
8660      /* Initialize the trees. */
8661
8662      for (n = 0; n < L_CODES$1; n++) {
8663        s.dyn_ltree[n * 2]
8664        /*.Freq*/
8665        = 0;
8666      }
8667
8668      for (n = 0; n < D_CODES$1; n++) {
8669        s.dyn_dtree[n * 2]
8670        /*.Freq*/
8671        = 0;
8672      }
8673
8674      for (n = 0; n < BL_CODES$1; n++) {
8675        s.bl_tree[n * 2]
8676        /*.Freq*/
8677        = 0;
8678      }
8679
8680      s.dyn_ltree[END_BLOCK * 2]
8681      /*.Freq*/
8682      = 1;
8683      s.opt_len = s.static_len = 0;
8684      s.last_lit = s.matches = 0;
8685    };
8686    /* ===========================================================================
8687     * Flush the bit buffer and align the output on a byte boundary
8688     */
8689
8690
8691    const bi_windup = s => {
8692      if (s.bi_valid > 8) {
8693        put_short(s, s.bi_buf);
8694      } else if (s.bi_valid > 0) {
8695        //put_byte(s, (Byte)s->bi_buf);
8696        s.pending_buf[s.pending++] = s.bi_buf;
8697      }
8698
8699      s.bi_buf = 0;
8700      s.bi_valid = 0;
8701    };
8702    /* ===========================================================================
8703     * Copy a stored block, storing first the length and its
8704     * one's complement if requested.
8705     */
8706
8707
8708    const copy_block = (s, buf, len, header) => //DeflateState *s;
8709    //charf    *buf;    /* the input data */
8710    //unsigned len;     /* its length */
8711    //int      header;  /* true if block header must be written */
8712    {
8713      bi_windup(s);
8714      /* align on byte boundary */
8715
8716      if (header) {
8717        put_short(s, len);
8718        put_short(s, ~len);
8719      } //  while (len--) {
8720      //    put_byte(s, *buf++);
8721      //  }
8722
8723
8724      s.pending_buf.set(s.window.subarray(buf, buf + len), s.pending);
8725      s.pending += len;
8726    };
8727    /* ===========================================================================
8728     * Compares to subtrees, using the tree depth as tie breaker when
8729     * the subtrees have equal frequency. This minimizes the worst case length.
8730     */
8731
8732
8733    const smaller = (tree, n, m, depth) => {
8734      const _n2 = n * 2;
8735
8736      const _m2 = m * 2;
8737
8738      return tree[_n2]
8739      /*.Freq*/
8740      < tree[_m2]
8741      /*.Freq*/
8742      || tree[_n2]
8743      /*.Freq*/
8744      === tree[_m2]
8745      /*.Freq*/
8746      && depth[n] <= depth[m];
8747    };
8748    /* ===========================================================================
8749     * Restore the heap property by moving down the tree starting at node k,
8750     * exchanging a node with the smallest of its two sons if necessary, stopping
8751     * when the heap property is re-established (each father smaller than its
8752     * two sons).
8753     */
8754
8755
8756    const pqdownheap = (s, tree, k) => //    deflate_state *s;
8757    //    ct_data *tree;  /* the tree to restore */
8758    //    int k;               /* node to move down */
8759    {
8760      const v = s.heap[k];
8761      let j = k << 1;
8762      /* left son of k */
8763
8764      while (j <= s.heap_len) {
8765        /* Set j to the smallest of the two sons: */
8766        if (j < s.heap_len && smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {
8767          j++;
8768        }
8769        /* Exit if v is smaller than both sons */
8770
8771
8772        if (smaller(tree, v, s.heap[j], s.depth)) {
8773          break;
8774        }
8775        /* Exchange v with the smallest son */
8776
8777
8778        s.heap[k] = s.heap[j];
8779        k = j;
8780        /* And continue down the tree, setting j to the left son of k */
8781
8782        j <<= 1;
8783      }
8784
8785      s.heap[k] = v;
8786    }; // inlined manually
8787    // const SMALLEST = 1;
8788
8789    /* ===========================================================================
8790     * Send the block data compressed using the given Huffman trees
8791     */
8792
8793
8794    const compress_block = (s, ltree, dtree) => //    deflate_state *s;
8795    //    const ct_data *ltree; /* literal tree */
8796    //    const ct_data *dtree; /* distance tree */
8797    {
8798      let dist;
8799      /* distance of matched string */
8800
8801      let lc;
8802      /* match length or unmatched char (if dist == 0) */
8803
8804      let lx = 0;
8805      /* running index in l_buf */
8806
8807      let code;
8808      /* the code to send */
8809
8810      let extra;
8811      /* number of extra bits to send */
8812
8813      if (s.last_lit !== 0) {
8814        do {
8815          dist = s.pending_buf[s.d_buf + lx * 2] << 8 | s.pending_buf[s.d_buf + lx * 2 + 1];
8816          lc = s.pending_buf[s.l_buf + lx];
8817          lx++;
8818
8819          if (dist === 0) {
8820            send_code(s, lc, ltree);
8821            /* send a literal byte */
8822            //Tracecv(isgraph(lc), (stderr," '%c' ", lc));
8823          } else {
8824            /* Here, lc is the match length - MIN_MATCH */
8825            code = _length_code[lc];
8826            send_code(s, code + LITERALS$1 + 1, ltree);
8827            /* send the length code */
8828
8829            extra = extra_lbits[code];
8830
8831            if (extra !== 0) {
8832              lc -= base_length[code];
8833              send_bits(s, lc, extra);
8834              /* send the extra length bits */
8835            }
8836
8837            dist--;
8838            /* dist is now the match distance - 1 */
8839
8840            code = d_code(dist); //Assert (code < D_CODES, "bad d_code");
8841
8842            send_code(s, code, dtree);
8843            /* send the distance code */
8844
8845            extra = extra_dbits[code];
8846
8847            if (extra !== 0) {
8848              dist -= base_dist[code];
8849              send_bits(s, dist, extra);
8850              /* send the extra distance bits */
8851            }
8852          }
8853          /* literal or match pair ? */
8854
8855          /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
8856          //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
8857          //       "pendingBuf overflow");
8858
8859        } while (lx < s.last_lit);
8860      }
8861
8862      send_code(s, END_BLOCK, ltree);
8863    };
8864    /* ===========================================================================
8865     * Construct one Huffman tree and assigns the code bit strings and lengths.
8866     * Update the total bit length for the current block.
8867     * IN assertion: the field freq is set for all tree elements.
8868     * OUT assertions: the fields len and code are set to the optimal bit length
8869     *     and corresponding code. The length opt_len is updated; static_len is
8870     *     also updated if stree is not null. The field max_code is set.
8871     */
8872
8873
8874    const build_tree = (s, desc) => //    deflate_state *s;
8875    //    tree_desc *desc; /* the tree descriptor */
8876    {
8877      const tree = desc.dyn_tree;
8878      const stree = desc.stat_desc.static_tree;
8879      const has_stree = desc.stat_desc.has_stree;
8880      const elems = desc.stat_desc.elems;
8881      let n, m;
8882      /* iterate over heap elements */
8883
8884      let max_code = -1;
8885      /* largest code with non zero frequency */
8886
8887      let node;
8888      /* new node being created */
8889
8890      /* Construct the initial heap, with least frequent element in
8891       * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
8892       * heap[0] is not used.
8893       */
8894
8895      s.heap_len = 0;
8896      s.heap_max = HEAP_SIZE$1;
8897
8898      for (n = 0; n < elems; n++) {
8899        if (tree[n * 2]
8900        /*.Freq*/
8901        !== 0) {
8902          s.heap[++s.heap_len] = max_code = n;
8903          s.depth[n] = 0;
8904        } else {
8905          tree[n * 2 + 1]
8906          /*.Len*/
8907          = 0;
8908        }
8909      }
8910      /* The pkzip format requires that at least one distance code exists,
8911       * and that at least one bit should be sent even if there is only one
8912       * possible code. So to avoid special checks later on we force at least
8913       * two codes of non zero frequency.
8914       */
8915
8916
8917      while (s.heap_len < 2) {
8918        node = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0;
8919        tree[node * 2]
8920        /*.Freq*/
8921        = 1;
8922        s.depth[node] = 0;
8923        s.opt_len--;
8924
8925        if (has_stree) {
8926          s.static_len -= stree[node * 2 + 1]
8927          /*.Len*/
8928          ;
8929        }
8930        /* node is 0 or 1 so it does not have extra bits */
8931
8932      }
8933
8934      desc.max_code = max_code;
8935      /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
8936       * establish sub-heaps of increasing lengths:
8937       */
8938
8939      for (n = s.heap_len >> 1
8940      /*int /2*/
8941      ; n >= 1; n--) {
8942        pqdownheap(s, tree, n);
8943      }
8944      /* Construct the Huffman tree by repeatedly combining the least two
8945       * frequent nodes.
8946       */
8947
8948
8949      node = elems;
8950      /* next internal node of the tree */
8951
8952      do {
8953        //pqremove(s, tree, n);  /* n = node of least frequency */
8954
8955        /*** pqremove ***/
8956        n = s.heap[1
8957        /*SMALLEST*/
8958        ];
8959        s.heap[1
8960        /*SMALLEST*/
8961        ] = s.heap[s.heap_len--];
8962        pqdownheap(s, tree, 1
8963        /*SMALLEST*/
8964        );
8965        /***/
8966
8967        m = s.heap[1
8968        /*SMALLEST*/
8969        ];
8970        /* m = node of next least frequency */
8971
8972        s.heap[--s.heap_max] = n;
8973        /* keep the nodes sorted by frequency */
8974
8975        s.heap[--s.heap_max] = m;
8976        /* Create a new node father of n and m */
8977
8978        tree[node * 2]
8979        /*.Freq*/
8980        = tree[n * 2]
8981        /*.Freq*/
8982        + tree[m * 2]
8983        /*.Freq*/
8984        ;
8985        s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;
8986        tree[n * 2 + 1]
8987        /*.Dad*/
8988        = tree[m * 2 + 1]
8989        /*.Dad*/
8990        = node;
8991        /* and insert the new node in the heap */
8992
8993        s.heap[1
8994        /*SMALLEST*/
8995        ] = node++;
8996        pqdownheap(s, tree, 1
8997        /*SMALLEST*/
8998        );
8999      } while (s.heap_len >= 2);
9000
9001      s.heap[--s.heap_max] = s.heap[1
9002      /*SMALLEST*/
9003      ];
9004      /* At this point, the fields freq and dad are set. We can now
9005       * generate the bit lengths.
9006       */
9007
9008      gen_bitlen(s, desc);
9009      /* The field len is now set, we can generate the bit codes */
9010
9011      gen_codes(tree, max_code, s.bl_count);
9012    };
9013    /* ===========================================================================
9014     * Scan a literal or distance tree to determine the frequencies of the codes
9015     * in the bit length tree.
9016     */
9017
9018
9019    const scan_tree = (s, tree, max_code) => //    deflate_state *s;
9020    //    ct_data *tree;   /* the tree to be scanned */
9021    //    int max_code;    /* and its largest code of non zero frequency */
9022    {
9023      let n;
9024      /* iterates over all tree elements */
9025
9026      let prevlen = -1;
9027      /* last emitted length */
9028
9029      let curlen;
9030      /* length of current code */
9031
9032      let nextlen = tree[0 * 2 + 1]
9033      /*.Len*/
9034      ;
9035      /* length of next code */
9036
9037      let count = 0;
9038      /* repeat count of the current code */
9039
9040      let max_count = 7;
9041      /* max repeat count */
9042
9043      let min_count = 4;
9044      /* min repeat count */
9045
9046      if (nextlen === 0) {
9047        max_count = 138;
9048        min_count = 3;
9049      }
9050
9051      tree[(max_code + 1) * 2 + 1]
9052      /*.Len*/
9053      = 0xffff;
9054      /* guard */
9055
9056      for (n = 0; n <= max_code; n++) {
9057        curlen = nextlen;
9058        nextlen = tree[(n + 1) * 2 + 1]
9059        /*.Len*/
9060        ;
9061
9062        if (++count < max_count && curlen === nextlen) {
9063          continue;
9064        } else if (count < min_count) {
9065          s.bl_tree[curlen * 2]
9066          /*.Freq*/
9067          += count;
9068        } else if (curlen !== 0) {
9069          if (curlen !== prevlen) {
9070            s.bl_tree[curlen * 2] /*.Freq*/++;
9071          }
9072
9073          s.bl_tree[REP_3_6 * 2] /*.Freq*/++;
9074        } else if (count <= 10) {
9075          s.bl_tree[REPZ_3_10 * 2] /*.Freq*/++;
9076        } else {
9077          s.bl_tree[REPZ_11_138 * 2] /*.Freq*/++;
9078        }
9079
9080        count = 0;
9081        prevlen = curlen;
9082
9083        if (nextlen === 0) {
9084          max_count = 138;
9085          min_count = 3;
9086        } else if (curlen === nextlen) {
9087          max_count = 6;
9088          min_count = 3;
9089        } else {
9090          max_count = 7;
9091          min_count = 4;
9092        }
9093      }
9094    };
9095    /* ===========================================================================
9096     * Send a literal or distance tree in compressed form, using the codes in
9097     * bl_tree.
9098     */
9099
9100
9101    const send_tree = (s, tree, max_code) => //    deflate_state *s;
9102    //    ct_data *tree; /* the tree to be scanned */
9103    //    int max_code;       /* and its largest code of non zero frequency */
9104    {
9105      let n;
9106      /* iterates over all tree elements */
9107
9108      let prevlen = -1;
9109      /* last emitted length */
9110
9111      let curlen;
9112      /* length of current code */
9113
9114      let nextlen = tree[0 * 2 + 1]
9115      /*.Len*/
9116      ;
9117      /* length of next code */
9118
9119      let count = 0;
9120      /* repeat count of the current code */
9121
9122      let max_count = 7;
9123      /* max repeat count */
9124
9125      let min_count = 4;
9126      /* min repeat count */
9127
9128      /* tree[max_code+1].Len = -1; */
9129
9130      /* guard already set */
9131
9132      if (nextlen === 0) {
9133        max_count = 138;
9134        min_count = 3;
9135      }
9136
9137      for (n = 0; n <= max_code; n++) {
9138        curlen = nextlen;
9139        nextlen = tree[(n + 1) * 2 + 1]
9140        /*.Len*/
9141        ;
9142
9143        if (++count < max_count && curlen === nextlen) {
9144          continue;
9145        } else if (count < min_count) {
9146          do {
9147            send_code(s, curlen, s.bl_tree);
9148          } while (--count !== 0);
9149        } else if (curlen !== 0) {
9150          if (curlen !== prevlen) {
9151            send_code(s, curlen, s.bl_tree);
9152            count--;
9153          } //Assert(count >= 3 && count <= 6, " 3_6?");
9154
9155
9156          send_code(s, REP_3_6, s.bl_tree);
9157          send_bits(s, count - 3, 2);
9158        } else if (count <= 10) {
9159          send_code(s, REPZ_3_10, s.bl_tree);
9160          send_bits(s, count - 3, 3);
9161        } else {
9162          send_code(s, REPZ_11_138, s.bl_tree);
9163          send_bits(s, count - 11, 7);
9164        }
9165
9166        count = 0;
9167        prevlen = curlen;
9168
9169        if (nextlen === 0) {
9170          max_count = 138;
9171          min_count = 3;
9172        } else if (curlen === nextlen) {
9173          max_count = 6;
9174          min_count = 3;
9175        } else {
9176          max_count = 7;
9177          min_count = 4;
9178        }
9179      }
9180    };
9181    /* ===========================================================================
9182     * Construct the Huffman tree for the bit lengths and return the index in
9183     * bl_order of the last bit length code to send.
9184     */
9185
9186
9187    const build_bl_tree = s => {
9188      let max_blindex;
9189      /* index of last bit length code of non zero freq */
9190
9191      /* Determine the bit length frequencies for literal and distance trees */
9192
9193      scan_tree(s, s.dyn_ltree, s.l_desc.max_code);
9194      scan_tree(s, s.dyn_dtree, s.d_desc.max_code);
9195      /* Build the bit length tree: */
9196
9197      build_tree(s, s.bl_desc);
9198      /* opt_len now includes the length of the tree representations, except
9199       * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
9200       */
9201
9202      /* Determine the number of bit length codes to send. The pkzip format
9203       * requires that at least 4 bit length codes be sent. (appnote.txt says
9204       * 3 but the actual value used is 4.)
9205       */
9206
9207      for (max_blindex = BL_CODES$1 - 1; max_blindex >= 3; max_blindex--) {
9208        if (s.bl_tree[bl_order[max_blindex] * 2 + 1]
9209        /*.Len*/
9210        !== 0) {
9211          break;
9212        }
9213      }
9214      /* Update opt_len to include the bit length tree and counts */
9215
9216
9217      s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
9218      //        s->opt_len, s->static_len));
9219
9220      return max_blindex;
9221    };
9222    /* ===========================================================================
9223     * Send the header for a block using dynamic Huffman trees: the counts, the
9224     * lengths of the bit length codes, the literal tree and the distance tree.
9225     * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
9226     */
9227
9228
9229    const send_all_trees = (s, lcodes, dcodes, blcodes) => //    deflate_state *s;
9230    //    int lcodes, dcodes, blcodes; /* number of codes for each tree */
9231    {
9232      let rank;
9233      /* index in bl_order */
9234      //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
9235      //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
9236      //        "too many codes");
9237      //Tracev((stderr, "\nbl counts: "));
9238
9239      send_bits(s, lcodes - 257, 5);
9240      /* not +255 as stated in appnote.txt */
9241
9242      send_bits(s, dcodes - 1, 5);
9243      send_bits(s, blcodes - 4, 4);
9244      /* not -3 as stated in appnote.txt */
9245
9246      for (rank = 0; rank < blcodes; rank++) {
9247        //Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
9248        send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]
9249        /*.Len*/
9250        , 3);
9251      } //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
9252
9253
9254      send_tree(s, s.dyn_ltree, lcodes - 1);
9255      /* literal tree */
9256      //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
9257
9258      send_tree(s, s.dyn_dtree, dcodes - 1);
9259      /* distance tree */
9260      //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
9261    };
9262    /* ===========================================================================
9263     * Check if the data type is TEXT or BINARY, using the following algorithm:
9264     * - TEXT if the two conditions below are satisfied:
9265     *    a) There are no non-portable control characters belonging to the
9266     *       "black list" (0..6, 14..25, 28..31).
9267     *    b) There is at least one printable character belonging to the
9268     *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
9269     * - BINARY otherwise.
9270     * - The following partially-portable control characters form a
9271     *   "gray list" that is ignored in this detection algorithm:
9272     *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
9273     * IN assertion: the fields Freq of dyn_ltree are set.
9274     */
9275
9276
9277    const detect_data_type = s => {
9278      /* black_mask is the bit mask of black-listed bytes
9279       * set bits 0..6, 14..25, and 28..31
9280       * 0xf3ffc07f = binary 11110011111111111100000001111111
9281       */
9282      let black_mask = 0xf3ffc07f;
9283      let n;
9284      /* Check for non-textual ("black-listed") bytes. */
9285
9286      for (n = 0; n <= 31; n++, black_mask >>>= 1) {
9287        if (black_mask & 1 && s.dyn_ltree[n * 2]
9288        /*.Freq*/
9289        !== 0) {
9290          return Z_BINARY;
9291        }
9292      }
9293      /* Check for textual ("white-listed") bytes. */
9294
9295
9296      if (s.dyn_ltree[9 * 2]
9297      /*.Freq*/
9298      !== 0 || s.dyn_ltree[10 * 2]
9299      /*.Freq*/
9300      !== 0 || s.dyn_ltree[13 * 2]
9301      /*.Freq*/
9302      !== 0) {
9303        return Z_TEXT;
9304      }
9305
9306      for (n = 32; n < LITERALS$1; n++) {
9307        if (s.dyn_ltree[n * 2]
9308        /*.Freq*/
9309        !== 0) {
9310          return Z_TEXT;
9311        }
9312      }
9313      /* There are no "black-listed" or "white-listed" bytes:
9314       * this stream either is empty or has tolerated ("gray-listed") bytes only.
9315       */
9316
9317
9318      return Z_BINARY;
9319    };
9320
9321    let static_init_done = false;
9322    /* ===========================================================================
9323     * Initialize the tree data structures for a new zlib stream.
9324     */
9325
9326    const _tr_init$1 = s => {
9327      if (!static_init_done) {
9328        tr_static_init();
9329        static_init_done = true;
9330      }
9331
9332      s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc);
9333      s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc);
9334      s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);
9335      s.bi_buf = 0;
9336      s.bi_valid = 0;
9337      /* Initialize the first block of the first file: */
9338
9339      init_block(s);
9340    };
9341    /* ===========================================================================
9342     * Send a stored block
9343     */
9344
9345
9346    const _tr_stored_block$1 = (s, buf, stored_len, last) => //DeflateState *s;
9347    //charf *buf;       /* input block */
9348    //ulg stored_len;   /* length of input block */
9349    //int last;         /* one if this is the last block for a file */
9350    {
9351      send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3);
9352      /* send block type */
9353
9354      copy_block(s, buf, stored_len, true);
9355      /* with header */
9356    };
9357    /* ===========================================================================
9358     * Send one empty static block to give enough lookahead for inflate.
9359     * This takes 10 bits, of which 7 may remain in the bit buffer.
9360     */
9361
9362
9363    const _tr_align$1 = s => {
9364      send_bits(s, STATIC_TREES << 1, 3);
9365      send_code(s, END_BLOCK, static_ltree);
9366      bi_flush(s);
9367    };
9368    /* ===========================================================================
9369     * Determine the best encoding for the current block: dynamic trees, static
9370     * trees or store, and output the encoded block to the zip file.
9371     */
9372
9373
9374    const _tr_flush_block$1 = (s, buf, stored_len, last) => //DeflateState *s;
9375    //charf *buf;       /* input block, or NULL if too old */
9376    //ulg stored_len;   /* length of input block */
9377    //int last;         /* one if this is the last block for a file */
9378    {
9379      let opt_lenb, static_lenb;
9380      /* opt_len and static_len in bytes */
9381
9382      let max_blindex = 0;
9383      /* index of last bit length code of non zero freq */
9384
9385      /* Build the Huffman trees unless a stored block is forced */
9386
9387      if (s.level > 0) {
9388        /* Check if the file is binary or text */
9389        if (s.strm.data_type === Z_UNKNOWN$1) {
9390          s.strm.data_type = detect_data_type(s);
9391        }
9392        /* Construct the literal and distance trees */
9393
9394
9395        build_tree(s, s.l_desc); // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
9396        //        s->static_len));
9397
9398        build_tree(s, s.d_desc); // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
9399        //        s->static_len));
9400
9401        /* At this point, opt_len and static_len are the total bit lengths of
9402         * the compressed block data, excluding the tree representations.
9403         */
9404
9405        /* Build the bit length tree for the above two trees, and get the index
9406         * in bl_order of the last bit length code to send.
9407         */
9408
9409        max_blindex = build_bl_tree(s);
9410        /* Determine the best encoding. Compute the block lengths in bytes. */
9411
9412        opt_lenb = s.opt_len + 3 + 7 >>> 3;
9413        static_lenb = s.static_len + 3 + 7 >>> 3; // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
9414        //        opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
9415        //        s->last_lit));
9416
9417        if (static_lenb <= opt_lenb) {
9418          opt_lenb = static_lenb;
9419        }
9420      } else {
9421        // Assert(buf != (char*)0, "lost buf");
9422        opt_lenb = static_lenb = stored_len + 5;
9423        /* force a stored block */
9424      }
9425
9426      if (stored_len + 4 <= opt_lenb && buf !== -1) {
9427        /* 4: two words for the lengths */
9428
9429        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
9430         * Otherwise we can't have processed more than WSIZE input bytes since
9431         * the last block flush, because compression would have been
9432         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
9433         * transform a block into a stored block.
9434         */
9435        _tr_stored_block$1(s, buf, stored_len, last);
9436      } else if (s.strategy === Z_FIXED$1 || static_lenb === opt_lenb) {
9437        send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
9438        compress_block(s, static_ltree, static_dtree);
9439      } else {
9440        send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
9441        send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
9442        compress_block(s, s.dyn_ltree, s.dyn_dtree);
9443      } // Assert (s->compressed_len == s->bits_sent, "bad compressed size");
9444
9445      /* The above check is made mod 2^32, for files larger than 512 MB
9446       * and uLong implemented on 32 bits.
9447       */
9448
9449
9450      init_block(s);
9451
9452      if (last) {
9453        bi_windup(s);
9454      } // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
9455      //       s->compressed_len-7*last));
9456
9457    };
9458    /* ===========================================================================
9459     * Save the match info and tally the frequency counts. Return true if
9460     * the current block must be flushed.
9461     */
9462
9463
9464    const _tr_tally$1 = (s, dist, lc) => //    deflate_state *s;
9465    //    unsigned dist;  /* distance of matched string */
9466    //    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
9467    {
9468      //let out_length, in_length, dcode;
9469      s.pending_buf[s.d_buf + s.last_lit * 2] = dist >>
9469> 8 & 0xff;
9470      s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff;
9471      s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff;
9472      s.last_lit++;
9473
9474      if (dist === 0) {
9475        /* lc is the unmatched char */
9476        s.dyn_ltree[lc * 2] /*.Freq*/++;
9477      } else {
9478        s.matches++;
9479        /* Here, lc is the match length - MIN_MATCH */
9480
9481        dist--;
9482        /* dist = match distance - 1 */
9483        //Assert((ush)dist < (ush)MAX_DIST(s) &&
9484        //       (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
9485        //       (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
9486
9487        s.dyn_ltree[(_length_code[lc] + LITERALS$1 + 1) * 2] /*.Freq*/++;
9488        s.dyn_dtree[d_code(dist) * 2] /*.Freq*/++;
9489      } // (!) This block is disabled in zlib defaults,
9490      // don't enable it for binary compatibility
9491      //#ifdef TRUNCATE_BLOCK
9492      //  /* Try to guess if it is profitable to stop the current block here */
9493      //  if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {
9494      //    /* Compute an upper bound for the compressed length */
9495      //    out_length = s.last_lit*8;
9496      //    in_length = s.strstart - s.block_start;
9497      //
9498      //    for (dcode = 0; dcode < D_CODES; dcode++) {
9499      //      out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);
9500      //    }
9501      //    out_length >>>= 3;
9502      //    //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
9503      //    //       s->last_lit, in_length, out_length,
9504      //    //       100L - out_length*100L/in_length));
9505      //    if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) {
9506      //      return true;
9507      //    }
9508      //  }
9509      //#endif
9510
9511
9512      return s.last_lit === s.lit_bufsize - 1;
9513      /* We avoid equality with lit_bufsize because of wraparound at 64K
9514       * on 16 bit machines and because stored blocks are restricted to
9515       * 64K-1 bytes.
9516       */
9517    };
9518
9519    var _tr_init_1 = _tr_init$1;
9520    var _tr_stored_block_1 = _tr_stored_block$1;
9521    var _tr_flush_block_1 = _tr_flush_block$1;
9522    var _tr_tally_1 = _tr_tally$1;
9523    var _tr_align_1 = _tr_align$1;
9524    var trees = {
9525      _tr_init: _tr_init_1,
9526      _tr_stored_block: _tr_stored_block_1,
9527      _tr_flush_block: _tr_flush_block_1,
9528      _tr_tally: _tr_tally_1,
9529      _tr_align: _tr_align_1
9530    }; // Note: adler32 takes 12% for level 0 and 2% for level 6.
9531    // It isn't worth it to make additional optimizations as in original.
9532    // Small size is preferable.
9533    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
9534    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
9535    //
9536    // This software is provided 'as-is', without any express or implied
9537    // warranty. In no event will the authors be held liable for any damages
9538    // arising from the use of this software.
9539    //
9540    // Permission is granted to anyone to use this software for any purpose,
9541    // including commercial applications, and to alter it and redistribute it
9542    // freely, subject to the following restrictions:
9543    //
9544    // 1. The origin of this software must not be misrepresented; you must not
9545    //   claim that you wrote the original software. If you use this software
9546    //   in a product, an acknowledgment in the product documentation would be
9547    //   appreciated but is not required.
9548    // 2. Altered source versions must be plainly marked as such, and must not be
9549    //   misrepresented as being the original software.
9550    // 3. This notice may not be removed or altered from any source distribution.
9551
9552    const adler32 = (adler, buf, len, pos) => {
9553      let s1 = adler & 0xffff | 0,
9554          s2 = adler >>> 16 & 0xffff | 0,
9555          n = 0;
9556
9557      while (len !== 0) {
9558        // Set limit ~ twice less than 5552, to keep
9559        // s2 in 31-bits, because we force signed ints.
9560        // in other case %= will fail.
9561        n = len > 2000 ? 2000 : len;
9562        len -= n;
9563
9564        do {
9565          s1 = s1 + buf[pos++] | 0;
9566          s2 = s2 + s1 | 0;
9567        } while (--n);
9568
9569        s1 %= 65521;
9570        s2 %= 65521;
9571      }
9572
9573      return s1 | s2 << 16 | 0;
9574    };
9575
9576    var adler32_1 = adler32; // Note: we can't get significant speed boost here.
9577    // So write code to minimize size - no pregenerated tables
vendor: 20,537 bytes, lines 9578-10171
9578    // and array tools dependencies.
9579    // (C) 1995-2013 Jean-loup Gailly and Mark Adler
9580    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
9581    //
9582    // This software is provided 'as-is', without any express or implied
9583    // warranty. In no event will the authors be held liable for any damages
9584    // arising from the use of this software.
9585    //
9586    // Permission is granted to anyone to use this software for any purpose,
9587    // including commercial applications, and to alter it and redistribute it
9588    // freely, subject to the following restrictions:
9589    //
9590    // 1. The origin of this software must not be misrepresented; you must not
9591    //   claim that you wrote the original software. If you use this software
9592    //   in a product, an acknowledgment in the product documentation would be
9593    //   appreciated but is not required.
9594    // 2. Altered source versions must be plainly marked as such, and must not be
9595    //   misrepresented as being the original software.
9596    // 3. This notice may not be removed or altered from any source distribution.
9597    // Use ordinary array, since untyped makes no boost here
9598
9599    const makeTable = () => {
9600      let c,
9601          table = [];
9602
9603      for (var n = 0; n < 256; n++) {
9604        c = n;
9605
9606        for (var k = 0; k < 8; k++) {
9607          c = c & 1 ? 0xEDB88320 ^ c >>> 1 : c >>> 1;
9608        }
9609
9610        table[n] = c;
9611      }
9612
9613      return table;
9614    }; // Create table on load. Just 255 signed longs. Not a problem.
9615
9616
9617    const crcTable = new Uint32Array(makeTable());
9618
9619    const crc32 = (crc, buf, len, pos) => {
9620      const t = crcTable;
9621      const end = pos + len;
9622      crc ^= -1;
9623
9624      for (let i = pos; i < end; i++) {
9625        crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 0xFF];
9626      }
9627
9628      return crc ^ -1; // >>> 0;
9629    };
9630
9631    var crc32_1 = crc32; // (C) 1995-2013 Jean-loup Gailly and Mark Adler
9632    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
9633    //
9634    // This software is provided 'as-is', without any express or implied
9635    // warranty. In no event will the authors be held liable for any damages
9636    // arising from the use of this software.
9637    //
9638    // Permission is granted to anyone to use this software for any purpose,
9639    // including commercial applications, and to alter it and redistribute it
9640    // freely, subject to the following restrictions:
9641    //
9642    // 1. The origin of this software must not be misrepresented; you must not
9643    //   claim that you wrote the original software. If you use this software
9644    //   in a product, an acknowledgment in the product documentation would be
9645    //   appreciated but is not required.
9646    // 2. Altered source versions must be plainly marked as such, and must not be
9647    //   misrepresented as being the original software.
9648    // 3. This notice may not be removed or altered from any source distribution.
9649
9650    var messages = {
9651      2: 'need dictionary',
9652
9653      /* Z_NEED_DICT       2  */
9654      1: 'stream end',
9655
9656      /* Z_STREAM_END      1  */
9657      0: '',
9658
9659      /* Z_OK              0  */
9660      '-1': 'file error',
9661
9662      /* Z_ERRNO         (-1) */
9663      '-2': 'stream error',
9664
9665      /* Z_STREAM_ERROR  (-2) */
9666      '-3': 'data error',
9667
9668      /* Z_DATA_ERROR    (-3) */
9669      '-4': 'insufficient memory',
9670
9671      /* Z_MEM_ERROR     (-4) */
9672      '-5': 'buffer error',
9673
9674      /* Z_BUF_ERROR     (-5) */
9675      '-6': 'incompatible version'
9676      /* Z_VERSION_ERROR (-6) */
9677
9678    }; // (C) 1995-2013 Jean-loup Gailly and Mark Adler
9679    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
9680    //
9681    // This software is provided 'as-is', without any express or implied
9682    // warranty. In no event will the authors be held liable for any damages
9683    // arising from the use of this software.
9684    //
9685    // Permission is granted to anyone to use this software for any purpose,
9686    // including commercial applications, and to alter it and redistribute it
9687    // freely, subject to the following restrictions:
9688    //
9689    // 1. The origin of this software must not be misrepresented; you must not
9690    //   claim that you wrote the original software. If you use this software
9691    //   in a product, an acknowledgment in the product documentation would be
9692    //   appreciated but is not required.
9693    // 2. Altered source versions must be plainly marked as such, and must not be
9694    //   misrepresented as being the original software.
9695    // 3. This notice may not be removed or altered from any source distribution.
9696
9697    var constants$2 = {
9698      /* Allowed flush values; see deflate() and inflate() below for details */
9699      Z_NO_FLUSH: 0,
9700      Z_PARTIAL_FLUSH: 1,
9701      Z_SYNC_FLUSH: 2,
9702      Z_FULL_FLUSH: 3,
9703      Z_FINISH: 4,
9704      Z_BLOCK: 5,
9705      Z_TREES: 6,
9706
9707      /* Return codes for the compression/decompression functions. Negative values
9708      * are errors, positive values are used for special but normal events.
9709      */
9710      Z_OK: 0,
9711      Z_STREAM_END: 1,
9712      Z_NEED_DICT: 2,
9713      Z_ERRNO: -1,
9714      Z_STREAM_ERROR: -2,
9715      Z_DATA_ERROR: -3,
9716      Z_MEM_ERROR: -4,
9717      Z_BUF_ERROR: -5,
9718      //Z_VERSION_ERROR: -6,
9719
9720      /* compression levels */
9721      Z_NO_COMPRESSION: 0,
9722      Z_BEST_SPEED: 1,
9723      Z_BEST_COMPRESSION: 9,
9724      Z_DEFAULT_COMPRESSION: -1,
9725      Z_FILTERED: 1,
9726      Z_HUFFMAN_ONLY: 2,
9727      Z_RLE: 3,
9728      Z_FIXED: 4,
9729      Z_DEFAULT_STRATEGY: 0,
9730
9731      /* Possible values of the data_type field (though see inflate()) */
9732      Z_BINARY: 0,
9733      Z_TEXT: 1,
9734      //Z_ASCII:                1, // = Z_TEXT (deprecated)
9735      Z_UNKNOWN: 2,
9736
9737      /* The deflate compression method */
9738      Z_DEFLATED: 8 //Z_NULL:                 null // Use -1 or null inline, depending on var type
9739
9740    }; // (C) 1995-2013 Jean-loup Gailly and Mark Adler
9741    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
9742    //
9743    // This software is provided 'as-is', without any express or implied
9744    // warranty. In no event will the authors be held liable for any damages
9745    // arising from the use of this software.
9746    //
9747    // Permission is granted to anyone to use this software for any purpose,
9748    // including commercial applications, and to alter it and redistribute it
9749    // freely, subject to the following restrictions:
9750    //
9751    // 1. The origin of this software must not be misrepresented; you must not
9752    //   claim that you wrote the original software. If you use this software
9753    //   in a product, an acknowledgment in the product documentation would be
9754    //   appreciated but is not required.
9755    // 2. Altered source versions must be plainly marked as such, and must not be
9756    //   misrepresented as being the original software.
9757    // 3. This notice may not be removed or altered from any source distribution.
9758
9759    const {
9760      _tr_init,
9761      _tr_stored_block,
9762      _tr_flush_block,
9763      _tr_tally,
9764      _tr_align
9765    } = trees;
9766    /* Public constants ==========================================================*/
9767
9768    /* ===========================================================================*/
9769
9770    const {
9771      Z_NO_FLUSH: Z_NO_FLUSH$2,
9772      Z_PARTIAL_FLUSH,
9773      Z_FULL_FLUSH: Z_FULL_FLUSH$1,
9774      Z_FINISH: Z_FINISH$3,
9775      Z_BLOCK: Z_BLOCK$1,
9776      Z_OK: Z_OK$3,
9777      Z_STREAM_END: Z_STREAM_END$3,
9778      Z_STREAM_ERROR: Z_STREAM_ERROR$2,
9779      Z_DATA_ERROR: Z_DATA_ERROR$2,
9780      Z_BUF_ERROR: Z_BUF_ERROR$1,
9781      Z_DEFAULT_COMPRESSION: Z_DEFAULT_COMPRESSION$1,
9782      Z_FILTERED,
9783      Z_HUFFMAN_ONLY,
9784      Z_RLE,
9785      Z_FIXED,
9786      Z_DEFAULT_STRATEGY: Z_DEFAULT_STRATEGY$1,
9787      Z_UNKNOWN,
9788      Z_DEFLATED: Z_DEFLATED$2
9789    } = constants$2;
9790    /*============================================================================*/
9791
9792    const MAX_MEM_LEVEL = 9;
9793    /* Maximum value for memLevel in deflateInit2 */
9794
9795    const MAX_WBITS$1 = 15;
9796    /* 32K LZ77 window */
9797
9798    const DEF_MEM_LEVEL = 8;
9799    const LENGTH_CODES = 29;
9800    /* number of length codes, not counting the special END_BLOCK code */
9801
9802    const LITERALS = 256;
9803    /* number of literal bytes 0..255 */
9804
9805    const L_CODES = LITERALS + 1 + LENGTH_CODES;
9806    /* number of Literal or Length codes, including the END_BLOCK code */
9807
9808    const D_CODES = 30;
9809    /* number of distance codes */
9810
9811    const BL_CODES = 19;
9812    /* number of codes used to transfer the bit lengths */
9813
9814    const HEAP_SIZE = 2 * L_CODES + 1;
9815    /* maximum heap size */
9816
9817    const MAX_BITS = 15;
9818    /* All codes must not exceed MAX_BITS bits */
9819
9820    const MIN_MATCH = 3;
9821    const MAX_MATCH = 258;
9822    const MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1;
9823    const PRESET_DICT = 0x20;
9824    const INIT_STATE = 42;
9825    const EXTRA_STATE = 69;
9826    const NAME_STATE = 73;
9827    const COMMENT_STATE = 91;
9828    const HCRC_STATE = 103;
9829    const BUSY_STATE = 113;
9830    const FINISH_STATE = 666;
9831    const BS_NEED_MORE = 1;
9832    /* block not completed, need more input or more output */
9833
9834    const BS_BLOCK_DONE = 2;
9835    /* block flush performed */
9836
9837    const BS_FINISH_STARTED = 3;
9838    /* finish started, need only more output at next deflate */
9839
9840    const BS_FINISH_DONE = 4;
9841    /* finish done, accept no more input or output */
9842
9843    const OS_CODE = 0x03; // Unix :) . Don't detect, use this default.
9844
9845    const err = (strm, errorCode) => {
9846      strm.msg = messages[errorCode];
9847      return errorCode;
9848    };
9849
9850    const rank = f => {
9851      return (f << 1) - (f > 4 ? 9 : 0);
9852    };
9853
9854    const zero = buf => {
9855      let len = buf.length;
9856
9857      while (--len >= 0) {
9858        buf[len] = 0;
9859      }
9860    };
9861    /* eslint-disable new-cap */
9862
9863
9864    let HASH_ZLIB = (s, prev, data) => (prev << s.hash_shift ^ data) & s.hash_mask; // This hash causes less collisions, https://github.com/nodeca/pako/issues/135
9865    // But breaks binary compatibility
9866    //let HASH_FAST = (s, prev, data) => ((prev << 8) + (prev >> 8) + (data << 4)) & s.hash_mask;
9867
9868
9869    let HASH = HASH_ZLIB;
9870    /* =========================================================================
9871     * Flush as much pending output as possible. All deflate() output goes
9872     * through this function so some applications may wish to modify it
9873     * to avoid allocating a large strm->output buffer and copying into it.
9874     * (See also read_buf()).
9875     */
9876
9877    const flush_pending = strm => {
9878      const s = strm.state; //_tr_flush_bits(s);
9879
9880      let len = s.pending;
9881
9882      if (len > strm.avail_out) {
9883        len = strm.avail_out;
9884      }
9885
9886      if (len === 0) {
9887        return;
9888      }
9889
9890      strm.output.set(s.pending_buf.subarray(s.pending_out, s.pending_out + len), strm.next_out);
9891      strm.next_out += len;
9892      s.pending_out += len;
9893      strm.total_out += len;
9894      strm.avail_out -= len;
9895      s.pending -= len;
9896
9897      if (s.pending === 0) {
9898        s.pending_out = 0;
9899      }
9900    };
9901
9902    const flush_block_only = (s, last) => {
9903      _tr_flush_block(s, s.block_start >= 0 ? s.block_start : -1, s.strstart - s.block_start, last);
9904
9905      s.block_start = s.strstart;
9906      flush_pending(s.strm);
9907    };
9908
9909    const put_byte = (s, b) => {
9910      s.pending_buf[s.pending++] = b;
9911    };
9912    /* =========================================================================
9913     * Put a short in the pending buffer. The 16-bit value is put in MSB order.
9914     * IN assertion: the stream state is correct and there is enough room in
9915     * pending_buf.
9916     */
9917
9918
9919    const putShortMSB = (s, b) => {
9920      //  put_byte(s, (Byte)(b >> 8));
9921      //  put_byte(s, (Byte)(b & 0xff));
9922      s.pending_buf[s.pending++] = b >>> 8 & 0xff;
9923      s.pending_buf[s.pending++] = b & 0xff;
9924    };
9925    /* ===========================================================================
9926     * Read a new buffer from the current input stream, update the adler32
9927     * and total number of bytes read.  All deflate() input goes through
9928     * this function so some applications may wish to modify it to avoid
9929     * allocating a large strm->input buffer and copying from it.
9930     * (See also flush_pending()).
9931     */
9932
9933
9934    const read_buf = (strm, buf, start, size) => {
9935      let len = strm.avail_in;
9936
9937      if (len > size) {
9938        len = size;
9939      }
9940
9941      if (len === 0) {
9942        return 0;
9943      }
9944
9945      strm.avail_in -= len; // zmemcpy(buf, strm->next_in, len);
9946
9947      buf.set(strm.input.subarray(strm.next_in, strm.next_in + len), start);
9948
9949      if (strm.state.wrap === 1) {
9950        strm.adler = adler32_1(strm.adler, buf, len, start);
9951      } else if (strm.state.wrap === 2) {
9952        strm.adler = crc32_1(strm.adler, buf, len, start);
9953      }
9954
9955      strm.next_in += len;
9956      strm.total_in += len;
9957      return len;
9958    };
9959    /* ===========================================================================
9960     * Set match_start to the longest match starting at the given string and
9961     * return its length. Matches shorter or equal to prev_length are discarded,
9962     * in which case the result is equal to prev_length and match_start is
9963     * garbage.
9964     * IN assertions: cur_match is the head of the hash chain for the current
9965     *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
9966     * OUT assertion: the match length is not greater than s->lookahead.
9967     */
9968
9969
9970    const longest_match = (s, cur_match) => {
9971      let chain_length = s.max_chain_length;
9972      /* max hash chain length */
9973
9974      let scan = s.strstart;
9975      /* current string */
9976
9977      let match;
9978      /* matched string */
9979
9980      let len;
9981      /* length of current match */
9982
9983      let best_len = s.prev_length;
9984      /* best match length so far */
9985
9986      let nice_match = s.nice_match;
9987      /* stop if match long enough */
9988
9989      const limit = s.strstart > s.w_size - MIN_LOOKAHEAD ? s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0
9990      /*NIL*/
9991      ;
9992      const _win = s.window; // shortcut
9993
9994      const wmask = s.w_mask;
9995      const prev = s.prev;
9996      /* Stop when cur_match becomes <= limit. To simplify the code,
9997       * we prevent matches with the string of window index 0.
9998       */
9999
10000      const strend = s.strstart + MAX_MATCH;
10001      let scan_end1 = _win[scan + best_len - 1];
10002      let scan_end = _win[scan + best_len];
10003      /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
10004       * It is easy to get rid of this optimization if necessary.
10005       */
10006      // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
10007
10008      /* Do not waste too much time if we already have a good match: */
10009
10010      if (s.prev_length >= s.good_match) {
10011        chain_length >>= 2;
10012      }
10013      /* Do not look for matches beyond the end of the input. This is necessary
10014       * to make deflate deterministic.
10015       */
10016
10017
10018      if (nice_match > s.lookahead) {
10019        nice_match = s.lookahead;
10020      } // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
10021
10022
10023      do {
10024        // Assert(cur_match < s->strstart, "no future");
10025        match = cur_match;
10026        /* Skip to next match if the match length cannot increase
10027         * or if the match length is less than 2.  Note that the checks below
10028         * for insufficient lookahead only occur occasionally for performance
10029         * reasons.  Therefore uninitialized memory will be accessed, and
10030         * conditional jumps will be made that depend on those values.
10031         * However the length of the match is limited to the lookahead, so
10032         * the output of deflate is not affected by the uninitialized values.
10033         */
10034
10035        if (_win[match + best_len] !== scan_end || _win[match + best_len - 1] !== scan_end1 || _win[match] !== _win[scan] || _win[++match] !== _win[scan + 1]) {
10036          continue;
10037        }
10038        /* The check at best_len-1 can be removed because it will be made
10039         * again later. (This heuristic is not always a win.)
10040         * It is not necessary to compare scan[2] and match[2] since they
10041         * are always equal when the other bytes match, given that
10042         * the hash keys are equal and that HASH_BITS >= 8.
10043         */
10044
10045
10046        scan += 2;
10047        match++; // Assert(*scan == *match, "match[2]?");
10048
10049        /* We check for insufficient lookahead only every 8th comparison;
10050         * the 256th check will be made at strstart+258.
10051         */
10052
10053        do {
10054          /*jshint noempty:false*/
10055        } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && scan < strend); // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
10056
10057
10058        len = MAX_MATCH - (strend - scan);
10059        scan = strend - MAX_MATCH;
10060
10061        if (len > best_len) {
10062          s.match_start = cur_match;
10063          best_len = len;
10064
10065          if (len >= nice_match) {
10066            break;
10067          }
10068
10069          scan_end1 = _win[scan + best_len - 1];
10070          scan_end = _win[scan + best_len];
10071        }
10072      } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);
10073
10074      if (best_len <= s.lookahead) {
10075        return best_len;
10076      }
10077
10078      return s.lookahead;
10079    };
10080    /* ===========================================================================
10081     * Fill the window when the lookahead becomes insufficient.
10082     * Updates strstart and lookahead.
10083     *
10084     * IN assertion: lookahead < MIN_LOOKAHEAD
10085     * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
10086     *    At least one byte has been read, or avail_in == 0; reads are
10087     *    performed for at least two bytes (required for the zip translate_eol
10088     *    option -- not supported here).
10089     */
10090
10091
10092    const fill_window = s => {
10093      const _w_size = s.w_size;
10094      let p, n, m, more, str; //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
10095
10096      do {
10097        more = s.window_size - s.lookahead - s.strstart; // JS ints have 32 bit, block below not needed
10098
10099        /* Deal with !@#$% 64K limit: */
10100        //if (sizeof(int) <= 2) {
10101        //    if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
10102        //        more = wsize;
10103        //
10104        //  } else if (more == (unsigned)(-1)) {
10105        //        /* Very unlikely, but possible on 16 bit machine if
10106        //         * strstart == 0 && lookahead == 1 (input done a byte at time)
10107        //         */
10108        //        more--;
10109        //    }
10110        //}
10111
10112        /* If the window is almost full and there is insufficient lookahead,
10113         * move the upper half to the lower one to make room in the upper half.
10114         */
10115
10116        if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
10117          s.window.set(s.window.subarray(_w_size, _w_size + _w_size), 0);
10118          s.match_start -= _w_size;
10119          s.strstart -= _w_size;
10120          /* we now have strstart >= MAX_DIST */
10121
10122          s.block_start -= _w_size;
10123          /* Slide the hash table (could be avoided with 32 bit values
10124           at the expense of memory usage). We slide even when level == 0
10125           to keep the hash table consistent if we switch back to level > 0
10126           later. (Using level 0 permanently is not an optimal usage of
10127           zlib, so we don't care about this pathological case.)
10128           */
10129
10130          n = s.hash_size;
10131          p = n;
10132
10133          do {
10134            m = s.head[--p];
10135            s.head[p] = m >= _w_size ? m - _w_size : 0;
10136          } while (--n);
10137
10138          n = _w_size;
10139          p = n;
10140
10141          do {
10142            m = s.prev[--p];
10143            s.prev[p] = m >= _w_size ? m - _w_size : 0;
10144            /* If n is not on any hash chain, prev[n] is garbage but
10145             * its value will never be used.
10146             */
10147          } while (--n);
10148
10149          more += _w_size;
10150        }
10151
10152        if (s.strm.avail_in === 0) {
10153          break;
10154        }
10155        /* If there was no sliding:
10156         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
10157         *    more == window_size - lookahead - strstart
10158         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
10159         * => more >= window_size - 2*WSIZE + 2
10160         * In the BIG_MEM or MMAP case (not yet supported),
10161         *   window_size == input_size + MIN_LOOKAHEAD  &&
10162         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
10163         * Otherwise, window_size == 2*WSIZE so more >= 2.
10164         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
10165         */
10166        //Assert(more >= 2, "more < 2");
10167
10168
10169        n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
10170        s.lookahead += n;
10171        /* Initialize the hash value now that we have some input
10171: */
10172
10173        if (s.lookahead + s.insert >= MIN_MATCH) {
10174          str = s.strstart - s.insert;
10175          s.ins_h = s.window[str];
10176          /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */
10177
10178          s.ins_h = HASH(s, s.ins_h, s.window[str + 1]); //#if MIN_MATCH != 3
10179          //        Call update_hash() MIN_MATCH-3 more times
10180          //#endif
10181
10182          while (s.insert) {
10183            /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
10184            s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]);
10185            s.prev[str & s.w_mask] = s.head[s.ins_h];
10186            s.head[s.ins_h] = str;
10187            str++;
10188            s.insert--;
10189
10190            if (s.lookahead + s.insert < MIN_MATCH) {
10191              break;
10192            }
10193          }
10194        }
10195        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
10196         * but this is not important since only literal bytes will be emitted.
10197         */
10198
10199      } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);
10200      /* If the WIN_INIT bytes after the end of the current data have never been
10201       * written, then zero those bytes in order to avoid memory check reports of
10202       * the use of uninitialized (or uninitialised as Julian writes) bytes by
10203       * the longest match routines.  Update the high water mark for the next
10204       * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
10205       * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
10206       */
10207      //  if (s.high_water < s.window_size) {
10208      //    const curr = s.strstart + s.lookahead;
10209      //    let init = 0;
10210      //
10211      //    if (s.high_water < curr) {
10212      //      /* Previous high water mark below current data -- zero WIN_INIT
10213      //       * bytes or up to end of window, whichever is less.
10214      //       */
10215      //      init = s.window_size - curr;
10216      //      if (init > WIN_INIT)
10217      //        init = WIN_INIT;
10218      //      zmemzero(s->window + curr, (unsigned)init);
10219      //      s->high_water = curr + init;
10220      //    }
10221      //    else if (s->high_water < (ulg)curr + WIN_INIT) {
10222      //      /* High water mark at or above current data, but below current data
10223      //       * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
10224      //       * to end of window, whichever is less.
10225      //       */
10226      //      init = (ulg)curr + WIN_INIT - s->high_water;
10227      //      if (init > s->window_size - s->high_water)
10228      //        init = s->window_size - s->high_water;
10229      //      zmemzero(s->window + s->high_water, (unsigned)init);
10230      //      s->high_water += init;
10231      //    }
10232      //  }
10233      //
10234      //  Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
10235      //    "not enough room for search");
10236
10237    };
10238    /* ===========================================================================
10239     * Copy without compression as much as possible from the input stream, return
10240     * the current block state.
10241     * This function does not insert new strings in the dictionary since
10242     * uncompressible data is probably not useful. This function is used
10243     * only for the level=0 compression option.
10244     * NOTE: this function should be optimized to avoid extra copying from
10245     * window to pending_buf.
10246     */
10247
10248
10249    const deflate_stored = (s, flush) => {
10250      /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
10251       * to pending_buf_size, and each stored block has a 5 byte header:
10252       */
10253      let max_block_size = 0xffff;
10254
10255      if (max_block_size > s.pending_buf_size - 5) {
10256        max_block_size = s.pending_buf_size - 5;
10257      }
10258      /* Copy as much as possible from input to output: */
10259
10260
10261      for (;;) {
10262        /* Fill the window as much as possible: */
10263        if (s.lookahead <= 1) {
10264          //Assert(s->strstart < s->w_size+MAX_DIST(s) ||
10265          //  s->block_start >= (long)s->w_size, "slide too late");
10266          //      if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||
10267          //        s.block_start >= s.w_size)) {
10268          //        throw  new Error("slide too late");
10269          //      }
10270          fill_window(s);
10271
10272          if (s.lookahead === 0 && flush === Z_NO_FLUSH$2) {
10273            return BS_NEED_MORE;
10274          }
10275
10276          if (s.lookahead === 0) {
10277            break;
10278          }
10279          /* flush the current block */
10280
10281        } //Assert(s->block_start >= 0L, "block gone");
10282        //    if (s.block_start < 0) throw new Error("block gone");
10283
10284
10285        s.strstart += s.lookahead;
10286        s.lookahead = 0;
10287        /* Emit a stored block if pending_buf will be full: */
10288
10289        const max_start = s.block_start + max_block_size;
10290
10291        if (s.strstart === 0 || s.strstart >= max_start) {
10292          /* strstart == 0 is possible when wraparound on 16-bit machine */
10293          s.lookahead = s.strstart - max_start;
10294          s.strstart = max_start;
10295          /*** FLUSH_BLOCK(s, 0); ***/
10296
10297          flush_block_only(s, false);
10298
10299          if (s.strm.avail_out === 0) {
10300            return BS_NEED_MORE;
10301          }
10302          /***/
10303
10304        }
10305        /* Flush if we may have to slide, otherwise block_start may become
10306         * negative and the data will be gone:
10307         */
10308
10309
10310        if (s.strstart - s.block_start >= s.w_size - MIN_LOOKAHEAD) {
10311          /*** FLUSH_BLOCK(s, 0); ***/
10312          flush_block_only(s, false);
10313
10314          if (s.strm.avail_out === 0) {
10315            return BS_NEED_MORE;
10316          }
10317          /***/
10318
10319        }
10320      }
10321
10322      s.insert = 0;
10323
10324      if (flush === Z_FINISH$3) {
10325        /*** FLUSH_BLOCK(s, 1); ***/
10326        flush_block_only(s, true);
10327
10328        if (s.strm.avail_out === 0) {
10329          return BS_FINISH_STARTED;
10330        }
10331        /***/
10332
10333
10334        return BS_FINISH_DONE;
10335      }
10336
10337      if (s.strstart > s.block_start) {
10338        /*** FLUSH_BLOCK(s, 0); ***/
10339        flush_block_only(s, false);
10340
10341        if (s.strm.avail_out === 0) {
10342          return BS_NEED_MORE;
10343        }
10344        /***/
10345
10346      }
10347
10348      return BS_NEED_MORE;
10349    };
10350    /* ===========================================================================
10351     * Compress as much as possible from the input stream, return the current
10352     * block state.
10353     * This function does not perform lazy evaluation of matches and inserts
10354     * new strings in the dictionary only for unmatched strings or for short
vendor: 16,384 bytes, lines 10355-10906
10355     * matches. It is used only for the fast compression options.
10356     */
10357
10358
10359    const deflate_fast = (s, flush) => {
10360      let hash_head;
10361      /* head of the hash chain */
10362
10363      let bflush;
10364      /* set if current block must be flushed */
10365
10366      for (;;) {
10367        /* Make sure that we always have enough lookahead, except
10368         * at the end of the input file. We need MAX_MATCH bytes
10369         * for the next match, plus MIN_MATCH bytes to insert the
10370         * string following the next match.
10371         */
10372        if (s.lookahead < MIN_LOOKAHEAD) {
10373          fill_window(s);
10374
10375          if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) {
10376            return BS_NEED_MORE;
10377          }
10378
10379          if (s.lookahead === 0) {
10380            break;
10381            /* flush the current block */
10382          }
10383        }
10384        /* Insert the string window[strstart .. strstart+2] in the
10385         * dictionary, and set hash_head to the head of the hash chain:
10386         */
10387
10388
10389        hash_head = 0
10390        /*NIL*/
10391        ;
10392
10393        if (s.lookahead >= MIN_MATCH) {
10394          /*** INSERT_STRING(s, s.strstart, hash_head); ***/
10395          s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);
10396          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
10397          s.head[s.ins_h] = s.strstart;
10398          /***/
10399        }
10400        /* Find the longest match, discarding those <= prev_length.
10401         * At this point we have always match_length < MIN_MATCH
10402         */
10403
10404
10405        if (hash_head !== 0
10406        /*NIL*/
10407        && s.strstart - hash_head <= s.w_size - MIN_LOOKAHEAD) {
10408          /* To simplify the code, we prevent matches with the string
10409           * of window index 0 (in particular we have to avoid a match
10410           * of the string with itself at the start of the input file).
10411           */
10412          s.match_length = longest_match(s, hash_head);
10413          /* longest_match() sets match_start */
10414        }
10415
10416        if (s.match_length >= MIN_MATCH) {
10417          // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only
10418
10419          /*** _tr_tally_dist(s, s.strstart - s.match_start,
10420                         s.match_length - MIN_MATCH, bflush); ***/
10421          bflush = _tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);
10422          s.lookahead -= s.match_length;
10423          /* Insert new strings in the hash table only if the match length
10424           * is not too large. This saves time but degrades compression.
10425           */
10426
10427          if (s.match_length <= s.max_lazy_match
10428          /*max_insert_length*/
10429          && s.lookahead >= MIN_MATCH) {
10430            s.match_length--;
10431            /* string at strstart already in table */
10432
10433            do {
10434              s.strstart++;
10435              /*** INSERT_STRING(s, s.strstart, hash_head); ***/
10436
10437              s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);
10438              hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
10439              s.head[s.ins_h] = s.strstart;
10440              /***/
10441
10442              /* strstart never exceeds WSIZE-MAX_MATCH, so there are
10443               * always MIN_MATCH bytes ahead.
10444               */
10445            } while (--s.match_length !== 0);
10446
10447            s.strstart++;
10448          } else {
10449            s.strstart += s.match_length;
10450            s.match_length = 0;
10451            s.ins_h = s.window[s.strstart];
10452            /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */
10453
10454            s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + 1]); //#if MIN_MATCH != 3
10455            //                Call UPDATE_HASH() MIN_MATCH-3 more times
10456            //#endif
10457
10458            /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
10459             * matter since it will be recomputed at next deflate call.
10460             */
10461          }
10462        } else {
10463          /* No match, output a literal byte */
10464          //Tracevv((stderr,"%c", s.window[s.strstart]));
10465
10466          /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
10467          bflush = _tr_tally(s, 0, s.window[s.strstart]);
10468          s.lookahead--;
10469          s.strstart++;
10470        }
10471
10472        if (bflush) {
10473          /*** FLUSH_BLOCK(s, 0); ***/
10474          flush_block_only(s, false);
10475
10476          if (s.strm.avail_out === 0) {
10477            return BS_NEED_MORE;
10478          }
10479          /***/
10480
10481        }
10482      }
10483
10484      s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;
10485
10486      if (flush === Z_FINISH$3) {
10487        /*** FLUSH_BLOCK(s, 1); ***/
10488        flush_block_only(s, true);
10489
10490        if (s.strm.avail_out === 0) {
10491          return BS_FINISH_STARTED;
10492        }
10493        /***/
10494
10495
10496        return BS_FINISH_DONE;
10497      }
10498
10499      if (s.last_lit) {
10500        /*** FLUSH_BLOCK(s, 0); ***/
10501        flush_block_only(s, false);
10502
10503        if (s.strm.avail_out === 0) {
10504          return BS_NEED_MORE;
10505        }
10506        /***/
10507
10508      }
10509
10510      return BS_BLOCK_DONE;
10511    };
10512    /* ===========================================================================
10513     * Same as above, but achieves better compression. We use a lazy
10514     * evaluation for matches: a match is finally adopted only if there is
10515     * no better match at the next window position.
10516     */
10517
10518
10519    const deflate_slow = (s, flush) => {
10520      let hash_head;
10521      /* head of hash chain */
10522
10523      let bflush;
10524      /* set if current block must be flushed */
10525
10526      let max_insert;
10527      /* Process the input block. */
10528
10529      for (;;) {
10530        /* Make sure that we always have enough lookahead, except
10531         * at the end of the input file. We need MAX_MATCH bytes
10532         * for the next match, plus MIN_MATCH bytes to insert the
10533         * string following the next match.
10534         */
10535        if (s.lookahead < MIN_LOOKAHEAD) {
10536          fill_window(s);
10537
10538          if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH$2) {
10539            return BS_NEED_MORE;
10540          }
10541
10542          if (s.lookahead === 0) {
10543            break;
10544          }
10545          /* flush the current block */
10546
10547        }
10548        /* Insert the string window[strstart .. strstart+2] in the
10549         * dictionary, and set hash_head to the head of the hash chain:
10550         */
10551
10552
10553        hash_head = 0
10554        /*NIL*/
10555        ;
10556
10557        if (s.lookahead >= MIN_MATCH) {
10558          /*** INSERT_STRING(s, s.strstart, hash_head); ***/
10559          s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);
10560          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
10561          s.head[s.ins_h] = s.strstart;
10562          /***/
10563        }
10564        /* Find the longest match, discarding those <= prev_length.
10565         */
10566
10567
10568        s.prev_length = s.match_length;
10569        s.prev_match = s.match_start;
10570        s.match_length = MIN_MATCH - 1;
10571
10572        if (hash_head !== 0
10573        /*NIL*/
10574        && s.prev_length < s.max_lazy_match && s.strstart - hash_head <= s.w_size - MIN_LOOKAHEAD
10575        /*MAX_DIST(s)*/
10576        ) {
10577          /* To simplify the code, we prevent matches with the string
10578           * of window index 0 (in particular we have to avoid a match
10579           * of the string with itself at the start of the input file).
10580           */
10581          s.match_length = longest_match(s, hash_head);
10582          /* longest_match() sets match_start */
10583
10584          if (s.match_length <= 5 && (s.strategy === Z_FILTERED || s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096
10585          /*TOO_FAR*/
10586          )) {
10587            /* If prev_match is also MIN_MATCH, match_start is garbage
10588             * but we will ignore the current match anyway.
10589             */
10590            s.match_length = MIN_MATCH - 1;
10591          }
10592        }
10593        /* If there was a match at the previous step and the current
10594         * match is not better, output the previous match:
10595         */
10596
10597
10598        if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {
10599          max_insert = s.strstart + s.lookahead - MIN_MATCH;
10600          /* Do not insert strings in hash table beyond this. */
10601          //check_match(s, s.strstart-1, s.prev_match, s.prev_length);
10602
10603          /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
10604                         s.prev_length - MIN_MATCH, bflush);***/
10605
10606          bflush = _tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);
10607          /* Insert in hash table all strings up to the end of the match.
10608           * strstart-1 and strstart are already inserted. If there is not
10609           * enough lookahead, the last two strings are not inserted in
10610           * the hash table.
10611           */
10612
10613          s.lookahead -= s.prev_length - 1;
10614          s.prev_length -= 2;
10615
10616          do {
10617            if (++s.strstart <= max_insert) {
10618              /*** INSERT_STRING(s, s.strstart, hash_head); ***/
10619              s.ins_h = HASH(s, s.ins_h, s.window[s.strstart + MIN_MATCH - 1]);
10620              hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
10621              s.head[s.ins_h] = s.strstart;
10622              /***/
10623            }
10624          } while (--s.prev_length !== 0);
10625
10626          s.match_available = 0;
10627          s.match_length = MIN_MATCH - 1;
10628          s.strstart++;
10629
10630          if (bflush) {
10631            /*** FLUSH_BLOCK(s, 0); ***/
10632            flush_block_only(s, false);
10633
10634            if (s.strm.avail_out === 0) {
10635              return BS_NEED_MORE;
10636            }
10637            /***/
10638
10639          }
10640        } else if (s.match_available) {
10641          /* If there was no match at the previous position, output a
10642           * single literal. If there was a match but the current match
10643           * is longer, truncate the previous match to a single literal.
10644           */
10645          //Tracevv((stderr,"%c", s->window[s->strstart-1]));
10646
10647          /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
10648          bflush = _tr_tally(s, 0, s.window[s.strstart - 1]);
10649
10650          if (bflush) {
10651            /*** FLUSH_BLOCK_ONLY(s, 0) ***/
10652            flush_block_only(s, false);
10653            /***/
10654          }
10655
10656          s.strstart++;
10657          s.lookahead--;
10658
10659          if (s.strm.avail_out === 0) {
10660            return BS_NEED_MORE;
10661          }
10662        } else {
10663          /* There is no previous match to compare with, wait for
10664           * the next step to decide.
10665           */
10666          s.match_available = 1;
10667          s.strstart++;
10668          s.lookahead--;
10669        }
10670      } //Assert (flush != Z_NO_FLUSH, "no flush?");
10671
10672
10673      if (s.match_available) {
10674        //Tracevv((stderr,"%c", s->window[s->strstart-1]));
10675
10676        /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
10677        bflush = _tr_tally(s, 0, s.window[s.strstart - 1]);
10678        s.match_available = 0;
10679      }
10680
10681      s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;
10682
10683      if (flush === Z_FINISH$3) {
10684        /*** FLUSH_BLOCK(s, 1); ***/
10685        flush_block_only(s, true);
10686
10687        if (s.strm.avail_out === 0) {
10688          return BS_FINISH_STARTED;
10689        }
10690        /***/
10691
10692
10693        return BS_FINISH_DONE;
10694      }
10695
10696      if (s.last_lit) {
10697        /*** FLUSH_BLOCK(s, 0); ***/
10698        flush_block_only(s, false);
10699
10700        if (s.strm.avail_out === 0) {
10701          return BS_NEED_MORE;
10702        }
10703        /***/
10704
10705      }
10706
10707      return BS_BLOCK_DONE;
10708    };
10709    /* ===========================================================================
10710     * For Z_RLE, simply look for runs of bytes, generate matches only of distance
10711     * one.  Do not maintain a hash table.  (It will be regenerated if this run of
10712     * deflate switches away from Z_RLE.)
10713     */
10714
10715
10716    const deflate_rle = (s, flush) => {
10717      let bflush;
10718      /* set if current block must be flushed */
10719
10720      let prev;
10721      /* byte at distance one to match */
10722
10723      let scan, strend;
10724      /* scan goes up to strend for length of run */
10725
10726      const _win = s.window;
10727
10728      for (;;) {
10729        /* Make sure that we always have enough lookahead, except
10730         * at the end of the input file. We need MAX_MATCH bytes
10731         * for the longest run, plus one for the unrolled loop.
10732         */
10733        if (s.lookahead <= MAX_MATCH) {
10734          fill_window(s);
10735
10736          if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH$2) {
10737            return BS_NEED_MORE;
10738          }
10739
10740          if (s.lookahead === 0) {
10741            break;
10742          }
10743          /* flush the current block */
10744
10745        }
10746        /* See how many times the previous byte repeats */
10747
10748
10749        s.match_length = 0;
10750
10751        if (s.lookahead >= MIN_MATCH && s.strstart > 0) {
10752          scan = s.strstart - 1;
10753          prev = _win[scan];
10754
10755          if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {
10756            strend = s.strstart + MAX_MATCH;
10757
10758            do {
10759              /*jshint noempty:false*/
10760            } while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] && scan < strend);
10761
10762            s.match_length = MAX_MATCH - (strend - scan);
10763
10764            if (s.match_length > s.lookahead) {
10765              s.match_length = s.lookahead;
10766            }
10767          } //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
10768
10769        }
10770        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
10771
10772
10773        if (s.match_length >= MIN_MATCH) {
10774          //check_match(s, s.strstart, s.strstart - 1, s.match_length);
10775
10776          /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/
10777          bflush = _tr_tally(s, 1, s.match_length - MIN_MATCH);
10778          s.lookahead -= s.match_length;
10779          s.strstart += s.match_length;
10780          s.match_length = 0;
10781        } else {
10782          /* No match, output a literal byte */
10783          //Tracevv((stderr,"%c", s->window[s->strstart]));
10784
10785          /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
10786          bflush = _tr_tally(s, 0, s.window[s.strstart]);
10787          s.lookahead--;
10788          s.strstart++;
10789        }
10790
10791        if (bflush) {
10792          /*** FLUSH_BLOCK(s, 0); ***/
10793          flush_block_only(s, false);
10794
10795          if (s.strm.avail_out === 0) {
10796            return BS_NEED_MORE;
10797          }
10798          /***/
10799
10800        }
10801      }
10802
10803      s.insert = 0;
10804
10805      if (flush === Z_FINISH$3) {
10806        /*** FLUSH_BLOCK(s, 1); ***/
10807        flush_block_only(s, true);
10808
10809        if (s.strm.avail_out === 0) {
10810          return BS_FINISH_STARTED;
10811        }
10812        /***/
10813
10814
10815        return BS_FINISH_DONE;
10816      }
10817
10818      if (s.last_lit) {
10819        /*** FLUSH_BLOCK(s, 0); ***/
10820        flush_block_only(s, false);
10821
10822        if (s.strm.avail_out === 0) {
10823          return BS_NEED_MORE;
10824        }
10825        /***/
10826
10827      }
10828
10829      return BS_BLOCK_DONE;
10830    };
10831    /* ===========================================================================
10832     * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
10833     * (It will be regenerated if this run of deflate switches away from Huffman.)
10834     */
10835
10836
10837    const deflate_huff = (s, flush) => {
10838      let bflush;
10839      /* set if current block must be flushed */
10840
10841      for (;;) {
10842        /* Make sure that we have a literal to write. */
10843        if (s.lookahead === 0) {
10844          fill_window(s);
10845
10846          if (s.lookahead === 0) {
10847            if (flush === Z_NO_FLUSH$2) {
10848              return BS_NEED_MORE;
10849            }
10850
10851            break;
10852            /* flush the current block */
10853          }
10854        }
10855        /* Output a literal byte */
10856
10857
10858        s.match_length = 0; //Tracevv((stderr,"%c", s->window[s->strstart]));
10859
10860        /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
10861
10862        bflush = _tr_tally(s, 0, s.window[s.strstart]);
10863        s.lookahead--;
10864        s.strstart++;
10865
10866        if (bflush) {
10867          /*** FLUSH_BLOCK(s, 0); ***/
10868          flush_block_only(s, false);
10869
10870          if (s.strm.avail_out === 0) {
10871            return BS_NEED_MORE;
10872          }
10873          /***/
10874
10875        }
10876      }
10877
10878      s.insert = 0;
10879
10880      if (flush === Z_FINISH$3) {
10881        /*** FLUSH_BLOCK(s, 1); ***/
10882        flush_block_only(s, true);
10883
10884        if (s.strm.avail_out === 0) {
10885          return BS_FINISH_STARTED;
10886        }
10887        /***/
10888
10889
10890        return BS_FINISH_DONE;
10891      }
10892
10893      if (s.last_lit) {
10894        /*** FLUSH_BLOCK(s, 0); ***/
10895        flush_block_only(s, false);
10896
10897        if (s.strm.avail_out === 0) {
10898          return BS_NEED_MORE;
10899        }
10900        /***/
10901
10902      }
10903
10904      return BS_BLOCK_DONE;
10905    };
10906    /* Values for max_lazy_match, good_match and max_c
10906hain_length, depending on
10907     * the desired pack level (0..9). The values given below have been tuned to
10908     * exclude worst case performance for pathological files. Better values may be
10909     * found for specific files.
10910     */
10911
10912
10913    function Config(good_length, max_lazy, nice_length, max_chain, func) {
10914      this.good_length = good_length;
10915      this.max_lazy = max_lazy;
10916      this.nice_length = nice_length;
10917      this.max_chain = max_chain;
10918      this.func = func;
10919    }
10920
10921    const configuration_table = [
10922    /*      good lazy nice chain */
10923    new Config(0, 0, 0, 0, deflate_stored),
10924    /* 0 store only */
10925    new Config(4, 4, 8, 4, deflate_fast),
10926    /* 1 max speed, no lazy matches */
10927    new Config(4, 5, 16, 8, deflate_fast),
10928    /* 2 */
10929    new Config(4, 6, 32, 32, deflate_fast),
10930    /* 3 */
10931    new Config(4, 4, 16, 16, deflate_slow),
10932    /* 4 lazy matches */
10933    new Config(8, 16, 32, 32, deflate_slow),
10934    /* 5 */
10935    new Config(8, 16, 128, 128, deflate_slow),
10936    /* 6 */
10937    new Config(8, 32, 128, 256, deflate_slow),
10938    /* 7 */
10939    new Config(32, 128, 258, 1024, deflate_slow),
10940    /* 8 */
10941    new Config(32, 258, 258, 4096, deflate_slow)
10942    /* 9 max compression */
10943    ];
10944    /* ===========================================================================
10945     * Initialize the "longest match" routines for a new zlib stream
10946     */
10947
10948    const lm_init = s => {
10949      s.window_size = 2 * s.w_size;
10950      /*** CLEAR_HASH(s); ***/
10951
10952      zero(s.head); // Fill with NIL (= 0);
10953
10954      /* Set the default configuration parameters:
10955       */
10956
10957      s.max_lazy_match = configuration_table[s.level].max_lazy;
10958      s.good_match = configuration_table[s.level].good_length;
10959      s.nice_match = configuration_table[s.level].nice_length;
10960      s.max_chain_length = configuration_table[s.level].max_chain;
10961      s.strstart = 0;
10962      s.block_start = 0;
10963      s.lookahead = 0;
10964      s.insert = 0;
10965      s.match_length = s.prev_length = MIN_MATCH - 1;
10966      s.match_available = 0;
10967      s.ins_h = 0;
10968    };
10969
10970    function DeflateState() {
10971      this.strm = null;
10972      /* pointer back to this zlib stream */
10973
10974      this.status = 0;
10975      /* as the name implies */
10976
10977      this.pending_buf = null;
10978      /* output still pending */
10979
10980      this.pending_buf_size = 0;
10981      /* size of pending_buf */
10982
10983      this.pending_out = 0;
10984      /* next pending byte to output to the stream */
10985
10986      this.pending = 0;
10987      /* nb of bytes in the pending buffer */
10988
10989      this.wrap = 0;
10990      /* bit 0 true for zlib, bit 1 true for gzip */
10991
10992      this.gzhead = null;
10993      /* gzip header information to write */
10994
10995      this.gzindex = 0;
10996      /* where in extra, name, or comment */
10997
10998      this.method = Z_DEFLATED$2;
10999      /* can only be DEFLATED */
11000
11001      this.last_flush = -1;
11002      /* value of flush param for previous deflate call */
11003
11004      this.w_size = 0;
11005      /* LZ77 window size (32K by default) */
11006
11007      this.w_bits = 0;
11008      /* log2(w_size)  (8..16) */
11009
11010      this.w_mask = 0;
11011      /* w_size - 1 */
11012
11013      this.window = null;
11014      /* Sliding window. Input bytes are read into the second half of the window,
11015       * and move to the first half later to keep a dictionary of at least wSize
11016       * bytes. With this organization, matches are limited to a distance of
11017       * wSize-MAX_MATCH bytes, but this ensures that IO is always
11018       * performed with a length multiple of the block size.
11019       */
11020
11021      this.window_size = 0;
11022      /* Actual size of window: 2*wSize, except when the user input buffer
11023       * is directly used as sliding window.
11024       */
11025
11026      this.prev = null;
11027      /* Link to older string with same hash index. To limit the size of this
11028       * array to 64K, this link is maintained only for the last 32K strings.
11029       * An index in this array is thus a window index modulo 32K.
11030       */
11031
11032      this.head = null;
11033      /* Heads of the hash chains or NIL. */
11034
11035      this.ins_h = 0;
11036      /* hash index of string to be inserted */
11037
11038      this.hash_size = 0;
11039      /* number of elements in hash table */
11040
11041      this.hash_bits = 0;
11042      /* log2(hash_size) */
11043
11044      this.hash_mask = 0;
11045      /* hash_size-1 */
11046
11047      this.hash_shift = 0;
11048      /* Number of bits by which ins_h must be shifted at each input
11049       * step. It must be such that after MIN_MATCH steps, the oldest
11050       * byte no longer takes part in the hash key, that is:
11051       *   hash_shift * MIN_MATCH >= hash_bits
11052       */
11053
11054      this.block_start = 0;
11055      /* Window position at the beginning of the current output block. Gets
11056       * negative when the window is moved backwards.
11057       */
11058
11059      this.match_length = 0;
11060      /* length of best match */
11061
11062      this.prev_match = 0;
11063      /* previous match */
11064
11065      this.match_available = 0;
11066      /* set if previous match exists */
11067
11068      this.strstart = 0;
11069      /* start of string to insert */
11070
11071      this.match_start = 0;
11072      /* start of matching string */
11073
11074      this.lookahead = 0;
11075      /* number of valid bytes ahead in window */
11076
11077      this.prev_length = 0;
11078      /* Length of the best match at previous step. Matches not greater than this
11079       * are discarded. This is used in the lazy match evaluation.
11080       */
11081
11082      this.max_chain_length = 0;
11083      /* To speed up deflation, hash chains are never searched beyond this
11084       * length.  A higher limit improves compression ratio but degrades the
11085       * speed.
11086       */
11087
11088      this.max_lazy_match = 0;
11089      /* Attempt to find a better match only when the current match is strictly
11090       * smaller than this value. This mechanism is used only for compression
11091       * levels >= 4.
11092       */
11093      // That's alias to max_lazy_match, don't use directly
11094      //this.max_insert_length = 0;
11095
11096      /* Insert new strings in the hash table only if the match length is not
11097       * greater than this length. This saves time but degrades compression.
11098       * max_insert_length is used only for compression levels <= 3.
11099       */
11100
11101      this.level = 0;
11102      /* compression level (1..9) */
11103
11104      this.strategy = 0;
11105      /* favor or force Huffman coding*/
11106
11107      this.good_match = 0;
11108      /* Use a faster search when the previous match is longer than this */
11109
11110      this.nice_match = 0;
11111      /* Stop searching when current match exceeds this */
11112
11113      /* used by trees.c: */
11114
11115      /* Didn't use ct_data typedef below to suppress compiler warning */
11116      // struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
11117      // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
11118      // struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
11119      // Use flat array of DOUBLE size, with interleaved fata,
11120      // because JS does not support effective
11121
11122      this.dyn_ltree = new Uint16Array(HEAP_SIZE * 2);
11123      this.dyn_dtree = new Uint16Array((2 * D_CODES + 1) * 2);
11124      this.bl_tree = new Uint16Array((2 * BL_CODES + 1) * 2);
11125      zero(this.dyn_ltree);
11126      zero(this.dyn_dtree);
11127      zero(this.bl_tree);
11128      this.l_desc = null;
11129      /* desc. for literal tree */
11130
11131      this.d_desc = null;
11132      /* desc. for distance tree */
11133
11134      this.bl_desc = null;
11135      /* desc. for bit length tree */
11136      //ush bl_count[MAX_BITS+1];
11137
11138      this.bl_count = new Uint16Array(MAX_BITS + 1);
11139      /* number of codes at each bit length for an optimal tree */
11140      //int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
11141
11142      this.heap = new Uint16Array(2 * L_CODES + 1);
11143      /* heap used to build the Huffman trees */
11144
11145      zero(this.heap);
11146      this.heap_len = 0;
11147      /* number of elements in the heap */
11148
11149      this.heap_max = 0;
11150      /* element of largest frequency */
11151
11152      /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
11153       * The same heap array is used to build all trees.
11154       */
11155
11156      this.depth = new Uint16Array(2 * L_CODES + 1); //uch depth[2*L_CODES+1];
11157
11158      zero(this.depth);
11159      /* Depth of each subtree used as tie breaker for trees of equal frequency
11160       */
11161
11162      this.l_buf = 0;
11163      /* buffer index for literals or lengths */
11164
11165      this.lit_bufsize = 0;
11166      /* Size of match buffer for literals/lengths.  There are 4 reasons for
11167       * limiting lit_bufsize to 64K:
11168       *   - frequencies can be kept in 16 bit counters
11169       *   - if compression is not successful for the first block, all input
11170       *     data is still in the window so we can still emit a stored block even
11171       *     when input comes from standard input.  (This can also be done for
11172       *     all blocks if lit_bufsize is not greater than 32K.)
11173       *   - if compression is not successful for a file smaller than 64K, we can
11174       *     even emit a stored file instead of a stored block (saving 5 bytes).
11175       *     This is applicable only for zip (not gzip or zlib).
11176       *   - creating new Huffman trees less frequently may not provide fast
11177       *     adaptation to changes in the input data statistics. (Take for
11178       *     example a binary file with poorly compressible code followed by
11179       *     a highly compressible string table.) Smaller buffer sizes give
11180       *     fast adaptation but have of course the overhead of transmitting
11181       *     trees more frequently.
11182       *   - I can't count above 4
11183       */
11184
11185      this.last_lit = 0;
11186      /* running index in l_buf */
11187
11188      this.d_buf = 0;
11189      /* Buffer index for distances. To simplify the code, d_buf and l_buf have
11190       * the same number of elements. To use different lengths, an extra flag
11191       * array would be necessary.
11192       */
11193
11194      this.opt_len = 0;
11195      /* bit length of current block with optimal trees */
11196
11197      this.static_len = 0;
11198      /* bit length of current block with static trees */
11199
11200      this.matches = 0;
11201      /* number of string matches in current block */
11202
11203      this.insert = 0;
11204      /* bytes at end of window left to insert */
11205
11206      this.bi_buf = 0;
11207      /* Output buffer. bits are inserted starting at the bottom (least
11208       * significant bits).
11209       */
11210
11211      this.bi_valid = 0;
11212      /* Number of valid bits in bi_buf.  All bits above the last valid bit
11213       * are always zero.
11214       */
11215      // Used for window memory init. We safely ignore it for JS. That makes
11216      // sense only for pointers and memory check tools.
11217      //this.high_water = 0;
11218
11219      /* High water mark offset in window for initialized bytes -- bytes above
11220       * this are set to zero in order to avoid memory check warnings when
11221       * longest match routines access bytes past the input.  This is then
11222       * updated to the new high water mark.
11223       */
11224    }
11225
11226    const deflateResetKeep = strm => {
11227      if (!strm || !strm.state) {
11228        return err(strm, Z_STREAM_ERROR$2);
11229      }
11230
11231      strm.total_in = strm.total_out = 0;
11232      strm.data_type = Z_UNKNOWN;
11233      const s = strm.state;
11234      s.pending = 0;
11235      s.pending_out = 0;
11236
11237      if (s.wrap < 0) {
11238        s.wrap = -s.wrap;
11239        /* was made negative by deflate(..., Z_FINISH); */
11240      }
11241
11242      s.status = s.wrap ? INIT_STATE : BUSY_STATE;
11243      strm.adler = s.wrap === 2 ? 0 // crc32(0, Z_NULL, 0)
11244      : 1; // adler32(0, Z_NULL, 0)
11245
11246      s.last_flush = Z_NO_FLUSH$2;
11247
11248      _tr_init(s);
11249
11250      return Z_OK$3;
11251    };
11252
11253    const deflateReset = strm => {
11254      const ret = deflateResetKeep(strm);
11255
11256      if (ret === Z_OK$3) {
11257        lm_init(strm.state);
11258      }
11259
11260      return ret;
11261    };
11262
11263    const deflateSetHeader = (strm, head) => {
11264      if (!strm || !strm.state) {
11265        return Z_STREAM_ERROR$2;
11266      }
11267
11268      if (strm.state.wrap !== 2) {
11269        return Z_STREAM_ERROR$2;
11270      }
11271
11272      strm.state.gzhead = head;
11273      return Z_OK$3;
11274    };
11275
11276    const deflateInit2 = (strm, level, method, windowBits, memLevel, strategy) => {
11277      if (!strm) {
11278        // === Z_NULL
11279        return Z_STREAM_ERROR$2;
11280      }
11281
11282      let wrap = 1;
11283
11284      if (level === Z_DEFAULT_COMPRESSION$1) {
11285        level = 6;
11286      }
11287
11288      if (windowBits < 0) {
11289        /* suppress zlib wrapper */
11290        wrap = 0;
11291        windowBits = -windowBits;
11292      } else if (windowBits > 15) {
11293        wrap = 2;
11294        /* write gzip wrapper instead */
11295
11296        windowBits -= 16;
11297      }
11298
11299      if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED$2 || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
11300        return err(strm, Z_STREAM_ERROR$2);
11301      }
11302
11303      if (windowBits === 8) {
11304        windowBits = 9;
11305      }
11306      /* until 256-byte window bug fixed */
11307
11308
11309      const s = new DeflateState();
11310      strm.state = s;
11311      s.strm = strm;
11312      s.wrap = wrap;
11313      s.gzhead = null;
11314      s.w_bits = windowBits;
11315      s.w_size = 1 << s.w_bits;
11316      s.w_mask = s.w_size - 1;
11317      s.hash_bits = memLevel + 7;
11318      s.hash_size = 1 << s.hash_bits;
11319      s.hash_mask = s.hash_size - 1;
11320      s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);
11321      s.window = new Uint8Array(s.w_size * 2);
11322      s.head = new Uint16Array(s.hash_size);
11323      s.prev = new Uint16Array(s.w_size); // Don't need mem init magic for JS.
11324      //s.high_water = 0;
11324  /* nothing written to s->window yet */
11325
11326      s.lit_bufsize = 1 << memLevel + 6;
11327      /* 16K elements by default */
11328
11329      s.pending_buf_size = s.lit_bufsize * 4; //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
11330      //s->pending_buf = (uchf *) overlay;
11331
11332      s.pending_buf = new Uint8Array(s.pending_buf_size); // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)
11333      //s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
11334
11335      s.d_buf = 1 * s.lit_bufsize; //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
11336
11337      s.l_buf = (1 + 2) * s.lit_bufsize;
11338      s.level = level;
11339      s.strategy = strategy;
11340      s.method = method;
11341      return deflateReset(strm);
11342    };
11343
11344    const deflateInit = (strm, level) => {
11345      return deflateInit2(strm, level, Z_DEFLATED$2, MAX_WBITS$1, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY$1);
11346    };
11347
11348    const deflate$2 = (strm, flush) => {
11349      let beg, val; // for gzip header write only
11350
11351      if (!strm || !strm.state || flush > Z_BLOCK$1 || flush < 0) {
11352        return strm ? err(strm, Z_STREAM_ERROR$2) : Z_STREAM_ERROR$2;
11353      }
11354
11355      const s = strm.state;
11356
11357      if (!strm.output || !strm.input && strm.avail_in !== 0 || s.status === FINISH_STATE && flush !== Z_FINISH$3) {
11358        return err(strm, strm.avail_out === 0 ? Z_BUF_ERROR$1 : Z_STREAM_ERROR$2);
11359      }
11360
11361      s.strm = strm;
11362      /* just in case */
11363
11364      const old_flush = s.last_flush;
11365      s.last_flush = flush;
11366      /* Write the header */
11367
11368      if (s.status === INIT_STATE) {
11369        if (s.wrap === 2) {
11370          // GZIP header
11371          strm.adler = 0; //crc32(0L, Z_NULL, 0);
11372
11373          put_byte(s, 31);
11374          put_byte(s, 139);
11375          put_byte(s, 8);
11376
11377          if (!s.gzhead) {
11378            // s->gzhead == Z_NULL
11379            put_byte(s, 0);
11380            put_byte(s, 0);
11381            put_byte(s, 0);
11382            put_byte(s, 0);
11383            put_byte(s, 0);
11384            put_byte(s, s.level === 9 ? 2 : s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? 4 : 0);
11385            put_byte(s, OS_CODE);
11386            s.status = BUSY_STATE;
11387          } else {
11388            put_byte(s, (s.gzhead.text ? 1 : 0) + (s.gzhead.hcrc ? 2 : 0) + (!s.gzhead.extra ? 0 : 4) + (!s.gzhead.name ? 0 : 8) + (!s.gzhead.comment ? 0 : 16));
11389            put_byte(s, s.gzhead.time & 0xff);
11390            put_byte(s, s.gzhead.time >> 8 & 0xff);
11391            put_byte(s, s.gzhead.time >> 16 & 0xff);
11392            put_byte(s, s.gzhead.time >> 24 & 0xff);
11393            put_byte(s, s.level === 9 ? 2 : s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? 4 : 0);
11394            put_byte(s, s.gzhead.os & 0xff);
11395
11396            if (s.gzhead.extra && s.gzhead.extra.length) {
11397              put_byte(s, s.gzhead.extra.length & 0xff);
11398              put_byte(s, s.gzhead.extra.length >> 8 & 0xff);
11399            }
11400
11401            if (s.gzhead.hcrc) {
11402              strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending, 0);
11403            }
11404
11405            s.gzindex = 0;
11406            s.status = EXTRA_STATE;
11407          }
11408        } else // DEFLATE header
11409          {
11410            let header = Z_DEFLATED$2 + (s.w_bits - 8 << 4) << 8;
11411            let level_flags = -1;
11412
11413            if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {
11414              level_flags = 0;
11415            } else if (s.level < 6) {
11416              level_flags = 1;
11417            } else if (s.level === 6) {
11418              level_flags = 2;
11419            } else {
11420              level_flags = 3;
11421            }
11422
11423            header |= level_flags << 6;
11424
11425            if (s.strstart !== 0) {
11426              header |= PRESET_DICT;
11427            }
11428
11429            header += 31 - header % 31;
11430            s.status = BUSY_STATE;
11431            putShortMSB(s, header);
11432            /* Save the adler32 of the preset dictionary: */
11433
11434            if (s.strstart !== 0) {
11435              putShortMSB(s, strm.adler >>> 16);
11436              putShortMSB(s, strm.adler & 0xffff);
11437            }
11438
11439            strm.adler = 1; // adler32(0L, Z_NULL, 0);
11440          }
11441      } //#ifdef GZIP
11442
11443
11444      if (s.status === EXTRA_STATE) {
11445        if (s.gzhead.extra
11446        /* != Z_NULL*/
11447        ) {
11448          beg = s.pending;
11449          /* start of bytes to update crc */
11450
11451          while (s.gzindex < (s.gzhead.extra.length & 0xffff)) {
11452            if (s.pending === s.pending_buf_size) {
11453              if (s.gzhead.hcrc && s.pending > beg) {
11454                strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);
11455              }
11456
11457              flush_pending(strm);
11458              beg = s.pending;
11459
11460              if (s.pending === s.pending_buf_size) {
11461                break;
11462              }
11463            }
11464
11465            put_byte(s, s.gzhead.extra[s.gzindex] & 0xff);
vendor: 4,060 bytes, lines 11466-11608
11466            s.gzindex++;
11467          }
11468
11469          if (s.gzhead.hcrc && s.pending > beg) {
11470            strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);
11471          }
11472
11473          if (s.gzindex === s.gzhead.extra.length) {
11474            s.gzindex = 0;
11475            s.status = NAME_STATE;
11476          }
11477        } else {
11478          s.status = NAME_STATE;
11479        }
11480      }
11481
11482      if (s.status === NAME_STATE) {
11483        if (s.gzhead.name
11484        /* != Z_NULL*/
11485        ) {
11486          beg = s.pending;
11487          /* start of bytes to update crc */
11488          //int val;
11489
11490          do {
11491            if (s.pending === s.pending_buf_size) {
11492              if (s.gzhead.hcrc && s.pending > beg) {
11493                strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);
11494              }
11495
11496              flush_pending(strm);
11497              beg = s.pending;
11498
11499              if (s.pending === s.pending_buf_size) {
11500                val = 1;
11501                break;
11502              }
11503            } // JS specific: little magic to add zero terminator to end of string
11504
11505
11506            if (s.gzindex < s.gzhead.name.length) {
11507              val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;
11508            } else {
11509              val = 0;
11510            }
11511
11512            put_byte(s, val);
11513          } while (val !== 0);
11514
11515          if (s.gzhead.hcrc && s.pending > beg) {
11516            strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);
11517          }
11518
11519          if (val === 0) {
11520            s.gzindex = 0;
11521            s.status = COMMENT_STATE;
11522          }
11523        } else {
11524          s.status = COMMENT_STATE;
11525        }
11526      }
11527
11528      if (s.status === COMMENT_STATE) {
11529        if (s.gzhead.comment
11530        /* != Z_NULL*/
11531        ) {
11532          beg = s.pending;
11533          /* start of bytes to update crc */
11534          //int val;
11535
11536          do {
11537            if (s.pending === s.pending_buf_size) {
11538              if (s.gzhead.hcrc && s.pending > beg) {
11539                strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);
11540              }
11541
11542              flush_pending(strm);
11543              beg = s.pending;
11544
11545              if (s.pending === s.pending_buf_size) {
11546                val = 1;
11547                break;
11548              }
11549            } // JS specific: little magic to add zero terminator to end of string
11550
11551
11552            if (s.gzindex < s.gzhead.comment.length) {
11553              val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;
11554            } else {
11555              val = 0;
11556            }
11557
11558            put_byte(s, val);
11559          } while (val !== 0);
11560
11561          if (s.gzhead.hcrc && s.pending > beg) {
11562            strm.adler = crc32_1(strm.adler, s.pending_buf, s.pending - beg, beg);
11563          }
11564
11565          if (val === 0) {
11566            s.status = HCRC_STATE;
11567          }
11568        } else {
11569          s.status = HCRC_STATE;
11570        }
11571      }
11572
11573      if (s.status === HCRC_STATE) {
11574        if (s.gzhead.hcrc) {
11575          if (s.pending + 2 > s.pending_buf_size) {
11576            flush_pending(strm);
11577          }
11578
11579          if (s.pending + 2 <= s.pending_buf_size) {
11580            put_byte(s, strm.adler & 0xff);
11581            put_byte(s, strm.adler >> 8 & 0xff);
11582            strm.adler = 0; //crc32(0L, Z_NULL, 0);
11583
11584            s.status = BUSY_STATE;
11585          }
11586        } else {
11587          s.status = BUSY_STATE;
11588        }
11589      } //#endif
11590
11591      /* Flush as much pending output as possible */
11592
11593
11594      if (s.pending !== 0) {
11595        flush_pending(strm);
11596
11597        if (strm.avail_out === 0) {
11598          /* Since avail_out is 0, deflate will be called again with
11599           * more output space, but possibly with both pending and
11600           * avail_in equal to zero. There won't be anything to do,
11601           * but this is not an error situation so make sure we
11602           * return OK instead of BUF_ERROR at next call of deflate:
11603           */
11604          s.last_flush = -1;
11605          return Z_OK$3;
11606        }
11607        /* Make sure there is something to do and avoid duplicate consecutive
11608         * flushes. For repeated and useless calls with Z_FINISH, we keep
vendor: 18,031 bytes, lines 11609-12234
11609         * returning Z_STREAM_END instead of Z_BUF_ERROR.
11610         */
11611
11612      } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && flush !== Z_FINISH$3) {
11613        return err(strm, Z_BUF_ERROR$1);
11614      }
11615      /* User must not provide more input after the first FINISH: */
11616
11617
11618      if (s.status === FINISH_STATE && strm.avail_in !== 0) {
11619        return err(strm, Z_BUF_ERROR$1);
11620      }
11621      /* Start a new block or continue the current one.
11622       */
11623
11624
11625      if (strm.avail_in !== 0 || s.lookahead !== 0 || flush !== Z_NO_FLUSH$2 && s.status !== FINISH_STATE) {
11626        let bstate = s.strategy === Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : s.strategy === Z_RLE ? deflate_rle(s, flush) : configuration_table[s.level].func(s, flush);
11627
11628        if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {
11629          s.status = FINISH_STATE;
11630        }
11631
11632        if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {
11633          if (strm.avail_out === 0) {
11634            s.last_flush = -1;
11635            /* avoid BUF_ERROR next call, see above */
11636          }
11637
11638          return Z_OK$3;
11639          /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
11640           * of deflate should use the same flush parameter to make sure
11641           * that the flush is complete. So we don't have to output an
11642           * empty block here, this will be done at next call. This also
11643           * ensures that for a very small output buffer, we emit at most
11644           * one empty block.
11645           */
11646        }
11647
11648        if (bstate === BS_BLOCK_DONE) {
11649          if (flush === Z_PARTIAL_FLUSH) {
11650            _tr_align(s);
11651          } else if (flush !== Z_BLOCK$1) {
11652            /* FULL_FLUSH or SYNC_FLUSH */
11653            _tr_stored_block(s, 0, 0, false);
11654            /* For a full flush, this empty block will be recognized
11655             * as a special marker by inflate_sync().
11656             */
11657
11658
11659            if (flush === Z_FULL_FLUSH$1) {
11660              /*** CLEAR_HASH(s); ***/
11661
11662              /* forget history */
11663              zero(s.head); // Fill with NIL (= 0);
11664
11665              if (s.lookahead === 0) {
11666                s.strstart = 0;
11667                s.block_start = 0;
11668                s.insert = 0;
11669              }
11670            }
11671          }
11672
11673          flush_pending(strm);
11674
11675          if (strm.avail_out === 0) {
11676            s.last_flush = -1;
11677            /* avoid BUF_ERROR at next call, see above */
11678
11679            return Z_OK$3;
11680          }
11681        }
11682      } //Assert(strm->avail_out > 0, "bug2");
11683      //if (strm.avail_out <= 0) { throw new Error("bug2");}
11684
11685
11686      if (flush !== Z_FINISH$3) {
11687        return Z_OK$3;
11688      }
11689
11690      if (s.wrap <= 0) {
11691        return Z_STREAM_END$3;
11692      }
11693      /* Write the trailer */
11694
11695
11696      if (s.wrap === 2) {
11697        put_byte(s, strm.adler & 0xff);
11698        put_byte(s, strm.adler >> 8 & 0xff);
11699        put_byte(s, strm.adler >> 16 & 0xff);
11700        put_byte(s, strm.adler >> 24 & 0xff);
11701        put_byte(s, strm.total_in & 0xff);
11702        put_byte(s, strm.total_in >> 8 & 0xff);
11703        put_byte(s, strm.total_in >> 16 & 0xff);
11704        put_byte(s, strm.total_in >> 24 & 0xff);
11705      } else {
11706        putShortMSB(s, strm.adler >>> 16);
11707        putShortMSB(s, strm.adler & 0xffff);
11708      }
11709
11710      flush_pending(strm);
11711      /* If avail_out is zero, the application will call deflate again
11712       * to flush the rest.
11713       */
11714
11715      if (s.wrap > 0) {
11716        s.wrap = -s.wrap;
11717      }
11718      /* write the trailer only once! */
11719
11720
11721      return s.pending !== 0 ? Z_OK$3 : Z_STREAM_END$3;
11722    };
11723
11724    const deflateEnd = strm => {
11725      if (!strm
11726      /*== Z_NULL*/
11727      || !strm.state
11728      /*== Z_NULL*/
11729      ) {
11730        return Z_STREAM_ERROR$2;
11731      }
11732
11733      const status = strm.state.status;
11734
11735      if (status !== INIT_STATE && status !== EXTRA_STATE && status !== NAME_STATE && status !== COMMENT_STATE && status !== HCRC_STATE && status !== BUSY_STATE && status !== FINISH_STATE) {
11736        return err(strm, Z_STREAM_ERROR$2);
11737      }
11738
11739      strm.state = null;
11740      return status === BUSY_STATE ? err(strm, Z_DATA_ERROR$2) : Z_OK$3;
11741    };
11742    /* =========================================================================
11743     * Initializes the compression dictionary from the given byte
11744     * sequence without producing any compressed output.
11745     */
11746
11747
11748    const deflateSetDictionary = (strm, dictionary) => {
11749      let dictLength = dictionary.length;
11750
11751      if (!strm
11752      /*== Z_NULL*/
11753      || !strm.state
11754      /*== Z_NULL*/
11755      ) {
11756        return Z_STREAM_ERROR$2;
11757      }
11758
11759      const s = strm.state;
11760      const wrap = s.wrap;
11761
11762      if (wrap === 2 || wrap === 1 && s.status !== INIT_STATE || s.lookahead) {
11763        return Z_STREAM_ERROR$2;
11764      }
11765      /* when using zlib wrappers, compute Adler-32 for provided dictionary */
11766
11767
11768      if (wrap === 1) {
11769        /* adler32(strm->adler, dictionary, dictLength); */
11770        strm.adler = adler32_1(strm.adler, dictionary, dictLength, 0);
11771      }
11772
11773      s.wrap = 0;
11774      /* avoid computing Adler-32 in read_buf */
11775
11776      /* if dictionary would fill window, just replace the history */
11777
11778      if (dictLength >= s.w_size) {
11779        if (wrap === 0) {
11780          /* already empty otherwise */
11781
11782          /*** CLEAR_HASH(s); ***/
11783          zero(s.head); // Fill with NIL (= 0);
11784
11785          s.strstart = 0;
11786          s.block_start = 0;
11787          s.insert = 0;
11788        }
11789        /* use the tail */
11790        // dictionary = dictionary.slice(dictLength - s.w_size);
11791
11792
11793        let tmpDict = new Uint8Array(s.w_size);
11794        tmpDict.set(dictionary.subarray(dictLength - s.w_size, dictLength), 0);
11795        dictionary = tmpDict;
11796        dictLength = s.w_size;
11797      }
11798      /* insert dictionary into window and hash */
11799
11800
11801      const avail = strm.avail_in;
11802      const next = strm.next_in;
11803      const input = strm.input;
11804      strm.avail_in = dictLength;
11805      strm.next_in = 0;
11806      strm.input = dictionary;
11807      fill_window(s);
11808
11809      while (s.lookahead >= MIN_MATCH) {
11810        let str = s.strstart;
11811        let n = s.lookahead - (MIN_MATCH - 1);
11812
11813        do {
11814          /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
11815          s.ins_h = HASH(s, s.ins_h, s.window[str + MIN_MATCH - 1]);
11816          s.prev[str & s.w_mask] = s.head[s.ins_h];
11817          s.head[s.ins_h] = str;
11818          str++;
11819        } while (--n);
11820
11821        s.strstart = str;
11822        s.lookahead = MIN_MATCH - 1;
11823        fill_window(s);
11824      }
11825
11826      s.strstart += s.lookahead;
11827      s.block_start = s.strstart;
11828      s.insert = s.lookahead;
11829      s.lookahead = 0;
11830      s.match_length = s.prev_length = MIN_MATCH - 1;
11831      s.match_available = 0;
11832      strm.next_in = next;
11833      strm.input = input;
11834      strm.avail_in = avail;
11835      s.wrap = wrap;
11836      return Z_OK$3;
11837    };
11838
11839    var deflateInit_1 = deflateInit;
11840    var deflateInit2_1 = deflateInit2;
11841    var deflateReset_1 = deflateReset;
11842    var deflateResetKeep_1 = deflateResetKeep;
11843    var deflateSetHeader_1 = deflateSetHeader;
11844    var deflate_2$1 = deflate$2;
11845    var deflateEnd_1 = deflateEnd;
11846    var deflateSetDictionary_1 = deflateSetDictionary;
11847    var deflateInfo = 'pako deflate (from Nodeca project)';
11848    /* Not implemented
11849    module.exports.deflateBound = deflateBound;
11850    module.exports.deflateCopy = deflateCopy;
11851    module.exports.deflateParams = deflateParams;
11852    module.exports.deflatePending = deflatePending;
11853    module.exports.deflatePrime = deflatePrime;
11854    module.exports.deflateTune = deflateTune;
11855    */
11856
11857    var deflate_1$2 = {
11858      deflateInit: deflateInit_1,
11859      deflateInit2: deflateInit2_1,
11860      deflateReset: deflateReset_1,
11861      deflateResetKeep: deflateResetKeep_1,
11862      deflateSetHeader: deflateSetHeader_1,
11863      deflate: deflate_2$1,
11864      deflateEnd: deflateEnd_1,
11865      deflateSetDictionary: deflateSetDictionary_1,
11866      deflateInfo: deflateInfo
11867    };
11868
11869    const _has = (obj, key) => {
11870      return Object.prototype.hasOwnProperty.call(obj, key);
11871    };
11872
11873    var assign = function (obj
11874    /*from1, from2, from3, ...*/
11875    ) {
11876      const sources = Array.prototype.slice.call(arguments, 1);
11877
11878      while (sources.length) {
11879        const source = sources.shift();
11880
11881        if (!source) {
11882          continue;
11883        }
11884
11885        if (typeof source !== 'object') {
11886          throw new TypeError(source + 'must be non-object');
11887        }
11888
11889        for (const p in source) {
11890          if (_has(source, p)) {
11891            obj[p] = source[p];
11892          }
11893        }
11894      }
11895
11896      return obj;
11897    }; // Join array of chunks to single array.
11898
11899
11900    var flattenChunks = chunks => {
11901      // calculate data length
11902      let len = 0;
11903
11904      for (let i = 0, l = chunks.length; i < l; i++) {
11905        len += chunks[i].length;
11906      } // join chunks
11907
11908
11909      const result = new Uint8Array(len);
11910
11911      for (let i = 0, pos = 0, l = chunks.length; i < l; i++) {
11912        let chunk = chunks[i];
11913        result.set(chunk, pos);
11914        pos += chunk.length;
11915      }
11916
11917      return result;
11918    };
11919
11920    var common = {
11921      assign: assign,
11922      flattenChunks: flattenChunks
11923    }; // String encode/decode helpers
11924    // Quick check if we can use fast array to bin string conversion
11925    //
11926    // - apply(Array) can fail on Android 2.2
11927    // - apply(Uint8Array) can fail on iOS 5.1 Safari
11928    //
11929
11930    let STR_APPLY_UIA_OK = true;
11931
11932    try {
11933      String.fromCharCode.apply(null, new Uint8Array(1));
11934    } catch (__) {
11935      STR_APPLY_UIA_OK = false;
11936    } // Table with utf8 lengths (calculated by first byte of sequence)
11937    // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
11938    // because max possible codepoint is 0x10ffff
11939
11940
11941    const _utf8len = new Uint8Array(256);
11942
11943    for (let q = 0; q < 256; q++) {
11944      _utf8len[q] = q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1;
11945    }
11946
11947    _utf8len[254] = _utf8len[254] = 1; // Invalid sequence start
11948    // convert string to array (typed, when possible)
11949
11950    var string2buf = str => {
11951      if (typeof TextEncoder === 'function' && TextEncoder.prototype.encode) {
11952        return new TextEncoder().encode(str);
11953      }
11954
11955      let buf,
11956          c,
11957          c2,
11958          m_pos,
11959          i,
11960          str_len = str.length,
11961          buf_len = 0; // count binary size
11962
11963      for (m_pos = 0; m_pos < str_len; m_pos++) {
11964        c = str.charCodeAt(m_pos);
11965
11966        if ((c & 0xfc00) === 0xd800 && m_pos + 1 < str_len) {
11967          c2 = str.charCodeAt(m_pos + 1);
11968
11969          if ((c2 & 0xfc00) === 0xdc00) {
11970            c = 0x10000 + (c - 0xd800 << 10) + (c2 - 0xdc00);
11971            m_pos++;
11972          }
11973        }
11974
11975        buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
11976      } // allocate buffer
11977
11978
11979      buf = new Uint8Array(buf_len); // convert
11980
11981      for (i = 0, m_pos = 0; i < buf_len; m_pos++) {
11982        c = str.charCodeAt(m_pos);
11983
11984        if ((c & 0xfc00) === 0xd800 && m_pos + 1 < str_len) {
11985          c2 = str.charCodeAt(m_pos + 1);
11986
11987          if ((c2 & 0xfc00) === 0xdc00) {
11988            c = 0x10000 + (c - 0xd800 << 10) + (c2 - 0xdc00);
11989            m_pos++;
11990          }
11991        }
11992
11993        if (c < 0x80) {
11994          /* one byte */
11995          buf[i++] = c;
11996        } else if (c < 0x800) {
11997          /* two bytes */
11998          buf[i++] = 0xC0 | c >>> 6;
11999          buf[i++] = 0x80 | c & 0x3f;
12000        } else if (c < 0x10000) {
12001          /* three bytes */
12002          buf[i++] = 0xE0 | c >>> 12;
12003          buf[i++] = 0x80 | c >>> 6 & 0x3f;
12004          buf[i++] = 0x80 | c & 0x3f;
12005        } else {
12006          /* four bytes */
12007          buf[i++] = 0xf0 | c >>> 18;
12008          buf[i++] = 0x80 | c >>> 12 & 0x3f;
12009          buf[i++] = 0x80 | c >>> 6 & 0x3f;
12010          buf[i++] = 0x80 | c & 0x3f;
12011        }
12012      }
12013
12014      return buf;
12015    }; // Helper
12016
12017
12018    const buf2binstring = (buf, len) => {
12019      // On Chrome, the arguments in a function call that are allowed is `65534`.
12020      // If the length of the buffer is smaller than that, we can use this optimization,
12021      // otherwise we will take a slower path.
12022      if (len < 65534) {
12023        if (buf.subarray && STR_APPLY_UIA_OK) {
12024          return String.fromCharCode.apply(null, buf.length === len ? buf : buf.subarray(0, len));
12025        }
12026      }
12027
12028      let result = '';
12029
12030      for (let i = 0; i < len; i++) {
12031        result += String.fromCharCode(buf[i]);
12032      }
12033
12034      return result;
12035    }; // convert array to string
12036
12037
12038    var buf2string = (buf, max) => {
12039      const len = max || buf.length;
12040
12041      if (typeof TextDecoder === 'function' && TextDecoder.prototype.decode) {
12042        return new TextDecoder().decode(buf.subarray(0, max));
12043      }
12044
12045      let i, out; // Reserve max possible length (2 words per char)
12046      // NB: by unknown reasons, Array is significantly faster for
12047      //     String.fromCharCode.apply than Uint16Array.
12048
12049      const utf16buf = new Array(len * 2);
12050
12051      for (out = 0, i = 0; i < len;) {
12052        let c = buf[i++]; // quick process ascii
12053
12054        if (c < 0x80) {
12055          utf16buf[out++] = c;
12056          continue;
12057        }
12058
12059        let c_len = _utf8len[c]; // skip 5 & 6 byte codes
12060
12061        if (c_len > 4) {
12062          utf16buf[out++] = 0xfffd;
12063          i += c_len - 1;
12064          continue;
12065        } // apply mask on first byte
12066
12067
12068        c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; // join the rest
12069
12070        while (c_len > 1 && i < len) {
12071          c = c << 6 | buf[i++] & 0x3f;
12072          c_len--;
12073        } // terminated by end of string?
12074
12075
12076        if (c_len > 1) {
12077          utf16buf[out++] = 0xfffd;
12078          continue;
12079        }
12080
12081        if (c < 0x10000) {
12082          utf16buf[out++] = c;
12083        } else {
12084          c -= 0x10000;
12085          utf16buf[out++] = 0xd800 | c >> 10 & 0x3ff;
12086          utf16buf[out++] = 0xdc00 | c & 0x3ff;
12087        }
12088      }
12089
12090      return buf2binstring(utf16buf, out);
12091    }; // Calculate max possible position in utf8 buffer,
12092    // that will not break sequence. If that's not possible
12093    // - (very small limits) return max size as is.
12094    //
12095    // buf[] - utf8 bytes array
12096    // max   - length limit (mandatory);
12097
12098
12099    var utf8border = (buf, max) => {
12100      max = max || buf.length;
12101
12102      if (max > buf.length) {
12103        max = buf.length;
12104      } // go back from last position, until start of sequence found
12105
12106
12107      let pos = max - 1;
12108
12109      while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) {
12110        pos--;
12111      } // Very small and broken sequence,
12112      // return max, because we should return something anyway.
12113
12114
12115      if (pos < 0) {
12116        return max;
12117      } // If we came to start of buffer - that means buffer is too small,
12118      // return max too.
12119
12120
12121      if (pos === 0) {
12122        return max;
12123      }
12124
12125      return pos + _utf8len[buf[pos]] > max ? pos : max;
12126    };
12127
12128    var strings = {
12129      string2buf: string2buf,
12130      buf2string: buf2string,
12131      utf8border: utf8border
12132    }; // (C) 1995-2013 Jean-loup Gailly and Mark Adler
12133    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
12134    //
12135    // This software is provided 'as-is', without any express or implied
12136    // warranty. In no event will the authors be held liable for any damages
12137    // arising from the use of this software.
12138    //
12139    // Permission is granted to anyone to use this software for any purpose,
12140    // including commercial applications, and to alter it and redistribute it
12141    // freely, subject to the following restrictions:
12142    //
12143    // 1. The origin of this software must not be misrepresented; you must not
12144    //   claim that you wrote the original software. If you use this software
12145    //   in a product, an acknowledgment in the product documentation would be
12146    //   appreciated but is not required.
12147    // 2. Altered source versions must be plainly marked as such, and must not be
12148    //   misrepresented as being the original software.
12149    // 3. This notice may not be removed or altered from any source distribution.
12150
12151    function ZStream() {
12152      /* next input byte */
12153      this.input = null; // JS specific, because we have no pointers
12154
12155      this.next_in = 0;
12156      /* number of bytes available at input */
12157
12158      this.avail_in = 0;
12159      /* total number of input bytes read so far */
12160
12161      this.total_in = 0;
12162      /* next output byte should be put there */
12163
12164      this.output = null; // JS specific, because we have no pointers
12165
12166      this.next_out = 0;
12167      /* remaining free space at output */
12168
12169      this.avail_out = 0;
12170      /* total number of bytes output so far */
12171
12172      this.total_out = 0;
12173      /* last error message, NULL if no error */
12174
12175      this.msg = ''
12176      /*Z_NULL*/
12177      ;
12178      /* not visible by applications */
12179
12180      this.state = null;
12181      /* best guess about the data type: binary or text */
12182
12183      this.data_type = 2
12184      /*Z_UNKNOWN*/
12185      ;
12186      /* adler32 value of the uncompressed data */
12187
12188      this.adler = 0;
12189    }
12190
12191    var zstream = ZStream;
12192    const toString$1$1 = Object.prototype.toString;
12193    /* Public constants ==========================================================*/
12194
12195    /* ===========================================================================*/
12196
12197    const {
12198      Z_NO_FLUSH: Z_NO_FLUSH$1,
12199      Z_SYNC_FLUSH,
12200      Z_FULL_FLUSH,
12201      Z_FINISH: Z_FINISH$2,
12202      Z_OK: Z_OK$2,
12203      Z_STREAM_END: Z_STREAM_END$2,
12204      Z_DEFAULT_COMPRESSION,
12205      Z_DEFAULT_STRATEGY,
12206      Z_DEFLATED: Z_DEFLATED$1
12207    } = constants$2;
12208    /* ===========================================================================*/
12209
12210    /**
12211     * class Deflate
12212     *
12213     * Generic JS-style wrapper for zlib calls. If you don't need
12214     * streaming behaviour - use more simple functions: [[deflate]],
12215     * [[deflateRaw]] and [[gzip]].
12216     **/
12217
12218    /* internal
12219     * Deflate.chunks -> Array
12220     *
12221     * Chunks of output data, if [[Deflate#onData]] not overridden.
12222     **/
12223
12224    /**
12225     * Deflate.result -> Uint8Array
12226     *
12227     * Compressed result, generated by default [[Deflate#onData]]
12228     * and [[Deflate#onEnd]] handlers. Filled after you push last chunk
12229     * (call [[Deflate#push]] with `Z_FINISH` / `true` param).
12230     **/
12231
12232    /**
12233     * Deflate.err -> Number
12234     *
12235     * Error code after deflate finished. 0 (Z_OK) on success.
12236     * You will not need it in real life, because deflate errors
12237     * are possible only on wrong options or bad `onData` / `onEnd`
12238     * custom handlers.
12239     **/
12240
12241    /**
12242     * Deflate.msg -> String
12243     *
12244     * Error message, if [[Deflate.err]] != 0
12245     **/
12246
12247    /**
12248     * new Deflate(options)
12249     * - options (Object): zlib deflate options.
12250     *
12251     * Creates new deflator instance with specified params. Throws exception
12252     * on bad params. Supported options:
12253     *
12254     * - `level`
12255     * - `windowBits`
12256     * - `memLevel`
12257     * - `strategy`
12258     * - `dictionary`
12259     *
12260     * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
12261     * for more information on these.
12262     *
12263     * Additional options, for internal needs:
12264     *
12265     * - `chunkSize` - size of generated data chunks (16K by default)
12266     * - `raw` (Boolean) - do raw deflate
12267     * - `gzip` (Boolean) - create gzip wrapper
12268     * - `header` (Object) - custom header for gzip
12269     *   - `text` (Boolean) - true if compressed data believed to be text
12270     *   - `time` (Number) - modification time, unix timestamp
12271     *   - `os` (Number) - operation system code
12272     *   - `extra` (Array) - array of bytes with extra data (max 65536)
12273     *   - `name` (String) - file name (binary string)
12274     *   - `comment` (String) - comment (binary string)
12275     *   - `hcrc` (Boolean) - true if header crc should be added
12276     *
12277     * ##### Example:
12278     *
12279     * ```javascript
12280     * const pako = require('pako')
12281     *   , chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9])
12282     *   , chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]);
12283     *
12284     * const deflate = new pako.Deflate({ level: 3});
12285     *
12286     * deflate.push(chunk1, false);
12287     * deflate.push(chunk2, true);  // true -> last chunk
12288     *
12289     * if (deflate.err) { throw new Error(deflate.err); }
12290     *
12291     * console.log(deflate.result);
12292     * ```
12293     **/
12294
12295    function Deflate$1(options) {
12296      this.options = common.assign({
12297        level: Z_DEFAULT_COMPRESSION,
12298        method: Z_DEFLATED$1,
12299        chunkSize: 16384,
12300        windowBits: 15,
12301        memLevel: 8,
12302        strategy: Z_DEFAULT_STRATEGY
12303      }, options || {});
12304      let opt = this.options;
12305
12306      if (opt.raw && opt.windowBits > 0) {
12307        opt.windowBits = -opt.windowBits;
12308      } else if (opt.gzip && opt.windowBits > 0 && opt.windowBits < 16) {
12309        opt.windowBits += 16;
12310      }
12311
12312      this.err = 0; // error code, if happens (0 = Z_OK)
12313
12314      this.msg = ''; // error message
12315
12316      this.ended = false; // used to avoid multiple onEnd() calls
12317
12318      this.chunks = []; // chunks of compressed data
12319
12320      this.strm = new zstream();
12321      this.strm.avail_out = 0;
12322      let status = deflate_1$2.deflateInit2(this.strm, opt.level, opt.method, opt.windowBits, opt.memLevel, opt.strategy);
12323
12324      if (status !== Z_OK$2) {
12325        throw new Error(messages[status]);
12326      }
12327
12328      if (opt.header) {
12329        deflate_1$2.deflateSetHeader(this.strm, opt.header);
12330      }
12331
12332      if (opt.dictionary) {
12333        let dict; // Convert data if needed
12334
12335        if (typeof opt.dictionary === 'string') {
12336          // If we need to compress text, change encoding to utf8.
12337          dict = strings.string2buf(opt.dictionary);
12338        } else if (toString$1$1.call(opt.dictionary) === '[object ArrayBuffer]') {
12339          dict = new Uint8Array(opt.dictionary);
12340        } else {
12341          dict = opt.dictionary;
12342        }
12343
12344        status = deflate_1$2.deflateSetDictionary(this.strm, dict);
12345
12346        if (status !== Z_OK$2) {
12347          throw new Error(messages[status]);
12348        }
12349
12350        this._dict_set = true;
12351      }
12352    }
12353    /**
12354     * Deflate#push(data[, flush_mode]) -> Boolean
12355     * - data (Uint8Array|ArrayBuffer|String): input data. Strings will be
12356     *   converted to utf8 byte sequence.
12357     * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
12358     *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
12359     *
12360     * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with
12361     * new compressed chunks. Returns `true` on success. The last data block must
12362     * have `flush_mode` Z_FINISH (or `true`). That will flush internal pending
12363     * buffers and call [[Deflate#onEnd]].
12364     *
12365     * On fail call [[Deflate#onEnd]] with error code and return false.
12366     *
12367     * ##### Example
12368     *
12369     * ```javascript
12370     * push(chunk, false); // push one of data chunks
12371     * ...
12372     * push(chunk, true);  // push last chunk
12373     * ```
12374     **/
12375
12376
12377    Deflate$1.prototype.push = function (data, flush_mode) {
12378      const strm = this.strm;
12379      const chunkSize = this.options.chunkSize;
12380
12381      let status, _flush_mode;
12382
12383      if (this.ended) {
12384        return false;
vendor: 24,702 bytes, lines 12385-13139
12385      }
12386
12387      if (flush_mode === ~~flush_mode) _flush_mode = flush_mode;else _flush_mode = flush_mode === true ? Z_FINISH$2 : Z_NO_FLUSH$1; // Convert data if needed
12388
12389      if (typeof data === 'string') {
12390        // If we need to compress text, change encoding to utf8.
12391        strm.input = strings.string2buf(data);
12392      } else if (toString$1$1.call(data) === '[object ArrayBuffer]') {
12393        strm.input = new Uint8Array(data);
12394      } else {
12395        strm.input = data;
12396      }
12397
12398      strm.next_in = 0;
12399      strm.avail_in = strm.input.length;
12400
12401      for (;;) {
12402        if (strm.avail_out === 0) {
12403          strm.output = new Uint8Array(chunkSize);
12404          strm.next_out = 0;
12405          strm.avail_out = chunkSize;
12406        } // Make sure avail_out > 6 to avoid repeating markers
12407
12408
12409        if ((_flush_mode === Z_SYNC_FLUSH || _flush_mode === Z_FULL_FLUSH) && strm.avail_out <= 6) {
12410          this.onData(strm.output.subarray(0, strm.next_out));
12411          strm.avail_out = 0;
12412          continue;
12413        }
12414
12415        status = deflate_1$2.deflate(strm, _flush_mode); // Ended => flush and finish
12416
12417        if (status === Z_STREAM_END$2) {
12418          if (strm.next_out > 0) {
12419            this.onData(strm.output.subarray(0, strm.next_out));
12420          }
12421
12422          status = deflate_1$2.deflateEnd(this.strm);
12423          this.onEnd(status);
12424          this.ended = true;
12425          return status === Z_OK$2;
12426        } // Flush if out buffer full
12427
12428
12429        if (strm.avail_out === 0) {
12430          this.onData(strm.output);
12431          continue;
12432        } // Flush if requested and has data
12433
12434
12435        if (_flush_mode > 0 && strm.next_out > 0) {
12436          this.onData(strm.output.subarray(0, strm.next_out));
12437          strm.avail_out = 0;
12438          continue;
12439        }
12440
12441        if (strm.avail_in === 0) break;
12442      }
12443
12444      return true;
12445    };
12446    /**
12447     * Deflate#onData(chunk) -> Void
12448     * - chunk (Uint8Array): output data.
12449     *
12450     * By default, stores data blocks in `chunks[]` property and glue
12451     * those in `onEnd`. Override this handler, if you need another behaviour.
12452     **/
12453
12454
12455    Deflate$1.prototype.onData = function (chunk) {
12456      this.chunks.push(chunk);
12457    };
12458    /**
12459     * Deflate#onEnd(status) -> Void
12460     * - status (Number): deflate status. 0 (Z_OK) on success,
12461     *   other if not.
12462     *
12463     * Called once after you tell deflate that the input stream is
12464     * complete (Z_FINISH). By default - join collected chunks,
12465     * free memory and fill `results` / `err` properties.
12466     **/
12467
12468
12469    Deflate$1.prototype.onEnd = function (status) {
12470      // On success - join
12471      if (status === Z_OK$2) {
12472        this.result = common.flattenChunks(this.chunks);
12473      }
12474
12475      this.chunks = [];
12476      this.err = status;
12477      this.msg = this.strm.msg;
12478    };
12479    /**
12480     * deflate(data[, options]) -> Uint8Array
12481     * - data (Uint8Array|String): input data to compress.
12482     * - options (Object): zlib deflate options.
12483     *
12484     * Compress `data` with deflate algorithm and `options`.
12485     *
12486     * Supported options are:
12487     *
12488     * - level
12489     * - windowBits
12490     * - memLevel
12491     * - strategy
12492     * - dictionary
12493     *
12494     * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
12495     * for more information on these.
12496     *
12497     * Sugar (options):
12498     *
12499     * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
12500     *   negative windowBits implicitly.
12501     *
12502     * ##### Example:
12503     *
12504     * ```javascript
12505     * const pako = require('pako')
12506     * const data = new Uint8Array([1,2,3,4,5,6,7,8,9]);
12507     *
12508     * console.log(pako.deflate(data));
12509     * ```
12510     **/
12511
12512
12513    function deflate$1(input, options) {
12514      const deflator = new Deflate$1(options);
12515      deflator.push(input, true); // That will never happens, if you don't cheat with options :)
12516
12517      if (deflator.err) {
12518        throw deflator.msg || messages[deflator.err];
12519      }
12520
12521      return deflator.result;
12522    }
12523    /**
12524     * deflateRaw(data[, options]) -> Uint8Array
12525     * - data (Uint8Array|String): input data to compress.
12526     * - options (Object): zlib deflate options.
12527     *
12528     * The same as [[deflate]], but creates raw data, without wrapper
12529     * (header and adler32 crc).
12530     **/
12531
12532
12533    function deflateRaw$1(input, options) {
12534      options = options || {};
12535      options.raw = true;
12536      return deflate$1(input, options);
12537    }
12538    /**
12539     * gzip(data[, options]) -> Uint8Array
12540     * - data (Uint8Array|String): input data to compress.
12541     * - options (Object): zlib deflate options.
12542     *
12543     * The same as [[deflate]], but create gzip wrapper instead of
12544     * deflate one.
12545     **/
12546
12547
12548    function gzip$1(input, options) {
12549      options = options || {};
12550      options.gzip = true;
12551      return deflate$1(input, options);
12552    }
12553
12554    var Deflate_1$1 = Deflate$1;
12555    var deflate_2 = deflate$1;
12556    var deflateRaw_1$1 = deflateRaw$1;
12557    var gzip_1$1 = gzip$1;
12558    var constants$1 = constants$2;
12559    var deflate_1$1 = {
12560      Deflate: Deflate_1$1,
12561      deflate: deflate_2,
12562      deflateRaw: deflateRaw_1$1,
12563      gzip: gzip_1$1,
12564      constants: constants$1
12565    }; // (C) 1995-2013 Jean-loup Gailly and Mark Adler
12566    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
12567    //
12568    // This software is provided 'as-is', without any express or implied
12569    // warranty. In no event will the authors be held liable for any damages
12570    // arising from the use of this software.
12571    //
12572    // Permission is granted to anyone to use this software for any purpose,
12573    // including commercial applications, and to alter it and redistribute it
12574    // freely, subject to the following restrictions:
12575    //
12576    // 1. The origin of this software must not be misrepresented; you must not
12577    //   claim that you wrote the original software. If you use this software
12578    //   in a product, an acknowledgment in the product documentation would be
12579    //   appreciated but is not required.
12580    // 2. Altered source versions must be plainly marked as such, and must not be
12581    //   misrepresented as being the original software.
12582    // 3. This notice may not be removed or altered from any source distribution.
12583    // See state defs from inflate.js
12584
12585    const BAD$1 = 30;
12586    /* got a data error -- remain here until reset */
12587
12588    const TYPE$1 = 12;
12589    /* i: waiting for type bits, including last-flag bit */
12590
12591    /*
12592       Decode literal, length, and distance codes and write out the resulting
12593       literal and match bytes until either not enough input or output is
12594       available, an end-of-block is encountered, or a data error is encountered.
12595       When large enough input and output buffers are supplied to inflate(), for
12596       example, a 16K input buffer and a 64K output buffer, more than 95% of the
12597       inflate execution time is spent in this routine.
12598        Entry assumptions:
12599             state.mode === LEN
12600            strm.avail_in >= 6
12601            strm.avail_out >= 258
12602            start >= strm.avail_out
12603            state.bits < 8
12604        On return, state.mode is one of:
12605             LEN -- ran out of enough output space or enough available input
12606            TYPE -- reached end of block code, inflate() to interpret next block
12607            BAD -- error in block data
12608        Notes:
12609         - The maximum input bits used by a length/distance pair is 15 bits for the
12610          length code, 5 bits for the length extra, 15 bits for the distance code,
12611          and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
12612          Therefore if strm.avail_in >= 6, then there is enough input to avoid
12613          checking for available input while decoding.
12614         - The maximum bytes that a single length/distance pair can output is 258
12615          bytes, which is the maximum length that can be coded.  inflate_fast()
12616          requires strm.avail_out >= 258 for each loop to avoid checking for
12617          output space.
12618     */
12619
12620    var inffast = function inflate_fast(strm, start) {
12621      let _in;
12622      /* local strm.input */
12623
12624
12625      let last;
12626      /* have enough input while in < last */
12627
12628      let _out;
12629      /* local strm.output */
12630
12631
12632      let beg;
12633      /* inflate()'s initial strm.output */
12634
12635      let end;
12636      /* while out < end, enough space available */
12637      //#ifdef INFLATE_STRICT
12638
12639      let dmax;
12640      /* maximum distance from zlib header */
12641      //#endif
12642
12643      let wsize;
12644      /* window size or zero if not using window */
12645
12646      let whave;
12647      /* valid bytes in the window */
12648
12649      let wnext;
12650      /* window write index */
12651      // Use `s_window` instead `window`, avoid conflict with instrumentation tools
12652
12653      let s_window;
12654      /* allocated sliding window, if wsize != 0 */
12655
12656      let hold;
12657      /* local strm.hold */
12658
12659      let bits;
12660      /* local strm.bits */
12661
12662      let lcode;
12663      /* local strm.lencode */
12664
12665      let dcode;
12666      /* local strm.distcode */
12667
12668      let lmask;
12669      /* mask for first level of length codes */
12670
12671      let dmask;
12672      /* mask for first level of distance codes */
12673
12674      let here;
12675      /* retrieved table entry */
12676
12677      let op;
12678      /* code bits, operation, extra bits, or */
12679
12680      /*  window position, window bytes to copy */
12681
12682      let len;
12683      /* match length, unused bytes */
12684
12685      let dist;
12686      /* match distance */
12687
12688      let from;
12689      /* where to copy match from */
12690
12691      let from_source;
12692      let input, output; // JS specific, because we have no pointers
12693
12694      /* copy state to local variables */
12695
12696      const state = strm.state; //here = state.here;
12697
12698      _in = strm.next_in;
12699      input = strm.input;
12700      last = _in + (strm.avail_in - 5);
12701      _out = strm.next_out;
12702      output = strm.output;
12703      beg = _out - (start - strm.avail_out);
12704      end = _out + (strm.avail_out - 257); //#ifdef INFLATE_STRICT
12705
12706      dmax = state.dmax; //#endif
12707
12708      wsize = state.wsize;
12709      whave = state.whave;
12710      wnext = state.wnext;
12711      s_window = state.window;
12712      hold = state.hold;
12713      bits = state.bits;
12714      lcode = state.lencode;
12715      dcode = state.distcode;
12716      lmask = (1 << state.lenbits) - 1;
12717      dmask = (1 << state.distbits) - 1;
12718      /* decode literals and length/distances until end-of-block or not enough
12719         input data or output space */
12720
12721      top: do {
12722        if (bits < 15) {
12723          hold += input[_in++] << bits;
12724          bits += 8;
12725          hold += input[_in++] << bits;
12726          bits += 8;
12727        }
12728
12729        here = lcode[hold & lmask];
12730
12731        dolen: for (;;) {
12732          // Goto emulation
12733          op = here >>> 24
12734          /*here.bits*/
12735          ;
12736          hold >>>= op;
12737          bits -= op;
12738          op = here >>> 16 & 0xff
12739          /*here.op*/
12740          ;
12741
12742          if (op === 0) {
12743            /* literal */
12744            //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
12745            //        "inflate:         literal '%c'\n" :
12746            //        "inflate:         literal 0x%02x\n", here.val));
12747            output[_out++] = here & 0xffff
12748            /*here.val*/
12749            ;
12750          } else if (op & 16) {
12751            /* length base */
12752            len = here & 0xffff
12753            /*here.val*/
12754            ;
12755            op &= 15;
12756            /* number of extra bits */
12757
12758            if (op) {
12759              if (bits < op) {
12760                hold += input[_in++] << bits;
12761                bits += 8;
12762              }
12763
12764              len += hold & (1 << op) - 1;
12765              hold >>>= op;
12766              bits -= op;
12767            } //Tracevv((stderr, "inflate:         length %u\n", len));
12768
12769
12770            if (bits < 15) {
12771              hold += input[_in++] << bits;
12772              bits += 8;
12773              hold += input[_in++] << bits;
12774              bits += 8;
12775            }
12776
12777            here = dcode[hold & dmask];
12778
12779            dodist: for (;;) {
12780              // goto emulation
12781              op = here >>> 24
12782              /*here.bits*/
12783              ;
12784              hold >>>= op;
12785              bits -= op;
12786              op = here >>> 16 & 0xff
12787              /*here.op*/
12788              ;
12789
12790              if (op & 16) {
12791                /* distance base */
12792                dist = here & 0xffff
12793                /*here.val*/
12794                ;
12795                op &= 15;
12796                /* number of extra bits */
12797
12798                if (bits < op) {
12799                  hold += input[_in++] << bits;
12800                  bits += 8;
12801
12802                  if (bits < op) {
12803                    hold += input[_in++] << bits;
12804                    bits += 8;
12805                  }
12806                }
12807
12808                dist += hold & (1 << op) - 1; //#ifdef INFLATE_STRICT
12809
12810                if (dist > dmax) {
12811                  strm.msg = 'invalid distance too far back';
12812                  state.mode = BAD$1;
12813                  break top;
12814                } //#endif
12815
12816
12817                hold >>>= op;
12818                bits -= op; //Tracevv((stderr, "inflate:         distance %u\n", dist));
12819
12820                op = _out - beg;
12821                /* max distance in output */
12822
12823                if (dist > op) {
12824                  /* see if copy from window */
12825                  op = dist - op;
12826                  /* distance back in window */
12827
12828                  if (op > whave) {
12829                    if (state.sane) {
12830                      strm.msg = 'invalid distance too far back';
12831                      state.mode = BAD$1;
12832                      break top;
12833                    } // (!) This block is disabled in zlib defaults,
12834                    // don't enable it for binary compatibility
12835                    //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
12836                    //                if (len <= op - whave) {
12837                    //                  do {
12838                    //                    output[_out++] = 0;
12839                    //                  } while (--len);
12840                    //                  continue top;
12841                    //                }
12842                    //                len -= op - whave;
12843                    //                do {
12844                    //                  output[_out++] = 0;
12845                    //                } while (--op > whave);
12846                    //                if (op === 0) {
12847                    //                  from = _out - dist;
12848                    //                  do {
12849                    //                    output[_out++] = output[from++];
12850                    //                  } while (--len);
12851                    //                  continue top;
12852                    //                }
12853                    //#endif
12854
12855                  }
12856
12857                  from = 0; // window index
12858
12859                  from_source = s_window;
12860
12861                  if (wnext === 0) {
12862                    /* very common case */
12863                    from += wsize - op;
12864
12865                    if (op < len) {
12866                      /* some from window */
12867                      len -= op;
12868
12869                      do {
12870                        output[_out++] = s_window[from++];
12871                      } while (--op);
12872
12873                      from = _out - dist;
12874                      /* rest from output */
12875
12876                      from_source = output;
12877                    }
12878                  } else if (wnext < op) {
12879                    /* wrap around window */
12880                    from += wsize + wnext - op;
12881                    op -= wnext;
12882
12883                    if (op < len) {
12884                      /* some from end of window */
12885                      len -= op;
12886
12887                      do {
12888                        output[_out++] = s_window[from++];
12889                      } while (--op);
12890
12891                      from = 0;
12892
12893                      if (wnext < len) {
12894                        /* some from start of window */
12895                        op = wnext;
12896                        len -= op;
12897
12898                        do {
12899                          output[_out++] = s_window[from++];
12900                        } while (--op);
12901
12902                        from = _out - dist;
12903                        /* rest from output */
12904
12905                        from_source = output;
12906                      }
12907                    }
12908                  } else {
12909                    /* contiguous in window */
12910                    from += wnext - op;
12911
12912                    if (op < len) {
12913                      /* some from window */
12914                      len -= op;
12915
12916                      do {
12917                        output[_out++] = s_window[from++];
12918                      } while (--op);
12919
12920                      from = _out - dist;
12921                      /* rest from output */
12922
12923                      from_source = output;
12924                    }
12925                  }
12926
12927                  while (len > 2) {
12928                    output[_out++] = from_source[from++];
12929                    output[_out++] = from_source[from++];
12930                    output[_out++] = from_source[from++];
12931                    len -= 3;
12932                  }
12933
12934                  if (len) {
12935                    output[_out++] = from_source[from++];
12936
12937                    if (len > 1) {
12938                      output[_out++] = from_source[from++];
12939                    }
12940                  }
12941                } else {
12942                  from = _out - dist;
12943                  /* copy direct from output */
12944
12945                  do {
12946                    /* minimum length is three */
12947                    output[_out++] = output[from++];
12948                    output[_out++] = output[from++];
12949                    output[_out++] = output[from++];
12950                    len -= 3;
12951                  } while (len > 2);
12952
12953                  if (len) {
12954                    output[_out++] = output[from++];
12955
12956                    if (len > 1) {
12957                      output[_out++] = output[from++];
12958                    }
12959                  }
12960                }
12961              } else if ((op & 64) === 0) {
12962                /* 2nd level distance code */
12963                here = dcode[(here & 0xffff
12964                /*here.val*/
12965                ) + (hold & (1 << op) - 1)];
12966                continue dodist;
12967              } else {
12968                strm.msg = 'invalid distance code';
12969                state.mode = BAD$1;
12970                break top;
12971              }
12972
12973              break; // need to emulate goto via "continue"
12974            }
12975          } else if ((op & 64) === 0) {
12976            /* 2nd level length code */
12977            here = lcode[(here & 0xffff
12978            /*here.val*/
12979            ) + (hold & (1 << op) - 1)];
12980            continue dolen;
12981          } else if (op & 32) {
12982            /* end-of-block */
12983            //Tracevv((stderr, "inflate:         end of block\n"));
12984            state.mode = TYPE$1;
12985            break top;
12986          } else {
12987            strm.msg = 'invalid literal/length code';
12988            state.mode = BAD$1;
12989            break top;
12990          }
12991
12992          break; // need to emulate goto via "continue"
12993        }
12994      } while (_in < last && _out < end);
12995      /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
12996
12997
12998      len = bits >> 3;
12999      _in -= len;
13000      bits -= len << 3;
13001      hold &= (1 << bits) - 1;
13002      /* update state and return */
13003
13004      strm.next_in = _in;
13005      strm.next_out = _out;
13006      strm.avail_in = _in < last ? 5 + (last - _in) : 5 - (_in - last);
13007      strm.avail_out = _out < end ? 257 + (end - _out) : 257 - (_out - end);
13008      state.hold = hold;
13009      state.bits = bits;
13010      return;
13011    }; // (C) 1995-2013 Jean-loup Gailly and Mark Adler
13012    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
13013    //
13014    // This software is provided 'as-is', without any express or implied
13015    // warranty. In no event will the authors be held liable for any damages
13016    // arising from the use of this software.
13017    //
13018    // Permission is granted to anyone to use this software for any purpose,
13019    // including commercial applications, and to alter it and redistribute it
13020    // freely, subject to the following restrictions:
13021    //
13022    // 1. The origin of this software must not be misrepresented; you must not
13023    //   claim that you wrote the original software. If you use this software
13024    //   in a product, an acknowledgment in the product documentation would be
13025    //   appreciated but is not required.
13026    // 2. Altered source versions must be plainly marked as such, and must not be
13027    //   misrepresented as being the original software.
13028    // 3. This notice may not be removed or altered from any source distribution.
13029
13030
13031    const MAXBITS = 15;
13032    const ENOUGH_LENS$1 = 852;
13033    const ENOUGH_DISTS$1 = 592; //const ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
13034
13035    const CODES$1 = 0;
13036    const LENS$1 = 1;
13037    const DISTS$1 = 2;
13038    const lbase = new Uint16Array([
13039    /* Length codes 257..285 base */
13040    3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0]);
13041    const lext = new Uint8Array([
13042    /* Length codes 257..285 extra */
13043    16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78]);
13044    const dbase = new Uint16Array([
13045    /* Distance codes 0..29 base */
13046    1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0]);
13047    const dext = new Uint8Array([
13048    /* Distance codes 0..29 extra */
13049    16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64]);
13050
13051    const inflate_table = (type, lens, lens_index, codes, table, table_index, work, opts) => {
13052      const bits = opts.bits; //here = opts.here; /* table entry for duplication */
13053
13054      let len = 0;
13055      /* a code's length in bits */
13056
13057      let sym = 0;
13058      /* index of code symbols */
13059
13060      let min = 0,
13061          max = 0;
13062      /* minimum and maximum code lengths */
13063
13064      let root = 0;
13065      /* number of index bits for root table */
13066
13067      let curr = 0;
13068      /* number of index bits for current table */
13069
13070      let drop = 0;
13071      /* code bits to drop for sub-table */
13072
13073      let left = 0;
13074      /* number of prefix codes available */
13075
13076      let used = 0;
13077      /* code entries in table used */
13078
13079      let huff = 0;
13080      /* Huffman code */
13081
13082      let incr;
13083      /* for incrementing code, index */
13084
13085      let fill;
13086      /* index for replicating entries */
13087
13088      let low;
13089      /* low bits for current root entry */
13090
13091      let mask;
13092      /* mask for low root bits */
13093
13094      let next;
13095      /* next available space in table */
13096
13097      let base = null;
13098      /* base value table to use */
13099
13100      let base_index = 0; //  let shoextra;    /* extra bits table to use */
13101
13102      let end;
13103      /* use base and extra for symbol > end */
13104
13105      const count = new Uint16Array(MAXBITS + 1); //[MAXBITS+1];    /* number of codes of each length */
13106
13107      const offs = new Uint16Array(MAXBITS + 1); //[MAXBITS+1];     /* offsets in table for each length */
13108
13109      let extra = null;
13110      let extra_index = 0;
13111      let here_bits, here_op, here_val;
13112      /*
13113       Process a set of code lengths to create a canonical Huffman code.  The
13114       code lengths are lens[0..codes-1].  Each length corresponds to the
13115       symbols 0..codes-1.  The Huffman code is generated by first sorting the
13116       symbols by length from short to long, and retaining the symbol order
13117       for codes with equal lengths.  Then the code starts with all zero bits
13118       for the first code of the shortest length, and the codes are integer
13119       increments for the same length, and zeros are appended as the length
13120       increases.  For the deflate format, these bits are stored backwards
13121       from their more natural integer increment ordering, and so when the
13122       decoding tables are built in the large loop below, the integer codes
13123       are incremented backwards.
13124        This routine assumes, but does not check, that all of the entries in
13125       lens[] are in the range 0..MAXBITS.  The caller must assure this.
13126       1..MAXBITS is interpreted as that code length.  zero means that that
13127       symbol does not occur in this code.
13128        The codes are sorted by computing a count of codes for each length,
13129       creating from that a table of starting indices for each length in the
13130       sorted table, and then entering the symbols in order in the sorted
13131       table.  The sorted table is work[], with that space being provided by
13132       the caller.
13133        The length counts are used for other purposes as well, i.e. finding
13134       the minimum and maximum length codes, determining if there are any
13135       codes at all, checking for a valid set of lengths, and looking ahead
13136       at length counts to determine sub-table sizes when building the
13137       decoding tables.
13138       */
13139
vendor: 4,847 bytes, lines 13140-13297
13140      /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
13141
13142      for (len = 0; len <= MAXBITS; len++) {
13143        count[len] = 0;
13144      }
13145
13146      for (sym = 0; sym < codes; sym++) {
13147        count[lens[lens_index + sym]]++;
13148      }
13149      /* bound code lengths, force root to be within code lengths */
13150
13151
13152      root = bits;
13153
13154      for (max = MAXBITS; max >= 1; max--) {
13155        if (count[max] !== 0) {
13156          break;
13157        }
13158      }
13159
13160      if (root > max) {
13161        root = max;
13162      }
13163
13164      if (max === 0) {
13165        /* no symbols to code at all */
13166        //table.op[opts.table_index] = 64;  //here.op = (var char)64;    /* invalid code marker */
13167        //table.bits[opts.table_index] = 1;   //here.bits = (var char)1;
13168        //table.val[opts.table_index++] = 0;   //here.val = (var short)0;
13169        table[table_index++] = 1 << 24 | 64 << 16 | 0; //table.op[opts.table_index] = 64;
13170        //table.bits[opts.table_index] = 1;
13171        //table.val[opts.table_index++] = 0;
13172
13173        table[table_index++] = 1 << 24 | 64 << 16 | 0;
13174        opts.bits = 1;
13175        return 0;
13176        /* no symbols, but wait for decoding to report error */
13177      }
13178
13179      for (min = 1; min < max; min++) {
13180        if (count[min] !== 0) {
13181          break;
13182        }
13183      }
13184
13185      if (root < min) {
13186        root = min;
13187      }
13188      /* check for an over-subscribed or incomplete set of lengths */
13189
13190
13191      left = 1;
13192
13193      for (len = 1; len <= MAXBITS; len++) {
13194        left <<= 1;
13195        left -= count[len];
13196
13197        if (left < 0) {
13198          return -1;
13199        }
13200        /* over-subscribed */
13201
13202      }
13203
13204      if (left > 0 && (type === CODES$1 || max !== 1)) {
13205        return -1;
13206        /* incomplete set */
13207      }
13208      /* generate offsets into symbol table for each length for sorting */
13209
13210
13211      offs[1] = 0;
13212
13213      for (len = 1; len < MAXBITS; len++) {
13214        offs[len + 1] = offs[len] + count[len];
13215      }
13216      /* sort symbols by length, by symbol order within each length */
13217
13218
13219      for (sym = 0; sym < codes; sym++) {
13220        if (lens[lens_index + sym] !== 0) {
13221          work[offs[lens[lens_index + sym]]++] = sym;
13222        }
13223      }
13224      /*
13225       Create and fill in decoding tables.  In this loop, the table being
13226       filled is at next and has curr index bits.  The code being used is huff
13227       with length len.  That code is converted to an index by dropping drop
13228       bits off of the bottom.  For codes where len is less than drop + curr,
13229       those top drop + curr - len bits are incremented through all values to
13230       fill the table with replicated entries.
13231        root is the number of index bits for the root table.  When len exceeds
13232       root, sub-tables are created pointed to by the root entry with an index
13233       of the low root bits of huff.  This is saved in low to check for when a
13234       new sub-table should be started.  drop is zero when the root table is
13235       being filled, and drop is root when sub-tables are being filled.
13236        When a new sub-table is needed, it is necessary to look ahead in the
13237       code lengths to determine what size sub-table is needed.  The length
13238       counts are used for this, and so count[] is decremented as codes are
13239       entered in the tables.
13240        used keeps track of how many table entries have been allocated from the
13241       provided *table space.  It is checked for LENS and DIST tables against
13242       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
13243       the initial root table size constants.  See the comments in inftrees.h
13244       for more information.
13245        sym increments through all symbols, and the loop terminates when
13246       all codes of length max, i.e. all codes, have been processed.  This
13247       routine permits incomplete codes, so another loop after this one fills
13248       in the rest of the decoding tables with invalid code markers.
13249       */
13250
13251      /* set up for code type */
13252      // poor man optimization - use if-else instead of switch,
13253      // to avoid deopts in old v8
13254
13255
13256      if (type === CODES$1) {
13257        base = extra = work;
13258        /* dummy value--not used */
13259
13260        end = 19;
13261      } else if (type === LENS$1) {
13262        base = lbase;
13263        base_index -= 257;
13264        extra = lext;
13265        extra_index -= 257;
13266        end = 256;
13267      } else {
13268        /* DISTS */
13269        base = dbase;
13270        extra = dext;
13271        end = -1;
13272      }
13273      /* initialize opts for loop */
13274
13275
13276      huff = 0;
13277      /* starting code */
13278
13279      sym = 0;
13280      /* starting code symbol */
13281
13282      len = min;
13283      /* starting code length */
13284
13285      next = table_index;
13286      /* current table to fill in */
13287
13288      curr = root;
13289      /* current table index bits */
13290
13291      drop = 0;
13292      /* current bits to drop from code for index */
13293
13294      low = -1;
13295      /* trigger new sub-table when len > root */
13296
13297      used = 1 << root;
13298      /* use root table entries */
13299
13300      mask = used - 1;
13301      /* mask for comparing low */
13302
13303      /* check available table space */
13304
13305      if (type === LENS$1 && used > ENOUGH_LENS$1 || type === DISTS$1 && used > ENOUGH_DISTS$1) {
13306        return 1;
13307      }
13308      /* process all codes and make table entries */
13309
13310
13311      for (;;) {
13312        /* create table entry */
13313        here_bits = len - drop;
13314
13315        if (work[sym] < end) {
13316          here_op = 0;
13317          here_val = work[sym];
13318        } else if (work[sym] > end) {
13319          here_op = extra[extra_index + work[sym]];
13320          here_val = base[base_index + work[sym]];
13321        } else {
13322          here_op = 32 + 64;
13323          /* end of block */
13324
13325          here_val = 0;
13326        }
13327        /* replicate for those indices with low len bits equal to huff */
13328
13329
13330        incr = 1 << len - drop;
13331        fill = 1 << curr;
13332        min = fill;
13333        /* save offset to next table */
13334
13335        do {
13336          fill -= incr;
13337          table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val | 0;
13338        } while (fill !== 0);
13339        /* backwards increment the len-bit code huff */
13340
13341
13342        incr = 1 << len - 1;
13343
13344        while (huff & incr) {
13345          incr >>= 1;
13346        }
13347
13348        if (incr !== 0) {
13349          huff &= incr - 1;
13350          huff += incr;
13351        } else {
13352          huff = 0;
13353        }
13354        /* go to next symbol, update count, len */
13355
13356
13357        sym++;
13358
13359        if (--count[len] === 0) {
13360          if (len === max) {
13361            break;
13362          }
13363
13364          len = lens[lens_index + work[sym]];
13365        }
13366        /* create new sub-table if needed */
13367
13368
13369        if (len > root && (huff & mask) !== low) {
13370          /* if first time, transition to sub-tables */
13371          if (drop === 0) {
13372            drop = root;
13373          }
13374          /* increment past last table */
13375
13376
13377          next += min;
13378          /* here min is 1 << curr */
13379
13380          /* determine length of next table */
13381
13382          curr = len - drop;
13383          left = 1 << curr;
13384
13385          while (curr + drop < max) {
13386            left -= count[curr + drop];
13387
13388            if (left <= 0) {
13389              break;
13390            }
13391
13392            curr++;
13393            left <<= 1;
13394          }
13395          /* check for enough space */
13396
13397
13398          used += 1 << curr;
13399
13400          if (type === LENS$1 && used > ENOUGH_LENS$1 || type === DISTS$1 && used > ENOUGH_DISTS$1) {
13401            return 1;
13402          }
13403          /* point entry in root table to sub-table */
13404
13405
13406          low = huff & mask;
13407          /*table.op[low] = curr;
13408          table.bits[low] = root;
13409          table.val[low] = next - opts.table_index;*/
13410
13411          table[low] = root << 24 | curr << 16 | next - table_index | 0;
13412        }
13413      }
13414      /* fill in remaining table entry if code is incomplete (guaranteed to have
13415       at most one remaining entry, since if the code is incomplete, the
13416       maximum code length that was allowed to get this far is one bit) */
13417
13418
13419      if (huff !== 0) {
13420        //table.op[next + huff] = 64;            /* invalid code marker */
13421        //table.bits[next + huff] = len - drop;
13422        //table.val[next + huff] = 0;
13423        table[next + huff] = len - drop << 24 | 64 << 16 | 0;
13424      }
13425      /* set return parameters */
13426      //opts.table_index += used;
13427
13428
13429      opts.bits = root;
13430      return 0;
13431    };
13432
13433    var inftrees = inflate_table; // (C) 1995-2013 Jean-loup Gailly and Mark Adler
13434    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
13435    //
13436    // This software is provided 'as-is', without any express or implied
13437    // warranty. In no event will the authors be held liable for any damages
13438    // arising from the use of this software.
13439    //
13440    // Permission is granted to anyone to use this software for any purpose,
13441    // including commercial applications, and to alter it and redistribute it
13442    // freely, subject to the following restrictions:
13443    //
13444    // 1. The origin of this software must not be misrepresented; you must not
13445    //   claim that you wrote the original software. If you use this software
13446    //   in a product, an acknowledgment in the product documentation would be
13447    //   appreciated but is not required.
13448    // 2. Altered source versions must be plainly marked as such, and must not be
13449    //   misrepresented as being the original software.
13450    // 3. This notice may not be removed or altered from any source distribution.
13451
13452    const CODES = 0;
13453    const LENS = 1;
13454    const DISTS = 2;
13455    /* Public constants ==========================================================*/
13456
13457    /* ===========================================================================*/
13458
13459    const {
13460      Z_FINISH: Z_FINISH$1,
13461      Z_BLOCK,
13462      Z_TREES,
13463      Z_OK: Z_OK$1,
13464      Z_STREAM_END: Z_STREAM_END$1,
13465      Z_NEED_DICT: Z_NEED_DICT$1,
13466      Z_STREAM_ERROR: Z_STREAM_ERROR$1,
13467      Z_DATA_ERROR: Z_DATA_ERROR$1,
13468      Z_MEM_ERROR: Z_MEM_ERROR$1,
vendor: 14,416 bytes, lines 13469-14029
13469      Z_BUF_ERROR,
13470      Z_DEFLATED
13471    } = constants$2;
13472    /* STATES ====================================================================*/
13473
13474    /* ===========================================================================*/
13475
13476    const HEAD = 1;
13477    /* i: waiting for magic header */
13478
13479    const FLAGS = 2;
13480    /* i: waiting for method and flags (gzip) */
13481
13482    const TIME = 3;
13483    /* i: waiting for modification time (gzip) */
13484
13485    const OS = 4;
13486    /* i: waiting for extra flags and operating system (gzip) */
13487
13488    const EXLEN = 5;
13489    /* i: waiting for extra length (gzip) */
13490
13491    const EXTRA = 6;
13492    /* i: waiting for extra bytes (gzip) */
13493
13494    const NAME$1 = 7;
13495    /* i: waiting for end of file name (gzip) */
13496
13497    const COMMENT = 8;
13498    /* i: waiting for end of comment (gzip) */
13499
13500    const HCRC = 9;
13501    /* i: waiting for header crc (gzip) */
13502
13503    const DICTID = 10;
13504    /* i: waiting for dictionary check value */
13505
13506    const DICT = 11;
13507    /* waiting for inflateSetDictionary() call */
13508
13509    const TYPE = 12;
13510    /* i: waiting for type bits, including last-flag bit */
13511
13512    const TYPEDO = 13;
13513    /* i: same, but skip check to exit inflate on new block */
13514
13515    const STORED = 14;
13516    /* i: waiting for stored size (length and complement) */
13517
13518    const COPY_ = 15;
13519    /* i/o: same as COPY below, but only first time in */
13520
13521    const COPY = 16;
13522    /* i/o: waiting for input or output to copy stored block */
13523
13524    const TABLE = 17;
13525    /* i: waiting for dynamic block table lengths */
13526
13527    const LENLENS = 18;
13528    /* i: waiting for code length code lengths */
13529
13530    const CODELENS = 19;
13531    /* i: waiting for length/lit and distance code lengths */
13532
13533    const LEN_ = 20;
13534    /* i: same as LEN below, but only first time in */
13535
13536    const LEN = 21;
13537    /* i: waiting for length/lit/eob code */
13538
13539    const LENEXT = 22;
13540    /* i: waiting for length extra bits */
13541
13542    const DIST = 23;
13543    /* i: waiting for distance code */
13544
13545    const DISTEXT = 24;
13546    /* i: waiting for distance extra bits */
13547
13548    const MATCH = 25;
13549    /* o: waiting for output space to copy string */
13550
13551    const LIT = 26;
13552    /* o: waiting for output space to write literal */
13553
13554    const CHECK = 27;
13555    /* i: waiting for 32-bit check value */
13556
13557    const LENGTH = 28;
13558    /* i: waiting for 32-bit length (gzip) */
13559
13560    const DONE = 29;
13561    /* finished check, done -- remain here until reset */
13562
13563    const BAD = 30;
13564    /* got a data error -- remain here until reset */
13565
13566    const MEM = 31;
13567    /* got an inflate() memory error -- remain here until reset */
13568
13569    const SYNC = 32;
13570    /* looking for synchronization bytes to restart inflate() */
13571
13572    /* ===========================================================================*/
13573
13574    const ENOUGH_LENS = 852;
13575    const ENOUGH_DISTS = 592; //const ENOUGH =  (ENOUGH_LENS+ENOUGH_DISTS);
13576
13577    const MAX_WBITS = 15;
13578    /* 32K LZ77 window */
13579
13580    const DEF_WBITS = MAX_WBITS;
13581
13582    const zswap32 = q => {
13583      return (q >>> 24 & 0xff) + (q >>> 8 & 0xff00) + ((q & 0xff00) << 8) + ((q & 0xff) << 24);
13584    };
13585
13586    function InflateState() {
13587      this.mode = 0;
13588      /* current inflate mode */
13589
13590      this.last = false;
13591      /* true if processing last block */
13592
13593      this.wrap = 0;
13594      /* bit 0 true for zlib, bit 1 true for gzip */
13595
13596      this.havedict = false;
13597      /* true if dictionary provided */
13598
13599      this.flags = 0;
13600      /* gzip header method and flags (0 if zlib) */
13601
13602      this.dmax = 0;
13603      /* zlib header max distance (INFLATE_STRICT) */
13604
13605      this.check = 0;
13606      /* protected copy of check value */
13607
13608      this.total = 0;
13609      /* protected copy of output count */
13610      // TODO: may be {}
13611
13612      this.head = null;
13613      /* where to save gzip header information */
13614
13615      /* sliding window */
13616
13617      this.wbits = 0;
13618      /* log base 2 of requested window size */
13619
13620      this.wsize = 0;
13621      /* window size or zero if not using window */
13622
13623      this.whave = 0;
13624      /* valid bytes in the window */
13625
13626      this.wnext = 0;
13627      /* window write index */
13628
13629      this.window = null;
13630      /* allocated sliding window, if needed */
13631
13632      /* bit accumulator */
13633
13634      this.hold = 0;
13635      /* input bit accumulator */
13636
13637      this.bits = 0;
13638      /* number of bits in "in" */
13639
13640      /* for string and stored block copying */
13641
13642      this.length = 0;
13643      /* literal or length of data to copy */
13644
13645      this.offset = 0;
13646      /* distance back to copy string from */
13647
13648      /* for table and code decoding */
13649
13650      this.extra = 0;
13651      /* extra bits needed */
13652
13653      /* fixed and dynamic code tables */
13654
13655      this.lencode = null;
13656      /* starting table for length/literal codes */
13657
13658      this.distcode = null;
13659      /* starting table for distance codes */
13660
13661      this.lenbits = 0;
13662      /* index bits for lencode */
13663
13664      this.distbits = 0;
13665      /* index bits for distcode */
13666
13667      /* dynamic table building */
13668
13669      this.ncode = 0;
13670      /* number of code length code lengths */
13671
13672      this.nlen = 0;
13673      /* number of length code lengths */
13674
13675      this.ndist = 0;
13676      /* number of distance code lengths */
13677
13678      this.have = 0;
13679      /* number of code lengths in lens[] */
13680
13681      this.next = null;
13682      /* next available space in codes[] */
13683
13684      this.lens = new Uint16Array(320);
13685      /* temporary storage for code lengths */
13686
13687      this.work = new Uint16Array(288);
13688      /* work area for code table building */
13689
13690      /*
13691       because we don't have pointers in js, we use lencode and distcode directly
13692       as buffers so we don't need codes
13693      */
13694      //this.codes = new Int32Array(ENOUGH);       /* space for code tables */
13695
13696      this.lendyn = null;
13697      /* dynamic table for length/literal codes (JS specific) */
13698
13699      this.distdyn = null;
13700      /* dynamic table for distance codes (JS specific) */
13701
13702      this.sane = 0;
13703      /* if false, allow invalid distance too far */
13704
13705      this.back = 0;
13706      /* bits back of last unprocessed length/lit */
13707
13708      this.was = 0;
13709      /* initial length of match */
13710    }
13711
13712    const inflateResetKeep = strm => {
13713      if (!strm || !strm.state) {
13714        return Z_STREAM_ERROR$1;
13715      }
13716
13717      const state = strm.state;
13718      strm.total_in = strm.total_out = state.total = 0;
13719      strm.msg = '';
13720      /*Z_NULL*/
13721
13722      if (state.wrap) {
13723        /* to support ill-conceived Java test suite */
13724        strm.adler = state.wrap & 1;
13725      }
13726
13727      state.mode = HEAD;
13728      state.last = 0;
13729      state.havedict = 0;
13730      state.dmax = 32768;
13731      state.head = null
13732      /*Z_NULL*/
13733      ;
13734      state.hold = 0;
13735      state.bits = 0; //state.lencode = state.distcode = state.next = state.codes;
13736
13737      state.lencode = state.lendyn = new Int32Array(ENOUGH_LENS);
13738      state.distcode = state.distdyn = new Int32Array(ENOUGH_DISTS);
13739      state.sane = 1;
13740      state.back = -1; //Tracev((stderr, "inflate: reset\n"));
13741
13742      return Z_OK$1;
13743    };
13744
13745    const inflateReset = strm => {
13746      if (!strm || !strm.state) {
13747        return Z_STREAM_ERROR$1;
13748      }
13749
13750      const state = strm.state;
13751      state.wsize = 0;
13752      state.whave = 0;
13753      state.wnext = 0;
13754      return inflateResetKeep(strm);
13755    };
13756
13757    const inflateReset2 = (strm, windowBits) => {
13758      let wrap;
13759      /* get the state */
13760
13761      if (!strm || !strm.state) {
13762        return Z_STREAM_ERROR$1;
13763      }
13764
13765      const state = strm.state;
13766      /* extract wrap request from windowBits parameter */
13767
13768      if (windowBits < 0) {
13769        wrap = 0;
13770        windowBits = -windowBits;
13771      } else {
13772        wrap = (windowBits >> 4) + 1;
13773
13774        if (windowBits < 48) {
13775          windowBits &= 15;
13776        }
13777      }
13778      /* set number of window bits, free window if different */
13779
13780
13781      if (windowBits && (windowBits < 8 || windowBits > 15)) {
13782        return Z_STREAM_ERROR$1;
13783      }
13784
13785      if (state.window !== null && state.wbits !== windowBits) {
13786        state.window = null;
13787      }
13788      /* update state and reset the rest of it */
13789
13790
13791      state.wrap = wrap;
13792      state.wbits = windowBits;
13793      return inflateReset(strm);
13794    };
13795
13796    const inflateInit2 = (strm, windowBits) => {
13797      if (!strm) {
13798        return Z_STREAM_ERROR$1;
13799      } //strm.msg = Z_NULL;                 /* in case we return an error */
13800
13801
13802      const state = new InflateState(); //if (state === Z_NULL) return Z_MEM_ERROR;
13803      //Tracev((stderr, "inflate: allocated\n"));
13804
13805      strm.state = state;
13806      state.window = null
13807      /*Z_NULL*/
13808      ;
13809      const ret = inflateReset2(strm, windowBits);
13810
13811      if (ret !== Z_OK$1) {
13812        strm.state = null
13813        /*Z_NULL*/
13814        ;
13815      }
13816
13817      return ret;
13818    };
13819
13820    const inflateInit = strm => {
13821      return inflateInit2(strm, DEF_WBITS);
13822    };
13823    /*
13824     Return state with length and distance decoding tables and index sizes set to
13825     fixed code decoding.  Normally this returns fixed tables from inffixed.h.
13826     If BUILDFIXED is defined, then instead this routine builds the tables the
13827     first time it's called, and returns those tables the first time and
13828     thereafter.  This reduces the size of the code by about 2K bytes, in
13829     exchange for a little execution time.  However, BUILDFIXED should not be
13830     used for threaded applications, since the rewriting of the tables and virgin
13831     may not be thread-safe.
13832     */
13833
13834
13835    let virgin = true;
13836    let lenfix, distfix; // We have no pointers in JS, so keep tables separate
13837
13838    const fixedtables = state => {
13839      /* build fixed huffman tables if first call (may not be thread safe) */
13840      if (virgin) {
13841        lenfix = new Int32Array(512);
13842        distfix = new Int32Array(32);
13843        /* literal/length table */
13844
13845        let sym = 0;
13846
13847        while (sym < 144) {
13848          state.lens[sym++] = 8;
13849        }
13850
13851        while (sym < 256) {
13852          state.lens[sym++] = 9;
13853        }
13854
13855        while (sym < 280) {
13856          state.lens[sym++] = 7;
13857        }
13858
13859        while (sym < 288) {
13860          state.lens[sym++] = 8;
13861        }
13862
13863        inftrees(LENS, state.lens, 0, 288, lenfix, 0, state.work, {
13864          bits: 9
13865        });
13866        /* distance table */
13867
13868        sym = 0;
13869
13870        while (sym < 32) {
13871          state.lens[sym++] = 5;
13872        }
13873
13874        inftrees(DISTS, state.lens, 0, 32, distfix, 0, state.work, {
13875          bits: 5
13876        });
13877        /* do this just once */
13878
13879        virgin = false;
13880      }
13881
13882      state.lencode = lenfix;
13883      state.lenbits = 9;
13884      state.distcode = distfix;
13885      state.distbits = 5;
13886    };
13887    /*
13888     Update the window with the last wsize (normally 32K) bytes written before
13889     returning.  If window does not exist yet, create it.  This is only called
13890     when a window is already in use, or when output has been written during this
13891     inflate call, but the end of the deflate stream has not been reached yet.
13892     It is also called to create a window for dictionary data when a dictionary
13893     is loaded.
13894      Providing output buffers larger than 32K to inflate() should provide a speed
13895     advantage, since only the last 32K of output is copied to the sliding window
13896     upon return from inflate(), and since all distances after the first 32K of
13897     output will fall in the output data, making match copies simpler and faster.
13898     The advantage may be dependent on the size of the processor's data caches.
13899     */
13900
13901
13902    const updatewindow = (strm, src, end, copy) => {
13903      let dist;
13904      const state = strm.state;
13905      /* if it hasn't been done already, allocate space for the window */
13906
13907      if (state.window === null) {
13908        state.wsize = 1 << state.wbits;
13909        state.wnext = 0;
13910        state.whave = 0;
13911        state.window = new Uint8Array(state.wsize);
13912      }
13913      /* copy state->wsize or less output bytes into the circular window */
13914
13915
13916      if (copy >= state.wsize) {
13917        state.window.set(src.subarray(end - state.wsize, end), 0);
13918        state.wnext = 0;
13919        state.whave = state.wsize;
13920      } else {
13921        dist = state.wsize - state.wnext;
13922
13923        if (dist > copy) {
13924          dist = copy;
13925        } //zmemcpy(state->window + state->wnext, end - copy, dist);
13926
13927
13928        state.window.set(src.subarray(end - copy, end - copy + dist), state.wnext);
13929        copy -= dist;
13930
13931        if (copy) {
13932          //zmemcpy(state->window, end - copy, copy);
13933          state.window.set(src.subarray(end - copy, end), 0);
13934          state.wnext = copy;
13935          state.whave = state.wsize;
13936        } else {
13937          state.wnext += dist;
13938
13939          if (state.wnext === state.wsize) {
13940            state.wnext = 0;
13941          }
13942
13943          if (state.whave < state.wsize) {
13944            state.whave += dist;
13945          }
13946        }
13947      }
13948
13949      return 0;
13950    };
13951
13952    const inflate$2 = (strm, flush) => {
13953      let state;
13954      let input, output; // input/output buffers
13955
13956      let next;
13957      /* next input INDEX */
13958
13959      let put;
13960      /* next output INDEX */
13961
13962      let have, left;
13963      /* available input and output */
13964
13965      let hold;
13966      /* bit buffer */
13967
13968      let bits;
13969      /* bits in bit buffer */
13970
13971      let _in, _out;
13972      /* save starting available input and output */
13973
13974
13975      let copy;
13976      /* number of stored or match bytes to copy */
13977
13978      let from;
13979      /* where to copy match bytes from */
13980
13981      let from_source;
13982      let here = 0;
13983      /* current decoding table entry */
13984
13985      let here_bits, here_op, here_val; // paked "here" denormalized (JS specific)
13986      //let last;                   /* parent table entry */
13987
13988      let last_bits, last_op, last_val; // paked "last" denormalized (JS specific)
13989
13990      let len;
13991      /* length to copy for repeats, bits to drop */
13992
13993      let ret;
13994      /* return code */
13995
13996      const hbuf = new Uint8Array(4);
13997      /* buffer for gzip header crc calculation */
13998
13999      let opts;
14000      let n; // temporary variable for NEED_BITS
14001
14002      const order =
14003      /* permutation of code lengths */
14004      new Uint8Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
14005
14006      if (!strm || !strm.state || !strm.output || !strm.input && strm.avail_in !== 0) {
14007        return Z_STREAM_ERROR$1;
14008      }
14009
14010      state = strm.state;
14011
14012      if (state.mode === TYPE) {
14013        state.mode = TYPEDO;
14014      }
14015      /* skip check */
14016      //--- LOAD() ---
14017
14018
14019      put = strm.next_out;
14020      output = strm.output;
14021      left = strm.avail_out;
14022      next = strm.next_in;
14023      input = strm.input;
14024      have = strm.avail_in;
14025      hold = state.hold;
14026      bits = state.bits; //---
14027
14028      _in = have;
14029      _out = left;
14030      ret = Z_OK$1;
14031
14032      inf_leave: // goto emulation
14033      for (;;) {
14034        switch (state.mode) {
14035          case HEAD:
14036            if (state.wrap === 0) {
14037              state.mode = TYPEDO;
14038              break;
14039            } //=== NEEDBITS(16);
14040
14041
14042            while (bits < 16) {
14043              if (have === 0) {
14044                break inf_leave;
14045              }
14046
14047              have--;
14048              hold += input[next++] << bits;
14049              bits += 8;
14050            } //===//
14051
14052
14053            if (state.wrap & 2 && hold === 0x8b1f) {
14054              /* gzip header */
14055              state.check = 0
14056              /*crc32(0L, Z_NULL, 0)*/
14057              ; //=== CRC2(state.check, hold);
14058
14059              hbuf[0] = hold & 0xff;
14060              hbuf[1] = hold >>> 8 & 0xff;
14061              state.check = crc32_1(state.check, hbuf, 2, 0); //===//
14062              //=== INITBITS();
14063
14064              hold = 0;
14065              bits = 0; //===//
14066
14067              state.mode = FLAGS;
14068              break;
14069            }
14070
14071            state.flags = 0;
14072            /* expect zlib header */
14073
14074            if (state.head) {
14075              state.head.done = false;
14076            }
14077
14078            if (!(state.wrap & 1) ||
14079            /* check if zlib header allowed */
14080            (((hold & 0xff
14081            /*BITS(8)*/
14082            ) << 8) + (hold >> 8)) % 31) {
14083              strm.msg = 'incorrect header check';
14084              state.mode = BAD;
14085              break;
14086            }
14087
14088            if ((hold & 0x0f
14089            /*BITS(4)*/
14090            ) !== Z_DEFLATED) {
14091              strm.msg = 'unknown compression method';
14092              state.mode = BAD;
14093              break;
14094            } //--- DROPBITS(4) ---//
14095
14096
14097            hold >>>= 4;
14098            bits -= 4; //---//
14099
14100            len = (hold & 0x0f
14101            /*BITS(4)*/
14102            ) + 8;
14103
14104            if (state.wbits === 0) {
14105              state.wbits = len;
14106            } else if (len > state.wbits) {
14107              strm.msg = 'invalid window size';
14108              state.mode = BAD;
14109              break;
14110            } // !!! pako patch. Force use `options.windowBits` if passed.
14111            // Required to always use max window size by default.
14112
14113
14114            state.dmax = 1 << state.wbits; //state.dmax = 1 << len;
14115            //Tracev((stderr, "inflate:   zlib header ok\n"));
14116
14117            strm.adler = state.check = 1
14118            /*adler32(0L, Z_NULL, 0)*/
14119            ;
14120            state.mode = hold & 0x200 ? DICTID : TYPE; //=== INITBITS();
14121
14122            hold = 0;
14123            bits = 0; //===//
14124
14125            break;
14126
14127          case FLAGS:
14128            //=== NEEDBITS(16); */
14129            while (bits < 16) {
14130              if (have === 0) {
14131                break inf_leave;
14132              }
14133
14134              have--;
14135              hold += input[next++] << bits;
14136              bits += 8;
14137            } //===//
14138
14139
14140            state.flags = hold;
14141
14142            if ((state.flags & 0xff) !== Z_DEFLATED) {
14143              strm.msg = 'unknown compression method';
14144              state.mode = BAD;
14145              break;
14146            }
14147
14148            if (state.flags & 0xe000) {
14149              strm.msg = 'unknown header flags set';
14150              state.mode = BAD;
14151              break;
14152            }
14153
14154            if (state.head) {
14155              state.head.text = hold >> 8 & 1;
14156            }
14157
14158            if (state.flags & 0x0200) {
14159              //=== CRC2(state.check, hold);
14160              hbuf[0] = hold & 0xff;
14161              hbuf[1] = hold >>> 8 & 0xff;
14162              state.check = crc32_1(state.check, hbuf, 2, 0); //===//
14163            } //=== INITBITS();
14164
14165
14166            hold = 0;
14167            bits = 0; //===//
14168
14169            state.mode = TIME;
14170
14171          /* falls through */
14172
14173          case TIME:
14174            //=== NEEDBITS(32); */
14175            while (bits < 32) {
14176              if (have === 0) {
14177                break inf_leave;
14178              }
14179
14180              have--;
14181              hold += input[next++] << bits;
14182              bits += 8;
14183            } //===//
14184
14185
14186            if (state.head) {
14187              state.head.time = hold;
14188            }
14189
14190            if (state.flags & 0x0200) {
14191              //=== CRC4(state.check, hold)
14192              hbuf[0] = hold & 0xff;
vendor: 33,063 bytes, lines 14193-15392
14193              hbuf[1] = hold >>> 8 & 0xff;
14194              hbuf[2] = hold >>> 16 & 0xff;
14195              hbuf[3] = hold >>> 24 & 0xff;
14196              state.check = crc32_1(state.check, hbuf, 4, 0); //===
14197            } //=== INITBITS();
14198
14199
14200            hold = 0;
14201            bits = 0; //===//
14202
14203            state.mode = OS;
14204
14205          /* falls through */
14206
14207          case OS:
14208            //=== NEEDBITS(16); */
14209            while (bits < 16) {
14210              if (have === 0) {
14211                break inf_leave;
14212              }
14213
14214              have--;
14215              hold += input[next++] << bits;
14216              bits += 8;
14217            } //===//
14218
14219
14220            if (state.head) {
14221              state.head.xflags = hold & 0xff;
14222              state.head.os = hold >> 8;
14223            }
14224
14225            if (state.flags & 0x0200) {
14226              //=== CRC2(state.check, hold);
14227              hbuf[0] = hold & 0xff;
14228              hbuf[1] = hold >>> 8 & 0xff;
14229              state.check = crc32_1(state.check, hbuf, 2, 0); //===//
14230            } //=== INITBITS();
14231
14232
14233            hold = 0;
14234            bits = 0; //===//
14235
14236            state.mode = EXLEN;
14237
14238          /* falls through */
14239
14240          case EXLEN:
14241            if (state.flags & 0x0400) {
14242              //=== NEEDBITS(16); */
14243              while (bits < 16) {
14244                if (have === 0) {
14245                  break inf_leave;
14246                }
14247
14248                have--;
14249                hold += input[next++] << bits;
14250                bits += 8;
14251              } //===//
14252
14253
14254              state.length = hold;
14255
14256              if (state.head) {
14257                state.head.extra_len = hold;
14258              }
14259
14260              if (state.flags & 0x0200) {
14261                //=== CRC2(state.check, hold);
14262                hbuf[0] = hold & 0xff;
14263                hbuf[1] = hold >>> 8 & 0xff;
14264                state.check = crc32_1(state.check, hbuf, 2, 0); //===//
14265              } //=== INITBITS();
14266
14267
14268              hold = 0;
14269              bits = 0; //===//
14270            } else if (state.head) {
14271              state.head.extra = null
14272              /*Z_NULL*/
14273              ;
14274            }
14275
14276            state.mode = EXTRA;
14277
14278          /* falls through */
14279
14280          case EXTRA:
14281            if (state.flags & 0x0400) {
14282              copy = state.length;
14283
14284              if (copy > have) {
14285                copy = have;
14286              }
14287
14288              if (copy) {
14289                if (state.head) {
14290                  len = state.head.extra_len - state.length;
14291
14292                  if (!state.head.extra) {
14293                    // Use untyped array for more convenient processing later
14294                    state.head.extra = new Uint8Array(state.head.extra_len);
14295                  }
14296
14297                  state.head.extra.set(input.subarray(next, // extra field is limited to 65536 bytes
14298                  // - no need for additional size check
14299                  next + copy),
14300                  /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/
14301                  len); //zmemcpy(state.head.extra + len, next,
14302                  //        len + copy > state.head.extra_max ?
14303                  //        state.head.extra_max - len : copy);
14304                }
14305
14306                if (state.flags & 0x0200) {
14307                  state.check = crc32_1(state.check, input, copy, next);
14308                }
14309
14310                have -= copy;
14311                next += copy;
14312                state.length -= copy;
14313              }
14314
14315              if (state.length) {
14316                break inf_leave;
14317              }
14318            }
14319
14320            state.length = 0;
14321            state.mode = NAME$1;
14322
14323          /* falls through */
14324
14325          case NAME$1:
14326            if (state.flags & 0x0800) {
14327              if (have === 0) {
14328                break inf_leave;
14329              }
14330
14331              copy = 0;
14332
14333              do {
14334                // TODO: 2 or 1 bytes?
14335                len = input[next + copy++];
14336                /* use constant limit because in js we should not preallocate memory */
14337
14338                if (state.head && len && state.length < 65536
14339                /*state.head.name_max*/
14340                ) {
14341                  state.head.name += String.fromCharCode(len);
14342                }
14343              } while (len && copy < have);
14344
14345              if (state.flags & 0x0200) {
14346                state.check = crc32_1(state.check, input, copy, next);
14347              }
14348
14349              have -= copy;
14350              next += copy;
14351
14352              if (len) {
14353                break inf_leave;
14354              }
14355            } else if (state.head) {
14356              state.head.name = null;
14357            }
14358
14359            state.length = 0;
14360            state.mode = COMMENT;
14361
14362          /* falls through */
14363
14364          case COMMENT:
14365            if (state.flags & 0x1000) {
14366              if (have === 0) {
14367                break inf_leave;
14368              }
14369
14370              copy = 0;
14371
14372              do {
14373                len = input[next + copy++];
14374                /* use constant limit because in js we should not preallocate memory */
14375
14376                if (state.head && len && state.length < 65536
14377                /*state.head.comm_max*/
14378                ) {
14379                  state.head.comment += String.fromCharCode(len);
14380                }
14381              } while (len && copy < have);
14382
14383              if (state.flags & 0x0200) {
14384                state.check = crc32_1(state.check, input, copy, next);
14385              }
14386
14387              have -= copy;
14388              next += copy;
14389
14390              if (len) {
14391                break inf_leave;
14392              }
14393            } else if (state.head) {
14394              state.head.comment = null;
14395            }
14396
14397            state.mode = HCRC;
14398
14399          /* falls through */
14400
14401          case HCRC:
14402            if (state.flags & 0x0200) {
14403              //=== NEEDBITS(16); */
14404              while (bits < 16) {
14405                if (have === 0) {
14406                  break inf_leave;
14407                }
14408
14409                have--;
14410                hold += input[next++] << bits;
14411                bits += 8;
14412              } //===//
14413
14414
14415              if (hold !== (state.check & 0xffff)) {
14416                strm.msg = 'header crc mismatch';
14417                state.mode = BAD;
14418                break;
14419              } //=== INITBITS();
14420
14421
14422              hold = 0;
14423              bits = 0; //===//
14424            }
14425
14426            if (state.head) {
14427              state.head.hcrc = state.flags >> 9 & 1;
14428              state.head.done = true;
14429            }
14430
14431            strm.adler = state.check = 0;
14432            state.mode = TYPE;
14433            break;
14434
14435          case DICTID:
14436            //=== NEEDBITS(32); */
14437            while (bits < 32) {
14438              if (have === 0) {
14439                break inf_leave;
14440              }
14441
14442              have--;
14443              hold += input[next++] << bits;
14444              bits += 8;
14445            } //===//
14446
14447
14448            strm.adler = state.check = zswap32(hold); //=== INITBITS();
14449
14450            hold = 0;
14451            bits = 0; //===//
14452
14453            state.mode = DICT;
14454
14455          /* falls through */
14456
14457          case DICT:
14458            if (state.havedict === 0) {
14459              //--- RESTORE() ---
14460              strm.next_out = put;
14461              strm.avail_out = left;
14462              strm.next_in = next;
14463              strm.avail_in = have;
14464              state.hold = hold;
14465              state.bits = bits; //---
14466
14467              return Z_NEED_DICT$1;
14468            }
14469
14470            strm.adler = state.check = 1
14471            /*adler32(0L, Z_NULL, 0)*/
14472            ;
14473            state.mode = TYPE;
14474
14475          /* falls through */
14476
14477          case TYPE:
14478            if (flush === Z_BLOCK || flush === Z_TREES) {
14479              break inf_leave;
14480            }
14481
14482          /* falls through */
14483
14484          case TYPEDO:
14485            if (state.last) {
14486              //--- BYTEBITS() ---//
14487              hold >>>= bits & 7;
14488              bits -= bits & 7; //---//
14489
14490              state.mode = CHECK;
14491              break;
14492            } //=== NEEDBITS(3); */
14493
14494
14495            while (bits < 3) {
14496              if (have === 0) {
14497                break inf_leave;
14498              }
14499
14500              have--;
14501              hold += input[next++] << bits;
14502              bits += 8;
14503            } //===//
14504
14505
14506            state.last = hold & 0x01
14507            /*BITS(1)*/
14508            ; //--- DROPBITS(1) ---//
14509
14510            hold >>>= 1;
14511            bits -= 1; //---//
14512
14513            switch (hold & 0x03
14514            /*BITS(2)*/
14515            ) {
14516              case 0:
14517                /* stored block */
14518                //Tracev((stderr, "inflate:     stored block%s\n",
14519                //        state.last ? " (last)" : ""));
14520                state.mode = STORED;
14521                break;
14522
14523              case 1:
14524                /* fixed block */
14525                fixedtables(state); //Tracev((stderr, "inflate:     fixed codes block%s\n",
14526                //        state.last ? " (last)" : ""));
14527
14528                state.mode = LEN_;
14529                /* decode codes */
14530
14531                if (flush === Z_TREES) {
14532                  //--- DROPBITS(2) ---//
14533                  hold >>>= 2;
14534                  bits -= 2; //---//
14535
14536                  break inf_leave;
14537                }
14538
14539                break;
14540
14541              case 2:
14542                /* dynamic block */
14543                //Tracev((stderr, "inflate:     dynamic codes block%s\n",
14544                //        state.last ? " (last)" : ""));
14545                state.mode = TABLE;
14546                break;
14547
14548              case 3:
14549                strm.msg = 'invalid block type';
14550                state.mode = BAD;
14551            } //--- DROPBITS(2) ---//
14552
14553
14554            hold >>>= 2;
14555            bits -= 2; //---//
14556
14557            break;
14558
14559          case STORED:
14560            //--- BYTEBITS() ---// /* go to byte boundary */
14561            hold >>>= bits & 7;
14562            bits -= bits & 7; //---//
14563            //=== NEEDBITS(32); */
14564
14565            while (bits < 32) {
14566              if (have === 0) {
14567                break inf_leave;
14568              }
14569
14570              have--;
14571              hold += input[next++] << bits;
14572              bits += 8;
14573            } //===//
14574
14575
14576            if ((hold & 0xffff) !== (hold >>> 16 ^ 0xffff)) {
14577              strm.msg = 'invalid stored block lengths';
14578              state.mode = BAD;
14579              break;
14580            }
14581
14582            state.length = hold & 0xffff; //Tracev((stderr, "inflate:       stored length %u\n",
14583            //        state.length));
14584            //=== INITBITS();
14585
14586            hold = 0;
14587            bits = 0; //===//
14588
14589            state.mode = COPY_;
14590
14591            if (flush === Z_TREES) {
14592              break inf_leave;
14593            }
14594
14595          /* falls through */
14596
14597          case COPY_:
14598            state.mode = COPY;
14599
14600          /* falls through */
14601
14602          case COPY:
14603            copy = state.length;
14604
14605            if (copy) {
14606              if (copy > have) {
14607                copy = have;
14608              }
14609
14610              if (copy > left) {
14611                copy = left;
14612              }
14613
14614              if (copy === 0) {
14615                break inf_leave;
14616              } //--- zmemcpy(put, next, copy); ---
14617
14618
14619              output.set(input.subarray(next, next + copy), put); //---//
14620
14621              have -= copy;
14622              next += copy;
14623              left -= copy;
14624              put += copy;
14625              state.length -= copy;
14626              break;
14627            } //Tracev((stderr, "inflate:       stored end\n"));
14628
14629
14630            state.mode = TYPE;
14631            break;
14632
14633          case TABLE:
14634            //=== NEEDBITS(14); */
14635            while (bits < 14) {
14636              if (have === 0) {
14637                break inf_leave;
14638              }
14639
14640              have--;
14641              hold += input[next++] << bits;
14642              bits += 8;
14643            } //===//
14644
14645
14646            state.nlen = (hold & 0x1f
14647            /*BITS(5)*/
14648            ) + 257; //--- DROPBITS(5) ---//
14649
14650            hold >>>= 5;
14651            bits -= 5; //---//
14652
14653            state.ndist = (hold & 0x1f
14654            /*BITS(5)*/
14655            ) + 1; //--- DROPBITS(5) ---//
14656
14657            hold >>>= 5;
14658            bits -= 5; //---//
14659
14660            state.ncode = (hold & 0x0f
14661            /*BITS(4)*/
14662            ) + 4; //--- DROPBITS(4) ---//
14663
14664            hold >>>= 4;
14665            bits -= 4; //---//
14666            //#ifndef PKZIP_BUG_WORKAROUND
14667
14668            if (state.nlen > 286 || state.ndist > 30) {
14669              strm.msg = 'too many length or distance symbols';
14670              state.mode = BAD;
14671              break;
14672            } //#endif
14673            //Tracev((stderr, "inflate:       table sizes ok\n"));
14674
14675
14676            state.have = 0;
14677            state.mode = LENLENS;
14678
14679          /* falls through */
14680
14681          case LENLENS:
14682            while (state.have < state.ncode) {
14683              //=== NEEDBITS(3);
14684              while (bits < 3) {
14685                if (have === 0) {
14686                  break inf_leave;
14687                }
14688
14689                have--;
14690                hold += input[next++] << bits;
14691                bits += 8;
14692              } //===//
14693
14694
14695              state.lens[order[state.have++]] = hold & 0x07; //BITS(3);
14696              //--- DROPBITS(3) ---//
14697
14698              hold >>>= 3;
14699              bits -= 3; //---//
14700            }
14701
14702            while (state.have < 19) {
14703              state.lens[order[state.have++]] = 0;
14704            } // We have separate tables & no pointers. 2 commented lines below not needed.
14705            //state.next = state.codes;
14706            //state.lencode = state.next;
14707            // Switch to use dynamic table
14708
14709
14710            state.lencode = state.lendyn;
14711            state.lenbits = 7;
14712            opts = {
14713              bits: state.lenbits
14714            };
14715            ret = inftrees(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);
14716            state.lenbits = opts.bits;
14717
14718            if (ret) {
14719              strm.msg = 'invalid code lengths set';
14720              state.mode = BAD;
14721              break;
14722            } //Tracev((stderr, "inflate:       code lengths ok\n"));
14723
14724
14725            state.have = 0;
14726            state.mode = CODELENS;
14727
14728          /* falls through */
14729
14730          case CODELENS:
14731            while (state.have < state.nlen + state.ndist) {
14732              for (;;) {
14733                here = state.lencode[hold & (1 << state.lenbits) - 1];
14734                /*BITS(state.lenbits)*/
14735
14736                here_bits = here >>> 24;
14737                here_op = here >>> 16 & 0xff;
14738                here_val = here & 0xffff;
14739
14740                if (here_bits <= bits) {
14741                  break;
14742                } //--- PULLBYTE() ---//
14743
14744
14745                if (have === 0) {
14746                  break inf_leave;
14747                }
14748
14749                have--;
14750                hold += input[next++] << bits;
14751                bits += 8; //---//
14752              }
14753
14754              if (here_val < 16) {
14755                //--- DROPBITS(here.bits) ---//
14756                hold >>>= here_bits;
14757                bits -= here_bits; //---//
14758
14759                state.lens[state.have++] = here_val;
14760              } else {
14761                if (here_val === 16) {
14762                  //=== NEEDBITS(here.bits + 2);
14763                  n = here_bits + 2;
14764
14765                  while (bits < n) {
14766                    if (have === 0) {
14767                      break inf_leave;
14768                    }
14769
14770                    have--;
14771                    hold += input[next++] << bits;
14772                    bits += 8;
14773                  } //===//
14774                  //--- DROPBITS(here.bits) ---//
14775
14776
14777                  hold >>>= here_bits;
14778                  bits -= here_bits; //---//
14779
14780                  if (state.have === 0) {
14781                    strm.msg = 'invalid bit length repeat';
14782                    state.mode = BAD;
14783                    break;
14784                  }
14785
14786                  len = state.lens[state.have - 1];
14787                  copy = 3 + (hold & 0x03); //BITS(2);
14788                  //--- DROPBITS(2) ---//
14789
14790                  hold >>>= 2;
14791                  bits -= 2; //---//
14792                } else if (here_val === 17) {
14793                  //=== NEEDBITS(here.bits + 3);
14794                  n = here_bits + 3;
14795
14796                  while (bits < n) {
14797                    if (have === 0) {
14798                      break inf_leave;
14799                    }
14800
14801                    have--;
14802                    hold += input[next++] << bits;
14803                    bits += 8;
14804                  } //===//
14805                  //--- DROPBITS(here.bits) ---//
14806
14807
14808                  hold >>>= here_bits;
14809                  bits -= here_bits; //---//
14810
14811                  len = 0;
14812                  copy = 3 + (hold & 0x07); //BITS(3);
14813                  //--- DROPBITS(3) ---//
14814
14815                  hold >>>= 3;
14816                  bits -= 3; //---//
14817                } else {
14818                  //=== NEEDBITS(here.bits + 7);
14819                  n = here_bits + 7;
14820
14821                  while (bits < n) {
14822                    if (have === 0) {
14823                      break inf_leave;
14824                    }
14825
14826                    have--;
14827                    hold += input[next++] << bits;
14828                    bits += 8;
14829                  } //===//
14830                  //--- DROPBITS(here.bits) ---//
14831
14832
14833                  hold >>>= here_bits;
14834                  bits -= here_bits; //---//
14835
14836                  len = 0;
14837                  copy = 11 + (hold & 0x7f); //BITS(7);
14838                  //--- DROPBITS(7) ---//
14839
14840                  hold >>>= 7;
14841                  bits -= 7; //---//
14842                }
14843
14844                if (state.have + copy > state.nlen + state.ndist) {
14845                  strm.msg = 'invalid bit length repeat';
14846                  state.mode = BAD;
14847                  break;
14848                }
14849
14850                while (copy--) {
14851                  state.lens[state.have++] = len;
14852                }
14853              }
14854            }
14855            /* handle error breaks in while */
14856
14857
14858            if (state.mode === BAD) {
14859              break;
14860            }
14861            /* check for end-of-block code (better have one) */
14862
14863
14864            if (state.lens[256] === 0) {
14865              strm.msg = 'invalid code -- missing end-of-block';
14866              state.mode = BAD;
14867              break;
14868            }
14869            /* build code tables -- note: do not change the lenbits or distbits
14870               values here (9 and 6) without reading the comments in inftrees.h
14871               concerning the ENOUGH constants, which depend on those values */
14872
14873
14874            state.lenbits = 9;
14875            opts = {
14876              bits: state.lenbits
14877            };
14878            ret = inftrees(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); // We have separate tables & no pointers. 2 commented lines below not needed.
14879            // state.next_index = opts.table_index;
14880
14881            state.lenbits = opts.bits; // state.lencode = state.next;
14882
14883            if (ret) {
14884              strm.msg = 'invalid literal/lengths set';
14885              state.mode = BAD;
14886              break;
14887            }
14888
14889            state.distbits = 6; //state.distcode.copy(state.codes);
14890            // Switch to use dynamic table
14891
14892            state.distcode = state.distdyn;
14893            opts = {
14894              bits: state.distbits
14895            };
14896            ret = inftrees(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); // We have separate tables & no pointers. 2 commented lines below not needed.
14897            // state.next_index = opts.table_index;
14898
14899            state.distbits = opts.bits; // state.distcode = state.next;
14900
14901            if (ret) {
14902              strm.msg = 'invalid distances set';
14903              state.mode = BAD;
14904              break;
14905            } //Tracev((stderr, 'inflate:       codes ok\n'));
14906
14907
14908            state.mode = LEN_;
14909
14910            if (flush === Z_TREES) {
14911              break inf_leave;
14912            }
14913
14914          /* falls through */
14915
14916          case LEN_:
14917            state.mode = LEN;
14918
14919          /* falls through */
14920
14921          case LEN:
14922            if (have >= 6 && left >= 258) {
14923              //--- RESTORE() ---
14924              strm.next_out = put;
14925              strm.avail_out = left;
14926              strm.next_in = next;
14927              strm.avail_in = have;
14928              state.hold = hold;
14929              state.bits = bits; //---
14930
14931              inffast(strm, _out); //--- LOAD() ---
14932
14933              put = strm.next_out;
14934              output = strm.output;
14935              left = strm.avail_out;
14936              next = strm.next_in;
14937              input = strm.input;
14938              have = strm.avail_in;
14939              hold = state.hold;
14940              bits = state.bits; //---
14941
14942              if (state.mode === TYPE) {
14943                state.back = -1;
14944              }
14945
14946              break;
14947            }
14948
14949            state.back = 0;
14950
14951            for (;;) {
14952              here = state.lencode[hold & (1 << state.lenbits) - 1];
14953              /*BITS(state.lenbits)*/
14954
14955              here_bits = here >>> 24;
14956              here_op = here >>> 16 & 0xff;
14957              here_val = here & 0xffff;
14958
14959              if (here_bits <= bits) {
14960                break;
14961              } //--- PULLBYTE() ---//
14962
14963
14964              if (have === 0) {
14965                break inf_leave;
14966              }
14967
14968              have--;
14969              hold += input[next++] << bits;
14970              bits += 8; //---//
14971            }
14972
14973            if (here_op && (here_op & 0xf0) === 0) {
14974              last_bits = here_bits;
14975              last_op = here_op;
14976              last_val = here_val;
14977
14978              for (;;) {
14979                here = state.lencode[last_val + ((hold & (1 << last_bits + last_op) - 1
14980                /*BITS(last.bits + last.op)*/
14981                ) >> last_bits)];
14982                here_bits = here >>> 24;
14983                here_op = here >>> 16 & 0xff;
14984                here_val = here & 0xffff;
14985
14986                if (last_bits + here_bits <= bits) {
14987                  break;
14988                } //--- PULLBYTE() ---//
14989
14990
14991                if (have === 0) {
14992                  break inf_leave;
14993                }
14994
14995                have--;
14996                hold += input[next++] << bits;
14997                bits += 8; //---//
14998              } //--- DROPBITS(last.bits) ---//
14999
15000
15001              hold >>>= last_bits;
15002              bits -= last_bits; //---//
15003
15004              state.back += last_bits;
15005            } //--- DROPBITS(here.bits) ---//
15006
15007
15008            hold >>>= here_bits;
15009            bits -= here_bits; //---//
15010
15011            state.back += here_bits;
15012            state.length = here_val;
15013
15014            if (here_op === 0) {
15015              //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
15016              //        "inflate:         literal '%c'\n" :
15017              //        "inflate:         literal 0x%02x\n", here.val));
15018              state.mode = LIT;
15019              break;
15020            }
15021
15022            if (here_op & 32) {
15023              //Tracevv((stderr, "inflate:         end of block\n"));
15024              state.back = -1;
15025              state.mode = TYPE;
15026              break;
15027            }
15028
15029            if (here_op & 64) {
15030              strm.msg = 'invalid literal/length code';
15031              state.mode = BAD;
15032              break;
15033            }
15034
15035            state.extra = here_op & 15;
15036            state.mode = LENEXT;
15037
15038          /* falls through */
15039
15040          case LENEXT:
15041            if (state.extra) {
15042              //=== NEEDBITS(state.extra);
15043              n = state.extra;
15044
15045              while (bits < n) {
15046                if (have === 0) {
15047                  break inf_leave;
15048                }
15049
15050                have--;
15051                hold += input[next++] << bits;
15052                bits += 8;
15053              } //===//
15054
15055
15056              state.length += hold & (1 << state.extra) - 1
15057              /*BITS(state.extra)*/
15058              ; //--- DROPBITS(state.extra) ---//
15059
15060              hold >>>= state.extra;
15061              bits -= state.extra; //---//
15062
15063              state.back += state.extra;
15064            } //Tracevv((stderr, "inflate:         length %u\n", state.length));
15065
15066
15067            state.was = state.length;
15068            state.mode = DIST;
15069
15070          /* falls through */
15071
15072          case DIST:
15073            for (;;) {
15074              here = state.distcode[hold & (1 << state.distbits) - 1];
15075              /*BITS(state.distbits)*/
15076
15077              here_bits = here >>> 24;
15078              here_op = here >>> 16 & 0xff;
15079              here_val = here & 0xffff;
15080
15081              if (here_bits <= bits) {
15082                break;
15083              } //--- PULLBYTE() ---//
15084
15085
15086              if (have === 0) {
15087                break inf_leave;
15088              }
15089
15090              have--;
15091              hold += input[next++] << bits;
15092              bits += 8; //---//
15093            }
15094
15095            if ((here_op & 0xf0) === 0) {
15096              last_bits = here_bits;
15097              last_op = here_op;
15098              last_val = here_val;
15099
15100              for (;;) {
15101                here = state.distcode[last_val + ((hold & (1 << last_bits + last_op) - 1
15102                /*BITS(last.bits + last.op)*/
15103                ) >> last_bits)];
15104                here_bits = here >>> 24;
15105                here_op = here >>> 16 & 0xff;
15106                here_val = here & 0xffff;
15107
15108                if (last_bits + here_bits <= bits) {
15109                  break;
15110                } //--- PULLBYTE() ---//
15111
15112
15113                if (have === 0) {
15114                  break inf_leave;
15115                }
15116
15117                have--;
15118                hold += input[next++] << bits;
15119                bits += 8; //---//
15120              } //--- DROPBITS(last.bits) ---//
15121
15122
15123              hold >>>= last_bits;
15124              bits -= last_bits; //---//
15125
15126              state.back += last_bits;
15127            } //--- DROPBITS(here.bits) ---//
15128
15129
15130            hold >>>= here_bits;
15131            bits -= here_bits; //---//
15132
15133            state.back += here_bits;
15134
15135            if (here_op & 64) {
15136              strm.msg = 'invalid distance code';
15137              state.mode = BAD;
15138              break;
15139            }
15140
15141            state.offset = here_val;
15142            state.extra = here_op & 15;
15143            state.mode = DISTEXT;
15144
15145          /* falls through */
15146
15147          case DISTEXT:
15148            if (state.extra) {
15149              //=== NEEDBITS(state.extra);
15150              n = state.extra;
15151
15152              while (bits < n) {
15153                if (have === 0) {
15154                  break inf_leave;
15155                }
15156
15157                have--;
15158                hold += input[next++] << bits;
15159                bits += 8;
15160              } //===//
15161
15162
15163              state.offset += hold & (1 << state.extra) - 1
15164              /*BITS(state.extra)*/
15165              ; //--- DROPBITS(state.extra) ---//
15166
15167              hold >>>= state.extra;
15168              bits -= state.extra; //---//
15169
15170              state.back += state.extra;
15171            } //#ifdef INFLATE_STRICT
15172
15173
15174            if (state.offset > state.dmax) {
15175              strm.msg = 'invalid distance too far back';
15176              state.mode = BAD;
15177              break;
15178            } //#endif
15179            //Tracevv((stderr, "inflate:         distance %u\n", state.offset));
15180
15181
15182            state.mode = MATCH;
15183
15184          /* falls through */
15185
15186          case MATCH:
15187            if (left === 0) {
15188              break inf_leave;
15189            }
15190
15191            copy = _out - left;
15192
15193            if (state.offset > copy) {
15194              /* copy from window */
15195              copy = state.offset - copy;
15196
15197              if (copy > state.whave) {
15198                if (state.sane) {
15199                  strm.msg = 'invalid distance too far back';
15200                  state.mode = BAD;
15201                  break;
15202                } // (!) This block is disabled in zlib defaults,
15203                // don't enable it for binary compatibility
15204                //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
15205                //          Trace((stderr, "inflate.c too far\n"));
15206                //          copy -= state.whave;
15207                //          if (copy > state.length) { copy = state.length; }
15208                //          if (copy > left) { copy = left; }
15209                //          left -= copy;
15210                //          state.length -= copy;
15211                //          do {
15212                //            output[put++] = 0;
15213                //          } while (--copy);
15214                //          if (state.length === 0) { state.mode = LEN; }
15215                //          break;
15216                //#endif
15217
15218              }
15219
15220              if (copy > state.wnext) {
15221                copy -= state.wnext;
15222                from = state.wsize - copy;
15223              } else {
15224                from = state.wnext - copy;
15225              }
15226
15227              if (copy > state.length) {
15228                copy = state.length;
15229              }
15230
15231              from_source = state.window;
15232            } else {
15233              /* copy from output */
15234              from_source = output;
15235              from = put - state.offset;
15236              copy = state.length;
15237            }
15238
15239            if (copy > left) {
15240              copy = left;
15241            }
15242
15243            left -= copy;
15244            state.length -= copy;
15245
15246            do {
15247              output[put++] = from_source[from++];
15248            } while (--copy);
15249
15250            if (state.length === 0) {
15251              state.mode = LEN;
15252            }
15253
15254            break;
15255
15256          case LIT:
15257            if (left === 0) {
15258              break inf_leave;
15259            }
15260
15261            output[put++] = state.length;
15262            left--;
15263            state.mode = LEN;
15264            break;
15265
15266          case CHECK:
15267            if (state.wrap) {
15268              //=== NEEDBITS(32);
15269              while (bits < 32) {
15270                if (have === 0) {
15271                  break inf_leave;
15272                }
15273
15274                have--; // Use '|' instead of '+' to make sure that result is signed
15275
15276                hold |= input[next++] << bits;
15277                bits += 8;
15278              } //===//
15279
15280
15281              _out -= left;
15282              strm.total_out += _out;
15283              state.total += _out;
15284
15285              if (_out) {
15286                strm.adler = state.check =
15287                /*UPDATE(state.check, put - _out, _out);*/
15288                state.flags ? crc32_1(state.check, output, _out, put - _out) : adler32_1(state.check, output, _out, put - _out);
15289              }
15290
15291              _out = left; // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
15292
15293              if ((state.flags ? hold : zswap32(hold)) !== state.check) {
15294                strm.msg = 'incorrect data check';
15295                state.mode = BAD;
15296                break;
15297              } //=== INITBITS();
15298
15299
15300              hold = 0;
15301              bits = 0; //===//
15302              //Tracev((stderr, "inflate:   check matches trailer\n"));
15303            }
15304
15305            state.mode = LENGTH;
15306
15307          /* falls through */
15308
15309          case LENGTH:
15310            if (state.wrap && state.flags) {
15311              //=== NEEDBITS(32);
15312              while (bits < 32) {
15313                if (have === 0) {
15314                  break inf_leave;
15315                }
15316
15317                have--;
15318                hold += input[next++] << bits;
15319                bits += 8;
15320              } //===//
15321
15322
15323              if (hold !== (state.total & 0xffffffff)) {
15324                strm.msg = 'incorrect length check';
15325                state.mode = BAD;
15326                break;
15327              } //=== INITBITS();
15328
15329
15330              hold = 0;
15331              bits = 0; //===//
15332              //Tracev((stderr, "inflate:   length matches trailer\n"));
15333            }
15334
15335            state.mode = DONE;
15336
15337          /* falls through */
15338
15339          case DONE:
15340            ret = Z_STREAM_END$1;
15341            break inf_leave;
15342
15343          case BAD:
15344            ret = Z_DATA_ERROR$1;
15345            break inf_leave;
15346
15347          case MEM:
15348            return Z_MEM_ERROR$1;
15349
15350          case SYNC:
15351          /* falls through */
15352
15353          default:
15354            return Z_STREAM_ERROR$1;
15355        }
15356      } // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"
15357
15358      /*
15359         Return from inflate(), updating the total counts and the check value.
15360         If there was no progress during the inflate() call, return a buffer
15361         error.  Call updatewindow() to create and/or update the window state.
15362         Note: a memory error from inflate() is non-recoverable.
15363       */
15364      //--- RESTORE() ---
15365
15366
15367      strm.next_out = put;
15368      strm.avail_out = left;
15369      strm.next_in = next;
15370      strm.avail_in = have;
15371      state.hold = hold;
15372      state.bits = bits; //---
15373
15374      if (state.wsize || _out !== strm.avail_out && state.mode < BAD && (state.mode < CHECK || flush !== Z_FINISH$1)) {
15375        if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) ;
15376      }
15377
15378      _in -= strm.avail_in;
15379      _out -= strm.avail_out;
15380      strm.total_in += _in;
15381      strm.total_out += _out;
15382      state.total += _out;
15383
15384      if (state.wrap && _out) {
15385        strm.adler = state.check =
15386        /*UPDATE(state.check, strm.next_out - _out, _out);*/
15387        state.flags ? crc32_1(state.check, output, _out, strm.next_out - _out) : adler32_1(state.check, output, _out, strm.next_out - _out);
15388      }
15389
15390      strm.data_type = state.bits + (state.last ? 64 : 0) + (state.mode === TYPE ? 128 : 0) + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
15391
15392      if ((_in === 0 && _out === 0 || flush === Z_FINISH$1) && ret === Z_OK$1) {
15393        ret = Z_BUF_ERROR;
15394      }
15395
15396      return ret;
15397    };
15398
15399    const inflateEnd = strm => {
15400      if (!strm || !strm.state
15401      /*|| strm->zfree == (free_func)0*/
15402      ) {
15403        return Z_STREAM_ERROR$1;
15404      }
15405
15406      let state = strm.state;
15407
15408      if (state.window) {
15409        state.window = null;
15410      }
15411
15412      strm.state = null;
15413      return Z_OK$1;
15414    };
15415
15416    const inflateGetHeader = (strm, head) => {
15417      /* check state */
15418      if (!strm || !strm.state) {
15419        return Z_STREAM_ERROR$1;
15420      }
15421
15422      const state = strm.state;
15423
15424      if ((state.wrap & 2) === 0) {
15425        return Z_STREAM_ERROR$1;
15426      }
15427      /* save header structure */
15428
15429
15430      state.head = head;
15431      head.done = false;
15432      return Z_OK$1;
15433    };
15434
15435    const inflateSetDictionary = (strm, dictionary) => {
15436      const dictLength = dictionary.length;
15437      let state;
15438      let dictid;
15439      let ret;
15440      /* check state */
15441
15442      if (!strm
15443      /* == Z_NULL */
15444      || !strm.state
15445      /* == Z_NULL */
15446      ) {
15447        return Z_STREAM_ERROR$1;
15448      }
15449
15450      state = strm.state;
15451
15452      if (state.wrap !== 0 && state.mode !== DICT) {
15453        return Z_STREAM_ERROR$1;
15454      }
15455      /* check for correct dictionary identifier */
15456
15457
15458      if (state.mode === DICT) {
15459        dictid = 1;
15460        /* adler32(0, null, 0)*/
15461
15462        /* dictid = adler32(dictid, dictionary, dictLength); */
15463
15464        dictid = adler32_1(dictid, dictionary, dictLength, 0);
15465
15466        if (dictid !== state.check) {
15467          return Z_DATA_ERROR$1;
15468        }
15469      }
15470      /* copy dictionary to window using updatewindow(), which will amend the
15471       existing dictionary if appropriate */
15472
15473
15474      ret = updatewindow(strm, dictionary, dictLength, dictLength);
15475
15476      if (ret) {
15477        state.mode = MEM;
15478        return Z_MEM_ERROR$1;
15479      }
15480
15481      state.havedict = 1; // Tracev((stderr, "inflate:   dictionary set\n"));
15482
15483      return Z_OK$1;
15484    };
15485
15486    var inflateReset_1 = inflateReset;
15487    var inflateReset2_1 = inflateReset2;
15488    var inflateResetKeep_1 = inflateResetKeep;
15489    var inflateInit_1 = inflateInit;
15490    var inflateInit2_1 = inflateInit2;
15491    var inflate_2$1 = inflate$2;
15492    var inflateEnd_1 = inflateEnd;
15493    var inflateGetHeader_1 = inflateGetHeader;
15494    var inflateSetDictionary_1 = inflateSetDictionary;
15495    var inflateInfo = 'pako inflate (from Nodeca project)';
15496    /* Not implemented
15497    module.exports.inflateCopy = inflateCopy;
15498    module.exports.inflateGetDictionary = inflateGetDictionary;
15499    module.exports.inflateMark = inflateMark;
15500    module.exports.inflatePrime = inflatePrime;
15501    module.exports.inflateSync = inflateSync;
15502    module.exports.inflateSyncPoint = inflateSyncPoint;
15503    module.exports.inflateUndermine = inflateUndermine;
15504    */
15505
15506    var inflate_1$2 = {
15507      inflateReset: inflateReset_1,
15508      inflateReset2: inflateReset2_1,
15509      inflateResetKeep: inflateResetKeep_1,
15510      inflateInit: inflateInit_1,
15511      inflateInit2: inflateInit2_1,
15512      inflate: inflate_2$1,
15513      inflateEnd: inflateEnd_1,
15514      inflateGetHeader: inflateGetHeader_1,
15515      inflateSetDictionary: inflateSetDictionary_1,
15516      inflateInfo: inflateInfo
15517    }; // (C) 1995-2013 Jean-loup Gailly and Mark Adler
15518    // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
15519    //
15520    // This software is provided 'as-is', without any express or implied
15521    // warranty. In no event will the authors be held liable for any damages
15522    // arising from the use of this software.
15523    //
15524    // Permission is granted to anyone to use this software for any purpose,
15525    // including commercial applications, and to alter it and redistribute it
15526    // freely, subject to the following restrictions:
15527    //
15528    // 1. The origin of this software must not be misrepresented; you must not
15529    //   claim that you wrote the original software. If you use this software
15530    //   in a product, an acknowledgment in the product documentation would be
15531    //   appreciated but is not required.
15532    // 2. Altered source versions must be plainly marked as such, and must not be
15533    //   misrepresented as being the original software.
15534    // 3. This notice may not be removed or altered from any source distribution.
15535
15536    function GZheader() {
15537      /* true if compressed data believed to be text */
15538      this.text = 0;
15539      /* modification time */
15540
15541      this.time = 0;
15542      /* extra flags (not used when writing a gzip file) */
15543
15544      this.xflags = 0;
15545      /* operating system */
15546
15547      this.os = 0;
15548      /* pointer to extra field or Z_NULL if none */
15549
15550      this.extra = null;
15551      /* extra field length (valid if extra != Z_NULL) */
15552
15553      this.extra_len = 0; // Actually, we don't need it in JS,
15554      // but leave for few code modifications
15555      //
15556      // Setup limits is not necessary because in js we should not preallocate memory
15557      // for inflate use constant limit in 65536 bytes
15558      //
15559
15560      /* space at extra (only when reading header) */
15561      // this.extra_max  = 0;
15562
15563      /* pointer to zero-terminated file name or Z_NULL */
15564
15565      this.name = '';
15566      /* space at name (only when reading header) */
15567      // this.name_max   = 0;
15568
15569      /* pointer to zero-terminated comment or Z_NULL */
15570
15571      this.comment = '';
15572      /* space at comment (only when reading header) */
15573      // this.comm_max   = 0;
15574
15575      /* true if there was or will be a header crc */
15576
15577      this.hcrc = 0;
15578      /* true when done reading gzip header (not used when writing a gzip f
vendor: 11,051 bytes, lines 15578-15921
15578ile) */
15579
15580      this.done = false;
15581    }
15582
15583    var gzheader = GZheader;
15584    const toString$2 = Object.prototype.toString;
15585    /* Public constants ==========================================================*/
15586
15587    /* ===========================================================================*/
15588
15589    const {
15590      Z_NO_FLUSH,
15591      Z_FINISH,
15592      Z_OK,
15593      Z_STREAM_END,
15594      Z_NEED_DICT,
15595      Z_STREAM_ERROR,
15596      Z_DATA_ERROR,
15597      Z_MEM_ERROR
15598    } = constants$2;
15599    /* ===========================================================================*/
15600
15601    /**
15602     * class Inflate
15603     *
15604     * Generic JS-style wrapper for zlib calls. If you don't need
15605     * streaming behaviour - use more simple functions: [[inflate]]
15606     * and [[inflateRaw]].
15607     **/
15608
15609    /* internal
15610     * inflate.chunks -> Array
15611     *
15612     * Chunks of output data, if [[Inflate#onData]] not overridden.
15613     **/
15614
15615    /**
15616     * Inflate.result -> Uint8Array|String
15617     *
15618     * Uncompressed result, generated by default [[Inflate#onData]]
15619     * and [[Inflate#onEnd]] handlers. Filled after you push last chunk
15620     * (call [[Inflate#push]] with `Z_FINISH` / `true` param).
15621     **/
15622
15623    /**
15624     * Inflate.err -> Number
15625     *
15626     * Error code after inflate finished. 0 (Z_OK) on success.
15627     * Should be checked if broken data possible.
15628     **/
15629
15630    /**
15631     * Inflate.msg -> String
15632     *
15633     * Error message, if [[Inflate.err]] != 0
15634     **/
15635
15636    /**
15637     * new Inflate(options)
15638     * - options (Object): zlib inflate options.
15639     *
15640     * Creates new inflator instance with specified params. Throws exception
15641     * on bad params. Supported options:
15642     *
15643     * - `windowBits`
15644     * - `dictionary`
15645     *
15646     * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
15647     * for more information on these.
15648     *
15649     * Additional options, for internal needs:
15650     *
15651     * - `chunkSize` - size of generated data chunks (16K by default)
15652     * - `raw` (Boolean) - do raw inflate
15653     * - `to` (String) - if equal to 'string', then result will be converted
15654     *   from utf8 to utf16 (javascript) string. When string output requested,
15655     *   chunk length can differ from `chunkSize`, depending on content.
15656     *
15657     * By default, when no options set, autodetect deflate/gzip data format via
15658     * wrapper header.
15659     *
15660     * ##### Example:
15661     *
15662     * ```javascript
15663     * const pako = require('pako')
15664     * const chunk1 = new Uint8Array([1,2,3,4,5,6,7,8,9])
15665     * const chunk2 = new Uint8Array([10,11,12,13,14,15,16,17,18,19]);
15666     *
15667     * const inflate = new pako.Inflate({ level: 3});
15668     *
15669     * inflate.push(chunk1, false);
15670     * inflate.push(chunk2, true);  // true -> last chunk
15671     *
15672     * if (inflate.err) { throw new Error(inflate.err); }
15673     *
15674     * console.log(inflate.result);
15675     * ```
15676     **/
15677
15678    function Inflate$1(options) {
15679      this.options = common.assign({
15680        chunkSize: 1024 * 64,
15681        windowBits: 15,
15682        to: ''
15683      }, options || {});
15684      const opt = this.options; // Force window size for `raw` data, if not set directly,
15685      // because we have no header for autodetect.
15686
15687      if (opt.raw && opt.windowBits >= 0 && opt.windowBits < 16) {
15688        opt.windowBits = -opt.windowBits;
15689
15690        if (opt.windowBits === 0) {
15691          opt.windowBits = -15;
15692        }
15693      } // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
15694
15695
15696      if (opt.windowBits >= 0 && opt.windowBits < 16 && !(options && options.windowBits)) {
15697        opt.windowBits += 32;
15698      } // Gzip header has no info about windows size, we can do autodetect only
15699      // for deflate. So, if window size not set, force it to max when gzip possible
15700
15701
15702      if (opt.windowBits > 15 && opt.windowBits < 48) {
15703        // bit 3 (16) -> gzipped data
15704        // bit 4 (32) -> autodetect gzip/deflate
15705        if ((opt.windowBits & 15) === 0) {
15706          opt.windowBits |= 15;
15707        }
15708      }
15709
15710      this.err = 0; // error code, if happens (0 = Z_OK)
15711
15712      this.msg = ''; // error message
15713
15714      this.ended = false; // used to avoid multiple onEnd() calls
15715
15716      this.chunks = []; // chunks of compressed data
15717
15718      this.strm = new zstream();
15719      this.strm.avail_out = 0;
15720      let status = inflate_1$2.inflateInit2(this.strm, opt.windowBits);
15721
15722      if (status !== Z_OK) {
15723        throw new Error(messages[status]);
15724      }
15725
15726      this.header = new gzheader();
15727      inflate_1$2.inflateGetHeader(this.strm, this.header); // Setup dictionary
15728
15729      if (opt.dictionary) {
15730        // Convert data if needed
15731        if (typeof opt.dictionary === 'string') {
15732          opt.dictionary = strings.string2buf(opt.dictionary);
15733        } else if (toString$2.call(opt.dictionary) === '[object ArrayBuffer]') {
15734          opt.dictionary = new Uint8Array(opt.dictionary);
15735        }
15736
15737        if (opt.raw) {
15738          //In raw mode we need to set the dictionary early
15739          status = inflate_1$2.inflateSetDictionary(this.strm, opt.dictionary);
15740
15741          if (status !== Z_OK) {
15742            throw new Error(messages[status]);
15743          }
15744        }
15745      }
15746    }
15747    /**
15748     * Inflate#push(data[, flush_mode]) -> Boolean
15749     * - data (Uint8Array|ArrayBuffer): input data
15750     * - flush_mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE
15751     *   flush modes. See constants. Skipped or `false` means Z_NO_FLUSH,
15752     *   `true` means Z_FINISH.
15753     *
15754     * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with
15755     * new output chunks. Returns `true` on success. If end of stream detected,
15756     * [[Inflate#onEnd]] will be called.
15757     *
15758     * `flush_mode` is not needed for normal operation, because end of stream
15759     * detected automatically. You may try to use it for advanced things, but
15760     * this functionality was not tested.
15761     *
15762     * On fail call [[Inflate#onEnd]] with error code and return false.
15763     *
15764     * ##### Example
15765     *
15766     * ```javascript
15767     * push(chunk, false); // push one of data chunks
15768     * ...
15769     * push(chunk, true);  // push last chunk
15770     * ```
15771     **/
15772
15773
15774    Inflate$1.prototype.push = function (data, flush_mode) {
15775      const strm = this.strm;
15776      const chunkSize = this.options.chunkSize;
15777      const dictionary = this.options.dictionary;
15778
15779      let status, _flush_mode, last_avail_out;
15780
15781      if (this.ended) return false;
15782      if (flush_mode === ~~flush_mode) _flush_mode = flush_mode;else _flush_mode = flush_mode === true ? Z_FINISH : Z_NO_FLUSH; // Convert data if needed
15783
15784      if (toString$2.call(data) === '[object ArrayBuffer]') {
15785        strm.input = new Uint8Array(data);
15786      } else {
15787        strm.input = data;
15788      }
15789
15790      strm.next_in = 0;
15791      strm.avail_in = strm.input.length;
15792
15793      for (;;) {
15794        if (strm.avail_out === 0) {
15795          strm.output = new Uint8Array(chunkSize);
15796          strm.next_out = 0;
15797          strm.avail_out = chunkSize;
15798        }
15799
15800        status = inflate_1$2.inflate(strm, _flush_mode);
15801
15802        if (status === Z_NEED_DICT && dictionary) {
15803          status = inflate_1$2.inflateSetDictionary(strm, dictionary);
15804
15805          if (status === Z_OK) {
15806            status = inflate_1$2.inflate(strm, _flush_mode);
15807          } else if (status === Z_DATA_ERROR) {
15808            // Replace code with more verbose
15809            status = Z_NEED_DICT;
15810          }
15811        } // Skip snyc markers if more data follows and not raw mode
15812
15813
15814        while (strm.avail_in > 0 && status === Z_STREAM_END && strm.state.wrap > 0 && data[strm.next_in] !== 0) {
15815          inflate_1$2.inflateReset(strm);
15816          status = inflate_1$2.inflate(strm, _flush_mode);
15817        }
15818
15819        switch (status) {
15820          case Z_STREAM_ERROR:
15821          case Z_DATA_ERROR:
15822          case Z_NEED_DICT:
15823          case Z_MEM_ERROR:
15824            this.onEnd(status);
15825            this.ended = true;
15826            return false;
15827        } // Remember real `avail_out` value, because we may patch out buffer content
15828        // to align utf8 strings boundaries.
15829
15830
15831        last_avail_out = strm.avail_out;
15832
15833        if (strm.next_out) {
15834          if (strm.avail_out === 0 || status === Z_STREAM_END) {
15835            if (this.options.to === 'string') {
15836              let next_out_utf8 = strings.utf8border(strm.output, strm.next_out);
15837              let tail = strm.next_out - next_out_utf8;
15838              let utf8str = strings.buf2string(strm.output, next_out_utf8); // move tail & realign counters
15839
15840              strm.next_out = tail;
15841              strm.avail_out = chunkSize - tail;
15842              if (tail) strm.output.set(strm.output.subarray(next_out_utf8, next_out_utf8 + tail), 0);
15843              this.onData(utf8str);
15844            } else {
15845              this.onData(strm.output.length === strm.next_out ? strm.output : strm.output.subarray(0, strm.next_out));
15846            }
15847          }
15848        } // Must repeat iteration if out buffer is full
15849
15850
15851        if (status === Z_OK && last_avail_out === 0) continue; // Finalize if end of stream reached.
15852
15853        if (status === Z_STREAM_END) {
15854          status = inflate_1$2.inflateEnd(this.strm);
15855          this.onEnd(status);
15856          this.ended = true;
15857          return true;
15858        }
15859
15860        if (strm.avail_in === 0) break;
15861      }
15862
15863      return true;
15864    };
15865    /**
15866     * Inflate#onData(chunk) -> Void
15867     * - chunk (Uint8Array|String): output data. When string output requested,
15868     *   each chunk will be string.
15869     *
15870     * By default, stores data blocks in `chunks[]` property and glue
15871     * those in `onEnd`. Override this handler, if you need another behaviour.
15872     **/
15873
15874
15875    Inflate$1.prototype.onData = function (chunk) {
15876      this.chunks.push(chunk);
15877    };
15878    /**
15879     * Inflate#onEnd(status) -> Void
15880     * - status (Number): inflate status. 0 (Z_OK) on success,
15881     *   other if not.
15882     *
15883     * Called either after you tell inflate that the input stream is
15884     * complete (Z_FINISH). By default - join collected chunks,
15885     * free memory and fill `results` / `err` properties.
15886     **/
15887
15888
15889    Inflate$1.prototype.onEnd = function (status) {
15890      // On success - join
15891      if (status === Z_OK) {
15892        if (this.options.to === 'string') {
15893          this.result = this.chunks.join('');
15894        } else {
15895          this.result = common.flattenChunks(this.chunks);
15896        }
15897      }
15898
15899      this.chunks = [];
15900      this.err = status;
15901      this.msg = this.strm.msg;
15902    };
15903    /**
15904     * inflate(data[, options]) -> Uint8Array|String
15905     * - data (Uint8Array): input data to decompress.
15906     * - options (Object): zlib inflate options.
15907     *
15908     * Decompress `data` with inflate/ungzip and `options`. Autodetect
15909     * format via wrapper header by default. That's why we don't provide
15910     * separate `ungzip` method.
15911     *
15912     * Supported options are:
15913     *
15914     * - windowBits
15915     *
15916     * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
15917     * for more information.
15918     *
15919     * Sugar (options):
15920     *
15921     * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to 
15921specify
15922     *   negative windowBits implicitly.
15923     * - `to` (String) - if equal to 'string', then result will be converted
15924     *   from utf8 to utf16 (javascript) string. When string output requested,
15925     *   chunk length can differ from `chunkSize`, depending on content.
15926     *
15927     *
15928     * ##### Example:
15929     *
15930     * ```javascript
15931     * const pako = require('pako');
15932     * const input = pako.deflate(new Uint8Array([1,2,3,4,5,6,7,8,9]));
15933     * let output;
15934     *
15935     * try {
15936     *   output = pako.inflate(input);
15937     * } catch (err) {
15938     *   console.log(err);
15939     * }
15940     * ```
15941     **/
15942
15943
15944    function inflate$1(input, options) {
15945      const inflator = new Inflate$1(options);
15946      inflator.push(input); // That will never happens, if you don't cheat with options :)
15947
15948      if (inflator.err) throw inflator.msg || messages[inflator.err];
15949      return inflator.result;
15950    }
15951    /**
15952     * inflateRaw(data[, options]) -> Uint8Array|String
15953     * - data (Uint8Array): input data to decompress.
15954     * - options (Object): zlib inflate options.
15955     *
15956     * The same as [[inflate]], but creates raw data, without wrapper
15957     * (header and adler32 crc).
15958     **/
15959
15960
15961    function inflateRaw$1(input, options) {
15962      options = options || {};
15963      options.raw = true;
15964      return inflate$1(input, options);
15965    }
15966    /**
15967     * ungzip(data[, options]) -> Uint8Array|String
15968     * - data (Uint8Array): input data to decompress.
15969     * - options (Object): zlib inflate options.
15970     *
15971     * Just shortcut to [[inflate]], because it autodetects format
15972     * by header.content. Done for convenience.
15973     **/
15974
15975
15976    var Inflate_1$1 = Inflate$1;
15977    var inflate_2 = inflate$1;
15978    var inflateRaw_1$1 = inflateRaw$1;
15979    var ungzip$1 = inflate$1;
15980    var constants = constants$2;
15981    var inflate_1$1 = {
15982      Inflate: Inflate_1$1,
15983      inflate: inflate_2,
15984      inflateRaw: inflateRaw_1$1,
15985      ungzip: ungzip$1,
15986      constants: constants
15987    };
15988    const {
15989      Deflate,
15990      deflate,
15991      deflateRaw,
15992      gzip
15993    } = deflate_1$1;
15994    const {
15995      Inflate,
15996      inflate: inflate$3,
15997      inflateRaw,
15998      ungzip: ungzip$2
15999    } = inflate_1$1;
16000    var Deflate_1 = Deflate;
16001    var deflate_1 = deflate;
16002    var deflateRaw_1 = deflateRaw;
16003    var gzip_1 = gzip;
16004    var Inflate_1 = Inflate;
16005    var inflate_1 = inflate$3;
16006    var inflateRaw_1 = inflateRaw;
16007    var ungzip_1 = ungzip$2;
16008    var constants_1 = constants$2;
16009    var pako = {
16010      Deflate: Deflate_1,
16011      deflate: deflate_1,
16012      deflateRaw: deflateRaw_1,
16013      gzip: gzip_1,
16014      Inflate: Inflate_1,
16015      inflate: inflate_1,
16016      inflateRaw: inflateRaw_1,
16017      ungzip: ungzip_1,
16018      constants: constants_1
16019    }; // Added by JTR
16020    // exports.Deflate = Deflate_1;
16021    // exports.Inflate = Inflate_1;
16022    // exports.constants = constants_1;
16023    // exports['default'] = pako;
16024    // exports.deflate = deflate_1;
16025    // exports.deflateRaw = deflateRaw_1;
16026    // exports.gzip = gzip_1;
16027    // exports.inflate = inflate_1;
16028    // exports.inflateRaw = inflateRaw_1;
16029    // exports.ungzip = ungzip_1;
16030    //   Object.defineProperty(exports, '__esModule', { value: true });
16031    //
16032    // })));
16033
16034    pako.deflateRaw;
16035    pako.deflate;
16036    pako.inflateRaw;
16037    const inflate = pako.inflate;
16038    pako.gzip;
16039    const FEXTRA = 4; // gzip spec F.EXTRA flag
16040
16041    function isgzipped(data) {
16042      const b = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
16043      return b[0] === 31 && b[1] === 139;
16044    }
16045    /**
16046     * Pako does not properly ungzip block compressed files if > 1 block is present.  Test for bgzip and use wrapper.
16047     */
16048
16049
16050    function ungzip(data) {
16051      const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
16052      const b = ba[3] & FEXTRA;
16053
16054      if (b !== 0 && ba[12] === 66 && ba[13] === 67) {
16055        return unbgzf(ba.buffer);
16056      } else {
16057        return pako.ungzip(ba);
16058      }
16059    } // Uncompress data,  assumed to be series of bgzipped blocks
16060
16061
16062    function unbgzf(data, lim) {
16063      const oBlockList = [];
16064      let ptr = 0;
16065      let totalSize = 0;
16066      lim = lim || data.byteLength - 18;
16067
16068      while (ptr < lim) {
16069        try {
16070          const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data, ptr, 
1607018);
16071          const xlen = ba[11] << 8 | ba[10];
16072          const flg = ba[3];
16073          const fextra = flg & FEXTRA;
16074          const si1 = ba[12];
16075          const si2 = ba[13];
16076          const slen = ba[15] << 8 | ba[14];
16077          const bsize = (ba[17] << 8 | ba[16]) + 1;
16078          const start = 12 + xlen + ptr; // Start of CDATA
16079
16080          const bytesLeft = data.byteLength - start;
16081          const cDataSize = bsize - xlen - 19;
16082          if (bytesLeft < cDataSize || cDataSize <= 0) break;
16083          const a = new Uint8Array(data, start, cDataSize);
16084          const unc = pako.inflateRaw(a); // const inflate = new Zlib.RawInflate(a);
16085          // const unc = inflate.decompress();
16086
16087          ptr += cDataSize - 1 + 26; //inflate.ip + 26
16088
16089          totalSize += unc.byteLength;
16090          oBlockList.push(unc);
16091        } catch (e) {
16092          console.error(e);
16093          break;
16094        }
16095      } // Concatenate decompressed blocks
16096
16097
16098      if (oBlockList.length === 1) {
16099        return oBlockList[0];
16100      } else {
16101        const out = new Uint8Array(totalSize);
16102        let cursor = 0;
16103
16104        for (let i = 0; i < oBlockList.length; ++i) {
16105          var b = new Uint8Array(oBlockList[i]);
16106          arrayCopy(b, 0, out, cursor, b.length);
16107          cursor += b.length;
16108        }
16109
16110        return out;
16111      }
16112    }
16113
16114    function bgzBlockSize(data) {
16115      const ba = ArrayBuffer.isView(data) ? data : new Uint8Array(data);
16116      const bsize = (ba[17] << 8 | ba[16]) + 1;
16117      return bsize;
16118    } // From Thomas Down's zlib implementation
16119
16120
16121    const testArray = new Uint8Array(1);
16122    const hasSubarray = typeof testArray.subarray === 'function';
16123    /* (typeof testArray.slice === 'function'); */
16124    // Chrome slice performance is so dire that we're currently not using it...
16125
16126    function arrayCopy(src, srcOffset, dest, destOffset, count) {
16127      if (count === 0) {
16128        return;
16129      }
16130
16131      if (!src) {
16132        throw "Undef src";
16133      } else if (!dest) {
16134        throw "Undef dest";
16135      }
16136
16137      if (srcOffset === 0 && count === src.length) {
16138        arrayCopy_fast(src, dest, destOffset);
16139      } else if (hasSubarray) {
16140        arrayCopy_fast(src.subarray(srcOffset, srcOffset + count), dest, destOffset);
16141      } else if (src.BYTES_PER_ELEMENT === 1 && count > 100) {
16142        arrayCopy_fast(new Uint8Array(src.buffer, src.byteOffset + srcOffset, count), dest, destOffset);
16143      } else {
16144        arrayCopy_slow(src, srcOffset, dest, destOffset, count);
16145      }
16146    }
16147
16148    function arrayCopy_slow(src, srcOffset, dest, destOffset, count) {
16149      for (let i = 0; i < count; ++i) {
16150        dest[destOffset + i] = src[srcOffset + i];
16151      }
16152    }
16153
16154    function arrayCopy_fast(src, dest, destOffset) {
16155      dest.set(src, destOffset);
16156    }
16157    /**
16158     * Compress string and encode in a url safe form
16159     * @param s
16160     */
16161
16162
16163    function compressString(str) {
16164      const bytes = new Uint8Array(str.length);
16165
16166      for (var i = 0; i < str.length; i++) {
16167        bytes[i] = str.charCodeAt(i);
16168      }
16169
16170      const compressedBytes = new pako.deflateRaw(bytes); // UInt8Arry
16171
16172      const compressedString = String.fromCharCode.apply(null, compressedBytes); // Convert to string
16173
16174      let enc = btoa(compressedString);
16175      return enc.replace(/\+/g, '.').replace(/\//g, '_').replace(/=/g, '-'); // URL safe
16176    }
16177    /**
16178     * Uncompress the url-safe encoded compressed string, presumably created by compressString above
16179     *
16180     * @param enc
16181     * @returns {string}
16182     */
16183
16184
16185    function uncompressString(enc) {
16186      enc = enc.replace(/\./g, '+').replace(/_/g, '/').replace(/-/g, '=');
16187      const compressedString = atob(enc);
16188      const compressedBytes = [];
16189
16190      for (let i = 0; i < compressedString.length; i++) {
16191        compressedBytes.push(compressedString.charCodeAt(i));
16192      } //const bytes = new Zlib.RawInflate(compressedBytes).decompress();
16193
16194
16195      const bytes = pako.inflateRaw(compressedBytes);
16196      let str = '';
16197
16198      for (let b of bytes) {
16199        str += String.fromCharCode(b);
16200      }
16201
16202      return str;
16203    }
16204    /**
16205     * @param dataURI
16206     * @returns {Array<number>|Uint8Array}
16207     */
16208
16209
16210    function decodeDataURI$1(dataURI, gzip) {
16211      const split = dataURI.split(',');
16212      const info = split[0].split(':')[1];
16213      let dataString = split[1];
16214
16215      if (info.indexOf('base64') >= 0) {
16216        dataString = atob(dataString);
16217        const bytes = new Uint8Array(dataString.length);
16218
16219        for (let i = 0; i < dataString.length; i++) {
16220          bytes[i] = dataString.charCodeAt(i);
16221        }
16222
16223        let plain;
16224
16225        if (gzip || info.indexOf('gzip') > 0) {
16226          plain = pako.ungzip(bytes);
16227        } else {
16228          plain = bytes;
16229        }
16230
16231        return plain;
16232      } else {
16233        return decodeURIComponent(dataString); // URL encoded string -- not currently used or tested
16234      }
16235    }
16236
16237    /*
16238     * The MIT License (MIT)
16239     *
16240     * Copyright (c) 2016-2017 The Regents of the University of California
16241     * Author: Jim Robinson
16242     *
16243     * Permission is hereby granted, free of charge, to any person obtaining a copy
16244     * of this software and associated documentation files (the "Software"), to deal
16245     * in the Software without restriction, including without limitation the rights
16246     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16247     * copies of the Software, and to permit persons to whom the Software is
16248     * furnished to do so, subject to the following conditions:
16249     *
16250     * The above copyright notice and this permission notice shall be included in
16251     * all copies or substantial portions of the Software.
16252     *
16253     *
16254     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16255     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16256     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16257     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16258     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16259     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16260     * THE SOFTWARE.
16261     */
16262    const IGVMath = {
16263      lerp: (v0, v1, t) => {
16264        return (1 - t) * v0 + t * v1;
16265      },
16266      mean: function (array) {
16267        var t = 0,
16268            n = 0,
16269            i;
16270
16271        for (i = 0; i < array.length; i++) {
16272          if (!isNaN(array[i])) {
16273            t += array[i];
16274            n++;
16275          }
16276        }
16277
16278        return n > 0 ? t / n : 0;
16279      },
16280      meanAndStdev: function (array) {
16281        var v,
16282            t = 0,
16283            t2 = 0,
16284            n = 0,
16285            i;
16286
16287        for (i = 0; i < array.length; i++) {
16288          v = array[i];
16289
16290          if (!isNaN(v)) {
16291            t += v;
16292            t2 += v * v;
16293            n++;
16294          }
16295        }
16296
16297        return n > 0 ? {
16298          mean: t / n,
16299          stdev: Math.sqrt(t2 - t * t / n)
16300        } : {
16301          mean: 0,
16302          stdev: 0
16303        };
16304      },
16305      median: function (numbers) {
16306        // median of [3, 5, 4, 4, 1, 1, 2, 3] = 3
16307        var median = 0,
16308            numsLen = numbers.length;
16309        numbers.sort();
16310
16311        if (numsLen % 2 === 0 // is even
16312        ) {
16313          // average of two middle numbers
16314          median = (numbers[numsLen / 2 - 1] + numbers[numsLen / 2]) / 2;
16315        } else {
16316          // is odd
16317          // middle number only
16318          median = numbers[(numsLen - 1) / 2];
16319        }
16320
16321        return median;
16322      },
16323      // Fast percentile function for "p" near edges.  This needs profiled for p in middle (e.g. median)
16324      percentile: function (array, p) {
16325        if (array.length === 0) return undefined;
16326        var k = Math.floor(array.length * ((100 - p) / 100));
16327
16328        if (k === 0) {
16329          array.sort(function (a, b) {
16330            return b - a;
16331          });
16332          return array[k];
16333        } else {
16334          return selectElement(array, k);
16335        }
16336      },
16337      clamp: function (value, min, max) {
16338        return Math.min(Math.max(value, min), max);
16339      },
16340      log2: function (x) {
16341        return Math.log(x) / Math.LN2;
16342      }
16343    };
16344
16345    function selectElement(array, k) {
16346      // Credit Steve Hanov http://stevehanov.ca/blog/index.php?id=122
16347      var heap = new BinaryHeap(),
16348          i;
16349
16350      for (i = 0; i < array.length; i++) {
16351        var item = array[i]; // If we have not yet found k items, or the current item is larger than
16352        // the smallest item on the heap, add current item
16353
16354        if (heap.content.length < k || item > heap.content[0]) {
16355          // If the heap is full, remove the smallest element on the heap.
16356          if (heap.content.length === k) {
16357            heap.pop();
16358          }
16359
16360          heap.push(item);
16361        }
16362      }
16363
16364      return heap.content[0];
16365    }
16366
16367    function BinaryHeap() {
16368      this.content = [];
16369    }
16370
16371    BinaryHeap.prototype = {
16372      push: function (element) {
16373        // Add the new element to the end of the array.
16374        this.content.push(element); // Allow it to bubble up.
16375
16376        this.bubbleUp(this.content.length - 1);
16377      },
16378      pop: function () {
16379        // Store the first element so we can return it later.
16380        var result = this.content[0]; // Get the element at the end of the array.
16381
16382        var end = this.content.pop(); // If there are any elements left, put the end element at the
16383        // start, and let it sink down.
16384
16385        if (this.content.length > 0) {
16386          this.content[0] = end;
16387          this.sinkDown(0);
16388        }
16389
16390        return result;
16391      },
16392      remove: function (node) {
16393        var length = this.content.length; // To remove a value, we must search through the array to find
16394        // it.
16395
16396        for (var i = 0; i < length; i++) {
16397          if (this.content[i] !== node) continue; // When it is found, the process seen in 'pop' is repeated
16398          // to fill up the hole.
16399
16400          var end = this.content.pop(); // If the element we popped was the one we needed to remove,
16401          // we're done.
16402
16403          if (i === length - 1) break; // Otherwise, we replace the removed element with the popped
16404          // one, and allow it to float up or sink down as appropriate.
16405
16406          this.content[i] = end;
16407          this.bubbleUp(i);
16408          this.sinkDown(i);
16409          break;
16410        }
16411      },
16412      size: function () {
16413        return this.content.length;
16414      },
16415      bubbleUp: function (n) {
16416        // Fetch the element that has to be moved.
16417        var element = this.content[n],
16418            score = element; // When at 0, an element can not go up any further.
16419
16420        while (n > 0) {
16421          // Compute the parent element's index, and fetch it.
16422          var parentN = Math.floor((n + 1) / 2) - 1,
16423              parent = this.content[parentN]; // If the parent has a lesser score, things are in order and we
16424          // are done.
16425
16426          if (score >= parent) break; // Otherwise, swap the parent with the current element and
16427          // continue.
16428
16429          this.content[parentN] = element;
16430          this.content[n] = parent;
16431          n = parentN;
16432        }
16433      },
16434      sinkDown: function (n) {
16435        // Look up the target element and its score.
16436        var length = this.content.length,
16437            element = this.content[n],
16438            elemScore = element;
16439
16440        while (true) {
16441          // Compute the indices of the child elements.
16442          var child2N = (n + 1) * 2,
16443              child1N = child2N - 1; // This is used to store the new position of the element,
16444          // if any.
16445
16446          var swap = null; // If the first child exists (is inside the array)...
16447
16448          if (child1N < length) {
16449            // Look it up and compute its score.
16450            var child1 = this.content[child1N],
16451                child1Score = child1; // If the score is less than our element's, we need to swap.
16452
16453            if (child1Score < elemScore) swap = child1N;
16454          } // Do the same checks for the other child.
16455
16456
16457          if (child2N < length) {
16458            var child2 = this.content[child2N],
16459                child2Score = child2;
16460            if (child2Score < (swap == null ? elemScore : child1Score)) swap = child2N;
16461          } // No need to swap further, we are done.
16462
16463
16464          if (swap == null) break; // Otherwise, swap and continue.
16465
16466          this.content[n] = this.content[swap];
16467          this.content[swap] = element;
16468          n = swap;
16469        }
16470      }
16471    };
16472
16473    /*
16474     * The MIT License (MIT)
16475     *
16476     * Copyright (c) 2014 Broad Institute
16477     *
16478     * Permission is hereby granted, free of charge, to any person obtaining a copy
16479     * of this software and associated documentation files (the "Software"), to deal
16480     * in the Software without restriction, including without limitation the rights
16481     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16482     * copies of the Software, and to permit persons to whom the Software is
16483     * furnished to do so, subject to the following conditions:
16484     *
16485     * The above copyright notice and this permission notice shall be included in
16486     * all copies or substantial portions of the Software.
16487     *
16488     *
16489     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16490     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16491     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16492     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16493     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16494     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16495     * THE SOFTWARE.
16496     */
16497
16498    function _random(min, max) {
16499      return Math.random() * (max - min) + min;
16500    }
16501
16502    const IGVColor = {
16503      rgbListFromHSV: () => {
16504        let s = 1;
16505        let accumulation = [];
16506
16507        for (let v = 1; v >= 0.5; v -= .1) {
16508          for (let h = 0; h < 1; h += 1 / 28) {
16509            const r = "rgb(" + IGVColor.hsvToRgb(h, s, v).join(",") + ")";
16510            accumulation.push(r);
16511          }
16512        } // add black
16513
16514
16515        accumulation.pop();
16516        accumulation.push(IGVColor.rgbColor(16, 16, 16));
16517        return accumulation;
16518      },
16519      rgbToHex: function (rgb) {
16520        rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
16521        return rgb && rgb.length === 4 ? "#" + ("0" + parseInt(rgb[1], 10).toString(16)).slice(-2) + ("0" + parseInt(rgb[2], 10).toString(16)).slice(-2) + ("0" + parseInt(rgb[3], 10).toString(16)).slice(-2) : '';
16522      },
16523      hexToRgb: function (hex) {
16524        var cooked = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
16525
16526        if (null === cooked) {
16527          return undefined;
16528        }
16529
16530        return "rgb(" + parseInt(cooked[1], 16) + "," + parseInt(cooked[2], 16) + "," + parseInt(cooked[3], 16) + ")";
16531      },
16532
16533      /**
16534       * Converts an HSV color value to RGB. Conversion formula
16535       * adapted from http://en.wikipedia.org/wiki/HSV_color_space.
16536       * Assumes h, s, and v are contained in the set [0, 1] and
16537       * returns r, g, and b in the set [0, 255].
16538       *
16539       * Credit: https://gist.githubusercontent.com/mjackson/5311256
16540       *
16541       * @param   h       The hue
16542       * @param   s       The saturation
16543       * @param   v       The value
16544       * @return  Array   The RGB representation
16545       */
16546      hsvToRgb: function (h, s, v) {
16547        var r, g, b;
16548        var i = Math.floor(h * 6);
16549        var f = h * 6 - i;
16550        var p = v * (1 - s);
16551        var q = v * (1 - f * s);
16552        var t = v * (1 - (1 - f) * s);
16553
16554        switch (i % 6) {
16555          case 0:
16556            r = v, g = t, b = p;
16557            break;
16558
16559          case 1:
16560            r = q, g = v, b = p;
16561            break;
16562
16563          case 2:
16564            r = p, g = v, b = t;
16565            break;
16566
16567          case 3:
16568            r = p, g = q, b = v;
16569            break;
16570
16571          case 4:
16572            r = t, g = p, b = v;
16573            break;
16574
16575          case 5:
16576            r = v, g = p, b = q;
16577            break;
16578        }
16579
16580        return [Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)];
16581      },
16582
16583      /**
16584       * Converts an HSL color value to RGB. Conversion formula
16585       * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
16586       * Assumes h, s, and l are contained in the set [0, 1] and
16587       * returns r, g, and b in the set [0, 255].
16588       *
16589       * Credit: https://gist.githubusercontent.com/mjackson/5311256
16590       *
16591       * @param   h       The hue
16592       * @param   s       The saturation
16593       * @param   l       The lightness
16594       * @return  Array   The RGB representation
16595       */
16596      hslToRgb: function (h, s, l) {
16597        var r, g, b;
16598
16599        if (s === 0) {
16600          r = g = b = l; // achromatic
16601        } else {
16602          var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
16603          var p = 2 * l - q;
16604          r = IGVColor.hue2rgb(p, q, h + 1 / 3);
16605          g = IGVColor.hue2rgb(p, q, h);
16606          b = IGVColor.hue2rgb(p, q, h - 1 / 3);
16607        }
16608
16609        return [r * 255, g * 255, b * 255];
16610      },
16611      hue2rgb: (p, q, t) => {
16612        if (t < 0) t += 1;
16613        if (t > 1) t -= 1;
16614        if (t < 1 / 6) return p + (q - p) * 6 * t;
16615        if (t < 1 / 2) return q;
16616        if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
16617        return p;
16618      },
16619      rgbaColor: function (r, g, b, a) {
16620        r = IGVMath.clamp(r, 0, 255);
16621        g = IGVMath.clamp(g, 0, 255);
16622        b = IGVMath.clamp(b, 0, 255);
16623        a = IGVMath.clamp(a, 0.0, 1.0);
16624        return "rgba(" + r + "," + g + "," + b + "," + a + ")";
16625      },
16626      rgbColor: function (r, g, b) {
16627        r = IGVMath.clamp(r, 0, 255);
16628        g = IGVMath.clamp(g, 0, 255);
16629        b = IGVMath.clamp(b, 0, 255);
16630        return "rgb(" + r + "," + g + "," + b + ")";
16631      },
16632      greyScale: function (value) {
16633        var grey = IGVMath.clamp(value, 0, 255);
16634        return "rgb(" + grey + "," + grey + "," + grey + ")";
16635      },
16636      randomGrey: function (min, max) {
16637        min = IGVMath.clamp(min, 0, 255);
16638        max = IGVMath.clamp(max, 0, 255);
16639        var g = Math.round(_random(min, max)).toString(10);
16640        return "rgb(" + g + "," + g + "," + g + ")";
16641      },
16642      randomRGB: function (min, max) {
16643        min = IGVMath.clamp(min, 0, 255);
16644        max = IGVMath.clamp(max, 0, 255);
16645        var r = Math.round(_random(min, max)).toString(10);
16646        var g = Math.round(_random(min, max)).toString(10);
16647        var b = Math.round(_random(min, max)).toString(10);
16648        return "rgb(" + r + "," + g + "," + b + ")";
16649      },
16650      randomRGBConstantAlpha: function (min, max, alpha) {
16651        min = IGVMath.clamp(min, 0, 255);
16652        max = IGVMath.clamp(max, 0, 255);
16653        var r = Math.round(_random(min, max)).toString(10);
16654        var g = Math.round(_random(min, max)).toString(10);
16655        var b = Math.round(_random(min, max)).toString(10);
16656        return "rgba(" + r + "," + g + "," + b + "," + alpha + ")";
16657      },
16658      addAlpha: function (color, alpha) {
16659        if (color === "0" || color === ".") {
16660          color = "rgb(0,0,0)";
16661        } else {
16662          const c = this.colorNameToHex(color);
16663
16664          if (c) {
16665            color = c;
16666          }
16667        }
16668
16669        var isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color);
16670
16671        if (color.startsWith("rgba")) {
16672          const idx = color.lastIndexOf(",");
16673          return color.substring(0, idx + 1) + alpha.toString() + ")";
16674        }
16675
16676        if (isHex) {
16677          color = IGVColor.hexToRgb(color);
16678        }
16679
16680        if (color.startsWith("rgb")) {
16681          return color.replace("rgb", "rgba").replace(")", ", " + alpha + ")");
16682        } else {
16683          console.log(color + " is not an rgb style string");
16684          return color;
16685        }
16686      },
16687      rgbComponents: function (color) {
16688        if (color === "0" || color === ".") {
16689          return [0, 0, 0];
16690        }
16691
16692        const isHex = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color);
16693
16694        if (isHex) {
16695          color = IGVColor.hexToRgb(color);
16696        } else {
16697          if (!color.startsWith("rgb")) {
16698            const hex = this.colorNameToHex(color);
16699            color = this.hexToRgb(hex);
16700          }
16701        }
16702
16703        if (color.startsWith("rgb(")) {
16704          return color.substring(4, color.length - 1).split(",").map(s => Number.parseInt(s.trim()));
16705        } else if (color.startsWith("rgba(")) {
16706          return color.substring(5, color.length - 1).split(",").map((s, i) => {
16707            s = s.trim();
16708            return i === 3 ? Number.parseFloat(s) : Number.parseInt(s);
16709          });
16710        } else {
16711          throw Error("Unrecognized color string: color");
16712        }
16713      },
16714
16715      /**
16716       *
16717       * @param dest  RGB components as an array
16718       * @param src  RGB components as an array
16719       * @param alpha   alpha transparancy in the range 0-1
16720       * @returns {}
16721       */
16722      getCompositeColor: function (dest, src, alpha) {
16723        var r = Math.floor(alpha * src[0] + (1 - alpha) * dest[0]),
16724            g = Math.floor(alpha * src[1] + (1 - alpha) * dest[1]),
16725            b = Math.floor(alpha * src[2] + (1 - alpha) * dest[2]);
16726        return "rgb(" + r + "," + g + "," + b + ")";
16727      },
16728      createColorString: function (str) {
16729        // Excel will quote color strings, strip all quotes
16730        str = stripQuotes$1(str);
16731
16732        if (str.includes(",")) {
16733          return str.startsWith("rgb") ? str : "rgb(" + str + ")";
16734        } else {
16735          return str;
16736        }
16737      },
16738      darkenLighten: function (color, amt) {
16739        let src;
16740        let hexColor = this.colorNameToHex(color);
16741
16742        if (hexColor) {
16743          src = IGVColor.hexToRgb(hexColor);
16744        } else {
16745          src = color.startsWith('rgb(') ? color : IGVColor.hexToRgb(color);
16746        }
16747
16748        const components = src.replace(")", "").substring(4).split(",");
16749        const r = Math.max(0, Math.min(255, Number.parseInt(components[0].trim()) + amt));
16750        const g = Math.max(0, Math.min(255, Number.parseInt(components[1].trim()) + amt));
16751        const b = Math.max(0, Math.min(255, Number.parseInt(components[2].trim()) + amt));
16752        return 'rgb(' + r.toString() + ',' + g.toString() + ',' + b.toString() + ')';
16753      },
16754
16755      /**
16756       * Convert html/css color name to hex value.  Adapted from https://gist.github.com/mxfh/4719348
16757       * @param colorName
16758       * @returns {*}
16759       */
16760      colorNameToHex: function (colorName) {
16761        // color list from http://stackoverflow.com/q/1573053/731179  with added gray/gray
16762        const definedColorNames = {
16763          "aliceblue": "#f0f8ff",
16764          "antiquewhite": "#faebd7",
16765          "aqua": "#00ffff",
16766          "aquamarine": "#7fffd4",
16767          "azure": "#f0ffff",
16768          "beige": "#f5f5dc",
16769          "bisque": "#ffe4c4",
16770          "black": "#000000",
16771          "blanchedalmond": "#ffebcd",
16772          "blue": "#0000ff",
16773          "blueviolet": "#8a2be2",
16774          "brown": "#a52a2a",
16775          "burlywood": "#deb887",
16776          "cadetblue": "#5f9ea0",
16777          "chartreuse": "#7fff00",
16778          "chocolate": "#d2691e",
16779          "coral": "#ff7f50",
16780          "cornflowerblue": "#6495ed",
16781          "cornsilk": "#fff8dc",
16782          "crimson": "#dc143c",
16783          "cyan": "#00ffff",
16784          "darkblue": "#00008b",
16785          "darkcyan": "#008b8b",
16786          "darkgoldenrod": "#b8860b",
16787          "darkgray": "#a9a9a9",
16788          "darkgreen": "#006400",
16789          "darkkhaki": "#bdb76b",
16790          "darkmagenta": "#8b008b",
16791          "darkolivegreen": "#556b2f",
16792          "darkorange": "#ff8c00",
16793          "darkorchid": "#9932cc",
16794          "darkred": "#8b0000",
16795          "darksalmon": "#e9967a",
16796          "darkseagreen": "#8fbc8f",
16797          "darkslateblue": "#483d8b",
16798          "darkslategray": "#2f4f4f",
16799          "darkturquoise": "#00ced1",
16800          "darkviolet": "#9400d3",
16801          "deeppink": "#ff1493",
16802          "deepskyblue": "#00bfff",
16803          "dimgray": "#696969",
16804          "dodgerblue": "#1e90ff",
16805          "firebrick": "#b22222",
16806          "floralwhite": "#fffaf0",
16807          "forestgreen": "#228b22",
16808          "fuchsia": "#ff00ff",
16809          "gainsboro": "#dcdcdc",
16810          "ghostwhite": "#f8f8ff",
16811          "gold": "#ffd700",
16812          "goldenrod": "#daa520",
16813          "gray": "#808080",
16814          "green": "#008000",
16815          "greenyellow": "#adff2f",
16816          "honeydew": "#f0fff0",
16817          "hotpink": "#ff69b4",
16818          "indianred ": "#cd5c5c",
16819          "indigo ": "#4b0082",
16820          "ivory": "#fffff0",
16821          "khaki": "#f0e68c",
16822          "lavender": "#e6e6fa",
16823          "lavenderblush": "#fff0f5",
16824          "lawngreen": "#7cfc00",
16825          "lemonchiffon": "#fffacd",
16826          "lightblue": "#add8e6",
16827          "lightcoral": "#f08080",
16828          "lightcyan": "#e0ffff",
16829          "lightgoldenrodyellow": "#fafad2",
16830          "lightgrey": "#d3d3d3",
16831          "lightgreen": "#90ee90",
16832          "lightpink": "#ffb6c1",
16833          "lightsalmon": "#ffa07a",
16834          "lightseagreen": "#20b2aa",
16835          "lightskyblue": "#87cefa",
16836          "lightslategray": "#778899",
16837          "lightsteelblue": "#b0c4de",
16838          "lightyellow": "#ffffe0",
16839          "lime": "#00ff00",
16840          "limegreen": "#32cd32",
16841          "linen": "#faf0e6",
16842          "magenta": "#ff00ff",
16843          "maroon": "#800000",
16844          "mediumaquamarine": "#66cdaa",
16845          "mediumblue": "#0000cd",
16846          "mediumorchid": "#ba55d3",
16847          "mediumpurple": "#9370d8",
16848          "mediumseagreen": "#3cb371",
16849          "mediumslateblue": "#7b68ee",
16850          "mediumspringgreen": "#00fa9a",
16851          "mediumturquoise": "#48d1cc",
16852          "mediumvioletred": "#c71585",
16853          "midnightblue": "#191970",
16854          "mintcream": "#f5fffa",
16855          "mistyrose": "#ffe4e1",
16856          "moccasin": "#ffe4b5",
16857          "navajowhite": "#ffdead",
16858          "navy": "#000080",
16859          "oldlace": "#fdf5e6",
16860          "olive": "#808000",
16861          "olivedrab": "#6b8e23",
16862          "orange": "#ffa500",
16863          "orangered": "#ff4500",
16864          "orchid": "#da70d6",
16865          "palegoldenrod": "#eee8aa",
16866          "palegreen": "#98fb98",
16867          "paleturquoise": "#afeeee",
16868          "palevioletred": "#d87093",
16869          "papayawhip": "#ffefd5",
16870          "peachpuff": "#ffdab9",
16871          "peru": "#cd853f",
16872          "pink": "#ffc0cb",
16873          "plum": "#dda0dd",
16874          "powderblue": "#b0e0e6",
16875          "purple": "#800080",
16876          "red": "#ff0000",
16877          "rosybrown": "#bc8f8f",
16878          "royalblue": "#4169e1",
16879          "saddlebrown": "#8b4513",
16880          "salmon": "#fa8072",
16881          "sandybrown": "#f4a460",
16882          "seagreen": "#2e8b57",
16883          "seashell": "#fff5ee",
16884          "sienna": "#a0522d",
16885          "silver": "#c0c0c0",
16886          "skyblue": "#87ceeb",
16887          "slateblue": "#6a5acd",
16888          "slategray": "#708090",
16889          "snow": "#fffafa",
16890          "springgreen": "#00ff7f",
16891          "steelblue": "#4682b4",
16892          "tan": "#d2b48c",
16893          "teal": "#008080",
16894          "thistle": "#d8bfd8",
16895          "tomato": "#ff6347",
16896          "turquoise": "#40e0d0",
16897          "violet": "#ee82ee",
16898          "wheat": "#f5deb3",
16899          "white": "#ffffff",
16900          "whitesmoke": "#f5f5f5",
16901          "yellow": "#ffff00",
16902          "yellowgreen": "#9acd32",
16903          "darkgrey": "#a9a9a9",
16904          "darkslategrey": "#2f4f4f",
16905          "dimgrey": "#696969",
16906          "grey": "#808080",
16907          "lightgray": "#d3d3d3",
16908          "lightslategrey": "#778899",
16909          "slategrey": "#708090"
16910        };
16911        return definedColorNames[colorName];
16912      }
16913    };
16914
16915    /**
16916     * Make the target element movable by clicking and dragging on the handle.  This is not a general purprose function,
16917     * it makes several options specific to igv dialogs, the primary one being that the
16918     * target is absolutely positioned in pixel coordinates
16919
16920     */
16921    let dragData$1; // Its assumed we are only dragging one element at a time.
16922
16923    function makeDraggable$1(target, handle) {
16924      handle.addEventListener('mousedown', dragStart$1.bind(target));
16925    }
16926
16927    function dragStart$1(event) {
16928      event.stopPropagation();
16929      event.preventDefault();
16930      offset$1(this);
16931      const dragFunction = drag$1.bind(this);
16932      const dragEndFunction = dragEnd$1.bind(this);
16933      const computedStyle = getComputedStyle(this);
16934      const top = parseInt(computedStyle.top.replace("px", ""));
16935      const left = parseInt(computedStyle.left.replace("px", ""));
16936      dragData$1 = {
16937        dragFunction: dragFunction,
16938        dragEndFunction: dragEndFunction,
16939        screenX: event.screenX,
16940        screenY: event.screenY,
16941        top: top,
16942        left: left
16943      };
16944      document.addEventListener('mousemove', dragFunction);
16945      document.addEventListener('mouseup', dragEndFunction);
16946      document.addEventListener('mouseleave', dragEndFunction);
16947      document.addEventListener('mouseexit', dragEndFunction);
16948    }
16949
16950    function drag$1(event) {
16951      if (!dragData$1) {
16952        console.log("No drag data!");
16953        return;
16954      }
16955
16956      event.stopPropagation();
16957      event.preventDefault();
16958      const dx = event.screenX - dragData$1.screenX;
16959      const dy = event.screenY - dragData$1.screenY;
16960      this.style.left = `${dragData$1.left + dx}px`;
16961      this.style.top = `${dragData$1.top + dy}px`;
16962    }
16963
16964    function dragEnd$1(event) {
16965      if (!dragData$1) {
16966        console.log("No drag data!");
16967        return;
16968      }
16969
16970      event.stopPropagation();
16971      event.preventDefault();
16972      const dragFunction = dragData$1.dragFunction;
16973      const dragEndFunction = dragData$1.dragEndFunction;
16974      document.removeEventListener('mousemove', dragFunction);
16975      document.removeEventListener('mouseup', dragEndFunction);
16976      document.removeEventListener('mouseleave', dragEndFunction);
16977      document.removeEventListener('mouseexit', dragEndFunction);
16978      dragData$1 = undefined;
16979    }
16980
16981    const appleCrayonPalette$1 = {
16982      licorice: "#000000",
16983      lead: "#1e1e1e",
16984      tungsten: "#3a3a3a",
16985      iron: "#545453",
16986      steel: "#6e6e6e",
16987      tin: "#878687",
16988      nickel: "#888787",
16989      aluminum: "#a09fa0",
16990      magnesium: "#b8b8b8",
16991      silver: "#d0d0d0",
16992      mercury: "#e8e8e8",
16993      snow: "#ffffff",
16994      //
16995      cayenne: "#891100",
16996      mocha: "#894800",
16997      aspargus: "#888501",
16998      fern: "#458401",
16999      clover: "#028401",
17000      moss: "#018448",
17001      teal: "#008688",
17002      ocean: "#004a88",
17003      midnight: "#001888",
17004      eggplant: "#491a88",
17005      plum: "#891e88",
17006      maroon: "#891648",
17007      //
17008      maraschino: "#ff2101",
17009      tangerine: "#ff8802",
17010      lemon: "#fffa03",
17011      lime: "#83f902",
17012      spring: "#05f802",
17013      seam_foam: "#03f987",
17014      turquoise: "#00fdff",
17015      aqua: "#008cff",
17016      blueberry: "#002eff",
17017      grape: "#8931ff",
17018      magenta: "#ff39ff",
17019      strawberry: "#ff2987",
17020      //
17021      salmon: "#ff726e",
17022      cantaloupe: "#ffce6e",
17023      banana: "#fffb6d",
17024      honeydew: "#cefa6e",
17025      flora: "#68f96e",
17026      spindrift: "#68fbd0",
17027      ice: "#68fdff",
17028      sky: "#6acfff",
17029      orchid: "#6e76ff",
17030      lavender: "#d278ff",
17031      bubblegum: "#ff7aff",
17032      carnation: "#ff7fd3"
17033    };
17034
17035    // Support for oauth token based authorization
17036    // This class supports explicit setting of an oauth token either globally or for specific hosts.
17037    //
17038    // The variable oauth.google.access_token, which becomes igv.oauth.google.access_token on ES5 conversion is
17039    // supported for backward compatibility
17040    const DEFAULT_HOST = "googleapis";
17041    const oauth = {
17042      oauthTokens: {},
17043      setToken: function (token, host) {
17044        host = host || DEFAULT_HOST;
17045        this.oauthTokens[host] = token;
17046
17047        if (host === DEFAULT_HOST) {
17048          this.google.access_token = token; // legacy support
17049        }
17050      },
17051      getToken: function (host) {
17052        host = host || DEFAULT_HOST;
17053        let token;
17054
17055        for (let key of Object.keys(this.oauthTokens)) {
17056          const regex = wildcardToRegExp(key);
17057
17058          if (regex.test(host)) {
17059            token = this.oauthTokens[key];
17060            break;
17061          }
17062        }
17063
17064        return token;
17065      },
17066      removeToken: function (host) {
17067        host = host || DEFAULT_HOST;
17068
17069        for (let key of Object.keys(this.oauthTokens)) {
17070          const regex = wildcardToRegExp(key);
17071
17072          if (regex.test(host)) {
17073            this.oauthTokens[key] = undefined;
17074          }
17075        }
17076
17077        if (host === DEFAULT_HOST) {
17078          this.google.access_token = undefined; // legacy support
17079        }
17080      },
17081      // Special object for google -- legacy support
17082      google: {
17083        setToken: function (token) {
17084          oauth.setToken(token);
17085        }
17086      }
17087    };
17088    /**
17089     * Creates a RegExp from the given string, converting asterisks to .* expressions,
17090     * and escaping all other characters.
17091     *
17092     * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f
17093     */
17094
17095    function wildcardToRegExp(s) {
17096      return new RegExp('^' + s.split(/\*+/).map(regExpEscape).join('.*') + '$');
17097    }
17098    /**
17099     * RegExp-escapes all characters in the given string.
17100     *
17101     * credit https://gist.github.com/donmccurdy/6d073ce2c6f3951312dfa45da14a420f
17102     */
17103
17104
17105    function regExpEscape(s) {
17106      return s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
17107    }
17108
17109    // The MIT License (MIT)
17110    /**
17111     * @constructor
17112     * @param {Object} options A set op options to pass to the throttle function
17113     *        @param {number} requestsPerSecond The amount of requests per second
17114     *                                          the library will limit to
17115     */
17116
17117    class Throttle {
17118      constructor(options) {
17119        this.requestsPerSecond = options.requestsPerSecond || 10;
17120        this.lastStartTime = 0;
17121        this.queued = [];
17122      }
17123      /**
17124       * Adds a promise
17125       * @param {Function} async function to be executed
17126       * @param {Object} options A set of options.
17127       * @return {Promise} A promise
17128       */
17129
17130
17131      add(asyncFunction, options) {
17132        var self = this;
17133        return new Promise(function (resolve, reject) {
17134          self.queued.push({
17135            resolve: resolve,
17136            reject: reject,
17137            asyncFunction: asyncFunction
17138          });
17139          self.dequeue();
17140        });
17141      }
17142      /**
17143       * Adds all the promises passed as parameters
17144       * @param {Function} promises An array of functions that return a promise
17145       * @param {Object} options A set of options.
17146       * @param {number} options.signal An AbortSignal object that can be used to abort the returned promise
17147       * @param {number} options.weight A "weight" of each operation resolving by array of promises
17148       * @return {Promise} A promise that succeeds when all the promises passed as options do
17149       */
17150
17151
17152      addAll(promises, options) {
17153        var addedPromises = promises.map(function (promise) {
17154          return this.add(promise, options);
17155        }.bind(this));
17156        return Promise.all(addedPromises);
17157      }
17158
17159      /**
17160       * Dequeues a promise
17161       * @return {void}
17162       */
17163      dequeue() {
17164        if (this.queued.length > 0) {
17165          var now = new Date(),
17166              inc = 1000 / this.requestsPerSecond + 1,
17167              elapsed = now - this.lastStartTime;
17168
17169          if (elapsed >= inc) {
17170            this._execute();
17171          } else {
17172            // we have reached the limit, schedule a dequeue operation
17173            setTimeout(function () {
17174              this.dequeue();
17175            }.bind(this), inc - elapsed);
17176          }
17177        }
17178      }
17179      /**
17180       * Executes the promise
17181       * @private
17182       * @return {void}
17183       */
17184
17185
17186      async _execute() {
17187        this.lastStartTime = new Date();
17188        var candidate = this.queued.shift();
17189        const f = candidate.asyncFunction;
17190
17191        try {
17192          const r = await f();
17193          candidate.resolve(r);
17194        } catch (e) {
17195          candidate.reject(e);
17196        }
17197      }
17198
17199    }
17200
17201    /*
17202     * The MIT License (MIT)
17203     *
17204     * Copyright (c) 2014 Broad Institute
17205     *
17206     * Permission is hereby granted, free of charge, to any person obtaining a copy
17207     * of this software and associated documentation files (the "Software"), to deal
17208     * in the Software without restriction, including without limitation the rights
17209     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17210     * copies of the Software, and to permit persons to whom the Software is
17211     * furnished to do so, subject to the following conditions:
17212     *
17213     * The above copyright notice and this permission notice shall be included in
17214     * all copies or substantial portions of the Software.
17215     *
17216     *
17217     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17218     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17219     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17220     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17221     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17222     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17223     * THE SOFTWARE.
17224     */
17225    let RANGE_WARNING_GIVEN = false;
17226    const googleThrottle = new Throttle({
17227      requestsPerSecond: 8
17228    });
17229    const igvxhr = {
17230      apiKey: undefined,
17231      setApiKey: function (key) {
17232        this.apiKey = key;
17233      },
17234      load: load,
17235      loadArrayBuffer: async function (url, options) {
17236        options = options || {};
17237
17238        if (!options.responseType) {
17239          options.responseType = "arraybuffer";
17240        }
17241
17242        if (isFile(url)) {
17243          return loadFileSlice(url, options);
17244        } else {
17245          return load(url, options);
17246        }
17247      },
17248      loadJson: async function (url, options) {
17249        options = options || {};
17250        const method = options.method || (options.sendData ? "POST" : "GET");
17251
17252        if (method === "POST") {
17253          options.contentType = "application/json";
17254        }
17255
17256        const result = await this.loadString(url, options);
17257
17258        if (result) {
17259          return JSON.parse(result);
17260        } else {
17261          return result;
17262        }
17263      },
17264      loadString: async function (path, options) {
17265        options = options || {};
17266
17267        if (path instanceof File) {
17268          return loadStringFromFile(path, options);
17269        } else {
17270          return loadStringFromUrl(path, options);
17271        }
17272      }
17273    };
17274
17275    async function load(url, options) {
17276      options = options || {};
17277      const urlType = typeof url; // Resolve functions, promises, and functions that return promises
17278
17279      url = await (typeof url === 'function' ? url() : url);
17280
17281      if (isFile(url)) {
17282        return loadFileSlice(url, options);
17283      } else if (typeof url.startsWith === 'function') {
17284        // Test for string
17285        if (url.startsWith("data:")) {
17286          const buffer = decodeDataURI$1(url).buffer;
17287
17288          if (options.range) {
17289            const rangeEnd = options.range.size ? options.range.start + options.range.size : buffer.byteLength;
17290            return buffer.slice(options.range.start, rangeEnd);
17291          } else {
17292            return buffer;
17293          }
17294        } else {
17295          if (url.startsWith("https://drive.google.com")) {
17296            url = driveDownloadURL(url);
17297          }
17298
17299          if (isGoogleDriveURL(url) || url.startsWith("https://www.dropbox.com")) {
17300            return googleThrottle.add(async function () {
17301              return loadURL(url, options);
17302            });
17303          } else {
17304            return loadURL(url, options);
17305          }
17306        }
17307      } else {
17308        throw Error(`url must be either a 'File', 'string', 'function', or 'Promise'.  Actual type: ${urlType}`);
17309      }
17310    }
17311
17312    async function loadURL(url, options) {
17313      //console.log(`${Date.now()}   ${url}`)
17314      url = mapUrl(url);
17315      options = options || {};
17316      let oauthToken = options.oauthToken || getOauthToken(url);
17317
17318      if (oauthToken) {
17319        oauthToken = await (typeof oauthToken === 'function' ? oauthToken() : oauthToken);
17320      }
17321
17322      return new Promise(function (resolve, reject) {
17323        // Various Google tansformations
17324        if (isGoogleURL(url)) {
17325          if (isGoogleStorageURL(url)) {
17326            url = translateGoogleCloudURL(url);
17327          }
17328
17329          url = addApiKey(url);
17330
17331          if (isGoogleDriveURL(url)) {
17332            addTeamDrive(url);
17333          } // If we have an access token try it, but don't force a signIn or request for scopes yet
17334
17335
17336          if (!oauthToken) {
17337            oauthToken = getCurrentGoogleAccessToken();
17338          }
17339        }
17340
17341        const headers = options.headers || {};
17342
17343        if (oauthToken) {
17344          addOauthHeaders(headers, oauthToken);
17345        }
17346
17347        const range = options.range;
17348        const isChrome = navigator.userAgent.indexOf('Chrome') > -1;
17349        navigator.vendor.indexOf("Apple") === 0 && /\sSafari\//.test(navigator.userAgent);
17350
17351        if (range && isChrome && !isAmazonV4Signed(url)) {
17352          // Hack to prevent caching for byte-ranges. Attempt to fix net:err-cache errors in Chrome
17353          url += url.includes("?") ? "&" : "?";
17354          url += "someRandomSeed=" + Math.random().toString(36);
17355        }
17356
17357        const xhr = new XMLHttpRequest();
17358        const sendData = options.sendData || options.body;
17359        const method = options.method || (sendData ? "POST" : "GET");
17360        const responseType = options.responseType;
17361        const contentType = options.contentType;
17362        const mimeType = options.mimeType;
17363        xhr.open(method, url);
17364
17365        if (options.timeout) {
17366          xhr.timeout = options.timeout;
17367        }
17368
17369        if (range) {
17370          var rangeEnd = range.size ? range.start + range.size - 1 : "";
17371          xhr.setRequestHeader("Range", "bytes=" + range.start + "-" + rangeEnd);
17371 //      xhr.setRequestHeader("Cache-Control", "no-cache");    <= This can cause CORS issues, disabled for now
17372        }
17373
17374        if (contentType) {
17375          xhr.setRequestHeader("Content-Type", contentType);
17376        }
17377
17378        if (mimeType) {
17379          xhr.overrideMimeType(mimeType);
17380        }
17381
17382        if (responseType) {
17383          xhr.responseType = responseType;
17384        }
17385
17386        if (headers) {
17387          for (let key of Object.keys(headers)) {
17388            const value = headers[key];
17389            xhr.setRequestHeader(key, value);
17390          }
17391        } // NOTE: using withCredentials with servers that return "*" for access-allowed-origin will fail
17392
17393
17394        if (options.withCredentials === true) {
17395          xhr.withCredentials = true;
17396        }
17397
17398        xhr.onload = async function (event) {
17399          // when the url points to a local file, the status is 0 but that is not an error
17400          if (xhr.status === 0 || xhr.status >= 200 && xhr.status <= 300) {
17401            if (range && xhr.status !== 206 && range.start !== 0) {
17402              // For small files a range starting at 0 can return the whole file => 200
17403              // Provide just the slice we asked for, throw out the rest quietly
17404              // If file is large warn user
17405              if (xhr.response.length > 100000 && !RANGE_WARNING_GIVEN) {
17406                alert(`Warning: Range header ignored for URL: ${url}.  This can have performance impacts.`);
17407              }
17408
17409              resolve(xhr.response.slice(range.start, range.start + range.size));
17410            } else {
17411              resolve(xhr.response);
17412            }
17413          } else if (typeof gapi !== "undefined" && (xhr.status === 404 || xhr.status === 401 || xhr.status === 403) && isGoogleURL(url) && !options.retries) {
17414            tryGoogleAuth();
17415          } else {
17416            if (xhr.status === 403) {
17417              handleError("Access forbidden: " + url);
17418            } else if (xhr.status === 416) {
17419              //  Tried to read off the end of the file.   This shouldn't happen, but if it does return an
17420              handleError("Unsatisfiable range");
17421            } else {
17422              handleError(xhr.status);
17423            }
17424          }
17425        };
17426
17427        xhr.onerror = function (event) {
17428          if (isGoogleURL(url) && !options.retries) {
17429            tryGoogleAuth();
17430          }
17431
17432          handleError("Error accessing resource: " + url + " Status: " + xhr.status);
17433        };
17434
17435        xhr.ontimeout = function (event) {
17436          handleError("Timed out");
17437        };
17438
17439        xhr.onabort = function (event) {
17440          console.log("Aborted");
17441          reject(event);
17442        };
17443
17444        try {
17445          xhr.send(sendData);
17446        } catch (e) {
17447          reject(e);
17448        }
17449
17450        function handleError(error) {
17451          if (reject) {
17452            reject(error);
17453          } else {
17454            throw error;
17455          }
17456        }
17457
17458        async function tryGoogleAuth() {
17459          try {
17460            const accessToken = await fetchGoogleAccessToken(url);
17461            options.retries = 1;
17462            options.oauthToken = accessToken;
17463            const response = await load(url, options);
17464            resolve(response);
17465          } catch (e) {
17466            if (e.error) {
17467              const msg = e.error.startsWith("popup_blocked") ? "Google login popup blocked by browser." : e.error;
17468              alert(msg);
17469            } else {
17470              handleError(e);
17471            }
17472          }
17473        }
17474      });
17475    }
17476
17477    async function loadFileSlice(localfile, options) {
17478      let blob = options && options.range ? localfile.slice(options.range.start, options.range.start + options.range.size) : localfile;
17479
17480      if ("arraybuffer" === options.responseType) {
17481        return blobToArrayBuffer(blob);
17482      } else {
17483        // binary string format, shouldn't be used anymore
17484        return new Promise(function (resolve, reject) {
17485          const fileReader = new FileReader();
17486
17487          fileReader.onload = function (e) {
17488            resolve(fileReader.result);
17489          };
17490
17491          fileReader.onerror = function (e) {
17492            console.error("reject uploading local file " + localfile.name);
17493            reject(null, fileReader);
17494          };
17495
17496          fileReader.readAsBinaryString(blob);
17497          console.warn("Deprecated method used: readAsBinaryString");
17498        });
17499      }
17500    }
17501
17502    async function loadStringFromFile(localfile, options) {
17503      const blob = options.range ? localfile.slice(options.range.start, options.range.start + options.range.size) : localfile;
17504      const arrayBuffer = await blobToArrayBuffer(blob);
17505      return arrayBufferToString(arrayBuffer);
17506    }
17507
17508    async function blobToArrayBuffer(blob) {
17509      if (typeof blob.arrayBuffer === 'function') {
17510        return blob.arrayBuffer();
17511      }
17512
17513      return new Promise(function (resolve, reject) {
17514        const fileReader = new FileReader();
17515
17516        fileReader.onload = function (e) {
17517          resolve(fileReader.result);
17518        };
17519
17520        fileReader.onerror = function (e) {
17521          console.error("reject uploading local file " + localfile.name);
17522          reject(null, fileReader);
17523        };
17524
17525        fileReader.readAsArrayBuffer(blob);
17526      });
17527    }
17528
17529    async function loadStringFromUrl(url, options) {
17530      options = options || {};
17531      options.responseType = "arraybuffer";
17532      const data = await igvxhr.load(url, options);
17533      return arrayBufferToString(data);
17534    }
17535
17536    function isAmazonV4Signed(url) {
17537      return url.indexOf("X-Amz-Signature") > -1;
17538    }
17539
17540    function getOauthToken(url) {
17541      // Google is the default provider, don't try to parse host for google URLs
17542      const host = isGoogleURL(url) ? undefined : parseUri(url).host;
17543      let token = oauth.getToken(host);
17544
17545      if (token) {
17546        return token;
17547      } else if (host === undefined) {
17548        const googleToken = getCurrentGoogleAccessToken();
17549
17550        if (googleToken && googleToken.expires_at > Date.now()) {
17551          return googleToken.access_token;
17552        }
17553      }
17554    }
17555    /**
17556     * Return a Google oAuth token, triggering a sign in if required.   This method should not be called until we know
17557     * a token is required, that is until we've tried the url and received a 401, 403, or 404.
17558     *
17559     * @param url
17560     * @returns the oauth token
17561     */
17562
17563
17564    async function fetchGoogleAccessToken(url) {
17565      console.log("Fetch token for " + url);
17566
17567      if (isInitialized()) {
17568        const scope = getScopeForURL(url);
17569        const googleToken = await getAccessToken(scope);
17570        return googleToken ? googleToken.access_token : undefined;
17571      } else {
17572        throw Error(`Authorization is required, but Google oAuth has not been initalized. Contact your site administrator for assistance.`);
17573      }
17574    }
17575    /**
17576     * Return the current google access token, if one exists.  Do not triger signOn or request additional scopes.
17577     * @returns {undefined|access_token}
17578     */
17579
17580
17581    function getCurrentGoogleAccessToken() {
17582      if (isInitialized()) {
17583        const googleToken = getCurrentAccessToken();
17584        return googleToken ? googleToken.access_token : undefined;
17585      } else {
17586        return undefined;
17587      }
17588    }
17589
17590    function addOauthHeaders(headers, acToken) {
17591      if (acToken) {
17592        headers["Cache-Control"] = "no-cache";
17593        headers["Authorization"] = "Bearer " + acToken;
17594      }
17595
17596      return headers;
17597    }
17598
17599    function addApiKey(url) {
17600      let apiKey = igvxhr.apiKey;
17601
17602      if (!apiKey && typeof gapi !== "undefined") {
17603        apiKey = gapi.apiKey;
17604      }
17605
17606      if (apiKey !== undefined && !url.includes("key=")) {
17607        const paramSeparator = url.includes("?") ? "&" : "?";
17608        url = url + paramSeparator + "key=" + apiKey;
17609      }
17610
17611      return url;
17612    }
17613
17614    function addTeamDrive(url) {
17615      if (url.includes("supportsTeamDrive")) {
17616        return url;
17617      } else {
17618        const paramSeparator = url.includes("?") ? "&" : "?";
17619        url = url + paramSeparator + "supportsTeamDrive=true";
17620      }
17621    }
17622    /**
17623     * Perform some well-known url mappings.
17624     * @param url
17625     */
17626
17627
17628    function mapUrl(url) {
17629      if (url.includes("//www.dropbox.com")) {
17630        return url.replace("//www.dropbox.com", "//dl.dropboxusercontent.com");
17631      } else if (url.includes("//drive.google.com")) {
17632        return driveDownloadURL(url);
17633      } else if (url.includes("//www.broadinstitute.org/igvdata")) {
17634        return url.replace("//www.broadinstitute.org/igvdata", "//data.broadinstitute.org/igvdata");
17635      } else if (url.includes("//igvdata.broadinstitute.org")) {
17636        return url.replace("//igvdata.broadinstitute.org", "https://dn7ywbm9isq8j.cloudfront.net");
17637      } else if (url.startsWith("ftp://ftp.ncbi.nlm.nih.gov/geo")) {
17638        return url.replace("ftp://", "https://");
17639      } else {
17640        return url;
17641      }
17642    }
17643
17644    function arrayBufferToString(arraybuffer) {
17645      let plain;
17646
17647      if (isgzipped(arraybuffer)) {
17648        plain = ungzip(arraybuffer);
17649      } else {
17650        plain = new Uint8Array(arraybuffer);
17651      }
17652
17653      if ('TextDecoder' in getGlobalObject()) {
17654        return new TextDecoder().decode(plain);
17655      } else {
17656        return decodeUTF8(plain);
17657      }
17658    }
17659    /**
17660     * Use when TextDecoder is not available (primarily IE).
17661     *
17662     * From: https://gist.github.com/Yaffle/5458286
17663     *
17664     * @param octets
17665     * @returns {string}
17666     */
17667
17668
17669    function decodeUTF8(octets) {
17670      var string = "";
17671      var i = 0;
17672
17673      while (i < octets.length) {
17674        var octet = octets[i];
17675        var bytesNeeded = 0;
17676        var codePoint = 0;
17677
17678        if (octet <= 0x7F) {
17679          bytesNeeded = 0;
17680          codePoint = octet & 0xFF;
17681        } else if (octet <= 0xDF) {
17682          bytesNeeded = 1;
17683          codePoint = octet & 0x1F;
17684        } else if (octet <= 0xEF) {
17685          bytesNeeded = 2;
17686          codePoint = octet & 0x0F;
17687        } else if (octet <= 0xF4) {
17688          bytesNeeded = 3;
17689          codePoint = octet & 0x07;
17690        }
17691
17692        if (octets.length - i - bytesNeeded > 0) {
17693          var k = 0;
17694
17695          while (k < bytesNeeded) {
17696            octet = octets[i + k + 1];
17697            codePoint = codePoint << 6 | octet & 0x3F;
17698            k += 1;
17699          }
17700        } else {
17701          codePoint = 0xFFFD;
17702          bytesNeeded = octets.length - i;
17703        }
17704
17705        string += String.fromCodePoint(codePoint);
17706        i += bytesNeeded + 1;
17707      }
17708
17709      return string;
17710    }
17711
17712    function getGlobalObject() {
17713      if (typeof self !== 'undefined') {
17714        return self;
17715      }
17716
17717      if (typeof global !== 'undefined') {
17718        return global;
17719      } else {
17720        return window;
17721      }
17722    }
17723
17724    /*
17725     * The MIT License (MIT)
17726     *
17727     * Copyright (c) 2014 Broad Institute
17728     *
17729     * Permission is hereby granted, free of charge, to any person obtaining a copy
17730     * of this software and associated documentation files (the "Software"), to deal
17731     * in the Software without restriction, including without limitation the rights
17732     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17733     * copies of the Software, and to permit persons to whom the Software is
17734     * furnished to do so, subject to the following conditions:
17735     *
17736     * The above copyright notice and this permission notice shall be included in
17737     * all copies or substantial portions of the Software.
17738     *
17739     *
17740     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17741     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17742     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17743     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17744     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17745     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17746     * THE SOFTWARE.
17747     */
17748
17749    /** An implementation of an interval tree, following the explanation.
17750     * from CLR.
17751     *
17752     * Public interface:
17753     *   Constructor  IntervalTree
17754     *   Insertion    insert
17755     *   Search       findOverlapping
17756     */
17757    var BLACK = 1;
17758    var RED = 2;
17759    var NIL = {};
17760    NIL.color = BLACK;
17761    NIL.parent = NIL;
17762    NIL.left = NIL;
17763    NIL.right = NIL;
17764
17765    class IntervalTree {
17766      constructor() {
17767        this.root = NIL;
17768      }
17769
17770      insert(start, end, value) {
17771        var interval = new Interval(start, end, value);
17772        var x = new Node(interval);
17773        this.treeInsert(x);
17774        x.color = RED;
17775
17776        while (x !== this.root && x.parent.color === RED) {
17777          if (x.parent === x.parent.parent.left) {
17778            let y = x.parent.parent.right;
17779
17780            if (y.color === RED) {
17781              x.parent.color = BLACK;
17782              y.color = BLACK;
17783              x.parent.parent.color = RED;
17784              x = x.parent.parent;
17785            } else {
17786              if (x === x.parent.right) {
17787                x = x.parent;
17788                leftRotate.call(this, x);
17789              }
17790
17791              x.parent.color = BLACK;
17792              x.parent.parent.color = RED;
17793              rightRotate.call(this, x.parent.parent);
17794            }
17795          } else {
17796            let y = x.parent.parent.left;
17797
17798            if (y.color === RED) {
17799              x.parent.color = BLACK;
17800              y.color = BLACK;
17801              x.parent.parent.color = RED;
17802              x = x.parent.parent;
17803            } else {
17804              if (x === x.parent.left) {
17805                x = x.parent;
17806                rightRotate.call(this, x);
17807              }
17808
17809              x.parent.color = BLACK;
17810              x.parent.parent.color = RED;
17811              leftRotate.call(this, x.parent.parent);
17812            }
17813          }
17814        }
17815
17816        this.root.color = BLACK;
17817      }
17818      /**
17819       *
17820       * @param start - query interval
17821       * @param end - query interval
17822       * @returns Array of all intervals overlapping the query region
17823       */
17824
17825
17826      findOverlapping(start, end) {
17827        var searchInterval = new Interval(start, end, 0);
17828        if (this.root === NIL) return [];
17829        var intervals = searchAll.call(this, searchInterval, this.root, []);
17830
17831        if (intervals.length > 1) {
17832          intervals.sort(function (i1, i2) {
17833            return i1.low - i2.low;
17834          });
17835        }
17836
17837        return intervals;
17838      }
17839      /**
17840       * Dump info on intervals to console.  For debugging.
17841       */
17842
17843
17844      logIntervals() {
17845        logNode(this.root, 0);
17846
17847        function logNode(node, indent) {
17848          var space = "";
17849
17850          for (var i = 0; i < indent; i++) space += " ";
17851
17852          console.log(space + node.interval.low + " " + node.interval.high); // + " " + (node.interval.value ? node.interval.value : " null"));
17853
17854          indent += 5;
17855          if (node.left !== NIL) logNode(node.left, indent);
17856          if (node.right !== NIL) logNode(node.right, indent);
17857        }
17858      }
17859
17860      mapIntervals(func) {
17861        applyInterval(this.root);
17862
17863        function applyInterval(node) {
17864          func(node.interval);
17865          if (node.left !== NIL) applyInterval(node.left);
17866          if (node.right !== NIL) applyInterval(node.right);
17867        }
17868      }
17869      /**
17870       * Note:  Does not maintain RB constraints,  this is done post insert
17871       *
17872       * @param x  a Node
17873       */
17874
17875
17876      treeInsert(x) {
17877        var node = this.root;
17878        var y = NIL;
17879
17880        while (node !== NIL) {
17881          y = node;
17882
17883          if (x.interval.low <= node.interval.low) {
17884            node = node.left;
17885          } else {
17886            node = node.right;
17887          }
17888        }
17889
17890        x.parent = y;
17891
17892        if (y === NIL) {
17893          this.root = x;
17894          x.left = x.right = NIL;
17895        } else {
17896          if (x.interval.low <= y.interval.low) {
17897            y.left = x;
17898          } else {
17899            y.right = x;
17900          }
17901        }
17902
17903        applyUpdate.call(this, x);
17904      }
17905
17906    }
17907
17908    function searchAll(interval, node, results) {
17909      if (node.interval.overlaps(interval)) {
17910        results.push(node.interval);
17911      }
17912
17913      if (node.left !== NIL && node.left.max >= interval.low) {
17914        searchAll.call(this, interval, node.left, results);
17915      }
17916
17917      if (node.right !== NIL && node.right.min <= interval.high) {
17918        searchAll.call(this, interval, node.right, results);
17919      }
17920
17921      return results;
17922    }
17923
17924    function leftRotate(x) {
17925      var y = x.right;
17926      x.right = y.left;
17927
17928      if (y.left !== NIL) {
17929        y.left.parent = x;
17930      }
17931
17932      y.parent = x.parent;
17933
17934      if (x.parent === NIL) {
17935        this.root = y;
17936      } else {
17937        if (x.parent.left === x) {
17938          x.parent.left = y;
17939        } else {
17940          x.parent.right = y;
17941        }
17942      }
17943
17944      y.left = x;
17945      x.parent = y;
17946      applyUpdate.call(this, x); // no need to apply update on y, since it'll y is an ancestor
17947      // of x, and will be touched by applyUpdate().
17948    }
17949
17950    function rightRotate(x) {
17951      var y = x.left;
17952      x.left = y.right;
17953
17954      if (y.right !== NIL) {
17955        y.right.parent = x;
17956      }
17957
17958      y.parent = x.parent;
17959
17960      if (x.parent === NIL) {
17961        this.root = y;
17962      } else {
17963        if (x.parent.right === x) {
17964          x.parent.right = y;
17965        } else {
17966          x.parent.left = y;
17967        }
17968      }
17969
17970      y.right = x;
17971      x.parent = y;
17972      applyUpdate.call(this, x); // no need to apply update on y, since it'll y is an ancestor
17973      // of x, and will be touched by applyUpdate().
17974    } // Applies the statistic update on the node and its ancestors.
17975
17976
17977    function applyUpdate(node) {
17978      while (node !== NIL) {
17979        var nodeMax = node.left.max > node.right.max ? node.left.max : node.right.max;
17980        var intervalHigh = node.interval.high;
17981        node.max = nodeMax > intervalHigh ? nodeMax : intervalHigh;
17982        var nodeMin = node.left.min < node.right.min ? node.left.min : node.right.min;
17983        var intervalLow = node.interval.low;
17984        node.min = nodeMin < intervalLow ? nodeMin : intervalLow;
17985        node = node.parent;
17986      }
17987    }
17988
17989    class Interval {
17990      constructor(low, high, value) {
17991        this.low = low;
17992        this.high = high;
17993        this.value = value;
17994      }
17995
17996      equals(other) {
17997        if (!other) {
17998          return false;
17999        }
18000
18001        if (this === other) {
18002          return true;
18003        }
18004
18005        return this.low === other.low && this.high === other.high;
18006      }
18007
18008      compareTo(other) {
18009        if (this.low < other.low) return -1;
18010        if (this.low > other.low) return 1;
18011        if (this.high < other.high) return -1;
18012        if (this.high > other.high) return 1;
18013        return 0;
18014      }
18015      /**
18016       * Returns true if this interval overlaps the other.
18017       */
18018
18019
18020      overlaps(other) {
18021        return this.low <= other.high && other.low <= this.high;
18022      }
18023
18024    }
18025
18026    function Node(interval) {
18027      this.parent = NIL;
18028      this.left = NIL;
18029      this.right = NIL;
18030      this.interval = interval;
18031      this.color = RED;
18032    } //
18033
18034    /*
18035     * The MIT License (MIT)
18036     *
18037     * Copyright (c) 2014 Broad Institute
18038     *
18039     * Permission is hereby granted, free of charge, to any person obtaining a copy
18040     * of this software and associated documentation files (the "Software"), to deal
18041     * in the Software without restriction, including without limitation the rights
18042     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18043     * copies of the Software, and to permit persons to whom the Software is
18044     * furnished to do so, subject to the following conditions:
18045     *
18046     * The above copyright notice and this permission notice shall be included in
18047     * all copies or substantial portions of the Software.
18048     *
18049     *
18050     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18051     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18052     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18053     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18054     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18055     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18056     * THE SOFTWARE.
18057     */
18058    /**
18059     * Object for caching lists of features.  Supports effecient queries for sub-range  (chr, start, end)
18060     *
18061     * @param featureList
18062     * @param The genomic range spanned by featureList (optional)
18063     * @constructor
18064     */
18065
18066    class FeatureCache {
18067      constructor(featureList, genome, range) {
18068        featureList = featureList || [];
18069        this.treeMap = this.buildTreeMap(featureList, genome);
18070        this.range = range;
18071        this.count = featureList.length;
18072      }
18073
18074      containsRange(genomicRange) {
18075        // No range means cache contains all features
18076        return this.range === undefined || this.range.contains(genomicRange.chr, genomicRange.start, genomicRange.end);
18077      }
18078
18079      queryFeatures(chr, start, end) {
18080        const tree = this.treeMap[chr];
18081        if (!tree) return [];
18082        const intervals = tree.findOverlapping(start, end);
18083
18084        if (intervals.length === 0) {
18085          return [];
18086        } else {
18087          // Trim the list of features in the intervals to those
18088          // overlapping the requested range.
18089          // Assumption: features are sorted by start position
18090          const featureList = [];
18091          const all = this.allFeatures[chr];
18092
18093          if (all) {
18094            for (let interval of intervals) {
18095              const indexRange = interval.value;
18096
18097              for (let i = indexRange.start; i < indexRange.end; i++) {
18098                let feature = all[i];
18099                if (feature.start > end) break;else if (feature.end >= start) {
18100                  featureList.push(feature);
18101                }
18102              }
18103            }
18104
18105            featureList.sort(function (a, b) {
18106              return a.start - b.start;
18107            });
18108          }
18109
18110          return featureList;
18111        }
18112      }
18113
18114      /**
18115       * Returns all features, unsorted.
18116       *
18117       * @returns {Array}
18118       */
18119      getAllFeatures() {
18120        return this.allFeatures;
18121      }
18122
18123      buildTreeMap(featureList, genome) {
18124        const treeMap = {};
18125        const chromosomes = [];
18126        this.allFeatures = {};
18127
18128        if (featureList) {
18129          for (let feature of featureList) {
18130            let chr = feature.chr; // Translate to "official" name
18131
18132            if (genome) {
18133              chr = genome.getChromosomeName(chr);
18134            }
18135
18136            let geneList = this.allFeatures[chr];
18137
18138            if (!geneList) {
18139              chromosomes.push(chr);
18140              geneList = [];
18141              this.allFeatures[chr] = geneList;
18142            }
18143
18144            geneList.push(feature);
18145          } // Now build interval tree for each chromosome
18146
18147
18148          for (let chr of chromosomes) {
18149            const chrFeatures = this.allFeatures[chr];
18150            chrFeatures.sort(function (f1, f2) {
18151              return f1.start === f2.start ? 0 : f1.start > f2.start ? 1 : -1;
18152            });
18153            treeMap[chr] = buildIntervalTree$1(chrFeatures);
18154          }
18155        }
18156
18157        return treeMap;
18158      }
18159
18160    }
18161    /**
18162     * Build an interval tree from the feature list for fast interval based queries.   We lump features in groups
18163     * of 10, or total size / 100,   to reduce size of the tree.
18164     *
18165     * @param featureList
18166     */
18167
18168
18169    function buildIntervalTree$1(featureList) {
18170      const tree = new IntervalTree();
18171      const len = featureList.length;
18172      const chunkSize = Math.max(10, Math.round(len / 10));
18173
18174      for (let i = 0; i < len; i += chunkSize) {
18175        const e = Math.min(len, i + chunkSize);
18176        const subArray = new IndexRange(i, e); //featureList.slice(i, e);
18177
18178        const iStart = featureList[i].start; //
18179
18180        let iEnd = iStart;
18181
18182        for (let j = i; j < e; j++) {
18183          iEnd = Math.max(iEnd, featureList[j].end);
18184        }
18185
18186        tree.insert(iStart, iEnd, subArray);
18187      }
18188
18189      return tree;
18190    }
18191
18192    class IndexRange {
18193      constructor(start, end) {
18194        this.start = start;
18195        this.end = end;
18196      }
18197
18198    }
18199
18200    /*
18201     * The MIT License (MIT)
18202     *
18203     * Copyright (c) 2016-2017 The Regents of the University of California
18204     * Author: Jim Robinson
18205     *
18206     * Permission is hereby granted, free of charge, to any person obtaining a copy
18207     * of this software and associated documentation files (the "Software"), to deal
18208     * in the Software without restriction, including without limitation the rights
18209     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18210     * copies of the Software, and to permit persons to whom the Software is
18211     * furnished to do so, subject to the following conditions:
18212     *
18213     * The above copyright notice and this permission notice shall be included in
18214     * all copies or substantial portions of the Software.
18215     *
18216     *
18217     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18218     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18219     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18220     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18221     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18222     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18223     * THE SOFTWARE.
18224     */
18225    const FeatureUtils = {
18226      packFeatures: function (features, maxRows, sorted) {
18227        var start;
18228        var end;
18229        if (!features) return;
18230        maxRows = maxRows || 10000;
18231
18232        if (!sorted) {
18233          features.sort(function (a, b) {
18234            return a.start - b.start;
18235          });
18236        }
18237
18238        if (features.length === 0) {
18239          return [];
18240        } else {
18241          var bucketList = [],
18242              allocatedCount = 0,
18243              lastAllocatedCount = 0,
18244              nextStart,
18245              row,
18246              index,
18247              bucket,
18248              feature,
18249              gap = 2,
18250              bucketStart;
18251          start = features[0].start;
18252          end = features[features.length - 1].start;
18253          bucketStart = Math.max(start, features[0].start);
18254          nextStart = bucketStart;
18255          features.forEach(function (alignment) {
18256            var buckListIndex = Math.max(0, alignment.start - bucketStart);
18257
18258            if (bucketList[buckListIndex] === undefined) {
18259              bucketList[buckListIndex] = [];
18260            }
18261
18262            bucketList[buckListIndex].push(alignment);
18263          });
18264          row = 0;
18265
18266          while (allocatedCount < features.length && row <= maxRows) {
18267            while (nextStart <= end) {
18268              bucket = undefined;
18269
18270              while (!bucket && nextStart <= end) {
18271                index = nextStart - bucketStart;
18272
18273                if (bucketList[index] === undefined) {
18274                  ++nextStart; // No buckets at this index
18275                } else {
18276                  bucket = bucketList[index];
18277                }
18278              } // while (bucket)
18279
18280
18281              if (!bucket) {
18282                break;
18283              }
18284
18285              feature = bucket.pop();
18286
18287              if (0 === bucket.length) {
18288                bucketList[index] = undefined;
18289              }
18290
18291              feature.row = row;
18292              nextStart = feature.end + gap;
18293              ++allocatedCount;
18294            } // while (nextStart)
18295
18296
18297            row++;
18298            nextStart = bucketStart;
18299            if (allocatedCount === lastAllocatedCount) break; // Protect from infinite loops
18300
18301            lastAllocatedCount = allocatedCount;
18302          } // while (allocatedCount)
18303
18304        }
18305      },
18306
18307      /**
18308       * Find features overlapping the given interval.  It is assumed that all features share the same chromosome.
18309       *
18310       * TODO -- significant overlap with FeatureCache, refactor to combine
18311       *
18312       * @param featureList
18313       * @param start
18314       * @param end
18315       */
18316      findOverlapping: function (featureList, start, end) {
18317        if (!featureList || featureList.length === 0) {
18318          return [];
18319        } else {
18320          const tree = buildIntervalTree(featureList);
18321          const intervals = tree.findOverlapping(start, end);
18322
18323          if (intervals.length === 0) {
18324            return [];
18325          } else {
18326            // Trim the list of features in the intervals to those
18327            // overlapping the requested range.
18328            // Assumption: features are sorted by start position
18329            featureList = [];
18330            intervals.forEach(function (interval) {
18331              const intervalFeatures = interval.value;
18332              const len = intervalFeatures.length;
18333
18334              for (let i = 0; i < len; i++) {
18335                const feature = intervalFeatures[i];
18336                if (feature.start > end) break;else if (feature.end > start) {
18337                  featureList.push(feature);
18338                }
18339              }
18340            });
18341            featureList.sort(function (a, b) {
18342              return a.start - b.start;
18343            });
18344            return featureList;
18345          }
18346        }
18347      }
18348    };
18349    /**
18350     * Build an interval tree from the feature list for fast interval based queries.   We lump features in groups
18351     * of 10, or total size / 100,   to reduce size of the tree.
18352     *
18353     * @param featureList
18354     */
18355
18356    function buildIntervalTree(featureList) {
18357      const tree = new IntervalTree();
18358      const len = featureList.length;
18359      const chunkSize = Math.max(10, Math.round(len / 100));
18360      featureList.sort(function (f1, f2) {
18361        return f1.start === f2.start ? 0 : f1.start > f2.start ? 1 : -1;
18362      });
18363
18364      for (let i = 0; i < len; i += chunkSize) {
18365        const e = Math.min(len, i + chunkSize);
18366        const subArray = featureList.slice(i, e);
18367        const iStart = subArray[0].start;
18368        let iEnd = iStart;
18369        subArray.forEach(function (feature) {
18370          iEnd = Math.max(iEnd, feature.end);
18371        });
18372        tree.insert(iStart, iEnd, subArray);
18373      }
18374
18375      return tree;
18376    }
18377
18378    function createCheckbox$1(name, initialState) {
18379      const container = div$1({
18380        class: 'igv-menu-popup-check-container'
18381      });
18382      const div = div$1();
18383      container.appendChild(div);
18384      const svg = createIcon$1('check', true === initialState ? '#444' : 'transparent');
18385      div.appendChild(svg);
18386      const label = div$1();
18387      label.innerText = name;
18388      container.appendChild(label);
18389      return container;
18390    }
18391
18392    /**
18393     * Configure item list for track "gear" menu.
18394     * @param trackView
18395     */
18396
18397    const MenuUtils = {
18398      trackMenuItemList: function (trackView) {
18399        const vizWindowTypes = new Set(['alignment', 'annotation', 'variant', 'eqtl', 'snp']);
18400        const hasVizWindow = trackView.track.config && trackView.track.config.visibilityWindow !== undefined;
18401        let menuItems = [];
18402
18403        if (trackView.track.config.type !== 'sequence') {
18404          menuItems.push(trackRenameMenuItem(trackView));
18405          menuItems.push(trackHeightMenuItem(trackView));
18406        }
18407
18408        if (this.showColorPicker(trackView.track)) {
18409          menuItems.push('<hr/>');
18410          menuItems.push(colorPickerMenuItem({
18411            trackView,
18412            label: "Set track color",
18413            option: "color"
18414          }));
18415          menuItems.push(unsetColorMenuItem({
18416            trackView,
18417            label: "Unset track color"
18418          }));
18419          menuItems.push(colorPickerMenuItem({
18420            trackView,
18421            label: "Set alt color",
18422            option: "altColor"
18423          }));
18424        }
18425
18426        if (trackView.track.menuItemList) {
18427          menuItems = menuItems.concat(trackView.track.menuItemList());
18428        }
18429
18430        if (hasVizWindow || vizWindowTypes.has(trackView.track.type)) {
18431          menuItems.push('<hr/>');
18432          menuItems.push(visibilityWindowMenuItem(trackView));
18433        }
18434
18435        if (trackView.track.removable !== false) {
18436          menuItems.push('<hr/>');
18437          menuItems.push(trackRemovalMenuItem(trackView));
18438        }
18439
18440        return menuItems;
18441      },
18442      numericDataMenuItems: function (trackView) {
18443        const menuItems = [];
18444        menuItems.push('<hr/>'); // Data range
18445
18446        const object = $$1('<div>');
18447        object.text('Set data range');
18448
18449        const click = () => {
18450          trackView.browser.dataRangeDialog.configure(trackView);
18451          trackView.browser.dataRangeDialog.present($$1(trackView.browser.columnContainer));
18452        };
18453
18454        menuItems.push({
18455          object,
18456          click
18457        });
18458
18459        if (trackView.track.logScale !== undefined) {
18460          menuItems.push({
18461            object: $$1(createCheckbox$1("Log scale", trackView.track.logScale)),
18462            click: () => {
18463              trackView.track.logScale = !trackView.track.logScale;
18464              trackView.repaintViews();
18465            }
18466          });
18467        }
18468
18469        menuItems.push({
18470          object: $$1(createCheckbox$1("Autoscale", trackView.track.autoscale)),
18471          click: () => {
18472            trackView.track.autoscale = !trackView.track.autoscale;
18473            trackView.updateViews();
18474          }
18475        });
18476        return menuItems;
18477      },
18478      trackMenuItemListHelper: function (itemList, menuPopup) {
18479        var list = [];
18480
18481        if (itemList.length > 0) {
18482          list = itemList.map(function (item, i) {
18483            var $e; // name and object fields checked for backward compatibility
18484
18485            if (item.name) {
18486              $e = $$1('<div>');
18487              $e.text(item.name);
18488            } else if (item.object) {
18489              $e = item.object;
18490            } else if (typeof item.label === 'string') {
18491              $e = $$1('<div>');
18492              $e.html(item.label);
18493            } else if (typeof item === 'string') {
18494              if (item.startsWith("<")) {
18495                $e = $$1(item);
18496              } else {
18497                $e = $$1("<div>" + item + "</div>");
18498              }
18499            }
18500
18501            if (0 === i) {
18502              $e.addClass('igv-track-menu-border-top');
18503            }
18504
18505            if (item.click) {
18506              $e.on('click', handleClick);
18507              $e.on('touchend', function (e) {
18508                handleClick(e);
18509              });
18510              $e.on('mouseup', function (e) {
18511                e.preventDefault();
18512                e.stopPropagation();
18513              }); // eslint-disable-next-line no-inner-declarations
18514
18515              function handleClick(e) {
18516                item.click(e);
18517                menuPopup.hide();
18518                e.preventDefault();
18519                e.stopPropagation();
18520              }
18521            }
18522
18523            return {
18524              object: $e,
18525              init: item.init || undefined
18526            };
18527          });
18528        }
18529
18530        return list;
18531      },
18532
18533      showColorPicker(track) {
18534        return undefined === track.type || "bedtype" === track.type || "alignment" === track.type || "annotation" === track.type || "variant" === track.type || "wig" === track.type || 'interact' === track.type;
18535      },
18536
18537      createMenuItem(label, action) {
18538        const object = $$1('<div>');
18539        object.text(label);
18540        return {
18541          object,
18542          click: action
18543        };
18544      }
18545
18546    };
18547
18548    function visibilityWindowMenuItem(trackView) {
18549      const click = e => {
18550        const callback = () => {
18551          let value = trackView.browser.inputDialog.input.value;
18552          value = '' === value || undefined === value ? -1 : value.trim();
18553          trackView.track.visibilityWindow = Number.parseInt(value);
18554          trackView.track.config.visibilityWindow = Number.parseInt(value);
18555          trackView.updateViews();
18556        };
18557
18558        const config = {
18559          label: 'Visibility Window',
18560          value: trackView.track.visibilityWindow,
18561          callback
18562        };
18563        trackView.browser.inputDialog.present(config, e);
18564      };
18565
18566      const object = $$1('<div>');
18567      object.text('Set visibility window');
18568      return {
18569        object,
18570        click
18571      };
18572    }
18573
18574    function trackRemovalMenuItem(trackView) {
18575      const object = $$1('<div>');
18576      object.text('Remove track');
18577      return {
18578        object,
18579        click: () => trackView.browser.removeTrack(trackView.track)
18580      };
18581    }
18582
18583    function colorPickerMenuItem(_ref) {
18584      let {
18585        trackView,
18586        label,
18587        option
18588      } = _ref;
18589      const $e = $$1('<div>');
18590      $e.text(label);
18591      return {
18592        object: $e,
18593        click: () => trackView.presentColorPicker(option)
18594      };
18595    }
18596
18597    function unsetColorMenuItem(_ref2) {
18598      let {
18599        trackView,
18600        label
18601      } = _ref2;
18602      const $e = $$1('<div>');
18603      $e.text(label);
18604      return {
18605        object: $e,
18606        click: () => {
18607          trackView.track.color = undefined;
18608          trackView.repaintViews();
18609        }
18610      };
18611    }
18612
18613    function trackRenameMenuItem(trackView) {
18614      const click = e => {
18615        const callback = function () {
18616          let value = trackView.browser.inputDialog.input.value;
18617          value = '' === value || undefined === value ? 'untitled' : value.trim();
18618          trackView.track.name = value;
18619        };
18620
18621        const config = {
18622          label: 'Track Name',
18623          value: getTrackLabelText(trackView.track) || 'unnamed',
18624          callback
18625        };
18626        trackView.browser.inputDialog.present(config, e);
18627      };
18628
18629      const object = $$1('<div>');
18630      object.text('Set track name');
18631      return {
18632        object,
18633        click
18634      };
18635    }
18636
18637    function trackHeightMenuItem(trackView) {
18638      const click = e => {
18639        const callback = () => {
18640          const number = Number(trackView.browser.inputDialog.input.value, 10);
18641
18642          if (undefined !== number) {
18643            // If explicitly setting the height adust min or max, if neccessary.
18644            if (trackView.track.minHeight !== undefined && trackView.track.minHeight > number) {
18645              trackView.track.minHeight = number;
18646            }
18647
18648            if (trackView.track.maxHeight !== undefined && trackView.track.maxHeight < number) {
18649              trackView.track.minHeight = number;
18650            }
18651
18652            trackView.setTrackHeight(number, true);
18653            trackView.checkContentHeight();
18654            trackView.repaintViews(); // Explicitly setting track height turns off autoHeight
18655
18656            trackView.track.autoHeight = false;
18657          }
18658        };
18659
18660        const config = {
18661          label: 'Track Height',
18662          value: trackView.track.height,
18663          callback
18664        };
18665        trackView.browser.inputDialog.present(config, e);
18666      };
18667
18668      const object = $$1('<div>');
18669      object.text('Set track height');
18670      return {
18671        object,
18672        click
18673      };
18674    }
18675
18676    function getTrackLabelText(track) {
18677      var vp, txt;
18678      vp = track.trackView.viewports[0];
18679      txt = vp.$trackLabel.text();
18680      return txt;
18681    }
18682
18683    function div(options) {
18684      return create("div", options);
18685    }
18686
18687    function create(tag, options) {
18688      const elem = document.createElement(tag);
18689
18690      if (options) {
18691        if (options.class) {
18692          elem.classList.add(options.class);
18693        }
18694
18695        if (options.id) {
18696          elem.id = options.id;
18697        }
18698
18699        if (options.style) {
18700          applyStyle(elem, options.style);
18701        }
18702      }
18703
18704      return elem;
18705    }
18706
18707    function hide(elem) {
18708      const cssStyle = getComputedStyle(elem);
18709
18710      if (cssStyle.display !== "none") {
18711        elem._initialDisplay = cssStyle.display;
18712      }
18713
18714      elem.style.display = "none";
18715    }
18716
18717    function show(elem) {
18718      const currentDisplay = getComputedStyle(elem).display;
18719
18720      if (currentDisplay === "none") {
18721        const d = elem._initialDisplay || "block";
18722        elem.style.display = d;
18723      }
18724    }
18725
18726    function offset(elem) {
18727      // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
18728      // Support: IE <=11 only
18729      // Running getBoundingClientRect on a
18730      // disconnected node in IE throws an error
18731      if (!elem.getClientRects().length) {
18732        return {
18733          top: 0,
18734          left: 0
18735        };
18736      } // Get document-relative position by adding viewport scroll to viewport-relative gBCR
18737
18738
18739      const rect = elem.getBoundingClientRect();
18740      const win = elem.ownerDocument.defaultView;
18741      return {
18742        top: rect.top + win.pageYOffset,
18743        left: rect.left + win.pageXOffset
18744      };
18745    }
18746
18747    function pageCoordinates(e) {
18748      if (e.type.startsWith("touch")) {
18749        const touch = e.touches[0];
18750        return {
18751          x: touch.pageX,
18752          y: touch.pageY
18753        };
18754      } else {
18755        return {
18756          x: e.pageX,
18757          y: e.pageY
18758        };
18759      }
18760    }
18761
18762    function applyStyle(elem, style) {
18763      for (let key of Object.keys(style)) {
18764        elem.style[key] = style[key];
18765      }
18766    }
18767
18768    let getMouseXY = (domElement, {
18769      clientX,
18770      clientY
18771    }) => {
18772      // DOMRect object with eight properties: left, top, right, bottom, x, y, width, height
18773      const {
18774        left,
18775        top,
18776        width,
18777        height
18778      } = domElement.getBoundingClientRect();
18779      const x = clientX - left;
18780      const y = clientY - top;
18781      return {
18782        x,
18783        y,
18784        xNormalized: x / width,
18785        yNormalized: y / height,
18786        width,
18787        height
18788      };
18789    };
18790    /**
18791     * Translate the mouse coordinates for the event to the coordinates for the given target element
18792     * @param event
18793     * @param domElement
18794     * @returns {{x: number, y: number}}
18795     */
18796
18797
18798    function translateMouseCoordinates(event, domElement) {
18799      const {
18800        clientX,
18801        clientY
18802      } = event;
18803      return getMouseXY(domElement, {
18804        clientX,
18805        clientY
18806      });
18807    }
18808
18809    function createCheckbox(name, initialState) {
18810      const container = div({
18811        class: 'igv-ui-trackgear-popover-check-container'
18812      });
18813      const svg = iconMarkup('check', true === initialState ? '#444' : 'transparent');
18814      svg.style.borderColor = 'gray';
18815      svg.style.borderWidth = '1px';
18816      svg.style.borderStyle = 'solid';
18817      container.appendChild(svg);
18818      let label = div(); //{ class: 'igv-some-label-class' });
18819
18820      label.textContent = name;
18821      container.appendChild(label);
18822      return container;
18823    }
18824
18825    function createIcon(name, color) {
18826      return iconMarkup(name, color);
18827    }
18828
18829    function iconMarkup(name, color) {
18830      color = color || "currentColor";
18831      let icon = icons[name];
18832
18833      if (!icon) {
18834        console.error(`No icon named: ${name}`);
18835        icon = icons["question"];
18836      }
18837
18838      const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
18839      svg.setAttributeNS(null, 'viewBox', '0 0 ' + icon[0] + ' ' + icon[1]);
18840      const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
18841      path.setAttributeNS(null, 'fill', color);
18842      path.setAttributeNS(null, 'd', icon[4]);
18843      svg.appendChild(path);
18844      return svg;
18845    }
18846
18847    const icons = {
18848      "check": [512, 512, [], "f00c", "M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"],
18849      "cog": [512, 512, [], "f013", "M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"],
18850      "exclamation": [192, 512, [], "f12a", "M176 432c0 44.112-35.888 80-80 80s-80-35.888-80-80 35.888-80 80-80 80 35.888 80 80zM25.26 25.199l13.6 272C39.499 309.972 50.041 320 62.83 320h66.34c12.789 0 23.331-10.028 23.97-22.801l13.6-272C167.425 11.49 156.496 0 142.77 0H49.23C35.504 0 24.575 11.49 25.26 25.199z"],
18851      "exclamation-circle": [512, 512, [], "f06a", "M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418
18851-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],
18852      "exclamation-triangle": [576, 512, [], "f071", "M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"],
18853      "minus": [448, 512, [], "f068", "M424 318.2c13.3 0 24-10.7 24-24v-76.4c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h400z"],
18854      "minus-circle": [512, 512, [], "f056", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"],
18855      "minus-square": [448, 512, [], "f146", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z"],
18856      "plus": [448, 512, [], "f067", "M448 294.2v-76.4c0-13.3-10.7-24-24-24H286.2V56c0-13.3-10.7-24-24-24h-76.4c-13.3 0-24 10.7-24 24v137.8H24c-13.3 0-24 10.7-24 24v76.4c0 13.3 10.7 24 24 24h137.8V456c0 13.3 10.7 24 24 24h76.4c13.3 0 24-10.7 24-24V318.2H424c13.3 0 24-10.7 24-24z"],
18857      "plus-circle": [512, 512, [], "f055", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm144 276c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92h-92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],
18858      "plus-square": [448, 512, [], "f0fe", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z"],
18859      "question": [384, 512, [], "f128", "M202.021 0C122.202 0 70.503 32.703 29.914 91.026c-7.363 10.58-5.093 25.086 5.178 32.874l43.138 32.709c10.373 7.865 25.132 6.026 33.253-4.148 25.049-31.381 43.63-49.449 82.757-49.449 30.764 0 68.816 19.799 68.816 49.631 0 22.552-18.617 34.134-48.993 51.164-35.423 19.86-82.299 44.576-82.299 106.405V320c0 13.255 10.745 24 24 24h72.471c13.255 0 24-10.745 24-24v-5.773c0-42.86 125.268-44.645 125.268-160.627C377.504 66.256 286.902 0 202.021 0zM192 373.459c-38.196 0-69.271 31.075-69.271 69.271 0 38.195 31.075 69.27 69.271 69.27s69.271-31.075 69.271-69.271-31.075-69.27-69.271-69.27z"],
18860      "save": [448, 512, [], "f0c7", "M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z"],
18861      "search": [512, 512, [], "f002", "M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"],
18862      "share": [512, 512, [], "f064", "M503.691 189.836L327.687 37.851C312.281 24.546 288 35.347 288 56.015v80.053C127.371 137.907 0 170.1 0 322.326c0 61.441 39.581 122.309 83.333 154.132 13.653 9.931 33.111-2.533 28.077-18.631C66.066 312.814 132.917 274.316 288 272.085V360c0 20.7 24.3 31.453 39.687 18.164l176.004-152c11.071-9.562 11.086-26.753 0-36.328z"],
18863      "spinner": [512, 512, [], "f110", "M304 48c0 26.51-21.49 48-48 48s-48-21.49-48-48 21.49-48 48-48 48 21.49 48 48zm-48 368c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zm208-208c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.49-48-48-48zM96 256c0-26.51-21.49-48-48-48S0 229.49 0 256s21.49 48 48 48 48-21.49 48-48zm12.922 99.078c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.491-48-48-48zm294.156 0c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-26.509-21.49-48-48-48zM108.922 60.922c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48-21.491-48-48-48z"],
18864      "square": [448, 512, [], "f0c8", "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z"],
18865      "square-full": [512, 512, [], "f45c", "M512 512H0V0h512v512z"],
18866      "times": [384, 512, [], "f00d", "M323.1 441l53.9-53.9c9.4-9.4 9.4-24.5 0-33.9L279.8 256l97.2-97.2c9.4-9.4 9.4-24.5 0-33.9L323.1 71c-9.4-9.4-24.5-9.4-33.9 0L192 168.2 94.8 71c-9.4-9.4-24.5-9.4-33.9 0L7 124.9c-9.4 9.4-9.4 24.5 0 33.9l97.2 97.2L7 353.2c-9.4 9.4-9.4 24.5 0 33.9L60.9 441c9.4 9.4 24.5 9.4 33.9 0l97.2-97.2 97.2 97.2c9.3 9.3 24.5 9.3 33.9 0z"],
18867      "times-circle": [512, 512, [], "f057", "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"],
18868      "wrench": [512, 512, [], "f0ad", "M481.156 200c9.3 0 15.12 10.155 10.325 18.124C466.295 259.992 420.419 288 368 288c-79.222 0-143.501-63.974-143.997-143.079C223.505 65.469 288.548-.001 368.002 0c52.362.001 98.196 27.949 123.4 69.743C496.24 77.766 490.523 88 481.154 88H376l-40 56 40 56h105.156zm-171.649 93.003L109.255 493.255c-24.994 24.993-65.515 24.994-90.51 0-24.993-24.994-24.993-65.516 0-90.51L218.991 202.5c16.16 41.197 49.303 74.335 90.516 90.503zM104 432c0-13.255-10.745-24-24-24s-24 10.745-24 24 10.745 24 24 24 24-10.745 24-24z"]
18869    };
18870
18871    function attachDialogCloseHandlerWithParent(parent, closeHandler) {
18872      var container = document.createElement("div");
18873      parent.appendChild(container);
18874      container.appendChild(createIcon("times"));
18875      container.addEventListener('click', function (e) {
18876        e.preventDefault();
18877        e.stopPropagation();
18878        closeHandler();
18879      });
18880    }
18881    /**
18882     * Make the target element movable by clicking and dragging on the handle.  This is not a general purprose function,
18883     * it makes several options specific to igv dialogs, the primary one being that the
18884     * target is absolutely positioned in pixel coordinates
18885
18886     */
18887
18888
18889    let dragData; // Its assumed we are only dragging one element at a time.
18890
18891    function makeDraggable(target, handle) {
18892      handle.addEventListener('mousedown', dragStart.bind(target));
18893    }
18894
18895    function dragStart(event) {
18896      event.stopPropagation();
18897      event.preventDefault();
18898      offset(this);
18899      const dragFunction = drag.bind(this);
18900      const dragEndFunction = dragEnd.bind(this);
18901      const computedStyle = getComputedStyle(this);
18902      const top = parseInt(computedStyle.top.replace("px", ""));
18903      const left = parseInt(computedStyle.left.replace("px", ""));
18904      dragData = {
18905        dragFunction: dragFunction,
18906        dragEndFunction: dragEndFunction,
18907        screenX: event.screenX,
18908        screenY: event.screenY,
18909        top: top,
18910        left: left
18911      };
18912      document.addEventListener('mousemove', dragFunction);
18913      document.addEventListener('mouseup', dragEndFunction);
18914      document.addEventListener('mouseleave', dragEndFunction);
18915      document.addEventListener('mouseexit', dragEndFunction);
18916    }
18917
18918    function drag(event) {
18919      if (!dragData) {
18920        console.log("No drag data!");
18921        return;
18922      }
18923
18924      event.stopPropagation();
18925      event.preventDefault();
18926      const dx = event.screenX - dragData.screenX;
18927      const dy = event.screenY - dragData.screenY;
18928      this.style.left = `${dragData.left + dx}px`;
18929      this.style.top = `${dragData.top + dy}px`;
18930    }
18931
18932    function dragEnd(event) {
18933      if (!dragData) {
18934        console.log("No drag data!");
18935        return;
18936      }
18937
18938      event.stopPropagation();
18939      event.preventDefault();
18940      const dragFunction = dragData.dragFunction;
18941      const dragEndFunction = dragData.dragEndFunction;
18942      document.removeEventListener('mousemove', dragFunction);
18943      document.removeEventListener('mouseup', dragEndFunction);
18944      document.removeEventListener('mouseleave', dragEndFunction);
18945      document.removeEventListener('mouseexit', dragEndFunction);
18946      dragData = undefined;
18947    }
18948
18949    const httpMessages = {
18950      "401": "Access unauthorized",
18951      "403": "Access forbidden",
18952      "404": "Not found"
18953    };
18954
18955    class AlertDialog {
18956      /**
18957       * Initialize a new alert dialog
18958       * @param parent
18959       * @param alertProps - Optional - properties such as scroll to error
18960       */
18961      constructor(parent, alertProps) {
18962        this.alertProps = Object.assign({
18963          /** When an alert is presented - focus occur */
18964          shouldFocus: true,
18965
18966          /** When focus occur - scroll into that element in the view */
18967          preventScroll: false
18968        }, alertProps); // container
18969
18970        this.container = div({
18971          class: "igv-ui-alert-dialog-container"
18972        });
18973        parent.appendChild(this.container);
18974        this.container.setAttribute('tabIndex', '-1'); // header
18975
18976        const header = div();
18977        this.container.appendChild(header);
18978        this.errorHeadline = div();
18979        header.appendChild(this.errorHeadline);
18980        this.errorHeadline.textContent = ''; // body container
18981
18982        let bodyContainer = div({
18983          id: 'igv-ui-alert-dialog-body'
18984        });
18985        this.container.appendChild(bodyContainer); // body copy
18986
18987        this.body = div({
18988          id: 'igv-ui-alert-dialog-body-copy'
18989        });
18990        bodyContainer.appendChild(this.body); // ok container
18991
18992        let ok_container = div();
18993        this.container.appendChild(ok_container); // ok
18994
18995        this.ok = div();
18996        ok_container.appendChild(this.ok);
18997        this.ok.textContent = 'OK';
18998
18999        const okHandler = () => {
19000          if (typeof this.callback === 'function') {
19001            this.callback("OK");
19002            this.callback = undefined;
19003          }
19004
19005          this.body.innerHTML = '';
19006          hide(this.container);
19007        };
19008
19009        this.ok.addEventListener('click', event => {
19010          event.stopPropagation();
19011          okHandler();
19012        });
19013        this.container.addEventListener('keypress', event => {
19014          event.stopPropagation();
19015
19016          if ('Enter' === event.key) {
19017            okHandler();
19018          }
19019        });
19020        makeDraggable(this.container, header);
19021        hide(this.container);
19022      }
19023
19024      present(alert, callback) {
19025        this.errorHeadline.textContent = alert.message ? 'ERROR' : '';
19026        let string = alert.message || alert;
19027
19028        if (httpMessages.hasOwnProperty(string)) {
19029          string = httpMessages[string];
19030        }
19031
19032        this.body.innerHTML = string;
19033        this.callback = callback;
19034        show(this.container);
19035
19036        if (this.alertProps.shouldFocus) {
19037          this.container.focus({
19038            preventScroll: this.alertProps.preventScroll
19039          });
19040        }
19041      }
19042
19043    }
19044
19045    let alertDialog;
19046    const Alert = {
19047      init(root, config = {}) {
19048        alertDialog = new AlertDialog(root, config);
19049      },
19050
19051      presentAlert(alert, callback) {
19052        if (!alertDialog) {
19053          this.init(document.body);
19054        }
19055
19056        alertDialog.present(alert, callback);
19057      }
19058
19059    };
19060
19061    class InputDialog {
19062      constructor(parent) {
19063        this.parent = parent; // dialog container
19064
19065        this.container = div({
19066          class: 'igv-ui-generic-dialog-container'
19067        });
19068        parent.appendChild(this.container); // const { x, y, width, height } = this.container.getBoundingClientRect();
19069        // console.log(`InputDialog - x ${ x } y ${ y } width ${ width } height ${ height }`)
19070        // dialog header
19071
19072        const header = div({
19073          class: 'igv-ui-generic-dialog-header'
19074        });
19075        this.container.appendChild(header); // dialog label
19076
19077        this.label = div({
19078          class: 'igv-ui-generic-dialog-one-liner'
19079        });
19080        this.container.appendChild(this.label);
19081        this.label.text = 'Unlabeled'; // input container
19082
19083        this.input_container = div({
19084          class: 'igv-ui-generic-dialog-input'
19085        });
19086        this.container.appendChild(this.input_container); //
19087
19088        this.input = document.createElement("input");
19089        this.input_container.appendChild(this.input); // ok | cancel
19090
19091        const buttons = div({
19092          class: 'igv-ui-generic-dialog-ok-cancel'
19093        });
19094        this.container.appendChild(buttons); // ok
19095
19096        this.ok = div();
19097        buttons.appendChild(this.ok);
19098        this.ok.textContent = 'OK'; // cancel
19099
19100        this.cancel = div();
19101        buttons.appendChild(this.cancel);
19102        this.cancel.textContent = 'Cancel';
19103        hide(this.container);
19104        this.input.addEventListener('keyup', e => {
19105          if (13 === e.keyCode) {
19106            if (typeof this.callback === 'function') {
19107              this.callback(this.input.value);
19108              this.callback = undefined;
19109            }
19110
19111            this.input.value = undefined;
19112            hide(this.container);
19113          }
19114        });
19115        this.ok.addEventListener('click', () => {
19116          if (typeof this.callback === 'function') {
19117            this.callback(this.input.value);
19118            this.callback = undefined;
19119          }
19120
19121          this.input.value = undefined;
19122          hide(this.container);
19123        });
19124
19125        const cancel = () => {
19126          this.input.value = '';
19127          hide(this.container);
19128        };
19129
19130        this.cancel.addEventListener('click', cancel);
19131        attachDialogCloseHandlerWithParent(header, cancel);
19132        makeDraggable(this.container, header);
19133      }
19134
19135      present(options, e) {
19136        this.label.textContent = options.label;
19137        this.input.value = options.value;
19138        this.callback = options.callback || options.click;
19139        show(this.container);
19140        const {
19141          x,
19142          y
19143        } = pageCoordinates(e);
19144        this.clampLocation(x, y);
19145      }
19146
19147      clampLocation(pageX, pageY) {
19148        const {
19149          width: w,
19150          height: h
19151        } = this.container.getBoundingClientRect();
19152        const {
19153          x: px,
19154          y: py,
19155          width: pw,
19156          height: ph
19157        } = this.parent.getBoundingClientRect();
19158        const y = Math.min(Math.max(pageY, py), py + ph - h);
19159        const x = Math.min(Math.max(pageX, px), px + pw - w);
19160        this.container.style.left = `${x}px`;
19161        this.container.style.top = `${y}px`;
19162      }
19163
19164    }
19165
19166    const appleCrayonPalette = {
19167      licorice: "#000000",
19168      lead: "#1e1e1e",
19169      tungsten: "#3a3a3a",
19170      iron: "#545453",
19171      steel: "#6e6e6e",
19172      tin: "#878687",
19173      nickel: "#888787",
19174      aluminum: "#a09fa0",
19175      magnesium: "#b8b8b8",
19176      silver: "#d0d0d0",
19177      mercury: "#e8e8e8",
19178      snow: "#ffffff",
19179      //
19180      cayenne: "#891100",
19181      mocha: "#894800",
19182      aspargus: "#888501",
19183      fern: "#458401",
19184      clover: "#028401",
19185      moss: "#018448",
19186      teal: "#008688",
19187      ocean: "#004a88",
19188      midnight: "#001888",
19189      eggplant: "#491a88",
19190      plum: "#891e88",
19191      maroon: "#891648",
19192      //
19193      maraschino: "#ff2101",
19194      tangerine: "#ff8802",
19195      lemon: "#fffa03",
19196      lime: "#83f902",
19197      spring: "#05f802",
19198      seam_foam: "#03f987",
19199      turquoise: "#00fdff",
19200      aqua: "#008cff",
19201      blueberry: "#002eff",
19202      grape: "#8931ff",
19203      magenta: "#ff39ff",
19204      strawberry: "#ff2987",
19205      //
19206      salmon: "#ff726e",
19207      cantaloupe: "#ffce6e",
19208      banana: "#fffb6d",
19209      honeydew: "#cefa6e",
19210      flora: "#68f96e",
19211      spindrift: "#68fbd0",
19212      ice: "#68fdff",
19213      sky: "#6acfff",
19214      orchid: "#6e76ff",
19215      lavender: "#d278ff",
19216      bubblegum: "#ff7aff",
19217      carnation: "#ff7fd3"
19218    }; //import { DOMUtils, UIUtils, makeDraggable } from '../node_modules/igv-utils/src/index.js'
19219
19220    class GenericContainer {
19221      constructor({
19222        parent,
19223        top,
19224        left,
19225        width,
19226        height,
19227        border,
19228        closeHandler
19229      }) {
19230        let container = div({
19231          class: 'igv-ui-generic-container'
19232        });
19233        parent.appendChild(container);
19234        hide(container);
19235        this.container = container;
19236
19237        if (top !== undefined) {
19238          this.container.style.top = `${top}px`;
19239        }
19240
19241        if (left !== undefined) {
19242          this.container.style.left = `${left}px`;
19243        }
19244
19245        if (width !== undefined) {
19246          this.container.style.width = `${width}px`;
19247        }
19248
19249        if (height !== undefined) {
19250          this.container.style.height = `${height}px`;
19251        }
19252
19253        if (border) {
19254          this.container.style.border = border;
19255        } //
19256        // let bbox = parent.getBoundingClientRect();
19257        // this.origin = {x: bbox.x, y: bbox.y};
19258        // this.container.offset({left: this.origin.x, top: this.origin.y});
19259        // header
19260
19261
19262        const header = div();
19263        this.container.appendChild(header); // close button
19264
19265        attachDialogCloseHandlerWithParent(header, e => {
19266          hide(this.container);
19267
19268          if (typeof closeHandler === "function") {
19269            closeHandler(e);
19270          }
19271        });
19272        makeDraggable(this.container, header);
19273      }
19274
19275      show() {
19276        show(this.container);
19277      }
19278
19279      hide() {
19280        hide(this.container);
19281      }
19282
19283      dispose() {
19284        if (this.container.parent) {
19285          this.container.parent.removeChild(this.container);
19286        }
19287      }
19288
19289    }
19290
19291    class ColorPicker extends GenericContainer {
19292      constructor({
19293        parent,
19294        top,
19295        left,
19296        width,
19297        height,
19298        defaultColors,
19299        colorHandler
19300      }) {
19301        super({
19302          parent,
19303          top,
19304          left,
19305          width,
19306          height,
19307          border: '1px solid gray'
19308        });
19309        createColorSwatchSelector(this.container, colorHandler, defaultColors);
19310      }
19311
19312    }
19313
19314    const createColorSwatchSelector = (container, colorHandler, defaultColors) => {
19315      const hexColorStrings = Object.values(appleCrayonPalette);
19316
19317      for (let hexColorString of hexColorStrings) {
19318        const swatch = div({
19319          class: 'igv-ui-color-swatch'
19320        });
19321        container.appendChild(swatch);
19322        decorateSwatch(swatch, hexColorString, colorHandler);
19323      }
19324
19325      if (defaultColors) {
19326        for (let hexColorString of defaultColors) {
19327          const swatch = div({
19328            class: 'igv-ui-color-swatch'
19329          });
19330          container.appendChild(swatch);
19331          decorateSwatch(swatch, hexColorString, colorHandler);
19332        }
19333      }
19334    };
19335
19336    const decorateSwatch = (swatch, hexColorString, colorHandler) => {
19337      swatch.style.backgroundColor = hexColorString;
19338      swatch.addEventListener('mouseenter', e => swatch.style.borderColor = hexColorString);
19339      swatch.addEventListener('mouseleave', e => swatch.style.borderColor = 'white');
19340      swatch.addEventListener('click', event => {
19341        event.stopPropagation();
19342        colorHandler(hexColorString);
19343      });
19344      swatch.addEventListener('touchend', event => {
19345        event.stopPropagation();
19346        colorHandler(hexColorString);
19347      });
19348    };
19349
19350    class Popover {
19351      constructor(parent, title) {
19352        this.parent = parent; // popover
19353
19354        this.popover = div({
19355          class: "igv-ui-popover"
19356        });
19357        parent.appendChild(this.popover); // header
19358
19359        const popoverHeader = div();
19360        this.popover.appendChild(popoverHeader);
19361        const titleElement = div();
19362        popoverHeader.appendChild(titleElement);
19363
19364        if (title) {
19365          titleElement.textContent = title;
19366        }
19367
19368        attachDialogCloseHandlerWithParent(popoverHeader, () => this.hide());
19369        makeDraggable(this.popover, popoverHeader); // content
19370
19371        this.popoverContent = div();
19372        this.popover.appendChild(this.popoverContent);
19373        this.popover.style.display = 'none';
19374      }
19375
19376      presentContentWithEvent(e, content) {
19377        this.popover.style.display = 'block';
19378        this.popoverContent.innerHTML = content;
19379        present$1(e, this.popover, this.popoverContent);
19380      }
19381
19382      presentMenu(e, menuItems) {
19383        if (0 === menuItems.length) {
19384          return;
19385        }
19386
19387        this.popover.style.display = 'block';
19388        const menuElements = createMenuElements$1(menuItems, this.popover);
19389
19390        for (let item of menuElements) {
19391          this.popoverContent.appendChild(item.object);
19392        }
19393
19394        present$1(e, this.popover, this.popoverContent);
19395      }
19396
19397      hide() {
19398        this.popover.style.display = 'none';
19399        this.dispose();
19400      }
19401
19402      dispose() {
19403        if (this.popover) {
19404          this.popover.parentNode.removeChild(this.popover);
19405        }
19406
19407        const keys = Object.keys(this);
19408
19409        for (let key of keys) {
19410          this[key] = undefined;
19411        }
19412      }
19413
19414    }
19415
19416    function present$1(e, popover, popoverContent) {
19417      const {
19418        x,
19419        y,
19420        width
19421      } = translateMouseCoordinates(e, popover.parentNode);
19422      popover.style.top = `${y}px`;
19423      const {
19424        width: w
19425      } = popover.getBoundingClientRect();
19426      const xmax = x + w;
19427      const delta = xmax - width;
19428      popover.style.left = `${xmax > width ? x - delta : x}px`;
19429      popoverContent.style.maxWidth = `${Math.min(w, width)}px`;
19430    }
19431
19432    function createMenuElements$1(itemList, popover) {
19433      const list = itemList.map(function (item, i) {
19434        let elem;
19435
19436        if (typeof item === 'string') {
19437          elem = div();
19438          elem.innerHTML = item;
19439        } else if (typeof item === 'Node') {
19440          elem = item;
19441        } else {
19442          if (typeof item.init === 'function') {
19443            item.init();
19444          }
19445
19446          if ("checkbox" === item.type) {
19447            elem = createCheckbox("Show all bases", item.value);
19448          } else if ("color" === item.type) {
19449            const colorPicker = new ColorPicker({
19450              parent: popover.parentElement,
19451              width: 364,
19452              //defaultColor: 'aqua',
19453              colorHandler: color => item.click(color)
19454            });
19455            elem = div();
19456
19457            if (typeof item.label === 'string') {
19458              elem.innerHTML = item.label;
19459            }
19460
19461            const clickHandler = e => {
19462              colorPicker.show();
19463              hide(popover);
19464              e.preventDefault();
19465              e.stopPropagation();
19466            };
19467
19468            elem.addEventListener('click', clickHandler);
19469            elem.addEventListener('touchend', clickHandler);
19470            elem.addEventListener('mouseup', function (e) {
19471              e.preventDefault();
19472              e.stopPropagation();
19473            });
19474          } else {
19475            elem = div();
19476
19477            if (typeof item.label === 'string') {
19478              elem.innerHTML = item.label;
19479            }
19480          }
19481
19482          if (item.click && "color" !== item.type) {
19483            elem.addEventListener('click', handleClick);
19484            elem.addEventListener('touchend', handleClick);
19485            elem.addEventListener('mouseup', function (e) {
19486              e.preventDefault();
19487              e.stopPropagation();
19488            }); // eslint-disable-next-line no-inner-declarations
19489
19490            function handleClick(e) {
19491              item.click();
19492              hide(popover);
19493              e.preventDefault();
19494              e.stopPropagation();
19495            }
19496          }
19497        }
19498
19499        return {
19500          object: elem,
19501          init: item.init
19502        };
19503      });
19504      return list;
19505    }
19506
19507    function embedCSS$2() {
19508      var css = '.igv-ui-popover {\n  cursor: default;\n  position: absolute;\n  z-index: 2048;\n  border-color: #7F7F7F;\n  border-radius: 4px;\n  border-style: solid;\n  border-width: 1px;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: small;\n  background-color: white; }\n  .igv-ui-popover > div:first-child {\n    display: flex;\n    flex-direction: row;\n    flex-wrap: nowrap;\n    justify-content: space-between;\n    align-items: center;\n    width: 100%;\n    height: 24px;\n    cursor: move;\n    border-top-left-radius: 4px;\n    border-top-right-radius: 4px;\n    border-bottom-color: #7F7F7F;\n    border-bottom-style: solid;\n    border-bottom-width: thin;\n    background-color: #eee; }\n    .igv-ui-popover > div:first-child > div:first-child {\n      margin-left: 4px; }\n    .igv-ui-popover > div:first-child > div:last-child {\n      margin-right: 4px;\n      height: 12px;\n      width: 12px;\n      color: #7F7F7F; }\n    .igv-ui-popover > div:first-child > div:last-child:hover {\n      cursor: pointer;\n      color: #444; }\n  .igv-ui-popover > div:last-child {\n    overflow-y: auto;\n    overflow-x: hidden;\n    max-height: 400px;\n    max-width: 800px;\n    background-color: white; }\n    .igv-ui-popover > div:last-child > div {\n      -webkit-user-select: all;\n      /* Chrome/Safari */\n      -moz-user-select: all;\n      /* Firefox */\n      margin-left: 4px;\n      margin-right: 4px;\n      min-width: 220px;\n      overflow-x: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap; }\n      .igv-ui-popover > div:last-child > div > span {\n        font-weight: bolder; }\n    .igv-ui-popover > div:last-child hr {\n      width: 100%; }\n\n.igv-ui-alert-dialog-container {\n  box-sizing: content-box;\n  position: absolute;\n  z-index: 2048;\n  top: 50%;\n  left: 50%;\n  width: 400px;\n  height: 200px;\n  border-color: #7F7F7F;\n  border-radius: 4px;\n  border-style: solid;\n  border-width: thin;\n  outline: none;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: 15px;\n  font-weight: 400;\n  background-color: white;\n  display: flex;\n  flex-flow: column;\n  flex-wrap: nowrap;\n  justify-content: space-between;\n  align-items: center; }\n  .igv-ui-alert-dialog-container > div:first-child {\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n    align-items: center;\n    width: 100%;\n    height: 24px;\n    cursor: move;\n    border-top-left-radius: 4px;\n    border-top-right-radius: 4px;\n    border-bottom-color: #7F7F7F;\n    border-bottom-style: solid;\n    border-bottom-width: thin;\n    background-color: #eee; }\n    .igv-ui-alert-dialog-container > div:first-child div:first-child {\n      padding-left: 8px; }\n  .igv-ui-alert-dialog-container #igv-ui-alert-dialog-body {\n    color: #373737;\n    width: 100%;\n    height: calc(100% - 24px - 64px);\n    overflow-y: scroll; }\n    .igv-ui-alert-dialog-container #igv-ui-alert-dialog-body #igv-ui-alert-dialog-body-copy {\n      cursor: pointer;\n      margin: 16px;\n      width: auto;\n      height: auto;\n      overflow-wrap: break-word;\n      word-break: break-word;\n      background-color: white;\n      border: unset; }\n  .igv-ui-alert-dialog-container > div:last-child {\n    width: 100%;\n    margin-bottom: 10px;\n    background-color: white;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: center;
19508\n    align-items: center; }\n    .igv-ui-alert-dialog-container > div:last-child div {\n      margin: unset;\n      width: 40px;\n      height: 30px;\n      line-height: 30px;\n      text-align: center;\n      color: white;\n      font-family: \"Open Sans\", sans-serif;\n      font-size: small;\n      font-weight: 400;\n      border-color: #2B81AF;\n      border-style: solid;\n      border-width: thin;\n      border-radius: 4px;\n      background-color: #2B81AF; }\n    .igv-ui-alert-dialog-container > div:last-child div:hover {\n      cursor: pointer;\n      border-color: #25597f;\n      background-color: #25597f; }\n\n.igv-ui-color-swatch {\n  position: relative;\n  box-sizing: content-box;\n  display: flex;\n  flex-flow: row;\n  flex-wrap: wrap;\n  justify-content: center;\n  align-items: center;\n  width: 32px;\n  height: 32px;\n  border-style: solid;\n  border-width: 2px;\n  border-color: white;\n  border-radius: 4px; }\n\n.igv-ui-color-swatch:hover {\n  border-color: dimgray; }\n\n.igv-ui-colorpicker-menu-close-button {\n  display: flex;\n  flex-flow: row;\n  flex-wrap: nowrap;\n  justify-content: flex-end;\n  align-items: center;\n  width: 100%;\n  height: 32px;\n  margin-top: 4px;\n  margin-bottom: 4px;\n  padding-right: 8px; }\n  .igv-ui-colorpicker-menu-close-button i.fa {\n    display: block;\n    margin-left: 4px;\n    margin-right: 4px;\n    color: #5f5f5f; }\n  .igv-ui-colorpicker-menu-close-button i.fa:hover,\n  .igv-ui-colorpicker-menu-close-button i.fa:focus,\n  .igv-ui-colorpicker-menu-close-button i.fa:active {\n    cursor: pointer;\n    color: #0f0f0f; }\n\n.igv-ui-generic-dialog-container {\n  box-sizing: content-box;\n  position: fixed;\n  top: 0;\n  left: 0;\n  width: 300px;\n  height: 200px;\n  border-color: #7F7F7F;\n  border-radius: 4px;\n  border-style: solid;\n  border-width: thin;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: medium;\n  font-weight: 400;\n  z-index: 2048;\n  background-color: white;\n  display: flex;\n  flex-flow: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: center; }\n  .igv-ui-generic-dialog-container .igv-ui-generic-dialog-header {\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: flex-end;\n    align-items: center;\n    width: 100%;\n    height: 24px;\n    cursor: move;\n    border-top-left-radius: 4px;\n    border-top-right-radius: 4px;\n    border-bottom-color: #7F7F7F;\n    border-bottom-style: solid;\n    border-bottom-width: thin;\n    background-color: #eee; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div {\n      margin-right: 4px;\n      margin-bottom: 2px;\n      height: 12px;\n      width: 12px;\n      color: #7F7F7F; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-header div:hover {\n      cursor: pointer;\n      color: #444; }\n  .igv-ui-generic-dialog-container .igv-ui-generic-dialog-one-liner {\n    color: #373737;\n    width: 95%;\n    height: 24px;\n    line-height: 24px;\n    text-align: left;\n    margin-top: 8px;\n    padding-left: 8px;\n    overflow-wrap: break-word;\n    background-color: white; }\n  .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input {\n    margin-top: 8px;\n    width: 95%;\n    height: 24px;\n    color: #373737;\n    line-height: 24px;\n    padding-left: 8px;\n    background-color: white;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n    align-items: center; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input div {\n      width: 30%;\n      height: 100%;\n      font-size: 16px;\n      text-align: right;\n      padding-right: 8px;\n      background-color: white; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n      display: block;\n      height: 100%;\n      width: 100%;\n      padding-left: 4px;\n      font-family: \"Open Sans\", sans-serif;\n      font-weight: 400;\n      color: #373737;\n      text-align: left;\n      outline: none;\n      border-style: solid;\n      border-width: thin;\n      border-color: #7F7F7F;\n      background-color: white; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-label-input input {\n      width: 50%;\n      font-size: 16px; }\n  .igv-ui-generic-dialog-container .igv-ui-generic-dialog-input {\n    margin-top: 8px;\n    width: calc(100% - 16px);\n    height: 24px;\n    color: #373737;\n    line-height: 24px;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: space-around;
19508\n    align-items: center; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n      display: block;\n      height: 100%;\n      width: 100%;\n      padding-left: 4px;\n      font-family: \"Open Sans\", sans-serif;\n      font-weight: 400;\n      color: #373737;\n      text-align: left;\n      outline: none;\n      border-style: solid;\n      border-width: thin;\n      border-color: #7F7F7F;\n      background-color: white; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-input input {\n      font-size: 16px; }\n  .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel {\n    width: 100%;\n    height: 28px;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: space-around;\n    align-items: center; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div {\n      margin-top: 32px;\n      color: white;\n      font-family: \"Open Sans\", sans-serif;\n      font-size: 14px;\n      font-weight: 400;\n      width: 75px;\n      height: 28px;\n      line-height: 28px;\n      text-align: center;\n      border-color: transparent;\n      border-style: solid;\n      border-width: thin;\n      border-radius: 2px; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child {\n      margin-left: 32px;\n      margin-right: 0;\n      background-color: #5ea4e0; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child {\n      margin-left: 0;\n      margin-right: 32px;\n      background-color: #c4c4c4; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:first-child:hover {\n      cursor: pointer;\n      background-color: #3b5c7f; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok-cancel div:last-child:hover {\n      cursor: pointer;\n      background-color: #7f7f7f; }\n  .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok {\n    width: 100%;\n    height: 36px;\n    margin-top: 32px;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: space-around;\n    align-items: center; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div {\n      width: 98px;\n      height: 36px;\n      line-height: 36px;\n      text-align: center;\n      color: white;\n      font-family: \"Open Sans\", sans-serif;\n      font-size: medium;\n      font-weight: 400;\n      border-color: white;\n      border-style: solid;\n      border-width: thin;\n      border-radius: 4px;\n      background-color: #2B81AF; }\n    .igv-ui-generic-dialog-container .igv-ui-generic-dialog-ok div:hover {\n      cursor: pointer;\n      background-color: #25597f; }\n\n.igv-ui-generic-container {\n  box-sizing: content-box;\n  position: absolute;\n  z-index: 2048;\n  background-color: white;\n  cursor: pointer;\n  display: flex;\n  flex-direction: row;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n  align-items: center; }\n  .igv-ui-generic-container div:first-child {\n    cursor: move;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: flex-end;\n    align-items: center;\n    height: 24px;\n    width: 100%;\n    background-color: #dddddd; }\n    .igv-ui-generic-container div:first-child div {\n      display: block;\n      color: #5f5f5f;\n      cursor: pointer;\n      width: 14px;\n      height: 14px;\n      margin-right: 8px;\n      margin-bottom: 4px; }\n\n.igv-ui-dialog {\n  z-index: 2048;\n  position: fixed;\n  width: fit-content;\n  height: fit-content;\n  display: flex;\n  flex-flow: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  background-color: white;\n  border-color: #7F7F7F;\n  border-radius: 4px;\n  border-style: solid;\n  border-width: thin;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: medium;\n  font-weight: 400; }\n  .igv-ui-dialog .igv-ui-dialog-header {\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: flex-end;\n    align-items: center;\n    width: 100%;\n    height: 24px;\n    cursor: move;\n    border-top-left-radius: 4px;\n    border-top-right-radius: 4px;\n    border-bottom-color: #7F7F7F;\n    border-bottom-style: solid;\n    border-bottom-width: thin;\n    background-color: #eee; }\n    .igv-ui-dialog .igv-ui-dialog-header div {\n      margin-right: 4px;\n      margin-bottom: 2px;\n      height: 12px;\n      width: 12px;\n      color: #7F7F7F; }\n    .igv-ui-dialog .igv-ui-dialog-header div:hover {\n      cursor: pointer;\n      color: #444; }\n  .igv-ui-dialog .igv-ui-dialog-one-liner {\n    width: 95%;\n    height: 24px;\n    line-height: 24px;\n    text-align: left;\n    margin: 8px;\n    overflow-wrap: break-word;\n    background-color: white;\n    font-weight: bold; }\n  .igv-ui-dialog .igv-ui-dialog-ok-cancel {\n    width: 100%;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: space-around;
19508\n    align-items: center; }\n    .igv-ui-dialog .igv-ui-dialog-ok-cancel div {\n      margin: 16px;\n      margin-top: 32px;\n      color: white;\n      font-family: \"Open Sans\", sans-serif;\n      font-size: 14px;\n      font-weight: 400;\n      width: 75px;\n      height: 28px;\n      line-height: 28px;\n      text-align: center;\n      border-color: transparent;\n      border-style: solid;\n      border-width: thin;\n      border-radius: 2px; }\n    .igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child {\n      background-color: #5ea4e0; }\n    .igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child {\n      background-color: #c4c4c4; }\n    .igv-ui-dialog .igv-ui-dialog-ok-cancel div:first-child:hover {\n      cursor: pointer;\n      background-color: #3b5c7f; }\n    .igv-ui-dialog .igv-ui-dialog-ok-cancel div:last-child:hover {\n      cursor: pointer;\n      background-color: #7f7f7f; }\n  .igv-ui-dialog .igv-ui-dialog-ok {\n    width: 100%;\n    height: 36px;\n    margin-top: 32px;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: space-around;\n    align-items: center; }\n    .igv-ui-dialog .igv-ui-dialog-ok div {\n      width: 98px;\n      height: 36px;\n      line-height: 36px;\n      text-align: center;\n      color: white;\n      font-family: \"Open Sans\", sans-serif;\n      font-size: medium;\n      font-weight: 400;\n      border-color: white;\n      border-style: solid;\n      border-width: thin;\n      border-radius: 4px;\n      background-color: #2B81AF; }\n    .igv-ui-dialog .igv-ui-dialog-ok div:hover {\n      cursor: pointer;\n      background-color: #25597f; }\n\n.igv-ui-panel, .igv-ui-panel-column, .igv-ui-panel-row {\n  z-index: 2048;\n  background-color: white;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: medium;\n  font-weight: 400;\n  display: flex;\n  justify-content: flex-start;\n  align-items: flex-start; }\n\n.igv-ui-panel-column {\n  display: flex;\n  flex-direction: column; }\n\n.igv-ui-panel-row {\n  display: flex;\n  flex-direction: row; }\n\n.igv-ui-textbox {\n  background-color: white;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: medium;\n  font-weight: 400;\n  display: flex;\n  justify-content: flex-start;\n  align-items: flex-start; }\n\n/*# sourceMappingURL=igv-ui.css.map */\n';
19509      var style = document.createElement('style');
19510      style.setAttribute('type', 'text/css');
19511      style.innerHTML = css;
19512      document.head.insertBefore(style, document.head.childNodes[document.head.childNodes.length - 1]);
19513    }
19514
19515    if (typeof document !== 'undefined') {
19516      if (!stylesheetExists("igv-ui.css")) {
19517        // console.log('igv-ui. will call embedCSS() ...');
19518        embedCSS$2(); // console.log('... done.');
19519      }
19520
19521      function stylesheetExists(stylesheetName) {
19522        for (let ss of document.styleSheets) {
19523          ss = ss.href ? ss.href.replace(/^.*[\\\/]/, '') : '';
19524
19525          if (ss === stylesheetName) {
19526            return true;
19527          }
19528        }
19529
19530        return false;
19531      }
19532    }
19533
19534    /*
19535     * The MIT License (MIT)
19536     *
19537     * Copyright (c) 2016-2017 The Regents of the University of California
19538     * Author: Jim Robinson
19539     *
19540     * Permission is hereby granted, free of charge, to any person obtaining a copy
19541     * of this software and associated documentation files (the "Software"), to deal
19542     * in the Software without restriction, including without limitation the rights
19543     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19544     * copies of the Software, and to permit persons to whom the Software is
19545     * furnished to do so, subject to the following conditions:
19546     *
19547     * The above copyright notice and this permission notice shall be included in
19548     * all copies or substantial portions of the Software.
19549     *
19550     *
19551     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19552     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19553     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19554     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19555     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19556     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19557     * THE SOFTWARE.
19558     */
19559
19560    class DataRangeDialog {
19561      constructor($parent, alert) {
19562        // dialog container
19563        this.$container = $$1("<div>", {
19564          class: 'igv-generic-dialog-container'
19565        });
19566        $parent.append(this.$container);
19567        this.$container.offset({
19568          left: 0,
19569          top: 0
19570        }); // dialog header
19571
19572        const $header = $$1("<div>", {
19573          class: 'igv-generic-dialog-header'
19574        });
19575        this.$container.append($header);
19576        attachDialogCloseHandlerWithParent$1($header[0], () => {
19577          this.$minimum_input.val(undefined);
19578          this.$maximum_input.val(undefined);
19579          this.$container.offset({
19580            left: 0,
19581            top: 0
19582          });
19583          this.$container.hide();
19584        }); // minimun
19585
19586        this.$minimum = $$1("<div>", {
19587          class: 'igv-generic-dialog-label-input'
19588        });
19589        this.$container.append(this.$minimum);
19590        const $mindiv = $$1('<div>');
19591        $mindiv.text('Minimum');
19592        this.$minimum.append($mindiv);
19593        this.$minimum_input = $$1("<input>");
19594        this.$minimum.append(this.$minimum_input); // maximum
19595
19596        this.$maximum = $$1("<div>", {
19597          class: 'igv-generic-dialog-label-input'
19598        });
19599        this.$container.append(this.$maximum);
19600        const $maxdiv = $$1('<div>');
19601        $maxdiv.text('Maximum');
19602        this.$maximum.append($maxdiv);
19603        this.$maximum_input = $$1("<input>");
19604        this.$maximum.append(this.$maximum_input); // ok | cancel
19605
19606        const $buttons = $$1("<div>", {
19607          class: 'igv-generic-dialog-ok-cancel'
19608        });
19609        this.$container.append($buttons); // ok
19610
19611        this.$ok = $$1("<div>");
19612        $buttons.append(this.$ok);
19613        this.$ok.text('OK'); // cancel
19614
19615        this.$cancel = $$1("<div>");
19616        $buttons.append(this.$cancel);
19617        this.$cancel.text('Cancel');
19618        this.$cancel.on('click', () => {
19619          this.$minimum_input.val(undefined);
19620          this.$maximum_input.val(undefined);
19621          this.$container.offset({
19622            left: 0,
19623            top: 0
19624          });
19625          this.$container.hide();
19626        }); //this.$container.draggable({ handle:$header.get(0) });
19627
19628        makeDraggable$1(this.$container.get(0), $header.get(0));
19629        this.$container.hide();
19630      }
19631
19632      configure(trackView) {
19633        const dataRange = trackView.dataRange();
19634        let min;
19635        let max;
19636
19637        if (dataRange) {
19638          min = dataRange.min;
19639          max = dataRange.max;
19640        } else {
19641          min = 0;
19642          max = 100;
19643        }
19644
19645        this.$minimum_input.val(min);
19646        this.$maximum_input.val(max);
19647        this.$minimum_input.unbind();
19648        this.$minimum_input.on('keyup', e => {
19649          if (13 === e.keyCode) {
19650            this.processResults(trackView);
19651          }
19652        });
19653        this.$maximum_input.unbind();
19654        this.$maximum_input.on('keyup', e => {
19655          if (13 === e.keyCode) {
19656            this.processResults(trackView);
19657          }
19658        });
19659        this.$ok.unbind();
19660        this.$ok.on('click', e => {
19661          this.processResults(trackView);
19662        });
19663      }
19664
19665      processResults(trackView) {
19666        const min = Number(this.$minimum_input.val());
19667        const max = Number(this.$maximum_input.val());
19668
19669        if (isNaN(min) || isNaN(max)) {
19670          Alert.presentAlert(new Error('Must input numeric values'), undefined);
19671        } else {
19672          trackView.setDataRange(min, max);
19673        }
19674
19675        this.$minimum_input.val(undefined);
19676        this.$maximum_input.val(undefined);
19677        this.$container.offset({
19678          left: 0,
19679          top: 0
19680        });
19681        this.$container.hide();
19682      }
19683
19684      present($parent) {
19685        const offset_top = $parent.offset().top;
19686        const scroll_top = $$1('body').scrollTop();
19687        this.$container.offset({
19688          left: $parent.width() - this.$container.width(),
19689          top: offset_top + scroll_top
19690        });
19691        this.$container.show();
19692      }
19693
19694    }
19695
19696    /*
19697     * The MIT License (MIT)
19698     *
19699     * Copyright (c) 2014 Broad Institute
19700     *
19701     * Permission is hereby granted, free of charge, to any person obtaining a copy
19702     * of ctx software and associated documentation files (the "Software"), to deal
19703     * in the Software without restriction, including without limitation the rights
19704     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19705     * copies of the Software, and to permit persons to whom the Software is
19706     * furnished to do so, subject to the following conditions:
19707     *
19708     * The above copyright notice and ctx permission notice shall be included in
19709     * all copies or substantial portions of the Software.
19710     *
19711     *
19712     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19713     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19714     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19715     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19716     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19717     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19718     * THE SOFTWARE.
19719     */
19720
19721    const IGVGraphics = {
19722      configureHighDPICanvas: function (ctx, w, h) {
19723        const scaleFactor = window.devicePixelRatio; // const scaleFactor = 1
19724
19725        ctx.canvas.style.width = `${w}px`;
19726        ctx.canvas.width = Math.floor(scaleFactor * w);
19727        ctx.canvas.style.height = `${h}px`;
19728        ctx.canvas.height = Math.floor(scaleFactor * h);
19729        ctx.scale(scaleFactor, scaleFactor);
19730      },
19731      setProperties: function (ctx, properties) {
19732        for (var key in properties) {
19733          if (properties.hasOwnProperty(key)) {
19734            var value = properties[key];
19735            ctx[key] = value;
19736          }
19737        }
19738      },
19739      strokeLine: function (ctx, x1, y1, x2, y2, properties) {
19740        x1 = Math.floor(x1) + 0.5;
19741        y1 = Math.floor(y1) + 0.5;
19742        x2 = Math.floor(x2) + 0.5;
19743        y2 = Math.floor(y2) + 0.5;
19744
19745        if (properties) {
19746          ctx.save();
19747          IGVGraphics.setProperties(ctx, properties);
19748        }
19749
19750        ctx.beginPath();
19751        ctx.moveTo(x1, y1);
19752        ctx.lineTo(x2, y2);
19753        ctx.stroke();
19754        if (properties) ctx.restore();
19755      },
19756      fillRect: function (ctx, x, y, w, h, properties) {
19757        x = Math.round(x);
19758        y = Math.round(y);
19759
19760        if (properties) {
19761          ctx.save();
19762          IGVGraphics.setProperties(ctx, properties);
19763        }
19764
19765        ctx.fillRect(x, y, w, h);
19766        if (properties) ctx.restore();
19767      },
19768      fillPolygon: function (ctx, x, y, properties) {
19769        if (properties) {
19770          ctx.save();
19771          IGVGraphics.setProperties(ctx, properties);
19772        }
19773
19774        doPath(ctx, x, y);
19775        ctx.fill();
19776        if (properties) ctx.restore();
19777      },
19778      strokePolygon: function (ctx, x, y, properties) {
19779        if (properties) {
19780          ctx.save();
19781          IGVGraphics.setProperties(ctx, properties);
19782        }
19783
19784        doPath(ctx, x, y);
19785        ctx.stroke();
19786        if (properties) ctx.restore();
19787      },
19788      fillText: function (ctx, text, x, y, properties, transforms) {
19789        if (properties || transforms) {
19790          ctx.save();
19791        }
19792
19793        if (properties) {
19794          IGVGraphics.setProperties(ctx, properties);
19795        }
19796
19797        if (transforms) {
19798          // Slow path with context saving and extra translate
19799          ctx.translate(x, y);
19800
19801          for (var transform in transforms) {
19802            var value = transforms[transform]; // TODO: Add error checking for robustness
19803
19804            if (transform === 'translate') {
19805              ctx.translate(value['x'], value['y']);
19806            }
19807
19808            if (transform === 'rotate') {
19809              ctx.rotate(value['angle'] * Math.PI / 180);
19810            }
19811          }
19812
19813          ctx.fillText(text, 0, 0);
19814        } else {
19815          ctx.fillText(text, x, y);
19816        }
19817
19818        if (properties || transforms) ctx.restore();
19819      },
19820      strokeText: function (ctx, text, x, y, properties, transforms) {
19821        if (properties || transforms) {
19822          ctx.save();
19823        }
19824
19825        if (properties) {
19826          IGVGraphics.setProperties(ctx, properties);
19827        }
19828
19829        if (transforms) {
19830          ctx.translate(x, y);
19831
19832          for (var transform in transforms) {
19833            var value = transforms[transform]; // TODO: Add error checking for robustness
19834
19835            if (transform === 'translate') {
19836              ctx.translate(value['x'], value['y']);
19837            }
19838
19839            if (transform === 'rotate') {
19840              ctx.rotate(value['angle'] * Math.PI / 180);
19841            }
19842          }
19843
19844          ctx.strokeText(text, 0, 0);
19845        } else {
19846          ctx.strokeText(text, x, y);
19847        }
19848
19849        if (properties || transforms) ctx.restore();
19850      },
19851      strokeCircle: function (ctx, x, y, radius, properties) {
19852        if (properties) {
19853          ctx.save();
19854          IGVGraphics.setProperties(ctx, properties);
19855        }
19856
19857        ctx.beginPath();
19858        ctx.arc(x, y, radius, 0, 2 * Math.PI);
19859        ctx.stroke();
19860        if (properties) ctx.restore();
19861      },
19862      fillCircle: function (ctx, x, y, radius, properties) {
19863        if (properties) {
19864          ctx.save();
19865          IGVGraphics.setProperties(ctx, properties);
19866        }
19867
19868        ctx.beginPath();
19869        ctx.arc(x, y, radius, 0, 2 * Math.PI);
19870        ctx.fill();
19871        if (properties) ctx.restore();
19872      },
19873      drawArrowhead: function (ctx, x, y, size, lineWidth) {
19874        ctx.save();
19875
19876        if (!size) {
19877          size = 5;
19878        }
19879
19880        if (lineWidth) {
19881          ctx.lineWidth = lineWidth;
19882        }
19883
19884        ctx.beginPath();
19885        ctx.moveTo(x, y - size / 2);
19886        ctx.lineTo(x, y + size / 2);
19887        ctx.lineTo(x + size, y);
19888        ctx.lineTo(x, y - size / 2);
19889        ctx.closePath();
19890        ctx.fill();
19891        ctx.restore();
19892      },
19893      dashedLine: function (ctx, x1, y1, x2, y2, dashLen) {
19894        let properties = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {};
19895        if (dashLen === undefined) dashLen = 2;
19896        ctx.setLineDash([dashLen, dashLen]);
19897        IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, properties);
19898        ctx.setLineDash([]);
19899      },
19900      roundRect: function (ctx, x, y, width, height, radius, fill, stroke) {
19901        if (typeof stroke == "undefined") {
19902          stroke = true;
19903        }
19904
19905        if (typeof radius === "undefined") {
19906          radius = 5;
19907        }
19908
19909        ctx.beginPath();
19910        ctx.moveTo(x + radius, y);
19911        ctx.lineTo(x + width - radius, y);
19912        ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
19913        ctx.lineTo(x + width, y + height - radius);
19914        ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
19915        ctx.lineTo(x + radius, y + height);
19916        ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
19917        ctx.lineTo(x, y + radius);
19918        ctx.quadraticCurveTo(x, y, x + radius, y);
19919        ctx.closePath();
19920
19921        if (stroke) {
19922          ctx.stroke();
19923        }
19924
19925        if (fill) {
19926          ctx.fill();
19927        }
19928      },
19929      polygon: function (ctx, x, y, fill, stroke) {
19930        if (typeof stroke == "undefined") {
19931          stroke = true;
19932        }
19933
19934        ctx.beginPath();
19935        var len = x.length;
19936        ctx.moveTo(x[0], y[0]);
19937
19938        for (var i = 1; i < len; i++) {
19939          ctx.lineTo(x[i], y[i]); // this.moveTo(x[i], y[i]);
19940        }
19941
19942        ctx.closePath();
19943
19944        if (stroke) {
19945          ctx.stroke();
19946        }
19947
19948        if (fill) {
19949          ctx.fill();
19950        }
19951      }
19952    };
19953
19954    function doPath(ctx, x, y) {
19955      var i,
19956          len = x.length;
19957
19958      for (i = 0; i < len; i++) {
19959        x[i] = Math.round(x[i]);
19960        y[i] = Math.round(y[i]);
19961      }
19962
19963      ctx.beginPath();
19964      ctx.moveTo(x[0], y[0]);
19965
19966      for (i = 1; i < len; i++) {
19967        ctx.lineTo(x[i], y[i]);
19968      }
19969
19970      ctx.closePath();
19971    }
19972
19973    const FileFormats = {
19974      gwascatalog: {
19975        fields: ['bin', 'chr', 'start', 'end', 'name', 'pubMedID', 'author', 'pubDate', 'journal', 'title', 'trait', 'initSample', 'replSample', 'region', 'genes', 'riskAllele', 'riskAlFreq', 'pValue', 'pValueDesc', 'orOrBeta', 'ci95', 'platform', 'cnv']
19976      },
19977      wgrna: {
19978        fields: ['bin', 'chr', 'start', 'end', 'name', 'score', 'strand', 'thickStart', 'thickEnd', 'type']
19979      },
19980      cpgislandext: {
19981        fields: ['bin', 'chr', 'start', 'end', 'name', 'length', 'cpgNum', 'gcNum', 'perCpg', 'perGc', 'obsExp']
19982      },
19983      clinVarMain: {
19984        fields: ['chr1', 'start', 'end', 'name', 'score', 'strand', 'thickStart', 'thickEnd', 'reserved', 'blockCount', // Number of blocks
19985        'blockSizes', // Comma separated list of block sizes
19986        'chromStarts', // Start positions relative to chromStart
19987        'origName', // NM_198053.2(CD247):c.462C>T (p.Asp154=)	ClinVar Variation Report
19988        'clinSign', // Likely benign	Clinical significance
19989        'reviewStatus', // 	based on: criteria provided,single submitter	Review Status
19990        'type', // single nucleotide variant	Type of Variant
19991        'geneId', // CD247	Gene Symbol
19992        'snpId', //	181656780	dbSNP ID
19993        'nsvId', //		dbVar ID
19994        'rcvAcc', //	RCV000642347	ClinVar Allele Submission
19995        'testedInGtr', //	N	Genetic Testing Registry
19996        'phenotypeList', //	Immunodeficiency due to defect in cd3-zeta	Phenotypes
19997        'phenotype', //	MedGen:C1857798, OMIM:610163	Phenotype identifiers
19998        'origin', //	germline	Data origin
19999        'assembly', //	GRCh37	Genome assembly
20000        'cytogenetic', //	1q24.2	Cytogenetic status
20001        'hgvsCod', //	NM_198053.2:c.462C>T	Nucleotide HGVS
20002        'hgvsProt', //	NP_932170.1:p.Asp154=	Protein HGVS
20003        'numSubmit', //	1	Number of submitters
20004        'lastEval', //	Dec 19,2017	Last evaluation
20005        'guidelines', //		Guidelines
20006        'otherIds']
20007      }
20008    };
20009
20010    /*
20011     * The MIT License (MIT)
20012     *
20013     * Copyright (c) 2014 Broad Institute
20014     *
20015     * Permission is hereby granted, free of charge, to any person obtaining a copy
20016     * of this software and associated documentation files (the "Software"), to deal
20017     * in the Software without restriction, including without limitation the rights
20018     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20019     * copies of the Software, and to permit persons to whom the Software is
20020     * furnished to do so, subject to the following conditions:
20021     *
20022     * The above copyright notice and this permission notice shall be included in
20023     * all copies or substantial portions of the Software.
20024     *
20025     *
20026     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20027     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20028     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20029     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20030     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20031     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20032     * THE SOFTWARE.
20033     */
20034    const knownFileExtensions = new Set(["narrowpeak", "broadpeak", "regionpeak", "peaks", "bedgraph", "wig", "gff3", "gff", "gtf", "fusionjuncspan", "refflat", "seg", "aed", "bed", "vcf", "bb", "bigbed", "bw", "bigwig", "bam", "tdf", "refgene", "genepred", "genepredext", "bedpe", "bp", "snp", "rmsk", "cram", "gwas", "maf", "mut"]);
20035    /**
20036     * Return a custom format object with the given name.
20037     * @param name
20038     * @returns {*}
20039     */
20040
20041    function getFormat(name) {
20042      if (FileFormats && FileFormats[name]) {
20043        return expandFormat(FileFormats[name]);
20044      } else {
20045        return undefined;
20046      }
20047
20048      function expandFormat(format) {
20049        const fields = format.fields;
20050        const keys = ['chr', 'start', 'end'];
20051
20052        for (let i = 0; i < fields.length; i++) {
20053          for (let key of keys) {
20054            if (key === fields[i]) {
20055              format[key] = i;
20056            }
20057          }
20058        }
20059
20060        return format;
20061      }
20062    }
20063
20064    function inferFileFormat(fn) {
20065      var idx, ext;
20066      fn = fn.toLowerCase(); // Special case -- UCSC refgene files
20067
20068      if (fn.endsWith("refgene.txt.gz") || fn.endsWith("refgene.txt.bgz") || fn.endsWith("refgene.txt") || fn.endsWith("refgene.sorted.txt.gz") || fn.endsWith("refgene.sorted.txt.bgz")) {
20069        return "refgene";
20070      } //Strip parameters -- handle local files later
20071
20072
20073      idx = fn.indexOf("?");
20074
20075      if (idx > 0) {
20076        fn = fn.substr(0, idx);
20077      } //Strip aux extensions .gz, .tab, and .txt
20078
20079
20080      if (fn.endsWith(".gz")) {
20081        fn = fn.substr(0, fn.length - 3);
20082      }
20083
20084      if (fn.endsWith(".txt") || fn.endsWith(".tab") || fn.endsWith(".bgz")) {
20085        fn = fn.substr(0, fn.length - 4);
20086      }
20087
20088      idx = fn.lastIndexOf(".");
20089      ext = idx < 0 ? fn : fn.substr(idx + 1);
20090
20091      switch (ext) {
20092        case "bw":
20093          return "bigwig";
20094
20095        case "bb":
20096          return "bigbed";
20097
20098        default:
20099          if (knownFileExtensions.has(ext)) {
20100            return ext;
20101          } else {
20102            return undefined;
20103          }
20104
20105      }
20106    }
20107
20108    function inferIndexPath(url, extension) {
20109      if (isString$3(url)) {
20110        if (url.includes("?")) {
20111          const idx = url.indexOf("?");
20112          return url.substring(0, idx) + "." + extension + url.substring(idx);
20113        } else {
20114          return url + "." + extension;
20115        }
20116      } else {
20117        return undefined;
20118      }
20119    }
20120
20121    function inferTrackType(config) {
20122      translateDeprecatedTypes(config);
20123
20124      if (config.type) {
20125        return config.type;
20126      }
20127
20128      if (config.format) {
20129        const format = config.format.toLowerCase();
20130
20131        switch (format) {
20132          case "bw":
20133          case "bigwig":
20134          case "wig":
20135          case "bedgraph":
20136          case "tdf":
20137            return "wig";
20138
20139          case "vcf":
20140            return "variant";
20141
20142          case "seg":
20143            return "seg";
20144
20145          case "mut":
20146          case "maf":
20147            return "mut";
20148
20149          case "bam":
20150          case "cram":
20151            return "alignment";
20152
20153          case "bedpe":
20154          case "bedpe-loop":
20155            return "interact";
20156
20157          case "bp":
20158            return "arc";
20159
20160          case "gwas":
20161            return "gwas";
20162
20163          case "bed":
20164          case "bigbed":
20165          case "bb":
20166            return "bedtype";
20167
20168          default:
20169            return "annotation";
20170        }
20171      }
20172    }
20173
20174    function translateDeprecatedTypes(config) {
20175      if (config.featureType) {
20176        // Translate deprecated "feature" type
20177        config.type = config.type || config.featureType;
20178        config.featureType = undefined;
20179      }
20180
20181      if ("junctions" === config.type) {
20182        config.type = "junction";
20183      } else if ("bed" === config.type) {
20184        config.type = "annotation";
20185        config.format = config.format || "bed";
20186      } else if ("annotations" === config.type) {
20187        config.type = "annotation";
20188      } else if ("alignments" === config.type) {
20189        config.type = "alignment";
20190      } else if ("bam" === config.type) {
20191        config.type = "alignment";
20192        config.format = "bam";
20193      } else if ("vcf" === config.type) {
20194        config.type = "variant";
20195        config.format = "vcf";
20196      } else if ("t2d" === config.type) {
20197        config.type = "gwas";
20198      } else if ("FusionJuncSpan" === config.type && !config.format) {
20199        config.format = "fusionjuncspan";
20200      } else if ("aed" === config.type) {
20201        config.type = "annotation";
20202        config.format = config.format || "aed";
20203      }
20204    }
20205
20206    /*
20207     * The MIT License (MIT)
20208     *
20209     * Copyright (c) 2014 Broad Institute
20210     *
20211     * Permission is hereby granted, free of charge, to any person obtaining a copy
20212     * of this software and associated documentation files (the "Software"), to deal
20213     * in the Software without restriction, including without limitation the rights
20214     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20215     * copies of the Software, and to permit persons to whom the Software is
20216     * furnished to do so, subject to the following conditions:
20217     *
20218     * The above copyright notice and this permission notice shall be included in
20219     * all copies or substantial portions of the Software.
20220     *
20221     *
20222     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20223     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20224     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20225     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20226     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20227     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20228     * THE SOFTWARE.
20229     */
20230    const defaultSequenceTrackOrder = Number.MIN_SAFE_INTEGER;
20231    const translationDict = {
20232      'TTT': 'F',
20233      'TTC': 'F',
20234      'TTA': 'L',
20235      'TTG': 'L',
20236      'CTT': 'L',
20237      'CTC': 'L',
20238      'CTA': 'L',
20239      'CTG': 'L',
20240      'ATT': 'I',
20241      'ATC': 'I',
20242      'ATA': 'I',
20243      'ATG': 'M',
20244      'GTT': 'V',
20245      'GTC': 'V',
20246      'GTA': 'V',
20247      'GTG': 'V',
20248      'TCT': 'S',
20249      'TCC': 'S',
20250      'TCA': 'S',
20251      'TCG': 'S',
20252      'CCT': 'P',
20253      'CCC': 'P',
20254      'CCA': 'P',
20255      'CCG': 'P',
20256      'ACT': 'T',
20257      'ACC': 'T',
20258      'ACA': 'T',
20259      'ACG': 'T',
20260      'GCT': 'A',
20261      'GCC': 'A',
20262      'GCA': 'A',
20263      'GCG': 'A',
20264      'TAT': 'Y',
20265      'TAC': 'Y',
20266      'TAA': 'STOP',
20267      'TAG': 'STOP',
20268      'CAT': 'H',
20269      'CAC': 'H',
20270      'CAA': 'Q',
20271      'CAG': 'Q',
20272      'AAT': 'N',
20273      'AAC': 'N',
20274      'AAA': 'K',
20275      'AAG': 'K',
20276      'GAT': 'D',
20277      'GAC': 'D',
20278      'GAA': 'E',
20279      'GAG': 'E',
20280      'TGT': 'C',
20281      'TGC': 'C',
20282      'TGA': 'STOP',
20283      'TGG': 'W',
20284      'CGT': 'R',
20285      'CGC': 'R',
20286      'CGA': 'R',
20287      'CGG': 'R',
20288      'AGT': 'S',
20289      'AGC': 'S',
20290      'AGA': 'R',
20291      'AGG': 'R',
20292      'GGT': 'G',
20293      'GGC': 'G',
20294      'GGA': 'G',
20295      'GGG': 'G'
20296    };
20297    const complement = {};
20298    const t1 = ['A', 'G', 'C', 'T', 'Y', 'R', 'W', 'S', 'K', 'M', 'D', 'V', 'H', 'B', 'N', 'X'];
20299    const t2 = ['T', 'C', 'G', 'A', 'R', 'Y', 'W', 'S', 'M', 'K', 'H', 'B', 'D', 'V', 'N', 'X'];
20300
20301    for (let i = 0; i < t1.length; i++) {
20302      complement[t1[i]] = t2[i];
20303      complement[t1[i].toLowerCase()] = t2[i].toLowerCase();
20304    }
20305
20306    class SequenceTrack {
20307      constructor(config, browser) {
20308        this.type = "sequence";
20309        this.browser = browser;
20310        this.removable = false;
20311        this.config = config;
20312        this.name = "Sequence";
20313        this.id = "sequence";
20314        this.sequenceType = config.sequenceType || "dna"; //   dna | rna | prot
20315
20316        this.height = 25;
20317        this.disableButtons = false;
20318        this.order = config.order || defaultSequenceTrackOrder;
20319        this.ignoreTrackMenu = false;
20320        this.reversed = false;
20321        this.frameTranslate = false;
20322      }
20323
20324      menuItemList() {
20325        return [{
20326          name: this.reversed ? "Forward" : "Reverse",
20327          click: () => {
20328            this.reversed = !this.reversed;
20329            this.trackView.repaintViews();
20330          }
20331        }, {
20332          name: this.frameTranslate ? "Close Translation" : "Three-frame Translate",
20333          click: () => {
20334            this.frameTranslate = !this.frameTranslate;
20335
20336            if (this.frameTranslate) {
20337              for (let vp of this.trackView.viewports) {
20338                vp.setContentHeight(115);
20339              }
20340
20341              this.trackView.setTrackHeight(115);
20342            } else {
20343              for (let vp of this.trackView.viewports) {
20344                vp.setContentHeight(25);
20345              }
20346
20347              this.trackView.setTrackHeight(25);
20348            }
20349
20350            this.trackView.repaintViews();
20351          }
20352        }];
20353      }
20354
20355      contextMenuItemList(clickState) {
20356        const viewport = clickState.viewport;
20357
20358        if (viewport.referenceFrame.bpPerPixel <= 1) {
20359          const items = [{
20360            label: 'View visible sequence...',
20361            click: async () => {
20362              const pixelWidth = viewport.getWidth();
20363              const bpWindow = pixelWidth * viewport.referenceFrame.bpPerPixel;
20364              const chr = viewport.referenceFrame.chr;
20365              const start = viewport.referenceFrame.start;
20366              const end = start + bpWindow;
20367              const sequence = await this.browser.genome.sequence.getSequence(chr, start, end);
20368              Alert.presentAlert(sequence);
20369            }
20370          }];
20371
20372          if (isSecureContext()) {
20373            items.push({
20374              label: 'Copy visible sequence',
20375              click: async () => {
20376                const pixelWidth = viewport.getWidth();
20377                const bpWindow = pixelWidth * viewport.referenceFrame.bpPerPixel;
20378                const chr = viewport.referenceFrame.chr;
20379                const start = viewport.referenceFrame.start;
20380                const end = start + bpWindow;
20381                const sequence = await this.browser.genome.sequence.getSequence(chr, start, end);
20382                navigator.clipboard.writeText(sequence);
20383              }
20384            });
20385          }
20386
20387          items.push('<hr/>');
20388          return items;
20389        } else {
20390          return undefined;
20391        }
20392      }
20393
20394      translateSequence(seq) {
20395        const threeFrame = [[], [], []];
20396
20397        for (let fNum of [0, 1, 2]) {
20398          let idx = fNum;
20399
20400          while (seq.length - idx >= 3) {
20401            let st = seq.slice(idx, idx + 3);
20402
20403            if (this.reversed) {
20404              st = st.split('').reverse().join('');
20405            }
20406
20407            const aa = translationDict[st.toUpperCase()] || "";
20408            threeFrame[fNum].push({
20409              codons: st,
20410              aminoA: aa
20411            });
20412            idx += 3;
20413          }
20414        }
20415
20416        return threeFrame;
20417      }
20418
20419      async getFeatures(chr, start, end, bpPerPixel) {
20420        if (bpPerPixel && bpPerPixel > 1) {
20421          return null;
20422        } else {
20423          const sequence = await this.browser.genome.sequence.getSequence(chr, start, end);
20424          return {
20425            bpStart: start,
20426            sequence: sequence
20427          };
20428        }
20429      }
20430
20431      draw(options) {
20432        const ctx = options.context;
20433
20434        if (options.features) {
20435          const sequence = options.features.sequence;
20436          const sequenceBpStart = options.features.bpStart;
20437          const bpEnd = 1 + options.bpStart + options.pixelWidth * options.bpPerPixel;
20438          let height = 15;
20439
20440          for (let bp = sequenceBpStart; bp <= bpEnd; bp++) {
20441            let seqOffsetBp = Math.floor(bp - sequenceBpStart);
20442
20443            if (seqOffsetBp < sequence.length) {
20444              let letter = sequence[seqOffsetBp];
20445
20446              if (this.reversed) {
20447                letter = complement[letter] || "";
20448              }
20449
20450              let offsetBP = bp - options.bpStart;
20451              let aPixel = offsetBP / options.bpPerPixel;
20452              let bPixel = (offsetBP + 1) / options.bpPerPixel;
20453              let color = this.fillColor(letter); // IGVGraphics.fillRect(ctx, aPixel, 5, bPixel - aPixel, height - 5, { fillStyle: randomRGBConstantAlpha(150, 255, 0.75) });
20454
20455              if (options.bpPerPixel > 1 / 10) {
20456                IGVGraphics.fillRect(ctx, aPixel, 5, bPixel - aPixel, height - 5, {
20457                  fillStyle: color
20458                });
20459              } else {
20460                let xPixel = 0.5 * (aPixel + bPixel - ctx.measureText(letter).width);
20461                IGVGraphics.strokeText(ctx, letter, xPixel, height, {
20462                  strokeStyle: color
20463                });
20464              }
20465            }
20466          }
20467
20468          if (this.frameTranslate) {
20469            let transSeq;
20470
20471            if (this.reversed) {
20472              transSeq = sequence.split('').map(function (cv) {
20473                return complement[cv];
20474              });
20475              transSeq = transSeq.join('');
20476            } else {
20477              transSeq = sequence;
20478            }
20479
20480            let y = height;
20481            let translatedSequence = this.translateSequence(transSeq);
20482
20483            for (let arr of translatedSequence) {
20484              let i = translatedSequence.indexOf(arr);
20485              let fNum = i;
20486              let h = 25;
20487              y = i === 0 ? y + 10 : y + 30; //Little less room at first.
20488
20489              for (let cv of arr) {
20490                let aaS;
20491                let idx = arr.indexOf(cv);
20492                let xSeed = idx + fNum + 2 * idx;
20493                let color = 0 === idx % 2 ? 'rgb(160,160,160)' : 'rgb(224,224,224)';
20494                let p0 = Math.floor(xSeed / options.bpPerPixel);
20495                let p1 = Math.floor((xSeed + 3) / options.bpPerPixel);
20496                let pc = Math.round((p0 + p1) / 2);
20497
20498                if (cv.aminoA.indexOf('STOP') > -1) {
20499                  color = 'rgb(255, 0, 0)';
20500                  aaS = 'STOP'; //Color blind accessible
20501                } else {
20502                  aaS = cv.aminoA;
20503                }
20504
20505                if (cv.aminoA === 'M') {
20506                  color = 'rgb(0, 153, 0)';
20507                  aaS = 'START'; //Color blind accessible
20508                }
20509
20510                IGVGraphics.fillRect(ctx, p0, y, p1 - p0, h, {
20511                  fillStyle: color
20512                });
20513
20514                if (options.bpPerPixel <= 1 / 10) {
20515                  IGVGraphics.strokeText(ctx, aaS, pc - ctx.measureText(aaS).width / 2, y + 15);
20516                }
20517              }
20518            }
20519          }
20520        }
20521      }
20522
20523      supportsWholeGenome() {
20524        return false;
20525      }
20526
20527      computePixelHeight(ignore) {
20528        return this.height;
20529      }
20530
20531      fillColor(index) {
20532        if (this.color) {
20533          return this.color;
20534        } else if ("dna" === this.sequenceType) {
20535          return this.browser.nucleotideColors[index] || 'gray';
20536        } else {
20537          return 'rgb(0, 0, 150)';
20538        }
20539      }
20540
20541    }
20542
20543    /*
20544     * The MIT License (MIT)
20545     *
20546     * Copyright (c) 2014 Broad Institute
20547     *
20548     * Permission is hereby granted, free of charge, to any person obtaining a copy
20549     * of this software and associated documentation files (the "Software"), to deal
20550     * in the Software without restriction, including without limitation the rights
20551     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20552     * copies of the Software, and to permit persons to whom the Software is
20553     * furnished to do so, subject to the following conditions:
20554     *
20555     * The above copyright notice and this permission notice shall be included in
20556     * all copies or substantial portions of the Software.
20557     *
20558     *
20559     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20560     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20561     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20562     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20563     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20564     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20565     * THE SOFTWARE.
20566     */
20567
20568    class Viewport {
20569      constructor(trackView, viewportColumn, referenceFrame, width) {
20570        this.guid = guid$1();
20571        this.trackView = trackView;
20572        this.referenceFrame = referenceFrame;
20573        this.browser = trackView.browser;
20574        this.$viewport = $$1('<div class="igv-viewport">');
20575        viewportColumn.appendChild(this.$viewport.get(0));
20576
20577        if (trackView.track.height) {
20578          this.$viewport.get(0).style.height = `${trackView.track.height}px`;
20579        } // Create an alert dialog for the sequence track to copy ref sequence to.
20580
20581
20582        if (trackView.track instanceof SequenceTrack) {
20583          this.alert = new AlertDialog(this.$viewport.get(0));
20584        }
20585
20586        this.$content = $$1("<div>", {
20587          class: 'igv-viewport-content'
20588        });
20589        this.$viewport.append(this.$content);
20590        this.$content.height(this.$viewport.height());
20591        this.contentDiv = this.$content.get(0);
20592        this.$canvas = $$1('<canvas>');
20593        this.$content.append(this.$canvas);
20594        this.canvas = this.$canvas.get(0);
20595        this.ctx = this.canvas.getContext("2d");
20596        this.setWidth(width);
20597        this.initializationHelper();
20598      }
20599
20600      initializationHelper() {}
20601
20602      showMessage(message) {
20603        if (!this.messageDiv) {
20604          this.messageDiv = document.createElement('div');
20605          this.messageDiv.className = 'igv-viewport-message';
20606          this.contentDiv.append(this.messageDiv);
20607        }
20608
20609        this.messageDiv.textContent = message;
20610        this.messageDiv.style.display = 'inline-block';
20611      }
20612
20613      hideMessage(message) {
20614        if (this.messageDiv) this.messageDiv.style.display = 'none';
20615      }
20616
20617      setTrackLabel(label) {}
20618
20619      startSpinner() {}
20620
20621      stopSpinner() {}
20622
20623      checkZoomIn() {
20624        return true;
20625      }
20626
20627      shift() {}
20628
20629      setTop(contentTop) {
20630        const viewportHeight = this.$viewport.height();
20631        const viewTop = -contentTop;
20632        const viewBottom = viewTop + viewportHeight;
20633        this.$content.css('top', `${contentTop}px`);
20634
20635        if (undefined === this.canvasVerticalRange || this.canvasVerticalRange.bottom < viewBottom || this.canvasVerticalRange.top > viewTop) {
20636          this.repaint();
20637        }
20638      }
20639
20640      async loadFeatures() {
20641        return undefined;
20642      }
20643
20644      async repaint() {
20645        console.log('Viewport - repaint()');
20646      }
20647
20648      draw(drawConfiguration, features, roiFeatures) {
20649        console.log('Viewport - draw(drawConfiguration, features, roiFeatures)');
20650      }
20651
20652      checkContentHeight() {
20653        let track = this.trackView.track;
20654
20655        if ("FILL" === track.displayMode) {
20656          this.setContentHeight(this.$viewport.height());
20657        } else if (typeof track.computePixelHeight === 'function') {
20658          let features = this.cachedFeatures;
20659
20660          if (features && features.length > 0) {
20661            let requiredContentHeight = track.computePixelHeight(features);
20662            let currentContentHeight = this.$content.height();
20663
20664            if (requiredContentHeight !== currentContentHeight) {
20665              this.setContentHeight(requiredContentHeight);
20666            }
20667          }
20668        }
20669      }
20670
20671      getContentHeight() {
20672        return this.$content.height();
20673      }
20674
20675      setContentHeight(contentHeight) {
20676        // Maximum height of a canvas is ~32,000 pixels on Chrome, possibly smaller on other platforms
20677        contentHeight = Math.min(contentHeight, 32000);
20678        this.$content.height(contentHeight);
20679        if (this.tile) this.tile.invalidate = true;
20680      }
20681
20682      isLoading() {
20683        return false;
20684      }
20685
20686      saveSVG() {}
20687
20688      isVisible() {
20689        return this.$viewport.width();
20690      }
20691
20692      setWidth(width) {
20693        this.$viewport.width(width);
20694        this.canvas.style.width = `${width}px`;
20695        this.canvas.setAttribute('width', width);
20696      }
20697
20698      getWidth() {
20699        return this.$viewport.width();
20700      }
20701
20702      getContentTop() {
20703        return this.contentDiv.offsetTop;
20704      }
20705
20706      containsPosition(chr, position) {
20707        console.log('Viewport - containsPosition(chr, position)');
20708      }
20709
20710      addMouseHandlers() {}
20711
20712      removeMouseHandlers() {}
20713      /**
20714       * Called when the associated track is removed.  Do any needed cleanup here.
20715       */
20716
20717
20718      dispose() {
20719        if (this.popover) {
20720          this.popover.dispose();
20721        }
20722
20723        this.removeMouseHandlers();
20724        this.$viewport.get(0).remove(); // Null out all properties -- this should not be neccessary, but just in case there is a
20725        // reference to self somewhere we want to free memory.
20726
20727        for (let key of Object.keys(this)) {
20728          this[key] = undefined;
20729        }
20730      }
20731
20732    }
20733
20734    /*!!
20735     *  Canvas 2 Svg v1.0.19
20736     *  A low level canvas to SVG converter. Uses a mock canvas context to build an SVG document.
20737     *
20738     *  Licensed under the MIT license:
20739     *  http://www.opensource.org/licenses/mit-license.php
20740     *
20741     *  Author:
20742     *  Kerry Liu
20743     *
20744     *  Copyright (c) 2014 Gliffy Inc.
20745     */
20746
20747    function format(str, args) {
20748      var keys = Object.keys(args),
20749          i;
20750
20751      for (i = 0; i < keys.length; i++) {
20752        str = str.replace(new RegExp("\\{" + keys[i] + "\\}", "gi"), args[keys[i]]);
20753      }
20754
20755      return str;
20756    } //helper function that generates a random string
20757
20758
20759    function randomString(holder) {
20760      var chars, randomstring, i;
20761
20762      if (!holder) {
20763        throw new Error("cannot create a random attribute name for an undefined object");
20764      }
20765
20766      chars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
20767      randomstring = "";
20768
20769      do {
20770        randomstring = "";
20771
20772        for (i = 0; i < 12; i++) {
20773          randomstring += chars[Math.floor(Math.random() * chars.length)];
20774        }
20775      } while (holder[randomstring]);
20776
20777      return randomstring;
20778    } //helper function to map named to numbered entities
20779
20780
20781    function createNamedToNumberedLookup(items, radix) {
20782      var i,
20783          entity,
20784          lookup = {},
20785          base10;
20786      items = items.split(',');
20787      radix = radix || 10; // Map from named to numbered entities.
20788
20789      for (i = 0; i < items.length; i += 2) {
20790        entity = '&' + items[i + 1] + ';';
20791        base10 = parseInt(items[i], radix);
20792        lookup[entity] = '&#' + base10 + ';';
20793      } //FF and IE need to create a regex from hex values ie &nbsp; == \xa0
20794
20795
20796      lookup["\\xa0"] = '&#160;';
20797      return lookup;
20798    } //helper function to map canvas-textAlign to svg-textAnchor
20799
20800
20801    function getTextAnchor(textAlign) {
20802      //TODO: support rtl languages
20803      var mapping = {
20804        "left": "start",
20805        "right": "end",
20806        "center": "middle",
20807        "start": "start",
20808        "end": "end"
20809      };
20810      return mapping[textAlign] || mapping.start;
20811    } //helper function to map canvas-textBaseline to svg-dominantBaseline
20812
20813
20814    function getDominantBaseline(textBaseline) {
20815      //INFO: not supported in all browsers
20816      var mapping = {
20817        "alphabetic": "alphabetic",
20818        "hanging": "hanging",
20819        "top": "text-before-edge",
20820        "bottom": "text-after-edge",
20821        "middle": "central"
20822      };
20823      return mapping[textBaseline] || mapping.alphabetic;
20824    }
20825    /**
20826     * Return a new normalized vector of given vector
20827     */
20828
20829
20830    function normalize$1(vector) {
20831      var len = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
20832      return [vector[0] / len, vector[1] / len];
20833    }
20834
20835    function intersectRect(rect1, rect2) {
20836      return rect1.x < rect2.x + rect2.width && rect1.x + rect1.width > rect2.x && rect1.y < rect2.y + rect2.height && rect1.y + rect1.height > rect2.y;
20837    } // Unpack entities lookup where the numbers are in radix 32 to reduce the size
20838    // entity mapping courtesy of tinymce
20839
20840
20841    const namedEntities = createNamedToNumberedLookup('50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8
20841k4,' + 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' + 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' + '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' + '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32); //Some basic mappings for attributes and default values.
20842
20843    const STYLES = {
20844      "strokeStyle": {
20845        svgAttr: "stroke",
20846        //corresponding svg attribute
20847        canvas: "#000000",
20848        //canvas default
20849        svg: "none",
20850        //svg default
20851        apply: "stroke" //apply on stroke() or fill()
20852
20853      },
20854      "fillStyle": {
20855        svgAttr: "fill",
20856        canvas: "#000000",
20857        svg: null,
20858        //svg default is black, but we need to special case this to handle canvas stroke without fill
20859        apply: "fill"
20860      },
20861      "lineCap": {
20862        svgAttr: "stroke-linecap",
20863        canvas: "butt",
20864        svg: "butt",
20865        apply: "stroke"
20866      },
20867      "lineJoin": {
20868        svgAttr: "stroke-linejoin",
20869        canvas: "miter",
20870        svg: "miter",
20871        apply: "stroke"
20872      },
20873      "miterLimit": {
20874        svgAttr: "stroke-miterlimit",
20875        canvas: 10,
20876        svg: 4,
20877        apply: "stroke"
20878      },
20879      "lineWidth": {
20880        svgAttr: "stroke-width",
20881        canvas: 1,
20882        svg: 1,
20883        apply: "stroke"
20884      },
20885      "globalAlpha": {
20886        svgAttr: "opacity",
20887        canvas: 1,
20888        svg: 1,
20889        apply: "fill stroke"
20890      },
20891      "font": {
20892        //font converts to multiple svg attributes, there is custom logic for this
20893        canvas: "10px sans-serif"
20894      },
20895      "shadowColor": {
20896        canvas: "#000000"
20897      },
20898      "shadowOffsetX": {
20899        canvas: 0
20900      },
20901      "shadowOffsetY": {
20902        canvas: 0
20903      },
20904      "shadowBlur": {
20905        canvas: 0
20906      },
20907      "textAlign": {
20908        canvas: "start"
20909      },
20910      "textBaseline": {
20911        canvas: "alphabetic"
20912      },
20913      "lineDash": {
20914        svgAttr: "stroke-dasharray",
20915        canvas: [],
20916        svg: null,
20917        apply: "stroke"
20918      }
20919    };
20920    /**
20921     *
20922     * @param gradientNode - reference to the gradient
20923     * @constructor
20924     */
20925
20926    class CanvasGradient {
20927      constructor(gradientNode, ctx) {
20928        this.__root = gradientNode;
20929        this.__ctx = ctx;
20930      }
20931      /**
20932       * Adds a color stop to the gradient root
20933       */
20934
20935
20936      addColorStop(offset, color) {
20937        var stop = this.__ctx.__createElement("stop"),
20938            regex,
20939            matches;
20940
20941        stop.setAttribute("offset", offset);
20942
20943        if (color && color.indexOf("rgba") !== -1) {
20944          //separate alpha value, since webkit can't handle it
20945          regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi;
20946          matches = regex.exec(color);
20947          stop.setAttribute("stop-color", format("rgb({r},{g},{b})", {
20948            r: matches[1],
20949            g: matches[2],
20950            b: matches[3]
20951          }));
20952          stop.setAttribute("stop-opacity", matches[4]);
20953        } else {
20954          stop.setAttribute("stop-color", color);
20955        }
20956
20957        this.__root.appendChild(stop);
20958      }
20959
20960    }
20961
20962    class CanvasPattern {
20963      constructor(pattern, ctx) {
20964        this.__root = pattern;
20965        this.__ctx = ctx;
20966      }
20967
20968    }
20969    /**
20970     * The mock canvas context
20971     * @param config - options include:
20972     * ctx - existing Context2D to wrap around
20973     * width - width of your canvas (defaults to 500)
20974     * height - height of your canvas (defaults to 500)
20975     * enableMirroring - enables canvas mirroring (get image data) (defaults to false)
20976     * document - the document object (defaults to the current document)
20977     */
20978
20979
20980    class ctx {
20981      constructor(config) {
20982        if (!(this instanceof ctx)) {
20983          //did someone call this without new?
20984          return new ctx(config);
20985        } // clone config
20986
20987
20988        this.config = config; //setup options
20989
20990        this.width = config.width;
20991        this.height = config.height;
20992        this.enableMirroring = config.enableMirroring || false;
20993        this.canvas = this; ///point back to this instance!
20994
20995        this.__document = document; // allow passing in an existing context to wrap around
20996        // if a context is passed in, we know a canvas already exist
20997
20998        if (config.ctx) {
20999          this.__ctx = config.ctx;
21000        } else {
21001          this.__canvas = this.__document.createElement("canvas");
21002          this.__ctx = this.__canvas.getContext("2d");
21003        } // give this canvas a type
21004
21005
21006        this.isSVG = true;
21007
21008        this.__setDefaultStyles();
21009
21010        this.__stack = [this.__getStyleState()];
21011        this.__groupStack = []; // root svg element
21012
21013        this.__root = this.__createElement("svg");
21014
21015        this.__root.setAttribute("width", this.width);
21016
21017        this.__root.setAttribute("height", this.height); // allow contents to overflow svg bbox
21018
21019
21020        this.__root.setAttribute('overflow', 'visible'); // viewbox
21021
21022
21023        if (config.viewbox) {
21024          const str = config.viewbox.x + ' ' + config.viewbox.y + ' ' + config.viewbox.width + ' ' + config.viewbox.height;
21025
21026          this.__root.setAttribute("viewBox", str);
21027
21028          this.viewbox = config.viewbox;
21029        } // make sure we don't generate the same ids in defs
21030
21031
21032        this.__ids = {}; // defs
21033
21034        this.__defs = this.__createElement("defs");
21035
21036        this.__root.appendChild(this.__defs);
21037
21038        this.multiLocusGap = config.multiLocusGap; // svg background color
21039
21040        let backdropConfig = {
21041          id: 'svg_output_backdrop',
21042          width: '100%',
21043          height: '100%',
21044          fill: config.backdropColor || 'white'
21045        };
21046
21047        let backdropRect = this.__createElement('rect', backdropConfig);
21048
21049        this.__root.appendChild(backdropRect); // root group
21050
21051
21052        this.__rootGroup = this.__createElement('g', {
21053          id: 'root-group'
21054        });
21055
21056        this.__root.appendChild(this.__rootGroup); // point current element to root group
21057
21058
21059        this.__currentElement = this.__rootGroup;
21060      }
21061
21062      setWidth(width) {
21063        this.width = width;
21064
21065        this.__root.setAttribute("width", this.width);
21066
21067        const str = this.config.viewbox.x + ' ' + this.config.viewbox.y + ' ' + width + ' ' + this.config.viewbox.height;
21068
21069        this.__root.setAttribute("viewBox", str);
21070      }
21071
21072      setHeight(height) {
21073        this.height = height;
21074
21075        this.__root.setAttribute("height", this.height);
21076
21077        const str = this.config.viewbox.x + ' ' + this.config.viewbox.y + ' ' + this.config.viewbox.width + ' ' + height;
21078
21079        this.__root.setAttribute("viewBox", str);
21080      }
21081
21082      /**
21083       * Creates the specified svg element
21084       * @private
21085       */
21086      __createElement(elementName, properties, resetFill) {
21087        if (typeof properties === "undefined") {
21088          properties = {};
21089        }
21090
21091        let element = this.__document.createElementNS("http://www.w3.org/2000/svg", elementName);
21092
21093        if (resetFill) {
21094          //if fill or stroke is not specified, the svg element should not display. By default SVG's fill is black.
21095          element.setAttribute("fill", "none");
21096          element.setAttribute("stroke", "none");
21097        }
21098
21099        for (let key of Object.keys(properties)) {
21100          element.setAttribute(key, properties[key]);
21101        }
21102
21103        return element;
21104      }
21105
21106      /**
21107       * Applies default canvas styles to the context
21108       * @private
21109       */
21110      __setDefaultStyles() {
21111        //default 2d canvas context properties see:http://www.w3.org/TR/2dcontext/
21112        var keys = Object.keys(STYLES),
21113            i,
21114            key;
21115
21116        for (i = 0; i < keys.length; i++) {
21117          key = keys[i];
21118          this[key] = STYLES[key].canvas;
21119        }
21120      }
21121
21122      /**
21123       * Applies styles on restore
21124       * @param styleState
21125       * @private
21126       */
21127      __applyStyleState(styleState) {
21128        var keys = Object.keys(styleState),
21129            i,
21130            key;
21131
21132        for (i = 0; i < keys.length; i++) {
21133          key = keys[i];
21134          this[key] = styleState[key];
21135        }
21136      }
21137
21138      /**
21139       * Gets the current style state
21140       * @return {Object}
21141       * @private
21142       */
21143      __getStyleState() {
21144        var i,
21145            styleState = {},
21146            keys = Object.keys(STYLES),
21147            key;
21148
21149        for (i = 0; i < keys.length; i++) {
21150          key = keys[i];
21151          styleState[key] = this[key];
21152        }
21153
21154        return styleState;
21155      }
21156
21157      /**
21158       * Apples the current styles to the current SVG element. On "ctx.fill" or "ctx.stroke"
21159       * @param type
21160       * @private
21161       */
21162      __applyStyleToCurrentElement(type) {
21163        var currentElement = this.__currentElement;
21164        var currentStyleGroup = this.__currentElementsToStyle;
21165
21166        if (currentStyleGroup) {
21167          currentElement.setAttribute(type, "");
21168          currentElement = currentStyleGroup.element;
21169          currentStyleGroup.children.forEach(function (node) {
21170            node.setAttribute(type, "");
21171          });
21172        }
21173
21174        var keys = Object.keys(STYLES),
21175            i,
21176            style,
21177            value,
21178            id,
21179            regex,
21180            matches;
21181
21182        for (i = 0; i < keys.length; i++) {
21183          style = STYLES[keys[i]];
21184          value = this[keys[i]];
21185
21186          if (style.apply) {
21187            //is this a gradient or pattern?
21188            if (value instanceof CanvasPattern) {
21189              //pattern
21190              if (value.__ctx) {
21191                //copy over defs
21192                while (value.__ctx.__defs.childNodes.length) {
21193                  id = value.__ctx.__defs.childNodes[0].getAttribute("id");
21194                  this.__ids[id] = id;
21195
21196                  this.__defs.appendChild(value.__ctx.__defs.childNodes[0]);
21197                }
21198              }
21199
21200              currentElement.setAttribute(style.apply, format("url(#{id})", {
21201                id: value.__root.getAttribute("id")
21202              }));
21203            } else if (value instanceof CanvasGradient) {
21204              //gradient
21205              currentElement.setAttribute(style.apply, format("url(#{id})", {
21206                id: value.__root.getAttribute("id")
21207              }));
21208            } else if (style && style.apply.indexOf(type) !== -1 && style.svg !== value) {
21209              if ((style.svgAttr === "stroke" || style.svgAttr === "fill") && value && value.indexOf("rgba") !== -1) {
21210                //separate alpha value, since illustrator can't handle it
21211                regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi;
21212                matches = regex.exec(value);
21213                currentElement.setAttribute(style.svgAttr, format("rgb({r},{g},{b})", {
21214                  r: matches[1],
21215                  g: matches[2],
21216                  b: matches[3]
21217                })); //should take globalAlpha here
21218
21219                var opacity = matches[4];
21220                var globalAlpha = this.globalAlpha;
21221
21222                if (globalAlpha != null) {
21223                  opacity *= globalAlpha;
21224                }
21225
21226                currentElement.setAttribute(style.svgAttr + "-opacity", opacity);
21227              } else {
21228                var attr = style.svgAttr;
21229
21230                if (keys[i] === 'globalAlpha') {
21231                  attr = type + '-' + style.svgAttr;
21232
21233                  if (currentElement.getAttribute(attr)) {
21234                    //fill-opacity or stroke-opacity has already been set by stroke or fill.
21235                    continue;
21236                  }
21237                } //otherwise only update attribute if right type, and not svg default
21238
21239
21240                currentElement.setAttribute(attr, value);
21241              }
21242            }
21243          }
21244        }
21245      }
21246
21247      /**
21248       * Will return the closest group or svg node. May return the current element.
21249       * @private
21250       */
21251      __closestGroupOrSvg(node) {
21252        node = node || this.__currentElement;
21253
21254        if (node.nodeName === "g" || node.nodeName === "svg") {
21255          return node;
21256        } else {
21257          return this.__closestGroupOrSvg(node.parentNode);
21258        }
21259      }
21260
21261      /**
21262       * Returns the serialized value of the svg so far
21263       * @param fixNamedEntities - Standalone SVG doesn't support named entities, which document.createTextNode encodes.
21264       *                           If true, we attempt to find all named entities and encode it as a numeric entity.
21265       * @return serialized svg
21266       */
21267      getSerializedSvg(fixNamedEntities) {
21268        var serialized = new XMLSerializer().serializeToString(this.__root),
21269            keys,
21270            i,
21271            key,
21272            value,
21273            regexp;
21274     //IE search for a duplicate xmnls because they didn't implement setAttributeNS correctly
21275        // xmlns = /xmlns="http:\/\/www\.w3\.org\/2000\/svg".+xmlns="http:\/\/www\.w3\.org\/2000\/svg/gi;
21276        // if (xmlns.test(serialized)) {
21277        //     serialized = serialized.replace('xmlns="http://www.w3.org/2000/svg','xmlns:xlink="http://www.w3.org/1999/xlink');
21278        // }
21279
21280        if (fixNamedEntities) {
21281          keys = Object.keys(namedEntities); //loop over each named entity and replace with the proper equivalent.
21282
21283          for (i = 0; i < keys.length; i++) {
21284            key = keys[i];
21285            value = namedEntities[key];
21286            regexp = new RegExp(key, "gi");
21287
21288            if (regexp.test(serialized)) {
21289              serialized = serialized.replace(regexp, value);
21290            }
21291          }
21292        }
21293
21294        return serialized;
21295      }
21296
21297      /**
21298       * Returns the root svg
21299       * @return
21300       */
21301      getSvg() {
21302        return this.__root;
21303      }
21304
21305      /**
21306       * Will generate a group tag.
21307       */
21308      saveWithTranslationAndClipRect(id, tx, ty, width, height, clipYOffset) {
21309        // clip rect
21310        const clip_id = `${id}_clip_rect`;
21311
21312        let clipPath = this.__createElement('clipPath', {
21313          id: clip_id
21314        });
21315
21316        this.__defs.appendChild(clipPath);
21317
21318        const config = {
21319          x: '0',
21320          y: clipYOffset.toString(),
21321          width: width.toString(),
21322          height: height.toString()
21323        };
21324        clipPath.appendChild(this.__createElement('rect', config));
21325
21326        const group = this.__createElement("g");
21327
21328        group.setAttribute('transform', format('translate({x},{y})', {
21329          x: tx,
21330          y: ty
21331        }));
21332        group.setAttribute('clip-path', format('url(#{id})', {
21333          id: clip_id
21334        }));
21335
21336        const parent = this.__closestGroupOrSvg();
21337
21338        parent.appendChild(group);
21339
21340        this.__groupStack.push(parent);
21341
21342        this.__currentElement = group;
21343
21344        this.__stack.push(this.__getStyleState());
21345      }
21346
21347      save() {
21348        var group = this.__createElement("g");
21349
21350        var parent = this.__closestGroupOrSvg();
21351
21352        this.__groupStack.push(parent);
21353
21354        parent.appendChild(group);
21355        this.__currentElement = group;
21356
21357        this.__stack.push(this.__getStyleState());
21358      }
21359
21360      /**
21361       * Sets current element to parent, or just root if already root
21362       */
21363      restore() {
21364        this.__currentElement = this.__groupStack.pop();
21365        this.__currentElementsToStyle = null; //Clearing canvas will make the poped group invalid, currentElement is set to the root group node.
21366
21367        if (!this.__currentElement) {
21368          this.__currentElement = this.__root.childNodes[1];
21369        }
21370
21371        var state = this.__stack.pop();
21372
21373        this.__applyStyleState(state);
21374      }
21375
21376      /**
21377       * Helper method to add transform
21378       * @private
21379       */
21380      __addTransform(t) {
21381        //if the current element has siblings, add another group
21382        var parent = this.__closestGroupOrSvg();
21383
21384        if (parent.childNodes.length > 0) {
21385          if (this.__currentElement.nodeName === "path") {
21386            if (!this.__currentElementsToStyle) this.__currentElementsToStyle = {
21387              element: parent,
21388              children: []
21389            };
21390
21391            this.__currentElementsToStyle.children.push(this.__currentElement);
21392
21393            this.__applyCurrentDefaultPath();
21394          }
21395
21396          var group = this.__createElement("g");
21397
21398          parent.appendChild(group);
21399          this.__currentElement = group;
21400        }
21401
21402        var transform = this.__currentElement.getAttribute("transform");
21403
21404        if (transform) {
21405          transform += " ";
21406        } else {
21407          transform = "";
21408        }
21409
21410        transform += t;
21411
21412        this.__currentElement.setAttribute("transform", transform);
21413      }
21414
21415      addTrackGroupWithTranslationAndClipRect(id, tx, ty, width, height, clipYOffset) {
21416        // clip rect
21417        const clip_id = id + '_clip_rect';
21418
21419        let clipPath = this.__createElement('clipPath', {
21420          id: clip_id
21421        });
21422
21423        this.__defs.appendChild(clipPath);
21424
21425        clipPath.appendChild(this.__createElement('rect', {
21426          x: '0',
21427          y: clipYOffset.toString(),
21428          width: width.toString(),
21429          height: height.toString()
21430        }));
21431
21432        let group = this.__createElement('g');
21433
21434        this.__rootGroup.appendChild(group);
21435
21436        group.setAttribute('transform', format('translate({x},{y})', {
21437          x: tx,
21438          y: ty
21439        }));
21440        group.setAttribute('id', id + '_group'); // add clip rect
21441
21442        group.setAttribute('clip-path', format('url(#{id})', {
21443          id: clip_id
21444        }));
21445        this.__currentElement = group;
21446      }
21447
21448      /**
21449       *  scales the current element
21450       */
21451      scale(x, y) {
21452        if (y === undefined) {
21453          y = x;
21454        }
21455
21456        this.__addTransform(format("scale({x},{y})", {
21457          x: x,
21458          y: y
21459        }));
21460      }
21461
21462      /**
21463       * rotates the current element
21464       */
21465      rotate(angle) {
21466        var degrees = angle * 180 / Math.PI;
21467
21468        this.__addTransform(format("rotate({angle},{cx},{cy})", {
21469          angle: degrees,
21470          cx: 0,
21471          cy: 0
21472        }));
21473      }
21474
21475      /**
21476       * translates the current element
21477       */
21478      translate(x, y) {
21479        this.__addTransform(format("translate({x},{y})", {
21480          x: x,
21481          y: y
21482        }));
21483      }
21484
21485      /**
21486       * applies a transform to the current element
21487       */
21488      transform(a, b, c, d, e, f) {
21489        this.__addTransform(format("matrix({a},{b},{c},{d},{e},{f})", {
21490          a: a,
21491          b: b,
21492          c: c,
21493          d: d,
21494          e: e,
21495          f: f
21496        }));
21497      }
21498
21499      /**
21500       * Create a new Path Element
21501       */
21502      beginPath() {
21503        var path, parent; // Note that there is only one current default path, it is not part of the drawing state.
21504        // See also: https://html.spec.whatwg.org/multipage/scripting.html#current-default-path
21505
21506        this.__currentDefaultPath = "";
21507        this.__currentPosition = {};
21508        path = this.__createElement("path", {}, true);
21509        parent = this.__closestGroupOrSvg();
21510        parent.appendChild(path);
21511        this.__currentElement = path;
21512      }
21513
21514      /**
21515       * Helper function to apply currentDefaultPath to current path element
21516       * @private
21517       */
21518      __applyCurrentDefaultPath() {
21519        var currentElement = this.__currentElement;
21520
21521        if (currentElement.nodeName === "path") {
21522          currentElement.setAttribute("d", this.__currentDefaultPath);
21523        } else {
21524          console.error("Attempted to apply path command to node", currentElement.nodeName);
21525        }
21526      }
21527
21528      /**
21529       * Helper function to add path command
21530       * @private
21531       */
21532      __addPathCommand(command) {
21533        this.__currentDefaultPath += " ";
21534        this.__currentDefaultPath += command;
21535      }
21536
21537      /**
21538       * Adds the move command to the current path element,
21539       * if the currentPathElement is not empty create a new path element
21540       */
21541      moveTo(x, y) {
21542        if (this.__currentElement.nodeName !== "path") {
21543          this.beginPath();
21544        } // creates a new subpath with the given point
21545
21546
21547        this.__currentPosition = {
21548          x: x,
21549          y: y
21550        };
21551
21552        this.__addPathCommand(format("M {x}
21552 {y}", {
21553          x: x,
21554          y: y
21555        }));
21556      }
21557
21558      /**
21559       * Closes the current path
21560       */
21561      closePath() {
21562        if (this.__currentDefaultPath) {
21563          this.__addPathCommand("Z");
21564        }
21565      }
21566
21567      /**
21568       * Adds a line to command
21569       */
21570      lineTo(x, y) {
21571        this.__currentPosition = {
21572          x: x,
21573          y: y
21574        };
21575
21576        if (this.__currentDefaultPath && this.__currentDefaultPath.indexOf('M') > -1) {
21577          this.__addPathCommand(format("L {x} {y}", {
21578            x: x,
21579            y: y
21580          }));
21581        } else {
21582          this.__addPathCommand(format("M {x} {y}", {
21583            x: x,
21584            y: y
21585          }));
21586        }
21587      }
21588
21589      /**
21590       * Add a bezier command
21591       */
21592      bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) {
21593        this.__currentPosition = {
21594          x: x,
21595          y: y
21596        };
21597
21598        this.__addPathCommand(format("C {cp1x} {cp1y} {cp2x} {cp2y} {x} {y}", {
21599          cp1x: cp1x,
21600          cp1y: cp1y,
21601          cp2x: cp2x,
21602          cp2y: cp2y,
21603          x: x,
21604          y: y
21605        }));
21606      }
21607
21608      /**
21609       * Adds a quadratic curve to command
21610       */
21611      quadraticCurveTo(cpx, cpy, x, y) {
21612        this.__currentPosition = {
21613          x: x,
21614          y: y
21615        };
21616
21617        this.__addPathCommand(format("Q {cpx} {cpy} {x} {y}", {
21618          cpx: cpx,
21619          cpy: cpy,
21620          x: x,
21621          y: y
21622        }));
21623      }
21624
21625      /**
21626       * Adds the arcTo to the current path
21627       *
21628       * @see http://www.w3.org/TR/2015/WD-2dcontext-20150514/#dom-context-2d-arcto
21629       */
21630      arcTo(x1, y1, x2, y2, radius) {
21631        // Let the point (x0, y0) be the last point in the subpath.
21632        var x0 = this.__currentPosition && this.__currentPosition.x;
21633        var y0 = this.__currentPosition && this.__currentPosition.y; // First ensure there is a subpath for (x1, y1).
21634
21635        if (typeof x0 == "undefined" || typeof y0 == "undefined") {
21636          return;
21637        } // Negative values for radius must cause the implementation to throw an IndexSizeError exception.
21638
21639
21640        if (radius < 0) {
21641          throw new Error("IndexSizeError: The radius provided (" + radius + ") is negative.");
21642        } // If the point (x0, y0) is equal to the point (x1, y1),
21643        // or if the point (x1, y1) is equal to the point (x2, y2),
21644        // or if the radius radius is zero,
21645        // then the method must add the point (x1, y1) to the subpath,
21646        // and connect that point to the previous point (x0, y0) by a straight line.
21647
21648
21649        if (x0 === x1 && y0 === y1 || x1 === x2 && y1 === y2 || radius === 0) {
21650          this.lineTo(x1, y1);
21651          return;
21652        } // Otherwise, if the points (x0, y0), (x1, y1), and (x2, y2) all lie on a single straight line,
21653        // then the method must add the point (x1, y1) to the subpath,
21654        // and connect that point to the previous point (x0, y0) by a straight line.
21655
21656
21657        var unit_vec_p1_p0 = normalize$1([x0 - x1, y0 - y1]);
21658        var unit_vec_p1_p2 = normalize$1([x2 - x1, y2 - y1]);
21659
21660        if (unit_vec_p1_p0[0] * unit_vec_p1_p2[1] === unit_vec_p1_p0[1] * unit_vec_p1_p2[0]) {
21661          this.lineTo(x1, y1);
21662          return;
21663        } // Otherwise, let The Arc be the shortest arc given by circumference of the circle that has radius radius,
21664        // and that has one point tangent to the half-infinite line that crosses the point (x0, y0) and ends at the point (x1, y1),
21665        // and that has a different point tangent to the half-infinite line that ends at the point (x1, y1), and crosses the point (x2, y2).
21666        // The points at which this circle touches these two lines are called the start and end tangent points respectively.
21667        // note that both vectors are unit vectors, so the length is 1
21668
21669
21670        var cos = unit_vec_p1_p0[0] * unit_vec_p1_p2[0] + unit_vec_p1_p0[1] * unit_vec_p1_p2[1];
21671        var theta = Math.acos(Math.abs(cos)); // Calculate origin
21672
21673        var unit_vec_p1_origin = normalize$1([unit_vec_p1_p0[0] + unit_vec_p1_p2[0], unit_vec_p1_p0[1] + unit_vec_p1_p2[1]]);
21674        var len_p1_origin = radius / Math.sin(theta / 2);
21675        var x = x1 + len_p1_origin * unit_vec_p1_origin[0];
21676        var y = y1 + len_p1_origin * unit_vec_p1_origin[1]; // Calculate start angle and end angle
21677        // rotate 90deg clockwise (note that y axis points to its down)
21678
21679        var unit_vec_origin_start_tangent = [-unit_vec_p1_p0[1], unit_vec_p1_p0[0]]; // rotate 90deg counter clockwise (note that y axis points to its down)
21680
21681        var unit_vec_origin_end_tangent = [unit_vec_p1_p2[1], -unit_vec_p1_p2[0]];
21682
21683        var getAngle = function (vector) {
21684          // get angle (clockwise) between vector and (1, 0)
21685          var x = vector[0];
21686          var y = vector[1];
21687
21688          if (y >= 0) {
21689            // note that y axis points to its down
21690            return Math.acos(x);
21691          } else {
21692            return -Math.acos(x);
21693          }
21694        };
21695
21696        var startAngle = getAngle(unit_vec_origin_start_tangent);
21697        var endAngle = getAngle(unit_vec_origin_end_tangent); // Connect the point (x0, y0) to the start tangent point by a straight line
21698
21699        this.lineTo(x + unit_vec_origin_start_tangent[0] * radius, y + unit_vec_origin_start_tangent[1] * radius); // Connect the start tangent point to the end tangent point by arc
21700        // and adding the end tangent point to the subpath.
21701
21702        this.arc(x, y, radius, startAngle, endAngle);
21703      }
21704
21705      /**
21706       * Sets the stroke property on the current element
21707       */
21708      stroke() {
21709        if (this.__currentElement.nodeName === "path") {
21710          this.__currentElement.setAttribute("paint-order", "fill stroke markers");
21711        }
21712
21713        this.__applyCurrentDefaultPath();
21714
21715        this.__applyStyleToCurrentElement("stroke");
21716      }
21717
21718      /**
21719       * Sets fill properties on the current element
21720       */
21721      fill() {
21722        if (this.__currentElement.nodeName === "path") {
21723          this.__currentElement.setAttribute("paint-order", "stroke fill markers");
21724        }
21725
21726        this.__applyCurrentDefaultPath();
21727
21728        this.__applyStyleToCurrentElement("fill");
21729      }
21730
21731      /**
21732       *  Adds a rectangle to the path.
21733       */
21734      rect(x, y, width, height) {
21735        if (this.__currentElement.nodeName !== "path") {
21736          this.beginPath();
21737        }
21738
21739        this.moveTo(x, y);
21740        this.lineTo(x + width, y);
21741        this.lineTo(x + width, y + height);
21742        this.lineTo(x, y + height);
21743        this.lineTo(x, y);
21744        this.closePath();
21745      }
21746
21747      /**
21748       * adds a rectangle element
21749       */
21750      fillRect(x, y, width, height) {
21751        if (height < 0) {
21752          y += height;
21753          height = -height;
21754        }
21755
21756        if (width < 0) {
21757          x += width;
21758          width = -width;
21759        } // See if rect intersects current viewbox
21760
21761
21762        var r2 = {
21763          x: x,
21764          y: y,
21765          width: width,
21766          height: height
21767        };
21768
21769        if (this.viewbox) {
21770          if (!intersectRect(this.viewbox, r2)) {
21771            return;
21772          }
21773        }
21774
21775        var rect, parent;
21776        rect = this.__createElement("rect", r2, true);
21777        parent = this.__closestGroupOrSvg();
21778        parent.appendChild(rect);
21779        this.__currentElement = rect;
21780
21781        this.__applyStyleToCurrentElement("fill");
21782      }
21783
21784      /**
21785       * Draws a rectangle with no fill
21786       * @param x
21787       * @param y
21788       * @param width
21789       * @param height
21790       */
21791      strokeRect(x, y, width, height) {
21792        var rect, parent;
21793        rect = this.__createElement("rect", {
21794          x: x,
21795          y: y,
21796          width: width,
21797          height: height
21798        }, true);
21799        parent = this.__closestGroupOrSvg();
21800        parent.appendChild(rect);
21801        this.__currentElement = rect;
21802
21803        this.__applyStyleToCurrentElement("stroke");
21804      }
21805
21806      // stroke ellipse
21807      strokeEllipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW) {
21808        this.__ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, 'stroke');
21809      } // fill ellipse
21810
21811
21812      fillEllipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW) {
21813        this.__ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, 'fill');
21814      } // ellipse helper
21815
21816
21817      __ellipse(cx, cy, rx, ry, rotation, startAngle, endAngle, isCCW, style) {
21818        const config = {
21819          cx,
21820          cy,
21821          rx,
21822          ry
21823        };
21824
21825        const element = this.__createElement('ellipse', config, true);
21826
21827        const parent = this.__closestGroupOrSvg();
21828
21829        parent.appendChild(element);
21830        this.__currentElement = element;
21831
21832        this.__applyStyleToCurrentElement(style);
21833      }
21834      /**
21835       * Clear entire canvas:
21836       * 1. save current transforms
21837       * 2. remove all the childNodes of the root g element
21838       */
21839
21840
21841      __clearCanvas() {
21842        var current = this.__closestGroupOrSvg(),
21843            transform = current.getAttribute("transform");
21844
21845        var rootGroup = this.__root.childNodes[1];
21846        var childNodes = rootGroup.childNodes;
21847
21848        for (var i = childNodes.length - 1; i >= 0; i--) {
21849          if (childNodes[i]) {
21850            rootGroup.removeChild(childNodes[i]);
21851          }
21852        }
21853
21854        this.__currentElement = rootGroup; //reset __groupStack as all the child group nodes are all removed.
21855
21856        this.__groupStack = [];
21857
21858        if (transform) {
21859          this.__addTransform(transform);
21860        }
21861      }
21862
21863      /**
21864       * "Clears" a canvas by just drawing a white rectangle in the current group.
21865       */
21866      clearRect(x, y, width, height) {
21867        //clear entire canvas
21868        if (x === 0 && y === 0 && width === this.width && height === this.height) {
21869          this.__clearCanvas();
21870
21871          return;
21872        }
21873
21874        var rect,
21875            parent = this.__closestGroupOrSvg();
21876
21877        rect = this.__createElement("rect", {
21878          x: x,
21879          y: y,
21880          width: width,
21881          height: height,
21882          fill: "#FFFFFF"
21883        }, true);
21884        parent.appendChild(rect);
21885      }
21886
21887      /**
21888       * Adds a linear gradient to a defs tag.
21889       * Returns a canvas gradient object that has a reference to it's parent def
21890       */
21891      createLinearGradient(x1, y1, x2, y2) {
21892        var grad = this.__createElement("linearGradient", {
21893          id: randomString(this.__ids),
21894          x1: x1 + "px",
21895          x2: x2 + "px",
21896          y1: y1 + "px",
21897          y2: y2 + "px",
21898          "gradientUnits": "userSpaceOnUse"
21899        }, false);
21900
21901        this.__defs.appendChild(grad);
21902
21903        return new CanvasGradient(grad, this);
21904      }
21905
21906      /**
21907       * Adds a radial gradient to a defs tag.
21908       * Returns a canvas gradient object that has a reference to it's parent def
21909       */
21910      createRadialGradient(x0, y0, r0, x1, y1, r1) {
21911        var grad = this.__createElement("radialGradient", {
21912          id: randomString(this.__ids),
21913          cx: x1 + "px",
21914          cy: y1 + "px",
21915          r: r1 + "px",
21916          fx: x0 + "px",
21917          fy: y0 + "px",
21918          "gradientUnits": "userSpaceOnUse"
21919        }, false);
21920
21921        this.__defs.appendChild(grad);
21922
21923        return new CanvasGradient(grad, this);
21924      }
21925
21926      /**
21927       * Parses the font string and returns svg mapping
21928       * @private
21929       */
21930      __parseFont() {
21931        var regex = /^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-,\'\"\sa-z0-9]+?)\s*$/i;
21932        var fontPart = regex.exec(this.font);
21933        var data = {
21934          style: fontPart[1] || 'normal',
21935          size: fontPart[4] || '10px',
21936          family: fontPart[6] || 'sans-serif',
21937          weight: fontPart[3] || 'normal',
21938          decoration: fontPart[2] || 'normal',
21939          href: null
21940        }; //canvas doesn't support underline natively, but we can pass this attribute
21941
21942        if (this.__fontUnderline === "underline") {
21943          data.decoration = "underline";
21944        } //canvas also doesn't support linking, but we can pass this as well
21945
21946
21947        if (this.__fontHref) {
21948          data.href = this.__fontHref;
21949        }
21950
21951        return data;
21952      }
21953
21954      /**
21955       * Helper to link text fragments
21956       * @param font
21957       * @param element
21958       * @return {*}
21959       * @private
21960       */
21961      __wrapTextLink(font, element) {
21962        if (font.href) {
21963          var a = this.__createElement("a");
21964
21965          a.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", font.href);
21966          a.appendChild(element);
21967          return a;
21968        }
21969
21970        return element;
21971      }
21972
21973      /**
21974       * Fills or strokes text
21975       * @param text
21976       * @param x
21977       * @param y
21978       * @param action - stroke or fill
21979       * @private
21980       */
21981      __applyText(text, x, y, action) {
21982        var font = this.__parseFont(),
21983            parent = this.__closestGroupOrSvg(),
21984            textElement = this.__createElement("text", {
21985          "font-family": font.family,
21986          "font-size": font.size,
21987          "font-style": font.style,
21988          "font-weight": font.weight,
21989          "text-decoration": font.decoration,
21990          "x": x,
21991          "y": y,
21992          "text-anchor": getTextAnchor(this.textAlign),
21993          "dominant-baseline": getDominantBaseline(this.textBaseline)
21994        }, true);
21995
21996        textElement.appendChild(this.__document.createTextNode(text));
21997        this.__currentElement = textElement;
21998
21999        this.__applyStyleToCurrentElement(action);
22000
22001        parent.appendChild(this.__wrapTextLink(font, textElement));
22002      }
22003
22004      /**
22005       * Creates a text element
22006       * @param text
22007       * @param x
22008       * @param y
22009       */
22010      fillText(text, x, y) {
22011        this.__applyText(text, x, y, "fill");
22012      }
22013
22014      /**
22015       * Strokes text
22016       * @param text
22017       * @param x
22018       * @param y
22019       */
22020      strokeText(text, x, y) {
22021        this.__applyText(text, x, y, "stroke");
22022      }
22023
22024      /**
22025       * No need to implement this for svg.
22026       * @param text
22027       * @return {TextMetrics}
22028       */
22029      measureText(text) {
22030        this.__ctx.font = this.font;
22031        return this.__ctx.measureText(text);
22032      }
22033
22034      /**
22035       *  Arc command!
22036       */
22037      arc(x, y, radius, startAngle, endAngle, counterClockwise) {
22038        // in canvas no circle is drawn if no angle is provided.
22039        if (startAngle === endAngle) {
22040          return;
22041        }
22042
22043        startAngle = startAngle % (2 * Math.PI);
22044        endAngle = endAngle % (2 * Math.PI);
22045
22046        if (startAngle === endAngle) {
22047          //circle time! subtract some of the angle so svg is happy (svg elliptical arc can't draw a full circle)
22048          endAngle = (endAngle + 2 * Math.PI - 0.001 * (counterClockwise ? -1 : 1)) % (2 * Math.PI);
22049        }
22050
22051        var endX = x + radius * Math.cos(endAngle),
22052            endY = y + radius * Math.sin(endAngle),
22053            startX = x + radius * Math.cos(startAngle),
22054            startY = y + radius * Math.sin(startAngle),
22055            sweepFlag = counterClockwise ? 0 : 1,
22056            largeArcFlag = 0,
22057            diff = endAngle - startAngle; // https://github.com/gliffy/canvas2svg/issues/4
22058
22059        if (diff < 0) {
22060          diff += 2 * Math.PI;
22061        }
22062
22063        if (counterClockwise) {
22064          largeArcFlag = diff > Math.PI ? 0 : 1;
22065        } else {
22066          largeArcFlag = diff > Math.PI ? 1 : 0;
22067        }
22068
22069        this.lineTo(startX, startY);
22070
22071        this.__addPathCommand(format("A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}", {
22072          rx: radius,
22073          ry: radius,
22074          xAxisRotation: 0,
22075          largeArcFlag: largeArcFlag,
22076          sweepFlag: sweepFlag,
22077          endX: endX,
22078          endY: endY
22079        }));
22080
22081        this.__currentPosition = {
22082          x: endX,
22083          y: endY
22084        };
22085      }
22086
22087      /**
22088       * The ellipse() method creates an elliptical arc centered at (x, y) with the radii radiusX and radiusY. The path
22089       * starts at startAngle and ends at endAngle, and travels in the direction given by counterclockwise (defaulting to clockwise).
22090       */
22091      // ellipse (x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise) {
22092      //     // TODO -- implement
22093      // }
22094
22095      /**
22096       * Generates a ClipPath from the clip command.
22097       */
22098      clip() {
22099        var group = this.__closestGroupOrSvg(),
22100            clipPath = this.__createElement("clipPath"),
22101            id = randomString(this.__ids),
22102            newGroup = this.__createElement("g");
22103
22104        this.__applyCurrentDefaultPath();
22105
22106        group.removeChild(this.__currentElement);
22107        clipPath.setAttribute("id", id);
22108        clipPath.appendChild(this.__currentElement);
22109
22110        this.__defs.appendChild(clipPath); //set the clip path to this group
22111
22112
22113        group.setAttribute("clip-path", format("url(#{id})", {
22114          id: id
22115        })); //clip paths can be scaled and transformed, we need to add another wrapper group to avoid later transformations
22116        // to this path
22117
22118        group.appendChild(newGroup);
22119        this.__currentElement = newGroup;
22120      }
22121
22122      /**
22123       * Draws a canvas, image or mock context to this canvas.
22124       * Note that all svg dom manipulation uses node.childNodes rather than node.children for IE supp
22124ort.
22125       * http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-drawimage
22126       */
22127      drawImage() {
22128        //convert arguments to a real array
22129        var args = Array.prototype.slice.call(arguments),
22130            image = args[0],
22131            dx,
22132            dy,
22133            dw,
22134            dh,
22135            sx = 0,
22136            sy = 0,
22137            sw,
22138            sh,
22139            parent,
22140            svg,
22141            defs,
22142            group,
22143            svgImage,
22144            canvas,
22145            context,
22146            id;
22147
22148        if (args.length === 3) {
22149          dx = args[1];
22150          dy = args[2];
22151          sw = image.width;
22152          sh = image.height;
22153          dw = sw;
22154          dh = sh;
22155        } else if (args.length === 5) {
22156          dx = args[1];
22157          dy = args[2];
22158          dw = args[3];
22159          dh = args[4];
22160          sw = image.width;
22161          sh = image.height;
22162        } else if (args.length === 9) {
22163          sx = args[1];
22164          sy = args[2];
22165          sw = args[3];
22166          sh = args[4];
22167          dx = args[5];
22168          dy = args[6];
22169          dw = args[7];
22170          dh = args[8];
22171        } else {
22172          throw new Error("Invalid number of arguments passed to drawImage: " + arguments.length);
22173        }
22174
22175        parent = this.__closestGroupOrSvg();
22176        var translateDirective = "translate(" + dx + ", " + dy + ")";
22177
22178        if (image instanceof ctx) {
22179          //canvas2svg mock canvas context. In the future we may want to clone nodes instead.
22180          //also I'm currently ignoring dw, dh, sw, sh, sx, sy for a mock context.
22181          svg = image.getSvg().cloneNode(true);
22182
22183          if (svg.childNodes && svg.childNodes.length > 1) {
22184            defs = svg.childNodes[0];
22185
22186            while (defs.childNodes.length) {
22187              id = defs.childNodes[0].getAttribute("id");
22188              this.__ids[id] = id;
22189
22190              this.__defs.appendChild(defs.childNodes[0]);
22191            }
22192
22193            group = svg.childNodes[1];
22194
22195            if (group) {
22196              //save original transform
22197              var originTransform = group.getAttribute("transform");
22198              var transformDirective;
22199
22200              if (originTransform) {
22201                transformDirective = originTransform + " " + translateDirective;
22202              } else {
22203                transformDirective = translateDirective;
22204              }
22205
22206              group.setAttribute("transform", transformDirective);
22207              parent.appendChild(group);
22208            }
22209          }
22210        } else if (image.nodeName === "CANVAS" || image.nodeName === "IMG") {
22211          //canvas or image
22212          svgImage = this.__createElement("image");
22213          svgImage.setAttribute("width", dw);
22214          svgImage.setAttribute("height", dh);
22215          svgImage.setAttribute("preserveAspectRatio", "none");
22216
22217          if (sx || sy || sw !== image.width || sh !== image.height) {
22218            //crop the image using a temporary canvas
22219            canvas = this.__document.createElement("canvas");
22220            canvas.width = dw;
22221            canvas.height = dh;
22222            context = canvas.getContext("2d");
22223            context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh);
22224            image = canvas;
22225          }
22226
22227          svgImage.setAttribute("transform", translateDirective);
22228          svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src"));
22229          parent.appendChild(svgImage);
22230        }
22231      }
22232
22233      /**
22234       * Generates a pattern tag
22235       */
22236      createPattern(image, repetition) {
22237        let pattern = this.__document.__createElement("pattern");
22238
22239        let id = randomString(this.__ids);
22240        let img;
22241        pattern.setAttribute("id", id);
22242        pattern.setAttribute("width", image.width);
22243        pattern.setAttribute("height", image.height);
22244
22245        if (image.nodeName === "CANVAS" || image.nodeName === "IMG") {
22246          img = this.__createElement("image");
22247          img.setAttribute("width", image.width);
22248          img.setAttribute("height", image.height);
22249          img.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src"));
22250          pattern.appendChild(img);
22251
22252          this.__defs.appendChild(pattern);
22253        } else if (image instanceof ctx) {
22254          pattern.appendChild(image.__root.childNodes[1]);
22255
22256          this.__defs.appendChild(pattern);
22257        }
22258
22259        return new CanvasPattern(pattern, this);
22260      }
22261
22262      setLineDash(dashArray) {
22263        if (dashArray && dashArray.length > 0) {
22264          this.lineDash = dashArray.join(",");
22265        } else {
22266          this.lineDash = null;
22267        }
22268      }
22269
22270      /**
22271       * Not yet implemented
22272       */
22273      drawFocusRing() {}
22274
22275      createImageData() {}
22276
22277      getImageData() {}
22278
22279      putImageData() {}
22280
22281      globalCompositeOperation() {}
22282
22283      setTransform() {}
22284
22285    }
22286
22287    const Chromosome = function (name, order, bpStart, bpLength, rangeLocus) {
22288      this.name = name;
22289      this.order = order;
22290      this.bpStart = bpStart;
22291      this.bpLength = bpLength;
22292      this.rangeLocus = rangeLocus;
22293    };
22294
22295    /*
22296     * The MIT License (MIT)
22297     *
22298     * Copyright (c) 2014 Broad Institute
22299     *
22300     * Permission is hereby granted, free of charge, to any person obtaining a copy
22301     * of this software and associated documentation files (the "Software"), to deal
22302     * in the Software without restriction, including without limitation the rights
22303     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22304     * copies of the Software, and to permit persons to whom the Software is
22305     * furnished to do so, subject to the following conditions:
22306     *
22307     * The above copyright notice and this permission notice shall be included in
22308     * all copies or substantial portions of the Software.
22309     *
22310     *
22311     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22312     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22313     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22314     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22315     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22316     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22317     * THE SOFTWARE.
22318     */
22319    const splitLines$4 = splitLines$5;
22320    const reservedProperties$1 = new Set(['fastaURL', 'indexURL', 'cytobandURL', 'indexed']);
22321
22322    class NonIndexedFasta {
22323      constructor(reference) {
22324        this.fastaURL = reference.fastaURL;
22325        this.withCredentials = reference.withCredentials;
22326        this.chromosomeNames = [];
22327        this.chromosomes = {};
22328        this.sequences = new Map();
22329        this.offsets = {}; // Build a track-like config object from the referenceObject
22330
22331        const config = {};
22332
22333        for (let key in reference) {
22334          if (reference.hasOwnProperty(key) && !reservedProperties$1.has(key)) {
22335            config[key] = reference[key];
22336          }
22337        }
22338
22339        this.config = config;
22340      }
22341
22342      async init() {
22343        return this.loadAll();
22344      }
22345
22346      async getSequence(chr, start, end) {
22347        if (this.offsets[chr]) {
22348          start -= this.offsets[chr];
22349          end -= this.offsets[chr];
22350        }
22351
22352        let prefix = "";
22353
22354        if (start < 0) {
22355          for (let i = start; i < Math.min(end, 0); i++) {
22356            prefix += "*";
22357          }
22358        }
22359
22360        if (end <= 0) {
22361          return Promise.resolve(prefix);
22362        }
22363
22364        const seq = this.sequences.get(chr);
22365        const seqEnd = Math.min(end, seq.length);
22366        return prefix + seq.substring(start, seqEnd);
22367      }
22368
22369      async loadAll() {
22370        let data;
22371
22372        if (isDataURL(this.fastaURL)) {
22373          let bytes = decodeDataURI$1(this.fastaURL);
22374          data = "";
22375
22376          for (let b of bytes) {
22377            data += String.fromCharCode(b);
22378          }
22379        } else {
22380          data = await igvxhr.load(this.fastaURL, buildOptions(this.config));
22381        }
22382
22383        const lines = splitLines$4(data);
22384        const len = lines.length;
22385        let lineNo = 0;
22386        let currentSeq;
22387        let currentRangeLocus;
22388        let currentOffset = 0;
22389        let order = 0;
22390        let nextLine;
22391        let currentChr;
22392
22393        while (lineNo < len) {
22394          nextLine = lines[lineNo++].trim();
22395
22396          if (nextLine.startsWith("#") || nextLine.length === 0) ; else if (nextLine.startsWith(">")) {
22397            // Start the next sequence
22398            if (currentSeq) {
22399              this.chromosomeNames.push(currentChr);
22400              this.sequences.set(currentChr, currentSeq);
22401              this.chromosomes[currentChr] = new Chromosome(currentChr, order++, currentOffset, currentOffset + currentSeq.length, currentRangeLocus);
22402            }
22403
22404            const parts = nextLine.substr(1).split(/\s+/); // Check for samtools style locus string.   This is not perfect, and could fail on weird sequence names
22405
22406            const nameParts = parts[0].split(':');
22407            currentChr = nameParts[0];
22408            currentSeq = "";
22409            currentOffset = 0;
22410            currentRangeLocus = undefined;
22411
22412            if (nameParts.length > 1 && nameParts[1].indexOf('-') > 0) {
22413              const locusParts = nameParts[1].split('-');
22414
22415              if (locusParts.length === 2 && /^[0-9]+$/.test(locusParts[0]) && /^[0-9]+$/.test(locusParts[1])) ;
22416
22417              const from = Number.parseInt(locusParts[0]);
22418              const to = Number.parseInt(locusParts[1]);
22419
22420              if (to > from) {
22421                currentOffset = from - 1;
22422                this.offsets[currentChr] = currentOffset;
22423                currentRangeLocus = nameParts[1];
22424              }
22425            }
22426          } else {
22427            currentSeq += nextLine;
22428          }
22429        } // add last seq
22430
22431
22432        if (currentSeq) {
22433          this.chromosomeNames.push(currentChr);
22434          this.sequences.set(currentChr, currentSeq);
22435          this.chromosomes[currentChr] = new Chromosome(currentChr, order++, currentOffset, currentOffset + currentSeq.length, currentRangeLocus);
22436        }
22437      }
22438
22439    }
22440
22441    const GenomicInterval = function (chr, start, end, features) {
22442      this.chr = chr;
22443      this.start = start;
22444      this.end = end;
22445      this.features = features;
22446    };
22447
22448    GenomicInterval.prototype.contains = function (chr, start, end) {
22449      return this.chr === chr && this.start <= start && this.end >= end;
22450    };
22451
22452    GenomicInterval.prototype.containsRange = function (range) {
22453      return this.chr === range.chr && this.start <= range.start && this.end >= range.end;
22454    };
22455
22456    /*
22457     * The MIT License (MIT)
22458     *
22459     * Copyright (c) 2014 Broad Institute
22460     *
22461     * Permission is hereby granted, free of charge, to any person obtaining a copy
22462     * of this software and associated documentation files (the "Software"), to deal
22463     * in the Software without restriction, including without limitation the rights
22464     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22465     * copies of the Software, and to permit persons to whom the Software is
22466     * furnished to do so, subject to the following conditions:
22467     *
22468     * The above copyright notice and this permission notice shall be included in
22469     * all copies or substantial portions of the Software.
22470     *
22471     *
22472     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22473     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22474     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22475     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22476     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22477     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22478     * THE SOFTWARE.
22479     */
22480    const splitLines$3 = splitLines$5;
22481    const reservedProperties = new Set(['fastaURL', 'indexURL', 'cytobandURL', 'indexed']);
22482
22483    class FastaSequence {
22484      constructor(reference) {
22485        this.file = reference.fastaURL;
22486        this.indexFile = reference.indexURL || reference.indexFile || this.file + ".fai";
22487        this.withCredentials = reference.withCredentials;
22488        this.chromosomeNames = [];
22489        this.chromosomes = {};
22490        this.sequences = {};
22491        this.offsets = {}; // Build a track-like config object from the referenceObject
22492
22493        const config = {};
22494
22495        for (let key in reference) {
22496          if (reference.hasOwnProperty(key) && !reservedProperties.has(key)) {
22497            config[key] = reference[key];
22498          }
22499        }
22500
22501        this.config = config;
22502      }
22503
22504      async init() {
22505        return this.getIndex();
22506      }
22507
22508      async getSequence(chr, start, end) {
22509        if (!(this.interval && this.interval.contains(chr, start, end))) {
22510          // Expand query, to minimum of 50kb
22511          let qstart = start;
22512          let qend = end;
22513
22514          if (end - start < 50000) {
22515            const w = end - start;
22516            const center = Math.round(start + w / 2);
22517            qstart = Math.max(0, center - 25000);
22518            qend = center + 25000;
22519          }
22520
22521          const seqBytes = await this.readSequence(chr, qstart, qend);
22522          this.interval = new GenomicInterval(chr, qstart, qend, seqBytes);
22523        }
22524
22525        const offset = start - this.interval.start;
22526        const n = end - start;
22527        const seq = this.interval.features ? this.interval.features.substr(offset, n) : null;
22528        return seq;
22529      }
22530
22531      async getIndex() {
22532        if (this.index) {
22533          return this.index;
22534        } else {
22535          const data = await igvxhr.load(this.indexFile, buildOptions(this.config));
22536          const lines = splitLines$3(data);
22537          const len = lines.length;
22538          let lineNo = 0;
22539          let order = 0;
22540          this.index = {};
22541
22542          while (lineNo < len) {
22543            const tokens = lines[lineNo++].split("\t");
22544            const nTokens = tokens.length;
22545
22546            if (nTokens === 5) {
22547              // Parse the index line.
22548              const chr = tokens[0];
22549              const size = parseInt(tokens[1]);
22550              const position = parseInt(tokens[2]);
22551              const basesPerLine = parseInt(tokens[3]);
22552              const bytesPerLine = parseInt(tokens[4]);
22553              const indexEntry = {
22554                size: size,
22555                position: position,
22556                basesPerLine: basesPerLine,
22557                bytesPerLine: bytesPerLine
22558              };
22559              this.chromosomeNames.push(chr);
22560              this.index[chr] = indexEntry;
22561              this.chromosomes[chr] = new Chromosome(chr, order++, 0, size);
22562            }
22563          }
22564
22565          return this.index;
22566        }
22567      }
22568
22569      async readSequence(chr, qstart, qend) {
22570        // let offset;
22571        // let start;
22572        // let end;
22573        // let basesPerLine;
22574        // let nEndBytes;
22575        await this.getIndex();
22576        const idxEntry = this.index[chr];
22577
22578        if (!idxEntry) {
22579          console.log("No index entry for chr: " + chr); // Tag interval with null so we don't try again
22580
22581          this.interval = new GenomicInterval(chr, qstart, qend, null);
22582          return null;
22583        } else {
22584          const start = Math.max(0, qstart); // qstart should never be < 0
22585
22586          const end = Math.min(idxEntry.size, qend);
22587          const bytesPerLine = idxEntry.bytesPerLine;
22588          const basesPerLine = idxEntry.basesPerLine;
22589          const position = idxEntry.position;
22590          const nEndBytes = bytesPerLine - basesPerLine;
22591          const startLine = Math.floor(start / basesPerLine);
22592          const endLine = Math.floor(end / basesPerLine);
22593          const base0 = startLine * basesPerLine; // Base at beginning of start line
22594
22595          const offset = start - base0;
22596          const startByte = position + startLine * bytesPerLine + offset;
22597          const base1 = endLine * basesPerLine;
22598          const offset1 = end - base1;
22599          const endByte = position + endLine * bytesPerLine + offset1 - 1;
22600          const byteCount = endByte - startByte + 1;
22601          let allBytes;
22602
22603          if (byteCount <= 0) {
22604            console.error("No sequence for " + chr + ":" + qstart + "-" + qend);
22605          } else {
22606            allBytes = await igvxhr.load(this.file, buildOptions(this.config, {
22607              range: {
22608                start: startByte,
22609                size: byteCount
22610              }
22611            }));
22612          }
22613
22614          if (!allBytes) {
22615            return null;
22616          } else {
22617            let nBases,
22618                seqBytes = "",
22619                srcPos = 0,
22620                allBytesLength = allBytes.length;
22621
22622            if (offset > 0) {
22623              nBases = Math.min(end - start, basesPerLine - offset);
22624              seqBytes += allBytes.substr(srcPos, nBases);
22625              srcPos += nBases + nEndBytes;
22626            }
22627
22628            while (srcPos < allBytesLength) {
22629              nBases = Math.min(basesPerLine, allBytesLength - srcPos);
22630              seqBytes += allBytes.substr(srcPos, nBases);
22631              srcPos += nBases + nEndBytes;
22632            }
22633
22634            return seqBytes;
22635          }
22636        }
22637      }
22638
22639    }
22640
22641    /*
22642     * The MIT License (MIT)
22643     *
22644     * Copyright (c) 2014 Broad Institute
22645     *
22646     * Permission is hereby granted, free of charge, to any person obtaining a copy
22647     * of this software and associated documentation files (the "Software"), to deal
22648     * in the Software without restriction, including without limitation the rights
22649     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22650     * copies of the Software, and to permit persons to whom the Software is
22651     * furnished to do so, subject to the following conditions:
22652     *
22653     * The above copyright notice and this permission notice shall be included in
22654     * all copies or substantial portions of the Software.
22655     *
22656     *
22657     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22658     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22659     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22660     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22661     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22662     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22663     * THE SOFTWARE.
22664     */
22665    const splitLines$2 = splitLines$5;
22666
22667    class ChromSizes {
22668      constructor(url) {
22669        this.url = url;
22670        this.chromosomeNames = [];
22671        this.chromosomes = {};
22672      }
22673
22674      async init() {
22675        return this.loadAll();
22676      }
22677
22678      async getSequence(chr, start, end) {
22679        return undefined; // TODO -- return array of "N"s?
22680      }
22681
22682      async loadAll() {
22683        let data;
22684
22685        if (isDataURL(this.url)) {
22686          let bytes = decodeDataURI$1(this.fastaURL);
22687          data = "";
22688
22689          for (let b of bytes) {
22690            data += String.fromCharCode(b);
22691          }
22692        } else {
22693          data = await igvxhr.load(this.url, {});
22694        }
22695
22696        this.chromosomeNames = [];
22697        this.chromosomes = {};
22698        const lines = splitLines$2(data);
22699        let order = 0;
22700
22701        for (let nextLine of lines) {
22702          const tokens = nextLine.split('\t');
22703          this.chromosomeNames.push(tokens[0]);
22704          const chrLength = Number.parseInt(tokens[1]);
22705          const chromosome = new Chromosome(tokens[0], order++, 0, chrLength);
22706          this.chromosomes[tokens[0]] = chromosome;
22707        }
22708      }
22709
22710    }
22711
22712    async function loadFasta(reference) {
22713      let fasta;
22714
22715      if ("chromsizes" === reference.format) {
22716        fasta = new ChromSizes(reference.fastaURL);
22717      } else if (isDataURL(reference.fastaURL) || reference.indexed === false) {
22718        fasta = new NonIndexedFasta(reference);
22719      } else {
22720        fasta = new FastaSequence(reference);
22721      }
22722
22723      await fasta.init();
22724      return fasta;
22725    }
22726
22727    const Cytoband = function (start, end, name, typestain) {
22728      this.start = start;
22729      this.end = end;
22730      this.name = name;
22731      this.stain = 0; // Set the type, either p, n, or c
22732
22733      if (typestain === 'acen') {
22734        this.type = 'c';
22735      } else {
22736        this.type = typestain.charAt(1);
22737
22738        if (this.type === 'p') {
22739          this.stain = parseInt(typestain.substring(4));
22740        }
22741      }
22742    };
22743
22744    const _version = "2.10.5";
22745
22746    function version$1() {
22747      return _version;
22748    }
22749
22750    /*
22751     * The MIT License (MIT)
22752     *
22753     * Copyright (c) 2014 Broad Institute
22754     *
22755     * Permission is hereby granted, free of charge, to any person obtaining a copy
22756     * of this software and associated documentation files (the "Software"), to deal
22757     * in the Software without restriction, including without limitation the rights
22758     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22759     * copies of the Software, and to permit persons to whom the Software is
22760     * furnished to do so, subject to the following conditions:
22761     *
22762     * The above copyright notice and this permission notice shall be included in
22763     * all copies or substantial portions of the Software.
22764     *
22765     *
22766     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22767     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22768     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22769     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22770     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22771     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22772     * THE SOFTWARE.
22773     */
22774    const DEFAULT_GENOMES_URL = "https://igv.org/genomes/genomes.json";
22775    const BACKUP_GENOMES_URL = "https://s3.amazonaws.com/igv.org.genomes/genomes.json";
22776    const splitLines$1 = splitLines$5;
22777    const GenomeUtils = {
22778      loadGenome: async function (options) {
22779        const cytobandUrl = options.cytobandURL;
22780        const aliasURL = options.aliasURL;
22781        const sequence = await loadFasta(options);
22782        let cytobands;
22783
22784        if (cytobandUrl) {
22785          cytobands = await loadCytobands(cytobandUrl, sequence.config);
22786        }
22787
22788        let aliases;
22789
22790        if (aliasURL) {
22791          aliases = await loadAliases(aliasURL, sequence.config);
22792        }
22793
22794        return new Genome(options, sequence, cytobands, aliases);
22795      },
22796      initializeGenomes: async function (config) {
22797        if (!GenomeUtils.KNOWN_GENOMES) {
22798          const table = {}; // Get default genomes
22799
22800          if (config.loadDefaultGenomes !== false) {
22801            try {
22802              const url = DEFAULT_GENOMES_URL + `?randomSeed=${Math.random().toString(36)}&version=${version$1()}`; // prevent caching
22803
22804              const jsonArray = await igvxhr.loadJson(url, {
22805                timeout: 5000
22806              });
22807              processJson(jsonArray);
22808            } catch (e) {
22809              console.error(e);
22810
22811              try {
22812                const url = BACKUP_GENOMES_URL + `?randomSeed=${Math.random().toString(36)}&version=${version$1()}`; // prevent caching
22813
22814                const jsonArray = await igvxhr.loadJson(url, {});
22815                processJson(jsonArray);
22816              } catch (e) {
22817                console.error(e);
22818                console.warn("Errors loading default genome definitions.");
22819              }
22820            }
22821          } // Add user-defined genomes
22822
22823
22824          const genomeList = config.genomeList || config.genomes;
22825
22826          if (genomeList) {
22827            if (typeof genomeList === 'string') {
22828              const jsonArray = await igvxhr.loadJson(genomeList, {});
22829              processJson(jsonArray);
22830            } else {
22831              processJson(genomeList);
22832            }
22833          }
22834
22835          GenomeUtils.KNOWN_GENOMES = table;
22836
22837          function processJson(jsonArray) {
22838            jsonArray.forEach(function (json) {
22839              table[json.id] = json;
22840            });
22841            return table;
22842          }
22843        }
22844      },
22845      isWholeGenomeView: function (chr) {
22846        return 'all' === chr.toLowerCase();
22847      },
22848      // Expand a genome id to a reference object, if needed
22849      expandReference: function (idOrConfig) {
22850        // idOrConfig might be json
22851        if (isString$3(idOrConfig) && idOrConfig.startsWith("{")) {
22852          try {
22853            idOrConfig = JSON.parse(idOrConfig);
22854          } catch (e) {// Apparently its not json,  could be an ID starting with "{".  Unusual but legal.
22855          }
22856        }
22857
22858        let genomeID;
22859
22860        if (isString$3(idOrConfig)) {
22861          genomeID = idOrConfig;
22862        } else if (idOrConfig.genome) {
22863          genomeID = idOrConfig.genome;
22864        } else if (idOrConfig.id !== undefined && idOrConfig.fastaURL === undefined) {
22865          // Backward compatibility
22866          genomeID = idOrConfig.id;
22867        }
22868
22869        if (genomeID) {
22870          const knownGenomes = GenomeUtils.KNOWN_GENOMES;
22871          const reference = knownGenomes[genomeID];
22872
22873          if (!reference) {
22874            Alert.presentAlert(new Error(`Unknown genome id: ${genomeID}`), undefined);
22875          }
22876
22877          return reference;
22878        } else {
22879          return idOrConfig;
22880        }
22881      }
22882    };
22883
22884    class Genome {
22885      constructor(config, sequence, ideograms, aliases) {
22886        this.config = config;
22887        this.id = config.id;
22888        this.sequence = sequence;
22889        this.chromosomeNames = sequence.chromosomeNames;
22890        this.chromosomes = sequence.chromosomes; // An object (functions as a dictionary)
22891
22892        this.ideograms = ideograms;
22893        this.featureDB = {}; // Hash of name -> feature, used for search function.
22894
22895        this.wholeGenomeView = config.wholeGenomeView === undefined || config.wholeGenomeView;
22896
22897        if (this.wholeGenomeView && Object.keys(sequence.chromosomes).length > 1) {
22898          constructWG(this, config);
22899        } else {
22900          this.wgChromosomeNames = sequence.chromosomeNames;
22901        }
22902        /**
22903         * Return the official chromosome name for the (possibly) alias.  Deals with
22904         * 1 <-> chr1,  chrM <-> MT,  IV <-> chr4, etc.
22905         * @param str
22906         */
22907
22908
22909        var chrAliasTable = {},
22910            self = this; // The standard mappings
22911
22912        chrAliasTable["all"] = "all";
22913        this.chromosomeNames.forEach(function (name) {
22914          var alias = name.startsWith("chr") ? name.substring(3) : "chr" + name;
22915          chrAliasTable[alias.toLowerCase()] = name;
22916          if (name === "chrM") chrAliasTable["mt"] = "chrM";
22917          if (name === "MT") chrAliasTable["chrm"] = "MT";
22918          chrAliasTable[name.toLowerCase()] = name;
22919        }); // Custom mappings
22920
22921        if (aliases) {
22922          aliases.forEach(function (array) {
22923            // Find the official chr name
22924            var defName, i;
22925
22926            for (i = 0; i < array.length; i++) {
22927              if (self.chromosomes[array[i]]) {
22928                defName = array[i];
22929                break;
22930              }
22931            }
22932
22933            if (defName) {
22934              array.forEach(function (alias) {
22935                if (alias !== defName) {
22936                  chrAliasTable[alias.toLowerCase()] = defName;
22937                  chrAliasTable[alias] = defName; // Should not be needed
22938                }
22939              });
22940            }
22941          });
22942        }
22943
22944        this.chrAliasTable = chrAliasTable;
22945      }
22946
22947      showWholeGenomeView() {
22948        return this.config.wholeGenomeView !== false;
22949      }
22950
22951      toJSON() {
22952        return Object.assign({}, this.config, {
22953          tracks: undefined
22954        });
22955      }
22956
22957      getInitialLocus() {}
22958
22959      getHomeChromosomeName() {
22960        if (this.showWholeGenomeView() && this.chromosomes.hasOwnProperty("all")) {
22961          return "all";
22962        } else {
22963          return this.chromosomeNames[0];
22964        }
22965      }
22966
22967      getChromosomeName(str) {
22968        const chr = str ? this.chrAliasTable[str.toLowerCase()] : str;
22969        return chr ? chr : str;
22970      }
22971
22972      getChromosome(chr) {
22973        chr = this.getChromosomeName(chr);
22974        return this.chromosomes[chr];
22975      }
22976
22977      getCytobands(chr) {
22978        return this.ideograms ? this.ideograms[chr] : null;
22979      }
22980
22981      getLongestChromosome() {
22982        var longestChr,
22983            chromosomes = this.chromosomes;
22984
22985        for (let key in chromosomes) {
22986          if (chromosomes.hasOwnProperty(key)) {
22987            var chr = chromosomes[key];
22988
22989            if (longestChr === undefined || chr.bpLength > longestChr.bpLength) {
22990              longestChr = chr;
22991            }
22992          }
22993
22994          return longestChr;
22995        }
22996      }
22997
22998      getChromosomes() {
22999        return this.chromosomes;
23000      }
23001      /**
23002       * Return the genome coordinate in kb for the give chromosome and position.
23003       * NOTE: This might return undefined if the chr is filtered from whole genome view.
23004       */
23005
23006
23007      getGenomeCoordinate(chr, bp) {
23008        var offset = this.getCumulativeOffset(chr);
23009        if (offset === undefined) return undefined;
23010        return offset + bp;
23011      }
23012      /**
23013       * Return the chromosome and coordinate in bp for the given genome coordinate
23014       */
23015
23016
23017      getChromosomeCoordinate(genomeCoordinate) {
23018        if (this.cumulativeOffsets === undefined) {
23019          this.cumulativeOffsets = computeCumulativeOffsets.call(this);
23020        }
23021
23022        let lastChr = undefined;
23023        let lastCoord = 0;
23024
23025        for (let name of this.wgChromosomeNames) {
23026          const cumulativeOffset = this.cumulativeOffsets[name];
23027
23028          if (cumulativeOffset > genomeCoordinate) {
23029            const position = genomeCoordinate - lastCoord;
23030            return {
23031              chr: lastChr,
23032              position: position
23033            };
23034          }
23035
23036          lastChr = name;
23037          lastCoord = cumulativeOffset;
23038        } // If we get here off the end
23039
23040
23041        return {
23042          chr: this.wgChromosomeNames[this.wgChromosomeNames.length - 1],
23043          position: 0
23044        };
23045      }
23046
23047      /**
23048       * Return the offset in genome coordinates (kb) of the start of the given chromosome
23049       * NOTE:  This might return undefined if the chromosome is filtered from whole genome view.
23050       */
23051      getCumulativeOffset(chr) {
23052        if (this.cumulativeOffsets === undefined) {
23053          this.cumulativeOffsets = computeCumulativeOffsets.call(this);
23054        }
23055
23056        const queryChr = this.getChromosomeName(chr);
23057        return this.cumulativeOffsets[queryChr];
23058
23059        function computeCumulativeOffsets() {
23060          let self = this;
23061          let acc = {};
23062          let offset = 0;
23063
23064          for (let name of self.wgChromosomeNames) {
23065            acc[name] = Math.floor(offset);
23066            const chromosome = self.getChromosome(name);
23067            offset += chromosome.bpLength;
23068          }
23069
23070          return acc;
23071        }
23072      }
23073      /**
23074       * Return the nominal genome length, this is the length of the main chromosomes (no scaffolds, etc).
23075       */
23076
23077
23078      getGenomeLength() {
23079        let self = this;
23080
23081        if (!this.bpLength) {
23082          let bpLength = 0;
23083          self.wgChromosomeNames.forEach(function (cname) {
23084            let c = self.chromosomes[cname];
23085            bpLength += c.bpLength;
23086          });
23087          this.bpLength = bpLength;
23088        }
23089
23090        return this.bpLength;
23091      }
23092
23093      async getSequence(chr, start, end) {
23094        return this.sequence.getSequence(chr, start, end);
23095      }
23096
23097    }
23098
23099    async function loadCytobands(cytobandUrl, config) {
23100      let data;
23101
23102      if (isDataURL(cytobandUrl)) {
23103        const plain = decodeDataURI$1(cytobandUrl);
23104        data = "";
23105        const len = plain.length;
23106
23107        for (let i = 0; i < len; i++) {
23108          data += String.fromCharCode(plain[i]);
23109        }
23110      } else {
23111        data = await igvxhr.loadString(cytobandUrl, buildOptions(config));
23112      } // var bands = [],
23113      //     lastChr,
23114      //     n = 0,
23115      //     c = 1,
23116      //
23117      //     len = lines.length,
23118
23119
23120      const cytobands = {};
23121      let lastChr;
23122      let bands = [];
23123      const lines = splitLines$1(data);
23124
23125      for (let line of lines) {
23126        var tokens = line.split("\t");
23127        var chr = tokens[0];
23128        if (!lastChr) lastChr = chr;
23129
23130        if (chr !== lastChr) {
23131          cytobands[lastChr] = bands;
23132          bands = [];
23133          lastChr = chr;
23134        }
23135
23136        if (tokens.length === 5) {
23137          //10	0	3000000	p15.3	gneg
23138          var start = parseInt(tokens[1]);
23139          var end = parseInt(tokens[2]);
23140          var name = tokens[3];
23141          var stain = tokens[4];
23142          bands.push(new Cytoband(start, end, name, stain));
23143        }
23144      }
23145
23146      return cytobands;
23147    }
23148
23149    function loadAliases(aliasURL, config) {
23150      return igvxhr.loadString(aliasURL, buildOptions(config)).then(function (data) {
23151        var lines = splitLines$1(data),
23152            aliases = [];
23153        lines.forEach(function (line) {
23154          if (!line.startsWith("#") && line.length > 0) aliases.push(line.split("\t"));
23155        });
23156        return aliases;
23157      });
23158    }
23159
23160    function constructWG(genome, config) {
23161      let wgChromosomes;
23162
23163      if (config.chromosomeOrder) {
23164        if (Array.isArray(config.chromosomeOrder)) {
23165          genome.wgChromosomeNames = config.chromosomeOrder;
23166        } else {
23167          genome.wgChromosomeNames = config.chromosomeOrder.split(',').map(nm => nm.trim());
23168        }
23169
23170        wgChromosomes = genome.wgChromosomeNames.map(nm => genome.chromosomes[nm]).filter(chr => chr !== undefined);
23171      } else {
23172        // Trim small chromosomes.
23173        const lengths = Object.keys(genome.chromosomes).map(key => genome.chromosomes[key].bpLength);
23174        const median = lengths.reduce((a, b) => Math.max(a, b));
23175        const threshold = median / 50;
23176        wgChromosomes = Object.values(genome.chromosomes).filter(chr => chr.bpLength > threshold); // Sort chromosomes.  First segregate numeric and alpha names, sort numeric, leave alpha as is
23177
23178        const numericChromosomes = wgChromosomes.filter(chr => isDigit(chr.name.replace('chr', '')));
23179        const alphaChromosomes = wgChromosomes.filter(chr => !isDigit(chr.name.replace('chr', '')));
23180        numericChromosomes.sort((a, b) => Number.parseInt(a.name.replace('chr', '')) - Number.parseInt(b.name.replace('chr', '')));
23181        const wgChromosomeNames = numericChromosomes.map(chr => chr.name);
23182
23183        for (let chr of alphaChromosomes) {
23184          wgChromosomeNames.push(chr.name);
23185        }
23186
23187        genome.wgChromosomeNames = wgChromosomeNames;
23188      } // Compute psuedo-chromosome "all"
23189
23190
23191      const l = wgChromosomes.reduce((accumulator, currentValue) => accumulator += currentValue.bpLength, 0);
23192      genome.chromosomes["all"] = {
23193        name: "all",
23194        bpLength: l
23195      };
23196
23197      function isDigit(val) {
23198        return /^\d+$/.test(val);
23199      }
23200    }
23201
23202    /**
23203     * Created by dat on 9/16/16.
23204     */
23205    const NOT_LOADED_MESSAGE = 'Error loading track data';
23206    let lastClickTime = 0;
23207    let popupTimerID;
23208
23209    class TrackViewport extends Viewport {
23210      constructor(trackView, viewportColumn, referenceFrame, width) {
23211        super(trackView, viewportColumn, referenceFrame, width);
23212      }
23213
23214      initializationHelper() {
23215        this.$spinner = $$1('<div>', {
23216          class: 'igv-loading-spinner-container'
23217        });
23218        this.$viewport.append(this.$spinner);
23219        this.$spinner.append($$1('<div>'));
23220        const {
23221          track
23222        } = this.trackView;
23223
23224        if ('sequence' !== track.type) {
23225          this.$zoomInNotice = this.createZoomInNotice(this.$content);
23226        }
23227
23228        if (track.name && "sequence" !== track.config.type) {
23229          this.$trackLabel = $$1('<div class="igv-track-label">');
23230          this.$viewport.append(this.$trackLabel);
23231          this.setTrackLabel(track.name);
23232
23233          if (false === this.browser.trackLabelsVisible) {
23234            this.$trackLabel.hide();
23235          }
23236        }
23237
23238        this.stopSpinner();
23239        this.addMouseHandlers();
23240      }
23241
23242      setTrackLabel(label) {
23243        this.$trackLabel.empty();
23244        this.$trackLabel.html(label);
23245        const txt = this.$trackLabel.text();
23246        this.$trackLabel.attr('title', txt);
23247      }
23248
23249      startSpinner() {
23250        this.$spinner.show();
23251      }
23252
23253      stopSpinner() {
23254        this.$spinner.hide();
23255      }
23256
23257      checkZoomIn() {
23258        const showZoomInNotice = () => {
23259          const referenceFrame = this.referenceFrame;
23260
23261          if (this.referenceFrame.chr.toLowerCase() === "all" && !this.trackView.track.supportsWholeGenome()) {
23262            return true;
23263          } else {
23264            const visibilityWindow = this.trackView.track.visibilityWindow;
23265            return visibilityWindow !== undefined && visibilityWindow > 0 && referenceFrame.bpPerPixel * this.$viewport.width() > visibilityWindow;
23266          }
23267        };
23268
23269        if (!this.viewIsReady()) {
23270          return false;
23271        }
23272
23273        if (this.$zoomInNotice) {
23274          if (showZoomInNotice()) {
23275            // Out of visibility window
23276            if (this.canvas) {
23277              this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
23278              this.tile = undefined;
23279            }
23280
23281            this.$zoomInNotice.show();
23282
23283            if (this.trackView.track.autoHeight) {
23284              const minHeight = this.trackView.minHeight || 0;
23285              this.setContentHeight(minHeight);
23286            }
23287
23288            return false;
23289          } else {
23290            this.$zoomInNotice.hide();
23291            return true;
23292          }
23293        }
23294
23295        return true;
23296      }
23297
23298      shift() {
23299        const self = this;
23300        const referenceFrame = self.referenceFrame;
23301
23302        if (self.canvas && self.tile && self.tile.chr === self.referenceFrame.chr && self.tile.bpPerPixel === referenceFrame.bpPerPixel) {
23303          const pixelOffset = Math.round((self.tile.startBP - referenceFrame.start) / referenceFrame.bpPerPixel);
23304          self.canvas.style.left = pixelOffset + "px";
23305        }
23306      }
23307
23308      async loadFeatures() {
23309        const referenceFrame = this.referenceFrame;
23310        const chr = referenceFrame.chr; // Expand the requested range so we can pan a bit without reloading.  But not beyond chromosome bounds
23311
23312        const chrLength = this.browser.genome.getChromosome(chr).bpLength;
23313        const pixelWidth = this.$content.width(); // * 3;
23314
23315        const bpWidth = pixelWidth * referenceFrame.bpPerPixel;
23316        const bpStart = Math.floor(Math.max(0, referenceFrame.start - bpWidth));
23317        const bpEnd = Math.ceil(Math.min(chrLength, referenceFrame.start + bpWidth + bpWidth)); // Add one screen width to end
23318
23319        if (this.loading && this.loading.start === bpStart && this.loading.end === bpEnd) {
23320          return undefined;
23321        }
23322
23323        this.loading = {
23324          start: bpStart,
23325          end: bpEnd
23326        };
23327        this.startSpinner();
23328
23329        try {
23330          const features = await this.getFeatures(this.trackView.track, chr, bpStart, bpEnd, referenceFrame.bpPerPixel);
23331          let roiFeatures = [];
23332          const roi = mergeArrays(this.browser.roi, this.trackView.track.roi);
23333
23334          if (roi) {
23335            for (let r of roi) {
23336              const f = await r.getFeatures(chr, bpStart, bpEnd, referenceFrame.bpPerPixel);
23337              roiFeatures.push({
23338                track: r,
23339                features: f
23340              });
23341            }
23342          }
23343
23344          this.tile = new Tile(chr, bpStart, bpEnd, referenceFrame.bpPerPixel, features, roiFeatures);
23345          this.loading = false;
23346          this.hideMessage();
23347          this.stopSpinner();
23348          return this.tile;
23349        } catch (error) {
23350          // Track might have been removed during load
23351          if (this.trackView && this.trackView.disposed !== true) {
23352            this.showMessage(NOT_LOADED_MESSAGE);
23353            Alert.presentAlert(error);
23354            console.error(error);
23355          }
23356        } finally {
23357          this.loading = false;
23358          this.stopSpinner();
23359        }
23360      }
23361
23362      async repaint() {
23363        if (undefined === this.tile) {
23364          return;
23365        }
23366
23367        let {
23368          features,
23369          roiFeatures,
23370          bpPerPixel,
23371          startBP,
23372          endBP
23373        } = this.tile; // const isWGV = GenomeUtils.isWholeGenomeView(this.browser.referenceFrameList[0].chr)
23374
23375        const isWGV = GenomeUtils.isWholeGenomeView(this.referenceFrame.chr);
23376        let pixelWidth;
23377
23378        if (isWGV) {
23379          bpPerPixel = this.referenceFrame.end / this.$viewport.width();
23380          startBP = 0;
23381          endBP = this.referenceFrame.end;
23382          pixelWidth = this.$viewport.width();
23383        } else {
23384          pixelWidth = Math.ceil((endBP - startBP) / bpPerPixel);
23385        } // For deep tracks we paint a canvas == 3*viewportHeight centered on the current vertical scroll position
23386
23387
23388        const viewportHeight = this.$viewport.height();
23389        const contentHeight = this.getContentHeight();
23390        const minHeight = roiFeatures ? Math.max(contentHeight, viewportHeight) : contentHeight; // Need to fill viewport for ROIs.
23391
23392        let pixelHeight = Math.min(minHeight, 3 * viewportHeight);
23393
23394        if (0 === pixelWidth || 0 === pixelHeight) {
23395          if (this.canvas) {
23396            $$1(this.canvas).remove();
23397          }
23398
23399          return;
23400        }
23401
23402        const canvasTop = Math.max(0, -this.$content.position().top - viewportHeight); // Always use high DPI if in compressed display mode, otherwise use preference setting;
23403
23404        let devicePixelRatio;
23405
23406        if ("FILL" === this.trackView.track.displayMode) {
23407          devicePixelRatio = window.devicePixelRatio;
23408        } else {
23409          devicePixelRatio = this.trackView.track.supportHiDPI === false ? 1 : window.devicePixelRatio;
23410        }
23411
23412        const pixelXOffset = Math.round((startBP - this.referenceFrame.start) / this.referenceFrame.bpPerPixel);
23413        const newCanvas = $$1('<canvas class="igv-canvas">').get(0);
23414        const ctx = newCanvas.getContext("2d");
23415        newCanvas.style.width = pixelWidth + "px";
23416        newCanvas.style.height = pixelHeight + "px";
23417        newCanvas.width = devicePixelRatio * pixelWidth;
23418        newCanvas.height = devicePixelRatio * pixelHeight;
23419        ctx.scale(devicePixelRatio, devicePixelRatio);
23420        newCanvas.style.left = pixelXOffset + "px";
23421        newCanvas.style.top = canvasTop + "px";
23422        ctx.translate(0, -canvasTop);
23423        const drawConfiguration = {
23424          context: ctx,
23425          pixelXOffset,
23426          pixelWidth,
23427          pixelHeight,
23428          pixelTop: canvasTop,
23429          bpStart: startBP,
23430          bpEnd: endBP,
23431          bpPerPixel,
23432          referenceFrame: this.referenceFrame,
23433          selection: this.selection,
23434          viewport: this,
23435          viewportWidth: this.$viewport.width()
23436        };
23437        this.draw(drawConfiguration, features, roiFeatures);
23438        this.canvasVerticalRange = {
23439          top: canvasTop,
23440          bottom: canvasTop + pixelHeight
23441        };
23442
23443        if (this.$canvas) {
23444          this.$canvas.remove();
23445        }
23446
23447        this.$canvas = $$1(newCanvas);
23448        this.$content.append(this.$canvas);
23449        this.canvas = newCanvas;
23450        this.ctx = ctx;
23451      }
23452
23453      draw(drawConfiguration, features, roiFeatures) {
23454        // console.log(`${ Date.now() } viewport draw(). track ${ this.trackView.track.type }. content-css-top ${ this.$content.css('top') }. canvas-top ${ drawConfiguration.pixelTop }.`)
23455        if (features) {
23456          drawConfiguration.features = features;
23457          this.trackView.track.draw(drawConfiguration);
23458        }
23459
23460        if (roiFeatures) {
23461          for (let r of roiFeatures) {
23462            drawConfiguration.features = r.features;
23463            r.track.draw(drawConfiguration);
23464          }
23465        }
23466      } // TODO: Nolonger used. Will discard
23467
23468
23469      async toSVG(tile) {
23470        // Nothing to do if zoomInNotice is active
23471        if (this.$zoomInNotice && this.$zoomInNotice.is(":visible")) {
23472          return;
23473        }
23474
23475        const referenceFrame = this.referenceFrame;
23476        const bpPerPixel = tile.bpPerPixel;
23477        const features = tile.features;
23478        const roiFeatures = tile.roiFeatures;
23479        const pixelWidth = this.$viewport.width();
23480        const pixelHeight = this.$viewport.height();
23481        const bpStart = referenceFrame.start;
23482        const bpEnd = referenceFrame.start + pixelWidth * referenceFrame.bpPerPixel;
23483        const ctx$1 = new ctx({
23484          // svg
23485          width: pixelWidth,
23486          height: pixelHeight,
23487          viewbox: {
23488            x: 0,
23489            y: -this.$content.position().top,
23490            width: pixelWidth,
23491            height: pixelHeight
23492          }
23493        });
23494        const drawConfiguration = {
23495          viewport: this,
23496          context: ctx$1,
23497          top: -this.$content.position().top,
23498          pixelTop: 0,
23499          // for compatibility with canvas draw
23500          pixelWidth,
23501          pixelHeight,
23502          bpStart,
23503          bpEnd,
23504          bpPerPixel,
23505          referenceFrame: this.referenceFrame,
23506          selection: this.selection,
23507          viewportWidth: pixelWidth
23508        };
23509        this.draw(drawConfiguration, features, roiFeatures);
23510        return ctx$1.getSerializedSvg(true);
23511      }
23512
23513      containsPosition(chr, position) {
23514        if (this.referenceFrame.chr === chr && position >= this.referenceFrame.start) {
23515          return position <= this.referenceFrame.calculateEnd(this.getWidth());
23516        } else {
23517          return false;
23518        }
23519      }
23520
23521      isLoading() {
23522        return this.loading;
23523      }
23524
23525      saveImage() {
23526        if (!this.ctx) return;
23527        const canvasTop = this.canvasVerticalRange ? this.canvasVerticalRange.top : 0;
23528        const devicePixelRatio = window.devicePixelRatio;
23529        const w = this.$viewport.width() * devicePixelRatio;
23530        const h = this.$viewport.height() * devicePixelRatio;
23531        const x = -$$1(this.canvas).position().left * devicePixelRatio;
23532        const y = (-this.$content.position().top - canvasTop) * devicePixelRatio;
23533        const imageData = this.ctx.getImageData(x, y, w, h);
23534        const exportCanvas = document.createElement('canvas');
23535        const exportCtx = exportCanvas.getContext('2d');
23536        exportCanvas.width = imageData.width;
23537        exportCanvas.height = imageData.height;
23538        exportCtx.putImageData(imageData, 0, 0); // filename = this.trackView.track.name + ".png";
23539
23540        const filename = (this.$trackLabel.text() ? this.$trackLabel.text() : "image") + ".png";
23541        const data = exportCanvas.toDataURL("image/png");
23542        download(filename, data);
23543      }
23544
23545      saveSVG() {
23546        const {
23547          width,
23548          height
23549        } = this.$viewport.get(0).getBoundingClientRect();
23550        const config = {
23551          width,
23552          height,
23553          viewbox: {
23554            x: 0,
23555            y: -this.$content.position().top,
23556            width,
23557            height
23558          }
23559        };
23560        const context = new ctx(config);
23561        const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, '');
23562        const index = this.browser.referenceFrameList.indexOf(this.referenceFrame);
23563        const id = `${str}_referenceFrame_${index}_guid_${guid$1()}`;
23564        this.drawSVGWithContext(context, width, height, id, 0, 0, 0);
23565        const svg = context.getSerializedSvg(true);
23566        const data = URL.createObjectURL(new Blob([svg], {
23567          type: "application/octet-stream"
23568        }));
23569        download(`${id}.svg`, data);
23570      } // called by trackView.renderSVGContext() when rendering
23571      // entire browser as SVG
23572
23573
23574      renderSVGContext(context, _ref) {
23575        let {
23576          deltaX,
23577          deltaY
23578        } = _ref;
23579
23580        // Nothing to do if zoomInNotice is active
23581        if (this.$zoomInNotice && this.$zoomInNotice.is(":visible")) {
23582          return;
23583        }
23584
23585        const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, '');
23586        const index = this.browser.referenceFrameList.indexOf(this.referenceFrame);
23587        const id = `${str}_referenceFrame_${index}_guid_${guid$1()}`;
23588        const {
23589          top: yScrollDelta
23590        } = this.$content.position();
23591        const {
23592          width,
23593          height
23594        } = this.$viewport.get(0).getBoundingClientRect();
23595        this.drawSVGWithContext(context, width, height, id, deltaX, deltaY + yScrollDelta, -yScrollDelta);
23596
23597        if (this.$trackLabel && true === this.browser.trackLabelsVisible) {
23598          const {
23599            x,
23600            y,
23601            width,
23602            height
23603          } = relativeDOMBBox(this.$viewport.get(0), this.$trackLabel.get(0));
23604          this.renderTrackLabelSVG(context, deltaX + x, deltaY + y, width, height);
23605        }
23606      } // render track label element called from renderSVGContext()
23607
23608
23609      renderTrackLabelSVG(context, tx, ty, width, height) {
23610        const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, '');
23611        const id = `${str}_track_label_guid_${guid$1()}`;
23612        context.saveWithTranslationAndClipRect(id, tx, ty, width, height, 0);
23613        context.fillStyle = "white";
23614        context.fillRect(0, 0, width, height);
23615        context.font = "12px Arial";
23616        context.fillStyle = 'rgb(68, 68, 68)';
23617        const {
23618          width: stringWidth
23619        } = context.measureText(this.$trackLabel.text());
23620        const dx = 0.25 * (width - stringWidth);
23621        const dy = 0.7 * (height - 12);
23622        context.fillText(this.$trackLabel.text(), dx, height - dy);
23623        context.strokeStyle = 'rgb(68, 68, 68)';
23624        context.strokeRect(0, 0, width, height);
23625        context.restore();
23626      } // called by renderSVGContext()
23627
23628
23629      drawSVGWithContext(context, width, height, id, x, y, yClipOffset) {
23630        context.saveWithTranslationAndClipRect(id, x, y, width, height, yClipOffset);
23631        let {
23632          start,
23633          bpPerPixel
23634        } = this.referenceFrame;
23635        const config = {
23636          context,
23637          viewport: this,
23638          referenceFrame: this.referenceFrame,
23639          top: yClipOffset,
23640          pixelTop: yClipOffset,
23641          pixelWidth: width,
23642          pixelHeight: height,
23643          bpStart: start,
23644          bpEnd: start + width * bpPerPixel,
23645          bpPerPixel,
23646          viewportWidth: width,
23647          selection: this.selection
23648        };
23649        const features = this.tile ? this.tile.features : [];
23650        const roiFeatures = this.tile ? this.tile.roiFeatures : undefined;
23651        this.draw(config, features, roiFeatures);
23652        context.restore();
23653      }
23654
23655      getCachedFeatures() {
23656        return this.tile ? this.tile.features : [];
23657      }
23658
23659      async getFeatures(track, chr, start, end, bpPerPixel) {
23660        if (this.tile && this.tile.containsRange(chr, start, end, bpPerPixel)) {
23661          return this.tile.features;
23662        } else if (typeof track.getFeatures === "function") {
23663          const features = await track.getFeatures(chr, start, end, bpPerPixel, this);
23664          this.cachedFeatures = features;
23665          this.checkContentHeight();
23666          return features;
23667        } else {
23668          return undefined;
23669        }
23670      }
23671
23672      createZoomInNotice($parent) {
23673        const $container = $$1('<div>', {
23674          class: 'igv-zoom-in-notice-container'
23675        });
23676        $parent.append($container);
23677        const $e = $$1('<div>');
23678        $container.append($e);
23679        $e.text('Zoom in to see features');
23680        $container.hide();
23681        return $container;
23682      }
23683
23684      viewIsReady() {
23685        return this.browser && this.browser.referenceFrameList && this.referenceFrame;
23686      }
23687
23688      addMouseHandlers() {
23689        this.addViewportContextMenuHandler(this.$viewport.get(0));
23690        this.addViewportMouseDownHandler(this.$viewport.get(0));
23691        this.addViewportTouchStartHandler(this.$viewport.get(0));
23692        this.addViewportMouseUpHandler(this.$viewport.get(0));
23693        this.addViewportTouchEndHandler(this.$viewport.get(0));
23694        this.addViewportClickHandler(this.$viewport.get(0));
23695
23696        if (this.trackView.track.name && "sequence" !== this.trackView.track.config.type) {
23697          this.addTrackLabelClickHandler(this.$trackLabel.get(0));
23698        }
23699      }
23700
23701      removeMouseHandlers() {
23702        this.removeViewportContextMenuHandler(this.$viewport.get(0));
23703        this.removeViewportMouseDownHandler(this.$viewport.get(0));
23704        this.removeViewportTouchStartHandler(this.$viewport.get(0));
23705        this.removeViewportMouseUpHandler(this.$viewport.get(0));
23706        this.removeViewportTouchEndHandler(this.$viewport.get(0));
23707        this.removeViewportClickHandler(this.$viewport.get(0));
23708
23709        if (this.trackView.track.name && "sequence" !== this.trackView.track.config.type) {
23710          this.removeTrackLabelClickHandler(this.$trackLabel.get(0));
23711        }
23712      }
23713
23714      addViewportContextMenuHandler(viewport) {
23715        this.boundContextMenuHandler = contextMenuHandler.bind(this);
23716        viewport.addEventListener('contextmenu', this.boundContextMenuHandler);
23717
23718        function contextMenuHandler(event) {
23719          // Ignore if we are doing a drag.  This can happen with touch events.
23720          if (this.browser.dragObject) {
23721            return false;
23722          }
23723
23724          const clickState = createClickState(event, this);
23725
23726          if (undefined === clickState) {
23727            return false;
23728          }
23729
23730          event.preventDefault(); // Track specific items
23731
23732          let menuItems = [];
23733
23734          if (typeof this.trackView.track.contextMenuItemList === "function") {
23735            const trackMenuItems = this.trackView.track.contextMenuItemList(clickState);
23736
23737            if (trackMenuItems) {
23738              menuItems = trackMenuItems;
23739            }
23740          } // Add items common to all tracks
23741
23742
23743          if (menuItems.length > 0) {
23744            menuItems.push({
23745              label: $$1('<HR>')
23746            });
23747          }
23748
23749          menuItems.push({
23750            label: 'Save Image (PNG)',
23751            click: () => this.saveImage()
23752          });
23753          menuItems.push({
23754            label: 'Save Image (SVG)',
23755            click: () => this.saveSVG()
23756          });
23757          this.browser.menuPopup.presentTrackContextMenu(event, menuItems);
23758        }
23759      }
23760
23761      removeViewportContextMenuHandler(viewport) {
23762        viewport.removeEventListener('contextmenu', this.boundContextMenuHandler);
23763      }
23764
23765      addViewportMouseDownHandler(viewport) {
23766        this.boundMouseDownHandler = mouseDownHandler.bind(this);
23767        viewport.addEventListener('mousedown', this.boundMouseDownHandler);
23768      }
23769
23770      removeViewportMouseDownHandler(viewport) {
23771        viewport.removeEventListener('mousedown', this.boundMouseDownHandler);
23772      }
23773
23774      addViewportTouchStartHandler(viewport) {
23775        this.boundTouchStartHandler = mouseDownHandler.bind(this);
23776        viewport.addEventListener('touchstart', this.boundTouchStartHandler);
23777      }
23778
23779      removeViewportTouchStartHandler(viewport) {
23780        viewport.removeEventListener('touchstart', this.boundTouchStartHandler);
23781      }
23782
23783      addViewportMouseUpHandler(viewport) {
23784        this.boundMouseUpHandler = mouseUpHandler.bind(this);
23785        viewport.addEventListener('mouseup', this.boundMouseUpHandler);
23786      }
23787
23788      removeViewportMouseUpHandler(viewport) {
23789        viewport.removeEventListener('mouseup', this.boundMouseUpHandler);
23790      }
23791
23792      addViewportTouchEndHandler(viewport) {
23793        this.boundTouchEndHandler = mouseUpHandler.bind(this);
23794        viewport.addEventListener('touchend', this.boundTouchEndHandler);
23795      }
23796
23797      removeViewportTouchEndHandler(viewport) {
23798        viewport.removeEventListener('touchend', this.boundTouchEndHandler);
23799      }
23800
23801      addViewportClickHandler(viewport) {
23802        this.boundClickHandler = clickHandler.bind(this);
23803        viewport.addEventListener('click', this.boundClickHandler);
23804
23805        function clickHandler(event) {
23806          if (this.enableClick) {
23807            if (3 === event.which || event.ctrlKey) {
23808              return;
23809            } // Close any currently open popups
23810
23811
23812            $$1('.igv-popover').hide();
23813
23814            if (this.browser.dragObject || this.browser.isScrolling) {
23815              return;
23816            } // Treat as a mouse click, its either a single or double click.
23817            // Handle here and stop propogation / default
23818
23819
23820            event.preventDefault();
23821            const mouseX = translateMouseCoordinates$1(event, this.$viewport.get(0)).x;
23822            const mouseXCanvas = translateMouseCoordinates$1(event, this.canvas).x;
23823            const referenceFrame = this.referenceFrame;
23824            const xBP = Math.floor(referenceFrame.start + referenceFrame.toBP(mouseXCanvas));
23825            const time = Date.now();
23826
23827            if (time - lastClickTime < this.browser.constants.doubleClickDelay) {
23828              // double-click
23829              if (popupTimerID) {
23830                window.clearTimeout(popupTimerID);
23831                popupTimerID = undefined;
23832              }
23833
23834              const centerBP = Math.round(referenceFrame.start + referenceFrame.toBP(mouseX));
23835              let string;
23836
23837              if ('all' === this.referenceFrame.chr.toLowerCase()) {
23838                const chr = this.browser.genome.getChromosomeCoordinate(centerBP).chr;
23839
23840                if (1 === this.browser.referenceFrameList.length) {
23841                  string = chr;
23842                } else {
23843                  const loci = this.browser.referenceFrameList.map(_ref2 => {
23844                    let {
23845                      locusSearchString
23846                    } = _ref2;
23847                    return locusSearchString;
23848                  });
23849                  const index = this.browser.referenceFrameList.indexOf(this.referenceFrame);
23850                  loci[index] = chr;
23851                  string = loci.join(' ');
23852                }
23853
23854                this.browser.search(string);
23855              } else {
23856                this.browser.zoomWithScaleFactor(0.5, centerBP, this.referenceFrame);
23857              }
23858            } else {
23859              // single-click
23860              if (event.shiftKey && typeof this.trackView.track.shiftClick === "function") {
23861                this.trackView.track.shiftClick(xBP, event);
23862              } else if (typeof this.trackView.track.popupData === "function") {
23863                popupTimerID = setTimeout(() => {
23864                  const content = getPopupContent(event, this);
23865
23866                  if (content) {
23867                    if (this.popover) this.popover.dispose();
23868                    this.popover = new Popover(this.browser.columnContainer);
23869                    this.popover.presentContentWithEvent(event, content);
23870                  }
23871
23872                  window.clearTimeout(popupTimerID);
23873                  popupTimerID = undefined;
23874                }, this.browser.constants.doubleClickDelay);
23875              }
23876            }
23877
23878            lastClickTime = time;
23879          }
23880        }
23881      }
23882
23883      removeViewportClickHandler(viewport) {
23884        viewport.removeEventListener('click', this.boundClickHandler);
23885      }
23886
23887      addTrackLabelClickHandler(trackLabel) {
23888        this.boundTrackLabelClickHandler = clickHandler.bind(this);
23889        trackLabel.addEventListener('click', this.boundTrackLabelClickHandler);
23890
23891        function clickHandler(event) {
23892          event.stopPropagation();
23893          const {
23894            track
23895          } = this.trackView;
23896          let str;
23897
23898          if (typeof track.description === 'function') {
23899            str = track.description();
23900          } else if (track.description) {
23901            str = `<div>${track.description}</div>`;
23902          } else {
23903            if (track.url) {
23904              if (isFile(track.url)) {
23905                str = `<div><b>Filename: </b>${track.url.name}`;
23906              } else {
23907                str = `<div><b>URL: </b>${track.url}`;
23908              }
23909            } else {
23910              str = track.name;
23911            }
23912          }
23913
23914          if (this.popover) {
23915            this.popover.dispose();
23916          }
23917
23918          this.popover = new Popover(this.browser.columnContainer, track.name || 'unnamed');
23919          this.popover.presentContentWithEvent(event, str);
23920        }
23921      }
23922
23923      removeTrackLabelClickHandler(trackLabel) {
23924        trackLabel.removeEventListener('click', this.boundTrackLabelClickHandler);
23925      }
23926
23927    }
23928
23929    function mouseDownHandler(event) {
23930      this.enableClick = true;
23931      this.browser.mouseDownOnViewport(event, this);
23932      pageCoordinates$1(event);
23933    }
23934
23935    function mouseUpHandler(event) {
23936      // Any mouse up cancels drag and scrolling
23937      if (this.browser.dragObject || this.browser.isScrolling) {
23938        this.browser.cancelTrackPan(); // event.preventDefault();
23939        // event.stopPropagation();
23940
23941        this.enableClick = false; // Until next mouse down
23942      } else {
23943        this.browser.cancelTrackPan();
23944        this.browser.endTrackDrag();
23945      }
23946    }
23947
23948    function createClickState(event, viewport) {
23949      const referenceFrame = viewport.referenceFrame;
23950      const viewportCoords = translateMouseCoordinates$1(event, viewport.contentDiv);
23951      const canvasCoords = translateMouseCoordinates$1(event, viewport.canvas);
23952      const genomicLocation = referenceFrame.start + referenceFrame.toBP(viewportCoords.x);
23953
23954      if (undefined === genomicLocation || null === viewport.tile) {
23955        return undefined;
23956      }
23957
23958      return {
23959        event,
23960        viewport,
23961        referenceFrame,
23962        genomicLocation,
23963        x: viewportCoords.x,
23964        y: viewportCoords.y,
23965        canvasX: canvasCoords.x,
23966        canvasY: canvasCoords.y
23967      };
23968    }
23969
23970    function getPopupContent(event, viewport) {
23971      const clickState = createClickState(event, viewport);
23972
23973      if (undefined === clickState) {
23974        return;
23975      }
23976
23977      let track = viewport.trackView.track;
23978      const dataList = track.popupData(clickState);
23979      const popupClickHandlerResult = viewport.browser.fireEvent('trackclick', [track, dataList]);
23980      let content;
23981
23982      if (undefined === popupClickHandlerResult || true === popupClickHandlerResult) {
23983        // Indicates handler did not handle the result, or the handler wishes default behavior to occur
23984        if (dataList && dataList.length > 0) {
23985          content = formatPopoverText(dataList);
23986        }
23987      } else if (typeof popupClickHandlerResult === 'string') {
23988        content = popupClickHandlerResult;
23989      }
23990
23991      return content;
23992    }
23993
23994    function formatPopoverText(nameValues) {
23995      const rows = nameValues.map(nameValue => {
23996        if (nameValue.name) {
23997          const str = `<span>${nameValue.name}</span>&nbsp&nbsp&nbsp${nameValue.value}`;
23998          return `<div title="${nameValue.value}">${str}</div>`;
23999        } else if ('<hr>' === nameValue) {
24000          // this can be retired if nameValue.html is allowed.
24001          return nameValue;
24002        } else if (nameValue.html) {
24003          return nameValue.html;
24004        } else {
24005          return `<div title="${nameValue}">${nameValue}</div>`;
24006        }
24007      });
24008      return rows.join('');
24009    }
24010
24011    var Tile = function (chr, tileStart, tileEnd, bpPerPixel, features, roiFeatures) {
24012      this.chr = chr;
24013      this.startBP = tileStart;
24014      this.endBP = tileEnd;
24015      this.bpPerPixel = bpPerPixel;
24016      this.features = features;
24017      this.roiFeatures = roiFeatures;
24018    };
24019
24020    Tile.prototype.containsRange = function (chr, start, end, bpPerPixel) {
24021      return this.bpPerPixel === bpPerPixel && start >= this.startBP && end <= this.endBP && chr === this.chr;
24022    };
24023
24024    Tile.prototype.overlapsRange = function (chr, start, end) {
24025      return this.chr === chr && end >= this.startBP && start <= this.endBP;
24026    };
24027    /**
24028     * Merge 2 arrays.  a and/or b can be undefined.  If both are undefined, return undefined
24029     * @param a An array or undefined
24030     * @param b An array or undefined
24031     */
24032
24033
24034    function mergeArrays(a, b) {
24035      if (a && b) return a.concat(b);else if (a) return a;else return b;
24036    }
24037
24038    /*
24039     * The MIT License (MIT)
24040     *
24041     * Copyright (c) 2016-2017 The Regents of the University of California
24042     * Author: Jim Robinson
24043     *
24044     * Permission is hereby granted, free of charge, to any person obtaining a copy
24045     * of this software and associated documentation files (the "Software"), to deal
24046     * in the Software without restriction, including without limitation the rights
24047     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24048     * copies of the Software, and to permit persons to whom the Software is
24049     * furnished to do so, subject to the following conditions:
24050     *
24051     * The above copyright notice and this permission notice shall be included in
24052     * all copies or substantial portions of the Software.
24053     *
24054     *
24055     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24056     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24057     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24058     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24059     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24060     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24061     * THE SOFTWARE.
24062     */
24063
24064    class RulerSweeper {
24065      constructor(rulerViewport) {
24066        this.rulerSweeper = div$1({
24067          class: 'igv-ruler-sweeper'
24068        });
24069        rulerViewport.contentDiv.appendChild(this.rulerSweeper);
24070        this.rulerViewport = rulerViewport;
24071        this.isMouseHandlers = undefined;
24072        this.addBrowserObserver();
24073      }
24074
24075      addBrowserObserver() {
24076        // Viewport Content
24077        this.boundObserverHandler = observerHandler.bind(this);
24078        this.rulerViewport.browser.on('locuschange', this.boundObserverHandler);
24079
24080        function observerHandler() {
24081          if (this.rulerViewport.referenceFrame) {
24082            if (GenomeUtils.isWholeGenomeView(this.rulerViewport.referenceFrame.chr)) {
24083              this.removeMouseHandlers();
24084            } else {
24085              this.addMouseHandlers();
24086            }
24087          }
24088        }
24089      }
24090
24091      removeBrowserObserver() {
24092        this.rulerViewport.browser.off('locuschange', this.boundObserverHandler);
24093      }
24094
24095      addMouseHandlers() {
24096        if (true === this.isMouseHandlers) {
24097          return;
24098        }
24099
24100        let isMouseDown;
24101        let isMouseIn;
24102        let mouseDownX;
24103        let left;
24104        let width;
24105        let dx;
24106        let threshold = 1; // Viewport Content
24107
24108        this.boundContentMouseDownHandler = contentMouseDownHandler.bind(this);
24109        this.rulerViewport.contentDiv.addEventListener('mousedown', this.boundContentMouseDownHandler);
24110
24111        function contentMouseDownHandler(event) {
24112          isMouseDown = true;
24113          isMouseIn = true;
24114          const {
24115            x
24116          } = translateMouseCoordinates$1(event, this.rulerViewport.contentDiv);
24117          left = mouseDownX = x;
24118          width = threshold;
24119          this.rulerSweeper.style.display = 'block';
24120          this.rulerSweeper.style.left = `${left}px`;
24121          this.rulerSweeper.style.width = `${width}px`;
24122        } // Document
24123
24124
24125        this.boundDocumentMouseMoveHandler = documentMouseMoveHandler.bind(this);
24126        document.addEventListener('mousemove', this.boundDocumentMouseMoveHandler);
24127
24128        function documentMouseMoveHandler(event) {
24129          // console.log(`${ Date.now() } RulerSweeper - documentMouseMoveHandler - target ${ event.target.nodeName }`)
24130          let mouseCurrentX;
24131
24132          if (isMouseDown && isMouseIn) {
24133            const {
24134              x
24135            } = translateMouseCoordinates$1(event, this.rulerViewport.contentDiv);
24136            mouseCurrentX = Math.max(Math.min(x, this.rulerViewport.contentDiv.clientWidth), 0);
24137            dx = mouseCurrentX - mouseDownX;
24138            width = Math.abs(dx);
24139            this.rulerSweeper.style.width = `${width}px`;
24140
24141            if (dx < 0) {
24142              left = mouseDownX + dx;
24143              this.rulerSweeper.style.left = `${left}px`;
24144            }
24145          }
24146        }
24147
24148        this.boundDocumentMouseUpHandler = documentMouseUpHandler.bind(this);
24149        document.addEventListener('mouseup', this.boundDocumentMouseUpHandler);
24150
24151        function documentMouseUpHandler(event) {
24152          // console.log(`${ Date.now() } RulerSweeper - documentMouseUpHandler - target ${ event.target.nodeName }`)
24153          let extent;
24154
24155          if (true === isMouseDown && true === isMouseIn) {
24156            isMouseDown = isMouseIn = undefined;
24157            this.rulerSweeper.style.display = 'none';
24158
24159            if (width > threshold) {
24160              extent = {
24161                start: bp(this.rulerViewport.referenceFrame, left),
24162                end: bp(this.rulerViewport.referenceFrame, left + width)
24163              };
24164              validateLocusExtent(this.rulerViewport.browser.genome.getChromosome(this.rulerViewport.referenceFrame.chr).bpLength, extent, this.rulerViewport.browser.minimumBases());
24165              this.rulerViewport.referenceFrame.bpPerPixel = (Math.round(extent.end
24165) - Math.round(extent.start)) / this.rulerViewport.contentDiv.clientWidth;
24166              this.rulerViewport.referenceFrame.start = Math.round(extent.start);
24167              this.rulerViewport.referenceFrame.end = Math.round(extent.end);
24168              this.rulerViewport.browser.updateViews(this.rulerViewport.referenceFrame);
24169            }
24170          }
24171        }
24172
24173        this.isMouseHandlers = true;
24174      }
24175
24176      removeMouseHandlers() {
24177        this.rulerViewport.contentDiv.removeEventListener('mousedown', this.boundContentMouseDownHandler);
24178        document.removeEventListener('mousemove', this.boundDocumentMouseMoveHandler);
24179        document.removeEventListener('mouseup', this.boundDocumentMouseUpHandler);
24180        this.isMouseHandlers = false;
24181      }
24182
24183      dispose() {
24184        this.removeBrowserObserver();
24185        this.removeMouseHandlers();
24186        this.rulerSweeper.remove();
24187      }
24188
24189    }
24190
24191    function bp(referenceFrame, pixel) {
24192      return referenceFrame.start + pixel * referenceFrame.bpPerPixel;
24193    }
24194
24195    var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
24196
24197    function createCommonjsModule(fn) {
24198      var module = { exports: {} };
24199    	return fn(module, module.exports), module.exports;
24200    }
24201
24202    var check = function (it) {
24203      return it && it.Math == Math && it;
24204    }; // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
24205
24206
24207    var global$1 = // eslint-disable-next-line es/no-global-this -- safe
24208    check(typeof globalThis == 'object' && globalThis) || check(typeof window == 'object' && window) || // eslint-disable-next-line no-restricted-globals -- safe
24209    check(typeof self == 'object' && self) || check(typeof commonjsGlobal == 'object' && commonjsGlobal) || // eslint-disable-next-line no-new-func -- fallback
24210    function () {
24211      return this;
24212    }() || Function('return this')();
24213
24214    var FunctionPrototype$2 = Function.prototype;
24215    var bind$2 = FunctionPrototype$2.bind;
24216    var call$2 = FunctionPrototype$2.call;
24217    var callBind = bind$2 && bind$2.bind(call$2);
24218    var functionUncurryThis = bind$2 ? function (fn) {
24219      return fn && callBind(call$2, fn);
24220    } : function (fn) {
24221      return fn && function () {
24222        return call$2.apply(fn, arguments);
24223      };
24224    };
24225
24226    var fails = function (exec) {
24227      try {
24228        return !!exec();
24229      } catch (error) {
24230        return true;
24231      }
24232    };
24233
24234    // `IsCallable` abstract operation
24235    // https://tc39.es/ecma262/#sec-iscallable
24236    var isCallable = function (argument) {
24237      return typeof argument == 'function';
24238    };
24239
24240    var String$4 = global$1.String;
24241
24242    var tryToString = function (argument) {
24243      try {
24244        return String$4(argument);
24245      } catch (error) {
24246        return 'Object';
24247      }
24248    };
24249
24250    var TypeError$9 = global$1.TypeError; // `Assert: IsCallable(argument) is true`
24251
24252    var aCallable = function (argument) {
24253      if (isCallable(argument)) return argument;
24254      throw TypeError$9(tryToString(argument) + ' is not a function');
24255    };
24256
24257    var ceil = Math.ceil;
24258    var floor$1 = Math.floor; // `ToIntegerOrInfinity` abstract operation
24259    // https://tc39.es/ecma262/#sec-tointegerorinfinity
24260
24261    var toIntegerOrInfinity = function (argument) {
24262      var number = +argument; // eslint-disable-next-line no-self-compare -- safe
24263
24264      return number !== number || number === 0 ? 0 : (number > 0 ? floor$1 : ceil)(number);
24265    };
24266
24267    var max$1 = Math.max;
24268    var min$1 = Math.min; // Helper for a popular repeating case of the spec:
24269    // Let integer be ? ToInteger(index).
24270    // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
24271
24272    var toAbsoluteIndex = function (index, length) {
24273      var integer = toIntegerOrInfinity(index);
24274      return integer < 0 ? max$1(integer + length, 0) : min$1(integer, length);
24275    };
24276
24277    var min = Math.min; // `ToLength` abstract operation
24278    // https://tc39.es/ecma262/#sec-tolength
24279
24280    var toLength = function (argument) {
24281      return argument > 0 ? min(toIntegerOrInfinity(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
24282    };
24283
24284    // https://tc39.es/ecma262/#sec-lengthofarraylike
24285
24286    var lengthOfArrayLike = function (obj) {
24287      return toLength(obj.length);
24288    };
24289
24290    var call$1 = Function.prototype.call;
24291    var functionCall = call$1.bind ? call$1.bind(call$1) : function () {
24292      return call$1.apply(call$1, arguments);
24293    };
24294
24295    var isObject = function (it) {
24296      return typeof it == 'object' ? it !== null : isCallable(it);
24297    };
24298
24299    var aFunction = function (argument) {
24300      return isCallable(argument) ? argument : undefined;
24301    };
24302
24303    var getBuiltIn = function (namespace, method) {
24304      return arguments.length < 2 ? aFunction(global$1[namespace]) : global$1[namespace] && global$1[namespace][method];
24305    };
24306
24307    var objectIsPrototypeOf = functionUncurryThis({}.isPrototypeOf);
24308
24309    var engineUserAgent = getBuiltIn('navigator', 'userAgent') || '';
24310
24311    var process$2 = global$1.process;
24312    var Deno = global$1.Deno;
24313    var versions = process$2 && process$2.versions || Deno && Deno.version;
24314    var v8 = versions && versions.v8;
24315    var match, version;
24316
24317    if (v8) {
24318      match = v8.split('.'); // in old Chrome, versions of V8 isn't V8 = Chrome / 10
24319      // but their correct versions are not interesting for us
24320
24321      version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);
24322    } // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`
24323    // so check `userAgent` even if `.v8` exists, but 0
24324
24325
24326    if (!version && engineUserAgent) {
24327      match = engineUserAgent.match(/Edge\/(\d+)/);
24328
24329      if (!match || match[1] >= 74) {
24330        match = engineUserAgent.match(/Chrome\/(\d+)/);
24331        if (match) version = +match[1];
24332      }
24333    }
24334
24335    var engineV8Version = version;
24336
24337    /* eslint-disable es/no-symbol -- required for testing */
24338
24339    var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () {
24340      var symbol = Symbol(); // Chrome 38 Symbol has incorrect toString conversion
24341      // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
24342
24343      return !String(symbol) || !(Object(symbol) instanceof Symbol) || // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
24344      !Symbol.sham && engineV8Version && engineV8Version < 41;
24345    });
24346
24347    /* eslint-disable es/no-symbol -- required for testing */
24348    var useSymbolAsUid = nativeSymbol && !Symbol.sham && typeof Symbol.iterator == 'symbol';
24349
24350    var Object$5 = global$1.Object;
24351    var isSymbol = useSymbolAsUid ? function (it) {
24352      return typeof it == 'symbol';
24353    } : function (it) {
24354      var $Symbol = getBuiltIn('Symbol');
24355      return isCallable($Symbol) && objectIsPrototypeOf($Symbol.prototype, Object$5(it));
24356    };
24357
24358    // https://tc39.es/ecma262/#sec-getmethod
24359
24360    var getMethod = function (V, P) {
24361      var func = V[P];
24362      return func == null ? undefined : aCallable(func);
24363    };
24364
24365    var TypeError$8 = global$1.TypeError; // `OrdinaryToPrimitive` abstract operation
24366    // https://tc39.es/ecma262/#sec-ordinarytoprimitive
24367
24368    var ordinaryToPrimitive = function (input, pref) {
24369      var fn, val;
24370      if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = functionCall(fn, input))) return val;
24371      if (isCallable(fn = input.valueOf) && !isObject(val = functionCall(fn, input))) return val;
24372      if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = functionCall(fn, input))) return val;
24373      throw TypeError$8("Can't convert object to primitive value");
24374    };
24375
24376    var defineProperty$1 = Object.defineProperty;
24377
24378    var setGlobal = function (key, value) {
24379      try {
24380        defineProperty$1(global$1, key, {
24381          value: value,
24382          configurable: true,
24383          writable: true
24384        });
24385      } catch (error) {
24386        global$1[key] = value;
24387      }
24388
24389      return value;
24390    };
24391
24392    var SHARED = '__core-js_shared__';
24393    var store$1 = global$1[SHARED] || setGlobal(SHARED, {});
24394    var sharedStore = store$1;
24395
24396    var shared = createCommonjsModule(function (module) {
24397      (module.exports = function (key, value) {
24398        return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
24399      })('versions', []).push({
24400        version: '3.19.3',
24401        mode: 'global',
24402        copyright: '© 2021 Denis Pushkarev (zloirock.ru)'
24403      });
24404    });
24405
24406    var TypeError$7 = global$1.TypeError; // `RequireObjectCoercible` abstract operation
24407    // https://tc39.es/ecma262/#sec-requireobjectcoercible
24408
24409    var requireObjectCoercible = function (it) {
24410      if (it == undefined) throw TypeError$7("Can't call method on " + it);
24411      return it;
24412    };
24413
24414    var Object$4 = global$1.Object; // `ToObject` abstract operation
24415    // https://tc39.es/ecma262/#sec-toobject
24416
24417    var toObject = function (argument) {
24418      return Object$4(requireObjectCoercible(argument));
24419    };
24420
24421    var hasOwnProperty = functionUncurryThis({}.hasOwnProperty); // `HasOwnProperty` abstract operation
24422    // https://tc39.es/ecma262/#sec-hasownproperty
24423
24424    var hasOwnProperty_1 = Object.hasOwn || function hasOwn(it, key) {
24425      return hasOwnProperty(toObject(it), key);
24426    };
24427
24428    var id = 0;
24429    var postfix = Math.random();
24430    var toString$1 = functionUncurryThis(1.0.toString);
24431
24432    var uid = function (key) {
24433      return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString$1(++id + postfix, 36);
24434    };
24435
24436    var WellKnownSymbolsStore = shared('wks');
24437    var Symbol$1 = global$1.Symbol;
24438    var symbolFor = Symbol$1 && Symbol$1['for'];
24439    var createWellKnownSymbol = useSymbolAsUid ? Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid;
24440
24441    var wellKnownSymbol = function (name) {
24442      if (!hasOwnProperty_1(WellKnownSymbolsStore, name) || !(nativeSymbol || typeof WellKnownSymbolsStore[name] == 'string')) {
24443        var description = 'Symbol.' + name;
24444
24445        if (nativeSymbol && hasOwnProperty_1(Symbol$1, name)) {
24446          WellKnownSymbolsStore[name] = Symbol$1[name];
24447        } else if (useSymbolAsUid && symbolFor) {
24448          WellKnownSymbolsStore[name] = symbolFor(description);
24449        } else {
24450          WellKnownSymbolsStore[name] = createWellKnownSymbol(description);
24451        }
24452      }
24453
24454      return WellKnownSymbolsStore[name];
24455    };
24456
24457    var TypeError$6 = global$1.TypeError;
24458    var TO_PRIMITIVE = wellKnownSymbol('toPrimitive'); // `ToPrimitive` abstract operation
24459    // https://tc39.es/ecma262/#sec-toprimitive
24460
24461    var toPrimitive = function (input, pref) {
24462      if (!isObject(input) || isSymbol(input)) return input;
24463      var exoticToPrim = getMethod(input, TO_PRIMITIVE);
24464      var result;
24465
24466      if (exoticToPrim) {
24467        if (pref === undefined) pref = 'default';
24468        result = functionCall(exoticToPrim, input, pref);
24469        if (!isObject(result) || isSymbol(result)) return result;
24470        throw TypeError$6("Can't convert object to primitive value");
24471      }
24472
24473      if (pref === undefined) pref = 'number';
24474      return ordinaryToPrimitive(input, pref);
24475    };
24476
24477    // https://tc39.es/ecma262/#sec-topropertykey
24478
24479    var toPropertyKey = function (argument) {
24480      var key = toPrimitive(argument, 'string');
24481      return isSymbol(key) ? key : key + '';
24482    };
24483
24484    var descriptors = !fails(function () {
24485      // eslint-disable-next-line es/no-object-defineproperty -- required for testing
24486      return Object.defineProperty({}, 1, {
24487        get: function () {
24488          return 7;
24489        }
24490      })[1] != 7;
24491    });
24492
24493    var document$1 = global$1.document; // typeof document.createElement is 'object' in old IE
24494
24495    var EXISTS$1 = isObject(document$1) && isObject(document$1.createElement);
24496
24497    var documentCreateElement = function (it) {
24498      return EXISTS$1 ? document$1.createElement(it) : {};
24499    };
24500
24501    var ie8DomDefine = !descriptors && !fails(function () {
24502      // eslint-disable-next-line es/no-object-defineproperty -- requied for testing
24503      return Object.defineProperty(documentCreateElement('div'), 'a', {
24504        get: function () {
24505          return 7;
24506        }
24507      }).a != 7;
24508    });
24509
24510    var String$3 = global$1.String;
24511    var TypeError$5 = global$1.TypeError; // `Assert: Type(argument) is Object`
24512
24513    var anObject = function (argument) {
24514      if (isObject(argument)) return argument;
24515      throw TypeError$5(String$3(argument) + ' is not an object');
24516    };
24517
24518    var TypeError$4 = global$1.TypeError; // eslint-disable-next-line es/no-object-defineproperty -- safe
24519
24520    var $defineProperty = Object.defineProperty; // `Object.defineProperty` method
24521    // https://tc39.es/ecma262/#sec-object.defineproperty
24522
24523    var f$4 = descriptors ? $defineProperty : function defineProperty(O, P, Attributes) {
24524      anObject(O);
24525      P = toPropertyKey(P);
24526      anObject(Attributes);
24527      if (ie8DomDefine) try {
24528        return $defineProperty(O, P, Attributes);
24529      } catch (error) {
24530        /* empty */
24531      }
24532      if ('get' in Attributes || 'set' in Attributes) throw TypeError$4('Accessors not supported');
24533      if ('value' in Attributes) O[P] = Attributes.value;
24534      return O;
24535    };
24536    var objectDefineProperty = {
24537      f: f$4
24538    };
24539
24540    var createPropertyDescriptor = function (bitmap, value) {
24541      return {
24542        enumerable: !(bitmap & 1),
24543        configurable: !(bitmap & 2),
24544        writable: !(bitmap & 4),
24545        value: value
24546      };
24547    };
24548
24549    var createProperty = function (object, key, value) {
24550      var propertyKey = toPropertyKey(key);
24551      if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value));else object[propertyKey] = value;
24552    };
24553
24554    var Array$2 = global$1.Array;
24555    var max = Math.max;
24556
24557    var arraySliceSimple = function (O, start, end) {
24558      var length = lengthOfArrayLike(O);
24559      var k = toAbsoluteIndex(start, length);
24560      var fin = toAbsoluteIndex(end === undefined ? length : end, length);
24561      var result = Array$2(max(fin - k, 0));
24562
24563      for (var n = 0; k < fin; k++, n++) createProperty(result, n, O[k]);
24564
24565      result.length = n;
24566      return result;
24567    };
24568
24569    var floor = Math.floor;
24570
24571    var mergeSort = function (array, comparefn) {
24572      var length = array.length;
24573      var middle = floor(length / 2);
24574      return length < 8 ? insertionSort(array, comparefn) : merge(array, mergeSort(arraySliceSimple(array, 0, middle), comparefn), mergeSort(arraySliceSimple(array, middle), comparefn), comparefn);
24575    };
24576
24577    var insertionSort = function (array, comparefn) {
24578      var length = array.length;
24579      var i = 1;
24580      var element, j;
24581
24582      while (i < length) {
24583        j = i;
24584        element = array[i];
24585
24586        while (j && comparefn(array[j - 1], element) > 0) {
24587          array[j] = array[--j];
24588        }
24589
24590        if (j !== i++) array[j] = element;
24591      }
24592
24593      return array;
24594    };
24595
24596    var merge = function (array, left, right, comparefn) {
24597      var llength = left.length;
24598      var rlength = right.length;
24599      var lindex = 0;
24600      var rindex = 0;
24601
24602      while (lindex < llength || rindex < rlength) {
24603        array[lindex + rindex] = lindex < llength && rindex < rlength ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++] : lindex < llength ? left[lindex++] : right[rindex++];
24604      }
24605
24606      return array;
24607    };
24608
24609    var arraySort = mergeSort;
24610
24611    // eslint-disable-next-line es/no-typed-arrays -- safe
24612    var arrayBufferNative = typeof ArrayBuffer != 'undefined' && typeof DataView != 'undefined';
24613
24614    var TO_STRING_TAG$2 = wellKnownSymbol('toStringTag');
24615    var test = {};
24616    test[TO_STRING_TAG$2] = 'z';
24617    var toStringTagSupport = String(test) === '[object z]';
24618
24619    var toString = functionUncurryThis({}.toString);
24620    var stringSlice = functionUncurryThis(''.slice);
24621
24622    var classofRaw = function (it) {
24623      return stringSlice(toString(it), 8, -1);
24624    };
24625
24626    var TO_STRING_TAG$1 = wellKnownSymbol('toStringTag');
24627    var Object$3 = global$1.Object; // ES3 wrong here
24628
24629    var CORRECT_ARGUMENTS = classofRaw(function () {
24630      return arguments;
24631    }()) == 'Arguments'; // fallback for IE11 Script Access Denied error
24632
24633    var tryGet = function (it, key) {
24634      try {
24635        return it[key];
24636      } catch (error) {
24637        /* empty */
24638      }
24639    }; // getting tag from ES6+ `Object.prototype.toString`
24640
24641
24642    var classof = toStringTagSupport ? classofRaw : function (it) {
24643      var O, tag, result;
24644      return it === undefined ? 'Undefined' : it === null ? 'Null' // @@toStringTag case
24645      : typeof (tag = tryGet(O = Object$3(it), TO_STRING_TAG$1)) == 'string' ? tag // builtinTag case
24646      : CORRECT_ARGUMENTS ? classofRaw(O) // ES3 arguments fallback
24647      : (result = classofRaw(O)) == 'Object' && isCallable(O.callee) ? 'Arguments' : result;
24648    };
24649
24650    var createNonEnumerableProperty = descriptors ? function (object, key, value) {
24651      return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
24652    } : function (object, key, value) {
24653      object[key] = value;
24654      return object;
24655    };
24656
24657    var functionToString = functionUncurryThis(Function.toString); // this helper broken in `[email protected]`, so we can't use `shared` helper
24658
24659    if (!isCallable(sharedStore.inspectSource)) {
24660      sharedStore.inspectSource = function (it) {
24661        return functionToString(it);
24662      };
24663    }
24664
24665    var inspectSource = sharedStore.inspectSource;
24666
24667    var WeakMap$1 = global$1.WeakMap;
24668    var nativeWeakMap = isCallable(WeakMap$1) && /native code/.test(inspectSource(WeakMap$1));
24669
24670    var keys = shared('keys');
24671
24672    var sharedKey = function (key) {
24673      return keys[key] || (keys[key] = uid(key));
24674    };
24675
24676    var hiddenKeys$1 = {};
24677
24678    var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
24679    var TypeError$3 = global$1.TypeError;
24680    var WeakMap = global$1.WeakMap;
24681    var set$1, get, has;
24682
24683    var enforce = function (it) {
24684      return has(it) ? get(it) : set$1(it, {});
24685    };
24686
24687    var getterFor = function (TYPE) {
24688      return function (it) {
24689        var state;
24690
24691        if (!isObject(it) || (state = get(it)).type !== TYPE) {
24692          throw TypeError$3('Incompatible receiver, ' + TYPE + ' required');
24693        }
24694
24695        return state;
24696      };
24697    };
24698
24699    if (nativeWeakMap || sharedStore.state) {
24700      var store = sharedStore.state || (sharedStore.state = new WeakMap());
24701      var wmget = functionUncurryThis(store.get);
24702      var wmhas = functionUncurryThis(store.has);
24703      var wmset = functionUncurryThis(store.set);
24704
24705      set$1 = function (it, metadata) {
24706        if (wmhas(store, it)) throw new TypeError$3(OBJECT_ALREADY_INITIALIZED);
24707        metadata.facade = it;
24708        wmset(store, it, metadata);
24709        return metadata;
24710      };
24711
24712      get = function (it) {
24713        return wmget(store, it) || {};
24714      };
24715
24716      has = function (it) {
24717        return wmhas(store, it);
24718      };
24719    } else {
24720      var STATE = sharedKey('state');
24721      hiddenKeys$1[STATE] = true;
24722
24723      set$1 = function (it, metadata) {
24724        if (hasOwnProperty_1(it, STATE)) throw new TypeError$3(OBJECT_ALREADY_INITIALIZED);
24725        metadata.facade = it;
24726        createNonEnumerableProperty(it, STATE, metadata);
24727        return metadata;
24728      };
24729
24730      get = function (it) {
24731        return hasOwnProperty_1(it, STATE) ? it[STATE] : {};
24732      };
24733
24734      has = function (it) {
24735        return hasOwnProperty_1(it, STATE);
24736      };
24737    }
24738
24739    var internalState = {
24740      set: set$1,
24741      get: get,
24742      has: has,
24743      enforce: enforce,
24744      getterFor: getterFor
24745    };
24746
24747    var FunctionPrototype$1 = Function.prototype; // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
24748
24749    var getDescriptor = descriptors && Object.getOwnPropertyDescriptor;
24750    var EXISTS = hasOwnProperty_1(FunctionPrototype$1, 'name'); // additional protection from minified / mangled / dropped function names
24751
24752    var PROPER = EXISTS && function something() {
24753      /* empty */
24754    }.name === 'something';
24755
24756    var CONFIGURABLE = EXISTS && (!descriptors || descriptors && getDescriptor(FunctionPrototype$1, 'name').configurable);
24757    var functionName = {
24758      EXISTS: EXISTS,
24759      PROPER: PROPER,
24760      CONFIGURABLE: CONFIGURABLE
24761    };
24762
24763    var redefine = createCommonjsModule(function (module) {
24764      var CONFIGURABLE_FUNCTION_NAME = functionName.CONFIGURABLE;
24765      var getInternalState = internalState.get;
24766      var enforceInternalState = internalState.enforce;
24767      var TEMPLATE = String(String).split('String');
24768      (module.exports = function (O, key, value, options) {
24769        var unsafe = options ? !!options.unsafe : false;
24770        var simple = options ? !!options.enumerable : false;
24771        var noTargetGet = options ? !!options.noTargetGet : false;
24772        var name = options && options.name !== undefined ? options.name : key;
24773        var state;
24774
24775        if (isCallable(value)) {
24776          if (String(name).slice(0, 7) === 'Symbol(') {
24777            name = '[' + String(name).replace(/^Symbol\(([^)]*)\)/, '$1') + ']';
24778          }
24779
24780          if (!hasOwnProperty_1(value, 'name') || CONFIGURABLE_FUNCTION_NAME && value.name !== name) {
24781            createNonEnumerableProperty(value, 'name', name);
24782          }
24783
24784          state = enforceInternalState(value);
24785
24786          if (!state.source) {
24787            state.source = TEMPLATE.join(typeof name == 'string' ? name : '');
24788          }
24789        }
24790
24791        if (O === global$1) {
24792          if (simple) O[key] = value;else setGlobal(key, value);
24793          return;
24794        } else if (!unsafe) {
24795          delete O[key];
24796        } else if (!noTargetGet && O[key]) {
24797          simple = true;
24798        }
24799
24800        if (simple) O[key] = value;else createNonEnumerableProperty(O, key, value); // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
24801      })(Function.prototype, 'toString', function toString() {
24802        return isCallable(this) && getInternalState(this).source || inspectSource(this);
24803      });
24804    });
24805
24806    var correctPrototypeGetter = !fails(function () {
24807      function F() {
24808        /* empty */
24809      }
24810
24811      F.prototype.constructor = null; // eslint-disable-next-line es/no-object-getprototypeof -- required for testing
24812
24813      return Object.getPrototypeOf(new F()) !== F.prototype;
24814    });
24815
24816    var IE_PROTO = sharedKey('IE_PROTO');
24817    var Object$2 = global$1.Object;
24818    var ObjectPrototype$1 = Object$2.prototype; // `Object.getPrototypeOf` method
24819    // https://tc39.es/ecma262/#sec-object.getprototypeof
24820
24821    var objectGetPrototypeOf = correctPrototypeGetter ? Object$2.getPrototypeOf : function (O) {
24822      var object = toObject(O);
24823      if (hasOwnProperty_1(object, IE_PROTO)) return object[IE_PROTO];
24824      var constructor = object.constructor;
24825
24826      if (isCallable(constructor) && object instanceof constructor) {
24827        return constructor.prototype;
24828      }
24829
24830      return object instanceof Object$2 ? ObjectPrototype$1 : null;
24831    };
24832
24833    var String$2 = global$1.String;
24834    var TypeError$2 = global$1.TypeError;
24835
24836    var aPossiblePrototype = function (argument) {
24837      if (typeof argument == 'object' || isCallable(argument)) return argument;
24838      throw TypeError$2("Can't set " + String$2(argument) + ' as a prototype');
24839    };
24840
24841    /* eslint-disable no-proto -- safe */
24842    // https://tc39.es/ecma262/#sec-object.setprototypeof
24843    // Works with __proto__ only. Old v8 can't work with null proto objects.
24844    // eslint-disable-next-line es/no-object-setprototypeof -- safe
24845
24846    var objectSetPrototypeOf = Object.setPrototypeOf || ('__proto__' in {} ? function () {
24847      var CORRECT_SETTER = false;
24848      var test = {};
24849      var setter;
24850
24851      try {
24852        // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
24853        setter = functionUncurryThis(Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set);
24854        setter(test, []);
24855        CORRECT_SETTER = test instanceof Array;
24856      } catch (error) {
24857        /* empty */
24858      }
24859
24860      return function setPrototypeOf(O, proto) {
24861        anObject(O);
24862        aPossiblePrototype(proto);
24863        if (CORRECT_SETTER) setter(O, proto);else O.__proto__ = proto;
24864        return O;
24865      };
24866    }() : undefined);
24867
24868    var defineProperty = objectDefineProperty.f;
24869    var Int8Array = global$1.Int8Array;
24870    var Int8ArrayPrototype = Int8Array && Int8Array.prototype;
24871    var Uint8ClampedArray = global$1.Uint8ClampedArray;
24872    var Uint8ClampedArrayPrototype = Uint8ClampedArray && Uint8ClampedArray.prototype;
24873    var TypedArray = Int8Array && objectGetPrototypeOf(Int8Array);
24874    var TypedArrayPrototype = Int8ArrayPrototype && objectGetPrototypeOf(Int8ArrayPrototype);
24875    var ObjectPrototype = Object.prototype;
24876    var TypeError$1 = global$1.TypeError;
24877    var TO_STRING_TAG = wellKnownSymbol('toStringTag');
24878    var TYPED_ARRAY_TAG = uid('TYPED_ARRAY_TAG');
24879    var TYPED_ARRAY_CONSTRUCTOR = uid('TYPED_ARRAY_CONSTRUCTOR'); // Fixing native typed arrays in Opera Presto crashes the browser, see #595
24880
24881    var NATIVE_ARRAY_BUFFER_VIEWS = arrayBufferNative && !!objectSetPrototypeOf && classof(global$1.opera) !== 'Opera';
24882    var TYPED_ARRAY_TAG_REQIRED = false;
vendor: 5,883 bytes, lines 24883-25038
24883    var NAME, Constructor, Prototype;
24884    var TypedArrayConstructorsList = {
24885      Int8Array: 1,
24886      Uint8Array: 1,
24887      Uint8ClampedArray: 1,
24888      Int16Array: 2,
24889      Uint16Array: 2,
24890      Int32Array: 4,
24891      Uint32Array: 4,
24892      Float32Array: 4,
24893      Float64Array: 8
24894    };
24895    var BigIntArrayConstructorsList = {
24896      BigInt64Array: 8,
24897      BigUint64Array: 8
24898    };
24899
24900    var isView = function isView(it) {
24901      if (!isObject(it)) return false;
24902      var klass = classof(it);
24903      return klass === 'DataView' || hasOwnProperty_1(TypedArrayConstructorsList, klass) || hasOwnProperty_1(BigIntArrayConstructorsList, klass);
24904    };
24905
24906    var isTypedArray = function (it) {
24907      if (!isObject(it)) return false;
24908      var klass = classof(it);
24909      return hasOwnProperty_1(TypedArrayConstructorsList, klass) || hasOwnProperty_1(BigIntArrayConstructorsList, klass);
24910    };
24911
24912    var aTypedArray$1 = function (it) {
24913      if (isTypedArray(it)) return it;
24914      throw TypeError$1('Target is not a typed array');
24915    };
24916
24917    var aTypedArrayConstructor = function (C) {
24918      if (isCallable(C) && (!objectSetPrototypeOf || objectIsPrototypeOf(TypedArray, C))) return C;
24919      throw TypeError$1(tryToString(C) + ' is not a typed array constructor');
24920    };
24921
24922    var exportTypedArrayMethod$1 = function (KEY, property, forced) {
24923      if (!descriptors) return;
24924      if (forced) for (var ARRAY in TypedArrayConstructorsList) {
24925        var TypedArrayConstructor = global$1[ARRAY];
24926        if (TypedArrayConstructor && hasOwnProperty_1(TypedArrayConstructor.prototype, KEY)) try {
24927          delete TypedArrayConstructor.prototype[KEY];
24928        } catch (error) {
24929          /* empty */
24930        }
24931      }
24932
24933      if (!TypedArrayPrototype[KEY] || forced) {
24934        redefine(TypedArrayPrototype, KEY, forced ? property : NATIVE_ARRAY_BUFFER_VIEWS && Int8ArrayPrototype[KEY] || property);
24935      }
24936    };
24937
24938    var exportTypedArrayStaticMethod = function (KEY, property, forced) {
24939      var ARRAY, TypedArrayConstructor;
24940      if (!descriptors) return;
24941
24942      if (objectSetPrototypeOf) {
24943        if (forced) for (ARRAY in TypedArrayConstructorsList) {
24944          TypedArrayConstructor = global$1[ARRAY];
24945          if (TypedArrayConstructor && hasOwnProperty_1(TypedArrayConstructor, KEY)) try {
24946            delete TypedArrayConstructor[KEY];
24947          } catch (error) {
24948            /* empty */
24949          }
24950        }
24951
24952        if (!TypedArray[KEY] || forced) {
24953          // V8 ~ Chrome 49-50 `%TypedArray%` methods are non-writable non-configurable
24954          try {
24955            return redefine(TypedArray, KEY, forced ? property : NATIVE_ARRAY_BUFFER_VIEWS && TypedArray[KEY] || property);
24956          } catch (error) {
24957            /* empty */
24958          }
24959        } else return;
24960      }
24961
24962      for (ARRAY in TypedArrayConstructorsList) {
24963        TypedArrayConstructor = global$1[ARRAY];
24964
24965        if (TypedArrayConstructor && (!TypedArrayConstructor[KEY] || forced)) {
24966          redefine(TypedArrayConstructor, KEY, property);
24967        }
24968      }
24969    };
24970
24971    for (NAME in TypedArrayConstructorsList) {
24972      Constructor = global$1[NAME];
24973      Prototype = Constructor && Constructor.prototype;
24974      if (Prototype) createNonEnumerableProperty(Prototype, TYPED_ARRAY_CONSTRUCTOR, Constructor);else NATIVE_ARRAY_BUFFER_VIEWS = false;
24975    }
24976
24977    for (NAME in BigIntArrayConstructorsList) {
24978      Constructor = global$1[NAME];
24979      Prototype = Constructor && Constructor.prototype;
24980      if (Prototype) createNonEnumerableProperty(Prototype, TYPED_ARRAY_CONSTRUCTOR, Constructor);
24981    } // WebKit bug - typed arrays constructors prototype is Object.prototype
24982
24983
24984    if (!NATIVE_ARRAY_BUFFER_VIEWS || !isCallable(TypedArray) || TypedArray === Function.prototype) {
24985      // eslint-disable-next-line no-shadow -- safe
24986      TypedArray = function TypedArray() {
24987        throw TypeError$1('Incorrect invocation');
24988      };
24989
24990      if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) {
24991        if (global$1[NAME]) objectSetPrototypeOf(global$1[NAME], TypedArray);
24992      }
24993    }
24994
24995    if (!NATIVE_ARRAY_BUFFER_VIEWS || !TypedArrayPrototype || TypedArrayPrototype === ObjectPrototype) {
24996      TypedArrayPrototype = TypedArray.prototype;
24997      if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) {
24998        if (global$1[NAME]) objectSetPrototypeOf(global$1[NAME].prototype, TypedArrayPrototype);
24999      }
25000    } // WebKit bug - one more object in Uint8ClampedArray prototype chain
25001
25002
25003    if (NATIVE_ARRAY_BUFFER_VIEWS && objectGetPrototypeOf(Uint8ClampedArrayPrototype) !== TypedArrayPrototype) {
25004      objectSetPrototypeOf(Uint8ClampedArrayPrototype, TypedArrayPrototype);
25005    }
25006
25007    if (descriptors && !hasOwnProperty_1(TypedArrayPrototype, TO_STRING_TAG)) {
25008      TYPED_ARRAY_TAG_REQIRED = true;
25009      defineProperty(TypedArrayPrototype, TO_STRING_TAG, {
25010        get: function () {
25011          return isObject(this) ? this[TYPED_ARRAY_TAG] : undefined;
25012        }
25013      });
25014
25015      for (NAME in TypedArrayConstructorsList) if (global$1[NAME]) {
25016        createNonEnumerableProperty(global$1[NAME], TYPED_ARRAY_TAG, NAME);
25017      }
25018    }
25019
25020    var arrayBufferViewCore = {
25021      NATIVE_ARRAY_BUFFER_VIEWS: NATIVE_ARRAY_BUFFER_VIEWS,
25022      TYPED_ARRAY_CONSTRUCTOR: TYPED_ARRAY_CONSTRUCTOR,
25023      TYPED_ARRAY_TAG: TYPED_ARRAY_TAG_REQIRED && TYPED_ARRAY_TAG,
25024      aTypedArray: aTypedArray$1,
25025      aTypedArrayConstructor: aTypedArrayConstructor,
25026      exportTypedArrayMethod: exportTypedArrayMethod$1,
25027      exportTypedArrayStaticMethod: exportTypedArrayStaticMethod,
25028      isView: isView,
25029      isTypedArray: isTypedArray,
25030      TypedArray: TypedArray,
25031      TypedArrayPrototype: TypedArrayPrototype
25032    };
25033
25034    var firefox = engineUserAgent.match(/firefox\/(\d+)/i);
25035    var engineFfVersion = !!firefox && +firefox[1];
25036
25037    var engineIsIeOrEdge = /MSIE|Trident/.test(engineUserAgent);
25038
25039    var webkit = engineUserAgent.match(/AppleWebKit\/(\d+)\./);
25040    var engineWebkitVersion = !!webkit && +webkit[1];
25041
25042    var Array$1 = global$1.Array;
25043    var aTypedArray = arrayBufferViewCore.aTypedArray;
25044    var exportTypedArrayMethod = arrayBufferViewCore.exportTypedArrayMethod;
25045    var Uint16Array$1 = global$1.Uint16Array;
25046    var un$Sort = Uint16Array$1 && functionUncurryThis(Uint16Array$1.prototype.sort); // WebKit
25047
25048    var ACCEPT_INCORRECT_ARGUMENTS = !!un$Sort && !(fails(function () {
25049      un$Sort(new Uint16Array$1(2), null);
25050    }) && fails(function () {
25051      un$Sort(new Uint16Array$1(2), {});
25052    }));
25053    var STABLE_SORT = !!un$Sort && !fails(function () {
25054      // feature detection can be too slow, so check engines versions
25055      if (engineV8Version) return engineV8Version < 74;
25056      if (engineFfVersion) return engineFfVersion < 67;
25057      if (engineIsIeOrEdge) return true;
25058      if (engineWebkitVersion) return engineWebkitVersion < 602;
25059      var array = new Uint16Array$1(516);
25060      var expected = Array$1(516);
25061      var index, mod;
25062
25063      for (index = 0; index < 516; index++) {
25064        mod = index % 4;
25065        array[index] = 515 - index;
25066        expected[index] = index - 2 * mod + 3;
25067      }
25068
25069      un$Sort(array, function (a, b) {
25070        return (a / 4 | 0) - (b / 4 | 0);
25071      });
25072
25073      for (index = 0; index < 516; index++) {
25074        if (array[index] !== expected[index]) return true;
25075      }
25076    });
25077
25078    var getSortCompare = function (comparefn) {
25079      return function (x, y) {
25080        if (comparefn !== undefined) return +comparefn(x, y) || 0; // eslint-disable-next-line no-self-compare -- NaN check
25081
25082        if (y !== y) return -1; // eslint-disable-next-line no-self-compare -- NaN check
25083
25084        if (x !== x) return 1;
25085        if (x === 0 && y === 0) return 1 / x > 0 && 1 / y < 0 ? 1 : -1;
25086        return x > y;
25087      };
25088    }; // `%TypedArray%.prototype.sort` method
25089    // https://tc39.es/ecma262/#sec-%typedarray%.prototype.sort
25090
25091
25092    exportTypedArrayMethod('sort', function sort(comparefn) {
25093      if (comparefn !== undefined) aCallable(comparefn);
25094      if (STABLE_SORT) return un$Sort(this, comparefn);
25095      return arraySort(aTypedArray(this), getSortCompare(comparefn));
25096    }, !STABLE_SORT || ACCEPT_INCORRECT_ARGUMENTS);
25097
25098    /*
25099     * The MIT License (MIT)
25100     *
25101     * Copyright (c) 2016 University of California San Diego
25102     * Author: Jim Robinson
25103     *
25104     * Permission is hereby granted, free of charge, to any person obtaining a copy
25105     * of this software and associated documentation files (the "Software"), to deal
25106     * in the Software without restriction, including without limitation the rights
25107     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25108     * copies of the Software, and to permit persons to whom the Software is
25109     * furnished to do so, subject to the following conditions:
25110     *
25111     * The above copyright notice and this permission notice shall be included in
25112     * all copies or substantial portions of the Software.
25113     *
25114     *
25115     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25116     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25117     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25118     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25119     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25120     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25121     * THE SOFTWARE.
25122     */
25123    class PairedAlignment {
25124      constructor(firstAlignment) {
25125        this.paired = true;
25126        this.firstAlignment = firstAlignment;
25127        this.chr = firstAlignment.chr;
25128        this.readName = firstAlignment.readName;
25129
25130        if (firstAlignment.start < firstAlignment.mate.position) {
25131          this.start = firstAlignment.start;
25132          this.scStart = firstAlignment.scStart;
25133          this.connectingStart = firstAlignment.start + firstAlignment.lengthOnRef;
25134          this.connectingEnd = firstAlignment.mate.position;
25135        } else {
25136          this.start = firstAlignment.mate.position;
25137          this.scStart = this.start;
25138          this.connectingStart = firstAlignment.mate.position;
25139          this.connectingEnd = firstAlignment.start;
25140        }
25141
25142        this.end = Math.max(firstAlignment.mate.position, firstAlignment.start + firstAlignment.lengthOnRef); // Approximate
25143
25144        this.lengthOnRef = this.end - this.start;
25145        let scEnd = Math.max(this.end, firstAlignment.scStart + firstAlignment.scLengthOnRef);
25146        this.scLengthOnRef = scEnd - this.scStart;
25147      }
25148
25149      setSecondAlignment(secondAlignment) {
25150        // TODO -- check the chrs are equal,  error otherwise
25151        this.secondAlignment = secondAlignment;
25152        const firstAlignment = this.firstAlignment;
25153
25154        if (secondAlignment.start > firstAlignment.start) {
25155          this.connectingEnd = secondAlignment.start;
25156        } else {
25157          this.connectingStart = secondAlignment.start + secondAlignment.lengthOnRef;
25158        }
25159
25160        this.start = Math.min(firstAlignment.start, secondAlignment.start);
25161        this.end = Math.max(firstAlignment.start + firstAlignment.lengthOnRef, secondAlignment.start + secondAlignment.lengthOnRef);
25162        this.lengthOnRef = this.end - this.start;
25163        this.scStart = Math.min(firstAlignment.scStart, secondAlignment.scStart);
25164        const scEnd = Math.max(firstAlignment.scStart + firstAlignment.scLengthOnRef, secondAlignment.scStart + secondAlignment.scLengthOnRef);
25165        this.scLengthOnRef = scEnd - this.scStart;
25166      }
25167
25168      containsLocation(genomicLocation, showSoftClips) {
25169        const s = showSoftClips ? this.scStart : this.start;
25170        const l = showSoftClips ? this.scLengthOnRef : this.lengthOnRef;
25171        return genomicLocation >= s && genomicLocation <= s + l;
25172      }
25173
25174      alignmentContaining(genomicLocation, showSoftClips) {
25175        if (this.firstAlignment.containsLocation(genomicLocation, showSoftClips)) {
25176          return this.firstAlignment;
25177        } else if (this.secondAlignment && this.secondAlignment.containsLocation(genomicLocation, showSoftClips)) {
25178          return this.secondAlignment;
25179        } else {
25180          return undefined;
25181        }
25182      }
25183
25184      popupData(genomicLocation) {
25185        let nameValues = this.firstAlignment.popupData(genomicLocation);
25186
25187        if (this.secondAlignment) {
25188          nameValues.push("-------------------------------");
25189          nameValues = nameValues.concat(this.secondAlignment.popupData(genomicLocation));
25190        }
25191
25192        return nameValues;
25193      }
25194
25195      isPaired() {
25196        return true; // By definition
25197      }
25198
25199      firstOfPairStrand() {
25200        if (this.firstAlignment.isFirstOfPair()) {
25201          return this.firstAlignment.strand;
25202        } else if (this.secondAlignment && this.secondAlignment.isFirstOfPair()) {
25203          return this.secondAlignment.strand;
25204        } else {
25205          return this.firstAlignment.mate.strand; // Assumption is mate is first-of-pair
25206        }
25207      }
25208
25209    }
25210
25211    /*
25212     * The MIT License (MIT)
25213     *
25214     * Copyright (c) 2014 Broad Institute
25215     *
25216     * Permission is hereby granted, free of charge, to any person obtaining a copy
25217     * of this software and associated documentation files (the "Software"), to deal
25218     * in the Software without restriction, including without limitation the rights
25219     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25220     * copies of the Software, and to permit persons to whom the Software is
25221     * furnished to do so, subject to the following conditions:
25222     *
25223     * The above copyright notice and this permission notice shall be included in
25224     * all copies or substantial portions of the Software.
25225     *
25226     *
25227     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25228     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25229     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25230     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25231     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25232     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25233     * THE SOFTWARE.
25234     */
25235    const isString$2 = isString$3;
25236    const hashCode = hashCode$1;
25237
25238    class BamAlignmentRow {
25239      constructor() {
25240        this.alignments = [];
25241        this.score = undefined;
25242      }
25243
25244      findAlignment(genomicLocation) {
25245        const alignmentContains = (a, genomicLocation) => {
25246          return genomicLocation >= a.start && genomicLocation < a.start + a.lengthOnRef;
25247        }; // find single alignment that overlaps sort location
25248
25249
25250        let centerAlignment;
25251
25252        for (let i = 0; i < this.alignments.length; i++) {
25253          const a = this.alignments[i];
25254
25255          if (genomicLocation >= a.start && genomicLocation < a.start + a.lengthOnRef) {
25256            if (a.paired) {
25257              if (a.firstAlignment && alignmentContains(a.firstAlignment, genomicLocation)) {
25258                centerAlignment = a.firstAlignment;
25259              } else if (a.secondAlignment && alignmentContains(a.secondAlignment, genomicLocation)) {
25260                centerAlignment = a.secondAlignment;
25261              }
25262            } else {
25263              centerAlignment = a;
25264            }
25265
25266            break;
25267          }
25268        }
25269
25270        return centerAlignment;
25271      }
25272
25273      updateScore(options, alignmentContainer) {
25274        this.score = this.calculateScore(options, alignmentContainer);
25275      }
25276
25277      calculateScore(_ref, alignmentContainer) {
25278        let {
25279          position,
25280          option,
25281          direction,
25282          tag
25283        } = _ref;
25284        if (!option) option = "BASE";
25285        const alignment = this.findAlignment(position);
25286
25287        if (undefined === alignment) {
25288          return Number.MAX_VALUE * (direction ? 1 : -1);
25289        }
25290
25291        let mate;
25292
25293        switch (option) {
25294          case "NUCLEOTIDE":
25295          case "BASE":
25296            {
25297              return calculateBaseScore(alignment, alignmentContainer, position);
25298            }
25299
25300          case "STRAND":
25301            return alignment.strand ? 1 : -1;
25302
25303          case "START":
25304            return alignment.start;
25305
25306          case "TAG":
25307            {
25308              const tagValue = alignment.tags()[tag];
25309
25310              if (tagValue !== undefined) {
25311                return isString$2(tagValue) ? hashCode(tagValue) : tagValue;
25312              } else {
25313                return Number.MAX_VALUE;
25314              }
25315            }
25316
25317          case "READ_NAME":
25318            return hashCode(alignment.readName);
25319
25320          case "INSERT_SIZE":
25321            return -Math.abs(alignment.fragmentLength);
25322
25323          case "GAP_SIZE":
25324            return -alignment.gapSizeAt(position);
25325
25326          case "MATE_CHR":
25327            mate = alignment.mate;
25328
25329            if (!mate) {
25330              return Number.MAX_VALUE;
25331            } else {
25332              if (mate.chr === alignment.chr) {
25333                return Number.MAX_VALUE - 1;
25334              } else {
25335                return hashCode(mate.chr);
25336              }
25337            }
25338
25339          case "MQ":
25340            return alignment.mq === undefined ? Number.MAX_VALUE : -alignment.mq;
25341
25342          default:
25343            return Number.MAX_VALUE;
25344        }
25345
25346        function calculateBaseScore(alignment, alignmentContainer, genomicLocation) {
25347          let reference;
25348          const idx = Math.floor(genomicLocation) - alignmentContainer.start;
25349
25350          if (idx < alignmentContainer.sequence.length) {
25351            reference = alignmentContainer.sequence.charAt(idx);
25352          }
25353
25354          if (!reference) {
25355            return 0;
25356          }
25357
25358          const base = alignment.readBaseAt(genomicLocation);
25359          const quality = alignment.readBaseQualityAt(genomicLocation);
25360          const coverageMap = alignmentContainer.coverageMap;
25361          const coverageMapIndex = Math.floor(genomicLocation - coverageMap.bpStart);
25362          const coverage = coverageMap.coverage[coverageMapIndex]; // Insertions.  These are additive with base scores as they occur between bases, so you can have a
25363          // base mismatch AND an insertion
25364
25365          let baseScore = 0;
25366
25367          if (alignment.insertions) {
25368            for (let ins of alignment.insertions) {
25369              if (ins.start === genomicLocation) {
25370                baseScore = -coverage.ins;
25371              }
25372            }
25373          }
25374
25375          if (!base) {
25376            // Either deletion or skipped (splice junction)
25377            const delCount = coverage.del;
25378
25379            if (delCount > 0) {
25380              baseScore -= delCount;
25381            } else if (baseScore === 0) {
25382              // Don't modify insertion score, if any
25383              baseScore = 1;
25384            }
25385          } else {
25386            reference = reference.toUpperCase();
25387
25388            if ('N' === base && baseScore === 0) {
25389              baseScore = 2;
25390            } else if ((reference === base || '=' === base) && baseScore === 0) {
25391              baseScore = 4 - quality / 1000;
25392            } else if ("X" === base || reference !== base) {
25393              const count = coverage["pos" + base] + coverage["neg" + base];
25394              baseScore -= count + quality / 1000;
25395            }
25396          }
25397
25398          return baseScore;
25399        }
25400      }
25401
25402    }
25403
25404    function canBePaired(alignment) {
25405      return alignment.isPaired() && alignment.mate && alignment.isMateMapped() && alignment.chr === alignment.mate.chr && (alignment.isFirstOfPair() || alignment.isSecondOfPair()) && !(alignment.isSecondary() || alignment.isSupplementary());
25406    }
25407
25408    function pairAlignments(rows) {
25409      const pairCache = {};
25410      const result = [];
25411
25412      for (let row of rows) {
25413        for (let alignment of row.alignments) {
25414          if (canBePaired(alignment)) {
25415            let pairedAlignment = pairCache[alignment.readName];
25416
25417            if (pairedAlignment) {
25418              pairedAlignment.setSecondAlignment(alignment);
25419              pairCache[alignment.readName] = undefined; // Don't need to track this anymore.
25420            } else {
25421              pairedAlignment = new PairedAlignment(alignment);
25422              pairCache[alignment.readName] = pairedAlignment;
25423              result.push(pairedAlignment);
25424            }
25425          } else {
25426            result.push(alignment);
25427          }
25428        }
25429      }
25430
25431      return result;
25432    }
25433
25434    function unpairAlignments(rows) {
25435      const result = [];
25436
25437      for (let row of rows) {
25438        for (let alignment of row.alignments) {
25439          if (alignment instanceof PairedAlignment) {
25440            if (alignment.firstAlignment) result.push(alignment.firstAlignment); // shouldn't need the null test
25441
25442            if (alignment.secondAlignment) result.push(alignment.secondAlignment);
25443          } else {
25444            result.push(alignment);
25445          }
25446        }
25447      }
25448
25449      return result;
25450    }
25451
25452    function packAlignmentRows(alignments, start, end, showSoftClips) {
25453      if (!alignments) {
25454        return undefined;
25455      } else if (alignments.length === 0) {
25456        return [];
25457      } else {
25458        alignments.sort(function (a, b) {
25459          return showSoftClips ? a.scStart - b.scStart : a.start - b.start;
25460        }); // bucketStart = Math.max(start, alignments[0].start);
25461
25462        const firstAlignment = alignments[0];
25463        let bucketStart = Math.max(start, showSoftClips ? firstAlignment.scStart : firstAlignment.start);
25464        let nextStart = bucketStart;
25465        const bucketList = [];
25466
25467        for (let alignment of alignments) {
25468          //var buckListIndex = Math.max(0, alignment.start - bucketStart);
25469          const s = showSoftClips ? alignment.scStart : alignment.start;
25470          const buckListIndex = Math.max(0, s - bucketStart);
25471
25472          if (bucketList[buckListIndex] === undefined) {
25473            bucketList[buckListIndex] = [];
25474          }
25475
25476          bucketList[buckListIndex].push(alignment);
25477        }
25478
25479        let allocatedCount = 0;
25480        let lastAllocatedCount = 0;
25481        const packedAlignmentRows = [];
25482        const alignmentSpace = 2;
25483
25484        try {
25485          while (allocatedCount < alignments.length) {
25486            const alignmentRow = new BamAlignmentRow();
25487
25488            while (nextStart <= end) {
25489              let bucket = undefined;
25490              let index;
25491
25492              while (!bucket && nextStart <= end) {
25493                index = nextStart - bucketStart;
25494
25495                if (bucketList[index] === undefined) {
25496                  ++nextStart; // No alignments at this index
25497                } else {
25498                  bucket = bucketList[index];
25499                }
25500              } // while (bucket)
25501
25502
25503              if (!bucket) {
25504                break;
25505              }
25506
25507              const alignment = bucket.pop();
25508
25509              if (0 === bucket.length) {
25510                bucketList[index] = undefined;
25511              }
25512
25513              alignmentRow.alignments.push(alignment);
25514              nextStart = showSoftClips ? alignment.scStart + alignment.scLengthOnRef + alignmentSpace : alignment.start + alignment.lengthOnRef + alignmentSpace;
25515              ++allocatedCount;
25516            } // while (nextStart)
25517
25518
25519            if (alignmentRow.alignments.length > 0) {
25520              packedAlignmentRows.push(alignmentRow);
25521            }
25522
25523            nextStart = bucketStart;
25524            if (allocatedCount === lastAllocatedCount) break; // Protect from infinite loops
25525
25526            lastAllocatedCount = allocatedCount;
25527          } // while (allocatedCount)
25528
25529        } catch (e) {
25530          console.error(e);
25531          throw e;
25532        }
25533
25534        return packedAlignmentRows;
25535      }
25536    }
25537
25538    /*
25539     * The MIT License (MIT)
25540     *
25541     * Copyright (c) 2016 University of California San Diego
25542     * Author: Jim Robinson
25543     *
25544     * Permission is hereby granted, free of charge, to any person obtaining a copy
25545     * of this software and associated documentation files (the "Software"), to deal
25546     * in the Software without restriction, including without limitation the rights
25547     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25548     * copies of the Software, and to permit persons to whom the Software is
25549     * furnished to do so, subject to the following conditions:
25550     *
25551     * The above copyright notice and this permission notice shall be included in
25552     * all copies or substantial portions of the Software.
25553     *
25554     *
25555     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25556     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25557     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25558     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25559     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25560     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25561     * THE SOFTWARE.
25562     */
25563
25564    class AlignmentContainer {
25565      constructor(chr, start, end, samplingWindowSize, samplingDepth, pairsSupported, alleleFreqThreshold) {
25566        this.chr = chr;
25567        this.start = Math.floor(start);
25568        this.end = Math.ceil(end);
25569        this.length = end - start;
25570        this.alleleFreqThreshold = alleleFreqThreshold === undefined ? 0.2 : alleleFreqThreshold;
25571        this.coverageMap = new CoverageMap(chr, start, end, this.alleleFreqThreshold);
25572        this.alignments = [];
25573        this.downsampledIntervals = [];
25574        this.samplingWindowSize = samplingWindowSize === undefined ? 100 : samplingWindowSize;
25575        this.samplingDepth = samplingDepth === undefined ? 1000 : samplingDepth;
25576        this.pairsSupported = pairsSupported === undefined ? true : pairsSupported;
25577        this.paired = false; // false until proven otherwise
25578
25579        this.pairsCache = {};
25579 // working cache of paired alignments by read name
25580
25581        this.downsampledReads = new Set();
25582        this.currentBucket = new DownsampleBucket(this.start, this.start + this.samplingWindowSize, this);
25583
25584        this.filter = function filter(alignment) {
25585          // TODO -- pass this in
25586          return alignment.isMapped() && !alignment.isFailsVendorQualityCheck();
25587        };
25588
25589        this.pairedEndStats = new PairedEndStats();
25590      }
25591
25592      push(alignment) {
25593        if (this.filter(alignment) === false) return;
25594
25595        if (alignment.isPaired()) {
25596          this.pairedEndStats.push(alignment);
25597        }
25598
25599        this.coverageMap.incCounts(alignment); // Count coverage before any downsampling
25600
25601        if (this.pairsSupported && this.downsampledReads.has(alignment.readName)) {
25602          return; // Mate already downsampled -- pairs are treated as a single alignment for downsampling
25603        }
25604
25605        if (alignment.start >= this.currentBucket.end) {
25606          this.finishBucket();
25607          this.currentBucket = new DownsampleBucket(alignment.start, alignment.start + this.samplingWindowSize, this);
25608        }
25609
25610        this.currentBucket.addAlignment(alignment);
25611      }
25612
25613      forEach(callback) {
25614        this.alignments.forEach(callback);
25615      }
25616
25617      finish() {
25618        if (this.currentBucket !== undefined) {
25619          this.finishBucket();
25620        }
25621
25622        this.alignments.sort(function (a, b) {
25623          return a.start - b.start;
25624        });
25625        this.pairsCache = undefined;
25626        this.downsampledReads = undefined;
25627        this.pairedEndStats.compute();
25628      }
25629
25630      contains(chr, start, end) {
25631        return this.chr === chr && this.start <= start && this.end >= end;
25632      }
25633
25634      hasDownsampledIntervals() {
25635        return this.downsampledIntervals && this.downsampledIntervals.length > 0;
25636      }
25637
25638      finishBucket() {
25639        this.alignments = this.alignments.concat(this.currentBucket.alignments);
25640
25641        if (this.currentBucket.downsampledCount > 0) {
25642          this.downsampledIntervals.push(new DownsampledInterval(this.currentBucket.start, this.currentBucket.end, this.currentBucket.downsampledCount));
25643        }
25644
25645        this.paired = this.paired || this.currentBucket.paired;
25646      }
25647
25648      setViewAsPairs(bool) {
25649        let alignments;
25650
25651        if (bool) {
25652          alignments = pairAlignments(this.packedAlignmentRows);
25653        } else {
25654          alignments = unpairAlignments(this.packedAlignmentRows);
25655        }
25656
25657        this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end);
25658      }
25659
25660      setShowSoftClips(bool) {
25661        const alignments = this.allAlignments();
25662        this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end, bool);
25663      }
25664
25665      repack(bpPerPixel, showSoftClips) {
25666        const alignments = this.allAlignments();
25667        this.packedAlignmentRows = packAlignmentRows(alignments, this.start, this.end, showSoftClips);
25668      }
25669
25670      allAlignments() {
25671        const alignments = [];
25672
25673        for (let row of this.packedAlignmentRows) {
25674          for (let alignment of row.alignments) {
25675            alignments.push(alignment);
25676          }
25677        }
25678
25679        return alignments;
25680      }
25681
25682      getMax(start, end) {
25683        return this.coverageMap.getMax(start, end);
25684      }
25685
25686    }
25687
25688    class DownsampleBucket {
25689      constructor(start, end, alignmentContainer) {
25690        this.start = start;
25691        this.end = end;
25692        this.alignments = [];
25693        this.downsampledCount = 0;
25694        this.samplingDepth = alignmentContainer.samplingDepth;
25695        this.pairsSupported = alignmentContainer.pairsSupported;
25696        this.downsampledReads = alignmentContainer.downsampledReads;
25697        this.pairsCache = alignmentContainer.pairsCache;
25698      }
25699
25700      addAlignment(alignment) {
25701        var idx, replacedAlignment, pairedAlignment;
25702
25703        if (this.pairsSupported && canBePaired(alignment)) {
25704          pairedAlignment = this.pairsCache[alignment.readName];
25705
25706          if (pairedAlignment) {
25707            // Not subject to downsampling, just update the existing alignment
25708            pairedAlignment.setSecondAlignment(alignment);
25709            this.pairsCache[alignment.readName] = undefined; // Don't need to track this anymore. NOTE: Don't "delete", causes runtime performance issues
25710
25711            return;
25712          }
25713        }
25714
25715        if (this.alignments.length < this.samplingDepth) {
25716          if (this.pairsSupported && canBePaired(alignment)) {
25717            // First alignment in a pair
25718            pairedAlignment = new PairedAlignment(alignment);
25719            this.paired = true;
25720            this.pairsCache[alignment.readName] = pairedAlignment;
25721            this.alignments.push(pairedAlignment);
25722          } else {
25723            this.alignments.push(alignment);
25724          }
25725        } else {
25726          idx = Math.floor(Math.random() * (this.samplingDepth + this.downsampledCount - 1));
25727
25728          if (idx < this.samplingDepth) {
25729            // Keep the new item
25730            //  idx = Math.floor(Math.random() * (this.alignments.length - 1));
25731            replacedAlignment = this.alignments[idx]; // To be replaced
25732
25733            if (this.pairsSupported && canBePaired(alignment)) {
25734              if (this.pairsCache[replacedAlignment.readName] !== undefined) {
25735                this.pairsCache[replacedAlignment.readName] = undefined;
25736              }
25737
25738              pairedAlignment = new PairedAlignment(alignment);
25739              this.paired = true;
25740              this.pairsCache[alignment.readName] = pairedAlignment;
25741              this.alignments[idx] = pairedAlignment;
25742            } else {
25743              this.alignments[idx] = alignment;
25744            }
25745
25746            this.downsampledReads.add(replacedAlignment.readName);
25747          } else {
25748            this.downsampledReads.add(alignment.readName);
25749          }
25750
25751          this.downsampledCount++;
25752        }
25753      }
25754
25755    }
25756
25757    class CoverageMap {
25758      constructor(chr, start, end, alleleFreqThreshold) {
25759        this.chr = chr;
25760        this.bpStart = start;
25761        this.length = end - start;
25762        this.coverage = new Array(this.length);
25763        this.maximum = 0;
25764        this.threshold = alleleFreqThreshold;
25765        this.qualityWeight = true;
25766      }
25767      /**
25768       * Return the maximum coverage value between start and end.  This is used for autoscaling.
25769       * @param start
25770       * @param end
25771       */
25772
25773
25774      getMax(start, end) {
25775        let max = 0;
25776        const len = this.coverage.length;
25777
25778        for (let i = 0; i < len; i++) {
25779          const pos = this.bpStart + i;
25780          if (pos > end) break;
25781          const cov = this.coverage[i];
25782
25783          if (pos >= start && cov) {
25784            max = Math.max(max, cov.total);
25785          }
25786        }
25787
25788        return max;
25789      }
25790
25791      incCounts(alignment) {
25792        var self = this;
25793
25794        if (alignment.blocks === undefined) {
25795          incBlockCount(alignment);
25796        } else {
25797          alignment.blocks.forEach(function (block) {
25798            incBlockCount(block);
25799          });
25800        }
25801
25802        if (alignment.gaps) {
25803          for (let del of alignment.gaps) {
25804            if (del.type === 'D') {
25805              const offset = del.start - self.bpStart;
25806
25807              for (let i = offset; i < offset + del.len; i++) {
25808                if (i < 0) continue;
25809
25810                if (!this.coverage[i]) {
25811                  this.coverage[i] = new Coverage(self.threshold);
25812                }
25813
25814                this.coverage[i].del++;
25815              }
25816            }
25817          }
25818        }
25819
25820        if (alignment.insertions) {
25821          for (let del of alignment.insertions) {
25822            const i = del.start - this.bpStart;
25823            if (i < 0) continue;
25824
25825            if (!this.coverage[i]) {
25826              this.coverage[i] = new Coverage(self.threshold);
25827            }
25828
25829            this.coverage[i].ins++;
25830          }
25831        }
25832
25833        function incBlockCount(block) {
25834          if ('S' === block.type) return;
25835          const seq = alignment.seq;
25836          const qual = alignment.qual;
25837          const seqOffset = block.seqOffset;
25838
25839          for (let i = block.start - self.bpStart, j = 0; j < block.len; i++, j++) {
25840            if (!self.coverage[i]) {
25841              self.coverage[i] = new Coverage(self.threshold);
25842            }
25843
25844            const base = seq == undefined ? "N" : seq.charAt(seqOffset + j);
25845            const key = alignment.strand ? "pos" + base : "neg" + base;
25846            const q = qual && seqOffset + j < qual.length ? qual[seqOffset + j] : 30;
25847            self.coverage[i][key] += 1;
25848            self.coverage[i]["qual" + base] += q;
25849            self.coverage[i].total += 1;
25850            self.coverage[i].qual += q;
25851            self.maximum = Math.max(self.coverage[i].total, self.maximum);
25852          }
25853        }
25854      }
25855
25856    }
25857
25858    class Coverage {
25859      constructor(alleleThreshold) {
25860        this.qualityWeight = true;
25861        this.posA = 0;
25862        this.negA = 0;
25863        this.posT = 0;
25864        this.negT = 0;
25865        this.posC = 0;
25866        this.negC = 0;
25867        this.posG = 0;
25868        this.negG = 0;
25869        this.posN = 0;
25870        this.negN = 0;
25871        this.pos = 0;
25872        this.neg = 0;
25873        this.qualA = 0;
25874        this.qualT = 0;
25875        this.qualC = 0;
25876        this.qualG = 0;
25877        this.qualN = 0;
25878        this.qual = 0;
25879        this.total = 0;
25880        this.del = 0;
25881        this.ins = 0;
25882        this.threshold = alleleThreshold;
25883      }
25884
25885      isMismatch(refBase) {
25886        const threshold = this.threshold * (this.qualityWeight && this.qual ? this.qual : this.total);
25887        let mismatchQualitySum = 0;
25888
25889        for (let base of ["A", "T", "C", "G"]) {
25890          if (base !== refBase) {
25891            mismatchQualitySum += this.qualityWeight && this.qual ? this["qual" + base] : this["pos" + base] + this["neg" + base];
25892          }
25893        }
25894
25895        return mismatchQualitySum >= threshold;
25896      }
25897
25898    }
25899
25900    class DownsampledInterval {
25901      constructor(start, end, counts) {
25902        this.start = start;
25903        this.end = end;
25904        this.counts = counts;
25905      }
25906
25907      popupData(genomicLocation) {
25908        return [{
25909          name: "start",
25910          value: this.start + 1
25911        }, {
25912          name: "end",
25913          value: this.end
25914        }, {
25915          name: "# downsampled:",
25916          value: this.counts
25917        }];
25918      }
25919
25920    }
25921
25922    class PairedEndStats {
25923      constructor(lowerPercentile, upperPercentile) {
25924        this.totalCount = 0;
25925        this.frCount = 0;
25926        this.rfCount = 0;
25927        this.ffCount = 0;
25928        this.sumF = 0;
25929        this.sumF2 = 0; //this.lp = lowerPercentile === undefined ? 0.005 : lowerPercentile;
25930        //this.up = upperPercentile === undefined ? 0.995 : upperPercentile;
25931        //this.digest = new Digest();
25932      }
25933
25934      push(alignment) {
25935        if (alignment.isProperPair()) {
25936          var fragmentLength = Math.abs(alignment.fragmentLength); //this.digest.push(fragmentLength);
25937
25938          this.sumF += fragmentLength;
25939          this.sumF2 += fragmentLength * fragmentLength;
25940          var po = alignment.pairOrientation;
25941
25942          if (typeof po === "string" && po.length === 4) {
25943            var tmp = '' + po.charAt(0) + po.charAt(2);
25944
25945            switch (tmp) {
25946              case 'FF':
25947              case 'RR':
25948                this.ffCount++;
25949                break;
25950
25951              case "FR":
25952                this.frCount++;
25953                break;
25954
25955              case "RF":
25956                this.rfCount++;
25957            }
25958          }
25959
25960          this.totalCount++;
25961        }
25962      }
25963
25964      compute() {
25965        if (this.totalCount > 100) {
25966          if (this.ffCount / this.totalCount > 0.9) this.orienation = "ff";else if (this.frCount / this.totalCount > 0.9) this.orienation = "fr";else if (this.rfCount / this.totalCount > 0.9) this.orienation = "rf";
25967          var fMean = this.sumF / this.totalCount;
25968          var stdDev = Math.sqrt((this.totalCount * this.sumF2 - this.sumF * this.sumF) / (this.totalCount * this.totalCount));
25969          this.lowerFragmentLength = fMean - 3 * stdDev;
25970          this.upperFragmentLength = fMean + 3 * stdDev; //this.lowerFragmentLength = this.digest.percentile(this.lp);
25971          //this.upperFragmentLength = this.digest.percentile(this.up);
25972          //this.digest = undefined;
25973        }
25974      }
25975
25976    }
25977
25978    class SupplementaryAlignment {
25979      constructor(rec) {
25980        const tokens = rec.split(',');
25981        this.chr = tokens[0];
25982        this.start = parseInt(tokens[1]);
25983        this.strand = tokens[2].charAt(0);
25984        this.mapQ = parseInt(tokens[4]);
25985        this.numMismatches = parseInt(tokens[5]);
25986        this.lenOnRef = BamUtils.computeLengthOnReference(tokens[3]);
25987      }
25988
25989      printString() {
25990        return this.chr + ":" + numberFormatter$1(this.start) + "-" + numberFormatter$1(this.start + this.lenOnRef) + " (" + this.strand + ") = " + numberFormatter$1(this.lenOnRef) + "bp @MAPQ: " + this.mapQ + " NM: " + this.numMismatches;
25991      }
25992
25993    }
25994
25995    function createSupplementaryAlignments(str) {
25996      const tokens = str.split(';');
25997      return tokens.filter(t => t.length > 0).map(str => new SupplementaryAlignment(str));
25998    }
25999
26000    /*
26001     * The MIT License (MIT)
26002     *
26003     * Copyright (c) 2014 Broad Institute
26004     *
26005     * Permission is hereby granted, free of charge, to any person obtaining a copy
26006     * of this software and associated documentation files (the "Software"), to deal
26007     * in the Software without restriction, including without limitation the rights
26008     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26009     * copies of the Software, and to permit persons to whom the Software is
26010     * furnished to do so, subject to the following conditions:
26011     *
26012     * The above copyright notice and this permission notice shall be included in
26013     * all copies or substantial portions of the Software.
26014     *
26015     *
26016     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26017     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26018     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26019     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26020     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26021     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26022     * THE SOFTWARE.
26023     */
26024    const READ_PAIRED_FLAG = 0x1;
26025    const PROPER_PAIR_FLAG = 0x2;
26026    const READ_UNMAPPED_FLAG = 0x4;
26027    const MATE_UNMAPPED_FLAG = 0x8;
26028    const READ_STRAND_FLAG$2 = 0x10;
26029    const MATE_STRAND_FLAG$2 = 0x20;
26030    const FIRST_OF_PAIR_FLAG = 0x40;
26031    const SECOND_OF_PAIR_FLAG = 0x80;
26032    const SECONDARY_ALIGNMNET_FLAG = 0x100;
26033    const READ_FAILS_VENDOR_QUALITY_CHECK_FLAG = 0x200;
26034    const DUPLICATE_READ_FLAG = 0x400;
26035    const SUPPLEMENTARY_ALIGNMENT_FLAG = 0x800;
26036    const ELEMENT_SIZE = {
26037      c: 1,
26038      C: 1,
26039      s: 2,
26040      S: 2,
26041      i: 4,
26042      I: 4,
26043      f: 4
26044    };
26045    const MAX_CIGAR = 50;
26046    /**
26047     * readName
26048     * chr
26049     * cigar
26050     * lengthOnRef
26051     * start
26052     * seq
26053     * qual
26054     * mq
26055     * strand
26056     * blocks
26057     */
26058
26059    class BamAlignment {
26060      constructor() {
26061        this.hidden = false;
26062      }
26063
26064      isMapped() {
26065        return (this.flags & READ_UNMAPPED_FLAG) === 0;
26066      }
26067
26068      isPaired() {
26069        return (this.flags & READ_PAIRED_FLAG) !== 0;
26070      }
26071
26072      isProperPair() {
26073        return (this.flags & PROPER_PAIR_FLAG) !== 0;
26074      }
26075
26076      isFirstOfPair() {
26077        return (this.flags & FIRST_OF_PAIR_FLAG) !== 0;
26078      }
26079
26080      isSecondOfPair() {
26081        return (this.flags & SECOND_OF_PAIR_FLAG) !== 0;
26082      }
26083
26084      isSecondary() {
26085        return (this.flags & SECONDARY_ALIGNMNET_FLAG) !== 0;
26086      }
26087
26088      isSupplementary() {
26089        return (this.flags & SUPPLEMENTARY_ALIGNMENT_FLAG) !== 0;
26090      }
26091
26092      isFailsVendorQualityCheck() {
26093        return (this.flags & READ_FAILS_VENDOR_QUALITY_CHECK_FLAG) !== 0;
26094      }
26095
26096      isDuplicate() {
26097        return (this.flags & DUPLICATE_READ_FLAG) !== 0;
26098      }
26099
26100      isMateMapped() {
26101        return (this.flags & MATE_UNMAPPED_FLAG) === 0;
26102      }
26103
26104      isNegativeStrand() {
26105        return (this.flags & READ_STRAND_FLAG$2) !== 0;
26106      }
26107
26108      isMateNegativeStrand() {
26109        return (this.flags & MATE_STRAND_FLAG$2) !== 0;
26110      }
26111
26112      hasTag(tag) {
26113        const tmpTags = this.tagDict || decodeTags(this.tagBA);
26114        return tmpTags.hasOwnProperty(tag);
26115      }
26116
26117      tags() {
26118        if (!this.tagDict) {
26119          if (this.tagBA) {
26120            this.tagDict = decodeTags(this.tagBA);
26121            this.tagBA = undefined;
26122          } else {
26123            this.tagDict = {}; // Mark so we don't try again.  The record has no tags
26124          }
26125        }
26126
26127        return this.tagDict;
26128      }
26129      /**
26130       * Does alignment (or alignment extended by soft clips) contain the genomic location?
26131       *
26132       * @param genomicLocation
26133       * @param showSoftClips
26134       * @returns {boolean|boolean}
26135       */
26136
26137
26138      containsLocation(genomicLocation, showSoftClips) {
26139        const s = showSoftClips ? this.scStart : this.start;
26140        const l = showSoftClips ? this.scLengthOnRef : this.lengthOnRef;
26141        return genomicLocation >= s && genomicLocation <= s + l;
26142      }
26143
26144      popupData(genomicLocation) {
26145        // if the user clicks on a base next to an insertion, show just the
26146        // inserted bases in a popup (like in desktop IGV).
26147        const nameValues = []; // Consert genomic location to int
26148
26149        genomicLocation = Math.floor(genomicLocation);
26150
26151        if (this.insertions) {
26152          const seq = this.seq;
26153
26154          for (let insertion of this.insertions) {
26155            var ins_start = insertion.start;
26156
26157            if (genomicLocation === ins_start || genomicLocation === ins_start - 1) {
26158              nameValues.push({
26159                name: 'Insertion',
26160                value: seq.substr(insertion.seqOffset, insertion.len)
26161              });
26162              nameValues.push({
26163                name: 'Location',
26164                value: ins_start
26165              });
26166              return nameValues;
26167            }
26168          }
26169        }
26170
26171        nameValues.push({
26172          name: 'Read Name',
26173          value: this.readName
26174        }); // Sample
26175        // Read group
26176
26177        nameValues.push('<hr/>'); // Add 1 to genomic location to map from 0-based computer units to user-based units
26178
26179        nameValues.push({
26180          name: 'Alignment Start',
26181          value: numberFormatter$1(1 + this.start),
26182          borderTop: true
26183        });
26184        nameValues.push({
26185          name: 'Read Strand',
26186          value: true === this.strand ? '(+)' : '(-)',
26187          borderTop: true
26188        }); // Abbreviate long cigar strings, keeping the beginning and end to show cliping
26189
26190        let cigar = this.cigar;
26191
26192        if (cigar && cigar.length > MAX_CIGAR) {
26193          const half = MAX_CIGAR / 2;
26194          cigar = `${cigar.substring(0, half - 2)} ... ${cigar.substring(cigar.length - half + 2)}`;
26195        }
26196
26197        nameValues.push({
26198          name: 'Cigar',
26199          value: cigar
26200        });
26201        nameValues.push({
26202          name: 'Mapping Quality',
26203          value: this.mq
26204        });
26205        nameValues.push({
26206          name: 'Secondary',
26207          value: yesNo(this.isSecondary())
26208        });
26209        nameValues.push({
26210          name: 'Supplementary',
26211          value: yesNo(this.isSupplementary())
26212        });
26213        nameValues.push({
26214          name: 'Duplicate',
26215          value: yesNo(this.isDuplicate())
26216        });
26217        nameValues.push({
26218          name: 'Failed QC',
26219          value: yesNo(this.isFailsVendorQualityCheck())
26220        });
26221
26222        if (this.isPaired()) {
26223          nameValues.push('<hr/>');
26224          nameValues.push({
26225            name: 'First in Pair',
26226            value: !this.isSecondOfPair(),
26227            borderTop: true
26228          });
26229          nameValues.push({
26230            name: 'Mate is Mapped',
26231            value: yesNo(this.isMateMapped())
26232          });
26233
26234          if (this.pairOrientation) {
26235            nameValues.push({
26236              name: 'Pair Orientation',
26237              value: this.pairOrientation
26238            });
26239          }
26240
26241          if (this.isMateMapped()) {
26242            nameValues.push({
26243              name: 'Mate Chromosome',
26244              value: this.mate.chr
26245            });
26246            nameValues.push({
26247              name: 'Mate Start',
26248              value: this.mate.position + 1
26249            });
26250            nameValues.push({
26251              name: 'Mate Strand',
26252              value: true === this.mate.strand ? '(+)' : '(-)'
26253            });
26254            nameValues.push({
26255              name: 'Insert Size',
26256              value: this.fragmentLength
26257            }); // Mate Start
26258            // Mate Strand
26259            // Insert Size
26260          } // First in Pair
26261          // Pair Orientation
26262
26263        }
26264
26265        const tagDict = this.tags();
26266
26267        if (tagDict.hasOwnProperty('SA')) {
26268          nameValues.push('<hr/>');
26269          nameValues.push({
26270            name: 'Supplementary Alignments',
26271            value: ''
26272          });
26273          const sa = createSupplementaryAlignments(tagDict['SA']);
26274
26275          if (sa) {
26276            nameValues.push('<ul>');
26277
26278            for (let s of sa) {
26279              nameValues.push(`<li>${s.printString()}</li>`);
26280            }
26281
26282            nameValues.push('</ul>');
26283          }
26284        }
26285
26286        const hiddenTags = new Set(['SA', 'MD']);
26287        nameValues.push('<hr/>');
26288
26289        for (let key in tagDict) {
26290          if (!hiddenTags.has(key)) {
26291            nameValues.push({
26292              name: key,
26293              value: tagDict[key]
26294            });
26295          }
26296        }
26297
26298        nameValues.push({
26299          name: 'Hidden Tags',
26300          value: 'SA, MD'
26301        });
26302        nameValues.push('<hr/>');
26303        nameValues.push({
26304          name: 'Genomic Location: ',
26305          value: numberFormatter$1(1 + genomicLocation)
26306        });
26307        nameValues.push({
26308          name: 'Read Base:',
26309          value: this.readBaseAt(genomicLocation)
26310        });
26311        nameValues.push({
26312          name: 'Base Quality:',
26313          value: this.readBaseQualityAt(genomicLocation)
26314        });
26315        return nameValues;
26316
26317        function yesNo(bool) {
26318          return bool ? 'Yes' : 'No';
26319        }
26320      }
26321
26322      readBaseAt(genomicLocation) {
26323        const block = blockAtGenomicLocation(this.blocks, genomicLocation);
26324
26325        if (block) {
26326          if ("*" === this.seq) {
26327            return "*";
26328          } else {
26329            const idx = block.seqIndexAt(genomicLocation); // if (idx >= 0 && idx < this.seq.length) {
26330
26331            return this.seq[idx]; //  }
26332          }
26333        } else {
26334          return undefined;
26335        }
26336      }
26337
26338      readBaseQualityAt(genomicLocation) {
26339        const block = blockAtGenomicLocation(this.blocks, genomicLocation);
26340
26341        if (block) {
26342          if ("*" === this.qual) {
26343            return 30;
26344          } else {
26345            const idx = block.seqIndexAt(genomicLocation);
26346
26347            if (idx >= 0 && this.qual && idx < this.qual.length) {
26348              return this.qual[idx];
26349            } else {
26350              return 30;
26351            }
26352          }
26353        } else {
26354          return undefined;
26355        }
26356      }
26357
26358      gapSizeAt(genomicLocation) {
26359        if (this.gaps) {
26360          for (let gap of this.gaps) {
26361            if (genomicLocation >= gap.start && genomicLocation < gap.start + gap.len) {
26362              return gap.len;
26363            }
26364          }
26365        }
26366
26367        return 0;
26368      }
26369
26370    }
26371
26372    function blockAtGenomicLocation(blocks, genomicLocation) {
26373      for (let i = 0; i < blocks.length; i++) {
26374        const block = blocks[i];
26375
26376        if (genomicLocation >= block.start && genomicLocation < block.start + block.len) {
26377          return block;
26378        }
26379      }
26380
26381      return undefined;
26382    }
26383
26384    function decodeTags(ba) {
26385      let p = 0;
26386      const len = ba.length;
26387      const tags = {};
26388
26389      while (p < len) {
26390        const tag = String.fromCharCode(ba[p]) + String.fromCharCode(ba[p + 1]);
26391        p += 2;
26392        const type = String.fromCharCode(ba[p++]);
26393        let value;
26394
26395        if (type === 'A') {
26396          value = String.fromCharCode(ba[p]);
26397          p++;
26398        } else if (type === 'i' || type === 'I') {
26399          value = readInt$1(ba, p);
26400          p += 4;
26401        } else if (type === 'c') {
26402          value = readInt8(ba, p);
26403          p++;
26404        } else if (type === 'C') {
26405          value = readUInt8(ba, p);
26406          p++;
26407        } else if (type === 's' || type === 'S') {
26408          value = readShort(ba, p);
26409          p += 2;
26410        } else if (type === 'f') {
26411          value = readFloat(ba, p);
26412          p += 4;
26413        } else if (type === 'Z') {
26414          value = '';
26415
26416          for (;;) {
26417            var cc = ba[p++];
26418
26419            if (cc === 0) {
26420              break;
26421            } else {
26422              value += String.fromCharCode(cc);
26423            }
26424          }
26425        } else if (type === 'B') {
26426          const elementType = String.fromCharCode(ba[p++]);
26427          let elementSize = ELEMENT_SIZE[elementType];
26428
26429          if (elementSize === undefined) {
26430            tags[tag] = `Error: unknown element type '${elementType}'`;
26431            break;
26432          }
26433
26434          const numElements = readInt$1(ba, p);
26435          p += 4 + numElements * elementSize;
26436          value = '[not shown]';
26437        } else {
26438          //'Unknown type ' + type;
26439          value = 'Error unknown type: ' + type;
26440          tags[tag] = value;
26441          break;
26442        }
26443
26444        tags[tag] = value;
26445      }
26446
26447      return tags;
26448    }
26449
26450    function readInt$1(ba, offset) {
26451      return ba[offset + 3] << 24 | ba[offset + 2] << 16 | ba[offset + 1] << 8 | ba[offset];
26452    }
26453
26454    function readShort(ba, offset) {
26455      return ba[offset + 1] << 8 | ba[offset];
26456    }
26457
26458    function readFloat(ba, offset) {
26459      const dataView = new DataView(ba.buffer);
26460      return dataView.getFloat32(offset);
26461    }
26462
26463    function readInt8(ba, offset) {
26464      const dataView = new DataView(ba.buffer);
26465      return dataView.getInt8(offset);
26466    }
26467
26468    function readUInt8(ba, offset) {
26469      const dataView = new DataView(ba.buffer);
26470      return dataView.getUint8(offset);
26471    }
26472
26473    /*
26474     * The MIT License (MIT)
26475     *
26476     * Copyright (c) 2016-2017 The Regents of the University of California
26477     * Author: Jim Robinson
26478     *
26479     * Permission is hereby granted, free of charge, to any person obtaining a copy
26480     * of this software and associated documentation files (the "Software"), to deal
26481     * in the Software without restriction, including without limitation the rights
26482     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26483     * copies of the Software, and to permit persons to whom the Software is
26484     * furnished to do so, subject to the following conditions:
26485     *
26486     * The above copyright notice and this permission notice shall be included in
26487     * all copies or substantial portions of the Software.
26488     *
26489     *
26490     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26491     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26492     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26493     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26494     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26495     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26496     * THE SOFTWARE.
26497     */
26498
26499    /**
26500     * Created by jrobinso on 4/5/18.
26501     */
26502    class AlignmentBlock {
26503      constructor(b) {
26504        if (b) {
26505          Object.assign(this, b);
26506        }
26507      }
26508
26509      seqIndexAt(genomicLocation) {
26510        return Math.floor(genomicLocation) - this.start + this.seqOffset;
26511      }
26512
26513    }
26514
26515    class BamFilter {
26516      constructor(options) {
26517        if (!options) options = {};
26518        this.vendorFailed = options.vendorFailed === undefined ? true : options.vendorFailed;
26519        this.duplicates = options.duplicates === undefined ? true : options.duplicates;
26520        this.secondary = options.secondary || false;
26521        this.supplementary = options.supplementary || false;
26522        this.mqThreshold = options.mqThreshold === undefined ? 0 : options.mqThreshold;
26523
26524        if (options.readgroups) {
26525          this.readgroups = new Set(options.readgroups);
26526        }
26527      }
26528
26529      pass(alignment) {
26530        if (this.vendorFailed && alignment.isFailsVendorQualityCheck()) return false;
26531        if (this.duplicates && alignment.isDuplicate()) return false;
26532        if (this.secondary && alignment.isSecondary()) return false;
26533        if (this.supplementary && alignment.isSupplementary()) return false;
26534        if (alignment.mq < this.mqThreshold) return false;
26535
26536        if (this.readgroups) {
26537          var rg = alignment.tags()['RG'];
26538          return this.readgroups.has(rg);
26539        }
26540
26541        return true;
26542      }
26543
26544    }
26545
26546    /**
26547     * This code is based on the Biodalliance BAM reader by Thomas Down,  2011
26548     *
26549     * https://github.com/dasmoth/dalliance/blob/master/js/bam.js
26550     */
26551
26552    const SEQ_DECODER = ['=', 'A', 'C', 'x', 'G', 'x', 'x', 'x', 'T', 'x', 'x', 'x', 'x', 'x', 'x', 'N'];
26553    const CIGAR_DECODER = ['M', 'I', 'D', 'N', 'S', 'H', 'P', '=', 'X', '?', '?', '?', '?', '?', '?', '?'];
26554    const READ_STRAND_FLAG$1 = 0x10;
26555    const MATE_STRAND_FLAG$1 = 0x20;
26556    const BAM1_MAGIC_BYTES = new Uint8Array([0x42, 0x41, 0x4d, 0x01]); // BAM\1
26557
26558    const BAM1_MAGIC_NUMBER = readInt(BAM1_MAGIC_BYTES, 0);
26559    const DEFAULT_ALLELE_FREQ_THRESHOLD = 0.2;
26560    const DEFAULT_SAMPLING_WINDOW_SIZE = 100;
26561    const DEFAULT_SAMPLING_DEPTH = 500;
26562    const MAXIMUM_SAMPLING_DEPTH = 10000;
26563    const BamUtils = {
26564      readHeader: function (url, options, genome) {
26565        return igvxhr.loadArrayBuffer(url, options).then(function (compressedBuffer) {
26566          var header, unc, uncba;
26567          unc = unbgzf(compressedBuffer);
26568          uncba = unc;
26569          header = BamUtils.decodeBamHeader(uncba, genome);
26570          return header;
26571        });
26572      },
26573
26574      /**
26575       *
26576       * @param ba  bytes to decode as a UInt8Array
26577       * @param genome  optional igv genome object
26578       * @returns {{ magicNumer: number, size: number, chrNames: Array, chrToIndex: ({}|*), chrAliasTable: ({}|*) }}
26579       */
26580      decodeBamHeader: function (ba, genome) {
26581        var magic, samHeaderLen, samHeader, chrToIndex, chrNames, chrAliasTable, alias;
26582        magic = readInt(ba, 0);
26583
26584        if (magic !== BAM1_MAGIC_NUMBER) {
26585          throw new Error('BAM header errror: bad magic number.  This could be caused by either a corrupt or missing file.');
26586        }
26587
26588        samHeaderLen = readInt(ba, 4);
26589        samHeader = '';
26590
26591        for (var i = 0; i < samHeaderLen; ++i) {
26592          samHeader += String.fromCharCode(ba[i + 8]);
26593        }
26594
26595        var nRef = readInt(ba, samHeaderLen + 8);
26596        var p = samHeaderLen + 12;
26597        chrToIndex = {};
26598        chrNames = [];
26599        chrAliasTable = {};
26600
26601        for (i = 0; i < nRef; ++i) {
26602          var lName = readInt(ba, p);
26603          var name = '';
26604
26605          for (var j = 0; j < lName - 1; ++j) {
26606            name += String.fromCharCode(ba[p + 4 + j]);
26607          }
26608
26609          readInt(ba, p + lName + 4); //dlog(name + ': ' + lRef);
26610
26611          chrToIndex[name] = i;
26612          chrNames[i] = name;
26613
26614          if (genome) {
26615            alias = genome.getChromosomeName(name);
26616            chrAliasTable[alias] = name;
26617          }
26618
26619          p = p + 8 + lName;
26620        }
26621
26622        return {
26623          magicNumber: magic,
26624          size: p,
26625          chrNames: chrNames,
26626          chrToIndex: chrToIndex,
26627          chrAliasTable: chrAliasTable
26628        };
26629      },
26630      bam_tag2cigar: function (ba, block_end, seq_offset, lseq, al, cigarArray) {
26631        function type2size(x) {
26632          if (x === 'C' || x === 'c' || x === 'A') return 1;else if (x === 'S' || x === 's') return 2;else if (x === 'I' || x === 'i' || x === 'f') return 4;else return 0;
26633        } // test if the real CIGAR is encoded in a CG:B,I tag
26634
26635
26636        if (cigarArray.length !== 1 || al.start < 0) return false;
26637        var p = seq_offset + (lseq + 1 >> 1) + lseq;
26638
26639        while (p + 4 < block_end) {
26640          var tag = String.fromCharCode(ba[p]) + String.fromCharCode(ba[p + 1]);
26641          if (tag === 'CG') break;
26642          var type = String.fromCharCode(ba[p + 2]);
26643
26644          if (type === 'B') {
26645            // the binary array type
26646            type = String.fromCharCode(ba[p + 3]);
26647            var size = type2size(type);
26648            var len = readInt(ba, p + 4);
26649            p += 8 + size * len;
26650          } else if (type === 'Z' || type === 'H') {
26651            // 0-terminated string
26652            p += 3;
26653
26654            while (ba[p++] !== 0) {}
26655          } else {
26656            // other atomic types
26657            p += 3 + type2size(type);
26658          }
26659        }
26660
26661        if (p >= block_end) return false; // no CG tag
26662
26663        if (String.fromCharCode(ba[p + 2]) !== 'B' || String.fromCharCode(ba[p + 3]) !== 'I') return false; // not of type B,I
26664        // now we know the real CIGAR length and its offset in the binary array
26665
26666        var cigar_len = readInt(ba, p + 4);
26667        var cigar_offset = p + 8; // 4 for "CGBI" and 4 for length
26668
26669        if (cigar_offset + cigar_len * 4 > block_end) return false; // out of bound
26670        // decode CIGAR
26671
26672        var cigar = '';
26673        var lengthOnRef = 0;
26674        cigarArray.length = 0; // empty the old array
26675
26676        p = cigar_offset;
26677
26678        for (var k = 0; k < cigar_len; ++k, p += 4) {
26679          var cigop = readInt(ba, p);
26680          var opLen = cigop >> 4;
26681          var opLtr = CIGAR_DECODER[cigop & 0xf];
26682          if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') lengthOnRef += opLen;
26683          cigar = cigar + opLen + opLtr;
26684          cigarArray.push({
26685            len: opLen,
26686            ltr: opLtr
26687          });
26688        } // update alignment record. We are not updating bin, as apparently it is not used.
26689
26690
26691        al.cigar = cigar;
26692        al.lengthOnRef = lengthOnRef;
26693        return true;
26694      },
26695
26696      /**
26697       *
26698       * @param ba                 bytes to decode as an UInt8Array
26699       * @param offset             offset position of ba array to start decoding
26700       * @param alignmentContainer container to receive the decoded alignments
26701       * @param min                minimum genomic position
26702       * @param max                maximum genomic position
26703       * @param chrIdx             chromosome index
26704       * @param chrNames            array of chromosome names
26705       * @param filter             a BamFilter object
26706       *
26707       * @return true if we have moved beyond the right end of the genomic range.
26708       */
26709      decodeBamRecords: function (ba, offset, alignmentContainer, chrNames, chrIdx, min, max, filter) {
26710        while (offset < ba.length) {
26711          const blockSize = readInt(ba, offset);
26712          const blockEnd = offset + blockSize + 4;
26713          const alignment = new BamAlignment();
26714          const refID = readInt(ba, offset + 4);
26715          const pos = readInt(ba, offset + 8);
26716
26717          if (blockEnd > ba.length) {
26718            return;
26719          }
26720
26721          if (refID < 0) {
26722            offset = blockEnd;
26723            continue; // unmapped read
26724          } else if (chrIdx !== undefined && (refID > chrIdx || pos > max)) {
26725            return true; // off right edge, we're done
26726          } else if (chrIdx !== undefined && refID < chrIdx) {
26727            offset = blockEnd;
26728            continue; // ref ID to left of start, not sure this is possible
26729          }
26730
26731          const bin_mq_nl = readInt(ba, offset + 12);
26732          const mq = (bin_mq_nl & 0xff00) >> 8;
26733          const nl = bin_mq_nl & 0xff;
26734          const flag_nc = readInt(ba, offset + 16);
26735          const flag = (flag_nc & 0xffff0000) >> 16;
26736          const nc = flag_nc & 0xffff;
26737          const lseq = readInt(ba, offset + 20);
26738          const mateChrIdx = readInt(ba, offset + 24);
26739          const matePos = readInt(ba, offset + 28);
26740          const tlen = readInt(ba, offset + 32);
26741          let readName = [];
26742
26743          for (let j = 0; j < nl - 1; ++j) {
26744            readName.push(String.fromCharCode(ba[offset + 36 + j]));
26745          }
26746
26747          readName = readName.join('');
26748          let lengthOnRef = 0;
26749          let cigar = '';
26750          let p = offset + 36 + nl;
26751          const cigarArray = []; // concatenate M,=,EQ,and X
26752
26753          let lastCigRecord;
26754
26755          for (let c = 0; c < nc; ++c) {
26756            var cigop = readInt(ba, p);
26757            var opLen = cigop >> 4;
26758            var opLtr = CIGAR_DECODER[cigop & 0xf];
26759            if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') lengthOnRef += opLen;
26760            cigar = cigar + opLen + opLtr;
26761            p += 4; // if(mOperators.has(opLtr) && mOperators.has(lastCigRecord.ltr)) {
26762            //     lastCigRecord.len += opLen;
26763            //     lastCigRecord.ltr = 'M'
26764            // }
26765            // else {
26766
26767            lastCigRecord = {
26768              len: opLen,
26769              ltr: opLtr
26770            };
26771            cigarArray.push(lastCigRecord); //}
26772          }
26773
26774          alignment.chr = chrNames[refID];
26775          alignment.start = pos;
26776          alignment.flags = flag;
26777          alignment.strand = !(flag & READ_STRAND_FLAG$1);
26778          alignment.readName = readName;
26779          alignment.cigar = cigar;
26780          alignment.lengthOnRef = lengthOnRef;
26781          alignment.fragmentLength = tlen;
26782          alignment.mq = mq;
26783          BamUtils.bam_tag2cigar(ba, blockEnd, p, lseq, alignment, cigarArray);
26784          alignment.end = alignment.start + alignment.lengthOnRef;
26785
26786          if (alignment.end < min) {
26787            offset = blockEnd;
26788            continue;
26789          } // Record out-of-range "to the left", skip to next one
26790
26791
26792          let seq = [];
26793          const seqBytes = lseq + 1 >> 1;
26794
26795          for (let j = 0; j < seqBytes; ++j) {
26796            var sb = ba[p + j];
26797            seq.push(SEQ_DECODER[(sb & 0xf0) >> 4]);
26798            seq.push(SEQ_DECODER[sb & 0x0f]);
26799          }
26800
26801          seq = seq.slice(0, lseq).join(''); // seq might have one extra character (if lseq is an odd number)
26802
26803          p += seqBytes;
26804          const qualArray = [];
26805
26806          for (let j = 0; j < lseq; ++j) {
26807            qualArray.push(ba[p + j]);
26808          }
26809
26810          p += lseq;
26811
26812          if (mateChrIdx >= 0) {
26813            alignment.mate = {
26814              chr: chrNames[mateChrIdx],
26815              position: matePos,
26816              strand: !(flag & MATE_STRAND_FLAG$1)
26817            };
26818          }
26819
26820          alignment.seq = seq;
26821          alignment.qual = qualArray;
26822          alignment.tagBA = new Uint8Array(ba.buffer.slice(p, blockEnd)); // decode these on demand
26823
26824          this.setPairOrientation(alignment);
26825
26826          if (undefined === filter || filter.pass(alignment)) {
26827            makeBlocks(alignment, cigarArray);
26828            alignmentContainer.push(alignment);
26829          }
26830
26831          offset = blockEnd;
26832        }
26833      },
26834      decodeSamRecords: function (sam, alignmentContainer, chr, min, max, filter) {
26835        var lines, i, j, len, tokens, qualString, rnext, lengthOnRef, alignment, cigarArray, started;
26836        lines = splitLines$5(sam);
26837        len = lines.length;
26838        started = false;
26839
26840        for (i = 0; i < len; i++) {
26841          tokens = lines[i].split('\t');
26842          alignment = new BamAlignment();
26843          alignment.chr = tokens[2];
26844          alignment.start = Number.parseInt(tokens[3]) - 1;
26845          alignment.flags = Number.parseInt(tokens[1]);
26846          alignment.readName = tokens[0];
26847          alignment.strand = !(alignment.flags & READ_STRAND_FLAG$1);
26848          alignment.mq = Number.parseInt(tokens[4]);
26849          alignment.cigar = tokens[5];
26850          alignment.fragmentLength = Number.parseInt(tokens[8]);
26851          alignment.seq = tokens[9];
26852          if (alignment.chr === '*' || !alignment.isMapped()) continue; // Unmapped
26853
26854          if (alignment.chr !== chr) {
26855            if (started) break; // Off the right edge, we're done
26856            else continue; // Possibly to the left, skip but keep looping
26857          } else if (alignment.start > max) {
26858            break; // off right edge, we're done
26859          }
26860
26861          lengthOnRef = 0;
26862          cigarArray = buildOperators(alignment.cigar);
26863          cigarArray.forEach(function (op) {
26864            var opLen = op.len;
26865            var opLtr = op.ltr;
26866            if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') lengthOnRef += opLen;
26867          });
26868          alignment.lengthOnRef = lengthOnRef; // TODO for lh3: parse the CG:B,I tag in SAM here
26869
26870          if (alignment.start + lengthOnRef < min) {
26871            continue; // To the left, skip and continue
26872          }
26873
26874          qualString = tokens[10];
26875          alignment.qual = [];
26876
26877          for (j = 0; j < qualString.length; j++) {
26878            alignment.qual[j] = qualString.charCodeAt(j) - 33;
26879          }
26880
26881          alignment.tagDict = tokens.length < 11 ? {} : decodeSamTags(tokens.slice(11));
26882
26883          if (alignment.isMateMapped()) {
26884            rnext = tokens[6];
26885            alignment.mate = {
26886              chr: rnext === '=' ? alignment.chr : rnext,
26887              position: Number.parseInt(tokens[7]),
26888              strand: !(alignment.flags & MATE_STRAND_FLAG$1)
26889            };
26890          }
26891
26892          this.setPairOrientation(alignment);
26893
26894          if (undefined === filter || filter.pass(alignment)) {
26895            makeBlocks(alignment, cigarArray);
26896            alignmentContainer.push(alignment);
26897          }
26898        }
26899      },
26900      setReaderDefaults: function (reader, config) {
26901        reader.filter = new BamFilter(config.filter);
26902
26903        if (config.readgroup) {
26904          reader.filter.readgroups = new Set([config.readgroup]);
26905        }
26906
26907        reader.alleleFreqThreshold = config.alleleFreqThreshold === undefined ? DEFAULT_ALLELE_FREQ_THRESHOLD : config.alleleFreqThreshold;
26908        reader.samplingWindowSize = config.samplingWindowSize === undefined ? DEFAULT_SAMPLING_WINDOW_SIZE : config.samplingWindowSize;
26909        reader.samplingDepth = config.samplingDepth === undefined ? DEFAULT_SAMPLING_DEPTH : config.samplingDepth;
26910
26911        if (reader.samplingDepth > MAXIMUM_SAMPLING_DEPTH) {
26912          console.log("Warning: attempt to set sampling depth > maximum value of " + MAXIMUM_SAMPLING_DEPTH);
26913          reader.samplingDepth = MAXIMUM_SAMPLING_DEPTH;
26914        }
26915
26916        if (config.viewAsPairs) {
26917          reader.pairsSupported = true;
26918        } else {
26919          reader.pairsSupported = config.pairsSupported === undefined ? true : config.pairsSupported;
26920        }
26921      },
26922      setPairOrientation: function (alignment) {
26923        if (alignment.isMapped() && alignment.mate && alignment.isMateMapped() && alignment.mate.chr === alignment.chr) {
26924          var s1 = alignment.strand ? 'F' : 'R';
26925          var mate = alignment.mate;
26926          var s2 = mate.strand ? 'F' : 'R';
26927          var o1 = ' ';
26928          var o2 = ' ';
26929
26930          if (alignment.isFirstOfPair()) {
26931            o1 = '1';
26932            o2 = '2';
26933          } else if (alignment.isSecondOfPair()) {
26934            o1 = '2';
26935            o2 = '1';
26936          }
26937
26938          var tmp = [];
26939          var isize = alignment.fragmentLength;
26940          var estReadLen = alignment.end - alignment.start;
26941
26942          if (isize === 0) {
26943            //isize not recorded.  Need to estimate.  This calculation was validated against an Illumina
26944            // -> <- library bam.
26945            var estMateEnd = alignment.start < mate.position ? mate.position + estReadLen : mate.position - estReadLen;
26946            isize = estMateEnd - alignment.start;
26947          } //if (isize > estReadLen) {
26948
26949
26950          if (isize > 0) {
26951            tmp[0] = s1;
26952            tmp[1] = o1;
26953            tmp[2] = s2;
26954            tmp[3] = o2;
26955          } else {
26956            tmp[2] = s1;
26957            tmp[3] = o1;
26958            tmp[0] = s2;
26959            tmp[1] = o2;
26960          } // }
26961
26962
26963          alignment.pairOrientation = tmp.join('');
26964        }
26965      },
26966      computeLengthOnReference: function (cigarString) {
26967        let len = 0;
26968        let buf = '';
26969
26970        for (let i = 0; i < cigarString.length; i++) {
26971          const c = cigarString.charCodeAt(i);
26972
26973          if (c > 47 && c < 58) {
26974            buf += cigarString.charAt(i);
26975          } else {
26976            switch (c) {
26977              case 78: // N
26978
26979              case 68: // D
26980
26981              case 77: // M
26982
26983              case 61: // =
26984
26985              case 88:
26986                // X
26987                len += parseInt(buf.toString());
26988            }
26989
26990            buf = '';
26991          }
26992        }
26993
26994        return len;
26995      }
26996    };
26997    /**
26998     * Split the alignment record into blocks as specified in the cigarArray.  Each aligned block contains
26999     * its portion of the read sequence and base quality strings.  A read sequence or base quality string
27000     * of "*" indicates the value is not recorded.  In all other cases the length of the block sequence (block.seq)
27001     * and quality string (block.qual) must == the block length.
27002     *
27003     * @param alignment
27004     * @param cigarArray
27005     * @returns array of blocks
27006     */
27007
27008    function makeBlocks(alignment, cigarArray) {
27009      const blocks = [];
27010      let insertions;
27011      let gaps;
27012      let seqOffset = 0;
27013      let pos = alignment.start;
27014      alignment.scStart = alignment.start;
27015      alignment.scLengthOnRef = alignment.lengthOnRef;
27016
27017      for (let c of cigarArray) {
27018        let scPos;
27019
27020        switch (c.ltr) {
27021          case 'H':
27022            break;
27023          // ignore hard clips
27024
27025          case 'P':
27026            break;
27027          // ignore pads
27028
27029          case 'S':
27030            scPos = pos;
27031            alignment.scLengthOnRef += c.len;
27032
27033            if (blocks.length === 0) {
27034              alignment.scStart -= c.len;
27035              scPos -= c.len;
27036            }
27037
27038            blocks.push(new AlignmentBlock({
27039              start: scPos,
27040              seqOffset: seqOffset,
27041              len: c.len,
27042              type: 'S'
27043            }));
27044            seqOffset += c.len;
27045            break;
27046          // soft clip read bases
27047
27048          case 'N':
27049          case 'D':
27050            if (gaps === undefined) {
27051              gaps = [];
27052            }
27053
27054            gaps.push({
27055              start: pos,
27056              len: c.len,
27057              type: c.ltr
27058            });
27059            pos += c.len;
27060            break;
27061
27062          case 'I':
27063            if (insertions === undefined) {
27064              insertions = [];
27065            }
27066
27067            insertions.push(new AlignmentBlock({
27068              start: pos,
27069              len: c.len,
27070              seqOffset: seqOffset,
27071              type: 'I'
27072            }));
27073            seqOffset += c.len;
27074            break;
27075
27076          case 'M':
27077          case 'EQ':
27078          case '=':
27079          case 'X':
27080            blocks.push(new AlignmentBlock({
27081              start: pos,
27082              seqOffset: seqOffset,
27083              len: c.len,
27084              type: 'M'
27085            }));
27086            seqOffset += c.len;
27087            pos += c.len;
27088            break;
27089
27090          default:
27091            console.log('Error processing cigar element: ' + c.len + c.ltr);
27092        }
27093      }
27094
27095      alignment.blocks = blocks;
27096      alignment.insertions = insertions;
27097      alignment.gaps = gaps;
27098    }
27099
27100    function readInt(ba, offset) {
27101      return ba[offset + 3] << 24 | ba[offset + 2] << 16 | ba[offset + 1] << 8 | ba[offset];
27102    }
27103    /**
27104     * Build a list of cigar operators from a cigarString.  Removes padding operators and concatenates consecutive
27105     * operators of the same type
27106     *
27107     * @param cigarString
27108     * @return
27109     */
27110
27111
27112    function buildOperators(cigarString) {
27113      var operators, buffer, i, len, prevOp, next, op, nBases;
27114      operators = [];
27115      buffer = []; // Create list of cigar operators
27116
27117      prevOp = null;
27118      len = cigarString.length;
27119
27120      for (i = 0; i < len; i++) {
27121        next = cigarString.charAt(i);
27122
27123        if (isDigit(next)) {
27124          buffer.push(next);
27125        } else {
27126          op = next;
27127          nBases = Number.parseInt(buffer.join(''));
27128          buffer = [];
27129
27130          if (prevOp !== null && prevOp.ltr === op) {
27131            prevOp.len += nBases;
27132          } else {
27133            prevOp = {
27134              len: nBases,
27135              ltr: op
27136            };
27137            operators.push(prevOp);
27138          }
27139        }
27140      }
27141
27142      return operators;
27143    }
27144
27145    function isDigit(a) {
27146      var charCode = a.charCodeAt(0);
27147      return charCode >= 48 && charCode <= 57; // 0-9
27148    }
27149
27150    function decodeSamTags(tags) {
27151      var tagDict = {};
27152      tags.forEach(function (tag) {
27153        var tokens = tag.split(':');
27154        tagDict[tokens[0]] = tokens[2];
27155      });
27156      return tagDict;
27157    }
27158
27159    /**
27160     * Class for reading a bam file
27161     *
27162     * @param config
27163     * @constructor
27164     */
27165
27166    class BamReaderNonIndexed {
27167      constructor(config, genome) {
27168        this.config = config;
27169        this.genome = genome;
27170        this.bamPath = config.url;
27171        this.isDataUri = isDataURL(config.url);
27172        BamUtils.setReaderDefaults(this, config);
27173      } // Return an alignment container
27174
27175
27176      async readAlignments(chr, bpStart, bpEnd) {
27177        if (this.alignmentCache) {
27178          const header = this.header;
27179          const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr;
27180          const qAlignments = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd);
27181          const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.samplingWindowSize, this.samplingDepth, this.pairsSupported, this.alleleFreqThreshold);
27182
27183          for (let a of qAlignments) {
27184            alignmentContainer.push(a);
27185          }
27186
27187          alignmentContainer.finish();
27188          return alignmentContainer;
27189        } else {
27190          if (this.isDataUri) {
27191            const data = decodeDataURI(this.bamPath);
27192            const unc = unbgzf(data.buffer);
27193            this.parseAlignments(unc);
27194            return this.fetchAlignments(chr, bpStart, bpEnd);
27195          } else {
27196            const arrayBuffer = await igvxhr.loadArrayBuffer(this.bamPath, buildOptions(this.config));
27197            const unc = unbgzf(arrayBuffer);
27198            this.parseAlignments(unc);
27199            return this.fetchAlignments(chr, bpStart, bpEnd);
27200          }
27201        }
27202      }
27203
27204      parseAlignments(data) {
27205        const alignments = [];
27206        this.header = BamUtils.decodeBamHeader(data);
27207        BamUtils.decodeBamRecords(data, this.header.size, alignments, this.header.chrNames);
27208        this.alignmentCache = new FeatureCache(alignments, this.genome);
27209      }
27210
27211      fetchAlignments(chr, bpStart, bpEnd) {
27212        const queryChr = this.header.chrAliasTable.hasOwnProperty(chr) ? this.header.chrAliasTable[chr] : chr;
27213        const features = this.alignmentCache.queryFeatures(queryChr, bpStart, bpEnd);
27214        const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.samplingWindowSize, this.samplingDepth, this.pairsSupported);
27215
27216        for (let feature of features) {
27217          alignmentContainer.push(feature);
27218        }
27219
27220        alignmentContainer.finish();
27221        return alignmentContainer;
27222      }
27223
27224    }
27225
27226    function decodeDataURI(dataURI) {
27227      const split = dataURI.split(',');
27228      const info = split[0].split(':')[1];
27229      let dataString = split[1];
27230
27231      if (info.indexOf('base64') >= 0) {
27232        dataString = atob(dataString);
27233      } else {
27234        dataString = decodeURI(dataString);
27235      }
27236
27237      const bytes = new Uint8Array(dataString.length);
27238
27239      for (var i = 0; i < dataString.length; i++) {
27240        bytes[i] = dataString.charCodeAt(i);
27241      }
27242
27243      return bytes;
27244    }
27245
27246    /*
27247     * The MIT License (MIT)
27248     *
27249     * Copyright (c) 2014 Broad Institute
27250     *
27251     * Permission is hereby granted, free of charge, to any person obtaining a copy
27252     * of this software and associated documentation files (the "Software"), to deal
27253     * in the Software without restriction, including without limitation the rights
27254     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27255     * copies of the Software, and to permit persons to whom the Software is
27256     * furnished to do so, subject to the following conditions:
27257     *
27258     * The above copyright notice and this permission notice shall be included in
27259     * all copies or substantial portions of the Software.
27260     *
27261     *
27262     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27263     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27264     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27265     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27266     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27267     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27268     * THE SOFTWARE.
27269     */
27270    // TODO -- big endian?
27271    class BinaryParser {
27272      constructor(dataView, littleEndian) {
27273        this.littleEndian = littleEndian !== undefined ? littleEndian : true;
27274        this.position = 0;
27275        this.view = dataView;
27276        this.length = dataView.byteLength;
27277      }
27278
27279      available() {
27280        return this.length - this.position;
27281      }
27282
27283      remLength() {
27284        return this.length - this.position;
27285      }
27286
27287      hasNext() {
27288        return this.position < this.length - 1;
27289      }
27290
27291      getByte() {
27292        var retValue = this.view.getUint8(this.position, this.littleEndian);
27293        this.position++;
27294        return retValue;
27295      }
27296
27297      getShort() {
27298        var retValue = this.view.getInt16(this.position, this.littleEndian);
27299        this.position += 2;
27300        return retValue;
27301      }
27302
27303      getUShort() {
27304        // var byte1 = this.getByte(),
27305        //     byte2 = this.getByte(),
27306        //     retValue = ((byte2 << 24 >>> 16) + (byte1 << 24 >>> 24));
27307        //     return retValue;
27308        //
27309        var retValue = this.view.getUint16(this.position, this.littleEndian);
27310        this.position += 2;
27311        return retValue;
27312      }
27313
27314      getInt() {
27315        var retValue = this.view.getInt32(this.position, this.littleEndian);
27316        this.position += 4;
27317        return retValue;
27318      }
27319
27320      getUInt() {
27321        var retValue = this.view.getUint32(this.position, this.littleEndian);
27322        this.position += 4;
27323        return retValue;
27324      }
27325
27326      getLong() {
27327        // DataView doesn't support long. So we'll try manually
27328        var b = [];
27329        b[0] = this.view.getUint8(this.position);
27330        b[1] = this.view.getUint8(this.position + 1);
27331        b[2] = this.view.getUint8(this.position + 2);
27332        b[3] = this.view.getUint8(this.position + 3);
27333        b[4] = this.view.getUint8(this.position + 4);
27334        b[5] = this.view.getUint8(this.position + 5);
27335        b[6] = this.view.getUint8(this.position + 6);
27336        b[7] = this.view.getUint8(this.position + 7);
27337        var value = 0;
27338
27339        if (this.littleEndian) {
27340          for (let i = b.length - 1; i >= 0; i--) {
27341            value = value * 256 + b[i];
27342          }
27343        } else {
27344          for (let i = 0; i < b.length; i++) {
27345            value = value * 256 + b[i];
27346          }
27347        }
27348
27349        this.position += 8;
27350        return value;
27351      }
27352
27353      getString(len) {
27354        var s = "";
27355        var c;
27356
27357        while ((c = this.view.getUint8(this.position++)) !== 0) {
27358          s += String.fromCharCode(c);
27359          if (len && s.length === len) break;
27360        }
27361
27362        return s;
27363      }
27364
27365      getFixedLengthString(len) {
27366        var s = "";
27367        var i;
27368        var c;
27369
27370        for (i = 0; i < len; i++) {
27371          c = this.view.getUint8(this.position++);
27372
27373          if (c > 0) {
27374            s += String.fromCharCode(c);
27375          }
27376        }
27377
27378        return s;
27379      }
27380
27381      getFixedLengthTrimmedString(len) {
27382        var s = "";
27383        var i;
27384        var c;
27385
27386        for (i = 0; i < len; i++) {
27387          c = this.view.getUint8(this.position++);
27388
27389          if (c > 32) {
27390            s += String.fromCharCode(c);
27391          }
27392        }
27393
27394        return s;
27395      }
27396
27397      getFloat() {
27398        var retValue = this.view.getFloat32(this.position, this.littleEndian);
27399        this.position += 4;
27400        return retValue;
27401      }
27402
27403      getDouble() {
27404        var retValue = this.view.getFloat64(this.position, this.littleEndian);
27405        this.position += 8;
27406        return retValue;
27407      }
27408
27409      skip(n) {
27410        this.position += n;
27411        return this.position;
27412      }
27413      /**
27414       * Return a BGZip (bam and tabix) virtual pointer
27415       * TODO -- why isn't 8th byte used ?
27416       * @returns {*}
27417       */
27418
27419
27420      getVPointer() {
27421        var position = this.position,
27422            offset = this.view.getUint8(position + 1) << 8 | this.view.getUint8(position),
27423            byte6 = (this.view.getUint8(position + 6) & 0xff) * 0x100000000,
27424            byte5 = (this.view.getUint8(position + 5) & 0xff) * 0x1000000,
27425            byte4 = (this.view.getUint8(position + 4) & 0xff) * 0x10000,
27426            byte3 = (this.view.getUint8(position + 3) & 0xff) * 0x100,
27427            byte2 = this.view.getUint8(position + 2) & 0xff,
27428            block = byte6 + byte5 + byte4 + byte3 + byte2;
27429        this.position += 8; //       if (block == 0 && offset == 0) {
27430        //           return null;
27431        //       } else {
27432
27433        return new VPointer(block, offset); //       }
27434      }
27435
27436    }
27437
27438    class VPointer {
27439      constructor(block, offset) {
27440        this.block = block;
27441        this.offset = offset;
27442      }
27443
27444      isLessThan(vp) {
27445        return this.block < vp.block || this.block === vp.block && this.offset < vp.offset;
27446      }
27447
27448      isGreaterThan(vp) {
27449        return this.block > vp.block || this.block === vp.block && this.offset > vp.offset;
27450      }
27451
27452      print() {
27453        return "" + this.block + ":" + this.offset;
27454      }
27455
27456    }
27457
27458    // Represents a BAM index.
27459    const CSI1_MAGIC$1 = 21582659; // CSI\1
27460
27461    const CSI2_MAGIC$1 = 38359875; // CSI\2
27462
27463    async function parseCsiIndex(arrayBuffer, genome) {
27464      const idx = new CSIIndex();
27465      idx.parse(arrayBuffer, genome);
27466      return idx;
27467    }
27468
27469    class CSIIndex {
27470      constructor(tabix) {
27471        this.tabix = true; // Means whatever is indexed is BGZipped
27472      }
27473
27474      parse(arrayBuffer, genome) {
27475        const parser = new BinaryParser(new DataView(arrayBuffer));
27476        const magic = parser.getInt();
27477
27478        if (magic !== CSI1_MAGIC$1) {
27479          if (magic === CSI2_MAGIC$1) {
27480            throw Error("CSI version 2 is not supported.  Please enter an issue at https://github.com/igvteam/igv.js");
27481          } else {
27482            throw Error("Not a CSI index");
27483          }
27484        }
27485
27486        this.indices = [];
27487        this.blockMin = Number.MAX_SAFE_INTEGER;
27488        this.lastBlockPosition = [];
27489        this.sequenceIndexMap = {};
27490        this.minShift = parser.getInt();
27491        this.depth = parser.getInt();
27492        const lAux = parser.getInt();
27493        const seqNames = [];
27494        let bmax = 0;
27495
27496        if (lAux >= 28) {
27497          // Tabix header parameters aren't used, but they must be read to advance the pointer
27498          parser.getInt();
27499          parser.getInt();
27500          parser.getInt();
27501          parser.getInt();
27502          parser.getInt();
27503          parser.getInt();
27504          const l_nm = parser.getInt();
27505          const nameEndPos = parser.position + l_nm;
27506          let i = 0;
27507
27508          while (parser.position < nameEndPos) {
27509            let seq_name = parser.getString(); // Translate to "official" chr name.
27510
27511            if (genome) {
27512              seq_name = genome.getChromosomeName(seq_name);
27513            }
27514
27515            this.sequenceIndexMap[seq_name] = i;
27516            seqNames[i] = seq_name;
27517            i++;
27518          }
27519        }
27520
27521        const MAX_BIN = this.bin_limit() + 1;
27522        const nref = parser.getInt();
27523
27524        for (let ref = 0; ref < nref; ref++) {
27525          const binIndex = [];
27526          const loffset = [];
27527          const nbin = parser.getInt();
27528
27529          for (let b = 0; b < nbin; b++) {
27530            const binNumber = parser.getInt();
27531            loffset[binNumber] = parser.getVPointer();
27532
27533            if (binNumber > MAX_BIN) {
27534              // This is a psuedo bin, not used but we have to consume the bytes
27535              parser.getInt(); // # of chunks for this bin
27536
27537              parser.getVPointer(); // unmapped beg
27538
27539              parser.getVPointer(); // unmapped end
27540
27541              parser.getLong();
27542              parser.getLong();
27543            } else {
27544              binIndex[binNumber] = [];
27545              const nchnk = parser.getInt(); // # of chunks for this bin
27546
27547              for (let i = 0; i < nchnk; i++) {
27548                const cs = parser.getVPointer(); //chunk_beg
27549
27550                const ce = parser.getVPointer(); //chunk_end
27551
27552                if (cs && ce) {
27553                  if (cs.block < this.blockMin) {
27554                    this.blockMin = cs.block; // Block containing first alignment
27555                  }
27556
27557                  if (ce.block > bmax) {
27558                    bmax = ce.block;
27559                  }
27560
27561                  binIndex[binNumber].push([cs, ce]);
27562                }
27563              }
27564            }
27565          }
27566
27567          if (nbin > 0) {
27568            this.indices[ref] = {
27569              binIndex: binIndex,
27570              loffset: loffset
27571            };
27572          }
27573        }
27574
27575        this.lastBlockPosition = bmax;
27576      }
27577
27578      get chromosomeNames() {
27579        return Object.keys(this.sequenceIndexMap);
27580      }
27581      /**
27582       * Fetch blocks for a particular genomic range.  This method is public so it can be unit-tested.
27583       *
27584       * @param refId  the sequence dictionary index of the chromosome
27585       * @param min  genomic start position
27586       * @param max  genomic end position
27587       * @param return an array of {minv: {filePointer, offset}, {maxv: {filePointer, offset}}
27588       */
27589
27590
27591      blocksForRange(refId, min, max) {
27592        const ba = this.indices[refId];
27593
27594        if (!ba) {
27595          return [];
27596        } else {
27597          const overlappingBins = this.reg2bins(min, max); // List of bin #s that overlap min, max
27598
27599          if (overlappingBins.length == 0) return [];
27600          const chunks = []; // Find chunks in overlapping bins.  Leaf bins (< 4681) are not pruned
27601
27602          for (let binRange of overlappingBins) {
27603            for (let bin = binRange[0]; bin <= binRange[1]; bin++) {
27604              if (ba.binIndex[bin]) {
27605                const binChunks = ba.binIndex[bin];
27606                const nchnk = binChunks.length;
27607
27608                for (let c = 0; c < nchnk; ++c) {
27609                  const cs = binChunks[c][0];
27610                  const ce = binChunks[c][1];
27611                  chunks.push({
27612                    minv: cs,
27613                    maxv: ce,
27614                    bin: bin
27615                  });
27616                }
27617              }
27618            }
27619          }
27620
27621          const lowestOffset = ba.loffset[overlappingBins[0]];
27622          return optimizeChunks$1(chunks, lowestOffset);
27623        }
27624      } // reg2bins implementation adapted from GMOD/tabix-js  https://github.com/GMOD/tabix-js/blob/master/src/csi.ts
27625
27626
27627      reg2bins(beg, end) {
27628        beg -= 1; // < convert to 1-based closed
27629
27630        if (beg < 1) beg = 1;
27631        if (end > 2 ** 50) end = 2 ** 34; // 17 GiB ought to be enough for anybody
27632
27633        end -= 1;
27634        let l = 0;
27635        let t = 0;
27636        let s = this.minShift + this.depth * 3;
27637        const bins = [];
27638
27639        for (; l <= this.depth; s -= 3, t += 1 << l * 3, l += 1) {
27640          const b = t + (beg >> s);
27641          const e = t + (end >> s);
27642          if (e - b + bins.length > this.maxBinNumber) throw new Error(`query ${beg}-${end} is too large for current binning scheme (shift ${this.minShift}, depth ${this.depth}), try a smaller query or a coarser index binning scheme`); //for (let i = b; i <= e; i += 1) bins.push(i)
27643
27644          bins.push([b, e]);
27645        }
27646
27647        return bins;
27648      } // function reg2bins(beg, end, min_shift, depth) {
27649      //     let l, t, n, s = min_shift + depth * 3;
27650      //     const bins = [];
27651      //     for (--end, l = n = t = 0; l <= depth; s -= 3, t += 1 << l * 3, ++l) {
27652      //         let b = t + (beg >> s), e = t + (end >> s), i;
27653      //         for (i = b; i <= e; ++i) bins[n++] = i;
27654      //     }
27655      //     return bins;
27656      // }
27657
27658
27659      bin_limit() {
27660        return ((1 << (this.depth + 1) * 3) - 1) / 7;
27661      }
27662
27663    }
27664
27665    function optimizeChunks$1(chunks, lowest) {
27666      const mergedChunks = [];
27667      let lastChunk = null;
27668      if (chunks.length === 0) return chunks;
27669      chunks.sort(function (c0, c1) {
27670        const dif = c0.minv.block - c1.minv.block;
27671
27672        if (dif !== 0) {
27673          return dif;
27674        } else {
27675          return c0.minv.offset - c1.minv.offset;
27676        }
27677      });
27678      chunks.forEach(function (chunk) {
27679        if (!lowest || chunk.maxv.isGreaterThan(lowest)) {
27680          if (lastChunk === null) {
27681            mergedChunks.push(chunk);
27682            lastChunk = chunk;
27683          } else {
27684            if (canMerge$1(lastChunk, chunk)) {
27685              if (chunk.maxv.isGreaterThan(lastChunk.maxv)) {
27686                lastChunk.maxv = chunk.maxv;
27687              }
27688            } else {
27689              mergedChunks.push(chunk);
27690              lastChunk = chunk;
27691            }
27692          }
27693        }
27694      });
27695      return mergedChunks;
27696    }
27697
27698    function canMerge$1(chunk1, chunk2) {
27699      return chunk2.minv.block - chunk1.maxv.block < 65000 && chunk2.maxv.block - chunk1.minv.block < 5000000; // lastChunk.minv.block === lastChunk.maxv.block &&
27700      // lastChunk.maxv.block === chunk.minv.block &&
27701      // chunk.minv.block === chunk.maxv.block
27702    }
27703
27704    // Represents a BAM index.
27705    const BAI_MAGIC$1 = 21578050;
27706    const TABIX_MAGIC$1 = 21578324;
27707    const MB = 1000000;
27708
27709    async function parseBamIndex(arrayBuffer, genome) {
27710      const index = new BamIndex();
27711      await index.parse(arrayBuffer, false, genome);
27712      return index;
27713    }
27714
27715    async function parseTabixIndex(arrayBuffer, genome) {
27716      const index = new BamIndex();
27717      await index.parse(arrayBuffer, true, genome);
27718      return index;
27719    }
27720
27721    class BamIndex {
27722      constructor() {}
27723
27724      async parse(arrayBuffer, tabix, genome) {
27725        const indices = [];
27726        let blockMin = Number.MAX_SAFE_INTEGER;
27727        let blockMax = 0;
27728        const seqNames = [];
27729        const parser = new BinaryParser(new DataView(arrayBuffer));
27730        const magic = parser.getInt();
27731        const sequenceIndexMap = {};
27732
27733        if (magic === BAI_MAGIC$1 || tabix && magic === TABIX_MAGIC$1) {
27734          const nref = parser.getInt();
27735
27736          if (tabix) {
27737            // Tabix header parameters aren't used, but they must be read to advance the pointer
27738            parser.getInt();
27739            parser.getInt();
27740            parser.getInt();
27741            parser.getInt();
27742            parser.getInt();
27743            parser.getInt();
27744            parser.getInt();
27745
27746            for (let i = 0; i < nref; i++) {
27747              let seq_name = parser.getString(); // Translate to "official" chr name.
27748
27749              if (genome) {
27750                seq_name = genome.getChromosomeName(seq_name);
27751              }
27752
27753              sequenceIndexMap[seq_name] = i;
27754              seqNames[i] = seq_name;
27755            }
27756          }
27756 // Loop through sequences
27757
27758
27759          for (let ref = 0; ref < nref; ref++) {
27760            const binIndex = {};
27761            const linearIndex = [];
27762            const nbin = parser.getInt();
27763
27764            for (let b = 0; b < nbin; b++) {
27765              const binNumber = parser.getInt();
27766
27767              if (binNumber === 37450) {
27768                // This is a psuedo bin, not used but we have to consume the bytes
27769                parser.getInt(); // # of chunks for this bin
27770
27771                parser.getVPointer(); // unmapped beg
27772
27773                parser.getVPointer(); // unmapped end
27774
27775                parser.getLong();
27776                parser.getLong();
27777              } else {
27778                binIndex[binNumber] = [];
27779                const nchnk = parser.getInt(); // # of chunks for this bin
27780
27781                for (let i = 0; i < nchnk; i++) {
27782                  const cs = parser.getVPointer(); //chunk_beg
27783
27784                  const ce = parser.getVPointer(); //chunk_end
27785
27786                  if (cs && ce) {
27787                    if (cs.block < blockMin) {
27788                      blockMin = cs.block; // Block containing first alignment
27789                    }
27790
27791                    if (ce.block > blockMax) {
27792                      blockMax = ce.block;
27793                    }
27794
27795                    binIndex[binNumber].push([cs, ce]);
27796                  }
27797                }
27798              }
27799            }
27800
27801            const nintv = parser.getInt();
27802
27803            for (let i = 0; i < nintv; i++) {
27804              const cs = parser.getVPointer();
27805              linearIndex.push(cs); // Might be null
27806            }
27807
27808            if (nbin > 0) {
27809              indices[ref] = {
27810                binIndex: binIndex,
27811                linearIndex: linearIndex
27812              };
27813            }
27814          }
27815
27816          this.firstBlockPosition = blockMin;
27817          this.lastBlockPosition = blockMax;
27818          this.indices = indices;
27819          this.sequenceIndexMap = sequenceIndexMap;
27820          this.tabix = tabix;
27821        } else {
27822          throw new Error(indexURL + " is not a " + (tabix ? "tabix" : "bai") + " file");
27823        }
27824      }
27825
27826      get chromosomeNames() {
27827        return Object.keys(this.sequenceIndexMap);
27828      }
27829      /**
27830       * Fetch blocks for a particular genomic range.  This method is public so it can be unit-tested.
27831       *
27832       * @param refId  the sequence dictionary index of the chromosome
27833       * @param min  genomic start position
27834       * @param max  genomic end position
27835       * @param return an array of {minv: {filePointer, offset}, {maxv: {filePointer, offset}}
27836       */
27837
27838
27839      blocksForRange(refId, min, max) {
27840        const bam = this;
27841        const ba = bam.indices[refId];
27842
27843        if (!ba) {
27844          return [];
27845        } else {
27846          const overlappingBins = reg2bins(min, max); // List of bin #s that overlap min, max
27847
27848          const chunks = []; // Find chunks in overlapping bins.  Leaf bins (< 4681) are not pruned
27849
27850          for (let binRange of overlappingBins) {
27851            for (let bin = binRange[0]; bin <= binRange[1]; bin++) {
27852              if (ba.binIndex[bin]) {
27853                const binChunks = ba.binIndex[bin],
27854                      nchnk = binChunks.length;
27855
27856                for (let c = 0; c < nchnk; ++c) {
27857                  const cs = binChunks[c][0];
27858                  const ce = binChunks[c][1];
27859                  chunks.push({
27860                    minv: cs,
27861                    maxv: ce,
27862                    bin: bin
27863                  });
27864                }
27865              }
27866            }
27867          } // Use the linear index to find minimum file position of chunks that could contain alignments in the region
27868
27869
27870          const nintv = ba.linearIndex.length;
27871          let lowest = null;
27872          const minLin = Math.min(min >> 14, nintv - 1);
27873          const maxLin = Math.min(max >> 14, nintv - 1);
27874
27875          for (let i = minLin; i <= maxLin; ++i) {
27876            const vp = ba.linearIndex[i];
27877
27878            if (vp) {
27879              // todo -- I think, but am not sure, that the values in the linear index have to be in increasing order.  So the first non-null should be minimum
27880              if (!lowest || vp.isLessThan(lowest)) {
27881                lowest = vp;
27882              }
27883            }
27884          }
27885
27886          return optimizeChunks(chunks, lowest);
27887        }
27888      }
27889
27890    }
27891
27892    function optimizeChunks(chunks, lowest) {
27893      const mergedChunks = [];
27894      let lastChunk = null;
27895      if (chunks.length === 0) return chunks;
27896      chunks.sort(function (c0, c1) {
27897        const dif = c0.minv.block - c1.minv.block;
27898
27899        if (dif !== 0) {
27900          return dif;
27901        } else {
27902          return c0.minv.offset - c1.minv.offset;
27903        }
27904      });
27905      chunks.forEach(function (chunk) {
27906        if (!lowest || chunk.maxv.isGreaterThan(lowest)) {
27907          if (lastChunk === null) {
27908            mergedChunks.push(chunk);
27909            lastChunk = chunk;
27910          } else {
27911            if (canMerge(lastChunk, chunk)) {
27912              if (chunk.maxv.isGreaterThan(lastChunk.maxv)) {
27913                lastChunk.maxv = chunk.maxv;
27914              }
27915            } else {
27916              mergedChunks.push(chunk);
27917              lastChunk = chunk;
27918            }
27919          }
27920        }
27921      });
27922      return mergedChunks;
27923    }
27924    /**
27925     * Merge 2 blocks if the gap between them is < 1kb and the total resulting size < 100mb
27926     * @param chunk1
27927     * @param chunk2
27928     * @returns {boolean|boolean}
27929     */
27930
27931
27932    function canMerge(chunk1, chunk2) {
27933      const gap = chunk2.minv.block - chunk1.maxv.block;
27934      const total = chunk2.maxv.block - chunk1.minv.block;
27935      return gap < 30000 && total < 10 * MB;
27936    }
27937    /**
27938     * Calculate the list of bins that overlap with region [beg, end]
27939     *
27940     */
27941
27942
27943    function reg2bins(beg, end) {
27944      const list = [];
27945      if (end >= 1 << 29) end = 1 << 29;
27946      --end;
27947      list.push([0, 0]);
27948      list.push([1 + (beg >> 26), 1 + (end >> 26)]);
27949      list.push([9 + (beg >> 23), 9 + (end >> 23)]);
27950      list.push([73 + (beg >> 20), 73 + (end >> 20)]);
27951      list.push([585 + (beg >> 17), 585 + (end >> 17)]);
27952      list.push([4681 + (beg >> 14), 4681 + (end >> 14)]); // for (k = 1 + (beg >> 26); k <= 1 + (end >> 26); ++k) list.push(k);
27953      // for (k = 9 + (beg >> 23); k <= 9 + (end >> 23); ++k) list.push(k);
27954      // for (k = 73 + (beg >> 20); k <= 73 + (end >> 20); ++k) list.push(k);
27955      // for (k = 585 + (beg >> 17); k <= 585 + (end >> 17); ++k) list.push(k);
27956      // for (k = 4681 + (beg >> 14); k <= 4681 + (end >> 14); ++k) list.push(k);
27957
27958      return list;
27959    }
27960
27961    /*
27962     * The MIT License (MIT)
27963     *
27964     * Copyright (c) 2014 Broad Institute
27965     *
27966     * Permission is hereby granted, free of charge, to any person obtaining a copy
27967     * of this software and associated documentation files (the "Software"), to deal
27968     * in the Software without restriction, including without limitation the rights
27969     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27970     * copies of the Software, and to permit persons to whom the Software is
27971     * furnished to do so, subject to the following conditions:
27972     *
27973     * The above copyright notice and this permission notice shall be included in
27974     * all copies or substantial portions of the Software.
27975     *
27976     *
27977     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27978     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27979     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27980     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27981     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27982     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27983     * THE SOFTWARE.
27984     */
27985
27986    async function parseTribbleIndex(arrayBuffer, genome) {
27987      const index = new TribbleIndex();
27988      index.parse(arrayBuffer, genome);
27989      return index;
27990    }
27991
27992    class TribbleIndex {
27993      constructor() {}
27994
27995      async parse(arrayBuffer, genome) {
27996        let blockMax = 0;
27997        this.chrIndex = {};
27998        this.lastBlockPosition = [];
27999        const parser = new BinaryParser(new DataView(arrayBuffer));
28000        readHeader(parser);
28001        let nChrs = parser.getInt();
28002
28003        while (nChrs-- > 0) {
28004          // todo -- support interval tree index, we're assuming its a linear index
28005          let chr = parser.getString();
28006          if (genome) chr = genome.getChromosomeName(chr); // Translate to canonical name
28007
28008          const binWidth = parser.getInt();
28009          const nBins = parser.getInt();
28010          const longestFeature = parser.getInt();
28011          parser.getInt() > 0;
28012          parser.getInt(); // note the code below accounts for > 60% of the total time to read an index
28013
28014          let pos = parser.getLong();
28015          const blocks = [];
28016
28017          for (let binNumber = 0; binNumber < nBins; binNumber++) {
28018            const nextPos = parser.getLong();
28019            blocks.push({
28020              min: pos,
28021              max: nextPos
28022            }); //        {position: pos, size: size});
28023
28024            pos = nextPos;
28025
28026            if (nextPos > blockMax) {
28027              blockMax = nextPos;
28028            }
28029          }
28030
28031          this.chrIndex[chr] = {
28032            chr: chr,
28033            blocks: blocks,
28034            longestFeature: longestFeature,
28035            binWidth: binWidth
28036          };
28037        }
28038
28039        this.lastBlockPosition = blockMax;
28040        /**
28041         * Read the header .   Data here is not used in igv.js but we need to read it to advance the pointer.
28042         * @param parser
28043         */
28044
28045        function readHeader(parser) {
28046          parser.getInt(); //   view._getInt32(offset += 32, true);
28047
28048          parser.getInt();
28049          const version = parser.getInt();
28050          parser.getString();
28051          parser.getLong();
28052          parser.getLong();
28053          parser.getString();
28054          parser.getInt();
28055
28056          if (version >= 3) {
28057            let nProperties = parser.getInt();
28058
28059            while (nProperties-- > 0) {
28060              parser.getString();
28061              parser.getString();
28062            }
28063          }
28064        }
28065      }
28066
28067      get chromosomeNames() {
28068        return Object.keys(this.chrIndex);
28069      }
28070      /**
28071       * Fetch blocks for a particular genomic range.
28072       *
28073       * @param queryChr the sequence dictionary index of the chromosome
28074       * @param min  genomic start position
28075       * @param max  genomic end position
28076       */
28077
28078
28079      blocksForRange(queryChr, min, max) {
28080        const chrIdx = this.chrIndex[queryChr];
28081
28082        if (chrIdx) {
28083          const blocks = chrIdx.blocks;
28084          const longestFeature = chrIdx.longestFeature;
28085          const binWidth = chrIdx.binWidth;
28086          const adjustedPosition = Math.max(min - longestFeature, 0);
28087          const startBinNumber = Math.floor(adjustedPosition / binWidth);
28088          if (startBinNumber >= blocks.length) // are we off the end of the bin list, so return nothing
28089            return [];else {
28090            const endBinNumber = Math.min(Math.floor((max - 1) / binWidth), blocks.length - 1); // By definition blocks are adjacent in the file for the liner index.  Combine them into one merged block
28091
28092            const startPos = blocks[startBinNumber].min;
28093            const endPos = blocks[endBinNumber].max;
28094            const size = endPos - startPos;
28095
28096            if (size === 0) {
28097              return [];
28098            } else {
28099              const mergedBlock = {
28100                minv: {
28101                  block: startPos,
28102                  offset: 0
28103                },
28104                maxv: {
28105                  block: endPos,
28106                  offset: 0
28107                }
28108              };
28109              return [mergedBlock];
28110            }
28111          }
28112        } else {
28113          return undefined;
28114        }
28115      }
28116
28117    }
28118
28119    const CSI1_MAGIC = 21582659; // CSI\1
28120
28121    const CSI2_MAGIC = 38359875; // CSI\2
28122
28123    const BAI_MAGIC = 21578050;
28124    const TABIX_MAGIC = 21578324;
28125    const TRIBBLE_MAGIC = 1480870228; //  byte[]{'T', 'I', 'D', 'X'};
28126
28127    /**
28128     * @param indexURL
28129     * @param config
28130     * @param tabix
28131     *
28132     */
28133
28134    async function loadIndex(indexURL, config, genome) {
28135      let arrayBuffer = await igvxhr.loadArrayBuffer(indexURL, buildOptions(config));
28136      let dv = new DataView(arrayBuffer); // Some indexs are bgzipped, specifically tabix, and csi.  Bam (bai) are not.  Tribble is usually not.
28137      // Check first 2 bytes of file for gzip magic number, and inflate if neccessary
28138
28139      if (dv.getUint8(0) === 0x1f && dv.getUint8(1) === 0x8b) {
28140        // gzipped
28141        const inflate = unbgzf(arrayBuffer);
28142        arrayBuffer = inflate.buffer;
28143        dv = new DataView(arrayBuffer);
28144      }
28145
28146      const magic = dv.getInt32(0, true);
28147
28148      switch (magic) {
28149        case BAI_MAGIC:
28150          return parseBamIndex(arrayBuffer, genome);
28151
28152        case TABIX_MAGIC:
28153          return parseTabixIndex(arrayBuffer, genome);
28154
28155        case CSI1_MAGIC:
28156          return parseCsiIndex(arrayBuffer, genome);
28157
28158        case TRIBBLE_MAGIC:
28159          return parseTribbleIndex(arrayBuffer, genome);
28160
28161        case CSI2_MAGIC:
28162          throw Error("CSI version 2 is not supported.");
28163
28164        default:
28165          throw Error(`Unrecognized index type: ${indexURL}`);
28166      }
28167    }
28168
28169    /*
28170     * The MIT License (MIT)
28171     *
28172     * Copyright (c) 2016-2017 The Regents of the University of California
28173     * Author: Jim Robinson
28174     *
28175     * Permission is hereby granted, free of charge, to any person obtaining a copy
28176     * of this software and associated documentation files (the "Software"), to deal
28177     * in the Software without restriction, including without limitation the rights
28178     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28179     * copies of the Software, and to permit persons to whom the Software is
28180     * furnished to do so, subject to the following conditions:
28181     *
28182     * The above copyright notice and this permission notice shall be included in
28183     * all copies or substantial portions of the Software.
28184     *
28185     *
28186     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28187     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28188     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28189     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28190     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28191     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28192     * THE SOFTWARE.
28193     */
28194    /**
28195     * Class for reading a bam file
28196     *
28197     * @param config
28198     * @constructor
28199     */
28200
28201    class BamReader {
28202      constructor(config, genome) {
28203        this.config = config;
28204        this.genome = genome;
28205        this.bamPath = config.url;
28206        this.baiPath = config.indexURL;
28207        BamUtils.setReaderDefaults(this, config);
28208      }
28209
28210      async readAlignments(chr, bpStart, bpEnd) {
28211        const chrToIndex = await this.getChrIndex();
28212        const queryChr = this.chrAliasTable.hasOwnProperty(chr) ? this.chrAliasTable[chr] : chr;
28213        const chrId = chrToIndex[queryChr];
28214        const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.config.samplingWindowSize, this.config.samplingDepth, this.config.pairsSupported, this.config.alleleFreqThreshold);
28215
28216        if (chrId === undefined) {
28217          return alignmentContainer;
28218        } else {
28219          const bamIndex = await this.getIndex();
28220          const chunks = bamIndex.blocksForRange(chrId, bpStart, bpEnd);
28221
28222          if (!chunks || chunks.length === 0) {
28223            return alignmentContainer;
28224          }
28225
28226          for (let c of chunks) {
28227            let lastBlockSize;
28228
28229            if (c.maxv.offset === 0) {
28230              lastBlockSize = 0; // Don't need to read the last block.
28231            } else {
28232              const bsizeOptions = buildOptions(this.config, {
28233                range: {
28234                  start: c.maxv.block,
28235                  size: 26
28236                }
28237              });
28238              const abuffer = await igvxhr.loadArrayBuffer(this.bamPath, bsizeOptions);
28239              lastBlockSize = bgzBlockSize(abuffer);
28240            }
28241
28242            const fetchMin = c.minv.block;
28243            const fet
28243chMax = c.maxv.block + lastBlockSize;
28244            const range = {
28245              start: fetchMin,
28246              size: fetchMax - fetchMin + 1
28247            };
28248            const compressed = await igvxhr.loadArrayBuffer(this.bamPath, buildOptions(this.config, {
28249              range: range
28250            }));
28251            var ba = unbgzf(compressed); //new Uint8Array(BGZip.unbgzf(compressed)); //, c.maxv.block - c.minv.block + 1));
28252
28253            const done = BamUtils.decodeBamRecords(ba, c.minv.offset, alignmentContainer, this.indexToChr, chrId, bpStart, bpEnd, this.filter);
28254
28255            if (done) {
28256              //    console.log(`Loaded ${counter} chunks out of  ${chunks.length}`);
28257              break;
28258            }
28259          }
28260
28261          alignmentContainer.finish();
28262          return alignmentContainer;
28263        }
28264      }
28265
28266      async getHeader() {
28267        if (!this.header) {
28268          const genome = this.genome;
28269          const index = await this.getIndex();
28270          let len;
28271
28272          if (index.firstBlockPosition) {
28273            const bsizeOptions = buildOptions(this.config, {
28274              range: {
28275                start: index.firstBlockPosition,
28276                size: 26
28277              }
28278            });
28279            const abuffer = await igvxhr.loadArrayBuffer(this.bamPath, bsizeOptions);
28280            const bsize = bgzBlockSize(abuffer);
28281            len = index.firstBlockPosition + bsize; // Insure we get the complete compressed block containing the header
28282          } else {
28283            len = 64000;
28284          }
28285
28286          const options = buildOptions(this.config, {
28287            range: {
28288              start: 0,
28289              size: len
28290            }
28291          });
28292          this.header = await BamUtils.readHeader(this.bamPath, options, genome);
28293        }
28294
28295        return this.header;
28296      }
28297
28298      async getIndex() {
28299        const genome = this.genome;
28300
28301        if (!this.index) {
28302          this.index = await loadIndex(this.baiPath, this.config, genome);
28303        }
28304
28305        return this.index;
28306      }
28307
28308      async getChrIndex() {
28309        if (this.chrToIndex) {
28310          return this.chrToIndex;
28311        } else {
28312          const header = await this.getHeader();
28313          this.chrToIndex = header.chrToIndex;
28314          this.indexToChr = header.chrNames;
28315          this.chrAliasTable = header.chrAliasTable;
28316          return this.chrToIndex;
28317        }
28318      }
28319
28320    }
28321
28322    /*
28323     * The MIT License (MIT)
28324     *
28325     * Copyright (c) 2016-2017 The Regents of the University of California
28326     * Author: Jim Robinson
28327     *
28328     * Permission is hereby granted, free of charge, to any person obtaining a copy
28329     * of this software and associated documentation files (the "Software"), to deal
28330     * in the Software without restriction, including without limitation the rights
28331     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28332     * copies of the Software, and to permit persons to whom the Software is
28333     * furnished to do so, subject to the following conditions:
28334     *
28335     * The above copyright notice and this permission notice shall be included in
28336     * all copies or substantial portions of the Software.
28337     *
28338     *
28339     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28340     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28341     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28342     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28343     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28344     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28345     * THE SOFTWARE.
28346     */
28347
28348    class ShardedBamReader {
28349      constructor(config, genome) {
28350        this.config = config;
28351        this.genome = genome;
28352        const bamReaders = {};
28353        config.sources.sequences.forEach(function (chr) {
28354          const queryChr = genome ? genome.getChromosomeName(chr) : chr;
28355          bamReaders[queryChr] = getReader(config, genome, chr);
28356        });
28357        this.bamReaders = bamReaders;
28358        BamUtils.setReaderDefaults(this, config);
28359      }
28360
28361      async readAlignments(chr, start, end) {
28362        if (!this.bamReaders.hasOwnProperty(chr)) {
28363          return new AlignmentContainer(chr, start, end);
28364        } else {
28365          let reader = this.bamReaders[chr];
28366          const a = await reader.readAlignments(chr, start, end);
28367          return a;
28368        }
28369      }
28370
28371    }
28372
28373    function getReader(config, genome, chr) {
28374      const tmp = {
28375        url: config.sources.url.replace("$CHR", chr)
28376      };
28377
28378      if (config.sources.indexURL) {
28379        tmp.indexURL = config.sources.indexURL.replace("$CHR", chr);
28380      }
28381
28382      const bamConfig = Object.assign(config, tmp); // TODO -- support non-indexed, htsget, etc
28383
28384      return new BamReader(bamConfig, genome);
28385    }
28386
28387    /*
28388     * The MIT License (MIT)
28389     *
28390     * Copyright (c) 2016-2017 The Regents of the University of California
28391     * Author: Jim Robinson
28392     *
28393     * Permission is hereby granted, free of charge, to any person obtaining a copy
28394     * of this software and associated documentation files (the "Software"), to deal
28395     * in the Software without restriction, including without limitation the rights
28396     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28397     * copies of the Software, and to permit persons to whom the Software is
28398     * furnished to do so, subject to the following conditions:
28399     *
28400     * The above copyright notice and this permission notice shall be included in
28401     * all copies or substantial portions of the Software.
28402     *
28403     *
28404     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28405     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28406     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28407     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28408     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28409     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28410     * THE SOFTWARE.
28411     */
28412    /**
28413     * Class for reading bam records from an igv.js-flask server backed by pysam.  Deprecated.
28414     *
28415     * @param config
28416     * @constructor
28417     */
28418
28419    const BamWebserviceReader = function (config, genome) {
28420      this.config = config;
28421      this.genome = genome;
28422      BamUtils.setReaderDefaults(this, config);
28423    }; // Example http://localhost:5000/alignments/?reference=/Users/jrobinso/hg19mini.fa&file=/Users/jrobinso/cram_with_crai_index.cram&region=1:100-2000
28424
28425
28426    BamWebserviceReader.prototype.readAlignments = function (chr, bpStart, bpEnd) {
28427      var self = this;
28428      return getHeader.call(self).then(function (header) {
28429        var queryChr, url;
28430        queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr;
28431        url = self.config.url + "?reference=" + self.config.referenceFile + "&file=" + self.config.alignmentFile + "" + "&region=" + queryChr + ":" + bpStart + "-" + bpEnd;
28432        return igvxhr.loadString(url, buildOptions(self.config)).then(function (sam) {
28433          var alignmentContainer;
28434          header.chrToIndex[queryChr];
28435          alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, self.samplingWindowSize, self.samplingDepth, self.pairsSupported, self.alleleFreqThreshold);
28436          BamUtils.decodeSamRecords(sam, alignmentContainer, queryChr, bpStart, bpEnd, self.filter);
28437          return alignmentContainer;
28438        });
28439      });
28440    }; // Example  http://localhost:5000/alignments/?reference=/Users/jrobinso/hg19mini.fa&file=/Users/jrobinso/cram_with_crai_index.cram&options=-b%20-H
28441
28442
28443    function getHeader() {
28444      const self = this;
28445      const genome = this.genome;
28446
28447      if (this.header) {
28448        return Promise.resolve(this.header);
28449      } else {
28450        const url = this.config.url + "?file=" + this.config.alignmentFile + "&options=-b,-H";
28451        const options = buildOptions(this.config);
28452        return BamUtils.readHeader(url, options, genome).then(function (header) {
28453          self.header = header;
28454          return header;
28455        });
28456      }
28457    }
28458
28459    class HtsgetReader {
28460      constructor(config, genome) {
28461        this.config = config;
28462        this.genome = genome;
28463        this.format = config.format ? config.format.toUpperCase() : "BAM"; // Backward compatibility
28464
28465        if (!(this.format === "BAM" || this.format === "VCF")) {
28466          throw Error(`htsget format ${config.format} is not supported`);
28467        }
28468      }
28469
28470      async readHeaderData() {
28471        const url = `${getUrl(this.config)}?class=header&format=${this.format}`;
28472        const ticket = await igvxhr.loadJson(url, buildOptions(this.config));
28473        return await this.loadUrls(ticket.htsget.urls);
28474      }
28475
28476      async readData(chr, start, end) {
28477        const url = `${getUrl(this.config)}?format=${this.format}&referenceName=${chr}&start=${Math.floor(start)}&end=${Math.ceil(end)}`;
28478        const ticket = await igvxhr.loadJson(url, buildOptions(this.config));
28479        return this.loadUrls(ticket.htsget.urls);
28480      }
28481
28482      async loadUrls(urls) {
28483        const promiseArray = [];
28484
28485        for (let urlData of urls) {
28486          if (urlData.url.startsWith('data:')) {
28487            // this is a data-uri
28488            promiseArray.push(Promise.resolve(dataUriToBytes(urlData.url)));
28489          } else {
28490            const options = buildOptions(this.config || {});
28491
28492            if (urlData.headers) {
28493              options.headers = Object.assign(options.headers || {}, urlData.headers);
28494            }
28495
28496            promiseArray.push(igvxhr.loadArrayBuffer(urlData.url, options));
28497          }
28498        }
28499
28500        const arrayBuffers = await Promise.all(promiseArray);
28501        return concatArrays(arrayBuffers);
28502      }
28503
28504      static async inferFormat(config) {
28505        try {
28506          const url = getUrl(config);
28507          const headerURL = `${url}${url.includes("?") ? "&" : "?"}class=header`;
28508          const ticket = await igvxhr.loadJson(headerURL, buildOptions(config));
28509
28510          if (ticket.htsget) {
28511            const format = ticket.htsget.format;
28512
28513            if (!(format === "BAM" || format === "VCF")) {
28514              throw Error(`htsget format ${format} is not supported`);
28515            }
28516
28517            config.format = format.toLowerCase();
28518            config.sourceType = "htsget";
28519
28520            if (!config.name) {
28521              config.name = await getFilename(config.url);
28522            }
28523          }
28524        } catch (e) {// Errors => this is not an htsget source, not an application error.  Ignore
28525        }
28526      }
28527
28528    }
28529    /**
28530     * Extract the full url from the config.  Striving for backward compatibility, "endpoint" and "id" are deprecated.
28531     *
28532     * @param config
28533     */
28534
28535
28536    function getUrl(config) {
28537      if (config.url && config.endpoint && config.id) {
28538        return config.url + config.endpoint + config.id; // Deprecated
28539      } else if (config.endpoint && config.id) {
28540        return config.endpoint + config.id; // Deprecated
28541      } else if (config.url) {
28542        if (config.url.startsWith("htsget://")) {
28543          return config.url.replace("htsget://", "https://"); // htsget -> http not supported
28544        } else {
28545          return config.url;
28546        }
28547      } else {
28548        throw Error("Must specify either 'url', or 'endpoint' and 'id");
28549      }
28550    }
28551    /**
28552     * Concatenate a list of array buffers, returning an UInt8Array
28553     * @param arrayBuffers
28554     */
28555
28556
28557    function concatArrays(arrayBuffers) {
28558      let len = 0;
28559
28560      for (let a of arrayBuffers) {
28561        len += a.byteLength;
28562      }
28563
28564      let offset = 0;
28565      const newArray = new Uint8Array(len);
28566
28567      for (let buf of arrayBuffers) {
28568        const a = new Uint8Array(buf);
28569        newArray.set(a, offset);
28570        offset += a.length;
28571      }
28572
28573      return newArray;
28574    }
28575
28576    function dataUriToBytes(dataUri) {
28577      const split = dataUri.split(',');
28578      const info = split[0].split(':')[1];
28579      let dataString = split[1];
28580
28581      if (info.indexOf('base64') >= 0) {
28582        dataString = atob(dataString);
28583      } else {
28584        dataString = decodeURI(dataString);
28585      }
28586
28587      const bytes = new Uint8Array(dataString.length);
28588
28589      for (var i = 0; i < dataString.length; i++) {
28590        bytes[i] = dataString.charCodeAt(i);
28591      }
28592
28593      return bytes;
28594    }
28595
28596    /*
28597     * The MIT License (MIT)
28598     *
28599     * Copyright (c) 2016-2017 The Regents of the University of California
28600     * Author: Jim Robinson
28601     *
28602     * Permission is hereby granted, free of charge, to any person obtaining a copy
28603     * of this software and associated documentation files (the "Software"), to deal
28604     * in the Software without restriction, including without limitation the rights
28605     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28606     * copies of the Software, and to permit persons to whom the Software is
28607     * furnished to do so, subject to the following conditions:
28608     *
28609     * The above copyright notice and this permission notice shall be included in
28610     * all copies or substantial portions of the Software.
28611     *
28612     *
28613     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28614     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28615     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28616     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28617     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28618     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28619     * THE SOFTWARE.
28620     */
28621
28622    class HtsgetBamReader extends HtsgetReader {
28623      constructor(config, genome) {
28624        super(config, genome);
28625        BamUtils.setReaderDefaults(this, config);
28626      }
28627
28628      async readAlignments(chr, start, end) {
28629        if (!this.header) {
28630          const compressedData = await this.readHeaderData();
28631          const ba = unbgzf(compressedData.buffer);
28632          this.header = BamUtils.decodeBamHeader(ba, this.genome);
28633          this.chrAliasTable = new Map();
28634
28635          for (let key of Object.keys(this.header.chrAliasTable)) {
28636            this.chrAliasTable.set(key, this.header.chrAliasTable[key]);
28637          }
28638        }
28639
28640        let queryChr = this.chrAliasTable.has(chr) ? this.chrAliasTable.get(chr) : chr;
28641        const compressedData = await this.readData(queryChr, start, end); // BAM decoding
28642
28643        const ba = unbgzf(compressedData.buffer);
28644        const chrIdx = this.header.chrToIndex[chr];
28645        const alignmentContainer = new AlignmentContainer(chr, start, end, this.samplingWindowSize, this.samplingDepth, this.pairsSupported, this.alleleFreqThreshold);
28646        BamUtils.decodeBamRecords(ba, this.header.size, alignmentContainer, this.header.chrNames, chrIdx, start, end);
28647        alignmentContainer.finish();
28648        return alignmentContainer;
28649      }
28650
28651    }
28652
28653    var $propertyIsEnumerable = {}.propertyIsEnumerable; // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
28654
28655    var getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor; // Nashorn ~ JDK8 bug
28656
28657    var NASHORN_BUG = getOwnPropertyDescriptor$1 && !$propertyIsEnumerable.call({
28658      1: 2
28659    }, 1); // `Object.prototype.propertyIsEnumerable` method implementation
28660    // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
28661
28662    var f$3 = NASHORN_BUG ? function propertyIsEnumerable(V) {
28663      var descriptor = getOwnPropertyDescriptor$1(this, V);
28664      return !!descriptor && descriptor.enumerable;
28665    } : $propertyIsEnumerable;
28666    var objectPropertyIsEnumerable = {
28667      f: f$3
28668    };
28669
28670    var Object$1 = global$1.Object;
28671    var split = functionUncurryThis(''.split); // fallback for non-array-like ES3 and non-enumerable old V8 strings
28672
28673    var indexedObject = fails(function () {
28674      // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
28675      // eslint-disable-next-line no-prototype-builtins -- safe
28676      return !Object$1('z').propertyIsEnumerable(0);
28677    }) ? function (it) {
28678      return classofRaw(it) == 'String' ? split(it, '') : Object$1(it);
28679    } : Object$1;
28680
28681    var toIndexedObject = function (it) {
28682      return indexedObject(requireObjectCoercible(it));
28683    };
28684
28685    var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; // `Object.getOwnPropertyDescriptor` method
28686    // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
28687
28688    var f$2 = descriptors ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
28689      O = toIndexedObject(O);
28690      P = toPropertyKey(P);
28691      if (ie8DomDefine) try {
28692        return $getOwnPropertyDescriptor(O, P);
28693      } catch (error) {
28694        /* empty */
28695      }
28696      if (hasOwnProperty_1(O, P)) return createPropertyDescriptor(!functionCall(objectPropertyIsEnumerable.f, O, P), O[P]);
28697    };
28698    var objectGetOwnPropertyDescriptor = {
28699      f: f$2
28700    };
28701
28702    var createMethod = function (IS_INCLUDES) {
28703      return function ($this, el, fromIndex) {
28704        var O = toIndexedObject($this);
28705        var length = lengthOfArrayLike(O);
28706        var index = toAbsoluteIndex(fromIndex, length);
28707        var value; // Array#includes uses SameValueZero equality algorithm
28708        // eslint-disable-next-line no-self-compare -- NaN check
28709
vendor: 4,301 bytes, lines 28710-28816
28710        if (IS_INCLUDES && el != el) while (length > index) {
28711          value = O[index++]; // eslint-disable-next-line no-self-compare -- NaN check
28712
28713          if (value != value) return true; // Array#indexOf ignores holes, Array#includes - not
28714        } else for (; length > index; index++) {
28715          if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
28716        }
28717        return !IS_INCLUDES && -1;
28718      };
28719    };
28720
28721    var arrayIncludes = {
28722      // `Array.prototype.includes` method
28723      // https://tc39.es/ecma262/#sec-array.prototype.includes
28724      includes: createMethod(true),
28725      // `Array.prototype.indexOf` method
28726      // https://tc39.es/ecma262/#sec-array.prototype.indexof
28727      indexOf: createMethod(false)
28728    };
28729
28730    var indexOf = arrayIncludes.indexOf;
28731    var push = functionUncurryThis([].push);
28732
28733    var objectKeysInternal = function (object, names) {
28734      var O = toIndexedObject(object);
28735      var i = 0;
28736      var result = [];
28737      var key;
28738
28739      for (key in O) !hasOwnProperty_1(hiddenKeys$1, key) && hasOwnProperty_1(O, key) && push(result, key); // Don't enum bug & hidden keys
28740
28741
28742      while (names.length > i) if (hasOwnProperty_1(O, key = names[i++])) {
28743        ~indexOf(result, key) || push(result, key);
28744      }
28745
28746      return result;
28747    };
28748
28749    // IE8- don't enum bug keys
28750    var enumBugKeys = ['constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf'];
28751
28752    var hiddenKeys = enumBugKeys.concat('length', 'prototype'); // `Object.getOwnPropertyNames` method
28753    // https://tc39.es/ecma262/#sec-object.getownpropertynames
28754    // eslint-disable-next-line es/no-object-getownpropertynames -- safe
28755
28756    var f$1 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
28757      return objectKeysInternal(O, hiddenKeys);
28758    };
28759
28760    var objectGetOwnPropertyNames = {
28761      f: f$1
28762    };
28763
28764    // eslint-disable-next-line es/no-object-getownpropertysymbols -- safe
28765    var f = Object.getOwnPropertySymbols;
28766    var objectGetOwnPropertySymbols = {
28767      f: f
28768    };
28769
28770    var concat = functionUncurryThis([].concat); // all object keys, includes non-enumerable and symbols
28771
28772    var ownKeys = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
28773      var keys = objectGetOwnPropertyNames.f(anObject(it));
28774      var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
28775      return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys;
28776    };
28777
28778    var copyConstructorProperties = function (target, source) {
28779      var keys = ownKeys(source);
28780      var defineProperty = objectDefineProperty.f;
28781      var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
28782
28783      for (var i = 0; i < keys.length; i++) {
28784        var key = keys[i];
28785        if (!hasOwnProperty_1(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
28786      }
28787    };
28788
28789    var replacement = /#|\.prototype\./;
28790
28791    var isForced = function (feature, detection) {
28792      var value = data[normalize(feature)];
28793      return value == POLYFILL ? true : value == NATIVE ? false : isCallable(detection) ? fails(detection) : !!detection;
28794    };
28795
28796    var normalize = isForced.normalize = function (string) {
28797      return String(string).replace(replacement, '.').toLowerCase();
28798    };
28799
28800    var data = isForced.data = {};
28801    var NATIVE = isForced.NATIVE = 'N';
28802    var POLYFILL = isForced.POLYFILL = 'P';
28803    var isForced_1 = isForced;
28804
28805    var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
28806    /*
28807      options.target      - name of the target object
28808      options.global      - target is the global object
28809      options.stat        - export as static methods of target
28810      options.proto       - export as prototype methods of target
28811      options.real        - real prototype method for the `pure` version
28812      options.forced      - export even if the native feature is available
28813      options.bind        - bind methods to the target, required for the `pure` version
28814      options.wrap        - wrap constructors to preventing global pollution, required for the `pure` version
28815      options.unsafe      - use the simple assignment of property instead of delete + defineProperty
28816      options.sham        - add a flag to not completely full pol
28816yfills
28817      options.enumerable  - export as enumerable property
28818      options.noTargetGet - prevent calling a getter on target
28819      options.name        - the .name of the function if it does not match the key
28820    */
28821
28822    var _export = function (options, source) {
28823      var TARGET = options.target;
28824      var GLOBAL = options.global;
28825      var STATIC = options.stat;
28826      var FORCED, target, key, targetProperty, sourceProperty, descriptor;
28827
28828      if (GLOBAL) {
28829        target = global$1;
28830      } else if (STATIC) {
28831        target = global$1[TARGET] || setGlobal(TARGET, {});
28832      } else {
28833        target = (global$1[TARGET] || {}).prototype;
28834      }
28835
28836      if (target) for (key in source) {
28837        sourceProperty = source[key];
28838
28839        if (options.noTargetGet) {
28840          descriptor = getOwnPropertyDescriptor(target, key);
28841          targetProperty = descriptor && descriptor.value;
28842        } else targetProperty = target[key];
28843
28844        FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); // contained in target
28845
28846        if (!FORCED && targetProperty !== undefined) {
28847          if (typeof sourceProperty == typeof targetProperty) continue;
28848          copyConstructorProperties(sourceProperty, targetProperty);
28849        } // add a flag to not completely full polyfills
28850
28851
28852        if (options.sham || targetProperty && targetProperty.sham) {
28853          createNonEnumerableProperty(sourceProperty, 'sham', true);
28854        } // extend global
28855
28856
28857        redefine(target, key, sourceProperty, options);
28858      }
28859    };
28860
28861    var FunctionPrototype = Function.prototype;
28862    var apply = FunctionPrototype.apply;
28863    var bind$1 = FunctionPrototype.bind;
28864    var call = FunctionPrototype.call; // eslint-disable-next-line es/no-reflect -- safe
28865
28866    var functionApply = typeof Reflect == 'object' && Reflect.apply || (bind$1 ? call.bind(apply) : function () {
28867      return call.apply(apply, arguments);
28868    });
28869
28870    var bind = functionUncurryThis(functionUncurryThis.bind); // optional / simple context binding
28871
28872    var functionBindContext = function (fn, that) {
28873      aCallable(fn);
28874      return that === undefined ? fn : bind ? bind(fn, that) : function
28875        /* ...args */
28876      () {
28877        return fn.apply(that, arguments);
28878      };
28879    };
28880
28881    var html = getBuiltIn('document', 'documentElement');
28882
28883    var arraySlice = functionUncurryThis([].slice);
28884
28885    var engineIsIos = /(?:ipad|iphone|ipod).*applewebkit/i.test(engineUserAgent);
28886
28887    var engineIsNode = classofRaw(global$1.process) == 'process';
28888
28889    var set = global$1.setImmediate;
28890    var clear = global$1.clearImmediate;
28891    var process$1 = global$1.process;
28892    var Dispatch = global$1.Dispatch;
28893    var Function$1 = global$1.Function;
28894    var MessageChannel$1 = global$1.MessageChannel;
28895    var String$1 = global$1.String;
28896    var counter = 0;
28897    var queue = {};
28898    var ONREADYSTATECHANGE = 'onreadystatechange';
28899    var location, defer, channel, port;
28900
28901    try {
28902      // Deno throws a ReferenceError on `location` access without `--location` flag
28903      location = global$1.location;
28904    } catch (error) {
28905      /* empty */
28906    }
28907
28908    var run = function (id) {
28909      if (hasOwnProperty_1(queue, id)) {
28910        var fn = queue[id];
28911        delete queue[id];
28912        fn();
28913      }
28914    };
28915
28916    var runner = function (id) {
28917      return function () {
28918        run(id);
28919      };
28920    };
28921
28922    var listener = function (event) {
28923      run(event.data);
28924    };
28925
28926    var post = function (id) {
28927      // old engines have not location.origin
28928      global$1.postMessage(String$1(id), location.protocol + '//' + location.host);
28929    }; // Node.js 0.9+ & IE10+ has setImmediate, otherwise:
28930
28931
28932    if (!set || !clear) {
28933      set = function setImmediate(fn) {
28934        var args = arraySlice(arguments, 1);
28935
28936        queue[++counter] = function () {
28937          functionApply(isCallable(fn) ? fn : Function$1(fn), undefined, args);
28938        };
28939
28940        defer(counter);
28941        return counter;
28942      };
28943
28944      clear = function clearImmediate(id) {
28945        delete queue[id];
28946      }; // Node.js 0.8-
28947
28948
28949      if (engineIsNode) {
28950        defer = function (id) {
28951          process$1.nextTick(runner(id));
28952        }; // Sphere (JS game engine) Dispatch API
28953
28954      } else if (Dispatch && Dispatch.now) {
28955        defer = function (id) {
28956          Dispatch.now(runner(id));
28957        }; // Browsers with MessageChannel, includes WebWorkers
28958        // except iOS - https://github.com/zloirock/core-js/issues/624
28959
28960      } else if (MessageChannel$1 && !engineIsIos) {
28961        channel = new MessageChannel$1();
28962        port = channel.port2;
28963        channel.port1.onmessage = listener;
28964        defer = functionBindContext(port.postMessage, port); // Browsers with postMessage, skip WebWorkers
28965        // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
28966      } else if (global$1.addEventListener && isCallable(global$1.postMessage) && !global$1.importScripts && location && location.protocol !== 'file:' && !fails(post)) {
28967        defer = post;
28968        global$1.addEventListener('message', listener, false); // IE8-
28969      } else if (ONREADYSTATECHANGE in documentCreateElement('script')) {
28970        defer = function (id) {
28971          html.appendChild(documentCreateElement('script'))[ONREADYSTATECHANGE] = function () {
28972            html.removeChild(this);
28973            run(id);
28974          };
28975        }; // Rest old browsers
28976
28977      } else {
28978        defer = function (id) {
28979          setTimeout(runner(id), 0);
28980        };
28981      }
28982    }
28983
28984    var task = {
28985      set: set,
28986      clear: clear
28987    };
28988
28989    var FORCED = !global$1.setImmediate || !global$1.clearImmediate; // http://w3c.github.io/setImmediate/
28990
28991    _export({
28992      global: true,
28993      bind: true,
28994      enumerable: true,
28995      forced: FORCED
28996    }, {
28997      // `setImmediate` method
28998      // http://w3c.github.io/setImmediate/#si-setImmediate
28999      setImmediate: task.set,
29000      // `clearImmediate` method
29001      // http://w3c.github.io/setImmediate/#si-clearImmediate
29002      clearImmediate: task.clear
29003    });
29004
29005    const eval2 = eval;
29006
29007    const gmodCRAM = function (t) {
29008      var e = {};
29009
29010      function r(n) {
29011        if (e[n]) return e[n].exports;
29012        var i = e[n] = {
29013          i: n,
29014          l: !1,
29015          exports: {}
29016        };
29017        return t[n].call(i.exports, i, i.exports, r), i.l = !0, i.exports;
29018      }
29019
29020      return r.m = t, r.c = e, r.d = function (t, e, n) {
29021        r.o(t, e) || Object.defineProperty(t, e, {
29022          enumerable: !0,
29023          get: n
29024        });
29025      }, r.r = function (t) {
29026        "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
29027          value: "Module"
29028        }), Object.defineProperty(t, "__esModule", {
29029          value: !0
29030        });
29031      }, r.t = function (t, e) {
29032        if (1 & e && (t = r(t)), 8 & e) return t;
29033        if (4 & e && "object" == typeof t && t && t.__esModule) return t;
29034        var n = Object.create(null);
29035        if (r.r(n), Object.defineProperty(n, "default", {
29036          enumerable: !0,
29037          value: t
29038        }), 2 & e && "string" != typeof t) for (var i in t) r.d(n, i, function (e) {
29039          return t[e];
29040        }.bind(null, i));
29041        return n;
29042      }, r.n = function (t) {
29043        var e = t && t.__esModule ? function () {
29044          return t.default;
29045        } : function () {
29046          return t;
29047        };
29048        return r.d(e, "a", e), e;
29049      }, r.o = function (t, e) {
29050        return Object.prototype.hasOwnProperty.call(t, e);
29051      }, r.p = "", r(r.s = 163);
29052    }([function (t, e, r) {
29053
29054      var n = r(13),
29055          i = r(81).f,
29056          o = r(107),
29057          a = r(3),
29058          s = r(15),
29059          u = r(20),
29060          f = r(24),
29061          c = function (t) {
29062        var e = function (e, r, n) {
29063          if (this instanceof t) {
29064            switch (arguments.length) {
29065              case 0:
29066                return new t();
29067
29068              case 1:
29069                return new t(e);
29070
29071              case 2:
29072                return new t(e, r);
29073            }
29074
29075            return new t(e, r, n);
29076          }
29077
29078          return t.apply(this, arguments);
29079        };
29080
29081        return e.prototype = t.prototype, e;
29082      };
29083
29084      t.exports = function (t, e) {
29085        var r,
29086            l,
29087            h,
29088            d,
29089            p,
29090            g,
29091            v,
29092            y,
29093            m = t.target,
29094            b = t.global,
29095            _ = t.stat,
29096            w = t.proto,
29097            x = b ? n : _ ? n[m] : (n[m] || {}).prototype,
29098            E = b ? a : a[m] || (a[m] = {}),
29099            S = E.prototype;
29100
29101        for (h in e) r = !o(b ? h : m + (_ ? "." : "#") + h, t.forced) && x && f(x, h), p = E[h], r && (g = t.noTargetGet ? (y = i(x, h)) && y.value : x[h]), d = r && g ? g : e[h], r && typeof p == typeof d || (v = t.bind && r ? s(d, n) : t.wrap && r ? c(d) : w && "function" == typeof d ? s(Function.call, d) : d, (t.sham || d && d.sham || p && p.sham) && u(v, "sham", !0), E[h] = v, w && (f(a, l = m + "Prototype") || u(a, l, {}), a[l][h] = d, t.real && S && !S[h] && u(S, h, d)));
29102      };
29103    }, function (t, e) {
29104      t.exports = function (t) {
29105        return t && t.__esModule ? t : {
29106          default: t
29107        };
29108      };
29109    }, function (t, e, r) {
29110      var n = r(14);
29111
29112      t.exports = function (t) {
29113        if (!n(t)) throw TypeError(String(t) + " is not an object");
29114        return t;
29115      };
29116    }, function (t, e) {
29117      t.exports = {};
29118    }, function (t, e) {
29119      t.exports = !0;
29120    }, function (t, e) {
29121      t.exports = function (t) {
29122        if ("function" != typeof t) throw TypeError(String(t) + " is not a function");
29123        return t;
29124      };
29125    }, function (t, e, r) {
29126      var n = r(13),
29127          i = r(61),
29128          o = r(64),
29129          a = r(110),
29130          s = n.Symbol,
29131          u = i("wks");
29132
29133      t.exports = function (t) {
29134        return u[t] || (u[t] = a && s[t] || (a ? s : o)("Symbol." + t));
29135      };
29136    }, function (t, e) {
29137      t.exports = function (t, e) {
29138        if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function");
29139      };
29140    }, function (t, e, r) {
29141      var n = r(2),
29142          i = r(119),
29143          o = r(29),
29144          a = r(15),
29145          s = r(90),
29146          u = r(120),
29147          f = function (t, e) {
29148        this.stopped = t, this.result = e;
29149      };
29150
29151      (t.exports = function (t, e, r, c, l) {
29152        var h,
29153            d,
29154            p,
29155            g,
29156            v,
29157            y,
29158            m = a(e, r, c ? 2 : 1);
29159        if (l) h = t;else {
29160          if ("function" != typeof (d = s(t))) throw TypeError("Target is not iterable");
29161
29162          if (i(d)) {
29163            for (p = 0, g = o(t.length); g > p; p++) if ((v = c ? m(n(y = t[p])[0], y[1]) : m(t[p])) && v instanceof f) return v;
29164
29165            return new f(!1);
29166          }
29167
29168          h = d.call(t);
29169        }
29170
29171        for (; !(y = h.next()).done;) if ((v = u(h, m, y.value, c)) && v instanceof f) return v;
29172
29173        return new f(!1);
29174      }).stop = function (t) {
29175        return new f(!0, t);
29176      };
29177    }, function (t, e, r) {
29178
29179      var n = r(1),
29180          i = n(r(7)),
29181          o = n(r(32)),
29182          a = n(r(27)),
29183          s = n(r(33)),
29184          u = n(r(265)),
29185          f = function (t) {
29186        function e() {
29187          return (0, i.default)(this, e), (0, o.default)(this, (0, a.default)(e).apply(this, arguments));
29188        }
29189
29190        return (0, s.default)(e, t), e;
29191      }((0, u.default)(Error)),
29192          c = function (t) {
29193        function e() {
29194          return (0, i.default)(this, e), (0, o.default)(this, (0, a.default)(e).apply(this, arguments));
29195        }
29196
29197        return (0, s.default)(e, t), e;
29198      }((0, u.default)(Error)),
29199          l = function (t) {
29200        function e() {
29201          return (0, i.default)(this, e), (0, o.default)(this, (0, a.default)(e).apply(this, arguments));
29202        }
29203
29204        return (0, s.default)(e, t), e;
29205      }(f),
29206          h = function (t) {
29207        function e() {
29208          return (0, i.default)(this, e), (0, o.default)(this, (0, a.default)(e).apply(this, arguments));
29209        }
29210
29211        return (0, s.default)(e, t), e;
29212      }(l),
29213          d = function (t) {
29214        function e() {
29215          return (0, i.default)(this, e), (0, o.default)(this, (0, a.default)(e).apply(this, arguments));
29216        }
29217
29218        return (0, s.default)(e, t), e;
29219      }(f),
29220          p = function (t) {
29221        function e() {
29222          return (0, i.default)(this, e), (0, o.default)(this, (0, a.default)(e).apply(this, arguments));
29223        }
29224
29225        return (0, s.default)(e, t), e;
29226      }(f);
29227
29228      t.exports = {
29229        CramBufferOverrunError: h,
29230        CramMalformedError: l,
29231        CramUnimplementedError: c,
29232        CramSizeLimitError: d,
29233        CramArgumentError: p
29234      };
29235    }, function (t, e, r) {
29236      var n = r(196);
29237
29238      function i(t, e) {
29239        for (var r = 0; r < e.length; r++) {
29240          var i = e[r];
29241          i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), n(t, i.key, i);
29242        }
29243      }
29244
29245      t.exports = function (t, e, r) {
29246        return e && i(t.prototype, e), r && i(t, r), t;
29247      };
29248    }, function (t, e, r) {
29249      var n = r(3),
29250          i = r(24),
29251          o = r(95),
29252          a = r(21).f;
29253
29254      t.exports = function (t) {
29255        var e = n.Symbol || (n.Symbol = {});
29256        i(e, t) || a(e, t, {
29257          value: o.f(t)
29258        });
29259      };
29260    }, function (t, e) {
29261      t.exports = function (t) {
29262        try {
29263          return !!t();
29264        } catch (t) {
29265          return !0;
29266        }
29267      };
29268    }, function (t, e, r) {
29269      (function (e) {
29270        var r = "object",
29271            n = function (t) {
29272          return t && t.Math == Math && t;
29273        };
29274
29275        t.exports = n(typeof globalThis == r && globalThis) || n(typeof window == r && window) || n(typeof self == r && self) || n(typeof e == r && e) || Function("return this")();
29276      }).call(this, r(23));
29277    }, function (t, e) {
29278      t.exports = function (t) {
29279        return "object" == typeof t ? null !== t : "function" == typeof t;
29280      };
29281    }, function (t, e, r) {
29282      var n = r(5);
29283
29284      t.exports = function (t, e, r) {
29285        if (n(t), void 0 === e) return t;
29286
29287        switch (r) {
29288          case 0:
29289            return function () {
29290              return t.call(e);
29291            };
29292
29293          case 1:
29294            return function (r) {
29295              return t.call(e, r);
29296            };
29297
29298          case 2:
29299            return function (r, n) {
29300              return t.call(e, r, n);
29301            };
29302
29303          case 3:
29304            return function (r, n, i) {
29305              return t.call(e, r, n, i);
29306            };
29307        }
29308
29309        return function () {
29310          return t.apply(e, arguments);
29311        };
29312      };
29313    }, function (t, e, r) {
29314      t.exports = r(167);
29315    }, function (t, e, r) {
29316      var n = r(12);
29317      t.exports = !n(function () {
29318        return 7 != Object.defineProperty({}, "a", {
29319          get: function () {
29320            return 7;
29321          }
29322        }).a;
29323      });
29324    }, function (t, e, r) {
29325      var n = r(3);
29326
29327      t.exports = function (t) {
29328        return n[t + "Prototype"];
29329      };
29330    }, function (t, e, r) {
29331
29332      (function (t) {
29333        /*!
29334         * The buffer module from node.js, for the browser.
29335         *
29336         * @author   Feross Aboukhadijeh <[email protected]> <http://feross.org>
29337         * @license  MIT
29338         */
29339        var n = r(165),
29340            i = r(166),
29341            o = r(105);
29342
29343        function a() {
29344          return u.TYPED_ARRAY_SUPPORT ? 2147483647 : 1073741823;
29345        }
29346
29347        function s(t, e) {
29348          if (a() < e) throw new RangeError("Invalid typed array length");
29349          return u.TYPED_ARRAY_SUPPORT ? (t = new Uint8Array(e)).__proto__ = u.prototype : (null === t && (t = new u(e)), t.length = e), t;
29350        }
29351
29352        function u(t, e, r) {
29353          if (!(u.TYPED_ARRAY_SUPPORT || this instanceof u)) return new u(t, e, r);
29354
29355          if ("number" == typeof t) {
29356            if ("string" == typeof e) throw new Error("If encoding is specified then the first argument must be a string");
29357            return l(this, t);
29358          }
29359
29360          return f(this, t, e, r);
29361        }
29362
29363        function f(t, e, r, n) {
29364          if ("number" == typeof e) throw new TypeError('"value" argument must not be a number');
29365          return "undefined" != typeof ArrayBuffer && e instanceof ArrayBuffer ? function (t, e, r, n) {
29366            if (e.byteLength, r < 0 || e.byteLength < r) throw new RangeError("'offset' is out of bounds");
29367            if (e.byteLength < r + (n || 0)) throw new RangeError("'length' is out of bounds");
29368            e = void 0 === r && void 0 === n ? new Uint8Array(e) : void 0 === n ? new Uint8Array(e, r) : new Uint8Array(e, r, n);
29369            u.TYPED_ARRAY_SUPPORT ? (t = e).__proto__ = u.prototype : t = h(t, e);
29370            return t;
29371          }(t, e, r, n) : "string" == typeof e ? function (t, e, r) {
29372            "string" == typeof r && "" !== r || (r = "utf8");
29373            if (!u.isEncoding(r)) throw new TypeError('"encoding" must be a valid string encoding');
29374            var n = 0 | p(e, r),
29375                i = (t = s(t, n)).write(e, r);
29376            i !== n && (t = t.slice(0, i));
29377            return t;
29378          }(t, e, r) : function (t, e) {
29379            if (u.isBuffer(e)) {
29380              var r = 0 | d(e.length);
29381              return 0 === (t = s(t, r)).length ? t : (e.copy(t, 0, 0, r), t);
29382            }
29383
29384            if (e) {
29385              if ("undefined" != typeof ArrayBuffer && e.buffer instanceof ArrayBuffer || "length" in e) return "number" != typeof e.length || (n = e.length) != n ? s(t, 0) : h(t, e);
29386              if ("Buffer" === e.type && o(e.data)) return h(t, e.data);
29387            }
29388
29389            var n;
29390            throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.");
29391          }(t, e);
29392        }
29393
29394        function c(t) {
29395          if ("number" != typeof t) throw new TypeError('"size" argument must be a number');
29396          if (t < 0) throw new RangeError('"size" argument must not be negative');
29397        }
29398
29399        function l(t, e) {
29400          if (c(e), t = s(t, e < 0 ? 0 : 0 | d(e)), !u.TYPED_ARRAY_SUPPORT) for (var r = 0; r < e; ++r) t[r] = 0;
29401          return t;
29402        }
29403
29404        function h(t, e) {
29405          var r = e.length < 0 ? 0 : 0 | d(e.length);
29406          t = s(t, r);
29407
29408          for (var n = 0; n < r; n += 1) t[n] = 255 & e[n];
29409
29410          return t;
29411        }
29412
29413        function d(t) {
29414          if (t >= a()) throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x" + a().toString(16) + " bytes");
29415          return 0 | t;
29416        }
29417
29418        function p(t, e) {
29419          if (u.isBuffer(t)) return t.length;
29420          if ("undefined" != typeof ArrayBuffer && "function" == typeof ArrayBuffer.isView && (ArrayBuffer.isView(t) || t instanceof ArrayBuffer)) return t.byteLength;
29421          "string" != typeof t && (t = "" + t);
29422          var r = t.length;
29423          if (0 === r) return 0;
29424
29425          for (var n = !1;;) switch (e) {
29426            case "ascii":
29427            case "latin1":
29428            case "binary":
29429              return r;
29430
29431            case "utf8":
29432            case "utf-8":
29433            case void 0:
29434              return D(t).length;
29435
29436            case "ucs2":
29437            case "ucs-2":
29438            case "utf16le":
29439            case "utf-16le":
29440              return 2 * r;
29441
29442            case "hex":
29443              return r >>> 1;
29444
29445            case "base64":
29446              return q(t).length;
29447
29448            default:
29449              if (n) return D(t).length;
29450              e = ("" + e).toLowerCase(), n = !0;
29451          }
29452        }
29453
29454        function g(t, e, r) {
29455          var n = !1;
29456          if ((void 0 === e || e < 0) && (e = 0), e > this.length) return "";
29457          if ((void 0 === r || r > this.length) && (r = this.length), r <= 0) return "";
29458          if ((r >>>= 0) <= (e >>>= 0)) return "";
29459
29460          for (t || (t = "utf8");;) switch (t) {
29461            case "hex":
29462              return O(this, e, r);
29463
29464            case "utf8":
29465            case "utf-8":
29466              return A(this, e, r);
29467
29468            case "ascii":
29469              return T(this, e, r);
29470
29471            case "latin1":
29472            case "binary":
29473              return R(this, e, r);
29474
29475            case "base64":
29476              return k(this, e, r);
29477
29478            case "ucs2":
29479            case "ucs-2":
29480            case "utf16le":
29481            case "utf-16le":
29482              return I(this, e, r);
29483
29484            default:
29485              if (n) throw new TypeError("Unknown encoding: " + t);
29486              t = (t + "").toLowerCase(), n = !0;
29487          }
29488        }
29489
29490        function v(t, e, r) {
29491          var n = t[e];
29492          t[e] = t[r], t[r] = n;
29493        }
29494
29495        function y(t, e, r, n, i) {
29496          if (0 === t.length) return -1;
29497
29498          if ("string" == typeof r ? (n = r, r = 0) : r > 2147483647 ? r = 2147483647 : r < -2147483648 && (r = -2147483648), r = +r, isNaN(r) && (r = i ? 0 : t.length - 1), r < 0 && (r = t.length + r), r >= t.length) {
29499            if (i) return -1;
29500            r = t.length - 1;
29501          } else if (r < 0) {
29502            if (!i) return -1;
29503            r = 0;
29504          }
29505
29506          if ("string" == typeof e && (e = u.from(e, n)), u.isBuffer(e)) return 0 === e.length ? -1 : m(t, e, r, n, i);
29507          if ("number" == typeof e) return e &= 255, u.TYPED_ARRAY_SUPPORT && "function" == typeof Uint8Array.prototype.indexOf ? i ? Uint8Array.prototype.indexOf.call(t, e, r) : Uint8Array.prototype.lastIndexOf.call(t, e, r) : m(t, [e], r, n, i);
29508          throw new TypeError("val must be string, number or Buffer");
29509        }
29510
29511        function m(t, e, r, n, i) {
29512          var o,
29513              a = 1,
29514              s = t.length,
29515              u = e.length;
29516
29517          if (void 0 !== n && ("ucs2" === (n = String(n).toLowerCase()) || "ucs-2" === n || "utf16le" === n || "utf-16le" === n)) {
29518            if (t.length < 2 || e.length < 2) return -1;
29519            a = 2, s /= 2, u /= 2, r /= 2;
29520          }
29521
29522          function f(t, e) {
29523            return 1 === a ? t[e] : t.readUInt16BE(e * a);
29524          }
29525
29526          if (i) {
29527            var c = -1;
29528
29529            for (o = r; o < s; o++) if (f(t, o) === f(e, -1 === c ? 0 : o - c)) {
29530              if (-1 === c && (c = o), o - c + 1 === u) return c * a;
29531            } else -1 !== c && (o -= o - c), c = -1;
29532          } else for (r + u >
29532 s && (r = s - u), o = r; o >= 0; o--) {
29533            for (var l = !0, h = 0; h < u; h++) if (f(t, o + h) !== f(e, h)) {
29534              l = !1;
29535              break;
29536            }
29537
29538            if (l) return o;
29539          }
29540
29541          return -1;
29542        }
29543
29544        function b(t, e, r, n) {
29545          r = Number(r) || 0;
29546          var i = t.length - r;
29547          n ? (n = Number(n)) > i && (n = i) : n = i;
29548          var o = e.length;
29549          if (o % 2 != 0) throw new TypeError("Invalid hex string");
29550          n > o / 2 && (n = o / 2);
29551
29552          for (var a = 0; a < n; ++a) {
29553            var s = parseInt(e.substr(2 * a, 2), 16);
29554            if (isNaN(s)) return a;
29555            t[r + a] = s;
29556          }
29557
29558          return a;
29559        }
29560
29561        function _(t, e, r, n) {
29562          return Z(D(e, t.length - r), t, r, n);
29563        }
29564
29565        function w(t, e, r, n) {
29566          return Z(function (t) {
29567            for (var e = [], r = 0; r < t.length; ++r) e.push(255 & t.charCodeAt(r));
29568
29569            return e;
29570          }(e), t, r, n);
29571        }
29572
29573        function x(t, e, r, n) {
29574          return w(t, e, r, n);
29575        }
29576
29577        function E(t, e, r, n) {
29578          return Z(q(e), t, r, n);
29579        }
29580
29581        function S(t, e, r, n) {
29582          return Z(function (t, e) {
29583            for (var r, n, i, o = [], a = 0; a < t.length && !((e -= 2) < 0); ++a) r = t.charCodeAt(a), n = r >> 8, i = r % 256, o.push(i), o.push(n);
29584
29585            return o;
29586          }(e, t.length - r), t, r, n);
29587        }
29588
29589        function k(t, e, r) {
29590          return 0 === e && r === t.length ? n.fromByteArray(t) : n.fromByteArray(t.slice(e, r));
29591        }
29592
29593        function A(t, e, r) {
29594          r = Math.min(t.length, r);
29595
29596          for (var n = [], i = e; i < r;) {
29597            var o,
29598                a,
29599                s,
29600                u,
29601                f = t[i],
29602                c = null,
29603                l = f > 239 ? 4 : f > 223 ? 3 : f > 191 ? 2 : 1;
29604            if (i + l <= r) switch (l) {
29605              case 1:
29606                f < 128 && (c = f);
29607                break;
29608
29609              case 2:
29610                128 == (192 & (o = t[i + 1])) && (u = (31 & f) << 6 | 63 & o) > 127 && (c = u);
29611                break;
29612
29613              case 3:
29614                o = t[i + 1], a = t[i + 2], 128 == (192 & o) && 128 == (192 & a) && (u = (15 & f) << 12 | (63 & o) << 6 | 63 & a) > 2047 && (u < 55296 || u > 57343) && (c = u);
29615                break;
29616
29617              case 4:
29618                o = t[i + 1], a = t[i + 2], s = t[i + 3], 128 == (192 & o) && 128 == (192 & a) && 128 == (192 & s) && (u = (15 & f) << 18 | (63 & o) << 12 | (63 & a) << 6 | 63 & s) > 65535 && u < 1114112 && (c = u);
29619            }
29620            null === c ? (c = 65533, l = 1) : c > 65535 && (c -= 65536, n.push(c >>> 10 & 1023 | 55296), c = 56320 | 1023 & c), n.push(c), i += l;
29621          }
29622
29623          return function (t) {
29624            var e = t.length;
29625            if (e <= C) return String.fromCharCode.apply(String, t);
29626            var r = "",
29627                n = 0;
29628
29629            for (; n < e;) r += String.fromCharCode.apply(String, t.slice(n, n += C));
29630
29631            return r;
29632          }(n);
29633        }
29634
29635        e.Buffer = u, e.SlowBuffer = function (t) {
29636          +t != t && (t = 0);
29637          return u.alloc(+t);
29638        }, e.INSPECT_MAX_BYTES = 50, u.TYPED_ARRAY_SUPPORT = void 0 !== t.TYPED_ARRAY_SUPPORT ? t.TYPED_ARRAY_SUPPORT : function () {
29639          try {
29640            var t = new Uint8Array(1);
29641            return t.__proto__ = {
29642              __proto__: Uint8Array.prototype,
29643              foo: function () {
29644                return 42;
29645              }
29646            }, 42 === t.foo() && "function" == typeof t.subarray && 0 === t.subarray(1, 1).byteLength;
29647          } catch (t) {
29648            return !1;
29649          }
29650        }(), e.kMaxLength = a(), u.poolSize = 8192, u._augment = function (t) {
29651          return t.__proto__ = u.prototype, t;
29652        }, u.from = function (t, e, r) {
29653          return f(null, t, e, r);
29654        }, u.TYPED_ARRAY_SUPPORT && (u.prototype.__proto__ = Uint8Array.prototype, u.__proto__ = Uint8Array, "undefined" != typeof Symbol && Symbol.species && u[Symbol.species] === u && Ob
vendor: 14,856 bytes, lines 29654-29995
29654ject.defineProperty(u, Symbol.species, {
29655          value: null,
29656          configurable: !0
29657        })), u.alloc = function (t, e, r) {
29658          return function (t, e, r, n) {
29659            return c(e), e <= 0 ? s(t, e) : void 0 !== r ? "string" == typeof n ? s(t, e).fill(r, n) : s(t, e).fill(r) : s(t, e);
29660          }(null, t, e, r);
29661        }, u.allocUnsafe = function (t) {
29662          return l(null, t);
29663        }, u.allocUnsafeSlow = function (t) {
29664          return l(null, t);
29665        }, u.isBuffer = function (t) {
29666          return !(null == t || !t._isBuffer);
29667        }, u.compare = function (t, e) {
29668          if (!u.isBuffer(t) || !u.isBuffer(e)) throw new TypeError("Arguments must be Buffers");
29669          if (t === e) return 0;
29670
29671          for (var r = t.length, n = e.length, i = 0, o = Math.min(r, n); i < o; ++i) if (t[i] !== e[i]) {
29672            r = t[i], n = e[i];
29673            break;
29674          }
29675
29676          return r < n ? -1 : n < r ? 1 : 0;
29677        }, u.isEncoding = function (t) {
29678          switch (String(t).toLowerCase()) {
29679            case "hex":
29680            case "utf8":
29681            case "utf-8":
29682            case "ascii":
29683            case "latin1":
29684            case "binary":
29685            case "base64":
29686            case "ucs2":
29687            case "ucs-2":
29688            case "utf16le":
29689            case "utf-16le":
29690              return !0;
29691
29692            default:
29693              return !1;
29694          }
29695        }, u.concat = function (t, e) {
29696          if (!o(t)) throw new TypeError('"list" argument must be an Array of Buffers');
29697          if (0 === t.length) return u.alloc(0);
29698          var r;
29699          if (void 0 === e) for (e = 0, r = 0; r < t.length; ++r) e += t[r].length;
29700          var n = u.allocUnsafe(e),
29701              i = 0;
29702
29703          for (r = 0; r < t.length; ++r) {
29704            var a = t[r];
29705            if (!u.isBuffer(a)) throw new TypeError('"list" argument must be an Array of Buffers');
29706            a.copy(n, i), i += a.length;
29707          }
29708
29709          return n;
29710        }, u.byteLength = p, u.prototype._isBuffer = !0, u.prototype.swap16 = function () {
29711          var t = this.length;
29712          if (t % 2 != 0) throw new RangeError("Buffer size must be a multiple of 16-bits");
29713
29714          for (var e = 0; e < t; e += 2) v(this, e, e + 1);
29715
29716          return this;
29717        }, u.prototype.swap32 = function () {
29718          var t = this.length;
29719          if (t % 4 != 0) throw new RangeError("Buffer size must be a multiple of 32-bits");
29720
29721          for (var e = 0; e < t; e += 4) v(this, e, e + 3), v(this, e + 1, e + 2);
29722
29723          return this;
29724        }, u.prototype.swap64 = function () {
29725          var t = this.length;
29726          if (t % 8 != 0) throw new RangeError("Buffer size must be a multiple of 64-bits");
29727
29728          for (var e = 0; e < t; e += 8) v(this, e, e + 7), v(this, e + 1, e + 6), v(this, e + 2, e + 5), v(this, e + 3, e + 4);
29729
29730          return this;
29731        }, u.prototype.toString = function () {
29732          var t = 0 | this.length;
29733          return 0 === t ? "" : 0 === arguments.length ? A(this, 0, t) : g.apply(this, arguments);
29734        }, u.prototype.equals = function (t) {
29735          if (!u.isBuffer(t)) throw new TypeError("Argument must be a Buffer");
29736          return this === t || 0 === u.compare(this, t);
29737        }, u.prototype.inspect = function () {
29738          var t = "",
29739              r = e.INSPECT_MAX_BYTES;
29740          return this.length > 0 && (t = this.toString("hex", 0, r).match(/.{2}/g).join(" "), this.length > r && (t += " ... ")), "<Buffer " + t + ">";
29741        }, u.prototype.compare = function (t, e, r, n, i) {
29742          if (!u.isBuffer(t)) throw new TypeError("Argument must be a Buffer");
29743          if (void 0 === e && (e = 0), void 0 === r && (r = t ? t.length : 0), void 0 === n && (n = 0), void 0 === i && (i = this.length), e < 0 || r > t.length || n < 0 || i > this.length) throw new RangeError("out of range index");
29744          if (n >= i && e >= r) return 0;
29745          if (n >= i) return -1;
29746          if (e >= r) return 1;
29747          if (this === t) return 0;
29748
29749          for (var o = (i >>>= 0) - (n >>>= 0), a = (r >>>= 0) - (e >>>= 0), s = Math.min(o, a), f = this.slice(n, i), c = t.slice(e, r), l = 0; l < s; ++l) if (f[l] !== c[l]) {
29750            o = f[l], a = c[l];
29751            break;
29752          }
29753
29754          return o < a ? -1 : a < o ? 1 : 0;
29755        }, u.prototype.includes = function (t, e, r) {
29756          return -1 !== this.indexOf(t, e, r);
29757        }, u.prototype.indexOf = function (t, e, r) {
29758          return y(this, t, e, r, !0);
29759        }, u.prototype.lastIndexOf = function (t, e, r) {
29760          return y(this, t, e, r, !1);
29761        }, u.prototype.write = function (t, e, r, n) {
29762          if (void 0 === e) n = "utf8", r = this.length, e = 0;else if (void 0 === r && "string" == typeof e) n = e, r = this.length, e = 0;else {
29763            if (!isFinite(e)) throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");
29764            e |= 0, isFinite(r) ? (r |= 0, void 0 === n && (n = "utf8")) : (n = r, r = void 0);
29765          }
29766          var i = this.length - e;
29767          if ((void 0 === r || r > i) && (r = i), t.length > 0 && (r < 0 || e < 0) || e > this.length) throw new RangeError("Attempt to write outside buffer bounds");
29768          n || (n = "utf8");
29769
29770          for (var o = !1;;) switch (n) {
29771            case "hex":
29772              return b(this, t, e, r);
29773
29774            case "utf8":
29775            case "utf-8":
29776              return _(this, t, e, r);
29777
29778            case "ascii":
29779              return w(this, t, e, r);
29780
29781            case "latin1":
29782            case "binary":
29783              return x(this, t, e, r);
29784
29785            case "base64":
29786              return E(this, t, e, r);
29787
29788            case "ucs2":
29789            case "ucs-2":
29790            case "utf16le":
29791            case "utf-16le":
29792              return S(this, t, e, r);
29793
29794            default:
29795              if (o) throw new TypeError("Unknown encoding: " + n);
29796              n = ("" + n).toLowerCase(), o = !0;
29797          }
29798        }, u.prototype.toJSON = function () {
29799          return {
29800            type: "Buffer",
29801            data: Array.prototype.slice.call(this._arr || this, 0)
29802          };
29803        };
29804        var C = 4096;
29805
29806        function T(t, e, r) {
29807          var n = "";
29808          r = Math.min(t.length, r);
29809
29810          for (var i = e; i < r; ++i) n += String.fromCharCode(127 & t[i]);
29811
29812          return n;
29813        }
29814
29815        function R(t, e, r) {
29816          var n = "";
29817          r = Math.min(t.length, r);
29818
29819          for (var i = e; i < r; ++i) n += String.fromCharCode(t[i]);
29820
29821          return n;
29822        }
29823
29824        function O(t, e, r) {
29825          var n = t.length;
29826          (!e || e < 0) && (e = 0), (!r || r < 0 || r > n) && (r = n);
29827
29828          for (var i = "", o = e; o < r; ++o) i += U(t[o]);
29829
29830          return i;
29831        }
29832
29833        function I(t, e, r) {
29834          for (var n = t.slice(e, r), i = "", o = 0; o < n.length; o += 2) i += String.fromCharCode(n[o] + 256 * n[o + 1]);
29835
29836          return i;
29837        }
29838
29839        function L(t, e, r) {
29840          if (t % 1 != 0 || t < 0) throw new RangeError("offset is not uint");
29841          if (t + e > r) throw new RangeError("Trying to access beyond buffer length");
29842        }
29843
29844        function B(t, e, r, n, i, o) {
29845          if (!u.isBuffer(t)) throw new TypeError('"buffer" argument must be a Buffer instance');
29846          if (e > i || e < o) throw new RangeError('"value" argument is out of bounds');
29847          if (r + n > t.length) throw new RangeError("Index out of range");
29848        }
29849
29850        function P(t, e, r, n) {
29851          e < 0 && (e = 65535 + e + 1);
29852
29853          for (var i = 0, o = Math.min(t.length - r, 2); i < o; ++i) t[r + i] = (e & 255 << 8 * (n ? i : 1 - i)) >>> 8 * (n ? i : 1 - i);
29854        }
29855
29856        function F(t, e, r, n) {
29857          e < 0 && (e = 4294967295 + e + 1);
29858
29859          for (var i = 0, o = Math.min(t.length - r, 4); i < o; ++i) t[r + i] = e >>> 8 * (n ? i : 3 - i) & 255;
29860        }
29861
29862        function N(t, e, r, n, i, o) {
29863          if (r + n > t.length) throw new RangeError("Index out of range");
29864          if (r < 0) throw new RangeError("Index out of range");
29865        }
29866
29867        function M(t, e, r, n, o) {
29868          return o || N(t, 0, r, 4), i.write(t, e, r, n, 23, 4), r + 4;
29869        }
29870
29871        function j(t, e, r, n, o) {
29872          return o || N(t, 0, r, 8), i.write(t, e, r, n, 52, 8), r + 8;
29873        }
29874
29875        u.prototype.slice = function (t, e) {
29876          var r,
29877              n = this.length;
29878          if ((t = ~~t) < 0 ? (t += n) < 0 && (t = 0) : t > n && (t = n), (e = void 0 === e ? n : ~~e) < 0 ? (e += n) < 0 && (e = 0) : e > n && (e = n), e < t && (e = t), u.TYPED_ARRAY_SUPPORT) (r = this.subarray(t, e)).__proto__ = u.prototype;else {
29879            var i = e - t;
29880            r = new u(i, void 0);
29881
29882            for (var o = 0; o < i; ++o) r[o] = this[o + t];
29883          }
29884          return r;
29885        }, u.prototype.readUIntLE = function (t, e, r) {
29886          t |= 0, e |= 0, r || L(t, e, this.length);
29887
29888          for (var n = this[t], i = 1, o = 0; ++o < e && (i *= 256);) n += this[t + o] * i;
29889
29890          return n;
29891        }, u.prototype.readUIntBE = function (t, e, r) {
29892          t |= 0, e |= 0, r || L(t, e, this.length);
29893
29894          for (var n = this[t + --e], i = 1; e > 0 && (i *= 256);) n += this[t + --e] * i;
29895
29896          return n;
29897        }, u.prototype.readUInt8 = function (t, e) {
29898          return e || L(t, 1, this.length), this[t];
29899        }, u.prototype.readUInt16LE = function (t, e) {
29900          return e || L(t, 2, this.length), this[t] | this[t + 1] << 8;
29901        }, u.prototype.readUInt16BE = function (t, e) {
29902          return e || L(t, 2, this.length), this[t] << 8 | this[t + 1];
29903        }, u.prototype.readUInt32LE = function (t, e) {
29904          return e || L(t, 4, this.length), (this[t] | this[t + 1] << 8 | this[t + 2] << 16) + 16777216 * this[t + 3];
29905        }, u.prototype.readUInt32BE = function (t, e) {
29906          return e || L(t, 4, this.length), 16777216 * this[t] + (this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3]);
29907        }, u.prototype.readIntLE = function (t, e, r) {
29908          t |= 0, e |= 0, r || L(t, e, this.length);
29909
29910          for (var n = this[t], i = 1, o = 0; ++o < e && (i *= 256);) n += this[t + o] * i;
29911
29912          return n >= (i *= 128) && (n -= Math.pow(2, 8 * e)), n;
29913        }, u.prototype.readIntBE = function (t, e, r) {
29914          t |= 0, e |= 0, r || L(t, e, this.length);
29915
29916          for (var n = e, i = 1, o = this[t + --n]; n > 0 && (i *= 256);) o += this[t + --n] * i;
29917
29918          return o >= (i *= 128) && (o -= Math.pow(2, 8 * e)), o;
29919        }, u.prototype.readInt8 = function (t, e) {
29920          return e || L(t, 1, this.length), 128 & this[t] ? -1 * (255 - this[t] + 1) : this[t];
29921        }, u.prototype.readInt16LE = function (t, e) {
29922          e || L(t, 2, this.length);
29923          var r = this[t] | this[t + 1] << 8;
29924          return 32768 & r ? 4294901760 | r : r;
29925        }, u.prototype.readInt16BE = function (t, e) {
29926          e || L(t, 2, this.length);
29927          var r = this[t + 1] | this[t] << 8;
29928          return 32768 & r ? 4294901760 | r : r;
29929        }, u.prototype.readInt32LE = function (t, e) {
29930          return e || L(t, 4, this.length), this[t] | this[t + 1] << 8 | this[t + 2] << 16 | this[t + 3] << 24;
29931        }, u.prototype.readInt32BE = function (t, e) {
29932          return e || L(t, 4, this.length), this[t] << 24 | this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3];
29933        }, u.prototype.readFloatLE = function (t, e) {
29934          return e || L(t, 4, this.length), i.read(this, t, !0, 23, 4);
29935        }, u.prototype.readFloatBE = function (t, e) {
29936          return e || L(t, 4, this.length), i.read(this, t, !1, 23, 4);
29937        }, u.prototype.readDoubleLE = function (t, e) {
29938          return e || L(t, 8, this.length), i.read(this, t, !0, 52, 8);
29939        }, u.prototype.readDoubleBE = function (t, e) {
29940          return e || L(t, 8, this.length), i.read(this, t, !1, 52, 8);
29941        }, u.prototype.writeUIntLE = function (t, e, r, n) {
29942          (t = +t, e |= 0, r |= 0, n) || B(this, t, e, r, Math.pow(2, 8 * r) - 1, 0);
29943          var i = 1,
29944              o = 0;
29945
29946          for (this[e] = 255 & t; ++o < r && (i *= 256);) this[e + o] = t / i & 255;
29947
29948          return e + r;
29949        }, u.prototype.writeUIntBE = function (t, e, r, n) {
29950          (t = +t, e |= 0, r |= 0, n) || B(this, t, e, r, Math.pow(2, 8 * r) - 1, 0);
29951          var i = r - 1,
29952              o = 1;
29953
29954          for (this[e + i] = 255 & t; --i >= 0 && (o *= 256);) this[e + i] = t / o & 255;
29955
29956          return e + r;
29957        }, u.prototype.writeUInt8 = function (t, e, r) {
29958          return t = +t, e |= 0, r || B(this, t, e, 1, 255, 0), u.TYPED_ARRAY_SUPPORT || (t = Math.floor(t)), this[e] = 255 & t, e + 1;
29959        }, u.prototype.writeUInt16LE = function (t, e, r) {
29960          return t = +t, e |= 0, r || B(this, t, e, 2, 65535, 0), u.TYPED_ARRAY_SUPPORT ? (this[e] = 255 & t, this[e + 1] = t >>> 8) : P(this, t, e, !0), e + 2;
29961        }, u.prototype.writeUInt16BE = function (t, e, r) {
29962          return t = +t, e |= 0, r || B(this, t, e, 2, 65535, 0), u.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 8, this[e + 1] = 255 & t) : P(this, t, e, !1), e + 2;
29963        }, u.prototype.writeUInt32LE = function (t, e, r) {
29964          return t = +t, e |= 0, r || B(this, t, e, 4, 4294967295, 0), u.TYPED_ARRAY_SUPPORT ? (this[e + 3] = t >>> 24, this[e + 2] = t >>> 16, this[e + 1] = t >>> 8, this[e] = 255 & t) : F(this, t, e, !0), e + 4;
29965        }, u.prototype.writeUInt32BE = function (t, e, r) {
29966          return t = +t, e |= 0, r || B(this, t, e, 4, 4294967295, 0), u.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 24, this[e + 1] = t >>> 16, this[e + 2] = t >>> 8, this[e + 3] = 255 & t) : F(this, t, e, !1), e + 4;
29967        }, u.prototype.writeIntLE = function (t, e, r, n) {
29968          if (t = +t, e |= 0, !n) {
29969            var i = Math.pow(2, 8 * r - 1);
29970            B(this, t, e, r, i - 1, -i);
29971          }
29972
29973          var o = 0,
29974              a = 1,
29975              s = 0;
29976
29977          for (this[e] = 255 & t; ++o < r && (a *= 256);) t < 0 && 0 === s && 0 !== this[e + o - 1] && (s = 1), this[e + o] = (t / a >> 0) - s & 255;
29978
29979          return e + r;
29980        }, u.prototype.writeIntBE = function (t, e, r, n) {
29981          if (t = +t, e |= 0, !n) {
29982            var i = Math.pow(2, 8 * r - 1);
29983            B(this, t, e, r, i - 1, -i);
29984          }
29985
29986          var o = r - 1,
29987              a = 1,
29988              s = 0;
29989
29990          for (this[e + o] = 255 & t; --o >= 0 && (a *= 256);) t < 0 && 0 === s && 0 !== this[e + o + 1] && (s = 1), this[e + o] = (t / a >> 0) - s & 255;
29991
29992          return e + r;
29993        }, u.prototype.writeInt8 = function (t, e, r) {
29994          return t = +t, e |= 0, r || B(this, t, e, 1, 127, -128), u.TYPED_ARRAY_SUPPORT || (t = Math.floor(t)), t < 0 && (t = 255 + t + 1), this[e] = 255 & t, e + 1;
29995        }
29995, u.prototype.writeInt16LE = function (t, e, r) {
29996          return t = +t, e |= 0, r || B(this, t, e, 2, 32767, -32768), u.TYPED_ARRAY_SUPPORT ? (this[e] = 255 & t, this[e + 1] = t >>> 8) : P(this, t, e, !0), e + 2;
29997        }, u.prototype.writeInt16BE = function (t, e, r) {
29998          return t = +t, e |= 0, r || B(this, t, e, 2, 32767, -32768), u.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 8, this[e + 1] = 255 & t) : P(this, t, e, !1), e + 2;
29999        }, u.prototype.writeInt32LE = function (t, e, r) {
30000          return t = +t, e |= 0, r || B(this, t, e, 4, 2147483647, -2147483648), u.TYPED_ARRAY_SUPPORT ? (this[e] = 255 & t, this[e + 1] = t >>> 8, this[e + 2] = t >>> 16, this[e + 3] = t >>> 24) : F(this, t, e, !0), e + 4;
30001        }, u.prototype.writeInt32BE = function (t, e, r) {
30002          return t = +t, e |= 0, r || B(this, t, e, 4, 2147483647, -2147483648), t < 0 && (t = 4294967295 + t + 1), u.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 24, this[e + 1] = t >>> 16, this[e + 2] = t >>> 8, this[e + 3] = 255 & t) : F(this, t, e, !1), e + 4;
30003        }, u.prototype.writeFloatLE = function (t, e, r) {
30004          return M(this, t, e, !0, r);
30005        }, u.prototype.writeFloatBE = function (t, e, r) {
30006          return M(this, t, e, !1, r);
30007        }, u.prototype.writeDoubleLE = function (t, e, r) {
30008          return j(this, t, e, !0, r);
30009        }, u.prototype.writeDoubleBE = function (t, e, r) {
30010          return j(this, t, e, !1, r);
30011        }, u.prototype.copy = function (t, e, r, n) {
30012          if (r || (r = 0), n || 0 === n || (n = this.length), e >= t.length && (e = t.length), e || (e = 0), n > 0 && n < r && (n = r), n === r) return 0;
30013          if (0 === t.length || 0 === this.length) return 0;
30014          if (e < 0) throw new RangeError("targetStart out of bounds");
30015          if (r < 0 || r >= this.length) throw new RangeError("sourceStart out of bounds");
30016          if (n < 0) throw new RangeError("sourceEnd out of bounds");
30017          n > this.length && (n = this.length), t.length - e < n - r && (n = t.length - e + r);
30018          var i,
30019              o = n - r;
30020          if (this === t && r < e && e < n) for (i = o - 1; i >= 0; --i) t[i + e] = this[i + r];else if (o < 1e3 || !u.TYPED_ARRAY_SUPPORT) for (i = 0; i < o; ++i) t[i + e] = this[i + r];else Uint8Array.prototype.set.call(t, this.subarray(r, r + o), e);
30021          return o;
30022        }, u.prototype.fill = function (t, e, r, n) {
30023          if ("string" == typeof t) {
30024            if ("string" == typeof e ? (n = e, e = 0, r = this.length) : "string" == typeof r && (n = r, r = this.length), 1 === t.length) {
30025              var i = t.charCodeAt(0);
30026              i < 256 && (t = i);
30027            }
30028
30029            if (void 0 !== n && "string" != typeof n) throw new TypeError("encoding must be a string");
30030            if ("string" == typeof n && !u.isEncoding(n)) throw new TypeError("Unknown encoding: " + n);
30031          } else "number" == typeof t && (t &= 255);
30032
30033          if (e < 0 || this.length < e || this.length < r) throw new RangeError("Out of range index");
30034          if (r <= e) return this;
30035          var o;
30036          if (e >>>= 0, r = void 0 === r ? this.length : r >>> 0, t || (t = 0), "number" == typeof t) for (o = e; o < r; ++o) this[o] = t;else {
30037            var a = u.isBuffer(t) ? t : D(new u(t, n).toString()),
30038                s = a.length;
30039
30040            for (o = 0; o < r - e; ++o) this[o + e] = a[o % s];
30041          }
30042          return this;
30043        };
30044        var z = /[^+\/0-9A-Za-z-_]/g;
30045
30046        function U(t) {
30047          return t < 16 ? "0" + t.toString(16) : t.toString(16);
30048        }
30049
30050        function D(t, e) {
30051          var r;
30052          e = e || 1 / 0;
30053
30054          for (var n = t.length, i = null, o = [], a = 0; a < n; ++a) {
30055            if ((r = t.charCodeAt(a)) > 55295 && r < 57344) {
30056              if (!i) {
30057                if (r > 56319) {
30058                  (e -= 3) > -1 && o.push(239, 191, 189);
30059                  continue;
30060                }
30061
30062                if (a + 1 === n) {
30063                  (e -= 3) > -1 && o.push(239, 191, 189);
30064                  continue;
30065                }
30066
30067                i = r;
30068                continue;
30069              }
30070
30071              if (r < 56320) {
30072                (e -= 3) > -1 && o.push(239, 191, 189), i = r;
30073                continue;
30074              }
30075
30076              r = 65536 + (i - 55296 << 10 | r - 56320);
30077            } else i && (e -= 3) > -1 && o.push(239, 191, 189);
30078
30079            if (i = null, r < 128) {
30080              if ((e -= 1) < 0) break;
30081              o.push(r);
30082            } else if (r < 2048) {
30083              if ((e -= 2) < 0) break;
30084              o.push(r >> 6 | 192, 63 & r | 128);
30085            } else if (r < 65536) {
30086              if ((e -= 3) < 0) break;
30087              o.push(r >> 12 | 224, r >> 6 & 63 | 128, 63 & r | 128);
30088            } else {
30089              if (!(r < 1114112)) throw new Error("Invalid code point");
30090              if ((e -= 4) < 0) break;
30091              o.push(r >> 18 | 240, r >> 12 & 63 | 128, r >> 6 & 63 | 128, 63 & r | 128);
30092            }
30093          }
30094
30095          return o;
30096        }
30097
30098        function q(t) {
30099          return n.toByteArray(function (t) {
30100            if ((t = function (t) {
30101              return t.trim ? t.trim() : t.replace(/^\s+|\s+$/g, "");
30102            }(t).replace(z, "")).length < 2) return "";
30103
30104            for (; t.length % 4 != 0;) t += "=";
30105
30106            return t;
30107          }(t));
30108        }
30109
30110        function Z(t, e, r, n) {
30111          for (var i = 0; i < n && !(i + r >= e.length || i >= t.length); ++i) e[i + r] = t[i];
30112
30113          return i;
30114        }
30115      }).call(this, r(23));
30116    }, function (t, e, r) {
30117      var n = r(17),
30118          i = r(21),
30119          o = r(43);
30120      t.exports = n ? function (t, e, r) {
30121        return i.f(t, e, o(1, r));
30122      } : function (t, e, r) {
30123        return t[e] = r, t;
30124      };
30125    }, function (t, e, r) {
30126      var n = r(17),
30127          i = r(106),
30128          o = r(2),
30129          a = r(62),
30130          s = Object.defineProperty;
30131      e.f = n ? s : function (t, e, r) {
30132        if (o(t), e = a(e, !0), o(r), i) try {
30133          return s(t, e, r);
30134        } catch (t) {}
30135        if ("get" in r || "set" in r) throw TypeError("Accessors not supported");
30136        return "value" in r && (t[e] = r.value), t;
30137      };
30138    }, function (t, e, r) {
30139      var n = r(49);
30140
30141      t.exports = function (t) {
30142        return Object(n(t));
30143      };
30144    }, function (t, e) {
30145      var r;
30146
30147      r = function () {
30148        return this;
30149      }();
30150
30151      try {
30152        r = r || new Function("return this")();
30153      } catch (t) {
30154        "object" == typeof window && (r = window);
30155      }
30156
30157      t.exports = r;
30158    }, function (t, e) {
30159      var r = {}.hasOwnProperty;
30160
30161      t.exports = function (t, e) {
30162        return r.call(t, e);
30163      };
30164    }, function (t, e, r) {
30165      var n = r(4),
30166          i = r(142);
30167      t.exports = n ? i : function (t) {
30168        return Map.prototype.entries.call(t);
30169      };
30170    }, function (t, e, r) {
30171      var n = r(3),
30172          i = r(13),
30173          o = function (t) {
30174        return "function" == typeof t ? t : void 0;
30175      };
30176
30177      t.exports = function (t, e) {
30178        return arguments.length < 2 ? o(n[t]) || o(i[t]) : n[t] && n[t][e] || i[t] && i[t][e];
30179      };
30180    }, function (t, e, r) {
30181      var n = r(255),
30182          i = r(139);
30183
30184      function o(e) {
30185        return t.exports = o = i ? n : function (t) {
30186          return t.__proto__ || n(t);
30187        }, o(e);
30188      }
30189
30190      t.exports = o;
30191    }, function (t, e, r) {
30192      var n = r(60),
30193          i = r(49);
30194
30195      t.exports = function (t) {
30196        return n(i(t));
30197      };
30198    }, function (t, e, r) {
30199      var n = r(83),
30200          i = Math.min;
30201
30202      t.exports = function (t) {
30203        return t > 0 ? i(n(t), 9007199254740991) : 0;
30204      };
30205    }, function (t, e, r) {
30206      t.exports = r(184);
30207    }, function (t, e, r) {
30208      var n = r(185);
30209
30210      function i(t, e, r, i, o, a, s) {
30211        try {
30212          var u = t[a](s),
30213              f = u.value;
30214        } catch (t) {
30215          return void r(t);
30216        }
30217
30218        u.done ? e(f) : n.resolve(f).then(i, o);
30219      }
30220
30221      t.exports = function (t) {
30222        return function () {
30223          var e = this,
30224              r = arguments;
30225          return new n(function (n, o) {
30226            var a = t.apply(e, r);
30227
30228            function s(t) {
30229              i(a, n, o, s, u, "next", t);
30230            }
30231
30232            function u(t) {
30233              i(a, n, o, s, u, "throw", t);
30234            }
30235
30236            s(void 0);
30237          });
30238        };
30239      };
30240    }, function (t, e, r) {
30241      var n = r(225),
30242          i = r(254);
30243
30244      t.exports = function (t, e) {
30245        return !e || "object" !== n(e) && "function" != typeof e ? i(t) : e;
30246      };
30247    }, function (t, e, r) {
30248      var n = r(140),
30249          i = r(96);
30250
30251      t.exports = function (t, e) {
30252        if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
30253        t.prototype = n(e && e.prototype, {
30254          constructor: {
30255            value: t,
30256            writable: !0,
30257            configurable: !0
30258          }
30259        }), e && i(t, e);
30260      };
30261    }, function (t, e) {
30262      var r = {}.toString;
30263
30264      t.exports = function (t) {
30265        return r.call(t).slice(8, -1);
30266      };
30267    }, function (t, e) {
30268      t.exports = {};
30269    }, function (t, e, r) {
30270      var n = r(21).f,
30271          i = r(20),
30272          o = r(24),
30273          a = r(174),
30274          s = r(6)("toStringTag"),
30275          u = a !== {}.toString;
30276
30277      t.exports = function (t, e, r, f) {
30278        if (t) {
30279          var c = r ? t : t.prototype;
30280          o(c, s) || n(c, s, {
30281            configurable: !0,
30282            value: e
30283          }), f && u && i(c, "toString", a);
30284        }
30285      };
30286    }, function (t, e, r) {
30287      t.exports = r(181);
30288    }, function (t, e) {
30289      var r,
30290          n,
30291          i = t.exports = {};
30292
30293      function o() {
30294        throw new Error("setTimeout has not been defined");
30295      }
30296
30297      function a() {
30298        throw new Error("clearTimeout has not been defined");
30299      }
30300
30301      function s(t) {
30302        if (r === setTimeout) return setTimeout(t, 0);
30303        if ((r === o || !r) && setTimeout) return r = setTimeout, setTimeout(t, 0);
30304
30305        try {
30306          return r(t, 0);
30307        } catch (e) {
30308          try {
30309            return r.call(null, t, 0);
30310          } catch (e) {
30311            return r.call(this, t, 0);
30312          }
30313        }
30314      }
30315
30316      !function () {
30317        try {
30318          r = "function" == typeof setTimeout ? setTimeout : o;
30319        } catch (t) {
30320          r = o;
30321        }
30322
30323        try {
30324          n = "function" == typeof clearTimeout ? clearTimeout : a;
30325        } catch (t) {
30326          n = a;
30327        }
30328      }();
30329      var u,
30330          f = [],
30331          c = !1,
30332          l = -1;
30333
30334      function h() {
30335        c && u && (c = !1, u.length ? f = u.concat(f) : l = -1, f.length && d());
30336      }
30337
30338      function d() {
30339        if (!c) {
30340          var t = s(h);
30341          c = !0;
30342
30343          for (var e = f.length; e;) {
30344            for (u = f, f = []; ++l < e;) u && u[l].run();
30345
30346            l = -1, e = f.length;
30347          }
30348
30349          u = null, c = !1, function (t) {
30350            if (n === clearTimeout) return clearTimeout(t);
30351            if ((n === a || !n) && clearTimeout) return n = clearTimeout, clearTimeout(t);
30352
30353            try {
30354              n(t);
30355            } catch (e) {
30356              try {
30357                return n.call(null, t);
30358              } catch (e) {
30359                return n.call(this, t);
30360              }
30361            }
30362          }(t);
30363        }
30364      }
30365
30366      function p(t, e) {
30367        this.fun = t, this.array = e;
30368      }
30369
30370      function g() {}
30371
30372      i.nextTick = function (t) {
30373        var e = new Array(arguments.length - 1);
30374        if (arguments.length > 1) for (var r = 1; r < arguments.length; r++) e[r - 1] = arguments[r];
30375        f.push(new p(t, e)), 1 !== f.length || c || s(d);
30376      }, p.prototype.run = function () {
30377        this.fun.apply(null, this.array);
30378      }, i.title = "browser", i.browser = !0, i.env = {}, i.argv = [], i.version = "", i.versions = {}, i.on = g, i.addListener = g, i.once = g, i.off = g, i.removeListener = g, i.removeAllListeners = g, i.emit = g, i.prependListener = g, i.prependOnceListener = g, i.listeners = function (t) {
30379        return [];
30380      }, i.binding = function (t) {
30381        throw new Error("process.binding is not supported");
30382      }, i.cwd = function () {
30383        return "/";
30384      }, i.chdir = function (t) {
30385        throw new Error("process.chdir is not supported");
30386      }, i.umask = function () {
30387        return 0;
30388      };
30389    }, function (t, e, r) {
30390
30391      var n = r(70),
30392          i = Object.keys || function (t) {
30393        var e = [];
30394
30395        for (var r in t) e.push(r);
30396
30397        return e;
30398      };
30399
30400      t.exports = l;
30401      var o = r(57);
30402      o.inherits = r(47);
30403      var a = r(127),
30404          s = r(93);
30405      o.inherits(l, a);
30406
30407      for (var u = i(s.prototype), f = 0; f < u.length; f++) {
30408        var c = u[f];
30409        l.prototype[c] || (l.prototype[c] = s.prototype[c]);
30410      }
30411
30412      function l(t) {
30413        if (!(this instanceof l)) return new l(t);
30414        a.call(this, t), s.call(this, t), t && !1 === t.readable && (this.readable = !1), t && !1 === t.writable && (this.writable = !1), this.allowHalfOpen = !0, t && !1 === t.allowHalfOpen && (this.allowHalfOpen = !1), this.once("end", h);
30415      }
30416
30417      function h() {
30418        this.allowHalfOpen || this._writableState.ended || n.nextTick(d, this);
30419      }
30420
30421      function d(t) {
30422        t.end();
30423      }
30424
30425      Object.defineProperty(l.prototype, "writableHighWaterMark", {
30426        enumerable: !1,
30427        get: function () {
30428          return this._writableState.highWaterMark;
30429        }
30430      }), Object.defineProperty(l.prototype, "destroyed", {
30431        get: function () {
30432          return void 0 !== this._readableState && void 0 !== this._writableState && this._readableState.destroyed && this._writableState.destroyed;
30433        },
30434        set: function (t) {
30435          void 0 !== this._readableState && void 0 !== this._writableState && (this._readableState.destroyed = t, this._writableState.destroyed = t);
30436        }
30437      }), l.prototype._destroy = function (t, e) {
30438        this.push(null), this.end(), n.nextTick(e, t);
30439      };
30440    }, function (t, e, r) {
30441
30442      var n = r(1),
30443          i = n(r(7)),
30444          o = n(r(10)),
30445          a = r(9).CramBufferOverrunError,
30446          s = {
30447        int: !0,
30448        byte: !0,
30449        long: !0,
30450        byteArray: !0,
30451        byteArrayBlock: !0
30452      },
30453          u = function () {
30454        function t() {
30455          var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
30456              r = arguments.length > 1 ? arguments[1] : void 0;
30457          if ((0, i.default)(this, t), this.parameters = e, this.dataType = r, !r) throw new TypeError("must provide a data type to codec constructor");
30458          if (!s[r]) throw new TypeError("invalid data type ".concat(r));
30459        }
30460
30461        return (0, o.default)(t, [{
30462          key: "_getBits",
30463          value: function (t, e, r) {
30464            var n = 0;
30465            if (e.bytePosition + (7 - e.bitPosition + r) / 8 > t.length) throw new a("read error during decoding. the file seems to be truncated.");
30466
30467            for (var i = r; i; i -= 1) n <<= 1, n |= t[e.bytePosition] >> e.bitPosition & 1, e.bitPosition -= 1, e.bitPosition < 0 && (e.bytePosition += 1), e.bitPosition &= 7;
30468
30469            return n;
30470          }
30471        }]), t;
30472      }();
30473
30474      t.exports = u;
30475    }, function (t, e, r) {
30476      r(168);
30477      var n = r(176),
30478          i = r(13),
30479          o = r(20),
30480          a = r(35),
30481          s = r(6)("toStringTag");
30482
30483      for (var u in n) {
30484        var f = i[u],
30485            c = f && f.prototype;
30486        c && !c[s] && o(c, s, u), a[u] = a.Array;
30487      }
30488    }, function (t, e, r) {
30489      var n,
30490          i,
30491          o,
30492          a = r(169),
30493          s = r(13),
30494          u = r(14),
30495          f = r(20),
30496          c = r(24),
30497          l = r(63),
30498          h = r(50),
30499          d = s.WeakMap;
30500
30501      if (a) {
30502        var p = new d(),
30503            g = p.get,
30504            v = p.has,
30505            y = p.set;
30506        n = function (t, e) {
30507          return y.call(p, t, e), e;
30508        }, i = function (t) {
30509          return g.call(p, t) || {};
30510        }, o = function (t) {
30511          return v.call(p, t);
30512        };
30513      } else {
30514        var m = l("state");
30515        h[m] = !0, n = function (t, e) {
30516          return f(t, m, e), e;
30517        }, i = function (t) {
30518          return c(t, m) ? t[m] : {};
30519        }, o = function (t) {
30520          return c(t, m);
30521        };
30522      }
30523
30524      t.exports = {
30525        set: n,
30526        get: i,
30527        has: o,
30528        enforce: function (t) {
30529          return o(t) ? i(t) : n(t, {});
30530        },
30531        getterFor: function (t) {
30532          return function (e) {
30533            var r;
30534            if (!u(e) || (r = i(e)).type !== t) throw TypeError("Incompatible receiver, " + t + " required");
30535            return r;
30536          };
30537        }
30538      };
30539    }, function (t, e) {
30540      t.exports = function (t, e) {
30541        return {
30542          enumerable: !(1 & t),
30543          configurable: !(2 & t),
30544          writable: !(4 & t),
30545          value: e
30546        };
30547      };
30548    }, function (t, e, r) {
30549      var n = r(2),
30550          i = r(173),
30551          o = r(85),
30552          a = r(50),
30553          s = r(112),
30554          u = r(79),
30555          f = r(63)("IE_PROTO"),
30556          c = function () {},
30557          l = function () {
30558        var t,
30559            e = u("iframe"),
30560            r = o.length;
30561
30562        for (e.style.display = "none", s.appendChild(e), e.src = String("javascript:"), (t = e.contentWindow.document).open(), t.write("
30562<script>document.F=Object<\/script>"), t.close(), l = t.F; r--;) delete l.prototype[o[r]];
30563
30564        return l();
30565      };
30566
30567      t.exports = Object.create || function (t, e) {
30568        var r;
30569        return null !== t ? (c.prototype = n(t), r = new c(), c.prototype = null, r[f] = t) : r = l(), void 0 === e ? r : i(r, e);
30570      }, a[f] = !0;
30571    }, function (t, e, r) {
30572      var n = r(15),
30573          i = r(60),
30574          o = r(22),
30575          a = r(29),
30576          s = r(113),
30577          u = [].push,
30578          f = function (t) {
30579        var e = 1 == t,
30580            r = 2 == t,
30581            f = 3 == t,
30582            c = 4 == t,
30583            l = 6 == t,
30584            h = 5 == t || l;
30585        return function (d, p, g, v) {
30586          for (var y, m, b = o(d), _ = i(b), w = n(p, g, 3), x = a(_.length), E = 0, S = v || s, k = e ? S(d, x) : r ? S(d, 0) : void 0; x > E; E++) if ((h || E in _) && (m = w(y = _[E], E, b), t)) if (e) k[E] = m;else if (m) switch (t) {
30587            case 3:
30588              return !0;
30589
30590            case 5:
30591              return y;
30592
30593            case 6:
30594              return E;
30595
30596            case 2:
30597              u.call(k, y);
30598          } else if (c) return !1;
30599
30600          return l ? -1 : f || c ? c : k;
30601        };
30602      };
30603
30604      t.exports = {
30605        forEach: f(0),
30606        map: f(1),
30607        filter: f(2),
30608        some: f(3),
30609        every: f(4),
30610        find: f(5),
30611        findIndex: f(6)
30612      };
30613    }, function (t, e, r) {
30614
30615      var n = r(187).charAt,
30616          i = r(42),
30617          o = r(80),
30618          a = i.set,
30619          s = i.getterFor("String Iterator");
30620      o(String, "String", function (t) {
30621        a(this, {
30622          type: "String Iterator",
30623          string: String(t),
30624          index: 0
30625        });
30626      }, function () {
30627        var t,
30628            e = s(this),
30629            r = e.string,
30630            i = e.index;
30631        return i >= r.length ? {
30632          value: void 0,
30633          done: !0
30634        } : (t = n(r, i), e.index += t.length, {
30635          value: t,
30636          done: !1
30637        });
30638      });
30639    }, function (t, e) {
30640      "function" == typeof Object.create ? t.exports = function (t, e) {
30641        e && (t.super_ = e, t.prototype = Object.create(e.prototype, {
30642          constructor: {
30643            value: t,
30644            enumerable: !1,
30645            writable: !0,
30646            configurable: !0
30647          }
30648        }));
30649      } : t.exports = function (t, e) {
30650        if (e) {
30651          t.super_ = e;
30652
30653          var r = function () {};
30654
30655          r.prototype = e.prototype, t.prototype = new r(), t.prototype.constructor = t;
30656        }
30657      };
30658    }, function (t, e, r) {
30659      var n = r(157),
30660          i = r(384),
30661          o = r(158);
30662
30663      t.exports = function (t, e) {
30664        return n(t) || i(t, e) || o();
30665      };
30666    }, function (t, e) {
30667      t.exports = function (t) {
30668        if (null == t) throw TypeError("Can't call method on " + t);
30669        return t;
30670      };
30671    }, function (t, e) {
30672      t.exports = {};
30673    }, function (t, e, r) {
30674      var n = r(111),
30675          i = r(85);
30676
30677      t.exports = Object.keys || function (t) {
30678        return n(t, i);
30679      };
30680    }, function (t, e, r) {
30681      var n = r(20);
30682
30683      t.exports = function (t, e, r, i) {
30684        i && i.enumerable ? t[e] = r : n(t, e, r);
30685      };
30686    }, function (t, e, r) {
30687      var n = r(34);
30688
30689      t.exports = Array.isArray || function (t) {
30690        return "Array" == n(t);
30691      };
30692    }, function (t, e, r) {
30693
30694      var n = r(12);
30695
30696      t.exports = function (t, e) {
30697        var r = [][t];
30698        return !r || !n(function () {
30699          r.call(null, e || function () {
30700            throw 1;
30701          }, 1);
30702        });
30703      };
30704    }, function (t, e, r) {
30705      var n = r(2),
30706          i = r(5),
30707          o = r(6)("species");
30708
30709      t.exports = function (t, e) {
30710        var r,
30711            a = n(t).constructor;
30712        return void 0 === a || null == (r = n(a)[o]) ? e : i(r);
30713      };
30714    }, function (t, e, r) {
30715
30716      var n = r(5),
30717          i = function (t) {
30718        var e, r;
30719        this.promise = new t(function (t, n) {
30720          if (void 0 !== e || void 0 !== r) throw TypeError("Bad Promise constructor");
30721          e = t, r = n;
30722        }), this.resolve = n(e), this.reject = n(r);
30723      };
30724
30725      t.exports.f = function (t) {
30726        return new i(t);
30727      };
30728    }, function (t, e, r) {
30729      (function (t) {
30730        function r(t) {
30731          return Object.prototype.toString.call(t);
30732        }
30733
30734        e.isArray = function (t) {
30735          return Array.isArray ? Array.isArray(t) : "[object Array]" === r(t);
30736        }, e.isBoolean = function (t) {
30737          return "boolean" == typeof t;
30738        }, e.isNull = function (t) {
30739          return null === t;
30740        }, e.isNullOrUndefined = function (t) {
30741          return null == t;
30742        }, e.isNumber = function (t) {
30743          return "number" == typeof t;
30744        }, e.isString = function (t) {
30745          return "string" == typeof t;
30746        }, e.isSymbol = function (t) {
30747          return "symbol" == typeof t;
30748        }, e.isUndefined = function (t) {
30749          return void 0 === t;
30750        }, e.isRegExp = function (t) {
30751          return "[object RegExp]" === r(t);
30752        }, e.isObject = function (t) {
30753          return "object" == typeof t && null !== t;
30754        }, e.isDate = function (t) {
30755          return "[object Date]" === r(t);
30756        }, e.isError = function (t) {
30757          return "[object Error]" === r(t) || t instanceof Error;
30758        }, e.isFunction = function (t) {
30759          return "function" == typeof t;
30760        }, e.isPrimitive = function (t) {
30761          return null === t || "boolean" == typeof t || "number" == typeof t || "string" == typeof t || "symbol" == typeof t || void 0 === t;
30762        }, e.isBuffer = t.isBuffer;
30763      }).call(this, r(19).Buffer);
30764    }, function (t, e, r) {
30765
30766      var n = r(1)(r(76)),
30767          i = r(331),
30768          o = r(9).CramBufferOverrunError;
30769      t.exports = {
30770        itf8Size: function (t) {
30771          return -128 & t ? -16384 & t ? -2097152 & t ? -268435456 & t ? 5 : 4 : 3 : 2 : 1;
30772        },
30773        parseItf8: function (t, e) {
30774          var r,
30775              n = e,
30776              i = t[n];
30777          if (i < 128 ? (r = i, n += 1) : i < 192 ? (r = 16383 & (i << 8 | t[n + 1]), n += 2) : i < 224 ? (r = 2097151 & (i << 16 | t[n + 1] << 8 | t[n + 2]), n += 3) : i < 240 ? (r = 268435455 & (i << 24 | t[n + 1] << 16 | t[n + 2] << 8 | t[n + 3]), n += 4) : (r = (15 & i) << 28 | t[n + 1] << 20 | t[n + 2] << 12 | t[n + 3] << 4 | 15 & t[n + 4], n += 5), n > t.length) throw new o("Attempted to read beyond end of buffer; this file seems truncated.");
30778          return [r, n - e];
30779        },
30780        parseItem: function (t, e) {
30781          var r = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : 0,
30782              n = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : 0,
30783              i = e.parse(t),
30784              o = i.offset,
30785              a = i.result;
30786          return a._endPosition = o + n, a._size = o - r, a;
30787        },
30788        tinyMemoize: function (t, e) {
30789          var r = t.prototype[e],
30790              i = "_memo_".concat(e);
30791
30792          t.prototype[e] = function () {
30793            var t = this;
30794
30795            if (!(i in this)) {
30796              var e = r.call(this);
30797              this[i] = e, n.default.resolve(e).catch(function () {
30798                delete t[i];
30799              });
30800            }
30801
30802            return this[i];
30803          };
30804        },
30805        sequenceMD5: function (t) {
30806          return i(t.toUpperCase().replace(/[^\x21-\x7e]/g, ""));
30807        }
30808      };
30809    }, function (t, e, r) {
30810      var n = r(351),
30811          i = r(152),
30812          o = r(362);
30813
30814      t.exports = function (t) {
30815        return n(t) || i(t) || o();
30816      };
30817    }, function (t, e, r) {
30818      var n = r(12),
30819          i = r(34),
30820          o = "".split;
30821      t.exports = n(function () {
30822        return !Object("z").propertyIsEnumerable(0);
30823      }) ? function (t) {
30824        return "String" == i(t) ? o.call(t, "") : Object(t);
30825      } : Object;
30826    }, function (t, e, r) {
30827      var n = r(13),
30828          i = r(171),
30829          o = r(4),
30830          a = n["__core-js_shared__"] || i("__core-js_shared__", {});
30831      (t.exports = function (t, e) {
30832        return a[t] || (a[t] = void 0 !== e ? e : {});
30833      })("versions", []).push({
30834        version: "3.2.1",
30835        mode: o ? "pure" : "global",
30836        copyright: "© 2019 Denis Pushkarev (zloirock.ru)"
30837      });
30838    }, function (t, e, r) {
30839      var n = r(14);
30840
30841      t.exports = function (t, e) {
30842        if (!n(t)) return t;
30843        var r, i;
30844        if (e && "function" == typeof (r = t.toString) && !n(i = r.call(t))) return i;
30845        if ("function" == typeof (r = t.valueOf) && !n(i = r.call(t))) return i;
30846        if (!e && "function" == typeof (r = t.toString) && !n(i = r.call(t))) return i;
30847        throw TypeError("Can't convert object to primitive value");
30848      };
30849    }, function (t, e, r) {
30850      var n = r(61),
30851          i = r(64),
30852          o = n("keys");
30853
30854      t.exports = function (t) {
30855        return o[t] || (o[t] = i(t));
30856      };
30857    }, function (t, e) {
30858      var r = 0,
30859          n = Math.random();
30860
30861      t.exports = function (t) {
30862        return "Symbol(" + String(void 0 === t ? "" : t) + ")_" + (++r + n).toString(36);
30863      };
30864    }, function (t, e, r) {
30865
30866      var n = {}.propertyIsEnumerable,
30867          i = Object.getOwnPropertyDescriptor,
30868          o = i && !n.call({
30869        1: 2
30870      }, 1);
30871      e.f = o ? function (t) {
30872        var e = i(this, t);
30873        return !!e && e.enumerable;
30874      } : n;
30875    }, function (t, e, r) {
30876      var n = r(24),
30877          i = r(22),
30878          o = r(63),
30879          a = r(109),
30880          s = o("IE_PROTO"),
30881          u = Object.prototype;
30882      t.exports = a ? Object.getPrototypeOf : function (t) {
30883        return t = i(t), n(t, s) ? t[s] : "function" == typeof t.constructor && t instanceof t.constructor ? t.constructor.prototype : t instanceof Object ? u : null;
30884      };
30885    }, function (t, e, r) {
30886      var n = r(34),
30887          i = r(6)("toStringTag"),
30888          o = "Arguments" == n(function () {
30889        return arguments;
30890      }());
30891
30892      t.exports = function (t) {
30893        var e, r, a;
30894        return void 0 === t ? "Undefined" : null === t ? "Null" : "string" == typeof (r = function (t, e) {
30895          try {
30896            return t[e];
30897          } catch (t) {}
30898        }(e = Object(t), i)) ? r : o ? n(e) : "Object" == (a = n(e)) && "function" == typeof e.callee ? "Arguments" : a;
30899      };
30900    }, function (t, e, r) {
30901      var n = r(12),
30902          i = r(6)("species");
30903
30904      t.exports = function (t) {
30905        return !n(function () {
30906          var e = [];
30907          return (e.constructor = {})[i] = function () {
30908            return {
30909              foo: 1
30910            };
30911          }, 1 !== e[t](Boolean).foo;
30912        });
30913      };
30914    }, function (t, e) {
30915      t.exports = function (t) {
30916        try {
30917          return {
30918            error: !1,
30919            value: t()
30920          };
30921        } catch (t) {
30922          return {
30923            error: !0,
30924            value: t
30925          };
30926        }
30927      };
30928    }, function (t, e, r) {
30929
30930      (function (e) {
30931        void 0 === e || !e.version || 0 === e.version.indexOf("v0.") || 0 === e.version.indexOf("v1.") && 0 !== e.version.indexOf("v1.8.") ? t.exports = {
30932          nextTick: function (t, r, n, i) {
30933            if ("function" != typeof t) throw new TypeError('"callback" argument must be a function');
30934            var o,
30935                a,
30936                s = arguments.length;
30937
30938            switch (s) {
30939              case 0:
30940              case 1:
30941                return e.nextTick(t);
30942
30943              case 2:
30944                return e.nextTick(function () {
30945                  t.call(null, r);
30946                });
30947
30948              case 3:
30949                return e.nextTick(function () {
30950                  t.call(null, r, n);
30951                });
30952
30953              case 4:
30954                return e.nextTick(function () {
30955                  t.call(null, r, n, i);
30956                });
30957
30958              default:
30959                for (o = new Array(s - 1), a = 0; a < o.length;) o[a++] = arguments[a];
30960
30961                return e.nextTick(function () {
30962                  t.apply(null, o);
30963                });
30964            }
30965          }
30966        } : t.exports = e;
30967      }).call(this, r(38));
30968    }, function (t, e, r) {
30969      var n = r(19),
30970          i = n.Buffer;
30971
30972      function o(t, e) {
30973        for (var r in t) e[r] = t[r];
30974      }
30975
30976      function a(t, e, r) {
30977        return i(t, e, r);
30978      }
30979
30980      i.from && i.alloc && i.allocUnsafe && i.allocUnsafeSlow ? t.exports = n : (o(n, e), e.Buffer = a), o(i, a), a.from = function (t, e, r) {
30981        if ("number" == typeof t) throw new TypeError("Argument must not be a number");
30982        return i(t, e, r);
30983      }, a.alloc = function (t, e, r) {
30984        if ("number" != typeof t) throw new TypeError("Argument must be a number");
30985        var n = i(t);
30986        return void 0 !== e ? "string" == typeof r ? n.fill(e, r) : n.fill(e) : n.fill(0), n;
30987      }, a.allocUnsafe = function (t) {
30988        if ("number" != typeof t) throw new TypeError("Argument must be a number");
30989        return i(t);
30990      }, a.allocUnsafeSlow = function (t) {
30991        if ("number" != typeof t) throw new TypeError("Argument must be a number");
30992        return n.SlowBuffer(t);
30993      };
30994    }, function (t, e, r) {
30995
30996      var n = "undefined" != typeof Uint8Array && "undefined" != typeof Uint16Array && "undefined" != typeof Int32Array;
30997
30998      function i(t, e) {
30999        return Object.prototype.hasOwnProperty.call(t, e);
31000      }
31001
31002      e.assign = function (t) {
31003        for (var e = Array.prototype.slice.call(arguments, 1); e.length;) {
31004          var r = e.shift();
31005
31006          if (r) {
31007            if ("object" != typeof r) throw new TypeError(r + "must be non-object");
31008
31009            for (var n in r) i(r, n) && (t[n] = r[n]);
31010          }
31011        }
31012
31013        return t;
31014      }, e.shrinkBuf = function (t, e) {
31015        return t.length === e ? t : t.subarray ? t.subarray(0, e) : (t.length = e, t);
31016      };
31017      var o = {
31018        arraySet: function (t, e, r, n, i) {
31019          if (e.subarray && t.subarray) t.set(e.subarray(r, r + n), i);else for (var o = 0; o < n;
31019 o++) t[i + o] = e[r + o];
31020        },
31021        flattenChunks: function (t) {
31022          var e, r, n, i, o, a;
31023
31024          for (n = 0, e = 0, r = t.length; e < r; e++) n += t[e].length;
31025
31026          for (a = new Uint8Array(n), i = 0, e = 0, r = t.length; e < r; e++) o = t[e], a.set(o, i), i += o.length;
31027
31028          return a;
31029        }
31030      },
31031          a = {
31032        arraySet: function (t, e, r, n, i) {
31033          for (var o = 0; o < n; o++) t[i + o] = e[r + o];
31034        },
31035        flattenChunks: function (t) {
31036          return [].concat.apply([], t);
31037        }
31038      };
31039      e.setTyped = function (t) {
31040        t ? (e.Buf8 = Uint8Array, e.Buf16 = Uint16Array, e.Buf32 = Int32Array, e.assign(e, o)) : (e.Buf8 = Array, e.Buf16 = Array, e.Buf32 = Array, e.assign(e, a));
31041      }, e.setTyped(n);
31042    }, function (t, e, r) {
31043
31044      var n = r(1)(r(7)),
31045          i = r(9).CramMalformedError,
31046          o = r(74),
31047          a = function t() {
31048        (0, n.default)(this, t), this.F = void 0, this.C = void 0;
31049      };
31050
31051      function s(t, e, r, n) {
31052        return r * (t >> n) + (t & (1 << n) - 1) - e;
31053      }
31054
31055      var u = {
31056        FC: a,
31057        AriDecoder: function t() {
31058          (0, n.default)(this, t), this.fc = new Array(256);
31059
31060          for (var e = 0; e < this.fc.length; e += 1) this.fc[e] = new a();
31061
31062          this.R = null;
31063        },
31064        Symbol: function t() {
31065          (0, n.default)(this, t), this.start = void 0, this.freq = void 0;
31066        },
31067        symbolInit: function (t, e, r) {
31068          if (!(e <= 65536)) throw new i("assertion failed: start <= 1<<16");
31069          if (!(r <= 65536 - e)) throw new i("assertion failed: freq <= 1<<16");
31070          t.start = e, t.freq = r;
31071        },
31072        advanceStep: s,
31073        advanceSymbolStep: function (t, e, r) {
31074          return s(t, e.start, e.freq, r);
31075        },
31076        get: function (t, e) {
31077          return t & (1 << e) - 1;
31078        },
31079        advanceSymbol: function (t, e, r, n) {
31080          return function (t, e, r, n, i) {
31081            if ((t = n * (t >> i) + (t & (1 << i) - 1) - r) < o.RANS_BYTE_L) do {
31082              t = t << 8 | 255 & e.get();
31083            } while (t < o.RANS_BYTE_L);
31084            return t;
31085          }(t, e, r.start, r.freq, n);
31086        },
31087        renormalize: function (t, e) {
31088          if (t < o.RANS_BYTE_L) do {
31089            t = t << 8 | 255 & e.get();
31090          } while (t < o.RANS_BYTE_L);
31091          return t;
31092        }
31093      };
31094      t.exports = u;
31095    }, function (t, e, r) {
31096
31097      t.exports = {
31098        TF_SHIFT: 12,
31099        TOTFREQ: 4096,
31100        RANS_BYTE_L: 1 << 23
31101      };
31102    }, function (t, e, r) {
31103      t.exports = r(322);
31104    }, function (t, e, r) {
31105      t.exports = r(330);
31106    }, function (t, e, r) {
31107      t.exports = r(347);
31108    }, function (t, e) {
31109      t.exports = function () {};
31110    }, function (t, e, r) {
31111      var n = r(13),
31112          i = r(14),
31113          o = n.document,
31114          a = i(o) && i(o.createElement);
31115
31116      t.exports = function (t) {
31117        return a ? o.createElement(t) : {};
31118      };
31119    }, function (t, e, r) {
31120
31121      var n = r(0),
31122          i = r(172),
31123          o = r(66),
31124          a = r(86),
31125          s = r(36),
31126          u = r(20),
31127          f = r(52),
31128          c = r(6),
31129          l = r(4),
31130          h = r(35),
31131          d = r(108),
31132          p = d.IteratorPrototype,
31133          g = d.BUGGY_SAFARI_ITERATORS,
31134          v = c("iterator"),
31135          y = function () {
31136        return this;
31137      };
31138
31139      t.exports = function (t, e, r, c, d, m, b) {
31140        i(r, e, c);
31141
31142        var _,
31143            w,
31144            x,
31145            E = function (t) {
31146          if (t === d && T) return T;
31147          if (!g && t in A) return A[t];
31148
31149          switch (t) {
31150            case "keys":
31151            case "values":
31152            case "entries":
31153              return function () {
31154                return new r(this, t);
31155              };
31156          }
31157
31158          return function () {
31159            return new r(this);
31160          };
31161        },
31162            S = e + " Iterator",
31163            k = !1,
31164            A = t.prototype,
31165            C = A[v] || A["@@iterator"] || d && A[d],
31166            T = !g && C || E(d),
31167            R = "Array" == e && A.entries || C;
31168
31169        if (R && (_ = o(R.call(new t())), p !== Object.prototype && _.next && (l || o(_) === p || (a ? a(_, p) : "function" != typeof _[v] && u(_, v, y)), s(_, S, !0, !0), l && (h[S] = y))), "values" == d && C && "values" !== C.name && (k = !0, T = function () {
31170          return C.call(this);
31171        }), l && !b || A[v] === T || u(A, v, T), h[e] = T, d) if (w = {
31172          values: E("values"),
31173          keys: m ? T : E("keys"),
31174          entries: E("entries")
31175        }, b) for (x in w) !g && !k && x in A || f(A, x, w[x]);else n({
31176          target: e,
31177          proto: !0,
31178          forced: g || k
31179        }, w);
31180        return w;
31181      };
31182    }, function (t, e, r) {
31183      var n = r(17),
31184          i = r(65),
31185          o = r(43),
31186          a = r(28),
31187          s = r(62),
31188          u = r(24),
31189          f = r(106),
31190          c = Object.getOwnPropertyDescriptor;
31191      e.f = n ? c : function (t, e) {
31192        if (t = a(t), e = s(e, !0), f) try {
31193          return c(t, e);
31194        } catch (t) {}
31195        if (u(t, e)) return o(!i.f.call(t, e), t[e]);
31196      };
31197    }, function (t, e, r) {
31198      var n = r(28),
31199          i = r(29),
31200          o = r(84),
31201          a = function (t) {
31202        return function (e, r, a) {
31203          var s,
31204              u = n(e),
31205              f = i(u.length),
31206              c = o(a, f);
31207
31208          if (t && r != r) {
31209            for (; f > c;) if ((s = u[c++]) != s) return !0;
31210          } else for (; f > c; c++) if ((t || c in u) && u[c] === r) return t || c || 0;
31211
31212          return !t && -1;
31213        };
31214      };
31215
31216      t.exports = {
31217        includes: a(!0),
31218        indexOf: a(!1)
31219      };
31220    }, function (t, e) {
31221      var r = Math.ceil,
31222          n = Math.floor;
31223
31224      t.exports = function (t) {
31225        return isNaN(t = +t) ? 0 : (t > 0 ? n : r)(t);
31226      };
31227    }, function (t, e, r) {
31228      var n = r(83),
31229          i = Math.max,
31230          o = Math.min;
31231
31232      t.exports = function (t, e) {
31233        var r = n(t);
31234        return r < 0 ? i(r + e, 0) : o(r, e);
31235      };
31236    }, function (t, e) {
31237      t.exports = ["constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf"];
31238    }, function (t, e, r) {
31239      var n = r(2),
31240          i = r(175);
31241      t.exports = Object.setPrototypeOf || ("__proto__" in {} ? function () {
31242        var t,
31243            e = !1,
31244            r = {};
31245
31246        try {
31247          (t = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__").set).call(r, []), e = r instanceof Array;
31248        } catch (t) {}
31249
31250        return function (r, o) {
31251          return n(r), i(o), e ? t.call(r, o) : r.__proto__ = o, r;
31252        };
31253      }() : void 0);
31254    }, function (t, e, r) {
31255
31256      var n = r(62),
31257          i = r(21),
31258          o = r(43);
31259
31260      t.exports = function (t, e, r) {
31261        var a = n(e);
31262        a in t ? i.f(t, a, o(0, r)) : t[a] = r;
31263      };
31264    }, function (t, e) {}, function (t, e) {
31265      t.exports = function (t, e, r) {
31266        if (!(t instanceof e)) throw TypeError("Incorrect " + (r ? r + " " : "") + "invocation");
31267        return t;
31268      };
31269    }, function (t, e, r) {
31270      var n = r(67),
31271          i = r(35),
31272          o = r(6)("iterator");
31273
31274      t.exports = function (t) {
31275        if (null != t) return t[o] || t["@@iterator"] || i[n(t)];
31276      };
31277    }, function (t, e, r) {
31278
31279      var n,
31280          i = "object" == typeof Reflect ? Reflect : null,
31281          o = i && "function" == typeof i.apply ? i.apply : function (t, e, r) {
31282        return Function.prototype.apply.call(t, e, r);
31283      };
31284      n = i && "function" == typeof i.ownKeys ? i.ownKeys : Object.getOwnPropertySymbols ? function (t) {
31285        return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t));
31286      } : function (t) {
31287        return Object.getOwnPropertyNames(t);
31288      };
31289
31290      var a = Number.isNaN || function (t) {
31291        return t != t;
31292      };
31293
31294      function s() {
31295        s.init.call(this);
31296      }
31297
31298      t.exports = s, s.EventEmitter = s, s.prototype._events = void 0, s.prototype._eventsCount = 0, s.prototype._maxListeners = void 0;
31299      var u = 10;
31300
31301      function f(t) {
31302        return void 0 === t._maxListeners ? s.defaultMaxListeners : t._maxListeners;
31303      }
31304
31305      function c(t, e, r, n) {
31306        var i, o, a, s;
31307        if ("function" != typeof r) throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof r);
31308        if (void 0 === (o = t._events) ? (o = t._events = Object.create(null), t._eventsCount = 0) : (void 0 !== o.newListener && (t.emit("newListener", e, r.listener ? r.listener : r), o = t._events), a = o[e]), void 0 === a) a = o[e] = r, ++t._eventsCount;else if ("function" == typeof a ? a = o[e] = n ? [r, a] : [a, r] : n ? a.unshift(r) : a.push(r), (i = f(t)) > 0 && a.length > i && !a.warned) {
31309          a.warned = !0;
31310          var u = new Error("Possible EventEmitter memory leak detected. " + a.length + " " + String(e) + " listeners added. Use emitter.setMaxListeners() to increase limit");
31311          u.name = "MaxListenersExceededWarning", u.emitter = t, u.type = e, u.count = a.length, s = u, console && console.warn && console.warn(s);
31312        }
31313        return t;
31314      }
31315
31316      function l() {
31317        for (var t = [], e = 0; e < arguments.length; e++) t.push(arguments[e]);
31318
31319        this.fired || (this.target.removeListener(this.type, this.wrapFn), this.fired = !0, o(this.listener, this.target, t));
31320      }
31321
31322      function h(t, e, r) {
31323        var n = {
31324          fired: !1,
31325          wrapFn: void 0,
31326          target: t,
31327          type: e,
31328          listener: r
31329        },
31330            i = l.bind(n);
31331        return i.listener = r, n.wrapFn = i, i;
31332      }
31333
31334      function d(t, e, r) {
31335        var n = t._events;
31336        if (void 0 === n) return [];
31337        var i = n[e];
31338        return void 0 === i ? [] : "function" == typeof i ? r ? [i.listener || i] : [i] : r ? function (t) {
31339          for (var e = new Array(t.length), r = 0; r < e.length; ++r) e[r] = t[r].listener || t[r];
31340
31341          return e;
31342        }(i) : g(i, i.length);
31343      }
31344
31345      function p(t) {
31346        var e = this._events;
31347
31348        if (void 0 !== e) {
31349          var r = e[t];
31350          if ("function" == typeof r) return 1;
31351          if (void 0 !== r) return r.length;
31352        }
31353
31354        return 0;
31355      }
31356
31357      function g(t, e) {
31358        for (var r = new Array(e), n = 0; n < e; ++n) r[n] = t[n];
31359
31360        return r;
31361      }
31362
31363      Object.defineProperty(s, "defaultMaxListeners", {
31364        enumerable: !0,
31365        get: function () {
31366          return u;
31367        },
31368        set: function (t) {
31369          if ("number" != typeof t || t < 0 || a(t)) throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + t + ".");
31370          u = t;
31371        }
31372      }), s.init = function () {
31373        void 0 !== this._events && this._events !== Object.getPrototypeOf(this)._events || (this._events = Object.create(null), this._eventsCount = 0), this._maxListeners = this._maxListeners || void 0;
31374      }, s.prototype.setMaxListeners = function (t) {
31375        if ("number" != typeof t || t < 0 || a(t)) throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + t + ".");
31376        return this._maxListeners = t, this;
31377      }, s.prototype.getMaxListeners = function () {
31378        return f(this);
31379      }, s.prototype.emit = function (t) {
31380        for (var e = [], r = 1; r < arguments.length; r++) e.push(arguments[r]);
31381
31382        var n = "error" === t,
31383            i = this._events;
31384        if (void 0 !== i) n = n && void 0 === i.error;else if (!n) return !1;
31385
31386        if (n) {
31387          var a;
31388          if (e.length > 0 && (a = e[0]), a instanceof Error) throw a;
31389          var s = new Error("Unhandled error." + (a ? " (" + a.message + ")" : ""));
31390          throw s.context = a, s;
31391        }
31392
31393        var u = i[t];
31394        if (void 0 === u) return !1;
31395        if ("function" == typeof u) o(u, this, e);else {
31396          var f = u.length,
31397              c = g(u, f);
31398
31399          for (r = 0; r < f; ++r) o(c[r], this, e);
31400        }
31401        return !0;
31402      }, s.prototype.addListener = function (t, e) {
31403        return c(this, t, e, !1);
31404      }, s.prototype.on = s.prototype.addListener, s.prototype.prependListener = function (t, e) {
31405        return c(this, t, e, !0);
31406      }, s.prototype.once = function (t, e) {
31407        if ("function" != typeof e) throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof e);
31408        return this.on(t, h(this, t, e)), this;
31409      }, s.prototype.prependOnceListener = function (t, e) {
31410        if ("function" != typeof e) throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof e);
31411        return this.prependListener(t, h(this, t, e)), this;
31412      }, s.prototype.removeListener = function (t, e) {
31413        var r, n, i, o, a;
31414        if ("function" != typeof e) throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof e);
31415        if (void 0 === (n = this._events)) return this;
31416        if (void 0 === (r = n[t])) return this;
31417        if (r === e || r.listener === e) 0 == --this._eventsCount ? this._events = Object.create(null) : (delete n[t], n.removeListener && this.emit
31417("removeListener", t, r.listener || e));else if ("function" != typeof r) {
31418          for (i = -1, o = r.length - 1; o >= 0; o--) if (r[o] === e || r[o].listener === e) {
31419            a = r[o].listener, i = o;
31420            break;
31421          }
31422
31423          if (i < 0) return this;
31424          0 === i ? r.shift() : function (t, e) {
31425            for (; e + 1 < t.length; e++) t[e] = t[e + 1];
31426
31427            t.pop();
31428          }(r, i), 1 === r.length && (n[t] = r[0]), void 0 !== n.removeListener && this.emit("removeListener", t, a || e);
31429        }
31430        return this;
31431      }, s.prototype.off = s.prototype.removeListener, s.prototype.removeAllListeners = function (t) {
31432        var e, r, n;
31433        if (void 0 === (r = this._events)) return this;
31434        if (void 0 === r.removeListener) return 0 === arguments.length ? (this._events = Object.create(null), this._eventsCount = 0) : void 0 !== r[t] && (0 == --this._eventsCount ? this._events = Object.create(null) : delete r[t]), this;
31435
31436        if (0 === arguments.length) {
31437          var i,
31438              o = Object.keys(r);
31439
31440          for (n = 0; n < o.length; ++n) "removeListener" !== (i = o[n]) && this.removeAllListeners(i);
31441
31442          return this.removeAllListeners("removeListener"), this._events = Object.create(null), this._eventsCount = 0, this;
31443        }
31444
31445        if ("function" == typeof (e = r[t])) this.removeListener(t, e);else if (void 0 !== e) for (n = e.length - 1; n >= 0; n--) this.removeListener(t, e[n]);
31446        return this;
31447      }, s.prototype.listeners = function (t) {
31448        return d(this, t, !0);
31449      }, s.prototype.rawListeners = function (t) {
31450        return d(this, t, !1);
31451      }, s.listenerCount = function (t, e) {
31452        return "function" == typeof t.listenerCount ? t.listenerCount(e) : p.call(t, e);
31453      }, s.prototype.listenerCount = p, s.prototype.eventNames = function () {
31454        return this._eventsCount > 0 ? n(this._events) : [];
31455      };
31456    }, function (t, e, r) {
31457      (e = t.exports = r(127)).Stream = e, e.Readable = e, e.Writable = r(93), e.Duplex = r(39), e.Transform = r(131), e.PassThrough = r(207);
31458    }, function (t, e, r) {
31459
31460      (function (e, n, i) {
31461        var o = r(70);
31462
31463        function a(t) {
31464          var e = this;
31465          this.next = null, this.entry = null, this.finish = function () {
31466            !function (t, e, r) {
31467              var n = t.entry;
31468              t.entry = null;
31469
31470              for (; n;) {
31471                var i = n.callback;
31472                e.pendingcb--, i(r), n = n.next;
31473              }
31474
31475              e.corkedRequestsFree ? e.corkedRequestsFree.next = t : e.corkedRequestsFree = t;
31476            }(e, t);
31477          };
31478        }
31479
31480        t.exports = m;
31481        var s,
31482            u = !e.browser && ["v0.10", "v0.9."].indexOf(e.version.slice(0, 5)) > -1 ? n : o.nextTick;
31483        m.WritableState = y;
31484        var f = r(57);
31485        f.inherits = r(47);
31486
31487        var c = {
31488          deprecate: r(206)
31489        },
31490            l = r(128),
31491            h = r(71).Buffer,
31492            d = i.Uint8Array || function () {};
31493
31494        var p,
31495            g = r(129);
31496
31497        function v() {}
31498
31499        function y(t, e) {
31500          s = s || r(39), t = t || {};
31501          var n = e instanceof s;
31502          this.objectMode = !!t.objectMode, n && (this.objectMode = this.objectMode || !!t.writableObjectMode);
31503          var i = t.highWaterMark,
31504              f = t.writableHighWaterMark,
31505              c = this.objectMode ? 16 : 16384;
31506          this.highWaterMark = i || 0 === i ? i : n && (f || 0 === f) ? f : c, this.highWaterMark = Math.floor(this.highWaterMark), this.finalCalled = !1, this.needDrain = !1, this.ending = !1, this.ended = !1, this.finished = !1, this.destroyed = !1;
31507          var l = !1 === t.decodeStrings;
31508          this.decodeStrings = !l, this.defaultEncoding = t.defaultEncoding || "utf8", this.length = 0, this.writing = !1, this.corked = 0, this.sync = !0, this.bufferProcessing = !1, this.onwrite = function (t) {
31509            !function (t, e) {
31510              var r = t._writableState,
31511                  n = r.sync,
31512                  i = r.writecb;
31513              if (function (t) {
31514                t.writing = !1, t.writecb = null, t.length -= t.writelen, t.writelen = 0;
31515              }(r), e) !function (t, e, r, n, i) {
31516                --e.pendingcb, r ? (o.nextTick(i, n), o.nextTick(S, t, e), t._writableState.errorEmitted = !0, t.emit("error", n)) : (i(n), t._writableState.errorEmitted = !0, t.emit("error", n), S(t, e));
31517              }(t, r, n, e, i);else {
31518                var a = x(r);
31519                a || r.corked || r.bufferProcessing || !r.bufferedRequest || w(t, r), n ? u(_, t, r, a, i) : _(t, r, a, i);
31520              }
31521            }(e, t);
31522          }, this.writecb = null, this.writelen = 0, this.bufferedRequest = null, this.lastBufferedRequest = null, this.pendingcb = 0, this.prefinished = !1, this.errorEmitted = !1, this.bufferedRequestCount = 0, this.corkedRequestsFree = new a(this);
31523        }
31524
31525        function m(t) {
31526          if (s = s || r(39), !(p.call(m, this) || this instanceof s)) return new m(t);
31527          this._writableState = new y(t, this), this.writable = !0, t && ("function" == typeof t.write && (this._write = t.write), "function" == typeof t.writev && (this._writev = t.writev), "function" == typeof t.destroy && (this._destroy = t.destroy), "function" == typeof t.final && (this._final = t.final)), l.call(this);
31528        }
31529
31530        function b(t, e, r, n, i, o, a) {
31531          e.writelen = n, e.writecb = a, e.writing = !0, e.sync = !0, r ? t._writev(i, e.onwrite) : t._write(i, o, e.onwrite), e.sync = !1;
31532        }
31533
31534        function _(t, e, r, n) {
31535          r || function (t, e) {
31536            0 === e.length && e.needDrain && (e.needDrain = !1, t.emit("drain"));
31537          }(t, e), e.pendingcb--, n(), S(t, e);
31538        }
31539
31540        function w(t, e) {
31541          e.bufferProcessing = !0;
31542          var r = e.bufferedRequest;
31543
31544          if (t._writev && r && r.next) {
31545            var n = e.bufferedRequestCount,
31546                i = new Array(n),
31547                o = e.corkedRequestsFree;
31548            o.entry = r;
31549
31550            for (var s = 0, u = !0; r;) i[s] = r, r.isBuf || (u = !1), r = r.next, s += 1;
31551
31552            i.allBuffers = u, b(t, e, !0, e.length, i, "", o.finish), e.pendingcb++, e.lastBufferedRequest = null, o.next ? (e.corkedRequestsFree = o.next, o.next = null) : e.corkedRequestsFree = new a(e), e.bufferedRequestCount = 0;
31553          } else {
31554            for (; r;) {
31555              var f = r.chunk,
31556                  c = r.encoding,
31557                  l = r.callback;
31558              if (b(t, e, !1, e.objectMode ? 1 : f.length, f, c, l), r = r.next, e.bufferedRequestCount--, e.writing) break;
31559            }
31560
31561            null === r && (e.lastBufferedRequest = null);
31562          }
31563
31564          e.bufferedRequest = r, e.bufferProcessing = !1;
31565        }
31566
31567        function x(t) {
31568          return t.ending && 0 === t.length && null === t.bufferedRequest && !t.finished && !t.writing;
31569        }
31570
31571        function E(t, e) {
31572          t._final(function (r) {
31573            e.pendingcb--, r && t.emit("error", r), e.prefinished = !0, t.emit("prefinish"), S(t, e);
31574          });
31575        }
31576
31577        function S(t, e) {
31578          var r = x(e);
31579          return r && (!function (t, e) {
31580            e.prefinished || e.finalCalled || ("function" == typeof t._final ? (e.pendingcb++, e.finalCalled = !0, o.nextTick(E, t, e)) : (e.prefinished = !0, t.emit("prefinish")));
31581          }(t, e), 0 === e.pendingcb && (e.finished = !0, t.emit("finish"))), r;
31582        }
31583
31584        f.inherits(m, l), y.prototype.getBuffer = function () {
31585          for (var t = this.bufferedRequest, e = []; t;) e.push(t), t = t.next;
31586
31587          return e;
31588        }, function () {
31589          try {
31590            Object.defineProperty(y.prototype, "buffer", {
31591              get: c.deprecate(function () {
31592                return this.getBuffer();
31593              }, "_writableState.buffer is deprecated. Use _writableState.getBuffer instead.", "DEP0003")
31594            });
31595          } catch (t) {}
31596        }(), "function" == typeof Symbol && Symbol.hasInstance && "function" == typeof Function.prototype[Symbol.hasInstance] ? (p = Function.prototype[Symbol.hasInstance], Object.defineProperty(m, Symbol.hasInstance, {
31597          value: function (t) {
31598            return !!p.call(this, t) || this === m && t && t._writableState instanceof y;
31599          }
31600        })) : p = function (t) {
31601          return t instanceof this;
31602        }, m.prototype.pipe = function () {
31603          this.emit("error", new Error("Cannot pipe, not readable"));
31604        }, m.prototype.write = function (t, e, r) {
31605          var n,
31606              i = this._writableState,
31607              a = !1,
31608              s = !i.objectMode && (n = t, h.isBuffer(n) || n instanceof d);
31609          return s && !h.isBuffer(t) && (t = function (t) {
31610            return h.from(t);
31611          }(t)), "function" == typeof e && (r = e, e = null), s ? e = "buffer" : e || (e = i.defaultEncoding), "function" != typeof r && (r = v), i.ended ? function (t, e) {
31612            var r = new Error("write after end");
31613            t.emit("error", r), o.nextTick(e, r);
31614          }(this, r) : (s || function (t, e, r, n) {
31615            var i = !0,
31616                a = !1;
31617            return null === r ? a = new TypeError("May not write null values to stream") : "string" == typeof r || void 0 === r || e.objectMode || (a = new TypeError("Invalid non-string/buffer chunk")), a && (t.emit("error", a), o.nextTick(n, a), i = !1), i;
31618          }(this, i, t, r)) && (i.pendingcb++, a = function (t, e, r, n, i, o) {
31619            if (!r) {
31620              var a = function (t, e, r) {
31621                t.objectMode || !1 === t.decodeStrings || "string" != typeof e || (e = h.from(e, r));
31622                return e;
31623              }(e, n, i);
31624
31625              n !== a && (r = !0, i = "buffer", n = a);
31626            }
31627
31628            var s = e.objectMode ? 1 : n.length;
31629            e.length += s;
31630            var u = e.length < e.highWaterMark;
31631            u || (e.needDrain = !0);
31632
31633            if (e.writing || e.corked) {
31634              var f = e.lastBufferedRequest;
31635              e.lastBufferedRequest = {
31636                chunk: n,
31637                encoding: i,
31638                isBuf: r,
31639                callback: o,
31640                next: null
31641              }, f ? f.next = e.lastBufferedRequest : e.bufferedRequest = e.lastBufferedRequest, e.bufferedRequestCount += 1;
31642            } else b(t, e, !1, s, n, i, o);
31643
31644            return u;
31645          }(this, i, s, t, e, r)), a;
31646        }, m.prototype.cork = function () {
31647          this._writableState.corked++;
31648        }, m.prototype.uncork = function () {
31649          var t = this._writableState;
31650          t.corked && (t.corked--, t.writing || t.corked || t.finished || t.bufferProcessing || !t.bufferedRequest || w(this, t));
31651        }, m.prototype.setDefaultEncoding = function (t) {
31652          if ("string" == typeof t && (t = t.toLowerCase()), !(["hex", "utf8", "utf-8", "ascii", "binary", "base64", "ucs2", "ucs-2", "utf16le", "utf-16le", "raw"].indexOf((t + "").toLowerCase()) > -1)) throw new TypeError("Unknown encoding: " + t);
31653          return this._writableState.defaultEncoding = t, this;
31654        }, Object.defineProperty(m.prototype, "writableHighWaterMark", {
31655          enumerable: !1,
31656          get: function () {
31657            return this._writableState.highWaterMark;
31658          }
31659        }), m.prototype._write = function (t, e, r) {
31660          r(new Error("_write() is not implemented"));
31661        }, m.prototype._writev = null, m.prototype.end = function (t, e, r) {
31662          var n = this._writableState;
31663          "function" == typeof t ? (r = t, t = null, e = null) : "function" == typeof e && (r = e, e = null), null != t && this.write(t, e), n.corked && (n.corked = 1, this.uncork()), n.ending || n.finished || function (t, e, r) {
31664            e.ending = !0, S(t, e), r && (e.finished ? o.nextTick(r) : t.once("finish", r));
31665            e.ended = !0, t.writable = !1;
31666          }(this, n, r);
31667        }, Object.defineProperty(m.prototype, "destroyed", {
31668          get: function () {
31669            return void 0 !== this._writableState && this._writableState.destroyed;
31670          },
31671          set: function (t) {
31672            this._writableState && (this._writableState.destroyed = t);
31673          }
31674        }), m.prototype.destroy = g.destroy, m.prototype._undestroy = g.undestroy, m.prototype._destroy = function (t, e) {
31675          this.end(), e(t);
31676        };
31677      }).call(this, r(38), r(204).setImmediate, r(23));
31678    }, function (t, e, r) {
31679
31680      t.exports = class {
31681        constructor() {
31682          let t = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
31683          if (!(t.maxSize && t.maxSize > 0)) throw new TypeError("`maxSize` must be a number greater than 0");
31684          this.maxSize = t.maxSize, this.cache = new Map(), this.oldCache = new Map(), this._size = 0;
31685        }
31686
31687        _set(t, e) {
31688          this.cache.set(t, e), this._size++, this._size >= this.maxSize && (this._size = 0, this.oldCache = this.cache, this.cache = new Map());
31689        }
31690
31691        get(t) {
31692          if (this.cache.has(t)) return this.cache.get(t);
31693
31694          if (this.oldCache.has(t)) {
31695            const e = this.oldCache.get(t);
31696            return this._set(t, e), e;
31697          }
31698        }
31699
31700        set(t, e) {
31701          return this.cache.has(t) ? this.cache.set(t, e) : this._set(t, e), this;
31702        }
31703
31704        has(t) {
31705          return this.cache.has(t) || this.oldCache.has(t);
31706        }
31707
31708        peek(t) {
31709          return this.cache.has(t) ? this.cache.get(t) : this.oldCache.has(t) ? this.oldCache.get(t) : void 0;
31710        }
31711
31712        delete(t) {
31713          const e = this.cache.delete(t);
31714          return e && this._size--, this.oldCache.delete(t) || e;
31715        }
31716
31717        clear() {
31718          this.cache.clear(), this.oldCache.clear(), this._size = 0;
31719        }
31720
31721        *keys() {
31722          for (const [t] of this) yield t;
31723        }
31724
31725        *values() {
31726          for (const [, t] of this) yield t;
31727        }
31728
31729        *[Symbol.iterator]() {
31730          for (const t of this.cache) yield t;
31731
31732          for (const t of this.oldCache) {
31733            const [e] = t;
31734            this.cache.has(e) || (yield t);
31735          }
31736        }
31737
31738        get size() {
31739          let t = 0;
31740
31741          for (const e of this.oldCache.keys()) this.cache.has(e) || t++;
31742
31743          return this._size + t;
31744        }
31745
31746      };
31747    }, function (t, e, r) {
31748      e.f = r(6);
31749    }, function (t, e, r) {
31750      var n = r(139);
31751
31752      function i(e, r) {
31753        return t.exports = i = n || function (t, e) {
31754          return t.__proto__ = e, t;
31755        }, i(e, r);
31756      }
31757
31758      t.exports = i;
31759    }, function (t, e, r) {
31760      t.exports = r(310);
31761    }, function (t, e, r) {
31762      t.exports = r(319);
31763    }, function (t, e, r) {
31764      t.exports = r(342);
31765    }, function (t, e, r) {
31766
31767      t.exports = {
31768        CRAM_FLAG_PRESERVE_QUAL_SCORES: 1,
31769        CRAM_FLAG_DETACHED: 2,
31770        CRAM_FLAG_MATE_DOWNSTREAM: 4,
31771        CRAM_FLAG_NO_SEQ: 8,
31772        CRAM_FLAG_MASK: 15,
31773        CRAM_M_REVERSE: 1,
31774        CRAM_M_UNMAP: 2,
31775        BAM_FPAIRED: 1,
31776        BAM_FPROPER_PAIR: 2,
31777        BAM_FUNMAP: 4,
31778        BAM_FMUNMAP: 8,
31779        BAM_FREVERSE: 16,
31780        BAM_FMREVERSE: 32,
31781        BAM_FREAD1: 64,
31782        BAM_FREAD2: 128,
31783        BAM_FSECONDARY: 256,
31784        BAM_FQCFAIL: 512,
31785        BAM_FDUP: 1024,
31786        BAM_FSUPPLEMENTARY: 2048,
31787        BAM_CMATCH: 0,
31788        BAM_CINS: 1,
31789        BAM_CDEL: 2,
31790        BAM_CREF_SKIP: 3,
31791        BAM_CSOFT_CLIP: 4,
31792        BAM_CHARD_CLIP: 5,
31793        BAM_CPAD: 6,
31794        BAM_CEQUAL: 7,
31795        BAM_CDIFF: 8,
31796        BAM_CBACK: 9,
31797        BAM_CIGAR_STR: "MIDNSHP:XB",
31798        BAM_CIGAR_SHIFT: 4,
31799        BAM_CIGAR_MASK: 15,
31800        BAM_CIGAR_TYPE: 246183
31801      };
31802    }, function (t, e, r) {
31803      t.exports = r(368);
31804    }, function (t, e, r) {
31805      t.exports = r(396);
31806    }, function (t, e, r) {
31807      t.exports = r(399);
31808    }, function (t, e, r) {
31809
31810      var n = r(164);
31811      t.exports = n;
31812    }, function (t, e) {
31813      var r = {}.toString;
31814
31815      t.exports = Array.isArray || function (t) {
31816        return "[object Array]" == r.call(t);
31817      };
31818    }, function (t, e, r) {
31819      var n = r(17),
31820          i = r(12),
31821          o = r(79);
31822      t.exports = !n && !i(function () {
31823        return 7 != Object.defineProperty(o("div"), "a", {
31824          get: function () {
31825            return 7;
31826          }
31827        }).a;
31828      });
31829    }, function (t, e, r) {
31830      var n = r(12),
31831          i = /#|\.prototype\./,
31832          o = function (t, e) {
31833        var r = s[a(t)];
31834        return r == f || r != u && ("function" == typeof e ? n(e) : !!e);
31835      },
31836          a = o.normalize = function (t) {
31837        return String(t).replace(i, ".").toLowerCase();
31838      },
31839          s = o.data = {},
31840          u = o.NATIVE = "N",
31841          f = o.POLYFILL = "P";
31842
31843      t.exports = o;
31844    }, function (t, e, r) {
31845
31846      var n,
31847          i,
31848          o,
31849          a = r(66),
31850          s = r(20),
31851          u = r(24),
31852          f = r(6),
31853          c = r(4),
31854          l = f("iterator"),
31855          h = !1;
31856      [].keys && ("next" in (o = [].keys()) ? (i = a(a(o))) !== Object.prototype && (n = i) : h = !0), null == n && (n = {}), c || u(n, l) || s(n, l, function () {
31857        return this;
31858      }), t.exports = {
31859        IteratorPrototype: n,
31860        BUGGY_SAFARI_ITERATORS: h
31861      };
31862    }, function (t, e, r) {
31863      var n = r(12);
31864      t.exports = !n(function () {
31865        function t() {}
31866
31867        return t.prototype.constructor = null, Object.getPrototypeOf(new t()) !== t.prototype;
31868      });
31869    }, function (t, e, r) {
31870      var n = r(12);
31871      t.exports = !!Object.getOwnPropertySymbols && !n(function () {
31872        return !String(Symbol());
31873      });
31874    }, function (t, e, r) {
31875      var n = r(24),
31876          i = r(28),
31877          o = r(82).indexOf,
31878          a = r(50);
31879
31880      t.exports = function (t, e) {
31881        var r,
31882            s = i(t),
31883            u = 0,
31884            f = [];
31885
31886        for (r in s) !n(a, r) && n(s, r) && f.push(r);
31887
31888        for (; e.length > u;) n(s, r = e[u++]) && (~o(f, r) || f.push(r));
31889
31890        return f;
31891      };
31892    }, function (t, e, r) {
31893      var n = r(26);
31894      t.exports = n("document", "documentElement");
31895    }, function (t, e, r) {
31896      var n = r(14),
31897          i = r(53),
31898          o = r(6)("species");
31899
31900      t.exports = function (t, e) {
31901        var r;
31902        return i(t) && ("function" != typeof (r = t.constructor) || r !== Array && !i(r.prototype) ? n(r) && null === (r = r[o]) && (r = void 0) : r = void 0), new (void 0 === r ? Array : r)(0 === e ? 0 : e);
31903      };
31904    }, function (t, e, r) {
31905
31906      var n = r(0),
31907          i = r(12),
31908          o = r(53),
31909          a = r(14),
31910          s = r(22),
31911          u = r(29),
31912          f = r(87),
31913          c = r(113),
31914          l = r(68),
31915          h = r(6)("isConcatSpreadable"),
31916          d = !i(function () {
31917        var t = [];
31918        return t[h] = !1, t.concat()[0] !== t;
31919      }),
31920          p = l("concat"),
31921          g = function (t) {
31922        if (!a(t)) return !1;
31923        var e = t[h];
31924        return void 0 !== e ? !!e : o(t);
31925      };
31926
31927      n({
31928        target: "Array",
31929        proto: !0,
31930        forced: !d || !p
31931      }, {
31932        concat: function (t) {
31933          var e,
31934              r,
31935              n,
31936              i,
31937              o,
31938              a = s(this),
31939              l = c(a, 0),
31940              h = 0;
31941
31942          for (e = -1, n = arguments.length; e < n; e++) if (o = -1 === e ? a : arguments[e], g(o)) {
31943            if (h + (i = u(o.length)) >
31943 9007199254740991) throw TypeError("Maximum allowed index exceeded");
31944
31945            for (r = 0; r < i; r++, h++) r in o && f(l, h, o[r]);
31946          } else {
31947            if (h >= 9007199254740991) throw TypeError("Maximum allowed index exceeded");
31948            f(l, h++, o);
31949          }
31950
31951          return l.length = h, l;
31952        }
31953      });
31954    }, function (t, e, r) {
31955      r(88), r(46), r(41), r(188), r(125), r(191);
31956      var n = r(3);
31957      t.exports = n.Promise;
31958    }, function (t, e, r) {
31959      var n = r(13);
31960      t.exports = n.Promise;
31961    }, function (t, e, r) {
31962      var n = r(52);
31963
31964      t.exports = function (t, e, r) {
31965        for (var i in e) r && r.unsafe && t[i] ? t[i] = e[i] : n(t, i, e[i], r);
31966
31967        return t;
31968      };
31969    }, function (t, e, r) {
31970
31971      var n = r(26),
31972          i = r(21),
31973          o = r(6),
31974          a = r(17),
31975          s = o("species");
31976
31977      t.exports = function (t) {
31978        var e = n(t),
31979            r = i.f;
31980        a && e && !e[s] && r(e, s, {
31981          configurable: !0,
31982          get: function () {
31983            return this;
31984          }
31985        });
31986      };
31987    }, function (t, e, r) {
31988      var n = r(6),
31989          i = r(35),
31990          o = n("iterator"),
31991          a = Array.prototype;
31992
31993      t.exports = function (t) {
31994        return void 0 !== t && (i.Array === t || a[o] === t);
31995      };
31996    }, function (t, e, r) {
31997      var n = r(2);
31998
31999      t.exports = function (t, e, r, i) {
32000        try {
32001          return i ? e(n(r)[0], r[1]) : e(r);
32002        } catch (e) {
32003          var o = t.return;
32004          throw void 0 !== o && n(o.call(t)), e;
32005        }
32006      };
32007    }, function (t, e, r) {
32008      var n = r(6)("iterator"),
32009          i = !1;
32010
32011      try {
32012        var o = 0,
32013            a = {
32014          next: function () {
32015            return {
32016              done: !!o++
32017            };
32018          },
32019          return: function () {
32020            i = !0;
32021          }
32022        };
32023        a[n] = function () {
32024          return this;
32025        }, Array.from(a, function () {
32026          throw 2;
32027        });
32028      } catch (t) {}
32029
32030      t.exports = function (t, e) {
32031        if (!e && !i) return !1;
32032        var r = !1;
32033
32034        try {
32035          var o = {};
32036          o[n] = function () {
32037            return {
32038              next: function () {
32039                return {
32040                  done: r = !0
32041                };
32042              }
32043            };
32044          }, t(o);
32045        } catch (t) {}
32046
32047        return r;
32048      };
32049    }, function (t, e, r) {
32050      var n,
32051          i,
32052          o,
32053          a = r(13),
32054          s = r(12),
32055          u = r(34),
32056          f = r(15),
32057          c = r(112),
32058          l = r(79),
32059          h = a.location,
32060          d = a.setImmediate,
32061          p = a.clearImmediate,
32062          g = a.process,
32063          v = a.MessageChannel,
32064          y = a.Dispatch,
32065          m = 0,
32066          b = {},
32067          _ = function (t) {
32068        if (b.hasOwnProperty(t)) {
32069          var e = b[t];
32070          delete b[t], e();
32071        }
32072      },
32073          w = function (t) {
32074        return function () {
32075          _(t);
32076        };
32077      },
32078          x = function (t) {
32079        _(t.data);
32080      },
32081          E = function (t) {
32082        a.postMessage(t + "", h.protocol + "//" + h.host);
32083      };
32084
32085      d && p || (d = function (t) {
32086        for (var e = [], r = 1; arguments.length > r;) e.push(arguments[r++]);
32087
32088        return b[++m] = function () {
32089          ("function" == typeof t ? t : Function(t)).apply(void 0, e);
32090        }, n(m), m;
32091      }, p = function (t) {
32092        delete b[t];
32093      }, "process" == u(g) ? n = function (t) {
32094        g.nextTick(w(t));
32095      } : y && y.now ? n = function (t) {
32096        y.now(w(t));
32097      } : v ? (o = (i = new v()).port2, i.port1.onmessage = x, n = f(o.postMessage, o, 1)) : !a.addEventListener || "function" != typeof postMessage || a.importScripts || s(E) ? n = "onreadystatechange" in l("script") ? function (t) {
32098        c.appendChild(l("script")).onreadystatechange = function () {
32099          c.removeChild(this), _(t);
32100        };
32101      } : function (t) {
32102        setTimeout(w(t), 0);
32103      } : (n = E, a.addEventListener("message", x, !1))), t.exports = {
32104        set: d,
32105        clear: p
32106      };
32107    }, function (t, e, r) {
32108      var n = r(26);
32109      t.exports = n("navigator", "userAgent") || "";
32110    }, function (t, e, r) {
32111      var n = r(2),
32112          i = r(14),
32113          o = r(56);
32114
32115      t.exports = function (t, e) {
32116        if (n(t), i(e) && e.constructor === t) return e;
32117        var r = o.f(t);
32118        return (0, r.resolve)(e), r.promise;
32119      };
32120    }, function (t, e, r) {
32121
32122      var n = r(0),
32123          i = r(5),
32124          o = r(56),
32125          a = r(69),
32126          s = r(8);
32127      n({
32128        target: "Promise",
32129        stat: !0
32130      }, {
32131        allSettled: function (t) {
32132          var e = this,
32133              r = o.f(e),
32134              n = r.resolve,
32135              u = r.reject,
32136              f = a(function () {
32137            var r = i(e.resolve),
32138                o = [],
32139                a = 0,
32140                u = 1;
32141            s(t, function (t) {
32142              var i = a++,
32143                  s = !1;
32144              o.push(void 0), u++, r.call(e, t).then(function (t) {
32145                s || (s = !0, o[i] = {
32146                  status: "fulfilled",
32147                  value: t
32148                }, --u || n(o));
32149              }, function (t) {
32150                s || (s = !0, o[i] = {
32151                  status: "rejected",
32152                  reason: t
32153                }, --u || n(o));
32154              });
32155            }), --u || n(o);
32156          });
32157          return f.error && u(f.value), r.promise;
32158        }
32159      });
32160    }, function (t, e, r) {
32161
32162      (function (t) {
32163        var n = r(19).Buffer,
32164            i = r(200).Transform,
32165            o = r(212),
32166            a = r(133),
32167            s = r(132).ok,
32168            u = r(19).kMaxLength,
32169            f = "Cannot create final Buffer. It would be larger than 0x" + u.toString(16) + " bytes";
32170        o.Z_MIN_WINDOWBITS = 8, o.Z_MAX_WINDOWBITS = 15, o.Z_DEFAULT_WINDOWBITS = 15, o.Z_MIN_CHUNK = 64, o.Z_MAX_CHUNK = 1 / 0, o.Z_DEFAULT_CHUNK = 16384, o.Z_MIN_MEMLEVEL = 1, o.Z_MAX_MEMLEVEL = 9, o.Z_DEFAULT_MEMLEVEL = 8, o.Z_MIN_LEVEL = -1, o.Z_MAX_LEVEL = 9, o.Z_DEFAULT_LEVEL = o.Z_DEFAULT_COMPRESSION;
32171
32172        for (var c = Object.keys(o), l = 0; l < c.length; l++) {
32173          var h = c[l];
32174          h.match(/^Z/) && Object.defineProperty(e, h, {
32175            enumerable: !0,
32176            value: o[h],
32177            writable: !1
32178          });
32179        }
32180
32181        for (var d = {
32182          Z_OK: o.Z_OK,
32183          Z_STREAM_END: o.Z_STREAM_END,
32184          Z_NEED_DICT: o.Z_NEED_DICT,
32185          Z_ERRNO: o.Z_ERRNO,
32186          Z_STREAM_ERROR: o.Z_STREAM_ERROR,
32187          Z_DATA_ERROR: o.Z_DATA_ERROR,
32188          Z_MEM_ERROR: o.Z_MEM_ERROR,
32189          Z_BUF_ERROR: o.Z_BUF_ERROR,
32190          Z_VERSION_ERROR: o.Z_VERSION_ERROR
32191        }, p = Object.keys(d), g = 0; g < p.length; g++) {
32192          var v = p[g];
32193          d[d[v]] = v;
32194        }
32195
32196        function y(t, e, r) {
32197          var i = [],
32198              o = 0;
32199
32200          function a() {
32201            for (var e; null !== (e = t.read());) i.push(e), o += e.length;
32202
32203            t.once("readable", a);
32204          }
32205
32206          function s() {
32207            var e,
32208                a = null;
32209            o >= u ? a = new RangeError(f) : e = n.concat(i, o), i = [], t.close(), r(a, e);
32210          }
32211
32212          t.on("error", function (e) {
32213            t.removeListener("end", s), t.removeListener("readable", a), r(e);
32214          }), t.on("end", s), t.end(e), a();
32215        }
32216
32217        function m(t, e) {
32218          if ("string" == typeof e && (e = n.from(e)), !n.isBuffer(e)) throw new TypeError("Not a string or buffer");
32219          var r = t._finishFlushFlag;
32220          return t._processChunk(e, r);
32221        }
32222
32223        function b(t) {
32224          if (!(this instanceof b)) return new b(t);
32225          C.call(this, t, o.DEFLATE);
32226        }
32227
32228        function _(t) {
32229          if (!(this instanceof _)) return new _(t);
32230          C.call(this, t, o.INFLATE);
32231        }
32232
32233        function w(t) {
32234          if (!(this instanceof w)) return new w(t);
32235          C.call(this, t, o.GZIP);
32236        }
32237
32238        function x(t) {
32239          if (!(this instanceof x)) return new x(t);
32240          C.call(this, t, o.GUNZIP);
32241        }
32242
32243        function E(t) {
32244          if (!(this instanceof E)) return new E(t);
32245          C.call(this, t, o.DEFLATERAW);
32246        }
32247
32248        function S(t) {
32249          if (!(this instanceof S)) return new S(t);
32250          C.call(this, t, o.INFLATERAW);
32251        }
32252
32253        function k(t) {
32254          if (!(this instanceof k)) return new k(t);
32255          C.call(this, t, o.UNZIP);
32256        }
32257
32258        function A(t) {
32259          return t === o.Z_NO_FLUSH || t === o.Z_PARTIAL_FLUSH || t === o.Z_SYNC_FLUSH || t === o.Z_FULL_FLUSH || t === o.Z_FINISH || t === o.Z_BLOCK;
32260        }
32261
32262        function C(t, r) {
32263          var a = this;
32264          if (this._opts = t = t || {}, this._chunkSize = t.chunkSize || e.Z_DEFAULT_CHUNK, i.call(this, t), t.flush && !A(t.flush)) throw new Error("Invalid flush flag: " + t.flush);
32265          if (t.finishFlush && !A(t.finishFlush)) throw new Error("Invalid flush flag: " + t.finishFlush);
32266          if (this._flushFlag = t.flush || o.Z_NO_FLUSH, this._finishFlushFlag = void 0 !== t.finishFlush ? t.finishFlush : o.Z_FINISH, t.chunkSize && (t.chunkSize < e.Z_MIN_CHUNK || t.chunkSize > e.Z_MAX_CHUNK)) throw new Error("Invalid chunk size: " + t.chunkSize);
32267          if (t.windowBits && (t.windowBits < e.Z_MIN_WINDOWBITS || t.windowBits > e.Z_MAX_WINDOWBITS)) throw new Error("Invalid windowBits: " + t.windowBits);
32268          if (t.level && (t.level < e.Z_MIN_LEVEL || t.level > e.Z_MAX_LEVEL)) throw new Error("Invalid compression level: " + t.level);
32269          if (t.memLevel && (t.memLevel < e.Z_MIN_MEMLEVEL || t.memLevel > e.Z_MAX_MEMLEVEL)) throw new Error("Invalid memLevel: " + t.memLevel);
32270          if (t.strategy && t.strategy != e.Z_FILTERED && t.strategy != e.Z_HUFFMAN_ONLY && t.strategy != e.Z_RLE && t.strategy != e.Z_FIXED && t.strategy != e.Z_DEFAULT_STRATEGY) throw new Error("Invalid strategy: " + t.strategy);
32271          if (t.dictionary && !n.isBuffer(t.dictionary)) throw new Error("Invalid dictionary: it should be a Buffer instance");
32272          this._handle = new o.Zlib(r);
32273          var s = this;
32274          this._hadError = !1, this._handle.onerror = function (t, r) {
32275            T(s), s._hadError = !0;
32276            var n = new Error(t);
32277            n.errno = r, n.code = e.codes[r], s.emit("error", n);
32278          };
32279          var u = e.Z_DEFAULT_COMPRESSION;
32280          "number" == typeof t.level && (u = t.level);
32281          var f = e.Z_DEFAULT_STRATEGY;
32282          "number" == typeof t.strategy && (f = t.strategy), this._handle.init(t.windowBits || e.Z_DEFAULT_WINDOWBITS, u, t.memLevel || e.Z_DEFAULT_MEMLEVEL, f, t.dictionary), this._buffer = n.allocUnsafe(this._chunkSize), this._offset = 0, this._level = u, this._strategy = f, this.once("end", this.close), Object.defineProperty(this, "_closed", {
32283            get: function () {
32284              return !a._handle;
32285            },
32286            configurable: !0,
32287            enumerable: !0
32288          });
32289        }
32290
32291        function T(e, r) {
32292          r && t.nextTick(r), e._handle && (e._handle.close(), e._handle = null);
32293        }
32294
32295        function R(t) {
32296          t.emit("close");
32297        }
32298
32299        Object.defineProperty(e, "codes", {
32300          enumerable: !0,
32301          value: Object.freeze(d),
32302          writable: !1
32303        }), e.Deflate = b, e.Inflate = _, e.Gzip = w, e.Gunzip = x, e.DeflateRaw = E, e.InflateRaw = S, e.Unzip = k, e.createDeflate = function (t) {
32304          return new b(t);
32305        }, e.createInflate = function (t) {
32306          return new _(t);
32307        }, e.createDeflateRaw = function (t) {
32308          return new E(t);
32309        }, e.createInflateRaw = function (t) {
32310          return new S(t);
32311        }, e.createGzip = function (t) {
32312          return new w(t);
32313        }, e.createGunzip = function (t) {
32314          return new x(t);
32315        }, e.createUnzip = function (t) {
32316          return new k(t);
32317        }, e.deflate = function (t, e, r) {
32318          return "function" == typeof e && (r = e, e = {}), y(new b(e), t, r);
32319        }, e.deflateSync = function (t, e) {
32320          return m(new b(e), t);
32321        }, e.gzip = function (t, e, r) {
32322          return "function" == typeof e && (r = e, e = {}), y(new w(e), t, r);
32323        }, e.gzipSync = function (t, e) {
32324          return m(new w(e), t);
32325        }, e.deflateRaw = function (t, e, r) {
32326          return "function" == typeof e && (r = e, e = {}), y(new E(e), t, r);
32327        }, e.deflateRawSync = function (t, e) {
32328          return m(new E(e), t);
32329        }, e.unzip = function (t, e, r) {
32330          return "function" == typeof e && (r = e, e = {}), y(new k(e), t, r);
32331        }, e.unzipSync = function (t, e) {
32332          return m(new k(e), t);
32333        }, e.inflate = function (t, e, r) {
32334          return "function" == typeof e && (r = e, e = {}), y(new _(e), t, r);
32335        }, e.inflateSync = function (t, e) {
32336          return m(new _(e), t);
32337        }, e.gunzip = function (t, e, r) {
32338          return "function" == typeof e && (r = e, e = {}), y(new x(e), t, r);
32339        }, e.gunzipSync = function (t, e) {
32340          return m(new x(e), t);
32341        }, e.inflateRaw = function (t, e, r) {
32342          return "function" == typeof e && (r = e, e = {}), y(new S(e), t, r);
32343        }, e.inflateRawSync = function (t, e) {
32344          return m(new S(e), t);
32345        }, a.inherits(C, i), C.prototype.params = function (r, n, i) {
32346          if (r < e.Z_MIN_LEVEL || r > e.Z_MAX_LEVEL) throw new RangeError("Invalid compression level: " + r);
32347          if (n != e.Z_FILTERED && n != e.Z_HUFFMAN_ONLY && n != e.Z_RLE && n != e.Z_FIXED && n != e.Z_DEFAULT_STRATEGY) throw new TypeError("Invalid strategy: " + n);
32348
32349          if (this._level !== r || this._strategy !== n) {
32350            var a = this;
32351            this.flush(o.Z_SYNC_FLUSH, function () {
32352              s(a._handle, "zlib binding closed"), a._handle.params(r, n), a._hadError || (a._level = r, a._strategy = n, i && i());
32353            });
32354          } else t.nextTick(i);
32355        }, C.prototype.reset = function () {
32356          return s(this._handle, "zlib binding closed"), this._handle.reset();
32357        }, C.prototype._flush = function (t) {
32358          this._transform(n.alloc(0), "", t);
32359        }, C.prototype.flush = function (e, r) {
32360          var i = this,
32361              a = this._writableState;
32362          ("function" == typeof e || void 0 === e && !r) && (r = e, e = o.Z_FULL_FLUSH), a.ended ? r && t.nextTick(r) : a.ending ? r && this.once("end", r) : a.needDrain ? r && this.once("drain", function () {
32363            return i.flush(e, r);
32364          }) : (this._flushFlag = e, this.write(n.alloc(0), "", r));
32365        }, C.prototype.close = function (e) {
32366          T(this, e), t.nextTick(R, this);
32367        }, C.prototype._transform = function (t, e, r) {
32368          var i,
32369              a = this._writableState,
32370              s = (a.ending || a.ended) && (!t || a.length === t.length);
32371          return null === t || n.isBuffer(t) ? this._handle ? (s ? i = this._finishFlushFlag : (i = this._flushFlag, t.length >= a.length && (this._flushFlag = this._opts.flush || o.Z_NO_FLUSH)), void this._processChunk(t, i, r)) : r(new Error("zlib binding closed")) : r(new Error("invalid input"));
32372        }, C.prototype._processChunk = function (t, e, r) {
32373          var i = t && t.length,
32374              o = this._chunkSize - this._offset,
32375              a = 0,
32376              c = this,
32377              l = "function" == typeof r;
32378
32379          if (!l) {
32380            var h,
32381                d = [],
32382                p = 0;
32383            this.on("error", function (t) {
32384              h = t;
32385            }), s(this._handle, "zlib binding closed");
32386
32387            do {
32388              var g = this._handle.writeSync(e, t, a, i, this._buffer, this._offset, o);
32389            } while (!this._hadError && m(g[0], g[1]));
32390
32391            if (this._hadError) throw h;
32392            if (p >= u) throw T(this), new RangeError(f);
32393            var v = n.concat(d, p);
32394            return T(this), v;
32395          }
32396
32397          s(this._handle, "zlib binding closed");
32398
32399          var y = this._handle.write(e, t, a, i, this._buffer, this._offset, o);
32400
32401          function m(u, f) {
32402            if (this && (this.buffer = null, this.callback = null), !c._hadError) {
32403              var h = o - f;
32404
32405              if (s(h >= 0, "have should not go down"), h > 0) {
32406                var g = c._buffer.slice(c._offset, c._offset + h);
32407
32408                c._offset += h, l ? c.push(g) : (d.push(g), p += g.length);
32409              }
32410
32411              if ((0 === f || c._offset >= c._chunkSize) && (o = c._chunkSize, c._offset = 0, c._buffer = n.allocUnsafe(c._chunkSize)), 0 === f) {
32412                if (a += i - u, i = u, !l) return !0;
32413
32414                var v = c._handle.write(e, t, a, i, c._buffer, c._offset, c._chunkSize);
32415
32416                return v.callback = m, void (v.buffer = t);
32417              }
32418
32419              if (!l) return !1;
32420              r();
32421            }
32422          }
32423
32424          y.buffer = t, y.callback = m;
32425        }, a.inherits(b, C), a.inherits(_, C), a.inherits(w, C), a.inherits(x, C), a.inherits(E, C), a.inherits(S, C), a.inherits(k, C);
32426      }).call(this, r(38));
32427    }, function (t, e, r) {
32428
32429      (function (e, n) {
32430        var i = r(70);
32431        t.exports = b;
32432        var o,
32433            a = r(105);
32434        b.ReadableState = m;
32435        r(91).EventEmitter;
32436
32437        var s = function (t, e) {
32438          return t.listeners(e).length;
32439        },
32440            u = r(128),
32441            f = r(71).Buffer,
32442            c = e.Uint8Array || function () {};
32443
32444        var l = r(57);
32445        l.inherits = r(47);
32446        var h = r(201),
32447            d = void 0;
32448        d = h && h.debuglog ? h.debuglog("stream") : function () {};
32449        var p,
32450            g = r(202),
32451            v = r(129);
32452        l.inherits(b, u);
32453        var y = ["error", "close", "destroy", "pause", "resume"];
32454
32455        function m(t, e) {
32456          t = t || {};
32457          var n = e instanceof (o = o || r(39));
32458          this.objectMode = !!t.objectMode, n && (this.objectMode = this.objectMode || !!t.readableObjectMode);
32459          var i = t.highWaterMark,
32460              a = t.readableHighWaterMark,
32461              s = this.objectMode ? 16 : 16384;
32462          this.highWaterMark = i || 0 === i ? i : n && (a || 0 === a) ? a : s, this.highWaterMark = Math.floor(this.highWaterMark), this.buffer = new g(), this.length = 0, this.pipes = null, this.pipesCount = 0, this.flowing = null, this.ended = !1, this.endEmitted = !1, this.reading = !1, this.sync = !0, this.needReadable = !1, this.emittedReadable = !1, this.readableListening = !1, this.resumeScheduled = !1, this.destroyed = !1, this.defaultEncoding = t.defaultEncoding || "utf8", this.awaitDrain = 0, this.readingMore = !1, this.decoder = null, this.encoding = null, t.encoding && (p || (p = r(130).StringDecoder), this.decoder = new p(t.encoding), this.encoding = t.encoding);
32463        }
32464
32465        function b(t) {
32466          if (o = o || r(39), !(this instanceof b)) return new b(t);
32467          this._readableState = new m(t, this), this.readable = !0, t && ("function" == typeof t.read && (this._read = t.read), "function" == typeof t.destroy && (this._destroy = t.destroy)), u.call(this);
32468        }
32469
32470        function _(t, e, r, n, i) {
32471          var o,
32472              a = t._readableState;
32473          null === e ? (a.reading = !1, function (t, e) {
32474            if (e.ended) return;
32475
32476            if (e.decoder) {
32477              var r = e.decoder.end();
32478              r && r.length && (e.buffer.push(r), e.length += e.objectMode ? 1 : r.length);
32479            }
32480
32481            e.ended = !0, S(t);
32482          }(t, a)) : (i || (o = function (t, e) {
32483            var r;
32484            n = e, f.isBuffer(n) || n instanceof c || "string" == typeof e || void 0 === e || t.objectMode || (r = new TypeError("Invalid non-string/buffer chunk"));
32485            var n;
32486            return r;
32487          }(a, e)), o ? t.emit("error", o) : a.objectMode || e && e.length > 0 ? ("string" == typeof e || a.objectMode || Object.getPrototypeOf(e) === f.prototype || (e = function (t) {
32488            return f.from(t);
32489          }(e)), n ? a.endEmitted ? t.emit("error", new Error("stream.unshift() after end event")) : w(t, a, e, !0) : a.ended ? t.emit("error", new Error("stream.push() after EOF")) : (a.reading = !1, a.decoder && !r ? (e = a.decoder.write(e), a.objectMode || 0 !== e.length ? w(t, a, e, !1) : A(t, a)) : w(t, a, e, !1))) : n || (a.reading = !1));
32490          return function (t) {
32491            return !t.ended && (t.needReadable || t.length < t.highWaterMark || 0 === t.length);
32492          }(a);
32493        }
32494
32495        function w(t, e, r, n) {
32496          e.flowing && 0 === e.length && !e.sync ? (t.emit("data", r), t.read(0)) : (e.length += e.objectMode ? 1 : r.length, n ? e.buffer.unshift(r) : e.buffer.push(r), e.needReadable && S(t)), A(t, e);
32497        }
32498
32499        Object.defineProperty(b.prototype, "destroyed", {
32500          get: function () {
32501            return void 0 !== this._readableState && this._readableState.destroyed;
32502          },
32503          set: function (t) {
32504            this._readableState && (this._readableState.destroyed = t);
32505          }
32506        }), b.prototype.destroy = v.destroy, b.prototype._undestroy = v.undestroy, b.prototype._destroy = function (t, e) {
32507          this.push(null), e(t);
32508        }, b.prototype.push = function (t, e) {
32509          var r,
32510              n = this._readableState;
32511          return n.objectMode ? r = !0 : "string" == typeof t && ((e = e || n.defaultEncoding) !== n.encoding && (t = f.from(t, e), e = ""), r = !0), _(this, t, e, !1, r);
32512        }, b.prototype.unshift = function (t) {
32513          return _(this, t, null, !0, !1);
32514        }, b.prototype.isPaused = function () {
32515          return !1 === this._readableState.flowing;
32516        }, b.prototype.setEncoding = function (t) {
32517          return p || (p = r(130).StringDecoder), this._readableState.decoder = new p(t), this._readableState.encoding = t, this;
32518        };
32519        var x = 8388608;
32520
32521        function E(t, e) {
32522          return t <= 0 || 0 === e.length && e.ended ? 0 : e.objectMode ? 1 : t != t ? e.flowing && e.length ? e.buffer.head.data.length : e.length : (t > e.highWaterMark && (e.highWaterMark = function (t) {
32523            return t >= x ? t = x : (t--, t |= t >>> 1, t |= t >>> 2, t |= t >>> 4, t |= t >>> 8, t |= t >>> 16, t++), t;
vendor: 16,526 bytes, lines 32524-32947
32524          }(t)), t <= e.length ? t : e.ended ? e.length : (e.needReadable = !0, 0));
32525        }
32526
32527        function S(t) {
32528          var e = t._readableState;
32529          e.needReadable = !1, e.emittedReadable || (d("emitReadable", e.flowing), e.emittedReadable = !0, e.sync ? i.nextTick(k, t) : k(t));
32530        }
32531
32532        function k(t) {
32533          d("emit readable"), t.emit("readable"), O(t);
32534        }
32535
32536        function A(t, e) {
32537          e.readingMore || (e.readingMore = !0, i.nextTick(C, t, e));
32538        }
32539
32540        function C(t, e) {
32541          for (var r = e.length; !e.reading && !e.flowing && !e.ended && e.length < e.highWaterMark && (d("maybeReadMore read 0"), t.read(0), r !== e.length);) r = e.length;
32542
32543          e.readingMore = !1;
32544        }
32545
32546        function T(t) {
32547          d("readable nexttick read 0"), t.read(0);
32548        }
32549
32550        function R(t, e) {
32551          e.reading || (d("resume read 0"), t.read(0)), e.resumeScheduled = !1, e.awaitDrain = 0, t.emit("resume"), O(t), e.flowing && !e.reading && t.read(0);
32552        }
32553
32554        function O(t) {
32555          var e = t._readableState;
32556
32557          for (d("flow", e.flowing); e.flowing && null !== t.read(););
32558        }
32559
32560        function I(t, e) {
32561          return 0 === e.length ? null : (e.objectMode ? r = e.buffer.shift() : !t || t >= e.length ? (r = e.decoder ? e.buffer.join("") : 1 === e.buffer.length ? e.buffer.head.data : e.buffer.concat(e.length), e.buffer.clear()) : r = function (t, e, r) {
32562            var n;
32563            t < e.head.data.length ? (n = e.head.data.slice(0, t), e.head.data = e.head.data.slice(t)) : n = t === e.head.data.length ? e.shift() : r ? function (t, e) {
32564              var r = e.head,
32565                  n = 1,
32566                  i = r.data;
32567              t -= i.length;
32568
32569              for (; r = r.next;) {
32570                var o = r.data,
32571                    a = t > o.length ? o.length : t;
32572
32573                if (a === o.length ? i += o : i += o.slice(0, t), 0 === (t -= a)) {
32574                  a === o.length ? (++n, r.next ? e.head = r.next : e.head = e.tail = null) : (e.head = r, r.data = o.slice(a));
32575                  break;
32576                }
32577
32578                ++n;
32579              }
32580
32581              return e.length -= n, i;
32582            }(t, e) : function (t, e) {
32583              var r = f.allocUnsafe(t),
32584                  n = e.head,
32585                  i = 1;
32586              n.data.copy(r), t -= n.data.length;
32587
32588              for (; n = n.next;) {
32589                var o = n.data,
32590                    a = t > o.length ? o.length : t;
32591
32592                if (o.copy(r, r.length - t, 0, a), 0 === (t -= a)) {
32593                  a === o.length ? (++i, n.next ? e.head = n.next : e.head = e.tail = null) : (e.head = n, n.data = o.slice(a));
32594                  break;
32595                }
32596
32597                ++i;
32598              }
32599
32600              return e.length -= i, r;
32601            }(t, e);
32602            return n;
32603          }(t, e.buffer, e.decoder), r);
32604          var r;
32605        }
32606
32607        function L(t) {
32608          var e = t._readableState;
32609          if (e.length > 0) throw new Error('"endReadable()" called on non-empty stream');
32610          e.endEmitted || (e.ended = !0, i.nextTick(B, e, t));
32611        }
32612
32613        function B(t, e) {
32614          t.endEmitted || 0 !== t.length || (t.endEmitted = !0, e.readable = !1, e.emit("end"));
32615        }
32616
32617        function P(t, e) {
32618          for (var r = 0, n = t.length; r < n; r++) if (t[r] === e) return r;
32619
32620          return -1;
32621        }
32622
32623        b.prototype.read = function (t) {
32624          d("read", t), t = parseInt(t, 10);
32625          var e = this._readableState,
32626              r = t;
32627          if (0 !== t && (e.emittedReadable = !1), 0 === t && e.needReadable && (e.length >= e.highWaterMark || e.ended)) return d("read: emitReadable", e.length, e.ended), 0 === e.length && e.ended ? L(this) : S(this), null;
32628          if (0 === (t = E(t, e)) && e.ended) return 0 === e.length && L(this), null;
32629          var n,
32630              i = e.needReadable;
32631          return d("need readable", i), (0 === e.length || e.length - t < e.highWaterMark) && d("length less than watermark", i = !0), e.ended || e.reading ? d("reading or ended", i = !1) : i && (d("do read"), e.reading = !0, e.sync = !0, 0 === e.length && (e.needReadable = !0), this._read(e.highWaterMark), e.sync = !1, e.reading || (t = E(r, e))), null === (n = t > 0 ? I(t, e) : null) ? (e.needReadable = !0, t = 0) : e.length -= t, 0 === e.length && (e.ended || (e.needReadable = !0), r !== t && e.ended && L(this)), null !== n && this.emit("data", n), n;
32632        }, b.prototype._read = function (t) {
32633          this.emit("error", new Error("_read() is not implemented"));
32634        }, b.prototype.pipe = function (t, e) {
32635          var r = this,
32636              o = this._readableState;
32637
32638          switch (o.pipesCount) {
32639            case 0:
32640              o.pipes = t;
32641              break;
32642
32643            case 1:
32644              o.pipes = [o.pipes, t];
32645              break;
32646
32647            default:
32648              o.pipes.push(t);
32649          }
32650
32651          o.pipesCount += 1, d("pipe count=%d opts=%j", o.pipesCount, e);
32652          var u = (!e || !1 !== e.end) && t !== n.stdout && t !== n.stderr ? c : b;
32653
32654          function f(e, n) {
32655            d("onunpipe"), e === r && n && !1 === n.hasUnpiped && (n.hasUnpiped = !0, d("cleanup"), t.removeListener("close", y), t.removeListener("finish", m), t.removeListener("drain", l), t.removeListener("error", v), t.removeListener("unpipe", f), r.removeListener("end", c), r.removeListener("end", b), r.removeListener("data", g), h = !0, !o.awaitDrain || t._writableState && !t._writableState.needDrain || l());
32656          }
32657
32658          function c() {
32659            d("onend"), t.end();
32660          }
32661
32662          o.endEmitted ? i.nextTick(u) : r.once("end", u), t.on("unpipe", f);
32663
32664          var l = function (t) {
32665            return function () {
32666              var e = t._readableState;
32667              d("pipeOnDrain", e.awaitDrain), e.awaitDrain && e.awaitDrain--, 0 === e.awaitDrain && s(t, "data") && (e.flowing = !0, O(t));
32668            };
32669          }(r);
32670
32671          t.on("drain", l);
32672          var h = !1;
32673          var p = !1;
32674
32675          function g(e) {
32676            d("ondata"), p = !1, !1 !== t.write(e) || p || ((1 === o.pipesCount && o.pipes === t || o.pipesCount > 1 && -1 !== P(o.pipes, t)) && !h && (d("false write response, pause", r._readableState.awaitDrain), r._readableState.awaitDrain++, p = !0), r.pause());
32677          }
32678
32679          function v(e) {
32680            d("onerror", e), b(), t.removeListener("error", v), 0 === s(t, "error") && t.emit("error", e);
32681          }
32682
32683          function y() {
32684            t.removeListener("finish", m), b();
32685          }
32686
32687          function m() {
32688            d("onfinish"), t.removeListener("close", y), b();
32689          }
32690
32691          function b() {
32692            d("unpipe"), r.unpipe(t);
32693          }
32694
32695          return r.on("data", g), function (t, e, r) {
32696            if ("function" == typeof t.prependListener) return t.prependListener(e, r);
32697            t._events && t._events[e] ? a(t._events[e]) ? t._events[e].unshift(r) : t._events[e] = [r, t._events[e]] : t.on(e, r);
32698          }(t, "error", v), t.once("close", y), t.once("finish", m), t.emit("pipe", r), o.flowing || (d("pipe resume"), r.resume()), t;
32699        }, b.prototype.unpipe = function (t) {
32700          var e = this._readableState,
32701              r = {
32702            hasUnpiped: !1
32703          };
32704          if (0 === e.pipesCount) return this;
32705          if (1 === e.pipesCount) return t && t !== e.pipes ? this : (t || (t = e.pipes), e.pipes = null, e.pipesCount = 0, e.flowing = !1, t && t.emit("unpipe", this, r), this);
32706
32707          if (!t) {
32708            var n = e.pipes,
32709                i = e.pipesCount;
32710            e.pipes = null, e.pipesCount = 0, e.flowing = !1;
32711
32712            for (var o = 0; o < i; o++) n[o].emit("unpipe", this, r);
32713
32714            return this;
32715          }
32716
32717          var a = P(e.pipes, t);
32718          return -1 === a ? this : (e.pipes.splice(a, 1), e.pipesCount -= 1, 1 === e.pipesCount && (e.pipes = e.pipes[0]), t.emit("unpipe", this, r), this);
32719        }, b.prototype.on = function (t, e) {
32720          var r = u.prototype.on.call(this, t, e);
32721          if ("data" === t) !1 !== this._readableState.flowing && this.resume();else if ("readable" === t) {
32722            var n = this._readableState;
32723            n.endEmitted || n.readableListening || (n.readableListening = n.needReadable = !0, n.emittedReadable = !1, n.reading ? n.length && S(this) : i.nextTick(T, this));
32724          }
32725          return r;
32726        }, b.prototype.addListener = b.prototype.on, b.prototype.resume = function () {
32727          var t = this._readableState;
32728          return t.flowing || (d("resume"), t.flowing = !0, function (t, e) {
32729            e.resumeScheduled || (e.resumeScheduled = !0, i.nextTick(R, t, e));
32730          }(this, t)), this;
32731        }, b.prototype.pause = function () {
32732          return d("call pause flowing=%j", this._readableState.flowing), !1 !== this._readableState.flowing && (d("pause"), this._readableState.flowing = !1, this.emit("pause")), this;
32733        }, b.prototype.wrap = function (t) {
32734          var e = this,
32735              r = this._readableState,
32736              n = !1;
32737
32738          for (var i in t.on("end", function () {
32739            if (d("wrapped end"), r.decoder && !r.ended) {
32740              var t = r.decoder.end();
32741              t && t.length && e.push(t);
32742            }
32743
32744            e.push(null);
32745          }), t.on("data", function (i) {
32746            (d("wrapped data"), r.decoder && (i = r.decoder.write(i)), r.objectMode && null == i) || (r.objectMode || i && i.length) && (e.push(i) || (n = !0, t.pause()));
32747          }), t) void 0 === this[i] && "function" == typeof t[i] && (this[i] = function (e) {
32748            return function () {
32749              return t[e].apply(t, arguments);
32750            };
32751          }(i));
32752
32753          for (var o = 0; o < y.length; o++) t.on(y[o], this.emit.bind(this, y[o]));
32754
32755          return this._read = function (e) {
32756            d("wrapped _read", e), n && (n = !1, t.resume());
32757          }, this;
32758        }, Object.defineProperty(b.prototype, "readableHighWaterMark", {
32759          enumerable: !1,
32760          get: function () {
32761            return this._readableState.highWaterMark;
32762          }
32763        }), b._fromList = I;
32764      }).call(this, r(23), r(38));
32765    }, function (t, e, r) {
32766      t.exports = r(91).EventEmitter;
32767    }, function (t, e, r) {
32768
32769      var n = r(70);
32770
32771      function i(t, e) {
32772        t.emit("error", e);
32773      }
32774
32775      t.exports = {
32776        destroy: function (t, e) {
32777          var r = this,
32778              o = this._readableState && this._readableState.destroyed,
32779              a = this._writableState && this._writableState.destroyed;
32780          return o || a ? (e ? e(t) : !t || this._writableState && this._writableState.errorEmitted || n.nextTick(i, this, t), this) : (this._readableState && (this._readableState.destroyed = !0), this._writableState && (this._writableState.destroyed = !0), this._destroy(t || null, function (t) {
32781            !e && t ? (n.nextTick(i, r, t), r._writableState && (r._writableState.errorEmitted = !0)) : e && e(t);
32782          }), this);
32783        },
32784        undestroy: function () {
32785          this._readableState && (this._readableState.destroyed = !1, this._readableState.reading = !1, this._readableState.ended = !1, this._readableState.endEmitted = !1), this._writableState && (this._writableState.destroyed = !1, this._writableState.ended = !1, this._writableState.ending = !1, this._writableState.finished = !1, this._writableState.errorEmitted = !1);
32786        }
32787      };
32788    }, function (t, e, r) {
32789
32790      var n = r(71).Buffer,
32791          i = n.isEncoding || function (t) {
32792        switch ((t = "" + t) && t.toLowerCase()) {
32793          case "hex":
32794          case "utf8":
32795          case "utf-8":
32796          case "ascii":
32797          case "binary":
32798          case "base64":
32799          case "ucs2":
32800          case "ucs-2":
32801          case "utf16le":
32802          case "utf-16le":
32803          case "raw":
32804            return !0;
32805
32806          default:
32807            return !1;
32808        }
32809      };
32810
32811      function o(t) {
32812        var e;
32813
32814        switch (this.encoding = function (t) {
32815          var e = function (t) {
32816            if (!t) return "utf8";
32817
32818            for (var e;;) switch (t) {
32819              case "utf8":
32820              case "utf-8":
32821                return "utf8";
32822
32823              case "ucs2":
32824              case "ucs-2":
32825              case "utf16le":
32826              case "utf-16le":
32827                return "utf16le";
32828
32829              case "latin1":
32830              case "binary":
32831                return "latin1";
32832
32833              case "base64":
32834              case "ascii":
32835              case "hex":
32836                return t;
32837
32838              default:
32839                if (e) return;
32840                t = ("" + t).toLowerCase(), e = !0;
32841            }
32842          }(t);
32843
32844          if ("string" != typeof e && (n.isEncoding === i || !i(t))) throw new Error("Unknown encoding: " + t);
32845          return e || t;
32846        }(t), this.encoding) {
32847          case "utf16le":
32848            this.text = u, this.end = f, e = 4;
32849            break;
32850
32851          case "utf8":
32852            this.fillLast = s, e = 4;
32853            break;
32854
32855          case "base64":
32856            this.text = c, this.end = l, e = 3;
32857            break;
32858
32859          default:
32860            return this.write = h, void (this.end = d);
32861        }
32862
32863        this.lastNeed = 0, this.lastTotal = 0, this.lastChar = n.allocUnsafe(e);
32864      }
32865
32866      function a(t) {
32867        return t <= 127 ? 0 : t >> 5 == 6 ? 2 : t >> 4 == 14 ? 3 : t >> 3 == 30 ? 4 : t >> 6 == 2 ? -1 : -2;
32868      }
32869
32870      function s(t) {
32871        var e = this.lastTotal - this.lastNeed,
32872            r = function (t, e, r) {
32873          if (128 != (192 & e[0])) return t.lastNeed = 0, "�";
32874
32875          if (t.lastNeed > 1 && e.length > 1) {
32876            if (128 != (192 & e[1])) return t.lastNeed = 1, "�";
32877            if (t.lastNeed > 2 && e.length > 2 && 128 != (192 & e[2])) return t.lastNeed = 2, "�";
32878          }
32879        }(this, t);
32880
32881        return void 0 !== r ? r : this.lastNeed <= t.length ? (t.copy(this.lastChar, e, 0, this.lastNeed), this.lastChar.toString(this.encoding, 0, this.lastTotal)) : (t.copy(this.lastChar, e, 0, t.length), void (this.lastNeed -= t.length));
32882      }
32883
32884      function u(t, e) {
32885        if ((t.length - e) % 2 == 0) {
32886          var r = t.toString("utf16le", e);
32887
32888          if (r) {
32889            var n = r.charCodeAt(r.length - 1);
32890            if (n >= 55296 && n <= 56319) return this.lastNeed = 2, this.lastTotal = 4, this.lastChar[0] = t[t.length - 2], this.lastChar[1] = t[t.length - 1], r.slice(0, -1);
32891          }
32892
32893          return r;
32894        }
32895
32896        return this.lastNeed = 1, this.lastTotal = 2, this.lastChar[0] = t[t.length - 1], t.toString("utf16le", e, t.length - 1);
32897      }
32898
32899      function f(t) {
32900        var e = t && t.length ? this.write(t) : "";
32901
32902        if (this.lastNeed) {
32903          var r = this.lastTotal - this.lastNeed;
32904          return e + this.lastChar.toString("utf16le", 0, r);
32905        }
32906
32907        return e;
32908      }
32909
32910      function c(t, e) {
32911        var r = (t.length - e) % 3;
32912        return 0 === r ? t.toString("base64", e) : (this.lastNeed = 3 - r, this.lastTotal = 3, 1 === r ? this.lastChar[0] = t[t.length - 1] : (this.lastChar[0] = t[t.length - 2], this.lastChar[1] = t[t.length - 1]), t.toString("base64", e, t.length - r));
32913      }
32914
32915      function l(t) {
32916        var e = t && t.length ? this.write(t) : "";
32917        return this.lastNeed ? e + this.lastChar.toString("base64", 0, 3 - this.lastNeed) : e;
32918      }
32919
32920      function h(t) {
32921        return t.toString(this.encoding);
32922      }
32923
32924      function d(t) {
32925        return t && t.length ? this.write(t) : "";
32926      }
32927
32928      e.StringDecoder = o, o.prototype.write = function (t) {
32929        if (0 === t.length) return "";
32930        var e, r;
32931
32932        if (this.lastNeed) {
32933          if (void 0 === (e = this.fillLast(t))) return "";
32934          r = this.lastNeed, this.lastNeed = 0;
32935        } else r = 0;
32936
32937        return r < t.length ? e ? e + this.text(t, r) : this.text(t, r) : e || "";
32938      }, o.prototype.end = function (t) {
32939        var e = t && t.length ? this.write(t) : "";
32940        return this.lastNeed ? e + "�" : e;
32941      }, o.prototype.text = function (t, e) {
32942        var r = function (t, e, r) {
32943          var n = e.length - 1;
32944          if (n < r) return 0;
32945          var i = a(e[n]);
32946          if (i >= 0) return i > 0 && (t.lastNeed = i - 1), i;
32947          if (--n < r || -2 === i) return 0;
32948          if ((i = a(e[n])) >= 0) return i > 0 && (t.lastNeed = i - 2), i;
32949          if (--n < r || -2 === i) return 0;
32950          if ((i = a(e[n])) >= 0) return i > 0 && (2 === i ? i = 0 : t.lastNeed = i - 3), i;
32951          return 0;
32952        }(this, t, e);
32953
32954        if (!this.lastNeed) return t.toString("utf8", e);
32955        this.lastTotal = r;
32956        var n = t.length - (r - this.lastNeed);
32957        return t.copy(this.lastChar, 0, n), t.toString("utf8", e, n);
32958      }, o.prototype.fillLast = function (t) {
32959        if (this.lastNeed <= t.length) return t.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed), this.lastChar.toString(this.encoding, 0, this.lastTotal);
32960        t.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, t.length), this.lastNeed -= t.length;
32961      };
32962    }, function (t, e, r) {
32963
32964      t.exports = a;
32965      var n = r(39),
32966          i = r(57);
32967
32968      function o(t, e) {
32969        var r = this._transformState;
32970        r.transforming = !1;
32971        var n = r.writecb;
32972        if (!n) return this.emit("error", new Error("write callback called multiple times"));
32973        r.writechunk = null, r.writecb = null, null != e && this.push(e), n(t);
32974        var i = this._readableState;
32975        i.reading = !1, (i.needReadable || i.length < i.highWaterMark) && this._read(i.highWaterMark);
32976      }
32977
32978      function a(t) {
32979        if (!(this instanceof a)) return new a(t);
32980        n.call(this, t), this._transformState = {
32981          afterTransform: o.bind(this),
32982          needTransform: !1,
32983          transforming: !1,
32984          writecb: null,
32985          writechunk: null,
32986          writeencoding: null
32987        }, this._readableState.needReadable = !0, this._readableState.sync = !1, t && ("function" == typeof t.transform && (this._transform = t.transform), "function" == typeof t.flush && (this._flush = t.flush)), this.on("prefinish", s);
32988      }
32989
32990      function s() {
32991        var t = this;
32992        "function" == typeof this._flush ? this._flush(function (e, r) {
32993          u(t, e, r);
32994        }) : u(this, null, null);
32995      }
32996
32997      function u(t, e, r) {
32998        if (e) return t.emit("error", e);
32999        if (null != r && t.push(r), t._writableState.length) throw new Error("Calling transform done when ws.length != 0");
33000        if (t._transformState.transforming) throw new Error("Calling transform done when still transforming");
33001        return t.push(null);
33002      }
33003
33004      i.inherits = r(47), i.inherits(a, n), a.prototype.push = function (t, e) {
33005        return this._transformState.needTransform = !1, n.prototype.push.call(this, t, e);
33006      }, a.prototype._transform = function (t, e, r) {
33007        throw new Error("_transform() is not implemented");
33008      }, a.prototype._write = function (t, e, r) {
33009        var n = this._transformState;
33010
33011        if (n.writecb = r, n.writechunk = t, n.writeencoding = e, !n.transforming) {
33012          var i = this._readableState;
33013          (n.needTransform || i.needReadable || i.length < i.highWaterMark) && this._read(i.highWaterMark);
33014        }
33015      }, a.prototype._read = function (t) {
33016        var e = this._transformState;
33017        null !== e.writechunk && e.writecb && !e.transforming ? (e.transforming = !0, this._transform(e.writechunk, e.writeencoding, e.afterTransform)) : e.needTransform = !0;
33018      }, a.prototype._destroy = function (t, e) {
33019        var r = this;
33020
33021        n.prototype._destroy.call(this, t, function (t) {
33022          e(t), r.emit("close");
33023        });
33024      };
33025    }, function (t, e, r) {
33026
33027      (function (e) {
33028        var n = r(213);
33029        /*!
33030         * The buffer module from node.js, for the browser.
33031         *
33032         * @author   Feross Aboukhadijeh <[email protected]> <http://feross.org>
33033         * @license  MIT
33034         */
33035
33036        function i(t, e) {
33037          if (t === e) return 0;
33038
33039          for (var r = t.length, n = e.length, i = 0, o = Math.min(r, n); i < o; ++i) if (t[i] !== e[i]) {
33040            r = t[i], n = e[i];
33041            break;
33042          }
33043
33044          return r < n ? -1 : n < r ? 1 : 0;
33045        }
33046
33047        function o(t) {
33048          return e.Buffer && "function" == typeof e.Buffer.isBuffer ? e.Buffer.isBuffer(t) : !(null == t || !t._isBuffer);
33049        }
33050
33051        var a = r(133),
33052            s = Object.prototype.hasOwnProperty,
33053            u = Array.prototype.slice,
33054            f = "foo" === function () {}.name;
33055
33056        function c(t) {
33057          return Object.prototype.toString.call(t);
33058        }
33059
33060        function l(t) {
33061          return !o(t) && "function" == typeof e.ArrayBuffer && ("function" == typeof ArrayBuffer.isView ? ArrayBuffer.isView(t) : !!t && (t instanceof DataView || !!(t.buffer && t.buffer instanceof ArrayBuffer)));
33062        }
33063
33064        var h = t.exports = m,
33065            d = /\s*function\s+([^\(\s]*)\s*/;
33066
33067        function p(t) {
33068          if (a.isFunction(t)) {
33069            if (f) return t.name;
33070            var e = t.toString().match(d);
33071            return e && e[1];
33072          }
33073        }
33074
33075        function g(t, e) {
33076          return "string" == typeof t ? t.length < e ? t : t.slice(0, e) : t;
33077        }
33078
33079        function v(t) {
33080          if (f || !a.isFunction(t)) return a.inspect(t);
33081          var e = p(t);
33082          return "[Function" + (e ? ": " + e : "") + "]";
33083        }
33084
33085        function y(t, e, r, n, i) {
33086          throw new h.AssertionError({
33087            message: r,
33088            actual: t,
33089            expected: e,
33090            operator: n,
33091            stackStartFunction: i
33092          });
33093        }
33094
33095        function m(t, e) {
33096          t || y(t, !0, e, "==", h.ok);
33097        }
33098
33099        function b(t, e, r, n) {
33100          if (t === e) return !0;
33101          if (o(t) && o(e)) return 0 === i(t, e);
33102          if (a.isDate(t) && a.isDate(e)) return t.getTime() === e.getTime();
33103          if (a.isRegExp(t) && a.isRegExp(e)) return t.source === e.source && t.global === e.global && t.multiline === e.multiline && t.lastIndex === e.lastIndex && t.ignoreCase === e.ignoreCase;
33104
33105          if (null !== t && "object" == typeof t || null !== e && "object" == typeof e) {
33106            if (l(t) && l(e) && c(t) === c(e) && !(t instanceof Float32Array || t instanceof Float64Array)) return 0 === i(new Uint8Array(t.buffer), new Uint8Array(e.buffer));
33107            if (o(t) !== o(e)) return !1;
33108            var s = (n = n || {
33109              actual: [],
33110              expected: []
33111            }).actual.indexOf(t);
33112            return -1 !== s && s === n.expected.indexOf(e) || (n.actual.push(t), n.expected.push(e), function (t, e, r, n) {
33113              if (null == t || null == e) return !1;
33114              if (a.isPrimitive(t) || a.isPrimitive(e)) return t === e;
33115              if (r && Object.getPrototypeOf(t) !== Object.getPrototypeOf(e)) return !1;
33116
33117              var i = _(t),
33118                  o = _(e);
33119
33120              if (i && !o || !i && o) return !1;
33121              if (i) return t = u.call(t), e = u.call(e), b(t, e, r);
33122              var s,
33123                  f,
33124                  c = E(t),
33125                  l = E(e);
33126              if (c.length !== l.length) return !1;
33127
33128              for (c.sort(), l.sort(), f = c.length - 1; f >= 0;
33128 f--) if (c[f] !== l[f]) return !1;
33129
33130              for (f = c.length - 1; f >= 0; f--) if (s = c[f], !b(t[s], e[s], r, n)) return !1;
33131
33132              return !0;
33133            }(t, e, r, n));
33134          }
33135
33136          return r ? t === e : t == e;
33137        }
33138
33139        function _(t) {
33140          return "[object Arguments]" == Object.prototype.toString.call(t);
33141        }
33142
33143        function w(t, e) {
33144          if (!t || !e) return !1;
33145          if ("[object RegExp]" == Object.prototype.toString.call(e)) return e.test(t);
33146
33147          try {
33148            if (t instanceof e) return !0;
33149          } catch (t) {}
33150
33151          return !Error.isPrototypeOf(e) && !0 === e.call({}, t);
33152        }
33153
33154        function x(t, e, r, n) {
33155          var i;
33156          if ("function" != typeof e) throw new TypeError('"block" argument must be a function');
33157          "string" == typeof r && (n = r, r = null), i = function (t) {
33158            var e;
33159
33160            try {
33161              t();
33162            } catch (t) {
33163              e = t;
33164            }
33165
33166            return e;
33167          }(e), n = (r && r.name ? " (" + r.name + ")." : ".") + (n ? " " + n : "."), t && !i && y(i, r, "Missing expected exception" + n);
33168          var o = "string" == typeof n,
33169              s = !t && i && !r;
33170          if ((!t && a.isError(i) && o && w(i, r) || s) && y(i, r, "Got unwanted exception" + n), t && i && r && !w(i, r) || !t && i) throw i;
33171        }
33172
33173        h.AssertionError = function (t) {
33174          this.name = "AssertionError", this.actual = t.actual, this.expected = t.expected, this.operator = t.operator, t.message ? (this.message = t.message, this.generatedMessage = !1) : (this.message = function (t) {
33175            return g(v(t.actual), 128) + " " + t.operator + " " + g(v(t.expected), 128);
33176          }(this), this.generatedMessage = !0);
33177          var e = t.stackStartFunction || y;
33178          if (Error.captureStackTrace) Error.captureStackTrace(this, e);else {
33179            var r = new Error();
33180
33181            if (r.stack) {
33182              var n = r.stack,
33183                  i = p(e),
33184                  o = n.indexOf("\n" + i);
33185
33186              if (o >= 0) {
33187                var a = n.indexOf("\n", o + 1);
33188                n = n.substring(a + 1);
33189              }
33190
33191              this.stack = n;
33192            }
33193          }
33194        }, a.inherits(h.AssertionError, Error), h.fail = y, h.ok = m, h.equal = function (t, e, r) {
33195          t != e && y(t, e, r, "==", h.equal);
33196        }, h.notEqual = function (t, e, r) {
33197          t == e && y(t, e, r, "!=", h.notEqual);
33198        }, h.deepEqual = function (t, e, r) {
33199          b(t, e, !1) || y(t, e, r, "deepEqual", h.deepEqual);
33200        }, h.deepStrictEqual = function (t, e, r) {
33201          b(t, e, !0) || y(t, e, r, "deepStrictEqual", h.deepStrictEqual);
33202        }, h.notDeepEqual = function (t, e, r) {
33203          b(t, e, !1) && y(t, e, r, "notDeepEqual", h.notDeepEqual);
33204        }, h.notDeepStrictEqual = function t(e, r, n) {
33205          b(e, r, !0) && y(e, r, n, "notDeepStrictEqual", t);
33206        }, h.strictEqual = function (t, e, r) {
33207          t !== e && y(t, e, r, "===", h.strictEqual);
33208        }, h.notStrictEqual = function (t, e, r) {
33209          t === e && y(t, e, r, "!==", h.notStrictEqual);
33210        }, h.throws = function (t, e, r) {
33211          x(!0, t, e, r);
33212        }, h.doesNotThrow = function (t, e, r) {
33213          x(!1, t, e, r);
33214        }, h.ifError = function (t) {
33215          if (t) throw t;
33216        }, h.strict = n(function t(e, r) {
33217          e || y(e, !0, r, "==", t);
33218        }, h, {
33219          equal: h.strictEqual,
33220          deepEqual: h.deepStrictEqual,
33221          notEqual: h.notStrictEqual,
33222          notDeepEqual: h.notDeepStrictEqual
33223        }), h.strict.strict = h.strict;
33224
33225        var E = Object.keys || function (t) {
33226          var e = [];
33227
33228          for (var r in t) s.call(t, r) && e.push(r);
33229
33230          return e;
33231        };
33232      }).call(this, r(23));
33233    }, function (t, e, r) {
33234      (function (t) {
33235        var n = Object.getOwnPropertyDescriptors || function (t) {
33236          for (var e = Object.keys(t), r = {}, n = 0; n < e.length; n++) r[e[n]] = Object.getOwnPropertyDescriptor(t, e[n]);
33237
33238          return r;
33239        },
33240            i = /%[sdj%]/g;
33241
33242        e.format = function (t) {
33243          if (!y(t)) {
33244            for (var e = [], r = 0; r < arguments.length; r++) e.push(s(arguments[r]));
33245
33246            return e.join(" ");
33247          }
33248
33249          r = 1;
33250
33251          for (var n = arguments, o = n.length, a = String(t).replace(i, function (t) {
33252            if ("%%" === t) return "%";
33253            if (r >= o) return t;
33254
33255            switch (t) {
33256              case "%s":
33257                return String(n[r++]);
33258
33259              case "%d":
33260                return Number(n[r++]);
33261
33262              case "%j":
33263                try {
33264                  return JSON.stringify(n[r++]);
33265                } catch (t) {
33266                  return "[Circular]";
33267                }
33268
33269              default:
33270                return t;
33271            }
33272          }), u = n[r]; r < o; u = n[++r]) g(u) || !_(u) ? a += " " + u : a += " " + s(u);
33273
33274          return a;
33275        }, e.deprecate = function (r, n) {
33276          if (void 0 !== t && !0 === t.noDeprecation) return r;
33277          if (void 0 === t) return function () {
33278            return e.deprecate(r, n).apply(this, arguments);
33279          };
33280          var i = !1;
33281          return function () {
33282            if (!i) {
33283              if (t.throwDeprecation) throw new Error(n);
vendor: 4,125 bytes, lines 33284-33382
33284              t.traceDeprecation ? console.trace(n) : console.error(n), i = !0;
33285            }
33286
33287            return r.apply(this, arguments);
33288          };
33289        };
33290        var o,
33291            a = {};
33292
33293        function s(t, r) {
33294          var n = {
33295            seen: [],
33296            stylize: f
33297          };
33298          return arguments.length >= 3 && (n.depth = arguments[2]), arguments.length >= 4 && (n.colors = arguments[3]), p(r) ? n.showHidden = r : r && e._extend(n, r), m(n.showHidden) && (n.showHidden = !1), m(n.depth) && (n.depth = 2), m(n.colors) && (n.colors = !1), m(n.customInspect) && (n.customInspect = !0), n.colors && (n.stylize = u), c(n, t, n.depth);
33299        }
33300
33301        function u(t, e) {
33302          var r = s.styles[e];
33303          return r ? "�[" + s.colors[r][0] + "m" + t + "�[" + s.colors[r][1] + "m" : t;
33304        }
33305
33306        function f(t, e) {
33307          return t;
33308        }
33309
33310        function c(t, r, n) {
33311          if (t.customInspect && r && E(r.inspect) && r.inspect !== e.inspect && (!r.constructor || r.constructor.prototype !== r)) {
33312            var i = r.inspect(n, t);
33313            return y(i) || (i = c(t, i, n)), i;
33314          }
33315
33316          var o = function (t, e) {
33317            if (m(e)) return t.stylize("undefined", "undefined");
33318
33319            if (y(e)) {
33320              var r = "'" + JSON.stringify(e).replace(/^"|"$/g, "").replace(/'/g, "\\'").replace(/\\"/g, '"') + "'";
33321              return t.stylize(r, "string");
33322            }
33323
33324            if (v(e)) return t.stylize("" + e, "number");
33325            if (p(e)) return t.stylize("" + e, "boolean");
33326            if (g(e)) return t.stylize("null", "null");
33327          }(t, r);
33328
33329          if (o) return o;
33330
33331          var a = Object.keys(r),
33332              s = function (t) {
33333            var e = {};
33334            return t.forEach(function (t, r) {
33335              e[t] = !0;
33336            }), e;
33337          }(a);
33338
33339          if (t.showHidden && (a = Object.getOwnPropertyNames(r)), x(r) && (a.indexOf("message") >= 0 || a.indexOf("description") >= 0)) return l(r);
33340
33341          if (0 === a.length) {
33342            if (E(r)) {
33343              var u = r.name ? ": " + r.name : "";
33344              return t.stylize("[Function" + u + "]", "special");
33345            }
33346
33347            if (b(r)) return t.stylize(RegExp.prototype.toString.call(r), "regexp");
33348            if (w(r)) return t.stylize(Date.prototype.toString.call(r), "date");
33349            if (x(r)) return l(r);
33350          }
33351
33352          var f,
33353              _ = "",
33354              S = !1,
33355              k = ["{", "}"];
33356          (d(r) && (S = !0, k = ["[", "]"]), E(r)) && (_ = " [Function" + (r.name ? ": " + r.name : "") + "]");
33357          return b(r) && (_ = " " + RegExp.prototype.toString.call(r)), w(r) && (_ = " " + Date.prototype.toUTCString.call(r)), x(r) && (_ = " " + l(r)), 0 !== a.length || S && 0 != r.length ? n < 0 ? b(r) ? t.stylize(RegExp.prototype.toString.call(r), "regexp") : t.stylize("[Object]", "special") : (t.seen.push(r), f = S ? function (t, e, r, n, i) {
33358            for (var o = [], a = 0, s = e.length; a < s; ++a) T(e, String(a)) ? o.push(h(t, e, r, n, String(a), !0)) : o.push("");
33359
33360            return i.forEach(function (i) {
33361              i.match(/^\d+$/) || o.push(h(t, e, r, n, i, !0));
33362            }), o;
33363          }(t, r, n, s, a) : a.map(function (e) {
33364            return h(t, r, n, s, e, S);
33365          }), t.seen.pop(), function (t, e, r) {
33366            if (t.reduce(function (t, e) {
33367              return e.indexOf("\n") >= 0 && 0, t + e.replace(/\u001b\[\d\d?m/g, "").length + 1;
33368            }, 0) > 60) return r[0] + ("" === e ? "" : e + "\n ") + " " + t.join(",\n  ") + " " + r[1];
33369            return r[0] + e + " " + t.join(", ") + " " + r[1];
33370          }(f, _, k)) : k[0] + _ + k[1];
33371        }
33372
33373        function l(t) {
33374          return "[" + Error.prototype.toString.call(t) + "]";
33375        }
33376
33377        function h(t, e, r, n, i, o) {
33378          var a, s, u;
33379
33380          if ((u = Object.getOwnPropertyDescriptor(e, i) || {
33381            value: e[i]
33382          }).get ? s = u.set ? t.stylize("[Getter/Setter]", "special") : t.stylize("[Getter]", "special") : u.set && (s = t.stylize("[
33382Setter]", "special")), T(n, i) || (a = "[" + i + "]"), s || (t.seen.indexOf(u.value) < 0 ? (s = g(r) ? c(t, u.value, null) : c(t, u.value, r - 1)).indexOf("\n") > -1 && (s = o ? s.split("\n").map(function (t) {
33383            return "  " + t;
33384          }).join("\n").substr(2) : "\n" + s.split("\n").map(function (t) {
33385            return "   " + t;
33386          }).join("\n")) : s = t.stylize("[Circular]", "special")), m(a)) {
33387            if (o && i.match(/^\d+$/)) return s;
33388            (a = JSON.stringify("" + i)).match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/) ? (a = a.substr(1, a.length - 2), a = t.stylize(a, "name")) : (a = a.replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'"), a = t.stylize(a, "string"));
33389          }
33390
33391          return a + ": " + s;
33392        }
33393
33394        function d(t) {
33395          return Array.isArray(t);
33396        }
33397
33398        function p(t) {
33399          return "boolean" == typeof t;
33400        }
33401
33402        function g(t) {
33403          return null === t;
33404        }
33405
33406        function v(t) {
33407          return "number" == typeof t;
33408        }
33409
33410        function y(t) {
33411          return "string" == typeof t;
33412        }
33413
33414        function m(t) {
33415          return void 0 === t;
33416        }
33417
33418        function b(t) {
33419          return _(t) && "[object RegExp]" === S(t);
33420        }
33421
33422        function _(t) {
33423          return "object" == typeof t && null !== t;
33424        }
33425
33426        function w(t) {
33427          return _(t) && "[object Date]" === S(t);
33428        }
33429
33430        function x(t) {
33431          return _(t) && ("[object Error]" === S(t) || t instanceof Error);
33432        }
33433
33434        function E(t) {
33435          return "function" == typeof t;
33436        }
33437
33438        function S(t) {
33439          return Object.prototype.toString.call(t);
33440        }
33441
33442        function k(t) {
33443          return t < 10 ? "0" + t.toString(10) : t.toString(10);
33444        }
33445
33446        e.debuglog = function (r) {
33447          if (m(o) && (o = t.env.NODE_DEBUG || ""), r = r.toUpperCase(), !a[r]) if (new RegExp("\\b" + r + "\\b", "i").test(o)) {
33448            var n = t.pid;
33449
33450            a[r] = function () {
33451              var t = e.format.apply(e, arguments);
33452              console.error("%s %d: %s", r, n, t);
33453            };
33454          } else a[r] = function () {};
33455          return a[r];
33456        }, e.inspect = s, s.colors = {
33457          bold: [1, 22],
33458          italic: [3, 23],
33459          underline: [4, 24],
33460          inverse: [7, 27],
33461          white: [37, 39],
33462          grey: [90, 39],
33463          black: [30, 39],
33464          blue: [34, 39],
33465          cyan: [36, 39],
33466          green: [32, 39],
33467          magenta: [35, 39],
33468          red: [31, 39],
33469          yellow: [33, 39]
33470        }, s.styles = {
33471          special: "cyan",
33472          number: "yellow",
33473          boolean: "yellow",
33474          undefined: "grey",
33475          null: "bold",
33476          string: "green",
33477          date: "magenta",
33478          regexp: "red"
33479        }, e.isArray = d, e.isBoolean = p, e.isNull = g, e.isNullOrUndefined = function (t) {
33480          return null == t;
33481        }, e.isNumber = v, e.isString = y, e.isSymbol = function (t) {
33482          return "symbol" == typeof t;
33483        }, e.isUndefined = m, e.isRegExp = b, e.isObject = _, e.isDate = w, e.isError = x, e.isFunction = E, e.isPrimitive = function (t) {
33484          return null === t || "boolean" == typeof t || "number" == typeof t || "string" == typeof t || "symbol" == typeof t || void 0 === t;
33485        }, e.isBuffer = r(214);
33486        var A = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
33487
33488        function C() {
33489          var t = new Date(),
33490              e = [k(t.getHours()), k(t.getMinutes()), k(t.getSeconds())].join(":");
33491          return [t.getDate(), A[t.getMonth()], e].join(" ");
33492        }
33493
33494        function T(t, e) {
33495          return Object.prototype.hasOwnProperty.call(t, e);
33496        }
33497
33498        e.log = function () {
33499          console.log("%s - %s", C(), e.format.apply(e, arguments));
33500        }, e.inherits = r(215), e._extend = function (t, e) {
33501          if (!e || !_(e)) return t;
33502
33503          for (var r = Object.keys(e), n = r.length; n--;) t[r[n]] = e[r[n]];
33504
33505          return t;
33506        };
33507        var R = "undefined" != typeof Symbol ? Symbol("util.promisify.custom") : void 0;
33508
33509        function O(t, e) {
33510          if (!t) {
33511            var r = new Error("Promise was rejected with a falsy value");
33512            r.reason = t, t = r;
33513          }
33514
33515          return e(t);
33516        }
33517
33518        e.promisify = function (t) {
33519          if ("function" != typeof t) throw new TypeError('The "original" argument must be of type Function');
33520
33521          if (R && t[R]) {
33522            var e;
33523            if ("function" != typeof (e = t[R])) throw new TypeError('The "util.promisify.custom" argument must be of type Function');
33524            return Object.defineProperty(e, R, {
33525              value: e,
33526              enumerable: !1,
33527              writable: !1,
33528              configurable: !0
33529            }), e;
33530          }
33531
33532          function e() {
33533            for (var e, r, n = new Promise(function (t, n) {
33534              e = t, r = n;
33535            }), i = [], o = 0; o < arguments.length; o++) i.push(arguments[o]);
33536
33537            i.push(function (t, n) {
33538              t ? r(t) : e(n);
33539            });
33540
33541            try {
33542              t.apply(this, i);
33543            } catch (t) {
33544              r(t);
33545            }
33546
33547            return n;
33548          }
33549
33550          return Object.setPrototypeOf(e, Object.getPrototypeOf(t)), R && Object.defineProperty(e, R, {
33551            value: e,
33552            enumerable: !1,
33553            writable: !1,
33554            configurable: !0
33555          }), Object.defineProperties(e, n(t));
33556        }, e.promisify.custom = R, e.callbackify = function (e) {
33557          if ("function" != typeof e) throw new TypeError('The "original" argument must be of type Function');
33558
33559          function r() {
33560            for (var r = [], n = 0; n < arguments.length;
33560 n++) r.push(arguments[n]);
33561
33562            var i = r.pop();
33563            if ("function" != typeof i) throw new TypeError("The last argument must be of type Function");
33564
33565            var o = this,
33566                a = function () {
33567              return i.apply(o, arguments);
33568            };
33569
33570            e.apply(this, r).then(function (e) {
33571              t.nextTick(a, null, e);
33572            }, function (e) {
33573              t.nextTick(O, e, a);
33574            });
33575          }
33576
33577          return Object.setPrototypeOf(r, Object.getPrototypeOf(e)), Object.defineProperties(r, n(e)), r;
33578        };
33579      }).call(this, r(38));
33580    }, function (t, e, r) {
33581
33582      t.exports = function (t, e, r, n) {
33583        for (var i = 65535 & t | 0, o = t >>> 16 & 65535 | 0, a = 0; 0 !== r;) {
33584          r -= a = r > 2e3 ? 2e3 : r;
33585
33586          do {
33587            o = o + (i = i + e[n++] | 0) | 0;
33588          } while (--a);
33589
33590          i %= 65521, o %= 65521;
33591        }
33592
33593        return i | o << 16 | 0;
33594      };
33595    }, function (t, e, r) {
33596
33597      var n = function () {
33598        for (var t, e = [], r = 0; r < 256; r++) {
33599          t = r;
33600
33601          for (var n = 0; n < 8; n++) t = 1 & t ? 3988292384 ^ t >>> 1 : t >>> 1;
33602
33603          e[r] = t;
33604        }
33605
33606        return e;
33607      }();
33608
33609      t.exports = function (t, e, r, i) {
33610        var o = n,
33611            a = i + r;
33612        t ^= -1;
33613
33614        for (var s = i; s < a; s++) t = t >>> 8 ^ o[255 & (t ^ e[s])];
33615
33616        return -1 ^ t;
33617      };
33618    }, function (t, e, r) {
33619      r(11)("iterator");
33620    }, function (t, e, r) {
33621      var n = r(111),
33622          i = r(85).concat("length", "prototype");
33623
33624      e.f = Object.getOwnPropertyNames || function (t) {
33625        return n(t, i);
33626      };
33627    }, function (t, e) {
33628      e.f = Object.getOwnPropertySymbols;
33629    }, function (t, e, r) {
33630      t.exports = r(259);
33631    }, function (t, e, r) {
33632      t.exports = r(262);
33633    }, function (t, e, r) {
33634      var n = r(50),
33635          i = r(14),
33636          o = r(24),
33637          a = r(21).f,
33638          s = r(64),
33639          u = r(271),
33640          f = s("meta"),
33641          c = 0,
33642          l = Object.isExtensible || function () {
33643        return !0;
33644      },
33645          h = function (t) {
33646        a(t, f, {
33647          value: {
33648            objectID: "O" + ++c,
33649            weakData: {}
33650          }
33651        });
33652      },
33653          d = t.exports = {
33654        REQUIRED: !1,
33655        fastKey: function (t, e) {
33656          if (!i(t)) return "symbol" == typeof t ? t : ("string" == typeof t ? "S" : "P") + t;
33657
33658          if (!o(t, f)) {
33659            if (!l(t)) return "F";
33660            if (!e) return "E";
33661            h(t);
33662          }
33663
33664          return t[f].objectID;
33665        },
33666        getWeakData: function (t, e) {
33667          if (!o(t, f)) {
33668            if (!l(t)) return !0;
33669            if (!e) return !1;
33670            h(t);
33671          }
33672
33673          return t[f].weakData;
33674        },
33675        onFreeze: function (t) {
33676          return u && d.REQUIRED && l(t) && !o(t, f) && h(t), t;
33677        }
33678      };
33679
33680      n[f] = !0;
33681    }, function (t, e, r) {
33682      var n = r(2),
33683          i = r(90);
33684
33685      t.exports = function (t) {
33686        var e = i(t);
33687        if ("function" != typeof e) throw TypeError(String(t) + " is not iterable");
33688        return n(e.call(t));
33689      };
33690    }, function (t, e, r) {
33691      var n = r(298),
33692          i = Array.prototype;
33693
33694      t.exports = function (t) {
33695        var e = t.indexOf;
33696        return t === i || t instanceof Array && e === i.indexOf ? n : e;
33697      };
33698    }, function (t, e, r) {
33699      var n = r(303),
33700          i = Function.prototype;
33701
33702      t.exports = function (t) {
33703        var e = t.bind;
33704        return t === i || t instanceof Function && e === i.bind ? n : e;
33705      };
33706    }, function (t, e, r) {
33707
33708      var n = r(5),
33709          i = r(14),
33710          o = [].slice,
33711          a = {},
33712          s = function (t, e, r) {
33713        if (!(e in a)) {
33714          for (var n = [], i = 0; i < e; i++) n[i] = "a[" + i + "]";
33715
33716          a[e] = Function("C,a", "return new C(" + n.join(",") + ")");
33717        }
33718
33719        return a[e](t, r);
33720      };
33721
33722      t.exports = Function.bind || function (t) {
33723        var e = n(this),
33724            r = o.call(arguments, 1),
33725            a = function () {
33726          var n = r.concat(o.call(arguments));
33727          return this instanceof a ? s(e, n.length, n) : e.apply(t, n);
33728        };
33729
33730        return i(e.prototype) && (a.prototype = e.prototype), a;
33731      };
33732    }, function (t, e) {
33733      t.exports = n;
33734      var r = null;
33735
33736      try {
33737        r = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11])), {}).exports;
33738      } catch (t) {}
33739
33740      function n(t, e, r) {
33741        this.low = 0 | t, this.high = 0 | e, this.unsigned = !!r;
33742      }
33743
33744      function i(t) {
33745        return !0 === (t && t.__isLong__);
33746      }
33747
33748      n.prototype.__isLong__, Object.defineProperty(n.prototype, "__isLong__", {
33749        value: !0
33750      }), n.isLong = i;
33751      var o = {},
33752          a = {};
33753
33754      function s(t, e) {
33755        var r, n, i;
33756        return e ? (i = 0 <= (t >>>= 0) && t < 256) && (n = a[t]) ? n : (r = f(t, (0 | t) < 0 ? -1 : 0, !0), i && (a[t] = r), r) : (i = -128 <= (t |= 0) && t < 128) && (n = o[t]) ? n : (r = f(t, t < 0 ? -1 : 0, !1), i && (o[t] = r), r);
33757      }
33758
33759      function u(t, e) {
33760        if (isNaN(t)) return e ? m : y;
33761
33762        if (e) {
33763          if (t < 0) return m;
33764          if (t >= p) return E;
33765        } else {
33766          if (t <= -g) return S;
33767          if (t + 1 >= g) return x;
33768        }
33769
33770        return t < 0 ? u(-t, e).neg() : f(t % d | 0, t / d | 0, e);
33771      }
33772
33773      function f(t, e, r) {
33774        return new n(t, e, r);
33775      }
33776
33777      n.fromInt = s, n.fromNumber = u, n.fromBits = f;
33778      var c = Math.pow;
33779
33780      function l(t, e, r) {
33781        if (0 === t.length) throw Error("empty string");
33782        if ("NaN" === t || "Infinity" === t || "+Infinity" === t || "-Infinity" === t) return y;
33783        if ("number" == typeof e ? (r = e, e = !1) : e = !!e, (r = r || 10) < 2 || 36 < r) throw RangeError("radix");
33784        var n;
33785        if ((n = t.indexOf("-")) > 0) throw Error("interior hyphen");
33786        if (0 === n) return l(t.substring(1), e, r).neg();
33787
33788        for (var i = u(c(r, 8)), o = y, a = 0; a < t.length; a += 8) {
33789          var s = Math.min(8, t.length - a),
33790              f = parseInt(t.substring(a, a + s), r);
33791
33792          if (s < 8) {
33793            var h = u(c(r, s));
33794            o = o.mul(h).add(u(f));
33795          } else o = (o = o.mul(i)).add(u(f));
33796        }
33797
33798        return o.unsigned = e, o;
33799      }
33800
33801      function h(t, e) {
33802        return "number" == typeof t ? u(t, e) : "string" == typeof t ? l(t, e) : f(t.low, t.high, "boolean" == typeof e ? e : t.unsigned);
33803      }
33804
33805      n.fromString = l, n.fromValue = h;
33806      var d = 4294967296,
33807          p = d * d,
33808          g = p / 2,
33809          v = s(1 << 24),
33810          y = s(0);
33811      n.ZERO = y;
33812      var m = s(0, !0);
33813      n.UZERO = m;
33814      var b = s(1);
33815      n.ONE = b;
33816
33817      var _ = s(1, !0);
33818
33819      n.UONE = _;
33820      var w = s(-1);
33821      n.NEG_ONE = w;
33822      var x = f(-1, 2147483647, !1);
33823      n.MAX_VALUE = x;
33824      var E = f(-1, -1, !0);
33825      n.MAX_UNSIGNED_VALUE = E;
33826      var S = f(0, -2147483648, !1);
33827      n.MIN_VALUE = S;
33828      var k = n.prototype;
33829      k.toInt = function () {
33830        return this.unsigned ? this.low >>> 0 : this.low;
33831      }, k.toNumber = function () {
33832        return this.unsigned ? (this.high >>> 0) * d + (this.low >>> 0) : this.high * d + (this.low >>> 0);
33833      }, k.toString = function (t) {
33834        if ((t = t || 10) < 2 || 36 < t) throw RangeError("radix");
33835        if (this.isZero()) return "0";
33836
33837        if (this.isNegative()) {
33838          if (this.eq(S)) {
33839            var e = u(t),
33840                r = this.div(e),
33841                n = r.mul(e).sub(this);
33842            return r.toString(t) + n.toInt().toString(t);
33843          }
33844
33845          return "-" + this.neg().toString(t);
33846        }
33847
33848        for (var i = u(c(t, 6), this.unsigned), o = this, a = "";;) {
33849          var s = o.div(i),
33850              f = (o.sub(s.mul(i)).toInt() >>> 0).toString(t);
33851          if ((o = s).isZero()) return f + a;
33852
33853          for (; f.length < 6;) f = "0" + f;
33854
33855          a = "" + f + a;
33856        }
33857      }, k.getHighBits = function () {
33858        return this.high;
33859      }, k.getHighBitsUnsigned = function () {
33860        return this.high >>> 0;
33861      }, k.getLowBits = function () {
33862        return this.low;
33863      }, k.getLowBitsUnsigned = function () {
33864        return this.low >>> 0;
33865      }, k.getNumBitsAbs = function () {
33866        if (this.isNegative()) return this.eq(S) ? 64 : this.neg().getNumBitsAbs();
33867
33868        for (var t = 0 != this.high ? this.high : this.low, e = 31; e > 0 && 0 == (t & 1 << e); e--);
33869
33870        return 0 != this.high ? e + 33 : e + 1;
33871      }, k.isZero = function () {
33872        return 0 === this.high && 0 === this.low;
33873      }, k.eqz = k.isZero, k.isNegative = function () {
33874        return !this.unsigned && this.high < 0;
33875      }, k.isPositive = function () {
33876        return this.unsigned || this.high >= 0;
33877      }, k.isOdd = function () {
33878        return 1 == (1 & this.low);
33879      }, k.isEven = function () {
33880        return 0 == (1 & this.low);
33881      }, k.equals = function (t) {
33882        return i(t) || (t = h(t)), (this.unsigned === t.unsigned || this.high >>> 31 != 1 || t.high >>> 31 != 1) && this.high === t.high && this.low === t.low;
33883      }, k.eq = k.equals, k.notEquals = function (t) {
33884        return !this.eq(t);
33885      }
33885, k.neq = k.notEquals, k.ne = k.notEquals, k.lessThan = function (t) {
33886        return this.comp(t) < 0;
33887      }, k.lt = k.lessThan, k.lessThanOrEqual = function (t) {
33888        return this.comp(t) <= 0;
33889      }, k.lte = k.lessThanOrEqual, k.le = k.lessThanOrEqual, k.greaterThan = function (t) {
33890        return this.comp(t) > 0;
33891      }, k.gt = k.greaterThan, k.greaterThanOrEqual = function (t) {
33892        return this.comp(t) >= 0;
33893      }, k.gte = k.greaterThanOrEqual, k.ge = k.greaterThanOrEqual, k.compare = function (t) {
33894        if (i(t) || (t = h(t)), this.eq(t)) return 0;
33895        var e = this.isNegative(),
33896            r = t.isNegative();
33897        return e && !r ? -1 : !e && r ? 1 : this.unsigned ? t.high >>> 0 > this.high >>> 0 || t.high === this.high && t.low >>> 0 > this.low >>> 0 ? -1 : 1 : this.sub(t).isNegative() ? -1 : 1;
33898      }, k.comp = k.compare, k.negate = function () {
33899        return !this.unsigned && this.eq(S) ? S : this.not().add(b);
33900      }, k.neg = k.negate, k.add = function (t) {
33901        i(t) || (t = h(t));
33902        var e = this.high >>> 16,
33903            r = 65535 & this.high,
33904            n = this.low >>> 16,
33905            o = 65535 & this.low,
33906            a = t.high >>> 16,
33907            s = 65535 & t.high,
33908            u = t.low >>> 16,
33909            c = 0,
33910            l = 0,
33911            d = 0,
33912            p = 0;
33913        return d += (p += o + (65535 & t.low)) >>> 16, l += (d += n + u) >>> 16, c += (l += r + s) >>> 16, c += e + a, f((d &= 65535) << 16 | (p &= 65535), (c &= 65535) << 16 | (l &= 65535), this.unsigned);
33914      }, k.subtract = function (t) {
33915        return i(t) || (t = h(t)), this.add(t.neg());
33916      }, k.sub = k.subtract, k.multiply = function (t) {
33917        if (this.isZero()) return y;
33918        if (i(t) || (t = h(t)), r) return f(r.mul(this.low, this.high, t.low, t.high), r.get_high(), this.unsigned);
33919        if (t.isZero()) return y;
33920        if (this.eq(S)) return t.isOdd() ? S : y;
33921        if (t.eq(S)) return this.isOdd() ? S : y;
33922        if (this.isNegative()) return t.isNegative() ? this.neg().mul(t.neg()) : this.neg().mul(t).neg();
33923        if (t.isNegative()) return this.mul(t.neg()).neg();
33924        if (this.lt(v) && t.lt(v)) return u(this.toNumber() * t.toNumber(), this.unsigned);
33925        var e = this.high >>> 16,
33926            n = 65535 & this.high,
33927            o = this.low >>> 16,
33928            a = 65535 & this.low,
33929            s = t.high >>> 16,
33930            c = 65535 & t.high,
33931            l = t.low >>> 16,
33932            d = 65535 & t.low,
33933            p = 0,
33934            g = 0,
33935            m = 0,
33936            b = 0;
33937        return m += (b += a * d) >>> 16, g += (m += o * d) >>> 16, m &= 65535, g += (m += a * l) >>> 16, p += (g += n * d) >>> 16, g &= 65535, p += (g += o * l) >>> 16, g &= 65535, p += (g += a * c) >>> 16, p += e * d + n * l + o * c + a * s, f((m &= 65535) << 16 | (b &= 65535), (p &= 65535) << 16 | (g &= 65535), this.unsigned);
33938      }, k.mul = k.multiply, k.divide = function (t) {
33939        if (i(t) || (t = h(t)), t.isZero()) throw Error("division by zero");
33940        var e, n, o;
33941        if (r) return this.unsigned || -2147483648 !== this.high || -1 !== t.low || -1 !== t.high ? f((this.unsigned ? r.div_u : r.div_s)(this.low, this.high, t.low, t.high), r.get_high(), this.unsigned) : this;
33942        if (this.isZero()) return this.unsigned ? m : y;
33943
33944        if (this.unsigned) {
33945          if (t.unsigned || (t = t.toUnsigned()), t.gt(this)) return m;
33946          if (t.gt(this.shru(1))) return _;
33947          o = m;
33948        } else {
33949          if (this.eq(S)) return t.eq(b) || t.eq(w) ? S : t.eq(S) ? b : (e = this.shr(1).div(t).shl(1)).eq(y) ? t.isNegative() ? b : w : (n = this.sub(t.mul(e)), o = e.add(n.div(t)));
33950          if (t.eq(S)) return this.unsigned ? m : y;
33951          if (this.isNegative()) return t.isNegative() ? this.neg().div(t.neg()) : this.neg().div(t).neg();
33952          if (t.isNegative()) return this.div(t.neg()).neg();
33953          o = y;
33954        }
33955
33956        for (n = this; n.gte(t);) {
33957          e = Math.max(1, Math.floor(n.toNumber() / t.toNumber()));
33958
33959          for (var a = Math.ceil(Math.log(e) / Math.LN2), s = a <= 48 ? 1 : c(2, a - 48), l = u(e), d = l.mul(t); d.isNegative() || d.gt(n);
33959) d = (l = u(e -= s, this.unsigned)).mul(t);
33960
33961          l.isZero() && (l = b), o = o.add(l), n = n.sub(d);
33962        }
33963
33964        return o;
33965      }, k.div = k.divide, k.modulo = function (t) {
33966        return i(t) || (t = h(t)), r ? f((this.unsigned ? r.rem_u : r.rem_s)(this.low, this.high, t.low, t.high), r.get_high(), this.unsigned) : this.sub(this.div(t).mul(t));
33967      }, k.mod = k.modulo, k.rem = k.modulo, k.not = function () {
33968        return f(~this.low, ~this.high, this.unsigned);
33969      }, k.and = function (t) {
33970        return i(t) || (t = h(t)), f(this.low & t.low, this.high & t.high, this.unsigned);
33971      }, k.or = function (t) {
33972        return i(t) || (t = h(t)), f(this.low | t.low, this.high | t.high, this.unsigned);
33973      }, k.xor = function (t) {
33974        return i(t) || (t = h(t)), f(this.low ^ t.low, this.high ^ t.high, this.unsigned);
33975      }, k.shiftLeft = function (t) {
33976        return i(t) && (t = t.toInt()), 0 == (t &= 63) ? this : t < 32 ? f(this.low << t, this.high << t | this.low >>> 32 - t, this.unsigned) : f(0, this.low << t - 32, this.unsigned);
33977      }, k.shl = k.shiftLeft, k.shiftRight = function (t) {
33978        return i(t) && (t = t.toInt()), 0 == (t &= 63) ? this : t < 32 ? f(this.low >>> t | this.high << 32 - t, this.high >> t, this.unsigned) : f(this.high >> t - 32, this.high >= 0 ? 0 : -1, this.unsigned);
33979      }, k.shr = k.shiftRight, k.shiftRightUnsigned = function (t) {
33980        if (i(t) && (t = t.toInt()), 0 === (t &= 63)) return this;
33981        var e = this.high;
33982        return t < 32 ? f(this.low >>> t | e << 32 - t, e >>> t, this.unsigned) : f(32 === t ? e : e >>> t - 32, 0, this.unsigned);
33983      }, k.shru = k.shiftRightUnsigned, k.shr_u = k.shiftRightUnsigned, k.toSigned = function () {
33984        return this.unsigned ? f(this.low, this.high, !1) : this;
33985      }, k.toUnsigned = function () {
33986        return this.unsigned ? this : f(this.low, this.high, !0);
33987      }, k.toBytes = function (t) {
33988        return t ? this.toBytesLE() : this.toBytesBE();
33989      }, k.toBytesLE = function () {
33990        var t = this.high,
33991            e = this.low;
33992        return [255 & e, e >>> 8 & 255, e >>> 16 & 255, e >>> 24, 255 & t, t >>> 8 & 255, t >>> 16 & 255, t >>> 24];
33993      }, k.toBytesBE = function () {
33994        var t = this.high,
33995            e = this.low;
33996        return [t >>> 24, t >>> 16 & 255, t >>> 8 & 255, 255 & t, e >>> 24, e >>> 16 & 255, e >>> 8 & 255, 255 & e];
33997      }, n.fromBytes = function (t, e, r) {
33998        return r ? n.fromBytesLE(t, e) : n.fromBytesBE(t, e);
33999      }, n.fromBytesLE = function (t, e) {
34000        return new n(t[0] | t[1] << 8 | t[2] << 16 | t[3] << 24, t[4] | t[5] << 8 | t[6] << 16 | t[7] << 24, e);
34001      }, n.fromBytesBE = function (t, e) {
34002        return new n(t[4] << 24 | t[5] << 16 | t[6] << 8 | t[7], t[0] << 24 | t[1] << 16 | t[2] << 8 | t[3], e);
34003      };
34004    }, function (t, e) {
34005      var r = {
34006        utf8: {
34007          stringToBytes: function (t) {
34008            return r.bin.stringToBytes(unescape(encodeURIComponent(t)));
34009          },
34010          bytesToString: function (t) {
34011            return decodeURIComponent(escape(r.bin.bytesToString(t)));
34012          }
34013        },
34014        bin: {
34015          stringToBytes: function (t) {
34016            for (var e = [], r = 0; r < t.length; r++) e.push(255 & t.charCodeAt(r));
34017
34018            return e;
34019          },
34020          bytesToString: function (t) {
34021            for (var e = [], r = 0; r < t.length; r++) e.push(String.fromCharCode(t[r]));
34022
34023            return e.join("");
34024          }
34025        }
34026      };
34027      t.exports = r;
34028    }, function (t, e, r) {
34029      t.exports = r(335);
34030    }, function (t, e, r) {
34031      var n = r(17),
34032          i = r(51),
34033          o = r(28),
34034          a = r(65).f,
34035          s = function (t) {
34036        return function (e) {
34037          for (var r, s = o(e), u = i(s), f = u.length, c = 0, l = []; f > c;) r = u[c++], n && !a.call(s, r) || l.push(t ? [r, s[r]] : s[r]);
34038
34039          return l;
34040        };
34041      };
34042
34043      t.exports = {
34044        entries: s(!0),
34045        values: s(!1)
34046      };
34047    }, function (t, e, r) {
34048      t.exports = r(338);
34049    }, function (t, e, r) {
34050      t.exports = r(352);
34051    }, function (t, e, r) {
34052      var n = r(355),
34053          i = r(153);
34054
34055      t.exports = function (t) {
34056        if (i(Object(t)) || "[object Arguments]" === Object.prototype.toString.call(t)) return n(t);
34057      };
34058    }, function (t, e, r) {
34059      t.exports = r(360);
34060    }, function (t, e, r) {
34061      t.exports = r(372);
34062    }, function (t, e, r) {
34063      var n = r(13),
34064          i = r(375).trim,
34065          o = r(156),
34066          a = n.parseInt,
34067          s = /^[+-]?0[Xx]/,
34068          u = 8 !== a(o + "08") || 22 !== a(o + "0x16");
34069      t.exports = u ? function (t, e) {
34070        var r = i(String(t));
34071        return a(r, e >>> 0 || (s.test(r) ? 16 : 10));
34072      } : a;
34073    }, function (t, e) {
34074      t.exports = "\t\n\v\f\r                 \u2028\u2029\ufeff";
34075    }, function (t, e, r) {
34076      var n = r(151);
34077
34078      t.exports = function (t) {
34079        if (n(t)) return t;
34080      };
34081    }, function (t, e) {
34082      t.exports = function () {
34083        throw new TypeError("Invalid attempt to destructure non-iterable instance");
34084      };
34085    }, function (t, e, r) {
34086      t.exports = r(393);
34087    }, function (t, e, r) {
34088
34089      var n = r(419),
34090          i = r(426),
34091          o = r(429);
34092
34093      function a(t) {
34094        var e = n.parse(t),
34095            r = e.protocol,
34096            a = e.pathname;
34097        return "file:" === r ? new o(unescape(a)) : new i(t);
34098      }
34099
34100      t.exports = {
34101        LocalFile: o,
34102        RemoteFile: i,
34103        fromUrl: a,
34104        open: function (t, e, r) {
34105          if (r) return r;
34106          if (t) return a(t);
34107          if (e) return new o(e);
34108          throw new Error("no url, path, or filehandle provided, cannot open");
34109        }
34110      };
34111    }, function (t, e, r) {
34112
34113      Object.defineProperty(e, "__esModule", {
34114        value: !0
34115      }), e.promisify = i;
34116      var n = "__ES6-PROMISIFY--CUSTOM-ARGUMENTS__";
34117
34118      function i(t) {
34119        if ("function" != typeof t) throw new TypeError("Argument to promisify must be a function");
34120        var e = t[n],
34121            r = i.Promise || Promise;
34122        if ("function" != typeof r) throw new Error("No Promise implementation found; do you need a polyfill?");
34123        return function () {
34124          for (var n = this, i = arguments.length, o = new Array(i), a = 0; a < i; a++) o[a] = arguments[a];
34125
34126          return new r(function (r, i) {
34127            o.push(function (t) {
34128              if (t) return i(t);
34129
34130              for (var n = arguments.length, o = new Array(n > 1 ? n - 1 : 0), a = 1; a < n; a++) o[a - 1] = arguments[a];
34131
34132              if (1 === o.length || !e) return r(o[0]);
34133              var s = {};
34134              o.forEach(function (t, r) {
34135                var n = e[r];
34136                n && (s[n] = t);
34137              }), r(s);
34138            }), t.call.apply(t, [n].concat(o));
34139          });
34140        };
34141      }
34142
34143      i.argumentNames = n, i.Promise = void 0;
34144    }, function (t, e, r) {
34145
34146      (function (t) {
34147        Object.defineProperty(e, "__esModule", {
34148          value: !0
34149        });
34150
34151        var n = r(449),
34152            i = function () {
34153          if ("undefined" != typeof self) return self;
34154          if ("undefined" != typeof window) return window;
34155          if (void 0 !== t) return t;
34156          throw new Error("unable to locate global object");
34157        },
34158            o = void 0 === i().AbortController ? n.AbortController : i().AbortController;
34159
34160        e.AbortController = o;
34161        var a = void 0 === i().AbortController ? n.AbortSignal : i().AbortSignal;
34162        e.AbortSignal = a;
34163      }).call(this, r(23));
34164    }, function (t, e, r) {
34165
34166      var n = r(104),
34167          i = r(432),
34168          o = r(439);
34169      t.exports = {
34170        CramFile: n,
34171        IndexedCramFile: i,
34172        CraiIndex: o
34173      };
34174    }, function (t, e, r) {
34175
34176      (function (e) {
34177        var n,
34178            i = r(1),
34179            o = i(r(16)),
34180            a = i(r(37)),
34181            s = i(r(30)),
34182            u = i(r(31)),
34183            f = i(r(7)),
34184            c = i(r(10)),
34185            l = r(126),
34186            h = r(224),
34187            d = r(94),
34188            p = r(9),
34189            g = p.CramUnimplementedError,
34190            v = p.CramMalformedError,
34191            y = r(309),
34192            m = r(318),
34193            b = m.cramFileDefinition,
34194            _ = m.getSectionParsers,
34195            w = r(329),
34196            x = r(160).open,
34197            E = r(58),
34198            S = E.parseItem,
34199            k = E.tinyMemoize,
34200            A = r(430).parseHeaderText,
34201            C = function () {
34202          function t(e) {
34203            (0, f.default)(this, t), this.file = x(e.url, e.path, e.filehandle), this.validateChecksums = !0, this.fetchReferenceSequenceCallback = e.seqFetch, this.options = {
34204              checkSequenceMD5: !1 !== e.checkSequenceMD5,
34205              cacheSize: void 0 !== e.cacheSize ? e.cacheSize : 2e4
34206            }, this.featureCache = new d({
34207              maxSize: this.options.cacheSize
34208            });
34209          }
34210
34211          var r, n, i, o, p, m, E, k, C, T;
34212          return (0, c.default)(t, [{
34213            key: "toString",
34214            value: function () {
34215              return this.file.filename ? this.file.filename : this.file.url ? this.file.url : "(cram file)";
34216            }
34217          }, {
34218            key: "read",
34219            value: function (t, e, r, n) {
34220              return this.file.read(t, e, r, n);
34221            }
34222          }, {
34223            key: "stat",
34224            value: function () {
34225              return this.file.stat();
34226            }
34227          }, {
34228            key: "getDefinition",
34229            value: (T = (0, u.default)(s.default.mark(function t() {
34230              var r, n;
34231              return s.default.wrap(function (t) {
34232                for (;;) switch (t.prev = t.next) {
34233                  case 0:
34234                    return r = e.allocUnsafe(b.maxLength), t.next = 3, this.file.read(r, 0, b.maxLength, 0);
34235
34236                  case 3:
34237                    if (2 === (n = b.parser.parse(r).result).majorVersion || 3 === n.majorVersion) {
34238                      t.next = 6;
34239                      break;
34240                    }
34241
34242                    throw new g("CRAM version ".concat(n.majorVersion, " not supported"));
34243
34244                  case 6:
34245                    return t.abrupt("return", n);
34246
34247                  case 7:
34248                  case "end":
34249                    return t.stop();
34250                }
34251              }, t, this);
34252            })), function () {
34253              return T.apply(this, arguments);
34254            })
34255          }, {
34256            key: "getSamHeader",
34257            value: (C = (0, u.default)(s.default.mark(function t() {
34258              var e, r, n, i, o;
34259              return s.default.wrap(function (t) {
34260                for (;;) switch (t.prev = t.next) {
34261                  case 0:
34262                    return t.next = 2, this.getContainerById(0);
34263
34264                  case 2:
34265                    if (e = t.sent) {
34266                      t.next = 5;
34267                      break;
34268                    }
34269
34270                    throw new v("file contains no containers");
34271
34272                  case 5:
34273                    return t.next = 7, e.getFirstBlock();
34274
34275                  case 7:
34276                    return r = t.sent, n = r.content, i = n.readInt32LE(0), o = n.toString("utf8", 4, 4 + i), this.header = o, t.abrupt("return", A(o));
34277
34278                  case 14:
34279                  case "end":
34280                    return t.stop();
34281                }
34282              }, t, this);
34283            })), function () {
34284              return C.apply(this, arguments);
34285            })
34286          }, {
34287            key: "getHeaderText",
34288            value: (k = (0, u.default)(s.default.mark(function t() {
34289              return s.default.wrap(function (t) {
34290                for (;;) switch (t.prev = t.next) {
34291                  case 0:
34292                    return t.next = 2, this.getSamHeader();
34293
34294                  case 2:
34295                    return t.abrupt("return", this.header);
34296
34297                  case 3:
34298                  case "end":
34299                    return t.stop();
34300                }
34301              }, t, this);
34302            })), function () {
34303              return k.apply(this, arguments);
34304            })
34305          }, {
34306            key: "getSectionParsers",
34307            value: (E = (0, u.default)(s.default.mark(function t() {
34308              var e, r;
34309              return s.default.wrap(function (t) {
34310                for (;;) switch (t.prev = t.next) {
34311                  case 0:
34312                    return t.next = 2, this.getDefinition();
34313
34314                  case 2:
34315                    return e = t.sent, r = e.majorVersion, t.abrupt("return", _(r));
34316
34317                  case 5:
34318                  case "end":
34319                    return t.stop();
34320                }
34321              }, t, this);
34322            })), function () {
34323              return E.apply(this, arguments);
34324            })
34325          }, {
34326            key: "getContainerById",
34327            value: (m = (0, u.default)(s.default.mark(function t(e) {
34328              var r, n, i, o, a, u, f, c, l, h;
34329              return s.default.wrap(function (t) {
34330                for (;;) switch (t.prev = t.next) {
34331                  case 0:
34332                    return t.next = 2, this.getSectionParsers();
34333
34334                  case 2:
34335                    return r = t.sent, n = r.cramFileDefinition.maxLength, t.next = 6, this.file.stat();
34336
34337                  case 6:
34338                    i = t.sent, o = i.size, a = r.cramContainerHeader1, f = 0;
34339
34340                  case 10:
34341                    if (!(f <= e)) {
34342                      t.next = 36;
34343                      break;
34344                    }
34345
34346                    if (!(n + a.maxLength + 8 >= o)) {
34347                      t.next = 13;
34348                      break;
34349                    }
34350
34351                    return t.abrupt("return", void 0);
34352
34353                  case 13:
34354                    return u = this.getContainerAtPosition(n), t.next = 16, u.getHeader();
34355
34356                  case 16:
34357                    if (c = t.sent) {
34358                      t.next = 19;
34359                      break;
34360                    }
34361
34362                    throw new v("container ".concat(e, " not found in file"));
34363
34364                  case 19:
34365                    if (0 !== f) {
34366                      t.next = 32;
34367                      break;
34368                    }
34369
34370                    n = c._endPosition, l = 0;
34371
34372                  case 22:
34373                    if (!(l < c.numBlocks)) {
34374                      t.next = 30;
34375                      break;
34376                    }
34377
34378                    return t.next = 25, this.readBlock(n);
34379
34380                  case 25:
34381                    h = t.sent, n = h._endPosition;
34382
34383                  case 27:
34384                    l += 1, t.next = 22;
34385                    break;
34386
34387                  case 30:
34388                    t.next = 33;
34389                    break;
34390
34391                  case 32:
34392                    n += c._size + c.length;
34393
34394                  case 33:
34395                    f += 1, t.next = 10;
34396                    break;
34397
34398                  case 36:
34399                    return t.abrupt("return", u);
34400
34401                  case 37:
34402                  case "end":
34403                    return t.stop();
34404                }
34405              }, t, this);
34406            })), function (t) {
34407              return m.apply(this, arguments);
34408            })
34409          }, {
34410            key: "checkCrc32",
34411            value: (p = (0, u.default)(s.default.mark(function t(r, n, i, o) {
34412              var u, f, c, l;
34413              return s.default.wrap(function (t) {
34414                for (;;) switch (t.prev = t.next) {
34415                  case 0:
34416                    return u = e.allocUnsafe(n), t.next = 3, this.file.read(u, 0, n, r);
34417
34418                  case 3:
34419                    if ((f = h.unsigned(u)) === i) {
34420                      t.next = 6;
34421                      break;
34422                    }
34423
34424                    throw new v((0, a.default)(c = (0, a.default)(l = "crc mismatch in ".concat(o, ": recorded CRC32 = ")).call(l, i, ", but calculated CRC32 = ")).call(c, f));
34425
34426                  case 6:
34427                  case "end":
34428                    return t.stop();
34429                }
34430              }, t, this);
34431            })), function (t, e, r, n) {
34432              return p.apply(this, arguments);
34433            })
34434          }, {
34435            key: "containerCount",
34436            value: (o = (0, u.default)(s.default.mark(function t() {
34437              var e, r, n, i, o, a, u, f, c;
34438              return s.default.wrap(function (t) {
34439                for (;;) switch (t.prev = t.next) {
34440                  case 0:
34441                    return t.next = 2, this.getSectionParsers();
34442
34443                  case 2:
34444                    return e = t.sent, t.next = 5, this.file.stat();
34445
34446                  case 5:
34447                    r = t.sent, n = r.size, i = e.cramContainerHeader1, o = 0, a = e.cramFileDefinition.maxLength;
34448
34449                  case 10:
34450                    if (!(a + i.maxLength + 8 < n)) {
34451                      t.next = 33;
34452                      break;
34453                    }
34454
34455                    return t.next = 13, this.getContainerAtPosition(a).getHeader();
34456
34457                  case 13:
34458                    if (u = t.sent) {
34459                      t.next = 16;
34460                      break;
34461                    }
34462
34463                    return t.abrupt("break", 33);
34464
34465                  case 16:
34466                    if (0 !== o) {
34467                      t.next = 29;
34468                      break;
34469                    }
34470
34471                    a = u._endPosition, f = 0;
34472
34473                  case 19:
34474                    if (!(f < u.numBlocks)) {
34475                      t.next = 27;
34476                      break;
34477                    }
34478
34479                    return t.next = 22, this.readBlock(a);
34480
34481                  case 22:
34482                    c = t.sent, a = c._endPosition;
34483
34484                  case 24:
34485                    f += 1, t.next = 19;
34486                    break;
34487
34488                  case 27:
34489                    t.next = 30;
34490                    break;
34491
34492                  case 29:
34493                    a += u._size + u.length;
34494
34495                  case 30:
34496                    o += 1, t.next = 10;
34497                    break;
34498
34499                  case 33:
34500                    return t.abrupt("return", o);
34501
34502                  case 34:
34503                  case "end":
34504                    return t.stop();
34505                }
34506              }, t, this);
34507            })), function () {
34508              return o.apply(this, arguments);
34509            })
34510          }, {
34511            key: "getContainerAtPosition",
34512            value: function (t) {
34513              return new w(this, t);
34514            }
34515          }, {
34516            key: "readBlockHeader",
34517            value: (i = (0, u.default)(s.default.mark(function t(r) {
34518              var n, i, o, a, u;
34519              return s.default.wrap(function (t) {
34520                for (;;) switch (t.prev = t.next) {
34521                  case 0:
34522                    return t.next = 2, this.getSectionParsers();
34523
34524                  case 2:
34525                    return n = t.sent, i = n.cramBlockHeader, t.next = 6, this.file.stat();
34526
34527                  case 6:
34528                    if (o = t.sent, a = o.size, !(r + i.maxLength >= a)) {
34529                      t.next = 10;
34530                      break;
34531                    }
34532
34533                    return t.abrupt("return", void 0);
34534
34535                  case 10:
34536                    return u = e.allocUnsafe(i.maxLength), t.next = 13, this.file.read(u, 0, i.maxLength, r);
34537
34538                  case 13:
34539                    return t.abrupt("return", S(u, i.parser, 0, r));
34540
34541                  case 14:
34542                  case "end":
34543                    return t.stop();
34544                }
34545              }, t, this);
34546            })), function (t) {
34547              return i.apply(this, arguments);
34548            })
34549          }, {
34550            key: "_parseSection",
34551            value: (n = (0, u.default)(s.default.mark(function t(r, n) {
34552              var i,
34553                  o,
34554                  u,
34555                  f,
34556                  c,
34557                  l,
34558                  h,
34559                  d = arguments;
34560              return s.default.wrap(function (t) {
34561                for (;;) switch (t.prev = t.next) {
34562                  case 0:
34563                    if (o = d.length > 2 && void 0 !== d[2] ? d[2] : r.maxLength, !(u = d.length > 3 ? d[3] : void 0)) {
34564                      t.next = 6;
34565                      break;
34566                    }
34567
34568                    f = u, t.next = 15;
34569                    break;
34570
34571                  case 6:
34572                    return t.next = 8, this.file.stat();
34573
34574                  case 8:
34575                    if (c = t.sent, l = c.size, !(n + o >= l)) {
34576                      t.next = 12;
34577                      break;
34578                    }
34579
34580                    return t.abrupt("return", void 0);
34581
34582                  case 12:
34583                    return f = e.allocUnsafe(o), t.next = 15, this.file.read(f, 0, o, n);
34584
34585                  case 15:
34586                    if ((h = S(f, r.parser, 0, n))._size === o) {
34587                      t.next = 18;
34588                      break;
34589                    }
34590
34591                    throw new v((0, a.default)(i = "section read error: requested size ".concat(o, " does not equal parsed size ")).call(i, h._size));
34592
34593                  case 18:
34594                    return t.abrupt("return", h);
34595
34596                  case 19:
34597                  case "end":
34598                    return t.stop();
34599                }
34600              }, t, this);
34601            })), function (t, e) {
34602              return n.apply(this, arguments);
34603            })
34604          }, {
34605            key: "_uncompress",
34606            value: function (t, e, r) {
34607              if ("gzip" === t) {
34608                l.gunzipSync(e).copy(r);
34609              } else {
34610                if ("rans" !== t) throw new g("".concat(t, " decompression not yet implemented"));
34611                y.uncompress(e, r);
34612              }
34613            }
34614          }, {
34615            key: "readBlock",
34616            value: (r = (0, u.default)(s.default.mark(function t(r) {
34617              var n, i, o, a, u, f, c, l;
34618              return s.default.wrap(function (t) {
34619                for (;;) switch (t.prev = t.next) {
34620                  case 0:
34621                    return t.next = 2, this.getDefinition();
34622
34623                  case 2:
34624                    return n = t.sent, i = n.majorVersion, t.next = 6, this.get
34624SectionParsers();
34625
34626                  case 6:
34627                    return o = t.sent, t.next = 9, this.readBlockHeader(r);
34628
34629                  case 9:
34630                    if (a = t.sent, u = a._endPosition, a.contentPosition = a._endPosition, f = e.allocUnsafe(a.uncompressedSize), "raw" === a.compressionMethod) {
34631                      t.next = 20;
34632                      break;
34633                    }
34634
34635                    return c = e.allocUnsafe(a.compressedSize), t.next = 17, this.read(c, 0, a.compressedSize, u);
34636
34637                  case 17:
34638                    this._uncompress(a.compressionMethod, c, f), t.next = 22;
34639                    break;
34640
34641                  case 20:
34642                    return t.next = 22, this.read(f, 0, a.uncompressedSize, u);
34643
34644                  case 22:
34645                    if (a.content = f, !(i >= 3)) {
34646                      t.next = 35;
34647                      break;
34648                    }
34649
34650                    return t.next = 26, this._parseSection(o.cramBlockCrc32, u + a.compressedSize);
34651
34652                  case 26:
34653                    if (l = t.sent, a.crc32 = l.crc32, !this.validateChecksums) {
34654                      t.next = 31;
34655                      break;
34656                    }
34657
34658                    return t.next = 31, this.checkCrc32(r, a._size + a.compressedSize, a.crc32, "block data");
34659
34660                  case 31:
34661                    a._endPosition = l._endPosition, a._size = a.compressedSize + o.cramBlockCrc32.maxLength, t.next = 37;
34662                    break;
34663
34664                  case 35:
34665                    a._endPosition = u + a.compressedSize, a._size = a.compressedSize;
34666
34667                  case 37:
34668                    return t.abrupt("return", a);
34669
34670                  case 38:
34671                  case "end":
34672                    return t.stop();
34673                }
34674              }, t, this);
34675            })), function (t) {
34676              return r.apply(this, arguments);
34677            })
34678          }]), t;
34679        }();
34680
34681        (0, o.default)(n = "getDefinition getSectionParsers getSamHeader".split(" ")).call(n, function (t) {
34682          return k(C, t);
34683        }), t.exports = C;
34684      }).call(this, r(19).Buffer);
34685    }, function (t, e, r) {
34686
34687      e.byteLength = function (t) {
34688        var e = f(t),
34689            r = e[0],
34690            n = e[1];
34691        return 3 * (r + n) / 4 - n;
34692      }, e.toByteArray = function (t) {
34693        var e,
34694            r,
34695            n = f(t),
34696            a = n[0],
34697            s = n[1],
34698            u = new o(function (t, e, r) {
34699          return 3 * (e + r) / 4 - r;
34700        }(0, a, s)),
34701            c = 0,
34702            l = s > 0 ? a - 4 : a;
34703
34704        for (r = 0; r < l; r += 4) e = i[t.charCodeAt(r)] << 18 | i[t.charCodeAt(r + 1)] << 12 | i[t.charCodeAt(r + 2)] << 6 | i[t.charCodeAt(r + 3)], u[c++] = e >> 16 & 255, u[c++] = e >> 8 & 255, u[c++] = 255 & e;
34705
34706        2 === s && (e = i[t.charCodeAt(r)] << 2 | i[t.charCodeAt(r + 1)] >> 4, u[c++] = 255 & e);
34707        1 === s && (e = i[t.charCodeAt(r)] << 10 | i[t.charCodeAt(r + 1)] << 4 | i[t.charCodeAt(r + 2)] >> 2, u[c++] = e >> 8 & 255, u[c++] = 255 & e);
34708        return u;
34709      }, e.fromByteArray = function (t) {
34710        for (var e, r = t.length, i = r % 3, o = [], a = 0, s = r - i; a < s; a += 16383) o.push(c(t, a, a + 16383 > s ? s : a + 16383));
34711
34712        1 === i ? (e = t[r - 1], o.push(n[e >> 2] + n[e << 4 & 63] + "==")) : 2 === i && (e = (t[r - 2] << 8) + t[r - 1], o.push(n[e >> 10] + n[e >> 4 & 63] + n[e << 2 & 63] + "="));
34713        return o.join("");
34714      };
34715
34716      for (var n = [], i = [], o = "undefined" != typeof Uint8Array ? Uint8Array : Array, a = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", s = 0, u = a.length; s < u; ++s) n[s] = a[s], i[a.charCodeAt(s)] = s;
34717
34718      function f(t) {
34719        var e = t.length;
34720        if (e % 4 > 0) throw new Error("Invalid string. Length must be a multiple of 4");
34721        var r = t.indexOf("=");
34722        return -1 === r && (r = e), [r, r === e ? 0 : 4 - r % 4];
34723      }
34724
34725      function c(t, e, r) {
34726        for (var i, o, a = [], s = e; s < r; s += 3) i = (t[s] << 16 & 16711680) + (t[s + 1] << 8 & 65280) + (255 & t[s + 2]), a.push(n[(o = i) >> 18 & 63] + n[o >> 12 & 63] + n[o >> 6 & 63] + n[63 & o]);
34727
34728        return a.join("");
34729      }
34730
34731      i["-".charCodeAt(0)] = 62, i["_".charCodeAt(0)] = 63;
34732    }, function (t, e) {
34733      e.read = function (t, e, r, n, i) {
34734        var o,
34735            a,
34736            s = 8 * i - n - 1,
34737            u = (1 << s) - 1,
34738            f = u >> 1,
34739            c = -7,
34740            l = r ? i - 1 : 0,
34741            h = r ? -1 : 1,
34742            d = t[e + l];
34743
34744        for (l += h, o = d & (1 << -c) - 1, d >>= -c, c += s; c > 0; o = 256 * o + t[e + l], l += h, c -= 8);
34745
34746        for (a = o & (1 << -c) - 1, o >>= -c, c += n;
34746 c > 0; a = 256 * a + t[e + l], l += h, c -= 8);
34747
34748        if (0 === o) o = 1 - f;else {
34749          if (o === u) return a ? NaN : 1 / 0 * (d ? -1 : 1);
34750          a += Math.pow(2, n), o -= f;
34751        }
34752        return (d ? -1 : 1) * a * Math.pow(2, o - n);
34753      }, e.write = function (t, e, r, n, i, o) {
34754        var a,
34755            s,
34756            u,
34757            f = 8 * o - i - 1,
34758            c = (1 << f) - 1,
34759            l = c >> 1,
34760            h = 23 === i ? Math.pow(2, -24) - Math.pow(2, -77) : 0,
34761            d = n ? 0 : o - 1,
34762            p = n ? 1 : -1,
34763            g = e < 0 || 0 === e && 1 / e < 0 ? 1 : 0;
34764
34765        for (e = Math.abs(e), isNaN(e) || e === 1 / 0 ? (s = isNaN(e) ? 1 : 0, a = c) : (a = Math.floor(Math.log(e) / Math.LN2), e * (u = Math.pow(2, -a)) < 1 && (a--, u *= 2), (e += a + l >= 1 ? h / u : h * Math.pow(2, 1 - l)) * u >= 2 && (a++, u /= 2), a + l >= c ? (s = 0, a = c) : a + l >= 1 ? (s = (e * u - 1) * Math.pow(2, i), a += l) : (s = e * Math.pow(2, l - 1) * Math.pow(2, i), a = 0)); i >= 8; t[r + d] = 255 & s, d += p, s /= 256, i -= 8);
34766
34767        for (a = a << i | s, f += i; f > 0; t[r + d] = 255 & a, d += p, a /= 256, f -= 8);
34768
34769        t[r + d - p] |= 128 * g;
34770      };
34771    }, function (t, e, r) {
34772      r(41);
34773      var n = r(177),
34774          i = r(67),
34775          o = Array.prototype,
34776          a = {
34777        DOMTokenList: !0,
34778        NodeList: !0
34779      };
34780
34781      t.exports = function (t) {
34782        var e = t.forEach;
34783        return t === o || t instanceof Array && e === o.forEach || a.hasOwnProperty(i(t)) ? n : e;
34784      };
34785    }, function (t, e, r) {
34786
34787      var n = r(28),
34788          i = r(78),
34789          o = r(35),
34790          a = r(42),
34791          s = r(80),
34792          u = a.set,
34793          f = a.getterFor("Array Iterator");
34794      t.exports = s(Array, "Array", function (t, e) {
34795        u(this, {
34796          type: "Array Iterator",
34797          target: n(t),
34798          index: 0,
34799          kind: e
34800        });
34801      }, function () {
34802        var t = f(this),
34803            e = t.target,
34804            r = t.kind,
34805            n = t.index++;
34806        return !e || n >= e.length ? (t.target = void 0, {
34807          value: void 0,
34808          done: !0
34809        }) : "keys" == r ? {
34810          value: n,
34811          done: !1
34812        } : "values" == r ? {
34813          value: e[n],
34814          done: !1
34815        } : {
34816          value: [n, e[n]],
34817          done: !1
34818        };
34819      }, "values"), o.Arguments = o.Array, i("keys"), i("values"), i("entries");
34820    }, function (t, e, r) {
34821      var n = r(13),
34822          i = r(170),
34823          o = n.WeakMap;
34824      t.exports = "function" == typeof o && /native code/.test(i.call(o));
34825    }, function (t, e, r) {
34826      var n = r(61);
34827      t.exports = n("native-function-to-string", Function.toString);
34828    }, function (t, e, r) {
34829      var n = r(13),
34830          i = r(20);
34831
34832      t.exports = function (t, e) {
34833        try {
34834          i(n, t, e);
34835        } catch (r) {
34836          n[t] = e;
34837        }
34838
34839        return e;
34840      };
34841    }, function (t, e, r) {
34842
34843      var n = r(108).IteratorPrototype,
34844          i = r(44),
34845          o = r(43),
34846          a = r(36),
34847          s = r(35),
34848          u = function () {
34849        return this;
34850      };
34851
34852      t.exports = function (t, e, r) {
34853        var f = e + " Iterator";
34854        return t.prototype = i(n, {
34855          next: o(1, r)
34856        }), a(t, f, !1, !0), s[f] = u, t;
34857      };
34858    }, function (t, e, r) {
34859      var n = r(17),
34860          i = r(21),
34861          o = r(2),
34862          a = r(51);
34863      t.exports = n ? Object.defineProperties : function (t, e) {
34864        o(t);
34865
34866        for (var r, n = a(e), s = n.length, u = 0; s > u;) i.f(t, r = n[u++], e[r]);
34867
34868        return t;
34869      };
34870    }, function (t, e, r) {
34871
34872      var n = r(67),
34873          i = {};
34874      i[r(6)("toStringTag")] = "z", t.exports = "[object z]" !== String(i) ? function () {
34875        return "[object " + n(this) + "]";
34876      } : i.toString;
34877    }, function (t, e, r) {
34878      var n = r(14);
34879
34880      t.exports = function (t) {
34881        if (!n(t) && null !== t) throw TypeError("Can't set " + String(t) + " as a prototype");
34882        return t;
34883      };
34884    }, function (t, e) {
34885      t.exports = {
34886        CSSRuleList: 0,
34887        CSSStyleDeclaration: 0,
34888        CSSValueList: 0,
34889        ClientRectList: 0,
34890        DOMRectList: 0,
34891        DOMStringList: 0,
34892        DOMTokenList: 1,
34893        DataTransferItemList: 0,
34894        FileList: 0,
34895        HTMLAllCollection: 0,
34896        HTMLCollection: 0,
34897        HTMLFormElement: 0,
34898        HTMLSelectElement: 0,
34899        MediaList: 0,
34900        MimeTypeArray: 0,
34901        NamedNodeMap: 0,
34902        NodeList: 1,
34903        PaintRequestList: 0,
34904        Plugin: 0,
34905        PluginArray: 0,
34906        SVGLengthList: 0,
34907        SVGNumberList: 0,
34908        SVGPathSegList: 0,
34909        SVGPointList: 0,
34910        SVGStringList: 0,
34911        SVGTransformList: 0,
34912        SourceBufferList: 0,
34913        StyleSheetList: 0,
34914        TextTrackCueList: 0,
34915        TextTrackList: 0,
34916        TouchList: 0
34917      };
34918    }, function (t, e, r) {
34919      t.exports = r(178);
34920    }, function (t, e, r) {
34921      r(179);
34922      var n = r(18);
34923      t.exports = n("Array").forEach;
34924    }, function (t, e, r) {
34925
34926      var n = r(0),
34927          i = r(180);
34928      n({
34929        target: "Array",
34930        proto: !0,
34931        forced: [].forEach != i
34932      }, {
34933        forEach: i
34934      });
34935    }, function (t, e, r) {
34936
34937      var n = r(45).forEach,
34938          i = r(54);
34939      t.exports = i("forEach") ? function (t) {
34940        return n(this, t, arguments.length > 1 ? arguments[1] : void 0);
34941      } : [].forEach;
34942    }, function (t, e, r) {
34943      t.exports = r(182);
34944    }, function (t, e, r) {
34945      var n = r(183),
34946          i = Array.prototype;
34947
34948      t.exports = function (t) {
34949        var e = t.concat;
34950        return t === i || t instanceof Array && e === i.concat ? n : e;
34951      };
34952    }, function (t, e, r) {
34953      r(114);
34954      var n = r(18);
34955      t.exports = n("Array").concat;
34956    }, function (t, e, r) {
34957      var n = function (t) {
34958
34959        var e,
34960            r = Object.prototype,
34961            n = r.hasOwnProperty,
34962            i = "function" == typeof Symbol ? Symbol : {},
34963            o = i.iterator || "@@iterator",
34964            a = i.asyncIterator || "@@asyncIterator",
34965            s = i.toStringTag || "@@toStringTag";
34966
34967        function u(t, e, r, n) {
34968          var i = e && e.prototype instanceof g ? e : g,
34969              o = Object.create(i.prototype),
34970              a = new C(n || []);
34971          return o._invoke = function (t, e, r) {
34972            var n = c;
34973            return function (i, o) {
34974              if (n === h) throw new Error("Generator is already running");
34975
34976              if (n === d) {
34977                if ("throw" === i) throw o;
34978                return R();
34979              }
34980
34981              for (r.method = i, r.arg = o;;) {
34982                var a = r.delegate;
34983
34984                if (a) {
34985                  var s = S(a, r);
34986
34987                  if (s) {
34988                    if (s === p) continue;
34989                    return s;
34990                  }
34991                }
34992
34993                if ("next" === r.method) r.sent = r._sent = r.arg;else if ("throw" === r.method) {
34994                  if (n === c) throw n = d, r.arg;
34995                  r.dispatchException(r.arg);
34996                } else "return" === r.method && r.abrupt("return", r.arg);
34997                n = h;
34998                var u = f(t, e, r);
34999
35000                if ("normal" === u.type) {
35001                  if (n = r.done ? d : l, u.arg === p) continue;
35002                  return {
35003                    value: u.arg,
35004                    done: r.done
35005                  };
35006                }
35007
35008                "throw" === u.type && (n = d, r.method = "throw", r.arg = u.arg);
35009              }
35010            };
35011          }(t, r, a), o;
35012        }
35013
35014        function f(t, e, r) {
35015          try {
35016            return {
35017              type: "normal",
35018              arg: t.call(e, r)
35019            };
35020          } catch (t) {
35021            return {
35022              type: "throw",
35023              arg: t
35024            };
35025          }
35026        }
35027
35028        t.wrap = u;
35029        var c = "suspendedStart",
35030            l = "suspendedYield",
35031            h = "executing",
35032            d = "completed",
35033            p = {};
35034
35035        function g() {}
35036
35037        function v() {}
35038
35039        function y() {}
35040
35041        var m = {};
35042
35043        m[o] = function () {
35044          return this;
35045        };
35046
35047        var b = Object.getPrototypeOf,
35048            _ = b && b(b(T([])));
35049
35050        _ && _ !== r && n.call(_, o) && (m = _);
35051        var w = y.prototype = g.prototype = Object.create(m);
35052
35053        function x(t) {
35054          ["next", "throw", "return"].forEach(function (e) {
35055            t[e] = function (t) {
35056              return this._invoke(e, t);
35057            };
35058          });
35059        }
35060
35061        function E(t, e) {
35062          var r;
35063
35064          this._invoke = function (i, o) {
35065            function a() {
35066              return new e(function (r, a) {
35067                !function r(i, o, a, s) {
35068                  var u = f(t[i], t, o);
35069
35070                  if ("throw" !== u.type) {
35071                    var c = u.arg,
35072                        l = c.value;
35073                    return l && "object" == typeof l && n.call(l, "__await") ? e.resolve(l.__await).then(function (t) {
35074                      r("next", t, a, s);
35075                    }, function (t) {
35076                      r("throw", t, a, s);
35077                    }) : e.resolve(l).then(function (t) {
35078                      c.value = t, a(c);
35079                    }, function (t) {
35080                      return r("throw", t, a, s);
35081                    });
35082                  }
35083
35084                  s(u.arg);
35085                }(i, o, r, a);
35086              });
35087            }
35088
35089            return r = r ? r.then(a, a) : a();
35090          };
35091        }
35092
35093        function S(t, r) {
35094          var n = t.iterator[r.method];
35095
35096          if (n === e) {
35097            if (r.delegate = null, "throw" === r.method) {
35098              if (t.iterator.return && (r.method = "return", r.arg = e, S(t, r), "throw" === r.method)) return p;
35099              r.method = "throw", r.arg = new TypeError("The iterator does not provide a 'throw' method");
35100            }
35101
35102            return p;
35103          }
35104
35105          var i = f(n, t.iterator, r.arg);
35106          if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, p;
35107          var o = i.arg;
35108          return o ? o.done ? (r[t.resultName] = o.value, r.next = t.nextLoc, "return" !== r.method && (r.method = "next", r.arg = e), r.delegate = null, p) : o : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, p);
35109        }
35110
35111        function k(t) {
35112          var e = {
35113            tryLoc: t[0]
35114          };
35115          1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e);
35116        }
35117
35118        function A(t) {
35119          var e = t.completion || {};
35120          e.type = "normal", delete e.arg, t.completion = e;
35121        }
35122
35123        function C(t) {
35124          this.tryEntries = [{
35125            tryLoc: "root"
35126          }], t.forEach(k, this), this.reset(!0);
35127        }
35128
35129        function T(t) {
35130          if (t) {
35131            var r = t[o];
35132            if (r) return r.call(t);
35133            if ("function" == typeof t.next) return t;
35134
35135            if (!isNaN(t.length)) {
35136              var i = -1,
35137                  a = function r() {
35138                for (; ++i < t.length;) if (n.call(t, i)) return r.value = t[i], r.done = !1, r;
35139
35140                return r.value = e, r.done = !0, r;
35141              };
35142
35143              return a.next = a;
35144            }
35145          }
35146
35147          return {
35148            next: R
35149          };
35150        }
35151
35152        function R() {
35153          return {
35154            value: e,
35155            done: !0
35156          };
35157        }
35158
35159        return v.prototype = w.constructor = y, y.constructor = v, y[s] = v.displayName = "GeneratorFunction", t.isGeneratorFunction = function (t) {
35160          var e = "function" == typeof t && t.constructor;
35161          return !!e && (e === v || "GeneratorFunction" === (e.displayName || e.name));
35162        }, t.mark = function (t) {
35163          return Object.setPrototypeOf ? Object.setPrototypeOf(t, y) : (t.__proto__ = y, s in t || (t[s] = "GeneratorFunction")), t.prototype = Object.create(w), t;
35164        }, t.awrap = function (t) {
35165          return {
35166            __await: t
35167          };
35168        }, x(E.prototype), E.prototype[a] = function () {
35169          return this;
35170        }, t.AsyncIterator = E, t.async = function (e, r, n, i, o) {
35171          void 0 === o && (o = Promise);
35172          var a = new E(u(e, r, n, i), o);
35173          return t.isGeneratorFunction(r) ? a : a.next().then(function (t) {
35174            return t.done ? t.value : a.next();
35175          });
35176        }, x(w), w[s] = "Generator", w[o] = function () {
35177          return this;
35178        }, w.toString = function () {
35179          return "[object Generator]";
35180        }, t.keys = function (t) {
35181          var e = [];
35182
35183          for (var r in t) e.push(r);
35184
35185          return e.reverse(), function r() {
35186            for (; e.length;) {
35187              var n = e.pop();
35188              if (n in t) return r.value = n, r.done = !1, r;
35189            }
35190
35191            return r.done = !0, r;
35192          };
35193        }, t.values = T, C.prototype = {
35194          constructor: C,
35195          reset: function (t) {
35196            if (this.prev = 0, this.next = 0, this.sent = this._sent = e, this.done = !1, this.delegate = null, this.method = "next", this.arg = e, this.tryEntries.forEac
35196h(A), !t) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = e);
35197          },
35198          stop: function () {
35199            this.done = !0;
35200            var t = this.tryEntries[0].completion;
35201            if ("throw" === t.type) throw t.arg;
35202            return this.rval;
35203          },
35204          dispatchException: function (t) {
35205            if (this.done) throw t;
35206            var r = this;
35207
35208            function i(n, i) {
35209              return s.type = "throw", s.arg = t, r.next = n, i && (r.method = "next", r.arg = e), !!i;
35210            }
35211
35212            for (var o = this.tryEntries.length - 1; o >= 0; --o) {
35213              var a = this.tryEntries[o],
35214                  s = a.completion;
35215              if ("root" === a.tryLoc) return i("end");
35216
35217              if (a.tryLoc <= this.prev) {
35218                var u = n.call(a, "catchLoc"),
35219                    f = n.call(a, "finallyLoc");
35220
35221                if (u && f) {
35222                  if (this.prev < a.catchLoc) return i(a.catchLoc, !0);
35223                  if (this.prev < a.finallyLoc) return i(a.finallyLoc);
35224                } else if (u) {
35225                  if (this.prev < a.catchLoc) return i(a.catchLoc, !0);
35226                } else {
35227                  if (!f) throw new Error("try statement without catch or finally");
35228                  if (this.prev < a.finallyLoc) return i(a.finallyLoc);
35229                }
35230              }
35231            }
35232          },
35233          abrupt: function (t, e) {
35234            for (var r = this.tryEntries.length - 1; r >= 0; --r) {
35235              var i = this.tryEntries[r];
35236
35237              if (i.tryLoc <= this.prev && n.call(i, "finallyLoc") && this.prev < i.finallyLoc) {
35238                var o = i;
35239                break;
35240              }
35241            }
35242
35243            o && ("break" === t || "continue" === t) && o.tryLoc <= e && e <= o.finallyLoc && (o = null);
35244            var a = o ? o.completion : {};
35245            return a.type = t, a.arg = e, o ? (this.method = "next", this.next = o.finallyLoc, p) : this.complete(a);
35246          },
35247          complete: function (t, e) {
35248            if ("throw" === t.type) throw t.arg;
35249            return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), p;
35250          },
35251          finish: function (t) {
35252            for (var e = this.tryEntries.length - 1; e >= 0; --e) {
35253              var r = this.tryEntries[e];
35254              if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), A(r), p;
35255            }
35256          },
35257          catch: function (t) {
35258            for (var e = this.tryEntries.length - 1; e >= 0; --e) {
35259              var r = this.tryEntries[e];
35260
35261              if (r.tryLoc === t) {
35262                var n = r.completion;
35263
35264                if ("throw" === n.type) {
35265                  var i = n.arg;
35266                  A(r);
35267                }
35268
35269                return i;
35270              }
35271            }
35272
35273            throw new Error("illegal catch attempt");
35274          },
35275          delegateYield: function (t, r, n) {
35276            return this.delegate = {
35277              iterator: T(t),
35278              resultName: r,
35279              nextLoc: n
35280            }, "next" === this.method && (this.arg = e), p;
35281          }
35282        }, t;
35283      }(t.exports);
35284
35285      try {
35286        regeneratorRuntime = n;
35287      } catch (t) {
35288        Function("r", "regeneratorRuntime = r")(n);
35289      }
35290    }, function (t, e, r) {
35291      t.exports = r(186);
35292    }, function (t, e, r) {
35293      t.exports = r(115), r(192), r(193), r(194), r(195);
35294    }, function (t, e, r) {
35295      var n = r(83),
35296          i = r(49),
35297          o = function (t) {
35298        return function (e, r) {
35299          var o,
35300              a,
35301              s = String(i(e)),
35302              u = n(r),
35303              f = s.length;
35304          return u < 0 || u >= f ? t ? "" : void 0 : (o = s.charCodeAt(u)) < 55296 || o > 56319 || u + 1 === f || (a = s.charCodeAt(u + 1)) < 56320 || a > 57343 ? t ? s.charAt(u) : o : t ? s.slice(u, u + 2) : a - 56320 + (o - 55296 << 10) + 65536;
35305        };
35306      };
35307
35308      t.exports = {
35309        codeAt: o(!1),
35310        charAt: o(!0)
35311      };
35312    }, function (t, e, r) {
35313
35314      var n,
35315          i,
35316          o,
35317          a,
35318          s = r(0),
35319          u = r(4),
35320          f = r(13),
35321          c = r(3),
35322          l = r(116),
35323          h = r(52),
35324          d = r(117),
35325          p = r(36),
35326          g = r(118),
35327          v = r(14),
35328          y = r(5),
35329          m = r(89),
35330          b = r(34),
35331          _ = r(8),
35332          w = r(121),
35333          x = r(55),
35334          E = r(122).set,
35335          S = r(189),
35336          k = r(124),
35337          A = r(190),
35338          C = r(56),
35339          T = r(69),
35340          R = r(123),
35341          O = r(42),
35342          I = r(107),
35343          L = r(6)("species"),
35344          B = "Promise",
35345          P = O.get,
35346          F = O.set,
35347          N = O.getterFor(B),
35348          M = l,
35349          j = f.TypeError,
35350          z = f.document,
35351          U = f.process,
35352          D = f.fetch,
35353          q = U && U.versions,
35354          Z = q && q.v8 || "",
35355          H = C.f,
35356          V = H,
35357          G = "process" == b(U),
35358          Y = !!(z && z.createEvent && f.dispatchEvent),
35359          W = I(B, function () {
35360        var t = M.resolve(1),
35361            e = function () {},
35362            r = (t.constructor = {})[L] = function (t) {
35363          t(e, e);
35364        };
35365
35366        return !((G || "function" == typeof PromiseRejectionEvent) && (!u || t.finally) && t.then(e) instanceof r && 0 !== Z.indexOf("6.6") && -1 === R.indexOf("Chrome/66"));
35367      }),
35368          K = W || !w(function (t) {
35369        M.all(t).catch(function () {});
35370      }),
35371          Q = function (t) {
35372        var e;
35373        return !(!v(t) || "function" != typeof (e = t.then)) && e;
35374      },
35375          X = function (t, e, r) {
35376        if (!e.notified) {
35377          e.notified = !0;
35378          var n = e.reactions;
35379          S(function () {
35380            for (var i = e.value, o = 1 == e.state, a = 0; n.length > a;) {
35381              var s,
35382                  u,
35383                  f,
35384                  c = n[a++],
35385                  l = o ? c.ok : c.fail,
35386                  h = c.resolve,
35387                  d = c.reject,
35388                  p = c.domain;
35389
35390              try {
35391                l ? (o || (2 === e.rejection && et(t, e), e.rejection = 1), !0 === l ? s = i : (p && p.enter(), s = l(i), p && (p.exit(), f = !0)), s === c.promise ? d(j("Promise-chain cycle")) : (u = Q(s)) ? u.call(s, h, d) : h(s)) : d(i);
35392              } catch (t) {
35393                p && !f && p.exit(), d(t);
35394              }
35395            }
35396
35397            e.reactions = [], e.notified = !1, r && !e.rejection && J(t, e);
35398          });
35399        }
35400      },
35401          $ = function (t, e, r) {
35402        var n, i;
35403        Y ? ((n = z.createEvent("Event")).promise = e, n.reason = r, n.initEvent(t, !1, !0), f.dispatchEvent(n)) : n = {
35404          promise: e,
35405          reason: r
35406        }, (i = f["on" + t]) ? i(n) : "unhandledrejection" === t && A("Unhandled promise rejection", r);
35407      },
35408          J = function (t, e) {
35409        E.call(f, function () {
35410          var r,
35411              n = e.value;
35412          if (tt(e) && (r = T(function () {
35413            G ? U.emit("unhandledRejection", n, t) : $("unhandledrejection", t, n);
35414          }), e.rejection = G || tt(e) ? 2 : 1, r.error)) throw r.value;
35415        });
35416      },
35417          tt = function (t) {
35418        return 1 !== t.rejection && !t.parent;
35419      },
35420          et = function (t, e) {
35421        E.call(f, function () {
35422          G ? U.emit("rejectionHandled", t) : $("rejectionhandled", t, e.value);
35423        });
35424      },
35425          rt = function (t, e, r, n) {
35426        return function (i) {
35427          t(e, r, i, n);
35428        };
35429      },
35430          nt = function (t, e, r, n) {
35431        e.done || (e.done = !0, n && (e = n), e.value = r, e.state = 2, X(t, e, !0));
35432      },
35433          it = function (t, e, r, n) {
35434        if (!e.done) {
35435          e.done = !0, n && (e = n);
35436
35437          try {
35438            if (t === r) throw j("Promise can't be resolved itself");
35439            var i = Q(r);
35440            i ? S(function () {
35441              var n = {
35442                done: !1
35443              };
35444
35445              try {
35446                i.call(r, rt(it, t, n, e), rt(nt, t, n, e));
35447              } catch (r) {
35448                nt(t, n, r, e);
35449              }
35450            }) : (e.value = r, e.state = 1, X(t, e, !1));
35451          } catch (r) {
35452            nt(t, {
35453              done: !1
35454            }, r, e);
35455          }
35456        }
35457      };
35458
35459      W && (M = function (t) {
35460        m(this, M, B), y(t), n.call(this);
35461        var e = P(this);
35462
35463        try {
35464          t(rt(it, this, e), rt(nt, this, e));
35465        } catch (t) {
35466          nt(this, e, t);
35467        }
35468      }, (n = function (t) {
35469        F(this, {
35470          type: B,
35471          done: !1,
35472          notified: !1,
35473          parent: !1,
35474          reactions: [],
35475          rejection: !1,
35476          state: 0,
35477          value: void 0
35478        });
35479      }).prototype = d(M.prototype, {
35480        then: function (t, e) {
35481          var r = N(this),
35482              n = H(x(this, M));
35483          return n.ok = "function" != typeof t || t, n.fail = "function" == typeof e && e, n.domain = G ? U.domain : void 0, r.parent = !0, r.reactions.push(n), 0 != r.state && X(this, r, !1), n.promise;
35484        },
35485        catch: function (t) {
35486          return this.then(void 0, t);
35487        }
35488      }), i = function () {
35489        var t = new n(),
35490            e = P(t);
35491        this.promise = t, this.resolve = rt(it, t, e), this.reject = rt(nt, t, e);
35492      }, C.f = H = function (t) {
35493        return t === M || t === o ? new i(t) : V(t);
35494      }, u || "function" != typeof l || (a = l.prototype.then, h(l.prototype, "then", function (t, e) {
35495        var r = this;
35496        return new M(function (t, e) {
35497          a.call(r, t, e);
35498        }).then(t, e);
35499      }), "function" == typeof D && s({
35500        global: !0,
35501        enumerable: !0,
35502        forced: !0
35503      }, {
35504        fetch: function (t) {
35505          return k(M, D.apply(f, arguments));
35506        }
35507      }))), s({
35508        global: !0,
35509        wrap: !0,
35510        forced: W
35511      }, {
35512        Promise: M
35513      }), p(M, B, !1, !0), g(B), o = c.Promise, s({
35514        target: B,
35515        stat: !0,
35516        forced: W
35517      }, {
35518        reject: function (t) {
35519          var e = H(this);
35520          return e.reject.call(void 0, t), e.promise;
35521        }
35522      }), s({
35523        target: B,
35524        stat: !0,
35525        forced: u || W
35526      }, {
35527        resolve: function (t) {
35528          return k(u && this === o ? M : this, t);
35529        }
35530      }), s({
35531        target: B,
35532        stat: !0,
35533        forced: K
35534      }, {
35535        all: function (t) {
35536          var e = this,
35537              r = H(e),
35538              n = r.resolve,
35539              i = r.reject,
35540              o = T(function () {
35541            var r = y(e.resolve),
35542                o = [],
35543                a = 0,
35544                s = 1;
35545            _(t, function (t) {
35546              var u = a++,
35547                  f = !1;
35548              o.push(void 0), s++, r.call(e, t).then(function (t) {
35549                f || (f = !0, o[u] = t, --s || n(o));
35550              }, i);
35551            }), --s || n(o);
35552          });
35553          return o.error && i(o.value), r.promise;
35554        },
35555        race: function (t) {
35556          var e = this,
35557              r = H(e),
35558              n = r.reject,
35559              i = T(function () {
35560            var i = y(e.resolve);
35561
35562            _(t, function (t) {
35563              i.call(e, t).then(r.resolve, n);
35564            });
35565          });
35566          return i.error && n(i.value), r.promise;
35567        }
35568      });
35569    }, function (t, e, r) {
35570      var n,
35571          i,
35572          o,
35573          a,
35574          s,
35575          u,
35576          f,
35577          c,
35578          l = r(13),
35579          h = r(81).f,
35580          d = r(34),
35581          p = r(122).set,
35582          g = r(123),
35583          v = l.MutationObserver || l.WebKitMutationObserver,
35584          y = l.process,
35585          m = l.Promise,
35586          b = "process" == d(y),
35587          _ = h(l, "queueMicrotask"),
35588          w = _ && _.value;
35589
35590      w || (n = function () {
35591        var t, e;
35592
35593        for (b && (t = y.domain) && t.exit(); i;) {
35594          e = i.fn, i = i.next;
35595
35596          try {
35597            e();
35598          } catch (t) {
35599            throw i ? a() : o = void 0, t;
35600          }
35601        }
35602
35603        o = void 0, t && t.enter();
35604      }, b ? a = function () {
35605        y.nextTick(n);
35606      } : v && !/(iphone|ipod|ipad).*applewebkit/i.test(g) ? (s = !0, u = document.createTextNode(""), new v(n).observe(u, {
35607        characterData: !0
35608      }), a = function () {
35609        u.data = s = !s;
35610      }) : m && m.resolve ? (f = m.resolve(void 0), c = f.then, a = function () {
35611        c.call(f, n);
35612      }) : a = function () {
35613        p.call(l, n);
35614      }), t.exports = w || function (t) {
35615        var e = {
35616          fn: t,
35617          next: void 0
35618        };
35619        o && (o.next = e), i || (i = e, a()), o = e;
35620      };
35621    }, function (t, e, r) {
35622      var n = r(13);
35623
35624      t.exports = function (t, e) {
35625        var r = n.console;
35626        r && r.error && (1 === arguments.length ? r.error(t) : r.error(t, e));
35627      };
35628    }, function (t, e, r) {
35629
35630      var n = r(0),
35631          i = r(4),
35632          o = r(116),
35633          a = r(26),
35634          s = r(55),
35635          u = r(124),
35636          f = r(52);
35637      n({
35638        target: "Promise",
35639        proto: !0,
35640        real: !0
35641      }, {
35642        finally: function (t) {
35643          var e = s(this, a("Promise")),
35644              r = "function" == typeof t;
35645          return this.then(r ? function (r) {
35646            return u(e, t()).then(function () {
35647              return r;
35648            });
35649          } : t, r ? function (r) {
35650            return u(e, t()).then(function () {
35651              throw r;
35652            });
35653          } : t);
35654        }
35655      }), i || "function" != typeof o || o.prototype.finally || f(o.prototype, "finally", a("Promise").prototype.finally);
35656    }, function (t, e, r) {
35657      var n = r(0),
35658          i = r(66),
35659          o = r(86),
35660          a = r(44),
35661          s = r(43),
35662          u = r(8),
35663          f = r(20),
35664          c = function (t, e) {
35665        var r = this;
35666        if (!(r instanceof c)) return new c(t, e);
35667        o && (r = o(new Error(e), i(r)));
35668        var n = [];
35669        return u(t, n.push, n), f(r, "errors", n), void 0 !== e && f(r, "message", Str
35669ing(e)), r;
35670      };
35671
35672      c.prototype = a(Error.prototype, {
35673        constructor: s(5, c),
35674        name: s(5, "AggregateError")
35675      }), n({
35676        global: !0
35677      }, {
35678        AggregateError: c
35679      });
35680    }, function (t, e, r) {
35681      r(125);
35682    }, function (t, e, r) {
35683
35684      var n = r(0),
35685          i = r(56),
35686          o = r(69);
35687      n({
35688        target: "Promise",
35689        stat: !0
35690      }, {
35691        try: function (t) {
35692          var e = i.f(this),
35693              r = o(t);
35694          return (r.error ? e.reject : e.resolve)(r.value), e.promise;
35695        }
35696      });
35697    }, function (t, e, r) {
35698
35699      var n = r(0),
35700          i = r(5),
35701          o = r(26),
35702          a = r(56),
35703          s = r(69),
35704          u = r(8);
35705      n({
35706        target: "Promise",
35707        stat: !0
35708      }, {
35709        any: function (t) {
35710          var e = this,
35711              r = a.f(e),
35712              n = r.resolve,
35713              f = r.reject,
35714              c = s(function () {
35715            var r = i(e.resolve),
35716                a = [],
35717                s = 0,
35718                c = 1,
35719                l = !1;
35720            u(t, function (t) {
35721              var i = s++,
35722                  u = !1;
35723              a.push(void 0), c++, r.call(e, t).then(function (t) {
35724                u || l || (l = !0, n(t));
35725              }, function (t) {
35726                u || l || (u = !0, a[i] = t, --c || f(new (o("AggregateError"))(a, "No one promise resolved")));
35727              });
35728            }), --c || f(new (o("AggregateError"))(a, "No one promise resolved"));
35729          });
35730          return c.error && f(c.value), r.promise;
35731        }
35732      });
35733    }, function (t, e, r) {
35734      t.exports = r(197);
35735    }, function (t, e, r) {
35736      t.exports = r(198);
35737    }, function (t, e, r) {
35738      r(199);
35739
35740      var n = r(3).Object,
35741          i = t.exports = function (t, e, r) {
35742        return n.defineProperty(t, e, r);
35743      };
35744
35745      n.defineProperty.sham && (i.sham = !0);
35746    }, function (t, e, r) {
35747      var n = r(0),
35748          i = r(17);
35749      n({
35750        target: "Object",
35751        stat: !0,
35752        forced: !i,
35753        sham: !i
35754      }, {
35755        defineProperty: r(21).f
35756      });
35757    }, function (t, e, r) {
35758      t.exports = i;
35759      var n = r(91).EventEmitter;
35760
35761      function i() {
35762        n.call(this);
35763      }
35764
35765      r(47)(i, n), i.Readable = r(92), i.Writable = r(208), i.Duplex = r(209), i.Transform = r(210), i.PassThrough = r(211), i.Stream = i, i.prototype.pipe = function (t, e) {
35766        var r = this;
35767
35768        function i(e) {
35769          t.writable && !1 === t.write(e) && r.pause && r.pause();
35770        }
35771
35772        function o() {
35773          r.readable && r.resume && r.resume();
35774        }
35775
35776        r.on("data", i), t.on("drain", o), t._isStdio || e && !1 === e.end || (r.on("end", s), r.on("close", u));
35777        var a = !1;
35778
35779        function s() {
35780          a || (a = !0, t.end());
35781        }
35782
35783        function u() {
35784          a || (a = !0, "function" == typeof t.destroy && t.destroy());
35785        }
35786
35787        function f(t) {
35788          if (c(), 0 === n.listenerCount(this, "error")) throw t;
35789        }
35790
35791        function c() {
35792          r.removeListener("data", i), t.removeListener("drain", o), r.removeListener("end", s), r.removeListener("close", u), r.removeListener("error", f), t.removeListener("error", f), r.removeListener("end", c), r.removeListener("close", c), t.removeListener("close", c);
35793        }
35794
35795        return r.on("error", f), t.on("error", f), r.on("end", c), r.on("close", c), t.on("close", c), t.emit("pipe", r), t;
35796      };
35797    }, function (t, e) {}, function (t, e, r) {
35798
35799      var n = r(71).Buffer,
35800          i = r(203);
35801      t.exports = function () {
35802        function t() {
35803          !function (t, e) {
35804            if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function");
35805          }(this, t), this.head = null, this.tail = null, this.length = 0;
35806        }
35807
35808        return t.prototype.push = function (t) {
35809          var e = {
35810            data: t,
35811            next: null
35812          };
35813          this.length > 0 ? this.tail.next = e : this.head = e, this.tail = e, ++this.length;
35814        }, t.prototype.unshift = function (t) {
35815          var e = {
35816            data: t,
35817            next: this.head
35818          };
35819          0 === this.length && (this.tail = e), this.head = e, ++this.length;
35820        }, t.prototype.shift = function () {
35821          if (0 !== this.length) {
35822            var t = this.head.data;
35823            return 1 === this.length ? this.head = this.tail = null : this.head = this.head.next, --this.length, t;
35824          }
35825        }, t.prototype.clear = function () {
35826          this.head = this.tail = null, this.length = 0;
35827        }, t.prototype.join = function (t) {
35828          if (0 === this.length) return "";
35829
35830          for (var e = this.head, r = "" + e.data; e = e.next;) r += t + e.data;
35831
35832          return r;
35833        }, t.prototype.concat = function (t) {
35834          if (0 === this.length) return n.alloc(0);
35835          if (1 === this.length) return this.head.data;
35836
35837          for (var e, r, i, o = n.allocUnsafe(t >>> 0), a = this.head, s = 0; a;) e = a.data, r = o, i = s, e.copy(r, i), s += a.data.length, a = a.next;
35838
35839          return o;
35840        }, t;
35841      }(), i && i.inspect && i.inspect.custom && (t.exports.prototype[i.inspect.custom] = function () {
35842        var t = i.inspect({
35843          length: this.length
35844        });
35845        return this.constructor.name + " " + t;
35846      });
35847    }, function (t, e) {}, function (t, e, r) {
35848      (function (t) {
35849        var n = void 0 !== t && t || "undefined" != typeof self && self || window,
35850            i = Function.prototype.apply;
35851
35852        function o(t, e) {
35853          this._id = t, this._clearFn = e;
35854        }
35855
35856        e.setTimeout = function () {
35857          return new o(i.call(setTimeout, n, arguments), clearTimeout);
35858        }, e.setInterval = function () {
35859          return new o(i.call(setInterval, n, arguments), clearInterval);
35860        }, e.clearTimeout = e.clearInterval = function (t) {
35861          t && t.close();
35862        }, o.prototype.unref = o.prototype.ref = function () {}, o.prototype.close = function () {
35863          this._clearFn.call(n, this._id);
35864        }, e.enroll = function (t, e) {
35865          clearTimeout(t._idleTimeoutId), t._idleTimeout = e;
35866        }, e.unenroll = function (t) {
35867          clearTimeout(t._idleTimeoutId), t._idleTimeout = -1;
35868        }, e._unrefActive = e.active = function (t) {
35869          clearTimeout(t._idleTimeoutId);
35870          var e = t._idleTimeout;
35871          e >= 0 && (t._idleTimeoutId = setTimeout(function () {
35872            t._onTimeout && t._onTimeout();
35873          }, e));
35874        }, r(205), e.setImmediate = "undefined" != typeof self && self.setImmediate || void 0 !== t && t.setImmediate || this && this.setImmediate, e.clearImmediate = "undefined" != typeof self && self.clearImmediate || void 0 !== t && t.clearImmediate || this && this.clearImmediate;
35875      }).call(this, r(23));
35876    }, function (t, e, r) {
35877      (function (t, e) {
35878        !function (t, r) {
35879
35880          if (!t.setImmediate) {
35881            var n,
35882                i,
35883                o,
35884                a,
35885                s,
35886                u = 1,
35887                f = {},
35888                c = !1,
35889                l = t.document,
35890                h = Object.getPrototypeOf && Object.getPrototypeOf(t);
35891            h = h && h.setTimeout ? h : t, "[object process]" === {}.toString.call(t.process) ? n = function (t) {
35892              e.nextTick(function () {
35893                p(t);
35894              });
35895            } : !function () {
35896              if (t.postMessage && !t.importScripts) {
35897                var e = !0,
35898                    r = t.onmessage;
35899                return t.onmessage = function () {
35900                  e = !1;
35901                }, t.postMessage("", "*"), t.onmessage = r, e;
35902              }
35903            }() ? t.MessageChannel ? ((o = new MessageChannel()).port1.onmessage = function (t) {
35904              p(t.data);
35905            }, n = function (t) {
35906              o.port2.postMessage(t);
35907            }) : l && "onreadystatechange" in l.createElement("script") ? (i = l.documentElement, n = function (t) {
35908              var e = l.createElement("script");
35909              e.onreadystatechange = function () {
35910                p(t), e.onreadystatechange = null, i.removeChild(e), e = null;
35911              }, i.appendChild(e);
35912            }) : n = function (t) {
35913              setTimeout(p, 0, t);
35914            } : (a = "setImmediate$" + Math.random() + "$", s = function (e) {
35915              e.source === t && "string" == typeof e.data && 0 === e.data.indexOf(a) && p(+e.data.slice(a.length));
35916            }, t.addEventListener ? t.addEventListener("message", s, !1) : t.attachEvent("onmessage", s), n = function (e) {
35917              t.postMessage(a + e, "*");
35918            }), h.setImmediate = function (t) {
35919              "function" != typeof t && (t = new Function("" + t));
35920
35921              for (var e = new Array(arguments.length - 1), r = 0; r < e.length; r++) e[r] = arguments[r + 1];
35922
35923              var i = {
35924                callback: t,
35925                args: e
35926              };
35927              return f[u] = i, n(u), u++;
35928            }, h.clearImmediate = d;
35929          }
35930
35931          function d(t) {
35932            delete f[t];
35933          }
35934
35935          function p(t) {
35936            if (c) setTimeout(p, 0, t);else {
35937              var e = f[t];
35938
35939              if (e) {
35940                c = !0;
35941
35942                try {
35943                  !function (t) {
35944                    var e = t.callback,
35945                        n = t.args;
35946
35947                    switch (n.length) {
35948                      case 0:
35949                        e();
35950                        break;
35951
35952                      case 1:
35953                        e(n[0]);
35954                        break;
35955
35956                      case 2:
35957                        e(n[0], n[1]);
35958                        break;
35959
35960                      case 3:
35961                        e(n[0], n[1], n[2]);
35962                        break;
35963
35964                      default:
35965                        e.apply(r, n);
35966                    }
35967                  }(e);
35968                } finally {
35969                  d(t), c = !1;
35970                }
35971              }
35972            }
35973          }
35974        }("undefined" == typeof self ? void 0 === t ? this : t : self);
35975      }).call(this, r(23), r(38));
35976    }, function (t, e, r) {
35977      (function (e) {
35978        function r(t) {
35979          try {
35980            if (!e.localStorage) return !1;
35981          } catch (t) {
35982            return !1;
35983          }
35984
35985          var r = e.localStorage[t];
35986          return null != r && "true" === String(r).toLowerCase();
35987        }
35988
35989        t.exports = function (t, e) {
35990          if (r("noDeprecation")) return t;
35991          var n = !1;
35992          return function () {
35993            if (!n) {
35994              if (r("throwDeprecation")) throw new Error(e);
35995              r("traceDeprecation") ? console.trace(e) : console.warn(e), n = !0;
35996            }
35997
35998            return t.apply(this, arguments);
35999          };
36000        };
36001      }).call(this, r(23));
36002    }, function (t, e, r) {
36003
36004      t.exports = o;
36005      var n = r(131),
36006          i = r(57);
36007
36008      function o(t) {
36009        if (!(this instanceof o)) return new o(t);
36010        n.call(this, t);
36011      }
36012
36013      i.inherits = r(47), i.inherits(o, n), o.prototype._transform = function (t, e, r) {
36014        r(null, t);
36015      };
36016    }, function (t, e, r) {
36017      t.exports = r(93);
36018    }, function (t, e, r) {
36019      t.exports = r(39);
36020    }, function (t, e, r) {
36021      t.exports = r(92).Transform;
36022    }, function (t, e, r) {
36023      t.exports = r(92).PassThrough;
36024    }, function (t, e, r) {
36025
36026      (function (t, n) {
36027        var i = r(132),
36028            o = r(216),
36029            a = r(217),
36030            s = r(220),
36031            u = r(223);
36032
36033        for (var f in u) e[f] = u[f];
36034
36035        e.NONE = 0, e.DEFLATE = 1, e.INFLATE = 2, e.GZIP = 3, e.GUNZIP = 4, e.DEFLATERAW = 5, e.INFLATERAW = 6, e.UNZIP = 7;
36036
36037        function c(t) {
36038          if ("number" != typeof t || t < e.DEFLATE || t > e.UNZIP) throw new TypeError("Bad argument");
36039          this.dictionary = null, this.err = 0, this.flush = 0, this.init_done = !1, this.level = 0, this.memLevel = 0, this.mode = t, this.strategy = 0, this.windowBits = 0, this.write_in_progress = !1, this.pending_close = !1, this.gzip_id_bytes_read = 0;
36040        }
36041
36042        c.prototype.close = function () {
36043          this.write_in_progress ? this.pending_close = !0 : (this.pending_close = !1, i(this.init_done, "close before init"), i(this.mode <= e.UNZIP), this.mode === e.DEFLATE || this.mode === e.GZIP || this.mode === e.DEFLATERAW ? a.deflateEnd(this.strm) : this.mode !== e.INFLATE && this.mode !== e.GUNZIP && this.mode !== e.INFLATERAW && this.mode !== e.UNZIP || s.inflateEnd(this.strm), this.mode = e.NONE, this.dictionary = null);
36044        }, c.prototype.write = function (t, e, r, n, i, o, a) {
36045          return this._write(!0, t, e, r, n, i, o, a);
36046        }, c.prototype.writeSync = function (t, e, r, n, i, o, a) {
36047          return this._write(!1, t, e, r, n, i, o, a);
36048        }, c.prototype._write = function (r, o, a, s, u, f, c, l) {
36049          if (i.equal(arguments.length, 8), i(this.init_done, "write before init"), i(this.mode !== e.NONE, "already finalized"), i.equal(!1, this.write_in_progress, "write already in progress"), i.equal(!1, this.pending_close, "close is pending"), this.write_in_progress = !0, i.equal(!1, void 0 === o, "must provide flush value"), this.write_in_progress = !0, o !== e.Z_NO_FLUSH && o !== e.Z_PARTIAL_FLUSH && o !== e.Z_SYNC_FLUSH && o !== e.Z_FULL_FLUSH && o !== e.Z_FINISH && o !== e.Z_BLOCK) throw new Error("Invalid flush value");
36050          if (null == a && (a = t.alloc(0), u = 0, s = 0), this.strm.avail_in = u, this.strm.input = a, this.strm.next_in = s, this.strm.avail_out = l, this.strm.output = f, this.strm.next_out = c, this.flush = o, !r) return this._process(), this._checkError() ? this._afterSync() : void 0;
36051          var h = this;
36052          return n.nextTick(function () {
36053            h._process(), h._after();
36054          }), this;
36055        }, c.prototype._afterSync = function () {
36056          var t = this.strm.avail_out,
36057              e = this.strm.avail_in;
36058          return this.write_in_progress = !1, [e, t];
36059        }, c.prototype._process = function () {
36060          var t = null;
36061
36062          switch (this.mode) {
36063            case e.DEFLATE:
36064            case e.GZIP:
36065            case e.DEFLATERAW:
36066              this.err = a.deflate(this.strm, this.flush);
36067              break;
36068
36069            case e.UNZIP:
36070              switch (this.strm.avail_in > 0 && (t = this.strm.next_in), this.gzip_id_bytes_read) {
36071                case 0:
36072                  if (null === t) break;
36073
36074                  if (31 !== this.strm.input[t]) {
36075                    this.mode = e.INFLATE;
36076                    break;
36077                  }
36078
36079                  if (this.gzip_id_bytes_read = 1, t++, 1 === this.strm.avail_in) break;
36080
36081                case 1:
36082                  if (null === t) break;
36083                  139 === this.strm.input[t] ? (this.gzip_id_bytes_read = 2, this.mode = e.GUNZIP) : this.mode = e.INFLATE;
36084                  break;
36085
36086                default:
36087                  throw new Error("invalid number of gzip magic number bytes read");
36088              }
36089
36090            case e.INFLATE:
36091            case e.GUNZIP:
36092            case e.INFLATERAW:
36093              for (this.err = s.inflate(this.strm, this.flush), this.err === e.Z_NEED_DICT && this.dictionary && (this.err = s.inflateSetDictionary(this.strm, this.dictionary), this.err === e.Z_OK ? this.err = s.inflate(this.strm, this.flush) : this.err === e.Z_DATA_ERROR && (this.err = e.Z_NEED_DICT)); this.strm.avail_in > 0 && this.mode === e.GUNZIP && this.err === e.Z_STREAM_END && 0 !== this.strm.next_in[0];) this.reset(), this.err = s.inflate(this.strm, this.flush);
36094
36095              break;
36096
36097            default:
36098              throw new Error("Unknown mode " + this.mode);
36099          }
36100        }, c.prototype._checkError = function () {
36101          switch (this.err) {
36102            case e.Z_OK:
36103            case e.Z_BUF_ERROR:
36104              if (0 !== this.strm.avail_out && this.flush === e.Z_FINISH) return this._error("unexpected end of file"), !1;
36105              break;
36106
36107            case e.Z_STREAM_END:
36108              break;
36109
36110            case e.Z_NEED_DICT:
36111              return null == this.dictionary ? this._error("Missing dictionary") : this._error("Bad dictionary"), !1;
36112
36113            default:
36114              return this._error("Zlib error"), !1;
36115          }
36116
36117          return !0;
36118        }, c.prototype._after = function () {
36119          if (this._checkError()) {
36120            var t = this.strm.avail_out,
36121                e = this.strm.avail_in;
36122            this.write_in_progress = !1, this.callback(e, t), this.pending_close && this.close();
36123          }
36124        }, c.prototype._error = function (t) {
36125          this.strm.msg && (t = this.strm.msg), this.onerror(t, this.err), this.write_in_progress = !1, this.pending_close && this.close();
36126        }, c.prototype.init = function (t, r, n, o, a) {
36127          i(4 === arguments.length || 5 === arguments.length, "init(windowBits, level, memLevel, strategy, [dictionary])"), i(t >= 8 && t <= 15, "invalid windowBits"), i(r >= -1 && r <= 9, "invalid compression level"), i(n >= 1 && n <= 9, "invalid memlevel"), i(o === e.Z_FILTERED || o === e.Z_HUFFMAN_ONLY || o === e.Z_RLE || o === e.Z_FIXED || o === e.Z_DEFAULT_STRATEGY, "invalid strategy"), this._init(r, t, n, o, a), this._setDictionary();
36128        }, c.prototype.params = function () {
36129          throw new Error("deflateParams Not supported");
36130        }, c.prototype.reset = function () {
36131          this._reset(), this._setDictionary();
36132        }, c.prototype._init = function (t, r, n, i, u) {
36133          switch (this.level = t, this.windowBits = r, this.memLevel = n, this.strategy = i, this.flush = e.Z_NO_FLUSH, this.err = e.Z_OK, this.mode !== e.GZIP && this.mode !== e.GUNZIP || (this.windowBits += 16), this.mode === e.UNZIP && (this.windowBits += 32), this.mode !== e.DEFLATERAW && this.mode !== e.INFLATERAW || (this.windowBits = -1 * this.windowBits), this.strm = new o(), this.mode) {
36134            case e.DEFLATE:
36135            case e.GZIP:
36136            case e.DEFLATERAW:
36137              this.err = a.deflateInit2(this.strm, this.level, e.Z_DEFLATED, this.windowBits, this.memLevel, this.strategy);
36138              break;
36139
36140            case e.INFLATE:
36141            case e.GUNZIP:
36142            case e.INFLATERAW:
36143            case e.UNZIP:
36144              this.err = s.inflateInit2(this.strm, this.windowBits);
36145              break;
36146
36147            default:
36148              throw new Error("Unknown mode " + this.mode);
36149          }
36150
36151          this.err !== e.Z_OK && this._error("Init error"), this.dictionary = u, this.write_in_progress = !1, this.init_done = !0;
36152        }, c.prototype._setDictionary = function () {
36153          if (null != this.dictionary) {
36154            switch (this.err = e.Z_OK, this.mode) {
36155              case e.DEFLATE:
36156              case e.DEFLATERAW:
36157                this.err = a.deflateSetDictionary(this.strm, this.dictionary);
36158            }
36159
36160            this.err !== e.Z_OK && this._error("Failed to set dictionary");
36161          }
36162        }, c.prototype._reset = function () {
36163          switch (this.err = e.Z_OK, this.mode) {
36164            case e.DEFLATE:
36165            case e.DEFLATERAW:
36166            case e.GZIP:
36167              this.err = a.deflateReset(this.strm);
36168              break;
36169
36170            case e.INFLATE:
36171            case e.INFLATERAW:
36172            case e.GUNZIP:
36173              this.err = s.inflateReset(this.strm);
36174          }
36175
36176          this.err !== e.Z_OK && this._error("Failed to reset stream");
36177        }, e.Zlib = c;
36178      }).call(this, r(19).Buffer, r(38));
36179    }, function (t, e, r) {
36180      /*
36181      object-assign
36182      (c) Sindre Sorhus
36183      @license MIT
36184      */
36185
36186      var n = Object.getOwnPropertySymbols,
36187          i = Object.prototype.hasOwnProperty,
36188          o = Object.prototype.propertyIsEnumerable;
36189
36190      function a(t) {
36191        if (null == t) throw new TypeError("Object.assign cannot be called with null or undefined");
36192        return Object(t);
36193      }
36194
36195      t.exports = function () {
36196        try {
36197          if (!Object.assign) return !1;
36198          var t = new String("abc");
36199          if (t[5] = "de", "5" === Object.getOwnPropertyNames(t)[0]) return !1;
36200
36201          for (var e = {}, r = 0; r < 10; r++) e["_" + String.fromCharCode(r)] = r;
36202
36203          if ("0123456789" !== Object.getOwnPropertyNames(e).map(function (t) {
36204            return e[t];
36205          }).join("")) return !1;
36206          var n = {};
36207          return "abcdefghijklmnopqrst".split("").forEach(function (t) {
36208            n[t] = t;
36209          }), "abcdefghijklmnopqrst" === Object.keys(Object.assign({}, n)).join("");
36210        } catch (t) {
36211          return !1;
36212        }
36213      }() ? Object.assign : function (t, e) {
36214        for (var r, s, u = a(t), f = 1; f < arguments.length; f++) {
36215          for (var c in r = Object(arguments[f])) i.call(r, c) && (u[c] = r[c]);
36216
36217          if (n) {
36218            s = n(r);
36219
36220            for (var l = 0; l < s.length; l++) o.call(r, s[l]) && (u[s[l]] = r[s[l]]);
36221          }
36222        }
36223
36224        return u;
36225      };
36226    }, function (t, e) {
36227      t.exports = function (t) {
36228        return t && "object" == typeof t && "function" == typeof t.copy && "function" == typeof t.fill && "function" == typeof t.readUInt8;
36229      };
36230    }, function (t, e) {
36231      "function" == typeof Object.create ? t.exports = function (t, e) {
36232        t.super_ = e, t.prototype = Object.create(e.prototype, {
36233          constructor: {
36234            value: t,
36235            enumerable: !1,
36236            writable: !0,
36237            configurable: !0
36238          }
36239        });
36240      } : t.exports = function (t, e) {
36241        t.super_ = e;
36242
36243        var r = function () {};
36244
36245        r.prototype = e.prototype, t.prototype = new r(), t.prototype.constructor = t;
36246      };
36247    }, function (t, e, r) {
36248
36249      t.exports = function () {
36250        this.input = null, this.next_in = 0, this.avail_in = 0, this.total_in = 0, this.output = null, this.next_out = 0, this.avail_out = 0, this.total_out = 0, this.msg = "", this.state = null, this.data_type = 2, this.adler = 0;
36251      };
36252    }, function (t, e, r) {
36253
36254      var n,
36255          i = r(72),
36256          o = r(218),
36257          a = r(134),
36258          s = r(135),
36259          u = r(219),
36260          f = 0,
36261          c = 1,
36262          l = 3,
36263          h = 4,
36264          d = 5,
36265          p = 0,
36266          g = 1,
36267          v = -2,
36268          y = -3,
36269          m = -5,
36270          b = -1,
36271          _ = 1,
36272          w = 2,
36273          x = 3,
36274          E = 4,
36275          S = 0,
36276          k = 2,
36277          A = 8,
36278          C = 9,
36279          T = 15,
36280          R = 8,
36281          O = 286,
36282          I = 30,
36283          L = 19,
36284          B = 2 * O + 1,
36285          P = 15,
36286          F = 3,
36287          N = 258,
36288          M = N + F + 1,
36289          j = 32,
36290          z = 42,
36291          U = 69,
36292          D = 73,
36293          q = 91,
36294          Z = 103,
36295          H = 113,
36296          V = 666,
36297          G = 1,
36298          Y = 2,
36299          W = 3,
36300          K = 4,
36301          Q = 3;
36302
36303      function X(t, e) {
36304        return t.msg = u[e], e;
36305      }
36306
36307      function $(t) {
36308        return (t << 1) - (t > 4 ? 9 : 0);
36309      }
36310
36311      function J(t) {
36312        for (var e = t.length; --e >= 0;) t[e] = 0;
36313      }
36314
36315      function tt(t) {
36316        var e = t.state,
36317            r = e.pending;
36318        r > t.avail_out && (r = t.avail_out), 0 !== r && (i.arraySet(t.output, e.pending_buf, e.pending_out, r, t.next_out), t.next_out += r, e.pending_out += r, t.total_out += r, t.avail_out -= r, e.pending -= r, 0 === e.pending && (e.pending_out = 0));
36319      }
36320
36321      function et(t, e) {
36322        o._tr_flush_block(t, t.block_start >= 0 ? t.block_start : -1, t.strstart - t.block_start, e), t.block_start = t.strstart, tt(t.strm);
36323      }
36324
36325      function rt(t, e) {
36326        t.pending_buf[t.pending++] = e;
36327      }
36328
36329      function nt(t, e) {
36330        t.pending_buf[t.pending++] = e >>> 8 & 255, t.pending_buf[t.pending++] = 255 & e;
36331      }
36332
36333      function it(t, e) {
36334        var r,
36335            n,
36336            i = t.max_chain_length,
36337            o = t.strstart,
36338            a = t.prev_length,
36339            s = t.nice_match,
36340            u = t.strstart > t.w_size - M ? t.strstart - (t.w_size - M) : 0,
36341            f = t.window,
36342            c = t.w_mask,
36343            l = t.prev,
36344            h = t.strstart + N,
36345            d = f[o + a - 1],
36346            p = f[o + a];
36347        t.prev_length >= t.good_match && (i >>= 2), s > t.lookahead && (s = t.lookahead);
36348
36349        do {
36350          if (f[(r = e) + a] === p && f[r + a - 1] === d && f[r] === f[o] && f[++r] === f[o + 1]) {
36351            o += 2, r++;
36352
36353            do {} while (f[++o] === f[++r] && f[++o] === f[++r] && f[++o] === f[++r] && f[++o] === f[++r] && f[++o] === f[++r] && f[++o] === f[++r] && f[++o] === f[++r] && f[++o] === f[++r] && o < h);
36354
36355            if (n = N - (h - o), o = h - N, n > a) {
36356              if (t.match_start = e, a = n, n >= s) break;
36357              d = f[o + a - 1], p = f[o + a];
36358            }
36359          }
36360        } while ((e = l[e & c]) > u && 0 != --i);
36361
36362        return a <= t.lookahead ? a : t.lookahead;
36363      }
36364
36365      function ot(t) {
36366        var e,
36367            r,
36368            n,
36369            o,
36370            u,
36371            f,
36372            c,
36373            l,
36374            h,
36375            d,
36376            p = t.w_size;
36377
36378        do {
36379          if (o = t.window_size - t.lookahead - t.strstart, t.strstart >= p + (p - M)) {
36380            i.arraySet(t.window, t.window, p, p, 0), t.match_start -= p, t.strstart -= p, t.block_start -= p, e = r = t.hash_size;
36381
36382            do {
36383              n = t.head[--e], t.head[e] = n >= p ? n - p : 0;
36384            } while (--r);
36385
36386            e = r = p;
36387
36388            do {
36389              n = t.prev[--e], t.prev[e] = n >= p ? n - p : 0;
36390            } while (--r);
36391
36392            o += p;
36393          }
36394
36395          if (0 === t.strm.avail_in) break;
36396          if (f = t.strm, c = t.window, l = t.strstart + t.lookahead, h = o, d = void 0, (d = f.avail_in) > h && (d = h), r = 0 === d ? 0 : (f.avail_in -= d, i.arraySet(c, f.input, f.next_in, d, l), 1 === f.state.wrap ? f.adler = a(f.adler, c, d, l) : 2 === f.state.wrap && (f.adler = s(f.adler, c, d, l)), f.next_in += d, f.total_in += d, d), t.lookahead += r, t.lookahead + t.insert >= F) for (u = t.strstart - t.insert, t.ins_h = t.window[u], t.ins_h = (t.ins_h << t.hash_shift ^ t.window[u + 1]) & t.hash_mask; t.insert && (t.ins_h = (t.ins_h << t.hash_shift ^ t.window[u + F - 1]) & t.hash_mask, t.prev[u & t.w_mask] = t.head[t.ins_h], t.head[t.ins_h] = u, u++, t.insert--, !(t.lookahead + t.insert < F)););
36397        } while (t.lookahead < M && 0 !== t.strm.avail_in);
36398      }
36399
36400      function at(t, e) {
36401        for (var r, n;;) {
36402          if (t.lookahead < M) {
36403            if (ot(t), t.lookahead < M && e === f) return G;
36404            if (0 === t.lookahead) break;
36405          }
36406
36407          if (r = 0, t.lookahead >= F && (t.ins_h = (t.ins_h << t.hash_shift ^ t.window[t.strstart + F - 1]) & t.hash_mask, r = t.prev[t.strstart & t.w_mask] = t.head[t.ins_h], t.head[t.ins_h] = t.strstart), 0 !== r && t.strstart - r <= t.w_size - M && (t.match_length = it(t, r)), t.match_length >= F) {
36408            if (n = o._tr_tally(t, t.strstart - t.match_start, t.match_length - F), t.lookahead -= t.match_length, t.match_length <= t.max_lazy_match && t.lookahead >= F) {
36409              t.match_length--;
36410
36411              do {
36412                t.strstart++, t.ins_h = (t.ins_h << t.hash_shift ^ t.window[t.strstart + F - 1]) & t.hash_mask, r = t.prev[t.strstart & t.w_mask] = t.head[t.ins_h], t.head[t.ins_h] = t.strstart;
36413              } while (0 != --t.match_length);
36414
36415              t.strstart++;
36416            } else t.strstart += t.match_length, t.match_length = 0, t.ins_h = t.window[t.strstart], t.ins_h = (t.ins_h << t.hash_shift ^ t.window[t.strstart + 1]) & t.hash_mask;
36417          } else n = o._tr_tally(t, 0, t.window[t.strstart]), t.lookahead--, t.strstart++;
36418          if (n && (et(t, !1), 0 === t.strm.avail_out)) return G;
36419        }
36420
36421        return t.insert = t.strstart < F - 1 ? t.strstart : F - 1, e === h ? (et(t, !0), 0 === t.strm.avail_out ? W : K) : t.last_lit && (et(t, !1), 0 === t.strm.avail_out) ? G : Y;
36422      }
36423
36424      function st(t, e) {
36425        for (var r, n, i;;) {
36426          if (t.lookahead < M) {
36427            if (ot(t), t.lookahead < M && e === f) return G;
36428            if (0 === t.lookahead) break;
36429          }
36430
36431          if (r = 0, t.lookahead >= F && (t.ins_h = (t.ins_h << t.hash_shift ^ t.window[t.strstart + F - 1]) & t.hash_mask, r = t.prev[t.strstart & t.w_mask] = t.head[t.ins_h], t.head[t.ins_h] = t.strstart), t.prev_length = t.match_length, t.prev_match = t.match_start, t.match_length = F - 1, 0 !== r && t.prev_length < t.max_lazy_match && t.strstart - r <= t.w_size - M && (t.match_length = it(t, r), t.match_length <= 5 && (t.strategy === _ || t.match_length === F && t.strstart - t.match_start > 4096) && (t.match_length = F - 1)), t.prev_length >= F && t.match_length <= t.prev_length) {
36432            i = t.strstart + t.lookahead - F, n = o._tr_tally(t, t.strstart - 1 - t.prev_match, t.prev_length - F), t.lookahead -= t.prev_length - 1, t.prev_length -= 2;
36433
36434            do {
36435              ++t.strstart <= i && (t.ins_h = (t.ins_h << t.hash_shift ^ t.window[t.strstart + F - 1]) & t.hash_mask, r = t.prev[t.strstart & t.w_mask] = t.head[t.ins_h], t.head[t.ins_h] = t.strstart);
36436            } while (0 != --t.prev_length);
36437
36438            if (t.match_available = 0, t.match_length = F - 1, t.strstart++, n && (et(t, !1), 0 === t.strm.avail_out)) return G;
36439          } else if (t.match_available) {
36440            if ((n = o._tr_tally(t, 0, t.window[t.strstart - 1])) && et(t, !1), t.strstart++, t.lookahead--, 0 === t.strm.avail_out) return G;
36441          } else t.match_available = 1, t.strstart++, t.lookahead--;
36442        }
36443
36444        return t.match_available && (n = o._tr_tally(t, 0, t.window[t.strstart - 1]), t.match_available = 0), t.insert = t.strstart < F - 1 ? t.strstart : F - 1, e === h ? (et(t, !0), 0 === t.strm.avail_out ? W : K) : t.last_lit && (et(t, !1), 0 === t.strm.avail_out) ? G : Y;
36445      }
36446
36447      function ut(t, e, r, n, i) {
36448        this.good_length = t, this.max_lazy = e, this.nice_length = r, this.max_chain = n, this.func = i;
36449      }
36450
36451      function ft() {
36452        this.strm = null, this.status = 0, this.pending_buf = null, this.pending_buf_size = 0, this.pending_out = 0, this.pending = 0, this.wrap = 0, this.gzhead = null, this.gzindex = 0, this.method = A, this.last_flush = -1, this.w_size = 0, this.w_bits = 0, this.w_mask = 0, this.window = null, this.window_size = 0, this.prev = null, this.head = null, this.ins_h = 0, this.hash_size = 0, this.hash_bits = 0, this.hash_mask = 0, this.hash_shift = 0, this.block_start = 0, this.match_length = 0, this.prev_match = 0, this.match_available = 0, this.strstart = 0, this.match_start = 0, this.lookahead = 0, this.prev_length = 0, this.max_chain_length = 0, this.max_lazy_match = 0, this.level = 0, this.strategy = 0, this.good_match = 0, this.nice_match = 0, this.dyn_ltree = new i.Buf16(2 * B), this.dyn_dtree = new i.Buf16(2 * (2 * I + 1)), this.bl_tree = new i.Buf16(2 * (2 * L + 1)), J(this.dyn_ltree), J(this.dyn_dtree), J(this.bl_tree), this.l_desc = null, this.d_desc 
36452= null, this.bl_desc = null, this.bl_count = new i.Buf16(P + 1), this.heap = new i.Buf16(2 * O + 1), J(this.heap), this.heap_len = 0, this.heap_max = 0, this.depth = new i.Buf16(2 * O + 1), J(this.depth), this.l_buf = 0, this.lit_bufsize = 0, this.last_lit = 0, this.d_buf = 0, this.opt_len = 0, this.static_len = 0, this.matches = 0, this.insert = 0, this.bi_buf = 0, this.bi_valid = 0;
36453      }
36454
36455      function ct(t) {
36456        var e;
36457        return t && t.state ? (t.total_in = t.total_out = 0, t.data_type = k, (e = t.state).pending = 0, e.pending_out = 0, e.wrap < 0 && (e.wrap = -e.wrap), e.status = e.wrap ? z : H, t.adler = 2 === e.wrap ? 0 : 1, e.last_flush = f, o._tr_init(e), p) : X(t, v);
36458      }
36459
36460      function lt(t) {
36461        var e,
36462            r = ct(t);
36463        return r === p && ((e = t.state).window_size = 2 * e.w_size, J(e.head), e.max_lazy_match = n[e.level].max_lazy, e.good_match = n[e.level].good_length, e.nice_match = n[e.level].nice_length, e.max_chain_length = n[e.level].max_chain, e.strstart = 0, e.block_start = 0, e.lookahead = 0, e.insert = 0, e.match_length = e.prev_length = F - 1, e.match_available = 0, e.ins_h = 0), r;
36464      }
36465
36466      function ht(t, e, r, n, o, a) {
36467        if (!t) return v;
36468        var s = 1;
36469        if (e === b && (e = 6), n < 0 ? (s = 0, n = -n) : n > 15 && (s = 2, n -= 16), o < 1 || o > C || r !== A || n < 8 || n > 15 || e < 0 || e > 9 || a < 0 || a > E) return X(t, v);
36470        8 === n && (n = 9);
36471        var u = new ft();
36472        return t.state = u, u.strm = t, u.wrap = s, u.gzhead = null, u.w_bits = n, u.w_size = 1 << u.w_bits, u.w_mask = u.w_size - 1, u.hash_bits = o + 7, u.hash_size = 1 << u.hash_bits, u.hash_mask = u.hash_size - 1, u.hash_shift = ~~((u.hash_bits + F - 1) / F), u.window = new i.Buf8(2 * u.w_size), u.head = new i.Buf16(u.hash_size), u.prev = new i.Buf16(u.w_size), u.lit_bufsize = 1 << o + 6, u.pending_buf_size = 4 * u.lit_bufsize, u.pending_buf = new i.Buf8(u.pending_buf_size), u.d_buf = 1 * u.lit_bufsize, u.l_buf = 3 * u.lit_bufsize, u.level = e, u.strategy = a, u.method = r, lt(t);
36473      }
36474
36475      n = [new ut(0, 0, 0, 0, function (t, e) {
36476        var r = 65535;
36477
36478        for (r > t.pending_buf_size - 5 && (r = t.pending_buf_size - 5);;) {
36479          if (t.lookahead <= 1) {
36480            if (ot(t), 0 === t.lookahead && e === f) return G;
36481            if (0 === t.lookahead) break;
36482          }
36483
36484          t.strstart += t.lookahead, t.lookahead = 0;
36485          var n = t.block_start + r;
36486          if ((0 === t.strstart || t.strstart >= n) && (t.lookahead = t.strstart - n, t.strstart = n, et(t, !1), 0 === t.strm.avail_out)) return G;
36487          if (t.strstart - t.block_start >= t.w_size - M && (et(t, !1), 0 === t.strm.avail_out)) return G;
36488        }
36489
36490        return t.insert = 0, e === h ? (et(t, !0), 0 === t.strm.avail_out ? W : K) : (t.strstart > t.block_start && (et(t, !1), t.strm.avail_out), G);
36491      }), new ut(4, 4, 8, 4, at), new ut(4, 5, 16, 8, at), new ut(4, 6, 32, 32, at), new ut(4, 4, 16, 16, st), new ut(8, 16, 32, 32, st), new ut(8, 16, 128, 128, st), new ut(8, 32, 128, 256, st), new ut(32, 128, 258, 1024, st), new ut(32, 258, 258, 4096, st)], e.deflateInit = function (t, e) {
36492        return ht(t, e, A, T, R, S);
36493      }, e.deflateInit2 = ht, e.deflateReset = lt, e.deflateResetKeep = ct, e.deflateSetHeader = function (t, e) {
36494        return t && t.state ? 2 !== t.state.wrap ? v : (t.state.gzhead = e, p) : v;
36495      }, e.deflate = function (t, e) {
36496        var r, i, a, u;
36497        if (!t || !t.state || e > d || e < 0) return t ? X(t, v) : v;
36498        if (i = t.state, !t.output || !t.input && 0 !== t.avail_in || i.status === V && e !== h) return X(t, 0 === t.avail_out ? m : v);
36499        if (i.strm = t, r = i.last_flush, i.last_flush = e, i.status === z) if (2 === i.wrap) t.adler = 0, rt(i, 31), rt(i, 139), rt(i, 8), i.gzhead ? (rt(i, (i.gzhead.text ? 1 : 0) + (i.gzhead.hcrc ? 2 : 0) + (i.gzhead.extra ? 4 : 0) + (i.gzhead.name ? 8 : 0) + (i.gzhead.comment ? 16 : 0)), rt(i, 255 & i.gzhead.time), rt(i, i.gzhead.time >> 8 & 255), rt(i, i.gzhead.time >> 16 & 255), rt(i, i.gzhead.time >> 24 & 255), rt(i, 9 === i.level ? 2 : i.strategy >= w || i.level < 2 ? 4 : 0), rt(i, 255 & i.gzhead.os), i.gzhead.extra && i.gzhead.extra.length && (rt(i, 255 & i.gzhead.extra.length), rt(i, i.gzhead.extra.length >> 8 & 255)), i.gzhead.hcrc && (t.adler = s(t.adler, i.pending_buf, i.pending, 0)), i.gzindex = 0, i.status = U) : (rt(i, 0), rt(i, 0), rt(i, 0), rt(i, 0), rt(i, 0), rt(i, 9 === i.level ? 2 : i.strategy >= w || i.level < 2 ? 4 : 0), rt(i, Q), i.status = H);else {
36500          var y = A + (i.w_bits - 8 << 4) << 8;
36501          y |= (i.strategy >= w || i.level < 2 ? 0 : i.level < 6 ? 1 : 6 === i.level ? 2 : 3) << 6, 0 !== i.strstart && (y |= j), y += 31 - y % 31, i.status = H, nt(i, y), 0 !== i.strstart && (nt(i, t.adler >>> 16), nt(i, 65535 & t.adler)), t.adler = 1;
36502        }
36503        if (i.status === U) if (i.gzhead.extra) {
36504          for (a = i.pending; i.gzindex < (65535 & i.gzhead.extra.length) && (i.pending !== i.pending_buf_size || (i.gzhead.hcrc && i.pending > a && (t.adler = s(t.adler, i.pending_buf, i.pending - a, a)), tt(t), a = i.pending, i.pending !== i.pending_buf_size));
36504) rt(i, 255 & i.gzhead.extra[i.gzindex]), i.gzindex++;
36505
36506          i.gzhead.hcrc && i.pending > a && (t.adler = s(t.adler, i.pending_buf, i.pending - a, a)), i.gzindex === i.gzhead.extra.length && (i.gzindex = 0, i.status = D);
36507        } else i.status = D;
36508        if (i.status === D) if (i.gzhead.name) {
36509          a = i.pending;
36510
36511          do {
36512            if (i.pending === i.pending_buf_size && (i.gzhead.hcrc && i.pending > a && (t.adler = s(t.adler, i.pending_buf, i.pending - a, a)), tt(t), a = i.pending, i.pending === i.pending_buf_size)) {
36513              u = 1;
36514              break;
36515            }
36516
36517            u = i.gzindex < i.gzhead.name.length ? 255 & i.gzhead.name.charCodeAt(i.gzindex++) : 0, rt(i, u);
36518          } while (0 !== u);
36519
36520          i.gzhead.hcrc && i.pending > a && (t.adler = s(t.adler, i.pending_buf, i.pending - a, a)), 0 === u && (i.gzindex = 0, i.status = q);
36521        } else i.status = q;
36522        if (i.status === q) if (i.gzhead.comment) {
36523          a = i.pending;
36524
36525          do {
36526            if (i.pending === i.pending_buf_size && (i.gzhead.hcrc && i.pending > a && (t.adler = s(t.adler, i.pending_buf, i.pending - a, a)), tt(t), a = i.pending, i.pending === i.pending_buf_size)) {
36527              u = 1;
36528              break;
36529            }
36530
36531            u = i.gzindex < i.gzhead.comment.length ? 255 & i.gzhead.comment.charCodeAt(i.gzindex++) : 0, rt(i, u);
36532          } while (0 !== u);
36533
36534          i.gzhead.hcrc && i.pending > a && (t.adler = s(t.adler, i.pending_buf, i.pending - a, a)), 0 === u && (i.status = Z);
36535        } else i.status = Z;
36536
36537        if (i.status === Z && (i.gzhead.hcrc ? (i.pending + 2 > i.pending_buf_size && tt(t), i.pending + 2 <= i.pending_buf_size && (rt(i, 255 & t.adler), rt(i, t.adler >> 8 & 255), t.adler = 0, i.status = H)) : i.status = H), 0 !== i.pending) {
36538          if (tt(t), 0 === t.avail_out) return i.last_flush = -1, p;
36539        } else if (0 === t.avail_in && $(e) <= $(r) && e !== h) return X(t, m);
36540
36541        if (i.status === V && 0 !== t.avail_in) return X(t, m);
36542
36543        if (0 !== t.avail_in || 0 !== i.lookahead || e !== f && i.status !== V) {
36544          var b = i.strategy === w ? function (t, e) {
36545            for (var r;;) {
36546              if (0 === t.lookahead && (ot(t), 0 === t.lookahead)) {
36547                if (e === f) return G;
36548                break;
36549              }
36550
36551              if (t.match_length = 0, r = o._tr_tally(t, 0, t.window[t.strstart]), t.lookahead--, t.strstart++, r && (et(t, !1), 0 === t.strm.avail_out)) return G;
36552            }
36553
36554            return t.insert = 0, e === h ? (et(t, !0), 0 === t.strm.avail_out ? W : K) : t.last_lit && (et(t, !1), 0 === t.strm.avail_out) ? G : Y;
36555          }(i, e) : i.strategy === x ? function (t, e) {
36556            for (var r, n, i, a, s = t.window;;) {
36557              if (t.lookahead <= N) {
36558                if (ot(t), t.lookahead <= N && e === f) return G;
36559                if (0 === t.lookahead) break;
36560              }
36561
36562              if (t.match_length = 0, t.lookahead >= F && t.strstart > 0 && (n = s[i = t.strstart - 1]) === s[++i] && n === s[++i] && n === s[++i]) {
36563                a = t.strstart + N;
36564
36565                do {} while (n === s[++i] && n === s[++i] && n === s[++i] && n === s[++i] && n === s[++i] && n === s[++i] && n === s[++i] && n === s[++i] && i < a);
36566
36567                t.match_length = N - (a - i), t.match_length > t.lookahead && (t.match_length = t.lookahead);
36568              }
36569
36570              if (t.match_length >= F ? (r = o._tr_tally(t, 1, t.match_length - F), t.lookahead -= t.match_length, t.strstart += t.match_length, t.match_length = 0) : (r = o._tr_tally(t, 0, t.window[t.strstart]), t.lookahead--, t.strstart++), r && (et(t, !1), 0 === t.strm.avail_out)) return G;
36571            }
36572
36573            return t.insert = 0, e === h ? (et(t, !0), 0 === t.strm.avail_out ? W : K) : t.last_lit && (et(t, !1), 0 === t.strm.avail_out) ? G : Y;
36574          }(i, e) : n[i.level].func(i, e);
36575          if (b !== W && b !== K || (i.status = V), b === G || b === W) return 0 === t.avail_out && (i.last_flush = -1), p;
36576          if (b === Y && (e === c ? o._tr_align(i) : e !== d && (o._tr_stored_block(i, 0, 0, !1), e === l && (J(i.head), 0 === i.lookahead && (i.strstart = 0, i.block_start = 0, i.insert = 0))), tt(t), 0 === t.avail_out)) return i.last_flush = -1, p;
36577        }
36578
36579        return e !== h ? p : i.wrap <= 0 ? g : (2 === i.wrap ? (rt(i, 255 & t.adler), rt(i, t.adler >> 8 & 255), rt(i, t.adler >> 16 & 255), rt(i, t.adler >> 24 & 255), rt(i, 255 & t.total_in), rt(i, t.total_in >> 8 & 255), rt(i, t.total_in >> 16 & 255), rt(i, t.total_in >> 24 & 255)) : (nt(i, t.adler >>> 16), nt(i, 65535 & t.adler)), tt(t), i.wrap > 0 && (i.wrap = -i.wrap), 0 !== i.pending ? p : g);
36580      }, e.deflateEnd = function (t) {
36581        var e;
36582        return t && t.state ? (e = t.state.status) !== z && e !== U && e !== D && e !== q && e !== Z && e !== H && e !== V ? X(t, v) : (t.state = null, e === H ? X(t, y) : p) : v;
36583      }, e.deflateSetDictionary = function (t, e) {
36584        var r,
36585            n,
36586            o,
36587            s,
36588            u,
36589            f,
36590            c,
36591            l,
36592            h = e.length;
36593        if (!t || !t.state) return v;
36594        if (2 === (s = (r = t.state).wrap) || 1 === s && r.status !== z || r.lookahead) return v;
36595
36596        for (1 === s && (t.adler = a(t.adler, e, h, 0)), r.wrap = 0, h >= r.w_size && (0 === s && (J(r.head), r.strstart = 0, r.block_start = 0, r.insert = 0), l = new i.Buf8(r.w_size), i.arraySet(l, e, h - r.w_size, r.w_size, 0), e = l, h = r.w_size), u = t.avail_in, f = t.next_in, c = t.input, t.avail_in = h, t.next_in = 0, t.input = e, ot(r); r.lookahead >= F;) {
36597          n = r.strstart, o = r.lookahead - (F - 1);
36598
36599          do {
36600            r.ins_h = (r.ins_h << r.hash_shift ^ r.window[n + F - 1]) & r.hash_mask, r.prev[n & r.w_mask] = r.head[r.ins_h], r.head[r.ins_h] = n, n++;
36601          } while (--o);
36602
36603          r.strstart = n, r.lookahead = F - 1, ot(r);
36604        }
36605
36606        return r.strstart += r.lookahead, r.block_start = r.strstart, r.insert = r.lookahead, r.lookahead = 0, r.match_length = r.prev_length = F - 1, r.match_available = 0, t.next_in = f, t.input = c, t.avail_in = u, r.wrap = s, p;
36607      }, e.deflateInfo = "pako deflate (from Nodeca project)";
36608    }, function (t, e, r) {
36609
36610      var n = r(72),
36611          i = 4,
36612          o = 0,
36613          a = 1,
36614          s = 2;
36615
36616      function u(t) {
36617        for (var e = t.length; --e >= 0;) t[e] = 0;
36618      }
36619
36620      var f = 0,
36621          c = 1,
36622          l = 2,
36623          h = 29,
36624          d = 256,
36625          p = d + 1 + h,
36626          g = 30,
36627          v = 19,
36628          y = 2 * p + 1,
36629          m = 15,
36630          b = 16,
36631          _ = 7,
36632          w = 256,
36633          x = 16,
36634          E = 17,
36635          S = 18,
36636          k = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0],
36637          A = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13],
36638          C = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7],
36639          T = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15],
36640          R = new Array(2 * (p + 2));
36641      u(R);
36642      var O = new Array(2 * g);
36643      u(O);
36644      var I = new Array(512);
36645      u(I);
36646      var L = new Array(256);
36647      u(L);
36648      var B = new Array(h);
36649      u(B);
36650      var P,
36651          F,
36652          N,
36653          M = new Array(g);
36654
36655      function j(t, e, r, n, i) {
36656        this.static_tree = t, this.extra_bits = e, this.extra_base = r, this.elems = n, this.max_length = i, this.has_stree = t && t.length;
36657      }
36658
36659      function z(t, e) {
36660        this.dyn_tree = t, this.max_code = 0, this.stat_desc = e;
36661      }
36662
36663      function U(t) {
36664        return t < 256 ? I[t] : I[256 + (t >>> 7)];
36665      }
36666
36667      function D(t, e) {
36668        t.pending_buf[t.pending++] = 255 & e, t.pending_buf[t.pending++] = e >>> 8 & 255;
36669      }
36670
36671      function q(t, e, r) {
36672        t.bi_valid > b - r ? (t.bi_buf |= e << t.bi_valid & 65535, D(t, t.bi_buf), t.bi_buf = e >> b - t.bi_valid, t.bi_valid += r - b) : (t.bi_buf |= e << t.bi_valid & 65535, t.bi_valid += r);
36673      }
36674
36675      function Z(t, e, r) {
36676        q(t, r[2 * e], r[2 * e + 1]);
36677      }
36678
36679      function H(t, e) {
36680        var r = 0;
36681
36682        do {
36683          r |= 1 & t, t >>>= 1, r <<= 1;
36684        } while (--e > 0);
36685
36686        return r >>> 1;
36687      }
36688
36689      function V(t, e, r) {
36690        var n,
36691            i,
36692            o = new Array(m + 1),
36693            a = 0;
36694
36695        for (n = 1; n <= m; n++) o[n] = a = a + r[n - 1] << 1;
36696
36697        for (i = 0; i <= e; i++) {
36698          var s = t[2 * i + 1];
36699          0 !== s && (t[2 * i] = H(o[s]++, s));
36700        }
36701      }
36702
36703      function G(t) {
36704        var e;
36705
36706        for (e = 0; e < p; e++) t.dyn_ltree[2 * e] = 0;
36707
36708        for (e = 0; e < g; e++) t.dyn_dtree[2 * e] = 0;
36709
36710        for (e = 0; e < v; e++) t.bl_tree[2 * e] = 0;
36711
36712        t.dyn_ltree[2 * w] = 1, t.opt_len = t.static_len = 0, t.last_lit = t.matches = 0;
36713      }
36714
36715      function Y(t) {
36716        t.bi_valid > 8 ? D(t, t.bi_buf) : t.bi_valid >
36716 0 && (t.pending_buf[t.pending++] = t.bi_buf), t.bi_buf = 0, t.bi_valid = 0;
36717      }
36718
36719      function W(t, e, r, n) {
36720        var i = 2 * e,
36721            o = 2 * r;
36722        return t[i] < t[o] || t[i] === t[o] && n[e] <= n[r];
36723      }
36724
36725      function K(t, e, r) {
36726        for (var n = t.heap[r], i = r << 1; i <= t.heap_len && (i < t.heap_len && W(e, t.heap[i + 1], t.heap[i], t.depth) && i++, !W(e, n, t.heap[i], t.depth));) t.heap[r] = t.heap[i], r = i, i <<= 1;
36727
36728        t.heap[r] = n;
36729      }
36730
36731      function Q(t, e, r) {
36732        var n,
36733            i,
36734            o,
36735            a,
36736            s = 0;
36737        if (0 !== t.last_lit) do {
36738          n = t.pending_buf[t.d_buf + 2 * s] << 8 | t.pending_buf[t.d_buf + 2 * s + 1], i = t.pending_buf[t.l_buf + s], s++, 0 === n ? Z(t, i, e) : (Z(t, (o = L[i]) + d + 1, e), 0 !== (a = k[o]) && q(t, i -= B[o], a), Z(t, o = U(--n), r), 0 !== (a = A[o]) && q(t, n -= M[o], a));
36739        } while (s < t.last_lit);
36740        Z(t, w, e);
36741      }
36742
36743      function X(t, e) {
36744        var r,
36745            n,
36746            i,
36747            o = e.dyn_tree,
36748            a = e.stat_desc.static_tree,
36749            s = e.stat_desc.has_stree,
36750            u = e.stat_desc.elems,
36751            f = -1;
36752
36753        for (t.heap_len = 0, t.heap_max = y, r = 0; r < u; r++) 0 !== o[2 * r] ? (t.heap[++t.heap_len] = f = r, t.depth[r] = 0) : o[2 * r + 1] = 0;
36754
36755        for (; t.heap_len < 2;) o[2 * (i = t.heap[++t.heap_len] = f < 2 ? ++f : 0)] = 1, t.depth[i] = 0, t.opt_len--, s && (t.static_len -= a[2 * i + 1]);
36756
36757        for (e.max_code = f, r = t.heap_len >> 1; r >= 1; r--) K(t, o, r);
36758
36759        i = u;
36760
36761        do {
36762          r = t.heap[1], t.heap[1] = t.heap[t.heap_len--], K(t, o, 1), n = t.heap[1], t.heap[--t.heap_max] = r, t.heap[--t.heap_max] = n, o[2 * i] = o[2 * r] + o[2 * n], t.depth[i] = (t.depth[r] >= t.depth[n] ? t.depth[r] : t.depth[n]) + 1, o[2 * r + 1] = o[2 * n + 1] = i, t.heap[1] = i++, K(t, o, 1);
36763        } while (t.heap_len >= 2);
36764
36765        t.heap[--t.heap_max] = t.heap[1], function (t, e) {
36766          var r,
36767              n,
36768              i,
36769              o,
36770              a,
36771              s,
36772              u = e.dyn_tree,
36773              f = e.max_code,
36774              c = e.stat_desc.static_tree,
36775              l = e.stat_desc.has_stree,
36776              h = e.stat_desc.extra_bits,
36777              d = e.stat_desc.extra_base,
36778              p = e.stat_desc.max_length,
36779              g = 0;
36780
36781          for (o = 0; o <= m; o++) t.bl_count[o] = 0;
36782
36783          for (u[2 * t.heap[t.heap_max] + 1] = 0, r = t.heap_max + 1; r < y; r++) (o = u[2 * u[2 * (n = t.heap[r]) + 1] + 1] + 1) > p && (o = p, g++), u[2 * n + 1] = o, n > f || (t.bl_count[o]++, a = 0, n >= d && (a = h[n - d]), s = u[2 * n], t.opt_len += s * (o + a), l && (t.static_len += s * (c[2 * n + 1] + a)));
36784
36785          if (0 !== g) {
36786            do {
36787              for (o = p - 1; 0 === t.bl_count[o];) o--;
36788
36789              t.bl_count[o]--, t.bl_count[o + 1] += 2, t.bl_count[p]--, g -= 2;
36790            } while (g > 0);
36791
36792            for (o = p; 0 !== o; o--) for (n = t.bl_count[o]; 0 !== n;) (i = t.heap[--r]) > f || (u[2 * i + 1] !== o && (t.opt_len += (o - u[2 * i + 1]) * u[2 * i], u[2 * i + 1] = o), n--);
36793          }
36794        }(t, e), V(o, f, t.bl_count);
36795      }
36796
36797      function $(t, e, r) {
36798        var n,
36799            i,
36800            o = -1,
36801            a = e[1],
36802            s = 0,
36803            u = 7,
36804            f = 4;
36805
36806        for (0 === a && (u = 138, f = 3), e[2 * (r + 1) + 1] = 65535, n = 0; n <= r; n++) i = a, a = e[2 * (n + 1) + 1], ++s < u && i === a || (s < f ? t.bl_tree[2 * i] += s : 0 !== i ? (i !== o && t.bl_tree[2 * i]++, t.bl_tree[2 * x]++) : s <= 10 ? t.bl_tree[2 * E]++ : t.bl_tree[2 * S]++, s = 0, o = i, 0 === a ? (u = 138, f = 3) : i === a ? (u = 6, f = 3) : (u = 7, f = 4));
36807      }
36808
36809      function J(t, e, r) {
36810        var n,
36811            i,
36812            o = -1,
36813            a = e[1],
36814            s = 0,
36815            u = 7,
36816            f = 4;
36817
36818        for (0 === a && (u = 138, f = 3), n = 0; n <= r; n++) if (i = a, a = e[2 * (n + 1) + 1], !(++s < u && i === a)) {
36819          if (s < f) do {
36820            Z(t, i, t.bl_tree);
36821          } while (0 != --s);else 0 !== i ? (i !== o && (Z(t, i, t.bl_tree), s--), Z(t, x, t.bl_tree), q(t, s - 3, 2)) : s <= 10 ? (Z(t, E, t.bl_tree), q(t, s - 3, 3)) : (Z(t, S, t.bl_tree), q(t, s - 11, 7));
36822          s = 0, o = i, 0 === a ? (u = 138, f = 3) : i === a ? (u = 6, f = 3) : (u = 7, f = 4);
36823        }
36824      }
36825
36826      u(M);
36827      var tt = !1;
36828
36829      function et(t, e, r, i) {
36830        q(t, (f << 1) + (i ? 1 : 0), 3), function (t, e, r, i) {
36831          Y(t), i && (D(t, r), D(t, ~r)), n.arraySet(t.pending_buf, t.window, e, r, t.pending), t.pending += r;
36832        }(t, e, r, !0);
36833      }
36834
36835      e._tr_init = function (t) {
36836        tt || (!function () {
36837          var t,
36838              e,
36839              r,
36840              n,
36841              i,
36842              o = new Array(m + 1);
36843
36844          for (r = 0, n = 0; n < h - 1; n++) for (B[n] = r, t = 0; t < 1 << k[n]; t++) L[r++] = n;
36845
36846          for (L[r - 1] = n, i = 0, n = 0; n < 16; n++) for (M[n] = i, t = 0; t < 1 << A[n]; t++) I[i++] = n;
36847
36848          for (i >>= 7; n < g; n++) for (M[n] = i << 7, t = 0; t < 1 << A[n] - 7; t++) I[256 + i++] = n;
36849
36850          for (e = 0; e <= m; e++) o[e] = 0;
36851
36852          for (t = 0; t <= 143;) R[2 * t + 1] = 8, t++, o[8]++;
36853
36854          for (; t <= 255;) R[2 * t + 1] = 9, t++, o[9]++;
36855
36856          for (; t <= 279;) R[2 * t + 1] = 7, t++, o[7]++;
36857
36858          for (; t <= 287;) R[2 * t + 1] = 8, t++, o[8]++;
36859
36860          for (V(R, p + 1, o), t = 0; t < g; t++) O[2 * t + 1] = 5, O[2 * t] = H(t, 5);
36861
36862          P = new j(R, k, d + 1, p, m), F = new j(O, A, 0, g, m), N = new j(new Array(0), C, 0, v, _);
36863        }(), tt = !0), t.l_desc = new z(t.dyn_ltree, P), t.d_desc = new z(t.dyn_dtree, F), t.bl_desc = new z(t.bl_tree, N), t.bi_buf = 0, t.bi_valid = 0, G(t);
36864      }, e._tr_stored_block = et, e._tr_flush_block = function (t, e, r, n) {
36865        var u,
36866            f,
36867            h = 0;
36868        t.level > 0 ? (t.strm.data_type === s && (t.strm.data_type = function (t) {
36869          var e,
36870              r = 4093624447;
36871
36872          for (e = 0; e <= 31; e++, r >>>= 1) if (1 & r && 0 !== t.dyn_ltree[2 * e]) return o;
36873
36874          if (0 !== t.dyn_ltree[18] || 0 !== t.dyn_ltree[20] || 0 !== t.dyn_ltree[26]) return a;
36875
36876          for (e = 32; e < d; e++) if (0 !== t.dyn_ltree[2 * e]) return a;
36877
36878          return o;
36879        }
36879(t)), X(t, t.l_desc), X(t, t.d_desc), h = function (t) {
36880          var e;
36881
36882          for ($(t, t.dyn_ltree, t.l_desc.max_code), $(t, t.dyn_dtree, t.d_desc.max_code), X(t, t.bl_desc), e = v - 1; e >= 3 && 0 === t.bl_tree[2 * T[e] + 1]; e--);
36883
36884          return t.opt_len += 3 * (e + 1) + 5 + 5 + 4, e;
36885        }(t), u = t.opt_len + 3 + 7 >>> 3, (f = t.static_len + 3 + 7 >>> 3) <= u && (u = f)) : u = f = r + 5, r + 4 <= u && -1 !== e ? et(t, e, r, n) : t.strategy === i || f === u ? (q(t, (c << 1) + (n ? 1 : 0), 3), Q(t, R, O)) : (q(t, (l << 1) + (n ? 1 : 0), 3), function (t, e, r, n) {
36886          var i;
36887
36888          for (q(t, e - 257, 5), q(t, r - 1, 5), q(t, n - 4, 4), i = 0; i < n; i++) q(t, t.bl_tree[2 * T[i] + 1], 3);
36889
36890          J(t, t.dyn_ltree, e - 1), J(t, t.dyn_dtree, r - 1);
36891        }(t, t.l_desc.max_code + 1, t.d_desc.max_code + 1, h + 1), Q(t, t.dyn_ltree, t.dyn_dtree)), G(t), n && Y(t);
36892      }, e._tr_tally = function (t, e, r) {
36893        return t.pending_buf[t.d_buf + 2 * t.last_lit] = e >>> 8 & 255, t.pending_buf[t.d_buf + 2 * t.last_lit + 1] = 255 & e, t.pending_buf[t.l_buf + t.last_lit] = 255 & r, t.last_lit++, 0 === e ? t.dyn_ltree[2 * r]++ : (t.matches++, e--, t.dyn_ltree[2 * (L[r] + d + 1)]++, t.dyn_dtree[2 * U(e)]++), t.last_lit === t.lit_bufsize - 1;
36894      }, e._tr_align = function (t) {
36895        q(t, c << 1, 3), Z(t, w, R), function (t) {
36896          16 === t.bi_valid ? (D(t, t.bi_buf), t.bi_buf = 0, t.bi_valid = 0) : t.bi_valid >= 8 && (t.pending_buf[t.pending++] = 255 & t.bi_buf, t.bi_buf >>= 8, t.bi_valid -= 8);
36897        }(t);
36898      };
36899    }, function (t, e, r) {
36900
36901      t.exports = {
36902        2: "need dictionary",
36903        1: "stream end",
36904        0: "",
36905        "-1": "file error",
36906        "-2": "stream error",
36907        "-3": "data error",
36908        "-4": "insufficient memory",
36909        "-5": "buffer error",
36910        "-6": "incompatible version"
36911      };
36912    }, function (t, e, r) {
36913
36914      var n = r(72),
36915          i = r(134),
36916          o = r(135),
36917          a = r(221),
36918          s = r(222),
36919          u = 0,
36920          f = 1,
36921          c = 2,
36922          l = 4,
36923          h = 5,
36924          d = 6,
36925          p = 0,
36926          g = 1,
36927          v = 2,
36928          y = -2,
36929          m = -3,
36930          b = -4,
36931          _ = -5,
36932          w = 8,
36933          x = 1,
36934          E = 2,
36935          S = 3,
36936          k = 4,
36937          A = 5,
36938          C = 6,
36939          T = 7,
36940          R = 8,
36941          O = 9,
36942          I = 10,
36943          L = 11,
36944          B = 12,
36945          P = 13,
36946          F = 14,
36947          N = 15,
36948          M = 16,
36949          j = 17,
36950          z = 18,
36951          U = 19,
36952          D = 20,
36953          q = 21,
36954          Z = 22,
36955          H = 23,
36956          V = 24,
36957          G = 25,
36958          Y = 26,
36959          W = 27,
36960          K = 28,
36961          Q = 29,
36962          X = 30,
36963          $ = 31,
36964          J = 32,
36965          tt = 852,
36966          et = 592,
36967          rt = 15;
36968
36969      function nt(t) {
36970        return (t >>> 24 & 255) + (t >>> 8 & 65280) + ((65280 & t) << 8) + ((255 & t) << 24);
36971      }
36972
36973      function it() {
36974        this.mode = 0, this.last = !1, this.wrap = 0, this.havedict = !1, this.flags = 0, this.dmax = 0, this.check = 0, this.total = 0, this.head = null, this.wbits = 0, this.wsize = 0, this.whave = 0, this.wnext = 0, this.window = null, this.hold = 0, this.bits = 0, this.length = 0, this.offset = 0, this.extra = 0, this.lencode = null, this.distcode = null, this.lenbits = 0, this.distbits = 0, this.ncode = 0, this.nlen = 0, this.ndist = 0, this.have = 0, this.next = null, this.lens = new n.Buf16(320), this.work = new n.Buf16(288), this.lendyn = null, this.distdyn = null, this.sane = 0, this.back = 0, this.was = 0;
36975      }
36976
36977      function ot(t) {
36978        var e;
36979        return t && t.state ? (e = t.state, t.total_in = t.total_out = e.total = 0, t.msg = "", e.wrap && (t.adler = 1 & e.wrap), e.mode = x, e.last = 0, e.havedict = 0, e.dmax = 32768, e.head = null, e.hold = 0, e.bits = 0, e.lencode = e.lendyn = new n.Buf32(tt), e.distcode = e.distdyn = new n.Buf32(et), e.sane = 1, e.back = -1, p) : y;
36980      }
36981
36982      function at(t) {
36983        var e;
36984        return t && t.state ? ((e = t.state).wsize = 0, e.whave = 0, e.wnext = 0, ot(t)) : y;
36985      }
36986
36987      function st(t, e) {
36988        var r, n;
36989        return t && t.state ? (n = t.state, e < 0 ? (r = 0, e = -e) : (r = 1 + (e >> 4), e < 48 && (e &= 15)), e && (e < 8 || e > 15) ? y : (null !== n.window && n.wbits !== e && (n.window = null), n.wrap = r, n.wbits = e, at(t))) : y;
36990      }
36991
36992      function ut(t, e) {
36993        var r, n;
36994        return t ? (n = new it(), t.state = n, n.window = null, (r = st(t, e)) !== p && (t.state = null), r) : y;
36995      }
36996
36997      var ft,
36998          ct,
36999          lt = !0;
37000
37001      function ht(t) {
37002        if (lt) {
37003          var e;
37004
37005          for (ft = new n.Buf32(512), ct = new n.Buf32(32), e = 0; e < 144;) t.lens[e++] = 8;
37006
37007          for (; e < 256;) t.lens[e++] = 9;
37008
37009          for (; e < 280;) t.lens[e++] = 7;
37010
37011          for (; e < 288;) t.lens[e++] = 8;
37012
37013          for (s(f, t.lens, 0, 288, ft, 0, t.work, {
37014            bits: 9
37015          }), e = 0; e < 32;) t.lens[e++] = 5;
37016
37017          s(c, t.lens, 0, 32, ct, 0, t.work, {
37018            bits: 5
37019          }), lt = !1;
37020        }
37021
37022        t.lencode = ft, t.lenbits = 9, t.distcode = ct, t.distbits = 5;
37023      }
37024
37025      function dt(t, e, r, i) {
37026        var o,
37027            a = t.state;
37028        return null === a.window && (a.wsize = 1 << a.wbits, a.wnext = 0, a.whave = 0, a.window = new n.Buf8(a.wsize)), i >= a.wsize ? (n.arraySet(a.window, e, r - a.wsize, a.wsize, 0), a.wnext = 0, a.whave = a.wsize) : ((o = a.wsize - a.wnext) > i && (o = i), n.arraySet(a.window, e, r - i, o, a.wnext), (i -= o) ? (n.arraySet(a.window, e, r - i, i, 0), a.wnext = i, a.whave = a.wsize) : (a.wnext += o, a.wnext === a.wsize && (a.wnext = 0), a.whave < a.wsize && (a.whave += o))), 0;
37029      }
37030
37031      e.inflateReset = at, e.inflateReset2 = st, e.inflateResetKeep = ot, e.inflateInit = function (t) {
37032        return ut(t, rt);
37033      }, e.inflateInit2 = ut, e.inflate = function (t, e) {
37034        var r,
37035            tt,
37036            et,
37037            rt,
37038            it,
37039            ot,
37040            at,
37041            st,
37042            ut,
37043            ft,
37044            ct,
37045            lt,
37046            pt,
37047            gt,
37048            vt,
37049            yt,
37050            mt,
37051            bt,
37052            _t,
37053            wt,
37054            xt,
37055            Et,
37056            St,
37057            kt,
37058            At = 0,
37059            Ct = new n.Buf8(4),
37060            Tt = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
37061
37062        if (!t || !t.state || !t.output || !t.input && 0 !== t.avail_in) return y;
37063        (r = t.state).mode === B && (r.mode = P), it = t.next_out, et = t.output, at = t.avail_out, rt = t.next_in, tt = t.input, ot = t.avail_in, st = r.hold, ut = r.bits, ft = ot, ct = at, Et = p;
37064
37065        t: for (;;) switch (r.mode) {
37066          case x:
37067            if (0 === r.wrap) {
37068              r.mode = P;
37069              break;
37070            }
37071
37072            for (; ut < 16;) {
37073              if (0 === ot) break t;
37074              ot--, st += tt[rt++] << ut, ut += 8;
37075            }
37076
37077            if (2 & r.wrap && 35615 === st) {
37078              r.check = 0, Ct[0] = 255 & st, Ct[1] = st >>> 8 & 255, r.check = o(r.check, Ct, 2, 0), st = 0, ut = 0, r.mode = E;
37079              break;
37080            }
37081
37082            if (r.flags = 0, r.head && (r.head.done = !1), !(1 & r.wrap) || (((255 & st) << 8) + (st >> 8)) % 31) {
37083              t.msg = "incorrect header check", r.mode = X;
37084              break;
37085            }
37086
37087            if ((15 & st) !== w) {
37088              t.msg = "unknown compression method", r.mode = X;
37089              break;
37090            }
37091
37092            if (ut -= 4, xt = 8 + (15 & (st >>>= 4)), 0 === r.wbits) r.wbits = xt;else if (xt > r.wbits) {
37093              t.msg = "invalid window size", r.mode = X;
37094              break;
37095            }
37096            r.dmax = 1 << xt, t.adler = r.check = 1, r.mode = 512 & st ? I : B, st = 0, ut = 0;
37097            break;
37098
37099          case E:
37100            for (; ut < 16;) {
37101              if (0 === ot) break t;
37102              ot--, st += tt[rt++] << ut, ut += 8;
37103            }
37104
37105            if (r.flags = st, (255 & r.flags) !== w) {
37106              t.msg = "unknown compression method", r.mode = X;
37107              break;
37108            }
37109
37110            if (57344 & r.flags) {
37111              t.msg = "unknown header flags set", r.mode = X;
37112              break;
37113            }
37114
37115            r.head && (r.head.text = st >> 8 & 1), 512 & r.flags && (Ct[0] = 255 & st, Ct[1] = st >>> 8 & 255, r.check = o(r.check, Ct, 2, 0)), st = 0, ut = 0, r.mode = S;
37116
37117          case S:
37118            for (; ut < 32;) {
37119              if (0 === ot) break t;
37120              ot--, st += tt[rt++] << ut, ut += 8;
37121            }
37122
37123            r.head && (r.head.time = st), 512 & r.flags && (Ct[0] = 255 & st, Ct[1] = st >>> 8 & 255, Ct[2] = st >>> 16 & 255, Ct[3] = st >>> 24 & 255, r.check = o(r.check, Ct, 4, 0)), st = 0, ut = 0, r.mode = k;
37124
37125          case k:
37126            for (; ut < 16;) {
37127              if (0 === ot) break t;
37128              ot--, st += tt[rt++] << ut, ut += 8;
37129            }
37130
37131            r.head && (r.head.xflags = 255 & st, r.head.os = st >> 8), 512 & r.flags && (Ct[0] = 255 & st, Ct[1] = st >>> 8 & 255, r.check = o(r.check, Ct, 2, 0)), st = 0, ut = 0, r.mode = A;
37132
37133          case A:
37134            if (1024 & r.flags) {
37135              for (; ut < 16;) {
37136                if (0 === ot) break t;
37137                ot--, st += tt[rt++] << ut, ut += 8;
37138              }
37139
37140              r.length = st, r.head && (r.head.extra_len = st), 512 & r.flags && (Ct[0] = 255 & st, Ct[1] = st >>> 8 & 255, r.check = o(r.check, Ct, 2, 0)), st = 0, ut = 0;
37141            } else r.head && (r.head.extra = null);
37142
37143            r.mode = C;
37144
37145          case C:
37146            if (1024 & r.flags && ((lt = r.length) > ot && (lt = ot), lt && (r.head && (xt = r.head.extra_len - r.length, r.head.extra || (r.head.extra = new Array(r.head.extra_len)), n.arraySet(r.head.extra, tt, rt, lt, xt)), 512 & r.flags && (r.check = o(r.check, tt, lt, rt)), ot -= lt, rt += lt, r.length -= lt), r.length)) break t;
37147            r.length = 0, r.mode = T;
37148
37149          case T:
37150            if (2048 & r.flags) {
37151              if (0 === ot) break t;
37152              lt = 0;
37153
37154              do {
37155                xt = tt[rt + lt++], r.head && xt && r.length < 65536 && (r.head.name += String.fromCharCode(xt));
37156              } while (xt && lt < ot);
37157
37158              if (512 & r.flags && (r.check = o(r.check, tt, lt, rt)), ot -= lt, rt += lt, xt) break t;
37159            } else r.head && (r.head.name = null);
37160
37161            r.length = 0, r.mode = R;
37162
37163          case R:
37164            if (4096 & r.flags) {
37165              if (0 === ot) break t;
37166              lt = 0;
37167
37168              do {
37169                xt = tt[rt + lt++], r.head && xt && r.length < 65536 && (r.head.comment += String.fromCharCode(xt));
37170              } while (xt && lt < ot);
37171
37172              if (512 & r.flags && (r.check = o(r.check, tt, lt, rt)), ot -= lt, rt += lt, xt) break t;
37173            } else r.head && (r.head.comment = null);
37174
37175            r.mode = O;
37176
37177          case O:
37178            if (512 & r.flags) {
37179              for (; ut < 16;) {
37180                if (0 === ot) break t;
37181                ot--, st += tt[rt++] << ut, ut += 8;
37182              }
37183
37184              if (st !== (65535 & r.check)) {
37185                t.msg = "header crc mismatch", r.mode = X;
37186                break;
37187              }
37188
37189              st = 0, ut = 0;
37190            }
37191
37192            r.head && (r.head.hcrc = r.flags >>
37192 9 & 1, r.head.done = !0), t.adler = r.check = 0, r.mode = B;
37193            break;
37194
37195          case I:
37196            for (; ut < 32;) {
37197              if (0 === ot) break t;
37198              ot--, st += tt[rt++] << ut, ut += 8;
37199            }
37200
37201            t.adler = r.check = nt(st), st = 0, ut = 0, r.mode = L;
37202
37203          case L:
37204            if (0 === r.havedict) return t.next_out = it, t.avail_out = at, t.next_in = rt, t.avail_in = ot, r.hold = st, r.bits = ut, v;
37205            t.adler = r.check = 1, r.mode = B;
37206
37207          case B:
37208            if (e === h || e === d) break t;
37209
37210          case P:
37211            if (r.last) {
37212              st >>>= 7 & ut, ut -= 7 & ut, r.mode = W;
37213              break;
37214            }
37215
37216            for (; ut < 3;) {
37217              if (0 === ot) break t;
37218              ot--, st += tt[rt++] << ut, ut += 8;
37219            }
37220
37221            switch (r.last = 1 & st, ut -= 1, 3 & (st >>>= 1)) {
37222              case 0:
37223                r.mode = F;
37224                break;
37225
37226              case 1:
37227                if (ht(r), r.mode = D, e === d) {
37228                  st >>>= 2, ut -= 2;
37229                  break t;
37230                }
37231
37232                break;
37233
37234              case 2:
37235                r.mode = j;
37236                break;
37237
37238              case 3:
37239                t.msg = "invalid block type", r.mode = X;
37240            }
37241
37242            st >>>= 2, ut -= 2;
37243            break;
37244
37245          case F:
37246            for (st >>>= 7 & ut, ut -= 7 & ut; ut < 32;) {
37247              if (0 === ot) break t;
37248              ot--, st += tt[rt++] << ut, ut += 8;
37249            }
37250
37251            if ((65535 & st) != (st >>> 16 ^ 65535)) {
37252              t.msg = "invalid stored block lengths", r.mode = X;
37253              break;
37254            }
37255
37256            if (r.length = 65535 & st, st = 0, ut = 0, r.mode = N, e === d) break t;
37257
37258          case N:
37259            r.mode = M;
37260
37261          case M:
37262            if (lt = r.length) {
37263              if (lt > ot && (lt = ot), lt > at && (lt = at), 0 === lt) break t;
37264              n.arraySet(et, tt, rt, lt, it), ot -= lt, rt += lt, at -= lt, it += lt, r.length -= lt;
37265              break;
37266            }
37267
37268            r.mode = B;
37269            break;
37270
37271          case j:
37272            for (; ut < 14;) {
37273              if (0 === ot) break t;
37274              ot--, st += tt[rt++] << ut, ut += 8;
37275            }
37276
37277            if (r.nlen = 257 + (31 & st), st >>>= 5, ut -= 5, r.ndist = 1 + (31 & st), st >>>= 5, ut -= 5, r.ncode = 4 + (15 & st), st >>>= 4, ut -= 4, r.nlen > 286 || r.ndist > 30) {
37278              t.msg = "too many length or distance symbols", r.mode = X;
37279              break;
37280            }
37281
37282            r.have = 0, r.mode = z;
37283
37284          case z:
37285            for (; r.have < r.ncode;) {
37286              for (; ut < 3;) {
37287                if (0 === ot) break t;
37288                ot--, st += tt[rt++] << ut, ut += 8;
37289              }
37290
37291              r.lens[Tt[r.have++]] = 7 & st, st >>>= 3, ut -= 3;
37292            }
37293
37294            for (; r.have < 19;) r.lens[Tt[r.have++]] = 0;
37295
37296            if (r.lencode = r.lendyn, r.lenbits = 7, St = {
37297              bits: r.lenbits
37298            }, Et = s(u, r.lens, 0, 19, r.lencode, 0, r.work, St), r.lenbits = St.bits, Et) {
37299              t.msg = "invalid code lengths set", r.mode = X;
37300              break;
37301            }
37302
37303            r.have = 0, r.mode = U;
37304
37305          case U:
37306            for (; r.have < r.nlen + r.ndist;) {
37307              for (; yt = (At = r.lencode[st & (1 << r.lenbits) - 1]) >>> 16 & 255, mt = 65535 & At, !((vt = At >>> 24) <= ut);) {
37308                if (0 === ot) break t;
37309                ot--, st += tt[rt++] << ut, ut += 8;
37310              }
37311
37312              if (mt < 16) st >>>= vt, ut -= vt, r.lens[r.have++] = mt;else {
37313                if (16 === mt) {
37314                  for (kt = vt + 2; ut < kt;) {
37315                    if (0 === ot) break t;
37316                    ot--, st += tt[rt++] << ut, ut += 8;
37317                  }
37318
37319                  if (st >>>= vt, ut -= vt, 0 === r.have) {
37320                    t.msg = "invalid bit length repeat", r.mode = X;
37321                    break;
37322                  }
37323
37324                  xt = r.lens[r.have - 1], lt = 3 + (3 & st), st >>>= 2, ut -= 2;
37325                }
37325 else if (17 === mt) {
37326                  for (kt = vt + 3; ut < kt;) {
37327                    if (0 === ot) break t;
37328                    ot--, st += tt[rt++] << ut, ut += 8;
37329                  }
37330
37331                  ut -= vt, xt = 0, lt = 3 + (7 & (st >>>= vt)), st >>>= 3, ut -= 3;
37332                } else {
37333                  for (kt = vt + 7; ut < kt;) {
37334                    if (0 === ot) break t;
37335                    ot--, st += tt[rt++] << ut, ut += 8;
37336                  }
37337
37338                  ut -= vt, xt = 0, lt = 11 + (127 & (st >>>= vt)), st >>>= 7, ut -= 7;
37339                }
37340
37341                if (r.have + lt > r.nlen + r.ndist) {
37342                  t.msg = "invalid bit length repeat", r.mode = X;
37343                  break;
37344                }
37345
37346                for (; lt--;) r.lens[r.have++] = xt;
37347              }
37348            }
37349
37350            if (r.mode === X) break;
37351
37352            if (0 === r.lens[256]) {
37353              t.msg = "invalid code -- missing end-of-block", r.mode = X;
37354              break;
37355            }
37356
37357            if (r.lenbits = 9, St = {
37358              bits: r.lenbits
37359            }, Et = s(f, r.lens, 0, r.nlen, r.lencode, 0, r.work, St), r.lenbits = St.bits, Et) {
37360              t.msg = "invalid literal/lengths set", r.mode = X;
37361              break;
37362            }
37363
37364            if (r.distbits = 6, r.distcode = r.distdyn, St = {
37365              bits: r.distbits
37366            }, Et = s(c, r.lens, r.nlen, r.ndist, r.distcode, 0, r.work, St), r.distbits = St.bits, Et) {
37367              t.msg = "invalid distances set", r.mode = X;
37368              break;
37369            }
37370
37371            if (r.mode = D, e === d) break t;
37372
37373          case D:
37374            r.mode = q;
37375
37376          case q:
37377            if (ot >= 6 && at >= 258) {
37378              t.next_out = it, t.avail_out = at, t.next_in = rt, t.avail_in = ot, r.hold = st, r.bits = ut, a(t, ct), it = t.next_out, et = t.output, at = t.avail_out, rt = t.next_in, tt = t.input, ot = t.avail_in, st = r.hold, ut = r.bits, r.mode === B && (r.back = -1);
37379              break;
37380            }
37381
37382            for (r.back = 0; yt = (At = r.lencode[st & (1 << r.lenbits) - 1]) >>> 16 & 255, mt = 65535 & At, !((vt = At >>> 24) <= ut);) {
37383              if (0 === ot) break t;
37384              ot--, st += tt[rt++] << ut, ut += 8;
37385            }
37386
37387            if (yt && 0 == (240 & yt)) {
37388              for (bt = vt, _t = yt, wt = mt; yt = (At = r.lencode[wt + ((st & (1 << bt + _t) - 1) >> bt)]) >>> 16 & 255, mt = 65535 & At, !(bt + (vt = At >>> 24) <= ut);) {
37389                if (0 === ot) break t;
37390                ot--, st += tt[rt++] << ut, ut += 8;
37391              }
37392
37393              st >>>= bt, ut -= bt, r.back += bt;
37394            }
37395
37396            if (st >>>= vt, ut -= vt, r.back += vt, r.length = mt, 0 === yt) {
37397              r.mode = Y;
37398              break;
37399            }
37400
37401            if (32 & yt) {
37402              r.back = -1, r.mode = B;
37403              break;
37404            }
37405
37406            if (64 & yt) {
37407              t.msg = "invalid literal/length code", r.mode = X;
37408              break;
37409            }
37410
37411            r.extra = 15 & yt, r.mode = Z;
37412
37413          case Z:
37414            if (r.extra) {
37415              for (kt = r.extra; ut < kt;) {
37416                if (0 === ot) break t;
37417                ot--, st += tt[rt++] << ut, ut += 8;
37418              }
37419
37420              r.length += st & (1 << r.extra) - 1, st >>>= r.extra, ut -= r.extra, r.back += r.extra;
37421            }
37422
37423            r.was = r.length, r.mode = H;
37424
37425          case H:
37426            for (; yt = (At = r.distcode[st & (1 << r.distbits) - 1]) >>> 16 & 255, mt = 65535 & At, !((vt = At >>> 24) <= ut);) {
37427              if (0 === ot) break t;
37428              ot--, st += tt[rt++] << ut, ut += 8;
37429            }
37430
37431            if (0 == (240 & yt)) {
37432              for (bt = vt, _t = yt, wt = mt; yt = (At = r.distcode[wt + ((st & (1 << bt + _t) - 1) >> bt)]) >>> 16 & 255, mt = 65535 & At, !(bt + (vt = At >>> 24) <= ut);) {
37433                if (0 === ot) break t;
37434                ot--, st += tt[rt++] << ut, ut += 8;
37435              }
37436
37437              st >>>= bt, ut -= bt, r.back += bt;
37438            }
37439
37440            if (st >>>= vt, ut -= vt, r.back += vt, 64 & yt) {
37441              t.msg = "invalid distance code", r.mode = X;
37442              break;
37443            }
37444
37445            r.offset = mt, r.extra = 15 & yt, r.mode = V;
37446
37447          case V:
37448            if (r.extra) {
37449              for (kt = r.extra; ut < kt;) {
37450                if (0 === ot) break t;
37451                ot--, st += tt[rt++] << ut, ut += 8;
37452              }
37453
37454              r.offset += st & (1 << r.extra) - 1, st >>>= r.extra, ut -= r.extra, r.back += r.extra;
37455            }
37456
37457            if (r.offset > r.dmax) {
37458              t.msg = "invalid distance too far back", r.mode = X;
37459              break;
37460            }
37461
37462            r.mode = G;
37463
37464          case G:
37465            if (0 === at) break t;
37466
37467            if (lt = ct - at, r.offset > lt) {
37468              if ((lt = r.offset - lt) > r.whave && r.sane) {
37469                t.msg = "invalid distance too far back", r.mode = X;
37470                break;
37471              }
37472
37473              lt > r.wnext ? (lt -= r.wnext, pt = r.wsize - lt) : pt = r.wnext - lt, lt > r.length && (lt = r.length), gt = r.window;
37474            } else gt = et, pt = it - r.offset, lt = r.length;
37475
37476            lt > at && (lt = at), at -= lt, r.length -= lt;
37477
37478            do {
37479              et[it++] = gt[pt++];
37480            } while (--lt);
37481
37482            0 === r.length && (r.mode = q);
37483            break;
37484
37485          case Y:
37486            if (0 === at) break t;
37487            et[it++] = r.length, at--, r.mode = q;
37488            break;
37489
37490          case W:
37491            if (r.wrap) {
37492              for (; ut < 32;) {
37493                if (0 === ot) break t;
37494                ot--, st |= tt[rt++] << ut, ut += 8;
37495              }
37496
37497              if (ct -= at, t.total_out += ct, r.total += ct, ct && (t.adler = r.check = r.flags ? o(r.check, et, ct, it - ct) : i(r.check, et, ct, it - ct)), ct = at, (r.flags ? st : nt(st)) !== r.check) {
37498                t.msg = "incorrect data check", r.mode = X;
37499                break;
37500              }
37501
37502              st = 0, ut = 0;
37503            }
37504
37505            r.mode = K;
37506
37507          case K:
37508            if (r.wrap && r.flags) {
37509              for (; ut < 32;) {
37510                if (0 === ot) break t;
37511                ot--, st += tt[rt++] << ut, ut += 8;
37512              }
37513
37514              if (st !== (4294967295 & r.total)) {
37515                t.msg = "incorrect length check", r.mode = X;
37516                break;
37517              }
37518
37519              st = 0, ut = 0;
37520            }
37521
37522            r.mode = Q;
37523
37524          case Q:
37525            Et = g;
37526            break t;
37527
37528          case X:
37529            Et = m;
37530            break t;
37531
37532          case $:
37533            return b;
37534
37535          case J:
37536          default:
37537            return y;
37538        }
37539
37540        return t.next_out = it, t.avail_out = at, t.next_in = rt, t.avail_in = ot, r.hold = st, r.bits = ut, (r.wsize || ct !== t.avail_out && r.mode < X && (r.mode < W || e !== l)) && dt(t, t.output, t.next_out, ct - t.avail_out) ? (r.mode = $, b) : (ft -= t.avail_in, ct -= t.avail_out, t.total_in += ft, t.total_out += ct, r.total += ct, r.wrap && ct && (t.adler = r.check = r.flags ? o(r.check, et, ct, t.next_out - ct) : i(r.check, et, ct, t.next_out - ct)), t.data_type = r.bits + (r.last ? 64 : 0) + (r.mode === B ? 128 : 0) + (r.mode === D || r.mode === N ? 256 : 0), (0 === ft && 0 === ct || e === l) && Et === p && (Et = _), Et);
37541      }, e.inflateEnd = function (t) {
37542        if (!t || !t.state) return y;
37543        var e = t.state;
37544        return e.window && (e.window = null), t.state = null, p;
37545      }, e.inflateGetHeader = function (t, e) {
37546        var r;
37547        return t && t.state ? 0 == (2 & (r = t.state).wrap) ? y : (r.head = e, e.done = !1, p) : y;
37548      }, e.inflateSetDictionary = function (t, e) {
37549        var r,
37550            n = e.length;
37551        return t && t.state ? 0 !== (r = t.state).wrap && r.mode !== L ? y : r.mode === L && i(1, e, n, 0) !== r.check ? m : dt(t, e, n, n) ? (r.mode = $, b) : (r.havedict = 1, p) : y;
37552      }, e.inflateInfo = "pako inflate (from Nodeca project)";
37553    }, function (t, e, r) {
37554
37555      t.exports = function (t, e) {
37556        var r, n, i, o, a, s, u, f, c, l, h, d, p, g, v, y, m, b, _, w, x, E, S, k, A;
37557
37558        r = t.state, n = t.next_in, k = t.input, i = n + (t.avail_in - 5), o = t.next_out, A = t.output, a = o - (e - t.avail_out), s = o + (t.avail_out - 257), u = r.dmax, f = r.wsize, c = r.whave, l = r.wnext, h = r.window, d = r.hold, p = r.bits, g = r.lencode, v = r.distcode, y = (1 << r.lenbits) - 1, m = (1 << r.distbits) - 1;
37559
37560        t: do {
37561          p < 15 && (d += k[n++] << p, p += 8, d += k[n++] << p, p += 8), b = g[d & y];
37562
37563          e: for (;;) {
37564            if (d >>>= _ = b >>> 24, p -= _, 0 === (_ = b >>> 16 & 255)) A[o++] = 65535 & b;else {
37565              if (!(16 & _)) {
37566                if (0 == (64 & _)) {
37567                  b = g[(65535 & b) + (d & (1 << _) - 1)];
37568                  continue e;
37569                }
37570
37571                if (32 & _) {
37572                  r.mode = 12;
37573                  break t;
37574                }
37575
37576                t.msg = "invalid literal/length code", r.mode = 30;
37577                break t;
37578              }
37579
37580              w = 65535 & b, (_ &= 15) && (p < _ && (d += k[n++] << p, p += 8), w += d & (1 << _) - 1, d >>>= _, p -= _), p < 15 && (d += k[n++] << p, p += 8, d += k[n++] << p, p += 8), b = v[d & m];
37581
37582              r: for (;;) {
37583                if (d >>>= _ = b >>> 24, p -= _, !(16 & (_ = b >>> 16 & 255))) {
37584                  if (0 == (64 & _)) {
37585                    b = v[(65535 & b) + (d & (1 << _) - 1)];
37586                    continue r;
37587                  }
37588
37589                  t.msg = "invalid distance code", r.mode = 30;
37590                  break t;
37591                }
37592
37593                if (x = 65535 & b, p < (_ &= 15) && (d += k[n++] << p, (p += 8) < _ && (d += k[n++] << p, p += 8)), (x += d & (1 << _) - 1) > u) {
37594                  t.msg = "invalid distance too far back", r.mode = 30;
37595                  break t;
37596                }
37597
37598                if (d >>>= _, p -= _, x > (_ = o - a)) {
37599                  if ((_ = x - _) > c && r.sane) {
37600                    t.msg = "invalid distance too far back", r.mode = 30;
37601                    break t;
37602                  }
37603
37604                  if (E = 0, S = h, 0 === l) {
37605                    if (E += f - _, _ < w) {
37606                      w -= _;
37607
37608                      do {
37609                        A[o++] = h[E++];
37610                      } while (--_);
37611
37612                      E = o - x, S = A;
37613                    }
37614                  } else if (l < _) {
37615                    if (E += f + l - _, (_ -= l) < w) {
37616                      w -= _;
37617
37618                      do {
37619                        A[o++] = h[E++];
37620                      } while (--_);
37621
37622                      if (E = 0, l < w) {
37623                        w -= _ = l;
37624
37625                        do {
37626                          A[o++] = h[E++];
37627                        } while (--_);
37628
37629                        E = o - x, S = A;
37630                      }
37631                    }
37632                  } else if (E += l - _, _ < w) {
37633                    w -= _;
37634
37635                    do {
37636                      A[o++] = h[E++];
37637                    } while (--_);
37638
37639                    E = o - x, S = A;
37640                  }
37641
37642                  for (; w > 2;) A[o++] = S[E++], A[o++] = S[E++], A[o++] = S[E++], w -= 3;
37643
37644                  w && (A[o++] = S[E++], w > 1 && (A[o++] = S[E++]));
37645                } else {
37646                  E = o - x;
37647
37648                  do {
37649                    A[o++] = A[E++], A[o++] = A[E++], A[o++] = A[E++], w -= 3;
37650                  } while (w > 2);
37651
37652                  w && (A[o++] = A[E++], w > 1 && (A[o++] = A[E++]));
37653                }
37654
37655                break;
37656              }
37657            }
37658            break;
37659          }
37660        } while (n < i && o < s);
37661
37662        n -= w = p >> 3, d &= (1 << (p -= w << 3)) - 1, t.next_in = n, t.next_out = o, t.avail_in = n < i ? i - n + 5 : 5 - (n - i), t.avail_out = o < s ? s - o + 257 : 257 - (o - s), r.hold = d, r.bits = p;
37663      };
37664    }, function (t, e, r) {
37665
37666      var n = r(72),
37667          i = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0],
37668          o = [16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78],
37669          a = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0],
37670          s = [16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64];
37671
37672      t.exports = function (t, e, r, u, f, c, l, h) {
37673        var d,
37674            p,
37675            g,
37676            v,
37677            y,
37678            m,
37679            b,
37680            _,
37681            w,
37682            x = h.bits,
37683            E = 0,
37684            S = 0,
37685            k = 0,
37686            A = 0,
37687            C = 0,
37688            T = 0,
37689            R = 0,
37690            O = 0,
37691            I = 0,
37692            L = 0,
37693            B = null,
37694            P = 0,
37695            F = new n.Buf16(16),
37696            N = new n.Buf16(16),
37697            M = null,
37698            j = 0;
37699
37700        for (E = 0; E <= 15; E++) F[E] = 0;
37701
37702        for (S = 0; S < u; S++) F[e[r + S]]++;
37703
37704        for (C = x, A = 15; A >= 1 && 0 === F[A]; A--);
37705
37706        if (C > A && (C = A), 0 === A) return f[c++] = 20971520, f[c++] = 20971520, h.bits = 1, 0;
37707
37708        for (k = 1; k < A && 0 === F[k]; k++);
37709
37710        for (C < k && (C = k), O = 1, E = 1; E <= 15; E++) if (O <<= 1, (O -= F[E]) < 0) return -1;
37711
37712        if (O > 0 && (0 === t || 1 !== A)) return -1;
37713
37714        for (N[1] = 0, E = 1; E < 15;
37714 E++) N[E + 1] = N[E] + F[E];
37715
37716        for (S = 0; S < u; S++) 0 !== e[r + S] && (l[N[e[r + S]]++] = S);
37717
37718        if (0 === t ? (B = M = l, m = 19) : 1 === t ? (B = i, P -= 257, M = o, j -= 257, m = 256) : (B = a, M = s, m = -1), L = 0, S = 0, E = k, y = c, T = C, R = 0, g = -1, v = (I = 1 << C) - 1, 1 === t && I > 852 || 2 === t && I > 592) return 1;
37719
37720        for (;;) {
37721          b = E - R, l[S] < m ? (_ = 0, w = l[S]) : l[S] > m ? (_ = M[j + l[S]], w = B[P + l[S]]) : (_ = 96, w = 0), d = 1 << E - R, k = p = 1 << T;
37722
37723          do {
37724            f[y + (L >> R) + (p -= d)] = b << 24 | _ << 16 | w | 0;
37725          } while (0 !== p);
37726
37727          for (d = 1 << E - 1; L & d;) d >>= 1;
37728
37729          if (0 !== d ? (L &= d - 1, L += d) : L = 0, S++, 0 == --F[E]) {
37730            if (E === A) break;
37731            E = e[r + l[S]];
37732          }
37733
37734          if (E > C && (L & v) !== g) {
37735            for (0 === R && (R = C), y += k, O = 1 << (T = E - R); T + R < A && !((O -= F[T + R]) <= 0);) T++, O <<= 1;
37736
37737            if (I += 1 << T, 1 === t && I > 852 || 2 === t && I > 592) return 1;
37738            f[g = L & v] = C << 24 | T << 16 | y - c | 0;
37739          }
37740        }
37741
37742        return 0 !== L && (f[y + L] = E - R << 24 | 64 << 16 | 0), h.bits = C, 0;
37743      };
37744    }, function (t, e, r) {
37745
37746      t.exports = {
37747        Z_NO_FLUSH: 0,
37748        Z_PARTIAL_FLUSH: 1,
37749        Z_SYNC_FLUSH: 2,
37750        Z_FULL_FLUSH: 3,
37751        Z_FINISH: 4,
37752        Z_BLOCK: 5,
37753        Z_TREES: 6,
37754        Z_OK: 0,
37755        Z_STREAM_END: 1,
37756        Z_NEED_DICT: 2,
37757        Z_ERRNO: -1,
37758        Z_STREAM_ERROR: -2,
37759        Z_DATA_ERROR: -3,
37760        Z_BUF_ERROR: -5,
37761        Z_NO_COMPRESSION: 0,
37762        Z_BEST_SPEED: 1,
37763        Z_BEST_COMPRESSION: 9,
37764        Z_DEFAULT_COMPRESSION: -1,
37765        Z_FILTERED: 1,
37766        Z_HUFFMAN_ONLY: 2,
37767        Z_RLE: 3,
37768        Z_FIXED: 4,
37769        Z_DEFAULT_STRATEGY: 0,
37770        Z_BINARY: 0,
37771        Z_TEXT: 1,
37772        Z_UNKNOWN: 2,
37773        Z_DEFLATED: 8
37774      };
37775    }, function (t, e, r) {
37776      var n = r(19).Buffer,
37777          i = [0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035, 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049, 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639, 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317, 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443, 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665, 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303, 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565, 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059, 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297, 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223, 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405, 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995, 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649, 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015, 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989, 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523, 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377, 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879, 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637, 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859, 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161, 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815, 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221, 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371, 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881, 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567, 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701, 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035, 2932959818, 3654703836, 1088359270, 936918e3, 2847714899, 3736837829, 1202900863, 817233897, 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431, 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117];
37778
37779      function o(t) {
37780        if (n.isBuffer(t)) return t;
37781        var e = "function" == typeof n.alloc && "function" == typeof n.from;
37782        if ("number" == typeof t) return e ? n.alloc(t) : new n(t);
37783        if ("string" == typeof t) return e ? n.from(t) : new n(t);
37784        throw new Error("input must be buffer, number, or string, received " + typeof t);
37785      }
37786
37787      function a(t, e) {
37788        t = o(t), n.isBuffer(e) && (e = e.readUInt32BE(0));
37789
37790        for (var r = -1 ^ ~~e, a = 0; a < t.length; a++) r = i[255 & (r ^ t[a])] ^ r >>> 8;
37791
37792        return -1 ^ r;
37793      }
37794
37795      function s() {
37796        return t = a.apply(null, arguments), (e = o(4)).writeInt32BE(t, 0), e;
37797        var t, e;
37798      }
37799
37800      "undefined" != typeof Int32Array && (i = new Int32Array(i)), s.signed = function () {
37801        return a.apply(null, arguments);
37802      }, s.unsigned = function () {
37803        return a.apply(null, arguments) >>> 0;
37804      }, t.exports = s;
37805    }, function (t, e, r) {
37806      var n = r(226),
37807          i = r(229);
37808
37809      function o(t) {
37810        return (o = "function" == typeof i && "symbol" == typeof n ? function (t) {
37811          return typeof t;
37812        } : function (t) {
37813          return t && "function" == typeof i && t.constructor === i && t !== i.prototype ? "symbol" : typeof t;
37814        })(t);
37815      }
37816
37817      function a(e) {
37818        return "function" == typeof i && "symbol" === o(n) ? t.exports = a = function (t) {
37819          return o(t);
37820        } : t.exports = a = function (t) {
37821          return t && "function" == typeof i && t.constructor === i && t !== i.prototype ? "symbol" : o(t);
37822        }, a(e);
37823      }
37824
37825      t.exports = a;
37826    }, function (t, e, r) {
37827      t.exports = r(227);
37828    }, function (t, e, r) {
37829      t.exports = r(228);
37830    }, function (t, e, r) {
37831      r(136), r(46), r(41);
37832      var n = r(95);
37833      t.exports = n.f("iterator");
37834    }, function (t, e, r) {
37835      t.exports = r(230);
37836    }, function (t, e, r) {
37837      t.exports = r(231), r(249), r(250), r(251), r(252), r(253);
37838    }, function (t, e, r) {
37839      r(114), r(88), r(232), r(234), r(235), r(236), r(237), r(136), r(238), r(239), r(240), r(241), r(242), r(243), r(244), r(245), r(246), r(247), r(248);
37840      var n = r(3);
37841      t.exports = n.Symbol;
37842    }, function (t, e, r) {
37843
37844      var n = r(0),
37845          i = r(13),
37846          o = r(4),
37847          a = r(17),
37848          s = r(110),
37849          u = r(12),
37850          f = r(24),
37851          c = r(53),
37852          l = r(14),
37853          h = r(2),
37854          d = r(22),
37855          p = r(28),
37856          g = r(62),
37857          v = r(43),
37858          y = r(44),
37859          m = r(51),
37860          b = r(137),
37861          _ = r(233),
37862          w = r(138),
37863          x = r(81),
37864          E = r(21),
37865          S = r(65),
37866          k = r(20),
37867          A = r(52),
37868          C = r(61),
37869          T = r(63),
37870          R = r(50),
37871          O = r(64),
37872          I = r(6),
37873          L = r(95),
37874          B = r(11),
37875          P = r(36),
37876          F = r(42),
37877          N = r(45).forEach,
37878          M = T("hidden"),
37879          j = I("toPrimitive"),
37880          z = F.set,
37881          U = F.getterFor("Symbol"),
37882          D = Object.prototype,
37883          q = i.Symbol,
37884          Z = i.JSON,
37885          H = Z && Z.stringify,
37886          V = x.f,
37887          G = E.f,
37888          Y = _.f,
37889          W = S.f,
37890          K = C("symbols"),
37891          Q = C("op-symbols"),
37892          X = C("string-to-symbol-registry"),
37893          $ = C("symbol-to-string-registry"),
37894          J = C("wks"),
37895          tt = i.QObject,
37896          et = !tt || !tt.prototype || !tt.prototype.findChild,
37897          rt = a && u(function () {
37898        return 7 != y(G({}, "a", {
37899          get: function () {
37900            return G(this, "a", {
37901              value: 7
37902            }).a;
37903          }
37904        })).a;
37905      }) ? function (t, e, r) {
37906        var n = V(D, e);
37907        n && delete D[e], G(t, e, r), n && t !== D && G(D, e, n);
37908      } : G,
37909          nt = function (t, e) {
37910        var r = K[t] = y(q.prototype);
37911        return z(r, {
37912          type: "Symbol",
37913          tag: t,
37914          description: e
37915        }), a || (r.description = e), r;
37916      },
37917          it = s && "symbol" == typeof q.iterator ? function (t) {
37918        return "symbol" == typeof t;
37919      } : function (t) {
37920        return Object(t) instanceof q;
37921      },
37922          ot = function (t, e, r) {
37923        t === D && ot(Q, e, r), h(t);
37924        var n = g(e, !0);
37925        return h(r), f(K, n) ? (r.enumerable ? (f(t, M) && t[M][n] && (t[M][n] = !1), r = y(r, {
37926          enumerable: v(0, !1)
37927        })) : (f(t, M) || G(t, M, v(1, {})), t[M][n] = !0), rt(t, n, r)) : G(t, n, r);
37928      },
37929          at = function (t, e) {
37930        h(t);
37931        var r = p(e),
37932            n = m(r).concat(ct(r));
37933        return N(n, function (e) {
37934          a && !st.call(r, e) || ot(t, e, r[e]);
37935        }), t;
37936      },
37937          st = function (t) {
37938        var e = g(t, !0),
37939            r = W.call(this, e);
37940        return !(this === D && f(K, e) && !f(Q, e)) && (!(r || !f(this, e) || !f(K, e) || f(this, M) && this[M][e]) || r);
37941      },
37942          ut = function (t, e) {
37943        var r = p(t),
37944            n = g(e, !0);
37945
37946        if (r !== D || !f(K, n) || f(Q, n)) {
37947          var i = V(r, n);
37948          return !i || !f(K, n) || f(r, M) && r[M][n] || (i.enumerable = !0), i;
37949        }
37950      },
37951          ft = function (t) {
37952        var e = Y(p(t)),
37953            r = [];
37954        return N(e, function (t) {
37955          f(K, t) || f(R, t) || r.push(t);
37956        }), r;
37957      },
37958          ct = function (t) {
37959        var e = t === D,
37960            r = Y(e ? Q : p(t)),
37961            n = [];
37962        return N(r, function (t) {
37963          !f(K, t) || e && !f(D, t) || n.push(K[t]);
37964        }), n;
37965      };
37966
37967      s || (A((q = function () {
37968        if (this instanceof q) throw TypeError("Symbol is not a constructor");
37969
37970        var t = arguments.length && void 0 !== arguments[0] ? String(arguments[0]) : void 0,
37971            e = O(t),
37972            r = function (t) {
37973          this === D && r.call(Q, t), f(this, M) && f(this[M], e) && (this[M][e] = !1), rt(this, e, v(1, t));
37974        };
37975
37976        return a && et && rt(D, e, {
37977          configurable: !0,
37978          set: r
37979        }), nt(e, t);
37980      }).prototype, "toString", function () {
37981        return U(this).tag;
37982      }), S.f = st, E.f = ot, x.f = ut, b.f = _.f = ft, w.f = ct, a && (G(q.prototype, "description", {
37983        configurable: !0,
37984        get: function () {
37985          return U(this).description;
37986        }
37987      }), o || A(D, "propertyIsEnumerable", st, {
37988        unsafe: !0
37989      })), L.f = function (t) {
37990        return nt(I(t), t);
37991      }), n({
37992        global: !0,
37993        wrap: !0,
37994        forced: !s,
37995        sham: !s
37996      }, {
37997        Symbol: q
37998      }), N(m(J), function (t) {
37999        B(t);
38000      }), n({
38001        target: "Symbol",
38002        stat: !0,
38003        forced: !s
38004      }, {
38005        for: function (t) {
38006          var e = String(t);
38007          if (f(X, e)) return X[e];
38008          var r = q(e);
38009          return X[e] = r, $[r] = e, r;
38010        },
38011        keyFor: function (t) {
38012          if (!it(t)) throw TypeError(t + " is not a symbol");
38013          if (f($, t)) return $[t];
38014        },
38015        useSetter: function () {
38016          et = !0;
38017        },
38018        useSimple: function () {
38019          et = !1;
38020        }
38021      }), n({
38022        target: "Object",
38023        stat: !0,
38024        forced: !s,
38025        sham: !a
38026      }, {
38027        create: function (t, e) {
38028          return void 0 === e ? y(t) : at(y(t), e);
38029        },
38030        defineProperty: ot,
38031        defineProperties: at,
38032        getOwnPropertyDescriptor: ut
38033      }), n({
38034        target: "Object",
38035        stat: !0,
38036        forced: !s
38037      }, {
38038        getOwnPropertyNames: ft,
38039        getOwnPropertySymbols: ct
38040      }), n({
38041        target: "Object",
38042        stat: !0,
38043        forced: u(function () {
38044          w.f(1);
38045        })
38046      }, {
38047        getOwnPropertySymbols: function (t) {
38048          return w.f(d(t));
38049        }
38050      }), Z && n({
38051        target: "JSON",
38052        stat: !0,
38053        forced: !s || u(function () {
38054          var t = q();
38055          return "[null]" != H([t]) || "{}" != H({
38056            a: t
38057          }) || "{}" != H(Object(t));
38058        })
38059      }, {
38060        stringify: function (t) {
38061          for (var e, r, n = [t], i = 1; arguments.length > i;) n.push(arguments[i++]);
38062
38063          if (r = e = n[1], (l(e) || void 0 !== t) && !it(t)) return c(e) || (e = function (t, e) {
38064            if ("function" == typeof r && (e = r.call(this, t, e)), !it(e)) return e;
38065          }), n[1] = e, H.apply(Z, n);
38066        }
38067      }), q.prototype[j] || k(q.prototype, j, q.prototype.valueOf), P(q, "Symbol"), R[M] = !0;
38068    }, function (t, e, r) {
38069      var n = r(28),
38070          i = r(137).f,
38071          o = {}.toString,
38072          a = "object" == typeof window && window && Object.getOwnPropertyNames ? Object.getOwnPropertyNames(window) : [];
38073
38074      t.exports.f = function (t) {
38075        return a && "[object Window]" == o.call(t) ? function (t) {
38076          try {
38077            return i(t);
38078          } catch (t) {
38079            return a.slice();
38080          }
38081        }(t) : i(n(t));
38082      };
38083    }, function (t, e, r) {
38084      r(11)("asyncIterator");
38085    }, function (t, e) {}, function (t, e, r) {
38086      r(11)("hasInstance");
38087    }, function (t, e, r) {
38088      r(11)("isConcatSpreadable");
38089    }, function (t, e, r) {
38090      r(11)("match");
38091    }, function (t, e, r) {
38092      r(11)("matchAll");
38093    }, function (t, e, r) {
38094      r(11)("replace");
38095    }, function (t, e, r) {
38096      r(11)("search");
38097    }, function (t, e, r) {
38098      r(11)("species");
38099    }, function (t, e, r) {
38100      r(11)("split");
38101    }, function (t, e, r) {
38102      r(11)("toPrimitive");
38103    }, function (t, e, r) {
38104      r(11)("toStringTag");
38105    }, function (t, e, r) {
38106      r(11)("unscopables");
38107    }, function (t, e, r) {
38108      r(36)(Math, "Math", !0);
38109    }, function (t, e, r) {
38110      var n = r(13);
38111      r(36)(n.JSON, "JSON", !0);
38112    }, function (t, e, r) {
38113      r(11)("asyncDispose");
38114    }, function (t, e, r) {
38115      r(11)("dispose");
38116    }, function (t, e, r) {
38117      r(11)("observable");
38118    }, function (t, e, r) {
38119      r(11)("patternMatch");
38120    }, function (t, e, r) {
38121      r(11)("replaceAll");
38122    }, function (t, e) {
38123      t.exports = function (t) {
38124        if (void 0 === t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
38125        return t;
38126      };
38127    }, function (t, e, r) {
38128      t.exports = r(256);
38129    }, function (t, e, r) {
38130      t.exports = r(257);
38131    }, function (t, e, r) {
38132      r(258);
38133      var n = r(3);
38134      t.exports = n.Object.getPrototypeOf;
38135    }, function (t, e, r) {
38136      var n = r(0),
38137          i = r(12),
38138          o = r(22),
38139          a = r(66),
38140          s = r(109);
38141      n({
38142        target: "Object",
38143        stat: !0,
38144        forced: i(function () {
38145          a(1);
38146        }),
38147        sham: !s
38148      }, {
38149        getPrototypeOf: function (t) {
38150          return a(o(t));
38151        }
38152      });
38153    }, function (t, e, r) {
38154      t.exports = r(260);
38155    }, function (t, e, r) {
38156      r(261);
38157      var n = r(3);
38158      t.exports = n.Object.setPrototypeOf;
38159    }, function (t, e, r) {
38160      r(0)({
38161        target: "Object",
38162        stat: !0
38163      }, {
38164        setPrototypeOf: r(86)
38165      });
38166    }, function (t, e, r) {
38167      t.exports = r(263);
38168    }, function (t, e, r) {
38169      r(264);
38170      var n = r(3).Object;
38171
38172      t.exports = function (t, e) {
38173        return n.create(t, e);
38174      };
38175    }, function (t, e, r) {
38176      r(0)({
38177        target: "Object",
38178        stat: !0,
38179        sham: !r(17)
38180      }, {
38181        create: r(44)
38182      });
38183    }, function (t, e, r) {
38184      var n = r(140),
38185          i = r(266),
38186          o = r(27),
38187          a = r(96),
38188          s = r(295),
38189          u = r(300);
38190
38191      function f(e) {
38192        var r = "function" == typeof i ? new i() : void 0;
38193        return t.exports = f = function (t) {
38194          if (null === t || !s(t)) return t;
38195          if ("function" != typeof t) throw new TypeError("Super expression must either be null or a function");
38196
38197          if (void 0 !== r) {
38198            if (r.has(t)) return r.get(t);
38199            r.set(t, e);
38200          }
38201
38202          function e() {
38203            return u(t, arguments, o(this).constructor);
38204          }
38205
38206          return e.prototype = n(t.prototype, {
38207            constructor: {
38208              value: e,
38209              enumerable: !1,
38210              writable: !0,
38211              configurable: !0
38212            }
38213          }), a(e, t);
38214        }, f(e);
38215      }
38216
38217      t.exports = f;
38218    }, function (t, e, r) {
38219      t.exports = r(267);
38220    }, function (t, e, r) {
38221      t.exports = r(268), r(273), r(275), r(277), r(279), r(280), r(281), r(282), r(283), r(284), r(286), r(287), r(288), r(289), r(290), r(291), r(292), r(293), r(294);
38222    }, function (t, e, r) {
38223      r(269), r(88), r(46), r(41);
38224      var n = r(3);
38225      t.exports = n.Map;
38226    }, function (t, e, r) {
38227
38228      var n = r(270),
38229          i = r(272);
38230      t.exports = n("Map", function (t) {
38231        return function () {
38232          return t(this, arguments.length ? arguments[0] : void 0);
38233        };
38234      }, i, !0);
38235    }, function (t, e, r) {
38236
38237      var n = r(0),
38238          i = r(13),
38239          o = r(141),
38240          a = r(12),
38241          s = r(20),
38242          u = r(8),
38243          f = r(89),
38244          c = r(14),
38245          l = r(36),
38246          h = r(21).f,
38247          d = r(45).forEach,
38248          p = r(17),
38249          g = r(42),
38250          v = g.set,
38251          y = g.getterFor;
38252
38253      t.exports = function (t, e, r, g, m) {
38254        var b,
38255            _ = i[t],
38256            w = _ && _.prototype,
38257            x = g ? "set" : "add",
38258            E = {};
38259
38260        if (p && "function" == typeof _ && (m || w.forEach && !a(function () {
38261          new _().entries().next();
38262        }))) {
38263          b = e(function (e, r) {
38264            v(f(e, b, t), {
38265              type: t,
38266              collection: new _()
38267            }), null != r && u(r, e[x], e, g);
38268          });
38269          var S = y(t);
38270          d(["add", "clear", "delete", "forEach", "get", "has", "set", "keys", "values", "entries"], function (t) {
38271            var e = "add" == t || "set" == t;
38272            t in w && (!m || "clear" != t) && s(b.prototype, t, function (r, n) {
38273              var i = S(this).collection;
38274              if (!e && m && !c(r)) return "get" == t && void 0;
38275              var o = i[t](0 === r ? 0 : r, n);
38276              return e ? this : o;
38277            });
38278          }), m || h(b.prototype, "size", {
38279            get: function () {
38280              return S(this).collection.size;
38281            }
38282          });
38283        } else b = r.getConstructor(e, t, g, x), o.REQUIRED = !0;
38284
38285        return l(b, t, !1, !0), E[t] = b, n({
38286          global: !0,
38287          forced: !0
38288        }, E), m || r.setStrong(b, t, g), b;
38289      };
38290    }, function (t, e, r) {
38291      var n = r(12);
38292      t.exports = !n(function () {
38293        return Object.isExtensible(Object.preventExtensions({}));
38294      });
38295    }, function (t, e, r) {
38296
38297      var n = r(21).f,
38298          i = r(44),
38299          o = r(117),
38300          a = r(15),
38301          s = r(89),
38302          u = r(8),
38303          f = r(80),
38304          c = r(118),
38305          l = r(17),
38306          h = r(141).fastKey,
38307          d = r(42),
38308          p = d.set,
38309          g = d.getterFor;
38310      t.exports = {
38311        getConstructor: function (t, e, r, f) {
38312          var c = t(function (t, n) {
38313            s(t, c, e), p(t, {
38314              type: e,
38315              index: i(null),
38316              first: void 0,
38317              last: void 0,
38318              size: 0
38319            }), l || (t.size = 0), null != n && u(n, t[f], t, r);
38320          }),
38321              d = g(e),
38322              v = function (t, e, r) {
38323            var n,
38324                i,
38325                o = d(t),
38326                a = y(t, e);
38327            return a ? a.value = r : (o.last = a = {
38328              index: i = h(e, !0),
38329              key: e,
38330              value: r,
38331              previous: n = o.last,
38332              next: void 0,
38333              removed: !1
38334            }, o.first || (o.first = a), n && (n.next = a), l ? o.size++ : t.size++, "F" !== i && (o.index[i] = a)), t;
38335          },
38336              y = function (t, e) {
38337            var r,
38338                n = d(t),
38339                i = h(e);
38340            if ("F" !== i) return n.index[i];
38341
38342            for (r = n.first; r; r = r.next) if (r.key == e) return r;
38343          };
38344
38345          return o(c.prototype, {
38346            clear: function () {
38347              for (var t = d(this), e = t.index, r = t.first; r;) r.removed = !0, r.previous && (r.previous = r.previous.next = void 0), delete e[r.index], r = r.next;
38348
38349              t.first = t.last = void 0, l ? t.size = 0 : this.size = 0;
38350            },
38351            delete: function (t) {
38352              var e = d(this),
38353                  r = y(this, t);
38354
38355              if (r) {
38356                var n = r.next,
38357                    i = r.previous;
38358                delete e.index[r.index], r.removed = !0, i && (i.next = n), n && (n.previous = i), e.first == r && (e.first = n), e.last == r && (e.last = i), l ? e.size-- : this.size--;
38359              }
38360
38361              return !!r;
38362            },
38363            forEach: function (t) {
38364              for (var e, r = d(this), n = a(t, arguments.length > 1 ? arguments[1] : void 0, 3); e = e ? e.next : r.first;) for (n(e.value, e.key, this); e && e.removed;) e = e.previous;
38365            },
38366            has: function (t) {
38367              return !!y(this, t);
38368            }
38369          }), o(c.prototype, r ? {
38370            get: function (t) {
38371              var e = y(this, t);
38372              return e && e.value;
38373            },
38374            set: function (t, e) {
38375              return v(this, 0 === t ? 0 : t, e);
38376            }
38377          } : {
38378            add: function (t) {
38379              return v(this, t = 0 === t ? 0 : t, t);
38380            }
38381          }), l && n(c.prototype, "size", {
38382            get: function () {
38383              return d(this).size;
38384            }
38385          }), c;
38386        },
38387        setStrong: function (t, e, r) {
38388          var n = e + " Iterator",
38389              i = g(e),
38390              o = g(n);
38391          f(t, e, function (t, e) {
38392            p(this, {
38393              type: n,
38394              target: t,
38395              state: i(t),
38396              kind: e,
38397              last: void 0
38398            });
38399          }, function () {
38400            for (var t = o(this), e = t.kind, r = t.last; r && r.removed;) r = r.previous;
38401
38402            return t.target && (t.last = r = r ? r.next : t.state.first) ? "keys" == e ? {
38403              value: r.key,
38404              done: !1
38405            } : "values" == e ? {
38406              value: r.value,
38407              done: !1
38408            } : {
38409              value: [r.key, r.value],
38410              done: !1
38411            } : (t.target = void 0, {
38412              value: void 0,
38413              done: !0
38414            });
38415          }, r ? "entries" : "values", !r, !0), c(e);
38416        }
38417      };
38418    }, function (t, e, r) {
38419      r(0)({
38420        target: "Map",
38421        stat: !0
38422      }, {
38423        from: r(274)
38424      });
38425    }, function (t, e, r) {
38426
38427      var n = r(5),
38428          i = r(15),
38429          o = r(8);
38430
38431      t.exports = function (t) {
38432        var e,
38433            r,
38434            a,
38435            s,
38436            u = arguments.length,
38437            f = u > 1 ? arguments[1] : void 0;
38438        return n(this), (e = void 0 !== f) && n(f), null == t ? new this() : (r = [], e ? (a = 0, s = i(f, u > 2 ? arguments[2] : void 0, 2), o(t, function (t) {
38439          r.push(s(t, a++));
38440        })) : o(t, r.push, r), new this(r));
38441      };
38442    }, function (t, e, r) {
38443      r(0)({
38444        target: "Map",
38445        stat: !0
38446      }, {
38447        of: r(276)
38448      });
38449    }, function (t, e, r) {
38450
38451      t.exports = function () {
38452        for (var t = arguments.length, e = new Array(t); t--;) e[t] = arguments[t];
38453
38454        return new this(e);
38455      };
38456    }, function (t, e, r) {
38457
38458      var n = r(0),
38459          i = r(4),
38460          o = r(278);
38461      n({
38462        target: "Map",
38463        proto: !0,
38464        real: !0,
38465        forced: i
38466      }, {
38467        deleteAll: function () {
38468          return o.apply(this, arguments);
38469        }
38470      });
38471    }, function (t, e, r) {
38472
38473      var n = r(2),
38474          i = r(5);
38475
38476      t.exports = function () {
38477        for (var t, e = n(this), r = i(e.delete), o = !0, a = 0, s = arguments.length; a < s; a++) t = r.call(e, arguments[a]), o = o && t;
38478
38479        return !!o;
38480      };
38481    }, function (t, e, r) {
38482
38483      var n = r(0),
38484          i = r(4),
38485          o = r(2),
38486          a = r(15),
38487          s = r(25),
38488          u = r(8);
38489      n({
38490        target: "Map",
38491        proto: !0,
38492        real: !0,
38493        forced: i
38494      }, {
38495        every: function (t) {
38496          var e = o(this),
38497              r = s(e),
38498              n = a(t, arguments.length > 1 ? arguments[1] : void 0, 3);
38499          return !u(r, function (t, r) {
38500            if (!n(r, t, e)) return u.stop();
38501          }, void 0, !0, !0).stopped;
38502        }
38503      });
38504    }, function (t, e, r) {
38505
38506      var n = r(0),
38507          i = r(4),
38508          o = r(26),
38509          a = r(2),
38510          s = r(5),
38511          u = r(15),
38512          f = r(55),
38513          c = r(25),
38514          l = r(8);
38515      n({
38516        target: "Map",
38517        proto: !0,
38518        real: !0,
38519        forced: i
38520      }, {
38521        filter: function (t) {
38522          var e = a(this),
38523              r = c(e),
38524              n = u(t, arguments.length > 1 ? arguments[1] : void 0, 3),
38525              i = new (f(e, o("Map")))(),
38526              h = s(i.set);
38527          return l(r, function (t, r) {
38528            n(r, t, e) && h.call(i, t, r);
38529          }, void 0, !0, !0), i;
38530        }
38531      });
38532    }, function (t, e, r) {
38533
38534      var n = r(0),
38535          i = r(4),
38536          o = r(2),
38537          a = r(15),
38538          s = r(25),
38539          u = r(8);
38540      n({
38541        target: "Map",
38542        proto: !0,
38543        real: !0,
38544        forced: i
38545      }, {
38546        find: function (t) {
38547          var e = o(this),
38548              r = s(e),
38549              n = a(t, arguments.length > 1 ? arguments[1] : void 0, 3);
38550          return u(r, function (t, r) {
38551            if (n(r, t, e)) return u.stop(r);
38552          }, void 0, !0, !0).result;
38553        }
38554      });
38555    }, function (t, e, r) {
38556
38557      var n = r(0),
38558          i = r(4),
38559          o = r(2),
38560          a = r(15),
38561          s = r(25),
38562          u = r(8);
38563      n({
38564        target: "Map",
38565        proto: !0,
38566        real: !0,
38567        forced: i
38568      }, {
38569        findKey: function (t) {
38570          var e = o(this),
38571              r = s(e),
38572              n = a(t, arguments.length > 1 ? arguments[1] : void 0, 3);
38573          return u(r, function (t, r) {
38574            if (n(r, t, e)) return u.stop(t);
38575          }, void 0, !0, !0).result;
38576        }
38577      });
38578    }, function (t, e, r) {
38579
38580      var n = r(0),
38581          i = r(8),
38582          o = r(5);
38583      n({
38584        target: "Map",
38585        stat: !0
38586      }, {
38587        groupBy: function (t, e) {
38588          var r = new this();
38589          o(e);
38590          var n = o(r.has),
38591              a = o(r.get),
38592              s = o(r.set);
38593          return i(t, function (t) {
38594            var i = e(t);
38595            n.call(r, i) ? a.call(r, i).push(t) : s.call(r, i, [t]);
38596          }), r;
38597        }
38598      });
38599    }, function (t, e, r) {
38600
38601      var n = r(0),
38602          i = r(4),
38603          o = r(2),
38604          a = r(25),
38605          s = r(285),
38606          u = r(8);
38607      n({
38608        target: "Map",
38609        proto: !0,
38610        real: !0,
38611        forced: i
38612      }, {
38613        includes: function (t) {
38614          return u(a(o(this)), function (e, r) {
38615            if (s(r, t)) return u.stop();
38616          }, void 0, !0, !0).stopped;
38617        }
38618      });
38619    }, function (t, e) {
38620      t.exports = function (t, e) {
38621        return t === e || t != t && e != e;
38622      };
38623    }, function (t, e, r) {
38624
38625      var n = r(0),
38626          i = r(8),
38627          o = r(5);
38628      n({
38629        target: "Map",
38630        stat: !0
38631      }, {
38632        keyBy: function (t, e) {
38633          var r = new this();
38634          o(e);
38635          var n = o(r.set);
38636          return i(t, function (t) {
38637            n.call(r, e(t), t);
38638          }), r;
38639        }
38640      });
38641    }, function (t, e, r) {
38642
38643      var n = r(0),
38644          i = r(4),
38645          o = r(2),
38646          a = r(25),
38647          s = r(8);
38648      n({
38649        target: "Map",
38650        proto: !0,
38651        real: !0,
38652        forced: i
38653      }, {
38654        keyOf: function (t) {
38655          return s(a(o(this)), function (e, r) {
38656            if (r === t) return s.stop(e);
38657          }, void 0, !0, !0).result;
38658        }
38659      });
38660    }, function (t, e, r) {
38661
38662      var n = r(0),
38663          i = r(4),
38664          o = r(26),
38665          a = r(2),
38666          s = r(5),
38667          u = r(15),
38668          f = r(55),
38669          c = r(25),
38670          l = r(8);
38671      n({
38672        target: "Map",
38673        proto: !0,
38674        real: !0,
38675        forced: i
38676      }, {
38677        mapKeys: function (t) {
38678          var e = a(this),
38679              r = c(e),
38680              n = u(t, arguments.length > 1 ? arguments[1] : void 0, 3),
38681              i = new (f(e, o("Map")))(),
38682              h = s(i.set);
38683          return l(r, function (t, r) {
38684            h.call(i, n(r, t, e), r);
38685          }, void 0, !0, !0), i;
38686        }
38687      });
38688    }, function (t, e, r) {
38689
38690      var n = r(0),
38691          i = r(4),
38692          o = r(26),
38693          a = r(2),
38694          s = r(5),
38695          u = r(15),
38696          f = r(55),
38697          c = r(25),
38698          l = r(8);
38699      n({
38700        target: "Map",
38701        proto: !0,
38702        real: !0,
38703        forced: i
38704      }, {
38705        mapValues: function (t) {
38706          var e = a(this),
38707              r = c(e),
38708              n = u(t, arguments.length > 1 ? arguments[1] : void 0, 3),
38709              i = new (f(e, o("Map")))(),
38710              h = s(i.set);
38711          return l(r, function (t, r) {
38712            h.call(i, t, n(r, t, e));
38713          }, void 0, !0, !0), i;
38714        }
38715      });
38716    }, function (t, e, r) {
38717
38718      var n = r(0),
38719          i = r(4),
38720          o = r(2),
38721          a = r(5),
38722          s = r(8);
38723      n({
38724        target: "Map",
38725        proto: !0,
38726        real: !0,
38727        forced: i
38728      }, {
38729        merge: function (t) {
38730          for (var e = o(this), r = a(e.set), n = 0; n < arguments.length;) s(arguments[n++], r, e, !0);
38731
38732          return e;
38733        }
38734      });
38735    }, function (t, e, r) {
38736
38737      var n = r(0),
38738          i = r(4),
38739          o = r(2),
38740          a = r(5),
38741          s = r(25),
38742          u = r(8);
38743      n({
38744        target: "Map",
38745        proto: !0,
38746        real: !0,
38747        forced: i
38748      }, {
38749        reduce: function (t) {
38750          var e,
38751              r,
38752              n = o(this),
38753              i = s(n);
38754          if (a(t), arguments.length > 1) e = arguments[1];else {
38755            if ((r = i.next()).done) throw TypeError("Reduce of empty map with no initial value");
38756            e = r.value[1];
38757          }
38758          return u(i, function (r, i) {
38759            e = t(e, i, r, n);
38760          }, void 0, !0, !0), e;
38761        }
38762      });
38763    }, function (t, e, r) {
38764
38765      var n = r(0),
38766          i = r(4),
38767          o = r(2),
38768          a = r(15),
38769          s = r(25),
38770          u = r(8);
38771      n({
38772        target: "Map",
38773        proto: !0,
38774        real: !0,
38775        forced: i
38776      }, {
38777        some: function (t) {
38778          var e = o(this),
38779              r = s(e),
38780              n = a(t, arguments.length > 1 ? arguments[1] : void 0, 3);
38781          return u(r, function (t, r) {
38782            if (n(r, t, e)) return u.stop();
38783          }, void 0, !0, !0).stopped;
38784        }
38785      });
38786    }, function (t, e, r) {
38787
38788      var n = r(0),
38789          i = r(4),
38790          o = r(2),
38791          a = r(5);
38792      n({
38793        target: "Map",
38794        proto: !0,
38795        real: !0,
38796        forced: i
38797      }, {
38798        update: function (t, e) {
38799          var r = o(this),
38800              n = arguments.length;
38801          a(e);
38802          var i = r.has(t);
38803          if (!i && n < 3) throw TypeError("Updating absent value");
38804          var s = i ? r.get(t) : a(n > 2 ? arguments[2] : void 0)(t, r);
38805          return r.set(t, e(s, t, r)), r;
38806        }
38807      });
38808    }, function (t, e, r) {
38809
38810      var n = r(0),
38811          i = r(4),
38812          o = r(2),
38813          a = r(5);
38814      n({
38815        target: "Map",
38816        proto: !0,
38817        real: !0,
38818        forced: i
38819      }, {
38820        updateOrInsert: function (t, e, r) {
38821          var n = o(this);
38822          a(e), a(r);
38823          var i = n.has(t) ? e(n.get(t)) : r();
38824          return n.set(t, i), i;
38825        }
38826      });
38827    }, function (t, e, r) {
38828      var n = r(296);
38829
38830      t.exports = function (t) {
38831        var e;
38832        return -1 !== n(e = Function.toString.call(t)).call(e, "[native code]");
38833      };
38834    }, function (t, e, r) {
38835      t.exports = r(297);
38836    }, function (t, e, r) {
38837      t.exports = r(143);
38838    }, function (t, e, r) {
38839      r(299);
38840      var n = r(18);
38841      t.exports = n("Array").indexOf;
38842    }, function (t, e, r) {
38843
38844      var n = r(0),
38845          i = r(82).indexOf,
38846          o = r(54),
38847          a = [].indexOf,
38848          s = !!a && 1 / [1].indexOf(1, -0) < 0,
38849          u = o("indexOf");
38850      n({
38851        target: "Array",
38852        proto: !0,
38853        forced: s || u
38854      }, {
38855        indexOf: function (t) {
38856          return s ? a.apply(this, arguments) || 0 : i(this, t, arguments.length > 1 ? arguments[1] : void 0);
38857        }
38858      });
38859    }, function (t, e, r) {
38860      var n = r(301),
38861          i = r(305),
38862          o = r(96);
38863
38864      function a(e, r, s) {
38865        return !function () {
38866          if ("undefined" == typeof Reflect || !i) return !1;
38867          if (i.sham) return !1;
38868          if ("function" == typeof Proxy) return !0;
38869
38870          try {
38871            return Date.prototype.toString.call(i(Date, [], function () {})), !0;
38872          } catch (t) {
38873            
38873return !1;
38874          }
38875        }() ? t.exports = a = function (t, e, r) {
38876          var i = [null];
38877          i.push.apply(i, e);
38878          var a = new (n(Function).apply(t, i))();
38879          return r && o(a, r.prototype), a;
38880        } : t.exports = a = i, a.apply(null, arguments);
38881      }
38882
38883      t.exports = a;
38884    }, function (t, e, r) {
38885      t.exports = r(302);
38886    }, function (t, e, r) {
38887      t.exports = r(144);
38888    }, function (t, e, r) {
38889      r(304);
38890      var n = r(18);
38891      t.exports = n("Function").bind;
38892    }, function (t, e, r) {
38893      r(0)({
38894        target: "Function",
38895        proto: !0
38896      }, {
38897        bind: r(145)
38898      });
38899    }, function (t, e, r) {
38900      t.exports = r(306);
38901    }, function (t, e, r) {
38902      t.exports = r(307);
38903    }, function (t, e, r) {
38904      r(308);
38905      var n = r(3);
38906      t.exports = n.Reflect.construct;
38907    }, function (t, e, r) {
38908      var n = r(0),
38909          i = r(26),
38910          o = r(5),
38911          a = r(2),
38912          s = r(14),
38913          u = r(44),
38914          f = r(145),
38915          c = r(12),
38916          l = i("Reflect", "construct"),
38917          h = c(function () {
38918        function t() {}
38919
38920        return !(l(function () {}, [], t) instanceof t);
38921      }),
38922          d = !c(function () {
38923        l(function () {});
38924      }),
38925          p = h || d;
38926      n({
38927        target: "Reflect",
38928        stat: !0,
38929        forced: p,
38930        sham: p
38931      }, {
38932        construct: function (t, e) {
38933          o(t), a(e);
38934          var r = arguments.length < 3 ? t : o(arguments[2]);
38935          if (d && !h) return l(t, e, r);
38936
38937          if (t == r) {
38938            switch (e.length) {
38939              case 0:
38940                return new t();
38941
38942              case 1:
38943                return new t(e[0]);
38944
38945              case 2:
38946                return new t(e[0], e[1]);
38947
38948              case 3:
38949                return new t(e[0], e[1], e[2]);
38950
38951              case 4:
38952                return new t(e[0], e[1], e[2], e[3]);
38953            }
38954
38955            var n = [null];
38956            return n.push.apply(n, e), new (f.apply(t, n))();
38957          }
38958
38959          var i = r.prototype,
38960              c = u(s(i) ? i : Object.prototype),
38961              p = Function.apply.call(t, c, e);
38962          return s(p) ? p : c;
38963        }
38964      });
38965    }, function (t, e, r) {
38966
38967      (function (e) {
38968        var n = r(1),
38969            i = n(r(97)),
38970            o = n(r(7)),
38971            a = n(r(10)),
38972            s = r(9).CramMalformedError,
38973            u = r(73),
38974            f = r(315),
38975            c = r(316),
38976            l = r(317),
38977            h = 4;
38978
38979        var d = function () {
38980          function t(e) {
38981            var r = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0;
38982            (0, o.default)(this, t), this._buffer = e, this._position = r, this.length = e.length;
38983          }
38984
38985          return (0, a.default)(t, [{
38986            key: "get",
38987            value: function () {
38988              var t = this._buffer[this._position];
38989              return this._position += 1, t;
38990            }
38991          }, {
38992            key: "getByte",
38993            value: function () {
38994              return this.get();
38995            }
38996          }, {
38997            key: "getByteAt",
38998            value: function (t) {
38999              return this._buffer[t];
39000            }
39001          }, {
39002            key: "position",
39003            value: function () {
39004              return this._position;
39005            }
39006          }, {
39007            key: "put",
39008            value: function (t) {
39009              return this._buffer[this._position] = t, this._position += 1, t;
39010            }
39011          }, {
39012            key: "putAt",
39013            value: function (t, e) {
39014              return this._buffer[t] = e, e;
39015            }
39016          }, {
39017            key: "setPosition",
39018            value: function (t) {
39019              return this._position = t, t;
39020            }
39021          }, {
39022            key: "getInt",
39023            value: function () {
39024              var t = this._buffer.readInt32LE(this._position);
39025
39026              return this._position += 4, t;
39027            }
39028          }, {
39029            key: "remaining",
39030            value: function () {
39031              return this._buffer.length - this._position;
39032            }
39033          }]), t;
39034        }();
39035
39036        t.exports = {
39037          uncompress: function (t, r) {
39038            var n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : 0;
39039            if (0 === t.length) return (0, i.default)(r).call(r, 0), r;
39040            var o = new d(t, n),
39041                a = o.get();
39042            if (0 !== a && 1 !== a) throw new s("Invalid rANS order ".concat(a));
39043            if (o.getInt() !== o.remaining() - h) throw new s("Incorrect input length.");
39044            var p = o.getInt(),
39045                g = new d(r || e.allocUnsafe(p));
39046            if (g.length < p) throw new s("Output buffer too small to fit ".concat(p, " bytes."));
39047
39048            switch (a) {
39049              case 0:
39050                return function (t, e) {
39051                  for (var r = new u.AriDecoder(), n = new Array(256), i = 0; i < n.length; i += 1) n[i] = new u.Symbol();
39052
39053                  return f.readStatsO0(t, r, n), c.uncompress(t, r, n, e), e;
39054                }(o, g);
39055
39056              case 1:
39057                return function (t, e) {
39058                  for (var r = new Array(256), n = 0; n < r.length; n += 1) r[n] = new u.AriDecoder();
39059
39060                  for (var i = new Array(256), o = 0; o < i.length; o += 1) {
39061                    i[o] = new Array(256);
39062
39063                    for (var a = 0; a < i[o].length; a += 1) i[o][a] = new u.Symbol();
39064                  }
39065
39066                  return f.readStatsO1(t, r, i), l.uncompress(t, e, r, i), e;
39067                }(o, g);
39068
39069              default:
39070                throw new s("Invalid rANS order: ".concat(a));
39071            }
39072          }
39073        };
39074      }).call(this, r(19).Buffer);
39075    }, function (t, e, r) {
39076      t.exports = r(311);
39077    }, function (t, e, r) {
39078      var n = r(312),
39079          i = Array.prototype;
39080
39081      t.exports = function (t) {
39082        var e = t.fill;
39083        return t === i || t instanceof Array && e === i.fill ? n : e;
39084      };
39085    }, function (t, e, r) {
39086      r(313);
39087      var n = r(18);
39088      t.exports = n("Array").fill;
39089    }, function (t, e, r) {
39090      var n = r(0),
39091          i = r(314),
39092          o = r(78);
39093      n({
39094        target: "Array",
39095        proto: !0
39096      }, {
39097        fill: i
39098      }), o("fill");
39099    }, function (t, e, r) {
39100
39101      var n = r(22),
39102          i = r(84),
39103          o = r(29);
39104
39105      t.exports = function (t) {
39106        for (var e = n(this), r = o(e.length), a = arguments.length, s = i(a > 1 ? arguments[1] : void 0, r), u = a > 2 ? arguments[2] : void 0, f = void 0 === u ? r : i(u, r); f > s;) e[s++] = t;
39107
39108        return e;
39109      };
39110    }, function (t, e, r) {
39111
39112      var n = r(1)(r(97)),
39113          i = r(9).CramMalformedError,
39114          o = r(74),
39115          a = r(73);
39116
39117      function s(t) {
39118        if (!t) throw new i("assertion failed");
39119      }
39120
39121      t.exports = {
39122        readStatsO0: function (t, e, r) {
39123          var i = 0,
39124              u = 0,
39125              f = 255 & t.get();
39126
39127          do {
39128            var c;
39129            null == e.fc[f] && (e.fc[f] = new a.FC()), e.fc[f].F = 255 & t.get(), e.fc[f].F >= 128 && (e.fc[f].F &= -129, e.fc[f].F = (127 & e.fc[f].F) << 8 | 255 & t.get()), e.fc[f].C = u, a.symbolInit(r[f], e.fc[f].C, e.fc[f].F), e.R || (e.R = new Array(o.TOTFREQ)), (0, n.default)(c = e.R).call(c, f, u, u + e.fc[f].F), u += e.fc[f].F, 0 === i && f + 1 === (255 & t.getByteAt(t.position())) ? (f = 255 & t.get(), i = 255 & t.get()) : 0 !== i ? (i -= 1, f += 1) : f = 255 & t.get();
39130          } while (0 !== f);
39131
39132          s(u < o.TOTFREQ);
39133        },
39134        readStatsO1: function (t, e, r) {
39135          var i = 0,
39136              u = 255 & t.get();
39137
39138          do {
39139            var f = 0,
39140                c = 0,
39141                l = 255 & t.get();
39142            null == e[u] && (e[u] = new a.AriDecoder());
39143
39144            do {
39145              var h;
39146              null == e[u].fc[l] && (e[u].fc[l] = new a.FC()), e[u].fc[l].F = 255 & t.get(), e[u].fc[l].F >= 128 && (e[u].fc[l].F &= -129, e[u].fc[l].F = (127 & e[u].fc[l].F) << 8 | 255 & t.get()), e[u].fc[l].C = c, 0 === e[u].fc[l].F && (e[u].fc[l].F = o.TOTFREQ), null == r[u][l] && (r[u][l] = new a.RansDecSymbol()), a.symbolInit(r[u][l], e[u].fc[l].C, e[u].fc[l].F), null == e[u].R && (e[u].R = new Array(o.TOTFREQ)), (0, n.default)(h = e[u].R).call(h, l, c, c + e[u].fc[l].F), s((c += e[u].fc[l].F) <= o.TOTFREQ), 0 === f && l + 1 === (255 & t.getByteAt(t.position())) ? (l = 255 & t.get(), f = 255 & t.get()) : 0 !== f ? (f -= 1, l += 1) : l = 255 & t.get();
39147            } while (0 !== l);
39148
39149            0 === i && u + 1 === (255 & t.getByteAt(t.position())) ? (u = 255 & t.get(), i = 255 & t.get()) : 0 !== i ? (i -= 1, u += 1) : u = 255 & t.get();
39150          } while (0 !== u);
39151        }
39152      };
39153    }, function (t, e, r) {
39154
39155      var n = r(9).CramMalformedError,
39156          i = r(74),
39157          o = r(73);
39158      t.exports = {
39159        uncompress: function (t, e, r, a) {
39160          for (var s, u = t.getInt(), f = t.getInt(), c = t.getInt(), l = t.getInt(), h = a.remaining(), d = -4 & h, p = 0; p < d; p += 4) {
39161            var g = e.R[o.get(u, i.TF_SHIFT)],
39162                v = e.R[o.get(f, i.TF_SHIFT)],
39163                y = e.R[o.get(c, i.TF_SHIFT)],
39164                m = e.R[o.get(l, i.TF_SHIFT)];
39165            a.putAt(p, g), a.putAt(p + 1, v), a.putAt(p + 2, y), a.putAt(p + 3, m), u = o.advanceSymbolStep(u, r[255 & g], i.TF_SHIFT), f = o.advanceSymbolStep(f, r[255 & v], i.TF_SHIFT), c = o.advanceSymbolStep(c, r[255 & y], i.TF_SHIFT), l = o.advanceSymbolStep(l, r[255 & m], i.TF_SHIFT), u = o.renormalize(u, t), f = o.renormalize(f, t), c = o.renormalize(c, t), l = o.renormalize(l, t);
39166          }
39167
39168          switch (a.setPosition(d), 3 & h) {
39169            case 0:
39170              break;
39171
39172            case 1:
39173              s = e.R[o.get(u, i.TF_SHIFT)], o.advanceSymbol(u, t, r[255 & s], i.TF_SHIFT), a.put(s);
39174              break;
39175
39176            case 2:
39177              s = e.R[o.get(u, i.TF_SHIFT)], o.advanceSymbol(u, t, r[255 & s], i.TF_SHIFT), a.put(s), s = e.R[o.get(f, i.TF_SHIFT)], o.advanceSymbol(f, t, r[255 & s], i.TF_SHIFT), a.put(s);
39178              break;
39179
39180            case 3:
39181              s = e.R[o.get(u, i.TF_SHIFT)], o.advanceSymbol(u, t, r[255 & s], i.TF_SHIFT), a.put(s), s = e.R[o.get(f, i.TF_SHIFT)], o.advanceSymbol(f, t, r[255 & s], i.TF_SHIFT), a.put(s), s = e.R[o.get(c, i.TF_SHIFT)], o.advanceSymbol(c, t, r[255 & s], i.TF_SHIFT), a.put(s);
39182              break;
39183
39184            default:
39185              throw new n("invalid output size encountered during rANS decoding");
39186          }
39187
39188          a.setPosition(0);
39189        }
39190      };
39191    }, function (t, e, r) {
39192
39193      var n = r(74),
39194          i = r(73);
39195      t.exports = {
39196        uncompress: function (t, e, r, o) {
39197          for (var a = e.remaining(), s = t.getInt(), u = t.getInt(), f = t.getInt(), c = t.getInt(), l = a >> 2, h = 0, d = l, p = 2 * l, g = 3 * l, v = 0, y = 0, m = 0, b = 0; h < l; h += 1, d += 1, p += 1, g += 1) {
39198            var _ = 255 & r[v].R[i.get(s, n.TF_SHIFT)],
39199                w = 255 & r[y].R[i.get(u, n.TF_SHIFT)],
39200                x = 255 & r[m].R[i.get(f, n.TF_SHIFT)],
39201                E = 255 & r[b].R[i.get(c, n.TF_SHIFT)];
39202
39203            e.putAt(h, _), e.putAt(d, w), e.putAt(p, x), e.putAt(g, E), s = i.advanceSymbolStep(s, o[v][_], n.TF_SHIFT), u = i.advanceSymbolStep(u, o[y][w], n.TF_SHIFT), f = i.advanceSymbolStep(f, o[m][x], n.TF_SHIFT), c = i.advanceSymbolStep(c, o[b][E], n.TF_SHIFT), s = i.renormalize(s, t), u = i.renormalize(u, t), f = i.renormalize(f, t), c = i.renormalize(c, t), v = _, y = w, m = x, b = E;
39204          }
39205
39206          for (; g < a; g += 1) {
39207            var S = 255 & r[b].R[i.get(c, n.TF_SHIFT)];
39208            e.putAt(g, S), c = i.advanceSymbol(c, t, o[b][S], n.TF_SHIFT), b = S;
39209          }
39210        }
39211      };
39212    }, function (t, e, r) {
39213
39214      var n = r(1),
39215          i = n(r(98)),
39216          o = n(r(16)),
39217          a = n(r(75)),
39218          s = r(326).Parser,
39219          u = new s().itf8(),
39220          f = {
39221        parser: new s().string("magic", {
39222          length: 4
39223        }).uint8("majorVersion").uint8("minorVersion").string("fileId", {
39224          length: 20,
39225          stripNull: !0
39226        }),
39227        maxLength: 26
39228      },
39229          c = {
39230        parser: new s().uint8("compressionMethod", {
39231          formatter: function (t) {
39232            var e = ["raw", "gzip", "bzip2", "lzma", "rans"][t];
39233            if (!e) throw new Error("compression method number ".concat(t, " not implemented"));
39234            return e;
39235          }
39236        }).uint8("contentType", {
39237          formatter: function (t) {
39238            var e = ["FILE_HEADER", "COMPRESSION_HEADER", "MAPPED_SLICE_HEADER", "UNMAPPED_SLICE_HEADER", "EXTERNAL_DATA", "CORE_DATA"][t];
39239            if (!e) throw new Error("invalid block content type id ".concat(t));
39240            return e;
39241          }
39242        }).itf8("contentId").itf8("compressedSize").itf8("uncompressedSize"),
39243        maxLength: 17
39244      },
39245          l = {
39246        parser: new s().uint32("crc32"),
39247        maxLength: 4
39248      },
39249          h = new s().itf8("size").buffer("ents", {
39250        length: "size",
39251        formatter: function (t) {
39252          function e(e, r) {
39253            for (var n = t.toString("utf8", e, r), i = [], o = 0; o < n.length; o += 3) i.push(n.substr(o, 3));
39254
39255            return i;
39256          }
39257
39258          var r,
39259              n = [],
39260              i = 0;
39261
39262          for (r = 0; r < t.length; r += 1) t[r] || (n.push(e(i, r)), i = r + 1);
39263
39264          return r > i && n.push(e(i, r)), n;
39265        }
39266      }),
39267          d = new s().uint8(null, {
39268        formatter: function (t) {
39269          return !!t;
39270        }
39271      }),
39272          p = new s().itf8("mapSize").itf8("mapCount").array("ents", {
39273        length: "mapCount",
39274        type: new s().string("key", {
39275          length: 2,
39276          stripNull: !1
39277        }).choice("value", {
39278          tag: "key",
39279          choices: {
39280            MI: d,
39281            UI: d,
39282            PI: d,
39283            RN: d,
39284            AP: d,
39285            RR: d,
39286            SM: new s().array(null, {
39287              type: "uint8",
39288              length: 5
39289            }),
39290            TD: new s().nest(null, {
39291              type: h,
39292              formatter: function (t) {
39293                return t.ents;
39294              }
39295            })
39296          }
39297        })
39298      });
39299
39300      function g(t) {
39301        for (var e = {}, r = 0; r < t.ents.length; r += 1) {
39302          var n = t.ents[r],
39303              i = n.key,
39304              o = n.value;
39305          e[i] && console.warn("duplicate key ".concat(i, " in map")), e[i] = o;
39306        }
39307
39308        return e;
39309      }
39310
39311      var v = {
39312        cramFileDefinition: f,
39313        cramBlockHeader: c,
39314        cramBlockCrc32: l
39315      },
39316          y = {
39317        cramUnmappedSliceHeader: function (t) {
39318          var e = 0,
39319              r = new s().itf8("numRecords");
39320          e += 5, t >= 3 ? (r = r.ltf8("recordCounter"), e += 9) : 2 === t && (r = r.itf8("recordCounter"), e += 5), r = r.itf8("numBlocks").itf8("numContentIds").array("contentIds", {
39321            type: u,
39322            length: "numContentIds"
39323          }), e += 10, t >= 2 && (r = r.array("md5", {
39324            type: "uint8",
39325            length: 16
39326          }), e += 16);
39327          return {
39328            parser: r,
39329            maxLength: function (t) {
39330              return e + 5 * t;
39331            }
39332          };
39333        },
39334        cramMappedSliceHeader: function (t) {
39335          var e = new s().itf8("refSeqId").itf8("refSeqStart").itf8("refSeqSpan").itf8("numRecords"),
39336              r = 20;
39337          t >= 3 ? (e = e.ltf8("recordCounter"), r += 9) : 2 === t && (e = e.itf8("recordCounter"), r += 5), e = e.itf8("numBlocks").itf8("numContentIds").array("contentIds", {
39338            type: u,
39339            length: "numContentIds"
39340          }).itf8("refBaseBlockId"), r += 15, t >= 2 && (e = e.array("md5", {
39341            type: "uint8",
39342            length: 16
39343          }), r += 16);
39344          return {
39345            parser: e,
39346            maxLength: function (t) {
39347              return r + 5 * t;
39348            }
39349          };
39350        },
39351        cramEncoding: function (t) {
39352          return {
39353            parser: new s().namely("cramEncoding").itf8("codecId").itf8("parametersBytes").choice("parameters", {
39354              tag: "codecId",
39355              choices: {
39356                0: new s(),
39357                1: new s().itf8("blockContentId"),
39358                2: new s().itf8("offset").itf8("M"),
39359                3: s.start().itf8("numCodes").array("symbols", {
39360                  length: "numCodes",
39361                  type: u
39362                }).itf8("numLengths").array("bitLengths", {
39363                  length: "numLengths",
39364                  type: u
39365                }),
39366                4: s.start().nest("lengthsEncoding", {
39367                  type: "cramEncoding"
39368                }).nest("valuesEncoding", {
39369                  type: "cramEncoding"
39370                }),
39371                5: new s().uint8("stopByte")[t > 1 ? "itf8" : "int"]("blockContentId"),
39372                6: new s().itf8("offset").itf8("length"),
39373                7: new s().itf8("offset").itf8("K"),
39374                8: new s().itf8("offset").itf8("log2m"),
39375                9: new s().itf8("offset")
39376              }
39377            })
39378          };
39379        },
39380        cramDataSeriesEncodingMap: function (t) {
39381          return new s().itf8("mapSize").itf8("mapCount").array("ents", {
39382            length: "mapCount",
39383            type: new s().string("key", {
39384              length: 2,
39385              stripNull: !1
39386            }).nest("value", {
39387              type: this.cramEncoding(t).parser
39388            })
39389          });
39390        },
39391        cramTagEncodingMap: function (t) {
39392          return new s().itf8("mapSize").itf8("mapCount").array("ents", {
39393            length: "mapCount",
39394            type: new s().itf8("key", {
39395              formatter: function (t) {
39396                return String.fromCharCode(t >> 16 & 255) + String.fromCharCode(t >> 8 & 255) + String.fromCharCode(255 & t);
39397              }
39398            }).nest("value", {
39399              type: this.cramEncoding(t).parser
39400            })
39401          });
39402        },
39403        cramCompressionHeader: function (t) {
39404          var e = new s();
39405          return {
39406            parser: e = e.nest("preservation", {
39407              type: p,
39408              formatter: g
39409            }).nest("dataSeriesEncoding", {
39410              type: this.cramDataSeriesEncodingMap(t),
39411              formatter: g
39412            }).nest("tagEncoding", {
39413              type: this.cramTagEncodingMap(t),
39414              formatter: g
39415            })
39416          };
39417        },
39418        cramContainerHeader1: function (t) {
39419          var e = new s().int32("length").itf8("refSeqId").itf8("refSeqStart").itf8("alignmentSpan").itf8("numRecords"),
39420              r = 24;
39421          return t >= 3 ? (e = e.ltf8("recordCounter"), r += 9) : 2 === t && (e = e.itf8("recordCounter"), r += 5), t > 1 && (e = e.ltf8("numBases"), r += 9), {
39422            parser: e = e.itf8("numBlocks").itf8("numLandmarks"),
39423            maxLength: r += 10
39424          };
39425        },
39426        cramContainerHeader2: function (t) {
39427          var e = new s().itf8("numLandmarks").array("landmarks", {
39428            type: new s().itf8(),
39429            length: "numLandmarks"
39430          }),
39431              r = 0;
39432          return t >= 3 && (e = e.uint32("crc32"), r = 4), {
39433            parser: e,
39434            maxLength: function (t) {
39435              return 5 + 5 * t + r;
39436            }
39437          };
39438        }
39439      };
39440      t.exports = {
39441        cramFileDefinition: f,
39442        getSectionParsers: function (t) {
39443          var e,
39444              r = (0, a.default)({}, v);
39445          return (0, o.default)(e = (0, i.default)(y)).call(e, function (e) {
39446            r[e] = y[e](t);
39447          }), r;
39448        }
39449      };
39450    }, function (t, e, r) {
39451      t.exports = r(320);
39452    }, function (t, e, r) {
39453      r(321);
39454      var n = r(3);
39455      t.exports = n.Object.keys;
39456    }, function (t, e, r) {
39457      var n = r(0),
39458          i = r(22),
39459          o = r(51);
39460      n({
39461        target: "Object",
39462        stat: !0,
39463        forced: r(12)(function () {
39464          o(1);
39465        })
39466      }, {
39467        keys: function (t) {
39468          return o(i(t));
39469        }
39470      });
39471    }, function (t, e, r) {
39472      t.exports = r(323);
39473    }, function (t, e, r) {
39474      r(324);
39475      var n = r(3);
39476      t.exports = n.Object.assign;
39477    }, function (t, e, r) {
39478      var n = r(0),
39479          i = r(325);
39480      n({
39481        target: "Object",
39482        stat: !0,
39483        forced: Object.assign !== i
39484      }, {
39485        assign: i
39486      });
39487    }, function (t, e, r) {
39488
39489      var n = r(17),
39490          i = r(12),
39491          o = r(51),
39492          a = r(138),
39493          s = r(65),
39494          u = r(22),
39495          f = r(60),
39496          c = Object.assign;
39497      t.exports = !c || i(function () {
39498        var t = {},
39499            e = {},
39500            r = Symbol();
39501        return t[r] = 7, "abcdefghijklmnopqrst".split("").forEach(function (t) {
39502          e[t] = t;
39503        }), 7 != c({}, t)[r] || "abcdefghijklmnopqrst" != o(c({}, e)).join("");
39504      }) ? function (t, e) {
39505        for (var r = u(t), i = arguments.length, c = 1, l = a.f, h = s.f; i > c;) for (var d, p = f(arguments[c++]), g = l ? o(p).concat(l(p)) : o(p), v = g.length, y = 0; v > y;) d = g[y++], n && !h.call(p, d) || (r[d] = p[d]);
39506
39507        return r;
39508      } : c;
39509    }, function (t, e, r) {
39510
39511      (function (t) {
39512        function n(t) {
39513          return (n = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (t) {
39514            return typeof t;
39515          } : function (t) {
39516            return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t;
39517          })(t);
39518        }
39519
39520        var i = r(327),
39521            o = r(328).Context,
39522            a = r(146);
39523        "undefined" != typeof window && (window.Buffer = t), "undefined" != typeof self && (self.Buffer = t);
39524        var s = {
39525          UInt8: 1,
39526          UInt16LE: 2,
39527          UInt16BE: 2,
39528          UInt32LE: 4,
39529          UInt32BE: 4,
39530          Int8: 1,
39531          Int16LE: 2,
39532          Int16BE: 2,
39533          Int32LE: 4,
39534          Int32BE: 4,
39535          FloatLE: 4,
39536          FloatBE: 4,
39537          DoubleLE: 8,
39538          DoubleBE: 8,
39539          UInt64: 8,
39540          Int64: 8
39541        },
39542            u = {},
39543            f = [];
39544        !function () {
39545          var t;
39546
39547          for (t = 1; t <= 32; t++) f.push(t);
39548        }();
39549        var c = {};
39550        Object.keys(s).concat(Object.keys({
39551          String: null,
39552          Buffer: null,
39553          Array: null,
39554          Skip: null,
39555          Choice: null,
39556          Nest: null,
39557          Bit: null,
39558          Itf8: null,
39559          Ltf8: null
39560        }
39560)).forEach(function (t) {
39561          c[t.toLowerCase()] = t;
39562        });
39563
39564        var l = function () {
39565          this.varName = "", this.type = "", this.options = {}, this.next = null, this.head = null, this.compiled = null, this.endian = "le", this.constructorFn = null, this.alias = null;
39566        };
39567
39568        l.start = function () {
39569          return new l();
39570        }, Object.keys(s).forEach(function (t) {
39571          l.prototype[t.toLowerCase()] = function (e, r) {
39572            return this.setNextParser(t.toLowerCase(), e, r);
39573          };
39574
39575          var e = t.replace(/BE|LE/, "").toLowerCase();
39576          e in l.prototype || (l.prototype[e] = function (t, r) {
39577            return this[e + this.endian](t, r);
39578          });
39579        }), f.forEach(function (t) {
39580          l.prototype["bit".concat(t.toString())] = function (e, r) {
39581            return r || (r = {}), r.length = t, this.setNextParser("bit", e, r);
39582          };
39583        }), l.prototype.namely = function (t) {
39584          return u[t] = this, this.alias = t, this;
39585        }, l.prototype.skip = function (t, e) {
39586          if (e && e.assert) throw new Error("assert option on skip is not allowed.");
39587          return this.setNextParser("skip", "", {
39588            length: t
39589          });
39590        }, l.prototype.string = function (t, e) {
39591          if (!e.zeroTerminated && !e.length && !e.greedy) throw new Error("Neither length, zeroTerminated, nor greedy is defined for string.");
39592          if ((e.zeroTerminated || e.length) && e.greedy) throw new Error("greedy is mutually exclusive with length and zeroTerminated for string.");
39593          if (e.stripNull && !e.length && !e.greedy) throw new Error("Length or greedy must be defined if stripNull is defined.");
39594          return e.encoding = e.encoding || "utf8", this.setNextParser("string", t, e);
39595        }, l.prototype.buffer = function (t, e) {
39596          if (!e.length && !e.readUntil) throw new Error("Length nor readUntil is defined in buffer parser");
39597          return this.setNextParser("buffer", t, e);
39598        }, l.prototype.array = function (t, e) {
39599          if (!e.readUntil && !e.length && !e.lengthInBytes) throw new Error("Length option of array is not defined.");
39600          if (!e.type) throw new Error("Type option of array is not defined.");
39601          if ("string" == typeof e.type && !u[e.type] && Object.keys(s).indexOf(c[e.type]) < 0) throw new Error('Specified primitive type "'.concat(e.type, '" is not supported.'));
39602          return this.setNextParser("array", t, e);
39603        }, l.prototype.choice = function (t, e) {
39604          if (1 === arguments.length && "object" === n(t) && (e = t, t = null), !e.tag) throw new Error("Tag option of array is not defined.");
39605          if (!e.choices) throw new Error("Choices option of array is not defined.");
39606          return Object.keys(e.choices).forEach(function (r) {
39607            if (!e.choices[r]) throw new Error("Choice Case ".concat(r, " of ").concat(t, " is not valid."));
39608            if ("string" == typeof e.choices[r] && !u[e.choices[r]] && Object.keys(s).indexOf(c[e.choices[r]]) < 0) throw new Error('Specified primitive type "'.concat(e.choices[r], '" is not supported.'));
39609          }, this), this.setNextParser("choice", t, e);
39610        }, l.prototype.nest = function (t, e) {
39611          if (1 === arguments.length && "object" === n(t) && (e = t, t = null), !e.type) throw new Error("Type option of nest is not defined.");
39612          if (!(e.type instanceof l || u[e.type])) throw new Error("Type option of nest must be a Parser object.");
39613          if (!(e.type instanceof l || t)) throw new Error("options.type must be a object if variable name is omitted.");
39614          return this.setNextParser("nest", t, e);
39615        }, l.prototype.endianess = function (t) {
39616          switch (t.toLowerCase()) {
39617            case "little":
39618              this.endian = "le";
39619              break;
39620
39621            case "big":
39622              this.endian = "be";
39623              break;
39624
39625            default:
39626              throw new Error("Invalid endianess: ".concat(t));
39627          }
39628
39629          return this;
39630        }, l.prototype.create = function (t) {
39631          if (!(t instanceof Function)) throw new Error("Constructor must be a Function object.");
39632          return this.constructorFn = t, this;
39633        }, l.prototype.getCode = function () {
39634          var t = new o();
39635          return t.pushCode("if (!Buffer.isBuffer(buffer)) {"), t.generateError('"argument buffer is not a Buffer object"'), t.pushCode("}"), this.alias ? this.addAliasedCode(t) : this.addRawCode(t), this.alias ? t.pushCode("return {0}(0)", "___parser_" + this.alias) : t.pushCode("return { offset: offset, result: vars };"), t.code;
39636        }, l.prototype.addRawCode = function (t) {
39637          t.pushCode("var offset = 0;"), this.constructorFn ? t.pushCode("var vars = new constructorFn();") : t.pushCode("var vars = {};"), this.generate(t), this.resolveReferences(t), t.pushCode("return { offset: offset, result: vars };");
39638        }, l.prototype.addAliasedCode = function (t) {
39639          return t.pushCode("function {0}(offset) {", "___parser_" + this.alias), this.constructorFn ? t.pushCode("var vars = new constructorFn();") : t.pushCode("var vars = {};"), this.generate(t), t.markResolved(this.alias), this.resolveReferences(t), t.pushCode("return { offset: offset, result: vars };"), t.pushCode("}"), t;
39640        }, l.prototype.resolveReferences = function (t) {
39641          var e = t.getUnresolvedReferences();
39642          t.markRequested(e), e.forEach(function (e) {
39643            u[e].addAliasedCode(t);
39644          });
39645        }, l.prototype.compile = function () {
39646          var t = "(function(buffer, constructorFn, Long) { ".concat(this.getCode(), " })");
39647          this.compiled = i.runInThisContext(t);
39648        }, l.prototype.sizeOf = function () {
39649          var t = NaN;
39650          if (Object.keys(s).indexOf(this.type) >= 0) t = s[this.type];else if ("String" === this.type && "number" == typeof this.options.length) t = this.options.length;else if ("Buffer" === this.type && "number" == typeof this.options.length) t = this.options.length;else if ("Array" === this.type && "number" == typeof this.options.length) {
39651            var e = NaN;
39652            "string" == typeof this.options.type ? e = s[c[this.options.type]] : this.options.type instanceof l && (e = this.options.type.sizeOf()), t = this.options.length * e;
39653          } else "Skip" === this.type ? t = this.options.length : "Nest" === this.type ? t = this.options.type.sizeOf() : this.type || (t = 0);
39654          return this.next && (t += this.next.sizeOf()), t;
39655        }, l.prototype.parse = function (t) {
39656          return this.compiled || this.compile(), this.compiled(t, this.constructorFn, a);
39657        }, l.prototype.setNextParser = function (t, e, r) {
39658          var n = new l();
39659          return n.type = c[t], n.varName = e, n.options = r || n.options, n.endian = this.endian, this.head ? this.head.next = n : this.next = n, this.head = n, this;
39660        }, l.prototype.generate = function (t) {
39661          this.type && (this["generate".concat(this.type)](t), this.generateAssert(t));
39662          var e = t.generateVariable(this.varName);
39663          return this.options.formatter && this.generateFormatter(t, e, this.options.formatter), this.generateNext(t);
39664        }, l.prototype.generateAssert = function (t) {
39665          if (this.options.assert) {
39666            var e = t.generateVariable(this.varName);
39667
39668            switch (n(this.options.assert)) {
39669              case "function":
39670                t.pushCode("if (!({0}).call(vars, {1})) {", this.options.assert, e);
39671                break;
39672
39673              case "number":
39674                t.pushCode("if ({0} !== {1}) {", this.options.assert, e);
39675                break;
39676
39677              case "string":
39678                t.pushCode('if ("{0}" !== {1}) {', this.options.assert, e);
39679                break;
39680
39681              default:
39682                throw new Error("Assert option supports only strings, numbers and assert functions.");
39683            }
39684
39685            t.generateError('"Assert error: {0} is " + {0}', e), t.pushCode("}");
39686          }
39687        }, l.prototype.generateNext = function (t) {
39688          return this.next && (t = this.next.generate(t)), t;
39689        }, Object.keys(s).forEach(function (t) {
39690          l.prototype["generate".concat(t)] = function (e) {
39691            "UInt64" === t ? e.pushCode("{0} = Long.fromBytes(buffer.slice(offset,offset+8), true, this.endian === 'le').toNumber();", e.generateVariable(this.varName), t) : "Int64" === t ? e.pushCode("{0} = Long.fromBytes(buffer.slice(offset,offset+8), false, this.endian === 'le').toNumber();", e.generateVariable(this.varName), t) : e.pushCode("{0} = buffer.read{1}(offset);", e.generateVariable(this.varName), t), e.pushCode("offset += {0};", s[t]);
39692          };
39693        }), l.prototype.generateBit = function (t) {
39694          var e = JSON.parse(JSON.stringify(this));
39695
39696          if (e.varName = t.generateVariable(e.varName), t.bitFields.push(e), !this.next || this.next && ["Bit", "Nest"].indexOf(this.next.type) < 0) {
39697            var r = 0;
39698            t.bitFields.forEach(function (t) {
39699              r += t.options.length;
39700            });
39701            var n = t.generateTmpVariable();
39702            if (r <= 8) t.pushCode("var {0} = buffer.readUInt8(offset);", n), r = 8;else if (r <= 16) t.pushCode("var {0} = buffer.readUInt16BE(offset);", n), r = 16;else if (r <= 24) {
39703              var i = t.generateTmpVariable(),
39704                  o = t.generateTmpVariable();
39705              t.pushCode("var {0} = buffer.readUInt16BE(offset);", i), t.pushCode("var {0} = buffer.readUInt8(offset + 2);", o), t.pushCode("var {2} = ({0} << 8) | {1};", i, o, n), r = 24;
39706            } else {
39707              if (!(r <= 32)) throw new Error("Currently, bit field sequence longer than 4-bytes is not supported.");
39708              t.pushCode("var {0} = buffer.readUInt32BE(offset);", n), r = 32;
39709            }
39710            t.pushCode("offset += {0};", r / 8);
39711            var a = 0,
39712                s = "be" === this.endian;
39713            t.bitFields.forEach(function (e) {
39714              t.pushCode("{0} = {1} >> {2} & {3};", e.varName, n, s ? r - a - e.options.length : a, (1 << e.options.length) - 1), a += e.options.length;
39715            }), t.bitFields = [];
39716          }
39717        }, l.prototype.generateSkip = function (t) {
39718          var e = t.generateOption(this.options.length);
39719          t.pushCode("offset += {0};", e);
39720        }, l.prototype.generateString = function (t) {
39721          var e = t.generateVariable(this.varName),
39722              r = t.generateTmpVariable();
39723          this.options.length && this.options.zeroTerminated ? (t.pushCode("var {0} = offset;", r), t.pushCode("while(buffer.readUInt8(offset++) !== 0 && offset - {0}  < {1});", r, this.options.length), t.pushCode("{0} = buffer.toString('{1}', {2}, offset - {2} < {3} ? offset - 1 : offset);", e, this.options.encoding, r, this.options.length)) : this.options.length ? (t.pushCode("{0} = buffer.toString('{1}', offset, offset + {2});", e, this.options.encoding, t.generateOption(this.options.length)), t.pushCode("offset += {0};", t.generateOption(this.options.length))) : this.options.zeroTerminated ? (t.pushCode("var {0} = offset;", r), t.pushCode("while(buffer.readUInt8(offset++) !== 0);"), t.pushCode("{0} = buffer.toString('{1}', {2}, offset - 1);", e, this.options.encoding, r)) : this.options.greedy && (t.pushCode("var {0} = offset;", r), t.pushCode("while(buffer.length > offset++);"), t.pushCode("{0} = buffer.toString('{1}', {2}, offset);", e, this.options.encoding, r)), this.options.stripNull && t.pushCode("{0} = {0}.replace(/\\x00+$/g, '')", e);
39724        }, l.prototype.generateBuffer = function (t) {
39725          "eof" === this.options.readUntil ? t.pushCode("{0} = buffer.slice(offset);", t.generateVariable(this.varName)) : (t.pushCode("{0} = buffer.slice(offset, offset + {1});", t.generateVariable(this.varName), t.generateOption(this.options.length)), t.pushCode("offset += {0};", t.generateOption(this.options.length))), this.options.clone && t.pushCode("{0} = Buffer.from({0});", t.generateVariable(this.varName));
39726        }, l.prototype.generateArray = function (t) {
39727          var e = t.generateOption(this.options.length),
39728              r = t.generateOption(this.options.lengthInBytes),
39729              n = this.options.type,
39730              i = t.generateTmpVariable(),
39731              o = t.generateVariable(this.varName),
39732              a = t.generateTmpVariable(),
39733              f = this.options.key,
39734              h = "string" == typeof f;
39735          if (h ? t.pushCode("{0} = {};", o) : t.pushCode("{0} = [];", o), "function" == typeof this.options.readUntil ? t.pushCode("do {") : "eof" === this.options.readUntil ? t.pushCode("for (var {0} = 0; offset < buffer.length; {0}++) {", i) : void 0 !== r ? t.pushCode("for (var {0} = offset; offset - {0} < {1}; ) {", i, r) : t.pushCode("for (var {0} = 0; {0} < {1}; {0}++) {", i, e), "string" == typeof n) {
39736            if (u[n]) {
39737              var d = t.generateTmpVariable();
39738              t.pushCode("var {0} = {1}(offset);", d, "___parser_" + n), t.pushCode("var {0} = {1}.result; offset = {1}.offset;", a, d), n !== this.alias && t.addReference(n);
39739            } else t.pushCode("var {0} = buffer.read{1}(offset);", a, c[n]), t.pushCode("offset += {0};", s[c[n]]);
39740          } else n instanceof l && (t.pushCode("var {0} = {};", a), t.pushScope(a), n.generate(t), t.popScope());
39741          h ? t.pushCode("{0}[{2}.{1}] = {2};", o, f, a) : t.pushCode("{0}.push({1});", o, a), t.pushCode("}"), "function" == typeof this.options.readUntil && t.pushCode(" while (!({0}).call(this, {1}, buffer.slice(offset)));", this.options.readUntil, a);
39742        }, l.prototype.generateChoiceCase = function (t, e, r) {
39743          if ("string" == typeof r) {
39744            if (u[r]) {
39745              var n = t.generateTmpVariable();
39746              t.pushCode("var {0} = {1}(offset);", n, "___parser_" + r), t.pushCode("{0} = {1}.result; offset = {1}.offset;", t.generateVariable(this.varName), n), r !== this.alias && t.addReference(r);
39747            } else t.pushCode("{0} = buffer.read{1}(offset);", t.generateVariable(this.varName), c[r]), t.pushCode("offset += {0};", s[c[r]]);
39748          } else r instanceof l && (t.pushPath(e), r.generate(t), t.popPath(e));
39749        }, l.prototype.generateChoice = function (t) {
39750          var e = t.generateOption(this.options.tag);
39751          this.varName && t.pushCode("{0} = {};", t.generateVariable(this.varName)), t.pushCode("switch({0}
39751) {", e), Object.keys(this.options.choices).forEach(function (e) {
39752            var r = this.options.choices[e];
39753            Number.isNaN(parseInt(e, 10)) ? t.pushCode("case '{0}':", e) : t.pushCode("case {0}:", e), this.generateChoiceCase(t, this.varName, r), t.pushCode("break;");
39754          }, this), t.pushCode("default:"), this.options.defaultChoice ? this.generateChoiceCase(t, this.varName, this.options.defaultChoice) : t.generateError('"Met undefined tag value " + {0} + " at choice"', e), t.pushCode("}");
39755        }, l.prototype.generateNest = function (t) {
39756          var e = t.generateVariable(this.varName);
39757          if (this.options.type instanceof l) this.varName && t.pushCode("{0} = {};", e), t.pushPath(this.varName), this.options.type.generate(t), t.popPath(this.varName);else if (u[this.options.type]) {
39758            var r = t.generateTmpVariable();
39759            t.pushCode("var {0} = {1}(offset);", r, "___parser_" + this.options.type), t.pushCode("{0} = {1}.result; offset = {1}.offset;", e, r), this.options.type !== this.alias && t.addReference(this.options.type);
39760          }
39761        }, l.prototype.generateFormatter = function (t, e, r) {
39762          "function" == typeof r && t.pushCode("{0} = ({1}).call(this, {0});", e, r);
39763        }, l.prototype.isInteger = function () {
39764          return !!this.type.match(/U?Int[8|16|32][BE|LE]?|Bit\d+/);
39765        }, l.prototype.itf8 = function (t, e) {
39766          return this.setNextParser("itf8", t, e);
39767        }, l.prototype.itf8 = function (t, e) {
39768          return this.setNextParser("itf8", t, e);
39769        }, l.prototype.generateItf8 = function (t) {
39770          var e = t.generateVariable(this.varName),
39771              r = t.generateTmpVariable();
39772          t.pushCode("\n    var ".concat(r, " = buffer[offset];\n    if (").concat(r, " < 0x80) {\n      ").concat(e, " = ").concat(r, ";\n      offset += 1;\n    } else if (").concat(r, " < 0xc0) {\n      ").concat(e, " = ((").concat(r, "<<8) | buffer[offset+1]) & 0x3fff;\n      offset += 2;\n    } else if (").concat(r, " < 0xe0) {\n      ").concat(e, " = ((").concat(r, "<<16) | (buffer[offset+1]<< 8) |  buffer[offset+2]) & 0x1fffff;\n      offset += 3;\n    } else if (").concat(r, " < 0xf0) {\n      ").concat(e, " = ((").concat(r, "<<24) | (buffer[offset+1]<<16) | (buffer[offset+2]<<8) | buffer[offset+3]) & 0x0fffffff;\n      offset += 4\n    } else {\n      ").concat(e, " = ((").concat(r, " & 0x0f)<<28) | (buffer[offset+1]<<20) | (buffer[offset+2]<<12) | (buffer[offset+3]<<4) | (buffer[offset+4] & 0x0f);\n      // x=((0xff & 0x0f)<<28) | (0xff<<20) | (0xff<<12) | (0xff<<4) | (0x0f & 0x0f);\n      // TODO *val_p = uv < 0x80000000UL ? uv : -((int32_t) (0xffffffffUL - uv)) - 1;\n      offset += 5\n    }\n  "));
39773        }, l.prototype.ltf8 = function (t, e) {
39774          return this.setNextParser("ltf8", t, e);
39775        }, l.prototype.generateLtf8 = function (t) {
39776          var e = t.generateVariable(this.varName),
39777              r = t.generateTmpVariable();
39778          t.pushCode("\n  var ".concat(r, " = buffer[offset];\n  if (").concat(r, " < 0x80) {\n    ").concat(e, " = ").concat(r, ";\n    offset += 1;\n  } else if (").concat(r, " < 0xc0) {\n    ").concat(e, " = ((buffer[offset]<<8) | buffer[offset+1]) & 0x3fff;\n    offset += 2;\n  } else if (").concat(r, " < 0xe0) {\n    ").concat(e, " = ((buffer[offset]<<16) | (buffer[offset+1]<<8) | buffer[offset+2]) & 0x1fffff;\n    ").concat(e, " = (((").concat(r, " & 63) << 16) | buffer.readUInt16LE(offset + 1));\n    offset += 3;\n  } else if (").concat(r, " < 0xf0) {\n    ").concat(e, " = ((buffer[offset]<<24) | (buffer[offset+1]<<16) | (buffer[offset+2]<<8) | buffer[offset+3]) & 0x0fffffff;\n    offset += 4;\n  } else if (").concat(r, " < 0xf8) {\n    ").concat(e, " = (((buffer[offset] & 15) * Math.pow(2,32))) +\n      (buffer[offset+1]<<24) | (buffer[offset+2]<<16 | buffer[offset+3]<<8 | buffer[offset+4])\n    // TODO *val_p = uv < 0x80000000UL ? uv : -((int32_t) (0xffffffffUL - uv)) - 1;\n    offset += 5;\n  } else if (").concat(r, " < 0xfc) {\n    ").concat(e, " = ((((buffer[offset] & 7) << 8) | buffer[offset+1] )) * Math.pow(2,32) +\n      (buffer[offset+2]<<24) | (buffer[offset+3]<<16 | buffer[offset+4]<<8 | buffer[offset+5])\n    offset += 6;\n  } else if (").concat(r, " < 0xfe) {\n    ").concat(e, " = ((((buffer[offset] & 3) << 16) | buffer[offset+1]<<8 | buffer[offset+2])) * Math.pow(2,32) +\n      (buffer[offset+3]<<24) | (buffer[offset+4]<<16 | buffer[offset+5]<<8 | buffer[offset+6])\n    offset += 7;\n  } else if (").concat(r, " < 0xff) {\n    ").concat(e, " = Long.fromBytesBE(buffer.slice(offset+1,offset+8));\n    if (").concat(e, ".greaterThan(Number.MAX_SAFE_INTEGER) || ").concat(e, ".lessThan(Number.MIN_SAFE_INTEGER))\n      throw new Error('integer overflow')\n    ").concat(e, " = ").concat(e, ".toNumber()\n    offset += 8;\n  } else {\n    ").concat(e, " = Long.fromBytesBE(buffer.slice(offset+1,offset+9));\n    if (").concat(e, ".greaterThan(Number.MAX_SAFE_INTEGER) || ").concat(e, ".lessThan(Number.MIN_SAFE_INTEGER))\n      throw new Error('integer overflow')\n    ").concat(e, " = ").concat(e, ".toNumber()\n    offset += 9;\n  }\n  "));
39779        }, e.Parser = l;
39780      }).call(this, r(19).Buffer);
39781    }
39781, function (module, exports) {
39782      var indexOf = function (t, e) {
39783        if (t.indexOf) return t.indexOf(e);
39784
39785        for (var r = 0; r < t.length; r++) if (t[r] === e) return r;
39786
39787        return -1;
39788      },
39789          Object_keys = function (t) {
39790        if (Object.keys) return Object.keys(t);
39791        var e = [];
39792
39793        for (var r in t) e.push(r);
39794
39795        return e;
39796      },
39797          forEach = function (t, e) {
39798        if (t.forEach) return t.forEach(e);
39799
39800        for (var r = 0; r < t.length; r++) e(t[r], r, t);
39801      },
39802          defineProp = function () {
39803        try {
39804          return Object.defineProperty({}, "_", {}), function (t, e, r) {
39805            Object.defineProperty(t, e, {
39806              writable: !0,
39807              enumerable: !1,
39808              configurable: !0,
39809              value: r
39810            });
39811          };
39812        } catch (t) {
39813          return function (t, e, r) {
39814            t[e] = r;
39815          };
39816        }
39817      }(),
39818          globals = ["Array", "Boolean", "Date", "Error", "EvalError", "Function", "Infinity", "JSON", "Math", "NaN", "Number", "Object", "RangeError", "ReferenceError", "RegExp", "String", "SyntaxError", "TypeError", "URIError", "decodeURI", "decodeURIComponent", "encodeURI", "encodeURIComponent", "escape", "eval", "isFinite", "isNaN", "parseFloat", "parseInt", "undefined", "unescape"];
39819
39820      function Context() {}
39821
39822      Context.prototype = {};
39823
39824      var Script = exports.Script = function (t) {
39825        if (!(this instanceof Script)) return new Script(t);
39826        this.code = t;
39827      };
39828
39829      Script.prototype.runInContext = function (t) {
39830        if (!(t instanceof Context)) throw new TypeError("needs a 'context' argument.");
39831        var e = document.createElement("iframe");
39832        e.style || (e.style = {}), e.style.display = "none", document.body.appendChild(e);
39833        var r = e.contentWindow,
39834            n = r.eval,
39835            i = r.execScript;
39836        !n && i && (i.call(r, "null"), n = r.eval), forEach(Object_keys(t), function (e) {
39837          r[e] = t[e];
39838        }), forEach(globals, function (e) {
39839          t[e] && (r[e] = t[e]);
39840        });
39841        var o = Object_keys(r),
39842            a = n.call(r, this.code);
39843        return forEach(Object_keys(r), function (e) {
39844          (e in t || -1 === indexOf(o, e)) && (t[e] = r[e]);
39845        }), forEach(globals, function (e) {
39846          e in t || defineProp(t, e, r[e]);
39847        }), document.body.removeChild(e), a;
39848      }, Script.prototype.runInThisContext = function () {
39849        return eval2(this.code);
39850      }, Script.prototype.runInNewContext = function (t) {
39851        var e = Script.createContext(t),
39852            r = this.runInContext(e);
39853        return t && forEach(Object_keys(e), function (r) {
39854          t[r] = e[r];
39855        }), r;
39856      }, forEach(Object_keys(Script.prototype), function (t) {
39857        exports[t] = Script[t] = function (e) {
39858          var r = Script(e);
39859          return r[t].apply(r, [].slice.call(arguments, 1));
39860        };
39861      }), exports.isContext = function (t) {
39862        return t instanceof Context;
39863      }, exports.createScript = function (t) {
39864        return exports.Script(t);
39865      }, exports.createContext = Script.createContext = function (t) {
39866        var e = new Context();
39867        return "object" == typeof t && forEach(Object_keys(t), function (r) {
39868          e[r] = t[r];
39869        }), e;
39870      };
39871    }, function (t, e, r) {
39872
39873      function n(t) {
39874        return (n = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (t) {
39875          return typeof t;
39876        } : function (t) {
39877          return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t;
39878        })(t);
39879      }
39880
39881      var i = function () {
39882        this.code = "", this.scopes = [["vars"]], this.isAsync = !1, this.bitFields = [], this.tmpVariableCount = 0, this.references = {};
39883      };
39884
39885      i.prototype.generateVariable = function (t) {
39886        var e = [];
39887
39888        for (Array.prototype.push.apply(e, this.scopes[this.scopes.length - 1]); /^\$parent\./.test(t);) e.pop(), t = t.replace(/^\$parent\./, "");
39889
39890        return t && e.push(t), e.join(".");
39891      }, i.prototype.generateOption = function (t) {
39892        switch (n(t)) {
39893          case "number":
39894            return t.toString();
39895
39896          case "string":
39897            return this.generateVariable(t);
39898
39899          case "function":
39900            return "(".concat(t, ").call(").concat(this.generateVariable(), ", vars)");
39901
39902          default:
39903            return;
39904        }
39905      }, i.prototype.generateError = function () {
39906        var t = Array.prototype.slice.call(arguments),
39907            e = i.interpolate.apply(this, t);
39908        this.isAsync ? this.pushCode("return process.nextTick(function() { callback(new Error(".concat(e, "), vars); });")) : this.pushCode("throw new Error(".concat(e, ");"));
39909      }, i.prototype.generateTmpVariable = function () {
39910        return "$tmp".concat(this.tmpVariableCount++);
39911      }, i.prototype.pushCode = function () {
39912        var t = Array.prototype.slice.call(arguments);
39913        this.code += "".concat(i.interpolate.apply(this, t), "\n");
39914      }, i.prototype.pushPath = function (t) {
39915        t && this.scopes[this.scopes.length - 1].push(t);
39916      }, i.prototype.popPath = function (t) {
39917        t && this.scopes[this.scopes.length - 1].pop();
39918      }, i.prototype.pushScope = function (t) {
39919        this.scopes.push([t]);
39920      }, i.prototype.popScope = function () {
39921        this.scopes.pop();
39922      }, i.prototype.addReference = function (t) {
39923        this.references[t] || (this.references[t] = {
39924          resolved: !1,
39925          requested: !1
39926        });
39927      }, i.prototype.markResolved = function (t) {
39928        this.references[t].resolved = !0;
39929      }, i.prototype.markRequested = function (t) {
39930        t.forEach(function (t) {
39931          this.references[t].requested = !0;
39932        }.bind(this));
39933      }, i.prototype.getUnresolvedReferences = function () {
39934        var t = this.references;
39935        return Object.keys(this.references).filter(function (e) {
39936          return !t[e].resolved && !t[e].requested;
39937        });
39938      }, i.interpolate = function (t) {
39939        var e = /{\d+}/g,
39940            r = t.match(e),
39941            n = Array.prototype.slice.call(arguments, 1);
39942        return r && r.forEach(function (e) {
39943          var r = parseInt(e.substr(1, e.length - 2), 10);
39944          t = t.replace(e, n[r].toString());
39945        }), t;
39946      }, e.Context = i;
39947    }, function (t, e, r) {
39948
39949      (function (e) {
39950        var n,
39951            i = r(1),
39952            o = i(r(16)),
39953            a = i(r(75)),
39954            s = i(r(37)),
39955            u = i(r(30)),
39956            f = i(r(31)),
39957            c = i(r(7)),
39958            l = i(r(10)),
39959            h = r(9).CramMalformedError,
39960            d = r(58),
39961            p = d.itf8Size,
39962            g = d.parseItem,
39963            v = d.tinyMemoize,
39964            y = r(334),
39965            m = r(390),
39966            b = function () {
39967          function t(e, r) {
39968            (0, c.default)(this, t), this.file = e, this.filePosition = r;
39969          }
39970
39971          var r, n, i, o;
39972          return (0, l.default)(t, [{
39973            key: "getHeader",
39974            value: function () {
39975              return this._readContainerHeader(this.filePosition);
39976            }
39977          }, {
39978            key: "getCompressionHeaderBlock",
39979            value: (o = (0, f.default)(u.default.mark(function t() {
39980              var e, r, n;
39981              return u.default.wrap(function (t) {
39982                for (;;) switch (t.prev = t.next) {
39983                  case 0:
39984                    return t.next = 2, this.getHeader();
39985
39986                  case 2:
39987                    if (t.sent.numRecords) {
39988                      t.next = 5;
39989                      break;
39990                    }
39991
39992                    return t.abrupt("return", null);
39993
39994                  case 5:
39995                    return t.next = 7, this.file.getSectionParsers();
39996
39997                  case 7:
39998                    return e = t.sent, t.next = 10, this.getFirstBlock();
39999
40000                  case 10:
40001                    if ("COMPRESSION_HEADER" === (r = t.sent).contentType) {
40002                      t.next = 13;
40003                      break;
40004                    }
40005
40006                    throw new h("invalid content type ".concat(r.contentType, " in what is supposed to be the compression header block"));
40007
40008                  case 13:
40009                    return n = g(r.content, e.cramCompressionHeader.parser, 0, r.contentPosition), r.content = n, t.abrupt("return", r);
40010
40011                  case 16:
40012                  case "end":
40013                    return t.stop();
40014                }
40015              }, t, this);
40016            })), function () {
40017              return o.apply(this, arguments);
40018            })
40019          }, {
40020            key: "getFirstBlock",
40021            value: (i = (0, f.default)(u.default.mark(function t() {
40022              var e;
40023              return u.default.wrap(function (t) {
40024                for (;;) switch (t.prev = t.next) {
40025                  case 0:
40026                    return t.next = 2, this.getHeader();
40027
40028                  case 2:
40029                    return e = t.sent, t.abrupt("return", this.file.readBlock(e._endPosition));
40030
40031                  case 4:
40032                  case "end":
40033                    return t.stop();
40034                }
40035              }, t, this);
40036            })), function () {
40037              return i.apply(this, arguments);
40038            })
40039          }, {
40040            key: "getCompressionScheme",
40041            value: (n = (0, f.default)(u.default.mark(function t() {
40042              var e;
40043              return u.default.wrap(function (t) {
40044                for (;;) switch (t.prev = t.next) {
40045                  case 0:
40046                    return t.next = 2, this.getCompressionHeaderBlock();
40047
40048                  case 2:
40049                    if (e = t.sent) {
40050                      t.next = 5;
40051                      break;
40052                    }
40053
40054                    return t.abrupt("return", void 0);
40055
40056                  case 5:
40057                    return t.abrupt("return", new m(e.content));
40058
40059                  case 6:
40060                  case "end":
40061                    return t.stop();
40062                }
40063              }, t, this);
40064            })), function () {
40065              return n.apply(this, arguments);
40066            })
40067          }, {
40068            key: "getSlice",
40069            value: function (t, e) {
40070              return new y(this, t, e);
40071            }
40072          }, {
40073            key: "_readContainerHeader",
40074            value: (r = (0, f.default)(u.default.mark(function t(r) {
40075              var n, i, o, f, c, l, h, d, v, y, m, b, _;
40076
40077              return u.default.wrap(function (t) {
40078                for (;;) switch (t.prev = t.next) {
40079                  case 0:
40080                    return t.next = 2, this.file.getSectionParsers();
40081
40082                  case 2:
40083                    return n = t.sent, i = n.cramContainerHeader1, o = n.cramContainerHeader2, t.next = 6, this.file.stat();
40084
40085                  case 6:
40086                    if (f = t.sent, c = f.size, !(r >= c)) {
40087                      t.next = 10;
40088                      break;
40089                    }
40090
40091                    return t.abrupt("return", void 0);
40092
40093                  case 10:
40094                    return l = e.allocUnsafe(i.maxLength), t.next = 13, this.file.read(l, 0, i.maxLength, r);
40095
40096                  case 13:
40097                    if (h = g(l, i.parser), d = p(h.numLandmarks), !(r + h.length >= c)) {
40098                      t.next = 18;
40099                      break;
40100                    }
40101
40102                    return console.warn((0, s.default)(v = (0, s.default)(y = "".concat(this.file, ": container header at ")).call(y, r, " indicates that the container has length ")).call(v, h.length, ", which extends beyond the length of the file. Skipping this container.")), t.abrupt("return", void 0);
40103
40104                  case 18:
40105                    return m = e.allocUnsafe(o.maxLength(h.numLandmarks)), t.next = 21, this.file.read(m, 0, o.maxLength(h.numLandmarks), r + h._size - d);
40106
40107                  case 21:
40108                    if (b = g(m, o.parser), !this.file.validateChecksums || void 0 === b.crc32) {
40109                      t.next = 25;
40110                      break;
40111                    }
40112
40113                    return t.next = 25, this.file.checkCrc32(r, h._size + b._size - d - 4, b.crc32, "container header beginning at position ".concat(r));
40114
40115                  case 25:
40116                    return _ = (0, a.default)(h, b, {
40117                      _size: h._size + b._size - d,
40118                      _endPosition: h._size + b._size - d + r
40119                    }), t.abrupt("return", _);
40120
40121                  case 27:
40122                  case "end":
40123                    return t.stop();
40124                }
40125              }, t, this);
40126            })), function (t) {
40127              return r.apply(this, arguments);
40128            })
40129          }]), t;
40130        }();
40131
40132        (0, o.default)(n = "getHeader getCompressionHeaderBlock getCompressionScheme".split(" ")).call(n, function (t) {
40133          return v(b, t);
40134        }), t.exports = b;
40135      }).call(this, r(19).Buffer);
40136    }, function (t, e, r) {
40137      t.exports = r(115);
40138    }, function (t, e, r) {
40139      var n, i, o, a, s;
40140      n = r(332), i = r(147).utf8, o = r(333), a = r(147).bin, (s = function (t, e) {
40141        t.constructor == String ? t = e && "binary" === e.encoding ? a.stringToBytes(t) : i.stringToBytes(t) : o(t) ? t = Array.prototype.slice.call(t, 0) : Array.isArray(t) || (t = t.toString());
40142
40143        for (var r = n.bytesToWords(t), u = 8 * t.length, f = 1732584193, c = -271733879, l = -1732584194, h = 271733878, d = 0; d < r.length; d++) r[d] = 16711935 & (r[d] << 8 | r[d] >>> 24) | 4278255360 & (r[d] << 24 | r[d] >>> 8);
40144
40145        r[u >>> 5] |= 128 << u % 32, r[14 + (u + 64 >>> 9 << 4)] = u;
40146        var p = s._ff,
40147            g = s._gg,
40148            v = s._hh,
40149            y = s._ii;
40150
40151        for (d = 0; d < r.length; d += 16) {
40152          var m = f,
40153              b = c,
40154              _ = l,
40155              w = h;
40156          f = p(f, c, l, h, r[d + 0], 7, -680876936), h = p(h, f, c, l, r[d + 1], 12, -389564586), l = p(l, h, f, c, r[d + 2], 17, 606105819), c = p(c, l, h, f, r[d + 3], 22, -1044525330), f = p(f, c, l, h, r[d + 4], 7, -176418897), h = p(h, f, c, l, r[d + 5], 12, 1200080426), l = p(l, h, f, c, r[d + 6], 17, -1473231341), c = p(c, l, h, f, r[d + 7], 22, -45705983), f = p(f, c, l, h, r[d + 8], 7, 1770035416), h = p(h, f, c, l, r[d + 9], 12, -1958414417), l = p(l, h, f, c, r[d + 10], 17, -42063), c = p(c, l, h, f, r[d + 11], 22, -1990404162), f = p(f, c, l, h, r[d + 12], 7, 1804603682), h = p(h, f, c, l, r[d + 13], 12, -40341101), l = p(l, h, f, c, r[d + 14], 17, -1502002290), f = g(f, c = p(c, l, h, f, r[d + 15], 22, 
401561236535329), l, h, r[d + 1], 5, -165796510), h = g(h, f, c, l, r[d + 6], 9, -1069501632), l = g(l, h, f, c, r[d + 11], 14, 643717713), c = g(c, l, h, f, r[d + 0], 20, -373897302), f = g(f, c, l, h, r[d + 5], 5, -701558691), h = g(h, f, c, l, r[d + 10], 9, 38016083), l = g(l, h, f, c, r[d + 15], 14, -660478335), c = g(c, l, h, f, r[d + 4], 20, -405537848), f = g(f, c, l, h, r[d + 9], 5, 568446438), h = g(h, f, c, l, r[d + 14], 9, -1019803690), l = g(l, h, f, c, r[d + 3], 14, -187363961), c = g(c, l, h, f, r[d + 8], 20, 1163531501), f = g(f, c, l, h, r[d + 13], 5, -1444681467), h = g(h, f, c, l, r[d + 2], 9, -51403784), l = g(l, h, f, c, r[d + 7], 14, 1735328473), f = v(f, c = g(c, l, h, f, r[d + 12], 20, -1926607734), l, h, r[d + 5], 4, -378558), h = v(h, f, c, l, r[d + 8], 11, -2022574463), l = v(l, h, f, c, r[d + 11], 16, 1839030562), c = v(c, l, h, f, r[d + 14], 23, -35309556), f = v(f, c, l, h, r[d + 1], 4, -1530992060), h = v(h, f, c, l, r[d + 4], 11, 1272893353), l = v(l, h, f, c, r[d + 7], 16, -155497632), c = v(c, l, h, f, r[d + 10], 23, -1094730640), f = v(f, c, l, h, r[d + 13], 4, 681279174), h = v(h, f, c, l, r[d + 0], 11, -358537222), l = v(l, h, f, c, r[d + 3], 16, -722521979), c = v(c, l, h, f, r[d + 6], 23, 76029189), f = v(f, c, l, h, r[d + 9], 4, -640364487), h = v(h, f, c, l, r[d + 12], 11, -421815835), l = v(l, h, f, c, r[d + 15], 16, 530742520), f = y(f, c = v(c, l, h, f, r[d + 2], 23, -995338651), l, h, r[d + 0], 6, -198630844), h = y(h, f, c, l, r[d + 7], 10, 1126891415), l = y(l, h, f, c, r[d + 14], 15, -1416354905), c = y(c, l, h, f, r[d + 5], 21, -57434055), f = y(f, c, l, h, r[d + 12], 6, 1700485571), h = y(h, f, c, l, r[d + 3], 10, -1894986606), l = y(l, h, f, c, r[d + 10], 15, -1051523), c = y(c, l, h, f, r[d + 1], 21, -2054922799), f = y(f, c, l, h, r[d + 8], 6, 1873313359), h = y(h, f, c, l, r[d + 15], 10, -30611744), l = y(l, h, f, c, r[d + 6], 15, -1560198380), c = y(c, l, h, f, r[d + 13], 21, 1309151649), f = y(f, c, l, h, r[d + 4], 6, -145523070), h = y(h, f, c, l, r[d + 11], 10, -1120210379), l = y(l, h, f, c, r[d + 2], 15, 718787259), c = y(c, l, h, f, r[d + 9], 21, -343485551), f = f + m >>> 0, c = c + b >>> 0, l = l + _ >>> 0, h = h + w >>> 0;
40157        }
40158
40159        return n.endian([f, c, l, h]);
40160      })._ff = function (t, e, r, n, i, o, a) {
40161        var s = t + (e & r | ~e & n) + (i >>> 0) + a;
40162        return (s << o | s >>> 32 - o) + e;
40163      }, s._gg = function (t, e, r, n, i, o, a) {
40164        var s = t + (e & n | r & ~n) + (i >>> 0) + a;
40165        return (s << o | s >>> 32 - o) + e;
40166      }, s._hh = function (t, e, r, n, i, o, a) {
40167        var s = t + (e ^ r ^ n) + (i >>> 0) + a;
40168        return (s << o | s >>> 32 - o) + e;
40169      }, s._ii = function (t, e, r, n, i, o, a) {
40170        var s = t + (r ^ (e | ~n)) + (i >>> 0) + a;
40171        return (s << o | s >>> 32 - o) + e;
40172      }, s._blocksize = 16, s._digestsize = 16, t.exports = function (t, e) {
40173        if (null == t) throw new Error("Illegal argument " + t);
40174        var r = n.wordsToBytes(s(t, e));
40175        return e && e.asBytes ? r : e && e.asString ? a.bytesToString(r) : n.bytesToHex(r);
40176      };
40177    }, function (t, e) {
40178      var r, n;
40179      r = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", n = {
40180        rotl: function (t, e) {
40181          return t << e | t >>> 32 - e;
40182        },
40183        rotr: function (t, e) {
40184          return t << 32 - e | t >>> e;
40185        },
40186        endian: function (t) {
40187          if (t.constructor == Number) return 16711935 & n.rotl(t, 8) | 4278255360 & n.rotl(t, 24);
40188
40189          for (var e = 0; e < t.length; e++) t[e] = n.endian(t[e]);
40190
40191          return t;
40192        },
40193        randomBytes: function (t) {
40194          for (var e = []; t > 0; t--) e.push(Math.floor(256 * Math.random()));
40195
40196          return e;
40197        },
40198        bytesToWords: function (t) {
40199          for (var e = [], r = 0, n = 0; r < t.length; r++, n += 8) e[n >>> 5] |= t[r] << 24 - n % 32;
40200
40201          return e;
40202        },
40203        wordsToBytes: function (t) {
40204          for (var e = [], r = 0; r < 32 * t.length; r += 8) e.push(t[r >>> 5] >>> 24 - r % 32 & 255);
40205
40206          return e;
40207        },
40208        bytesToHex: function (t) {
40209          for (var e = [], r = 0; r < t.length; r++) e.push((t[r] >>> 4).toString(16)), e.push((15 & t[r]).toString(16));
40210
40211          return e.join("");
40212        },
40213        hexToBytes: function (t) {
40214          for (var e = [], r = 0; r < t.length; r += 2) e.push(parseInt(t.substr(r, 2), 16));
40215
40216          return e;
40217        },
40218        bytesToBase64: function (t) {
40219          for (var e = [], n = 0; n < t.length; n += 3) for (var i = t[n] << 16 | t[n + 1] << 8 | t[n + 2], o = 0; o < 4; o++) 8 * n + 6 * o <= 8 * t.length ? e.push(r.charAt(i >>> 6 * (3 - o) & 63)) : e.push("=");
40220
40221          return e.join("");
40222        },
40223        base64ToBytes: function (t) {
40224          t = t.replace(/[^A-Z0-9+\/]/gi, "");
40225
40226          for (var e = [], n = 0, i = 0; n < t.length; i = ++n % 4) 0 != i && e.push((r.indexOf(t.charAt(n - 1)) & Math.pow(2, -2 * i + 8) - 1) << 2 * i | r.indexOf(t.charAt(n)) >>> 6 - 2 * i);
40227
40228          return e;
40229        }
40230      }, t.exports = n;
40231    }, function (t, e) {
40232      function r(t) {
40233        return !!t.constructor && "function" == typeof t.constructor.isBuffer && t.constructor.isBuffer(t);
40234      }
40235      /*!
40236       * Determine if an object is a Buffer
40237       *
40238       * @author   Feross Aboukhadijeh <https://feross.org>
40239       * @license  MIT
40240       */
40241
40242
40243      t.exports = function (t) {
40244        return null != t && (r(t) || function (t) {
40245          return "function" == typeof t.readFloatLE && "function" == typeof t.slice && r(t.slice(0, 0));
40246        }(t) || !!t._isBuffer);
40247      };
40248    }, function (t, e, r) {
40249
40250      var n,
40251          i = r(1),
40252          o = i(r(148)),
40253          a = i(r(76)),
40254          s = i(r(150)),
40255          u = i(r(37)),
40256          f = i(r(30)),
40257          c = i(r(31)),
40258          l = i(r(7)),
40259          h = i(r(10)),
40260          d = i(r(99)),
40261          p = i(r(16)),
40262          g = i(r(77)),
40263          v = i(r(59)),
40264          y = r(9),
40265          m = y.CramMalformedError,
40266          b = y.CramBufferOverrunError,
40267          _ = y.CramArgumentError,
40268          w = r(58),
40269          x = w.parseItem,
40270          E = w.tinyMemoize,
40271          S = w.sequenceMD5,
40272          k = r(100),
40273          A = r(363);
40274
40275      function C(t, e, r, n) {
40276        if (!n) throw new m("could not resolve intra-slice mate pairs, file seems truncated or malformed");
40277        var i = !!(n.mate || void 0 !== n.mateRecordNumber && n.mateRecordNumber !== e);
40278        r.readName || (r.readName = String(r.uniqueId), n.readName = r.readName), r.mate = {
40279          sequenceId: n.sequenceId,
40280          alignmentStart: n.alignmentStart,
40281          uniqueId: n.uniqueId
40282        }, n.readName && (r.mate.readName = n.readName), n.mate || void 0 !== n.mateRecordNumber || (n.mate = {
40283          sequenceId: r.sequenceId,
40284          alignmentStart: r.alignmentStart,
40285          uniqueId: r.uniqueId
40286        }, r.readName && (n.mate.readName = r.readName)), r.flags |= k.BAM_FPAIRED, (0, d.default)(n) & k.BAM_FUNMAP && (r.flags |= k.BAM_FMUNMAP), (0, d.default)(r) & k.BAM_FUNMAP && (n.flags |= k.BAM_FMUNMAP), (0, d.default)(n) & k.BAM_FREVERSE && (r.flags |= k.BAM_FMREVERSE), (0, d.default)(r) & k.BAM_FREVERSE && (n.flags |= k.BAM_FMREVERSE), void 0 === r.templateLength && (i ? function (t, e, r) {
40287          var n = function e(r) {
40288            var n = [r];
40289
40290            if (r.mateRecordNumber >= 0) {
40291              var i = t[r.mateRecordNumber];
40292              if (!i) throw new m("intra-slice mate record not found, this file seems malformed");
40293              n.push.apply(n, (0, v.default)(e(i)));
40294            }
40295
40296            return n;
40297          }(r),
40298              i = (0, g.default)(n).call(n, function (t) {
40299            return t.alignmentStart;
40300          }),
40301              o = (0, g.default)(n).call(n, function (t) {
40302            return t.alignmentStart + t.readLength - 1;
40303          }),
40304              a = Math.max.apply(Math, (0, v.default)(o)) - Math.min.apply(Math, (0, v.default)(i)) + 1;
40305
40306          a >= 0 && (0, p.default)(n).call(n, function (t) {
40307            if (void 0 !== t.templateLength) throw new m("mate pair group has some members that have template lengths already, this file seems malformed");
40308            t.templateLength = a;
40309          });
40310        }(t, 0, r) : function (t, e) {
40311          var r = Math.min(t.alignmentStart, e.alignmentStart),
40312              n = Math.max(t.alignmentStart + t.readLength - 1, e.alignmentStart + e.readLength - 1) - r + 1;
40313          t.templateLength = n, e.templateLength = n;
40314        }(r, n)), delete r.mateRecordNumber;
40315      }
40316
40317      var T = function () {
40318        function t(e, r) {
40319          (0, l.default)(this, t), this.container = e, this.file = e.file, this.containerPosition = r;
40320        }
40321
40322        var e, r, n, i, d, v, y, w;
40323        return (0, h.default)(t, [{
40324          key: "getHeader",
40325          value: (w = (0, c.default)(f.default.mark(function t() {
40326            var e, r, n;
40327            return f.default.wrap(function (t) {
40328              for (;;) switch (t.prev = t.next) {
40329                case 0:
40330                  return t.next = 2, this.file.getSectionParsers();
40331
40332                case 2:
40333                  return e = t.sent, t.next = 5, this.container.getHeader();
40334
40335                case 5:
40336                  return r = t.sent, t.next = 8, this.file.readBlock(r._endPosition + this.containerPosition);
40337
40338                case 8:
40339                  if ("MAPPED_SLICE_HEADER" !== (n = t.sent).contentType) {
40340                    t.next = 13;
40341                    break;
40342                  }
40343
40344                  n.content = x(n.content, e.cramMappedSliceHeader.parser, 0, r._endPosition), t.next = 18;
40345                  break;
40346
40347                case 13:
40348                  if ("UNMAPPED_SLICE_HEADER" !== n.contentType) {
40349                    t.next = 17;
40350                    break;
40351                  }
40352
40353                  n.content = x(n.content, e.cramUnmappedSliceHeader.parser, 0, r._endPosition), t.next = 18;
40354                  break;
40355
40356                case 17:
40357                  throw new m("error reading slice header block, invalid content type ".concat(n._contentType));
40358
40359                case 18:
40360                  return t.abrupt("return", n);
40361
40362                case 19:
40363                case "end":
40364                  return t.stop();
40365              }
40366            }, t, this);
40367          })), function () {
40368            return w.apply(this, arguments);
40369          })
40370        }, {
40371          key: "getBlocks",
40372          value: (y = (0, c.default)(f.default.mark(function t() {
40373            var e, r, n, i;
40374            return f.default.wrap(function (t) {
40375              for (;;) switch (t.prev = t.next) {
40376                case 0:
40377                  return t.next = 2, this.getHeader();
40378
40379                case 2:
40380                  e = t.sent, r = e._endPosition, n = new Array(e.content.numBlocks), i = 0;
40381
40382                case 6:
40383                  if (!(i < n.length)) {
40384                    t.next = 14;
40385                    break;
40386                  }
40387
40388                  return t.next = 9, this.file.readBlock(r);
40389
40390                case 9:
40391                  n[i] = t.sent, r = n[i]._endPosition;
40392
40393                case 11:
40394                  i += 1, t.next = 6;
40395                  break;
40396
40397                case 14:
40398                  return t.abrupt("return", n);
40399
40400                case 15:
40401                case "end":
40402                  return t.stop();
40403              }
40404            }, t, this);
40405          })), function () {
40406            return y.apply(this, arguments);
40407          })
40408        }, {
40409          key: "getCoreDataBlock",
40410          value: (v = (0, c.default)(f.default.mark(function t() {
40411            var e;
40412            return f.default.wrap(function (t) {
40413              for (;;) switch (t.prev = t.next) {
40414                case 0:
40415                  return t.next = 2, this.getBlocks();
40416
40417                case 2:
40418                  return e = t.sent, t.abrupt("return", e[0]);
40419
40420                case 4:
40421                case "end":
40422                  return t.stop();
40423              }
40424            }, t, this);
40425          })), function () {
40426            return v.apply(this, arguments);
40427          })
40428        }, {
40429          key: "_getBlocksContentIdIndex",
40430          value: (d = (0, c.default)(f.default.mark(function t() {
40431            var e, r;
40432            return f.default.wrap(function (t) {
40433              for (;;) switch (t.prev = t.next) {
40434                case 0:
40435                  return t.next = 2, this.getBlocks();
40436
40437                case 2:
40438                  return e = t.sent, r = {}, (0, p.default)(e).call(e, function (t) {
40439                    "EXTERNAL_DATA" === t.contentType && (r[t.contentId] = t);
40440                  }), t.abrupt("return", r);
40441
40442                case 6:
40443                case "end":
40444                  return t.stop();
40445              }
40446            }, t, this);
40447          })), function () {
40448            return d.apply(this, arguments);
40449          })
40450        }, {
40451          key: "getBlockByContentId",
40452          value: (i = (0, c.default)(f.default.mark(function t(e) {
40453            var r;
40454            return f.default.wrap(function (t) {
40455              for (;;) switch (t.prev = t.next) {
40456                case 0:
40457                  return t.next = 2, this._getBlocksContentIdIndex();
40458
40459                case 2:
40460                  return r = t.sent, t.abrupt("return", r[e]);
40461
40462                case 4:
40463                case "end":
40464                  return t.stop();
40465              }
40466            }, t, this);
40467          })), function (t) {
40468            return i.apply(this, arguments);
40469          })
40470        }, {
40471          key: "getReferenceRegion",
40472          value: (n = (0, c.default)(f.default.mark(function t() {
40473            var e, r, n, i;
40474            return f.default.wrap(function (t) {
40475              for (;;) switch (t.prev = t.next) {
40476                case 0:
40477                  return t.next = 2, this.getHeader();
40478
40479                case 2:
40480                  if (!((e = t.sent.content).refSeqId < 0)) {
40481                    t.next = 5;
40482                    break;
40483                  }
40484
40485                  return t.abrupt("return", void 0);
40486
40487                case 5:
40488                  return t.next = 7, this.container.getCompressionScheme();
40489
40490                case 7:
40491                  if (r = t.sent, !(e.refBaseBlockId >= 0)) {
40492                    t.next = 15;
40493                    break;
40494                  }
40495
40496                  if (n = this.getBlockByContentId(e.refBaseBlockId)) {
40497                    t.next = 12;
40498                    break;
40499                  }
40500
40501                  throw new m("embedded reference specified, but reference block does not exist");
40502
40503                case 12:
40504                  if (!(e.span > n.uncompressedSize)) {
40505                    t.next = 14;
40506                    break;
40507                  }
40508
40509                  throw new m("Embedded reference is too small");
40510
40511                case 14:
40512                  return t.abrupt("return", {
40513                    seq: n.data.toString("utf8"),
40514                    start: e.refSeqStart,
40515                    end: e.refSeqStart + e.refSeqSpan - 1,
40516                    span: e.refSeqSpan
40517                  });
40518
40519                case 15:
40520                  if (!r.referenceRequired && !this.file.fetchReferenceSequenceCallback) {
40521                    t.next = 24;
40522                    break;
40523                  }
40524
40525                  if (this.file.fetchReferenceSequenceCallback) {
40526                    t.next = 18;
40527                    break;
40528                  }
40529
40530                  throw new Error("reference sequence not embedded, and seqFetch callback not provided, cannot fetch reference sequence");
40531
40532                case 18:
40533                  return t.next = 20, this.file.fetchReferenceSequenceCallback(e.refSeqId, e.refSeqStart, e.refSeqStart + e.refSeqSpan - 1);
40534
40535                case 20:
40536                  if ((i = t.sent).length === e.refSeqSpan) {
40537                    t.next = 23;
40538                    break;
40539                  }
40540
40541                  throw new _("seqFetch callback returned a reference sequence of the wrong length");
40542
40543                case 23:
40544                  return t.abrupt("return", {
40545                    seq: i,
40546                    start: e.refSeqStart,
40547                    end: e.refSeqStart + e.refSeqSpan - 1,
40548                    span: e.refSeqSpan
40549                  });
40550
40551                case 24:
40552                  return t.abrupt("return", void 0);
40553
40554                case 25:
40555                case "end":
40556                  return t.stop();
40557              }
40558            }, t, this);
40559          })), function () {
40560            return n.apply(this, arguments);
40561          })
40562        }, {
40563          key: "getAllRecords",
40564          value: function () {
40565            return this.getRecords(function () {
40566              return !0;
40567            });
40568          }
40569        }, {
40570          key: "_fetchRecords",
40571          value: (r = (0, c.default)(f.default.mark(function t() {
40572            var e,
40573                r,
40574                n,
40575                i,
40576                o,
40577                a,
40578                c,
40579                l,
40580                h,
40581                d,
40582                p,
40583                v,
40584                y,
40585                _,
40586                w,
40587                x,
40588                E,
40589                k,
40590                T,
40591                R,
40592                O,
40593                I,
40594                L,
40595                B = this;
40596
40597            return f.default.wrap(function (t) {
40598              for (;;) switch (t.prev = t.next) {
40599                case 0:
40600                  return t.next = 2, this.file.getDefinition();
40601
40602                case 2:
40603                  return e = t.sent, r = e.majorVersion, t.next = 6, this.container.getCompressionScheme();
40604
40605                case 6:
40606                  return n = t.sent, t.next = 9, this.getHeader();
40607
40608                case 9:
40609                  return i = t.sent, t.next = 12, this._getBlocksContentIdIndex();
40610
40611                case 12:
40612                  if (o = t.sent, !(r > 1 && this.file.options.checkSequenceMD5 && i.content.refSeqId >= 0 && "0000000000000000" !== i.content.md5.join(""))) {
40613                    t.next = 23;
40614                    break;
40615                  }
40616
40617                  return t.next = 16, this.getReferenceRegion();
40618
40619                case 16:
40620                  if (!(a = t.sent)) {
40621                    t.next = 23;
40622                    break;
40623                  }
40624
40625                  if (v = a.seq, y = a.start, _ = a.end, w = S(v), x = (0, g.default)(c = i.content.md5).call(c, function (t) {
40626                    return (t < 16 ? "0" : "") + t.toString(16);
40627                  }).join(""), w === x) {
40628                    t.next = 23;
40629                    break;
40630                  }
40631
40632                  throw new m((0, u.default)(l = (0, u.default)(h = (0, u.default)(d = (0, u.default)(p = "MD5 checksum reference mismatch for ref ".concat(i.content.refSeqId, " pos ")).call(p, y, "..")).call(d, _, ". recorded MD5: ")).call(h, x, ", calculated MD5: ")).call(l, w));
40633
40634                case 23:
40635                  return t.next = 25, this.getCoreDataBlock();
40636
40637                case 25:
40638                  E = t.sent, k = {
40639                    lastAlignmentStart: i.content.refSeqStart || 0,
40640                    coreBlock: {
40641                      bitPosition: 7,
40642                      bytePosition: 0
40643                    },
40644                    externalBlocks: {
40645                      getCursor: function (t) {
40646                        return this[t] || (this[t] = {
40647                          bitPosition: 7,
40648                          bytePosition: 0
40649                        }), this[t];
40650                      }
40651                    }
40652                  }, T = function (t) {
40653                    var e = n.getCodecForDataSeries(t);
40654                    if (!e) throw new m("no codec defined for ".concat(t, " data series"));
40655                    return e.decode(B, E, o, k);
40656                  }, R = new Array(i.content.numRecords), O = 0;
40657
40658                case 30:
40659                  if (!(O < R.length)) {
40660                    t.next = 48;
40661                    break;
40662                  }
40663
40664                  t.prev = 31, R[O] = A(this, T, n, i, E, o, k, r, O), R[O].uniqueId = i.contentPosition + i.content.recordCounter + O + 1, t.next = 45;
40665                  break;
40666
40667                case 36:
40668                  if (t.prev = 36, t.t0 = t.catch(31), !(t.t0 instanceof b)) {
40669                    t.next = 44;
40670                    break;
40671                  }
40672
40673                  return console.warn("read attempted beyond end of buffer, file seems truncated."), R = (0, s.default)(R).call(R, function (t) {
40674                    return !!t;
40675                  }), t.abrupt("break", 48);
40676
40677                case 44:
40678                  throw t.t0;
40679
40680                case 45:
40681                  O += 1, t.next = 30;
40682                  break;
40683
40684                case 48:
40685                  for (I = 0; I < R.length; I += 1) (L = R[I].mateRecordNumber) >= 0 && C(R, I, R[I], R[L]);
40686
40687                  return t.abrupt("return", R);
40688
40689                case 50:
40690                case "end":
40691                  return t.stop();
40692              }
40693            }, t, this, [[31, 36]]);
40694          })), function () {
40695            return r.apply(this, arguments);
40696          })
40697        }, {
40698          key: "getRecords",
40699          value: (e = (0, c.default)(f.default.mark(function t(e) {
40700            var r,
40701                n,
40702                i,
40703                u,
40704                l,
40705                h,
40706                d,
40707                p,
40708                v,
40709                y,
40710                m,
40711                b,
40712                _,
40713                w,
40714                x,
40715                E,
40716                S = this;
40717
40718            return f.default.wrap(function (t) {
40719              for (;;) switch (t.prev = t.next) {
40720                case 0:
40721                  return n = this.container.filePosition + this.containerPosition, (i = this.file.featureCache.get(n)) || (i = this._fetchRecords(), this.file.featureCache.set(n, i)), t.t0 = s.default, t.next = 6, i;
40722
40723                case 6:
40724                  if (t.t1 = r = t.sent, t.t2 = r, t.t3 = e, !(u = (0, t.t0)(t.t1).call(t.t2, t.t3)).length || !this.file.fetchReferenceSequenceCallback) {
40725                    t.next = 24;
40726                    break;
40727                  }
40728
40729                  return t.next = 13, this.getHeader();
40730
40731                case 13:
40732                  if (!((l = t.sent).content.refSeqId >= 0 || -2 === l.content.refSeqId)) {
40733                    t.next = 24;
40734                    break;
40735                  }
40736
40737                  return d = l.content.refSeqId >= 0 ? l.content.refSeqId : void 0, t.next = 18, this.container.getCompressionScheme();
40738
40739                case 18:
40740                  for (p = t.sent, v = {}, y = 0; y < u.length; y += 1) m = void 0 !== d ? d : u[y].sequenceId, (b = v[m]) || (b = {
40741                    id: m,
40742                    start: u[y].alignmentStart,
40743                    end: -1 / 0
40744                  }
40744, v[m] = b), (_ = u[y].alignmentStart + (u[y].lengthOnRef || u[y].readLength) - 1) > b.end && (b.end = _), u[y].alignmentStart < b.start && (b.start = u[y].alignmentStart);
40745
40746                  return t.next = 23, a.default.all((0, g.default)(h = (0, o.default)(v)).call(h, function () {
40747                    var t = (0, c.default)(f.default.mark(function t(e) {
40748                      return f.default.wrap(function (t) {
40749                        for (;;) switch (t.prev = t.next) {
40750                          case 0:
40751                            if (!(-1 !== e.id && e.start <= e.end)) {
40752                              t.next = 4;
40753                              break;
40754                            }
40755
40756                            return t.next = 3, S.file.fetchReferenceSequenceCallback(e.id, e.start, e.end);
40757
40758                          case 3:
40759                            e.seq = t.sent;
40760
40761                          case 4:
40762                          case "end":
40763                            return t.stop();
40764                        }
40765                      }, t);
40766                    }));
40767                    return function (e) {
40768                      return t.apply(this, arguments);
40769                    };
40770                  }()));
40771
40772                case 23:
40773                  for (w = 0; w < u.length; w += 1) x = void 0 !== d ? d : u[w].sequenceId, (E = v[x]) && E.seq && u[w].addReferenceSequence(E, p);
40774
40775                case 24:
40776                  return t.abrupt("return", u);
40777
40778                case 25:
40779                case "end":
40780                  return t.stop();
40781              }
40782            }, t, this);
40783          })), function (t) {
40784            return e.apply(this, arguments);
40785          })
40786        }]), t;
40787      }();
40788
40789      (0, p.default)(n = "getHeader getBlocks _getBlocksContentIdIndex".split(" ")).call(n, function (t) {
40790        return E(T, t);
40791      }), t.exports = T;
40792    }, function (t, e, r) {
40793      t.exports = r(336);
40794    }, function (t, e, r) {
40795      r(337);
40796      var n = r(3);
40797      t.exports = n.Object.values;
40798    }, function (t, e, r) {
40799      var n = r(0),
40800          i = r(149).values;
40801      n({
40802        target: "Object",
40803        stat: !0
40804      }, {
40805        values: function (t) {
40806          return i(t);
40807        }
40808      });
40809    }, function (t, e, r) {
40810      t.exports = r(339);
40811    }, function (t, e, r) {
40812      var n = r(340),
40813          i = Array.prototype;
40814
40815      t.exports = function (t) {
40816        var e = t.filter;
40817        return t === i || t instanceof Array && e === i.filter ? n : e;
40818      };
40819    }, function (t, e, r) {
40820      r(341);
40821      var n = r(18);
40822      t.exports = n("Array").filter;
40823    }, function (t, e, r) {
40824
40825      var n = r(0),
40826          i = r(45).filter;
40827      n({
40828        target: "Array",
40829        proto: !0,
40830        forced: !r(68)("filter")
40831      }, {
40832        filter: function (t) {
40833          return i(this, t, arguments.length > 1 ? arguments[1] : void 0);
40834        }
40835      });
40836    }, function (t, e, r) {
40837      t.exports = r(343);
40838    }, function (t, e, r) {
40839      var n = r(344),
40840          i = RegExp.prototype;
40841
40842      t.exports = function (t) {
40843        return !(t === i || t instanceof RegExp) || "flags" in t ? t.flags : n(t);
40844      };
40845    }, function (t, e, r) {
40846      r(345);
40847      var n = r(346);
40848
40849      t.exports = function (t) {
40850        return n.call(t);
40851      };
40852    }, function (t, e) {}, function (t, e, r) {
40853
40854      var n = r(2);
40855
40856      t.exports = function () {
40857        var t = n(this),
40858            e = "";
40859        return t.global && (e += "g"), t.ignoreCase && (e += "i"), t.multiline && (e += "m"), t.dotAll && (e += "s"), t.unicode && (e += "u"), t.sticky && (e += "y"), e;
40860      };
40861    }, function (t, e, r) {
40862      t.exports = r(348);
40863    }, function (t, e, r) {
40864      var n = r(349),
40865          i = Array.prototype;
40866
40867      t.exports = function (t) {
40868        var e = t.map;
40869        return t === i || t instanceof Array && e === i.map ? n : e;
40870      };
40871    }, function (t, e, r) {
40872      r(350);
40873      var n = r(18);
40874      t.exports = n("Array").map;
40875    }, function (t, e, r) {
40876
40877      var n = r(0),
40878          i = r(45).map;
40879      n({
40880        target: "Array",
40881        proto: !0,
40882        forced: !r(68)("map")
40883      }, {
40884        map: function (t) {
40885          return i(this, t, arguments.length > 1 ? arguments[1] : void 0);
40886        }
40887      });
40888    }, function (t, e, r) {
40889      var n = r(151);
40890
40891      t.exports = function (t) {
40892        if (n(t)) {
40893          for (var e = 0, r = new Array(t.length); e < t.length; e++) r[e] = t[e];
40894
40895          return r;
40896        }
40897      };
40898    }, function (t, e, r) {
40899      t.exports = r(353);
40900    }, function (t, e, r) {
40901      r(354);
40902      var n = r(3);
40903      t.exports = n.Array.isArray;
40904    }, function (t, e, r) {
40905      r(0)({
40906        target: "Array",
40907        stat: !0
40908      }, {
40909        isArray: r(53)
40910      });
40911    }, function (t, e, r) {
40912      t.exports = r(356);
40913    }, function (t, e, r) {
40914      t.exports = r(357);
40915    }, function (t, e, r) {
40916      r(46), r(358);
40917      var n = r(3);
40918      t.exports = n.Array.from;
40919    }, function (t, e, r) {
40920      var n = r(0),
40921          i = r(359);
40922      n({
40923        target: "Array",
40924        stat: !0,
40925        forced: !r(121)(function (t) {
40926          Array.from(t);
40927        })
40928      }, {
40929        from: i
40930      });
40931    }, function (t, e, r) {
40932
40933      var n = r(15),
40934          i = r(22),
40935          o = r(120),
40936          a = r(119),
40937          s = r(29),
40938          u = r(87),
40939          f = r(90);
40940
40941      t.exports = function (t) {
40942        var e,
40943            r,
40944            c,
40945            l,
40946            h = i(t),
40947            d = "function" == typeof this ? this : Array,
40948            p = arguments.length,
40949            g = p > 1 ? arguments[1] : void 0,
40950            v = void 0 !== g,
40951            y = 0,
40952            m = f(h);
40953        if (v && (g = n(g, p > 2 ? arguments[2] : void 0, 2)), null == m || d == Array && a(m)) for (r = new d(e = s(h.length)); e > y; y++) u(r, y, v ? g(h[y], y) : h[y]);else for (l = m.call(h), r = new d(); !(c = l.next()).done; y++) u(r, y, v ? o(l, g, [c.value, y], !0) : c.value);
40954        return r.length = y, r;
40955      };
40956    }, function (t, e, r) {
40957      r(41), r(46), t.exports = r(361);
40958    }, function (t, e, r) {
40959      var n = r(67),
40960          i = r(6),
40961          o = r(35),
40962          a = i("iterator");
40963
40964      t.exports = function (t) {
40965        var e = Object(t);
40966        return void 0 !== e[a] || "@@iterator" in e || o.hasOwnProperty(n(e));
40967      };
40968    }, function (t, e) {
40969      t.exports = function () {
40970        throw new TypeError("Invalid attempt to spread non-iterable instance");
40971      };
40972    }, function (t, e, r) {
40973
40974      (function (e) {
40975        var n = r(1),
40976            i = n(r(37)),
40977            o = n(r(364)),
40978            a = n(r(16)),
40979            s = n(r(99)),
40980            u = n(r(101)),
40981            f = n(r(59)),
40982            c = n(r(154)),
40983            l = n(r(376)),
40984            h = n(r(380)),
40985            d = n(r(48)),
40986            p = n(r(387)),
40987            g = r(146),
40988            v = r(9),
40989            y = v.CramMalformedError,
40990            m = v.CramUnimplementedError,
40991            b = r(389),
40992            _ = r(100);
40993
40994        function w(t) {
40995          var e = (0, p.default)(t).call(t, 0);
40996          return -1 === e ? t.toString("utf8") : t.toString("utf8", 0, e);
40997        }
40998
40999        function x(t, r) {
41000          if (r.readInt32LE || (r = e.from(r)), "Z" === t) return w(r);
41001          if ("A" === t) return String.fromCharCode(r[0]);
41002
41003          if ("I" === t) {
41004            var n = g.fromBytesLE(r);
41005            if (n.greaterThan(h.default) || n.lessThan(l.default)) throw new m("integer overflow");
41006            return n.toNumber();
41007          }
41008
41009          if ("i" === t) return r.readInt32LE(0);
41010          if ("s" === t) return r.readInt16LE(0);
41011          if ("S" === t) return r.readUInt16LE(0);
41012          if ("c" === t) return r.readInt8(0);
41013          if ("C" === t) return r.readUInt8(0);
41014          if ("f" === t) return r.readFloatLE(0);
41015
41016          if ("H" === t) {
41017            var i = w(r);
41018            return (0, c.default)(i.replace(/^0x/, ""), 16);
41019          }
41020
41021          if ("B" === t) return function (t) {
41022            var e = String.fromCharCode(t[0]),
41023                r = t.readInt32LE(1),
41024                n = {
41025              c: ["readInt8", 1],
41026              C: ["readUInt8", 1],
41027              s: ["readInt16LE", 2],
41028              S: ["readUInt16LE", 2],
41029              i: ["readInt32LE", 4],
41030              I: ["readUInt32LE", 4],
41031              f: ["readFloatLE", 4]
41032            }[e];
41033            if (!n) throw new y("invalid tag value array type '".concat(e, "'"));
41034
41035            for (var i = (0, d.default)(n, 2), o = i[0], a = i[1], s = new Array(r), u = 5, f = 0; f < r; f += 1) s[f] = t[o](u), u += a;
41036
41037            return s;
41038          }(r);
41039          throw new y("Unrecognized tag type ".concat(t));
41040        }
41041
41042        function E(t) {
41043          if (t instanceof e) return w(t);
41044
41045          if (t.length && (0, p.default)(t)) {
41046            if (!t[t.length - 1]) {
41047              var r = (0, p.default)(t).call(t, 0);
41048              return String.fromCharCode.apply(String, (0, f.default)((0, u.default)(t).call(t, 0, r)));
41049            }
41050
41051            return String.fromCharCode.apply(String, (0, f.default)(t));
41052          }
41053
41054          return String(t);
41055        }
41056
41057        t.exports = function (t, e, r, n, u, f, c, l, h) {
41058          var p = new b();
41059
41060          if (p.flags = e("BF"), p.cramFlags = e("CF"), l > 1 && -2 === n.content.refSeqId ? p.sequenceId = e("RI") : p.sequenceId = n.content.refSeqId, p.readLength = e("RL"), p.alignmentStart = e("AP"), r.APdelta && (p.alignmentStart += c.lastAlignmentStart), c.lastAlignmentStart = p.alignmentStart, p.readGroupId = e("RG"), r.readNamesIncluded && (p.readName = E(e("RN"))), p.isDetached()) {
41061            var g = {};
41062            g.flags = e("MF"), r.readNamesIncluded || (g.readName = E(e("RN")), p.readName = g.readName), g.sequenceId = e("NS"), g.alignmentStart = e("NP"), ((0, s.default)(g) || g.sequenceId > -1) && (p.mate = g), p.templateSize = e("TS"), (0, s.default)(g) & _.CRAM_M_UNMAP && (p.flags |= _.BAM_FMUNMAP), (0, s.default)(g) & _.CRAM_M_REVERSE && (p.flags |= _.BAM_FMREVERSE);
41063          } else p.hasMateDownStream() && (p.mateRecordNumber = e("NF") + h + 1);
41064
41065          var v = e("TL");
41066          if (v < 0) throw new y("invalid TL index");
41067
41068          for (var m = r.getTagNames(v), w = m.length, S = 0; S < w; S += 1) {
41069            var k = m[S],
41070                A = k.substr(0, 2),
41071                C = k.substr(2, 1),
41072                T = r.getCodecForTag(k);
41073            if (!T) throw new y("no codec defined for auxiliary tag ".concat(k));
41074            var R = T.decode(t, u, f, c);
41075            p.tags[A] = x(C, R);
41076          }
41077
41078          if (p.isSegmentUnmapped()) {
41079            if (p.isUnknownBases()) p.readBases = null, p.qualityScores = null;else {
41080              for (var O = new Array(p.readLength), I = 0; I < O.length; I += 1) O[I] = e("BA");
41081
41082              if (p.readBases = String.fromCharCode.apply(String, O), p.isPreservingQualityScores()) {
41083                for (var L = 0; L < O.length; L += 1) O[L] = e("QS");
41084
41085                p.qualityScores = O;
41086              }
41087            }
41088          } else {
41089            var B,
41090                P = e("FN");
41091            P && (p.readFeatures = function (t, e, r, n, i) {
41092              var o = 0,
41093                  a = t.alignmentStart - 1,
41094                  s = new Array(e);
41095
41096              function u(t) {
41097                var e = (0, d.default)(t, 2),
41098                    n = e[0],
41099                    i = e[1],
41100                    o = r(i);
41101                return "character" === n ? String.fromCharCode(o) : "string" === n ? o.toString("utf8") : "numArray" === n ? o.toArray() : o;
41102              }
41103
41104              for (var f = 0; f < e; f += 1) {
41105                var c = String.fromCharCode(r("FC")),
41106                    l = r("FP"),
41107                    h = {
41108                  code: c
41109                },
41110                    p = {
41111                  B: ["character", "BA"],
41112                  S: ["string", i > 1 ? "SC" : "IN"],
41113                  X: ["number", "BS"],
41114                  D: ["number", "DL"],
41115                  I: ["string", "IN"],
41116                  i: ["character", "BA"],
41117                  b: ["string", "BB"],
41118                  q: ["numArray", "QQ"],
41119                  Q: ["number", "QS"],
41120                  H: ["number", "HC"],
41121                  P: ["number", "PD"],
41122                  N: ["number", "RS"]
41123                }[c];
41124                if (!p) throw new y('invalid read feature code "'.concat(c, '"'));
41125                h.data = u(p);
41126                var g = {
41127                  B: ["number", "QS"]
41128                }[c];
41129                g && (h.data = [h.data, u(g)]), o += l, h.pos = o, a += l, h.refPos = a, "D" === c || "N" === c ? a += h.data : "I" === c || "S" === c ? a -= h.data.length : "i" === c && (a -= 1), s[f] = h;
41130              }
41131
41132              return s;
41133            }(p, P, e, 0, l));
41134            var F,
41135                N = p.readLength;
41136            if (p.readFeatures && (0, a.default)(B = p.readFeatures).call(B, function (t) {
41137              var e = t.code,
41138                  r = t.data;
41139              "D" === e || "N" === e ? N += r : "I" === e || "S" === e ? N -= r.length : "i" === e && (N -= 1);
41140            }), (0, o.default)(N)) console.warn("".concat(p.readName || (0, i.default)(F = "".concat(p.sequenceId, ":")).call(F, p.alignmentStart), " record has invalid read features")), N = p.readLength;
41141
41142            if (p.lengthOnRef = N, p.mappingQuality = e("MQ"), p.isPreservingQualityScores()) {
41143              for (var M = new Array(p.readLength), j = 0; j < M.length; j += 1) M[j] = e("QS");
41144
41145              p.qualityScores = M;
41146            }
41147          }
41148          return p;
41149        };
41150      }).call(this, r(19).Buffer);
41151    }, function (t, e, r) {
41152      t.exports = r(365);
41153    }, function (t, e, r) {
41154      t.exports = r(366);
41155    }, function (t, e, r) {
41156      r(367);
41157      var n = r(3);
41158      t.exports = n.Number.isNaN;
41159    }, function (t, e, r) {
41160      r(0)({
41161        target: "Number",
41162        stat: !0
41163      }, {
41164        isNaN: function (t) {
41165          return t != t;
41166        }
41167      });
41168    }, function (t, e, r) {
41169      t.exports = r(369);
41170    }, function (t, e, r) {
41171      var n = r(370),
41172          i = Array.prototype;
41173
41174      t.exports = function (t) {
41175        var e = t.slice;
41176        return t === i || t instanceof Array && e === i.slice ? n : e;
41177      };
41178    }, function (t, e, r) {
41179      r(371);
41180      var n = r(18);
41181      t.exports = n("Array").slice;
41182    }, function (t, e, r) {
41183
41184      var n = r(0),
41185          i = r(14),
41186          o = r(53),
41187          a = r(84),
41188          s = r(29),
41189          u = r(28),
41190          f = r(87),
41191          c = r(68),
41192          l = r(6)("species"),
41193          h = [].slice,
41194          d = Math.max;
41195      n({
41196        target: "Array",
41197        proto: !0,
41198        forced: !c("slice")
41199      }, {
41200        slice: function (t, e) {
41201          var r,
41202              n,
41203              c,
41204              p = u(this),
41205              g = s(p.length),
41206              v = a(t, g),
41207              y = a(void 0 === e ? g : e, g);
41208          if (o(p) && ("function" != typeof (r = p.constructor) || r !== Array && !o(r.prototype) ? i(r) && null === (r = r[l]) && (r = void 0) : r = void 0, r === Array || void 0 === r)) return h.call(p, v, y);
41209
41210          for (n = new (void 0 === r ? Array : r)(d(y - v, 0)), c = 0; v < y; v++, c++) v in p && f(n, c, p[v]);
41211
41212          return n.length = c, n;
41213        }
41214      });
41215    }, function (t, e, r) {
41216      t.exports = r(373);
41217    }, function (t, e, r) {
41218      r(374);
41219      var n = r(3);
41220      t.exports = n.Number.parseInt;
41221    }, function (t, e, r) {
41222      var n = r(0),
41223          i = r(155);
41224      n({
41225        target: "Number",
41226        stat: !0,
41227        forced: Number.parseInt != i
41228      }, {
41229        parseInt: i
41230      });
41231    }, function (t, e, r) {
41232      var n = r(49),
41233          i = "[" + r(156) + "]",
41234          o = RegExp("^" + i + i + "*"),
41235          a = RegExp(i + i + "*$"),
41236          s = function (t) {
41237        return function (e) {
41238          var r = String(n(e));
41239          return 1 & t && (r = r.replace(o, "")), 2 & t && (r = r.replace(a, "")), r;
41240        };
41241      };
41242
41243      t.exports = {
41244        start: s(1),
41245        end: s(2),
41246        trim: s(3)
41247      };
41248    }, function (t, e, r) {
41249      t.exports = r(377);
41250    }, function (t, e, r) {
41251      t.exports = r(378);
41252    }, function (t, e, r) {
41253      r(379), t.exports = -9007199254740991;
41254    }, function (t, e, r) {
41255      r(0)({
41256        target: "Number",
41257        stat: !0
41258      }, {
41259        MIN_SAFE_INTEGER: -9007199254740991
41260      });
41261    }, function (t, e, r) {
41262      t.exports = r(381);
41263    }, function (t, e, r) {
41264      t.exports = r(382);
41265    }, function (t, e, r) {
41266      r(383), t.exports = 9007199254740991;
41267    }, function (t, e, r) {
41268      r(0)({
41269        target: "Number",
41270        stat: !0
41271      }, {
41272        MAX_SAFE_INTEGER: 9007199254740991
41273      });
41274    }, function (t, e, r) {
41275      var n = r(385),
41276          i = r(153);
41277
41278      t.exports = function (t, e) {
41279        if (i(Object(t)) || "[object Arguments]" === Object.prototype.toString.call(t)) {
41280          var r = [],
41281              o = !0,
41282              a = !1,
41283              s = void 0;
41284
41285          try {
41286            for (var u, f = n(t); !(o = (u = f.next()).done) && (r.push(u.value), !e || r.length !== e); o = !0);
41287          } catch (t) {
41288            a = !0, s = t;
41289          } finally {
41290            try {
41291              o || null == f.return || f.return();
41292            } finally {
41293              if (a) throw s;
41294            }
41295          }
41296
41297          return r;
41298        }
41299      };
41300    }, function (t, e, r) {
41301      t.exports = r(386);
41302    }, function (t, e, r) {
41303      r(41), r(46), t.exports = r(142);
41304    }, function (t, e, r) {
41305      t.exports = r(388);
41306    }, function (t, e, r) {
41307      t.exports = r(143);
41308    }, function (t, e, r) {
41309
41310      var n = r(1),
41311          i = n(r(98)),
41312          o = n(r(16)),
41313          a = n(r(99)),
41314          s = n(r(7)),
41315          u = n(r(10)),
41316          f = n(r(59)),
41317          c = r(100);
41318      var l = {
41319        a: 0,
41320        A: 0,
41321        c: 1,
41322        C: 1,
41323        g: 2,
41324        G: 2,
41325        t: 3,
41326        T: 3,
41327        n: 4,
41328        N: 4
41329      };
41330
41331      var h = function () {
41332        function t() {
41333          (0, s.default)(this, t), this.tags = {};
41334        }
41335
41336        return (0, u.default)(t, [{
41337          key: "isPaired",
41338          value: function () {
41339            return !!((0, a.default)(this) & c.BAM_FPAIRED);
41340          }
41341        }, {
41342          key: "isProperlyPaired",
41343          value: function () {
41344            return !!((0, a.default)(this) & c.BAM_FPROPER_PAIR);
41345          }
41346        }, {
41347          key: "isSegmentUnmapped",
41348          value: function () {
41349            return !!((0, a.default)(this) & c.BAM_FUNMAP);
41350          }
41351        }, {
41352          key: "isMateUnmapped",
41353          value: function () {
41354            return !!((0, a.default)(this) & c.BAM_FMUNMAP);
41355          }
41356        }, {
41357          key: "isReverseComplemented",
41358          value: function () {
41359            return !!((0, a.default)(this) & c.BAM_FREVERSE);
41360          }
41361        }, {
41362          key: "isMateReverseComplemented",
41363          value: function () {
41364            return !!((0, a.default)(this) & c.BAM_FMREVERSE);
41365          }
41366        }, {
41367          key: "isRead1",
41368          value: function () {
41369            return !!((0, a.default)(this) & c.BAM_FREAD1);
41370          }
41371        }, {
41372          key: "isRead2",
41373          value: function () {
41374            return !!((0, a.default)(this) & c.BAM_FREAD2);
41375          }
41376        }, {
41377          key: "isSecondary",
41378          value: function () {
41379            return !!((0, a.default)(this) & c.BAM_FSECONDARY);
41380          }
41381        }, {
41382          key: "isFailedQc",
41383          value: function () {
41384            return !!((0, a.default)(this) & c.BAM_FQCFAIL);
41385          }
41386        }, {
41387          key: "isDuplicate",
41388          value: function () {
41389            return !!((0, a.default)(this) & c.BAM_FDUP);
41390          }
41391        }, {
41392          key: "isSupplementary",
41393          value: function () {
41394            return !!((0, a.default)(this) & c.BAM_FSUPPLEMENTARY);
41395          }
41396        }, {
41397          key: "isDetached",
41398          value: function () {
41399            return !!(this.cramFlags & c.CRAM_FLAG_DETACHED);
41400          }
41401        }, {
41402          key: "hasMateDownStream",
41403          value: function () {
41404            return !!(this.cramFlags & c.CRAM_FLAG_MATE_DOWNSTREAM);
41405          }
41406        }, {
41407          key: "isPreservingQualityScores",
41408          value: function () {
41409            return !!(this.cramFlags & c.CRAM_FLAG_PRESERVE_QUAL_SCORES);
41410          }
41411        }, {
41412          key: "isUnknownBases",
41413          value: function () {
41414            return !!(this.cramFlags & c.CRAM_FLAG_NO_SEQ);
41415          }
41416        }, {
41417          key: "getReadBases",
41418          value: function () {
41419            return !this.readBases && this._refRegion && (this.readBases = function (t, e) {
41420              if ((t.lengthOnRef || t.readLength) && !t.isUnknownBases()) {
41421                var r = t.alignmentStart - e.start;
41422                if (!t.readFeatures) return e.seq.substr(r, t.lengthOnRef).toUpperCase();
41423
41424                for (var n = "", i = r, o = 0; n.length < t.readLength;) if (o < t.readFeatures.length) {
41425                  var a = t.readFeatures[o];
41426                  if ("Q" === a.code || "q" === a.code) o += 1;else if (a.pos === n.length + 1) {
41427                    if (o += 1, "b" === a.code) {
41428                      var s = a.data.split(","),
41429                          u = String.fromCharCode.apply(String, (0, f.default)(s));
41430                      n += u, i += u.length;
41431                    } else "B" === a.code ? (n += a.data[0], i += 1) : "X" === a.code ? (n += a.sub, i += 1) : "I" === a.code ? n += a.data : "D" === a.code ? i += a.data : "i" === a.code ? n += a.data : "N" === a.code ? i += a.data : "S" === a.code ? n += a.data : "P" === a.code || a.code;
41432                  } else if (o < t.readFeatures.length) {
41433                    var c = e.seq.substr(i, t.readFeatures[o].pos - n.length - 1);
41434                    n += c, i += c.length;
41435                  }
41436                } else {
41437                  var l = e.seq.substr(i, t.readLength - n.length);
41438                  n += l, i += l.length;
41439                }
41440
41441                return n.toUpperCase();
41442              }
41443            }(this, this._refRegion)), this.readBases;
41444          }
41445        }, {
41446          key: "getPairOrientation",
41447          value: function () {
41448            if (!this.isSegmentUnmapped() && this.isPaired() && !this.isMateUnmapped() && this.mate && this.sequenceId === this.mate.sequenceId) {
41449              var t = this.isReverseComplemented() ? "R" : "F",
41450                  e = this.isMateReverseComplemented() ? "R" : "F",
41451                  r = " ",
41452                  n = " ";
41453              this.isRead1() ? (r = "1", n = "2") : this.isRead2() && (r = "2", n = "1");
41454              var i = [],
41455                  o = this.templateLength || this.templateSize;
41456              return this.alignmentStart > this.mate.alignmentStart && o > 0 && (o = -o), o > 0 ? (i[0] = t, i[1] = r, i[2] = e, i[3] = n) : (i[2] = t, i[3] = r, i[0] = e, i[1] = n), i.join("");
41457            }
41458
41459            return null;
41460          }
41461        }, {
41462          key: "addReferenceSequence",
41463          value: function (t, e) {
41464            var r;
41465            this.readFeatures && (0, o.default)(r = this.readFeatures).call(r, function (r) {
41466              "X" === r.code && function (t, e, r, n) {
41467                if (e) {
41468                  var i = n.refPos - e.start,
41469                      o = e.seq.charAt(i);
41470                  o && (n.ref = o);
41471                  var a = l[o];
41472                  void 0 === a && (a = 4);
41473                  var s = r.substitutionMatrix[a][n.data];
41474                  s && (n.sub = s);
41475                }
41476              }(0, t, e, r);
41477            });
41478            !this.readBases && t.start <= this.alignmentStart && t.end >= this.alignmentStart + (this.lengthOnRef || this.readLength) - 1 && (this._refRegion = t);
41479          }
41480        }, {
41481          key: "toJSON",
41482          value: function () {
41483            var t,
41484                e = this,
41485                r = {};
41486            return (0, o.default)(t = (0, i.default)(this)).call(t, function (t) {
41487              "_" !== t.charAt(0) && (r[t] = e[t]);
41488            }), r.readBases = this.getReadBases(), r;
41489          }
41490        }]), t;
41491      }();
41492
41493      t.exports = h;
41494    }, function (t, e, r) {
41495
41496      var n = r(1),
41497          i = n(r(98)),
41498          o = n(r(16)),
41499          a = n(r(75)),
41500          s = n(r(7)),
41501          u = n(r(10)),
41502          f = r(9).CramMalformedError,
41503          c = r(391).instantiateCodec,
41504          l = {
41505        BF: "int",
41506        CF: "int",
41507        RI: "int",
41508        RL: "int",
41509        AP: "int",
41510        RG: "int",
41511        MF: "int",
41512        NS: "int",
41513        NP: "int",
41514        TS: "int",
41515        NF: "int",
41516        TC: "byte",
41517        TN: "int",
41518        FN: "int",
41519        FC: "byte",
41520        FP: "int",
41521        BS: "byte",
41522        IN: "byteArray",
41523        SC: "byteArray",
41524        DL: "int",
41525        BA: "byte",
41526        BB: "byteArray",
41527        RS: "int",
41528        PD: "int",
41529        HC: "int",
41530        MQ: "int",
41531        RN: "byteArray",
41532        QS: "byte",
41533        QQ: "byteArray",
41534        TL: "int",
41535        TM: "ignore",
41536        TV: "ignore"
41537      };
41538
41539      var h = function () {
41540        function t(e) {
41541          (0, s.default)(this, t), (0, a.default)(this, e), this.readNamesIncluded = e.preservation.RN, this.APdelta = e.preservation.AP, this.referenceRequired = !!e.preservation.RR, this.tagIdsDictionary = e.preservation.TD, this.substitutionMatrix = function (t) {
41542            for (var e = new Array(5), r = 0; r < 5; r += 1) e[r] = new Array(4);
41543
41544            return e[0][t[0] >> 6 & 3] = "C", e[0][t[0] >> 4 & 3] = "G", e[0][t[0] >> 2 & 3] = "T", e[0][t[0] >> 0 & 3] = "N", e[1][t[1] >> 6 & 3] = "A", e[1][t[1] >> 4 & 3] = "G", e[1][t[1] >> 2 & 3] = "T", e[1][t[1] >> 0 & 3] = "N", e[2][t[2] >>
41544 6 & 3] = "A", e[2][t[2] >> 4 & 3] = "C", e[2][t[2] >> 2 & 3] = "T", e[2][t[2] >> 0 & 3] = "N", e[3][t[3] >> 6 & 3] = "A", e[3][t[3] >> 4 & 3] = "C", e[3][t[3] >> 2 & 3] = "G", e[3][t[3] >> 0 & 3] = "N", e[4][t[4] >> 6 & 3] = "A", e[4][t[4] >> 4 & 3] = "C", e[4][t[4] >> 2 & 3] = "G", e[4][t[4] >> 0 & 3] = "T", e;
41545          }(e.preservation.SM), this.dataSeriesCodecCache = {}, this.tagCodecCache = {};
41546        }
41547
41548        return (0, u.default)(t, [{
41549          key: "getCodecForTag",
41550          value: function (t) {
41551            if (!this.tagCodecCache[t]) {
41552              var e = this.tagEncoding[t];
41553              e && (this.tagCodecCache[t] = c(e, "byteArray"));
41554            }
41555
41556            return this.tagCodecCache[t];
41557          }
41558        }, {
41559          key: "getTagNames",
41560          value: function (t) {
41561            return this.tagIdsDictionary[t];
41562          }
41563        }, {
41564          key: "getCodecForDataSeries",
41565          value: function (t) {
41566            if (!this.dataSeriesCodecCache[t]) {
41567              var e = this.dataSeriesEncoding[t];
41568
41569              if (e) {
41570                var r = l[t];
41571                if (!r) throw new f("data series name ".concat(t, " not defined in file compression header"));
41572                this.dataSeriesCodecCache[t] = c(e, r);
41573              }
41574            }
41575
41576            return this.dataSeriesCodecCache[t];
41577          }
41578        }, {
41579          key: "toJSON",
41580          value: function () {
41581            var t,
41582                e = this,
41583                r = {};
41584            return (0, o.default)(t = (0, i.default)(this)).call(t, function (t) {
41585              /Cache$/.test(t) || (r[t] = e[t]);
41586            }), r;
41587          }
41588        }]), t;
41589      }();
41590
41591      t.exports = h;
41592    }, function (t, e, r) {
41593
41594      var n = r(9).CramUnimplementedError,
41595          i = r(392),
41596          o = r(413),
41597          a = r(414),
41598          s = r(415),
41599          u = r(416),
41600          f = r(417),
41601          c = {
41602        1: o,
41603        3: i,
41604        4: s,
41605        5: a,
41606        6: u,
41607        7: r(418),
41608        9: f
41609      };
41610
41611      function l(t) {
41612        return c[t];
41613      }
41614
41615      t.exports = {
41616        getCodecClassWithId: l,
41617        instantiateCodec: function t(e, r) {
41618          var i = l("ignore" === r ? 0 : e.codecId);
41619          if (!i) throw new n("no codec implemented for codec ID ".concat(e.codecId));
41620          return new i(e.parameters, r, t);
41621        }
41622      };
41623    }, function (t, e, r) {
41624
41625      var n = r(1),
41626          i = n(r(97)),
41627          o = n(r(59)),
41628          a = n(r(77)),
41629          s = n(r(148)),
41630          u = n(r(159)),
41631          f = n(r(48)),
41632          c = n(r(102)),
41633          l = n(r(16)),
41634          h = n(r(103)),
41635          d = n(r(403)),
41636          p = n(r(7)),
41637          g = n(r(10)),
41638          v = n(r(32)),
41639          y = n(r(27)),
41640          m = n(r(33)),
41641          b = r(9).CramMalformedError;
41642
41643      var _ = function (t) {
41644        function e() {
41645          var t,
41646              r,
41647              n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
41648              i = arguments.length > 1 ? arguments[1] : void 0;
41649          if ((0, p.default)(this, e), r = (0, v.default)(this, (0, y.default)(e).call(this, n, i)), !(0, d.default)(t = ["byte", "int"]).call(t, r.dataType)) throw new TypeError("".concat(r.dataType, " decoding not yet implemented by HUFFMAN_INT codec"));
41650          return r.buildCodeBook(), r.buildCodes(), r.buildCaches(), 0 === r.sortedCodes[0].bitLength && (r._decode = r._decodeZeroLengthCode), r;
41651        }
41652
41653        return (0, m.default)(e, t), (0, g.default)(e, [{
41654          key: "buildCodeBook",
41655          value: function () {
41656            for (var t = this, e = new Array(this.parameters.numCodes), r = 0; r < this.parameters.numCodes; r += 1) e[r] = {
41657              symbol: this.parameters.symbols[r],
41658              bitLength: this.parameters.bitLengths[r]
41659            };
41660
41661            e = (0, h.default)(e).call(e, function (t, e) {
41662              return t.bitLength - e.bitLength || t.symbol - e.symbol;
41663            }), this.codeBook = {}, (0, l.default)(e).call(e, function (e) {
41664              t.codeBook[e.bitLength] || (t.codeBook[e.bitLength] = []), t.codeBook[e.bitLength].push(e.symbol);
41665            });
41666          }
41667        }, {
41668          key: "buildCodes",
41669          value: function () {
41670            var t,
41671                e = this;
41672            this.codes = {};
41673            var r = 0,
41674                n = -1;
41675            (0, l.default)(t = (0, c.default)(this.codeBook)).call(t, function (t) {
41676              var i = (0, f.default)(t, 2),
41677                  o = i[0],
41678                  a = i[1];
41679              o = (0, u.default)(o, 10), (0, l.default)(a).call(a, function (t) {
41680                var i = {
41681                  bitLength: o,
41682                  value: t
41683                };
41684                n += 1;
41685                var a,
41686                    s,
41687                    u = o - r;
41688                if (n <<= u, i.bitCode = n, r += u, 16843009 * ((s = (858993459 & (s = (a = n) - (a >> 1) & 1431655765)) + (s >> 2 & 858993459)) + (s >> 4) & 252645135) >> 24 > o) throw new b("Symbol out of range");
41689                e.codes[t] = i;
41690              });
41691            });
41692          }
41693        }, {
41694          key: "buildCaches",
41695          value: function () {
41696            var t, e, r, n, u, f;
41697            this.sortedCodes = (0, h.default)(t = (0, s.default)(this.codes)).call(t, function (t, e) {
41698              return t.bitLength - e.bitLength || t.bitCode - e.bitCode;
41699            }), this.sortedByValue = (0, h.default)(e = (0, s.default)(this.codes)).call(e, function (t, e) {
41700              return t.value - e.value;
41701            }), this.sortedValuesByBitCode = (0, a.default)(r = this.sortedCodes).call(r, function (t) {
41702              return t.value;
41703            }), this.sortedBitCodes = (0, a.default)(n = this.sortedCodes).call(n, function (t) {
41704              return t.bitCode;
41705            }), this.sortedBitLengthsByBitCode = (0, a.default)(u = this.sortedCodes).call(u, function (t) {
41706              return t.bitLength;
41707            });
41708            var c = Math.max.apply(Math, (0, o.default)(this.sortedBitCodes));
41709            this.bitCodeToValue = (0, i.default)(f = new Array(c + 1)).call(f, -1);
41710
41711            for (var l = 0; l < this.sortedBitCodes.length; l += 1) this.bitCodeToValue[this.sortedCodes[l].bitCode] = l;
41712          }
41713        }, {
41714          key: "decode",
41715          value: function (t, e, r, n) {
41716            return this._decode(t, e, n.coreBlock);
41717          }
41718        }, {
41719          key: "_decodeZeroLengthCode",
41720          value: function () {
41721            return this.sortedCodes[0].value;
41722          }
41723        }, {
41724          key: "_decode",
41725          value: function (t, e, r) {
41726            for (var n = e.content, i = 0, o = 0, a = 0; a < this.sortedCodes.length; a += 1) {
41727              var s = this.sortedCodes[a].bitLength;
41728              o <<= s - i, o |= this._getBits(n, r, s - i), i = s;
41729              var u = this.bitCodeToValue[o];
41730              if (u > -1 && this.sortedBitLengthsByBitCode[u] === s) return this.sortedValuesByBitCode[u];
41731
41732              for (var f = a; this.sortedCodes[f + 1].bitLength === s && f < this.sortedCodes.length; f += 1) a += 1;
41733            }
41734
41735            throw new b("Huffman symbol not found.");
41736          }
41737        }]), e;
41738      }
41738(r(40));
41739
41740      t.exports = _;
41741    }, function (t, e, r) {
41742      t.exports = r(394);
41743    }, function (t, e, r) {
41744      r(395);
41745      var n = r(3);
41746      t.exports = n.parseInt;
41747    }, function (t, e, r) {
41748      var n = r(0),
41749          i = r(155);
41750      n({
41751        global: !0,
41752        forced: parseInt != i
41753      }, {
41754        parseInt: i
41755      });
41756    }, function (t, e, r) {
41757      t.exports = r(397);
41758    }, function (t, e, r) {
41759      r(398);
41760      var n = r(3);
41761      t.exports = n.Object.entries;
41762    }, function (t, e, r) {
41763      var n = r(0),
41764          i = r(149).entries;
41765      n({
41766        target: "Object",
41767        stat: !0
41768      }, {
41769        entries: function (t) {
41770          return i(t);
41771        }
41772      });
41773    }, function (t, e, r) {
41774      t.exports = r(400);
41775    }, function (t, e, r) {
41776      var n = r(401),
41777          i = Array.prototype;
41778
41779      t.exports = function (t) {
41780        var e = t.sort;
41781        return t === i || t instanceof Array && e === i.sort ? n : e;
41782      };
41783    }, function (t, e, r) {
41784      r(402);
41785      var n = r(18);
41786      t.exports = n("Array").sort;
41787    }, function (t, e, r) {
41788
41789      var n = r(0),
41790          i = r(5),
41791          o = r(22),
41792          a = r(12),
41793          s = r(54),
41794          u = [].sort,
41795          f = [1, 2, 3],
41796          c = a(function () {
41797        f.sort(void 0);
41798      }),
41799          l = a(function () {
41800        f.sort(null);
41801      }),
41802          h = s("sort");
41803      n({
41804        target: "Array",
41805        proto: !0,
41806        forced: c || !l || h
41807      }, {
41808        sort: function (t) {
41809          return void 0 === t ? u.call(o(this)) : u.call(o(this), i(t));
41810        }
41811      });
41812    }, function (t, e, r) {
41813      t.exports = r(404);
41814    }, function (t, e, r) {
41815      t.exports = r(405);
41816    }, function (t, e, r) {
41817      var n = r(406),
41818          i = r(408),
41819          o = Array.prototype,
41820          a = String.prototype;
41821
41822      t.exports = function (t) {
41823        var e = t.includes;
41824        return t === o || t instanceof Array && e === o.includes ? n : "string" == typeof t || t === a || t instanceof String && e === a.includes ? i : e;
41825      };
41826    }, function (t, e, r) {
41827      r(407);
41828      var n = r(18);
41829      t.exports = n("Array").includes;
41830    }, function (t, e, r) {
41831
41832      var n = r(0),
41833          i = r(82).includes,
41834          o = r(78);
41835      n({
41836        target: "Array",
41837        proto: !0
41838      }, {
41839        includes: function (t) {
41840          return i(this, t, arguments.length > 1 ? arguments[1] : void 0);
41841        }
41842      }), o("includes");
41843    }, function (t, e, r) {
41844      r(409);
41845      var n = r(18);
41846      t.exports = n("String").includes;
41847    }, function (t, e, r) {
41848
41849      var n = r(0),
41850          i = r(410),
41851          o = r(49);
41852      n({
41853        target: "String",
41854        proto: !0,
41855        forced: !r(412)("includes")
41856      }, {
41857        includes: function (t) {
41858          return !!~String(o(this)).indexOf(i(t), arguments.length > 1 ? arguments[1] : void 0);
41859        }
41860      });
41861    }, function (t, e, r) {
41862      var n = r(411);
41863
41864      t.exports = function (t) {
41865        if (n(t)) throw TypeError("The method doesn't accept regular expressions");
41866        return t;
41867      };
41868    }, function (t, e, r) {
41869      var n = r(14),
41870          i = r(34),
41871          o = r(6)("match");
41872
41873      t.exports = function (t) {
41874        var e;
41875        return n(t) && (void 0 !== (e = t[o]) ? !!e : "RegExp" == i(t));
41876      };
41877    }, function (t, e, r) {
41878      var n = r(6)("match");
41879
41880      t.exports = function (t) {
41881        var e = /./;
41882
41883        try {
41884          "/./"[t](e);
41885        } catch (r) {
41886          try {
41887            return e[n] = !1, "/./"[t](e);
41888          } catch (t) {}
41889        }
41890
41891        return !1;
41892      };
41893    }, function (t, e, r) {
41894
41895      var n = r(1),
41896          i = n(r(48)),
41897          o = n(r(7)),
41898          a = n(r(10)),
41899          s = n(r(32)),
41900          u = n(r(27)),
41901          f = n(r(33)),
41902          c = r(9),
41903          l = c.CramUnimplementedError,
41904          h = c.CramMalformedError,
41905          d = c.CramBufferOverrunError,
41906          p = r(40),
41907          g = r(58).parseItf8,
41908          v = function (t) {
41909        function e() {
41910          var t,
41911              r = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
41912              n = arguments.length > 1 ? arguments[1] : void 0;
41913          if ((0, o.default)(this, e), "int" === (t = (0, s.default)(this, (0, u.default)(e).call(this, r, n))).dataType) t._decodeData = t._decodeInt;else {
41914            if ("byte" !== t.dataType) throw new l("".concat(t.dataType, " decoding not yet implemented by EXTERNAL codec"));
41915            t._decodeData = t._decodeByte;
41916          }
41917          return t;
41918        }
41919
41920        return (0, f.default)(e, t), (0, a.default)(e, [{
41921          key: "decode",
41922          value: function (t, e, r, n) {
41923            var i = this.parameters.blockContentId,
41924                o = r[i];
41925            if (!o) throw new h("no block found with content ID ".concat(i));
41926            var a = n.externalBlocks.getCursor(i);
41927            return this._decodeData(o, a);
41928          }
41929        }, {
41930          key: "_decodeInt",
41931          value: function (t, e) {
41932            var r = g(t.content, e.bytePosition),
41933                n = (0, i.default)(r, 2),
41934                o = n[0],
41935                a = n[1];
41936            return e.bytePosition += a, o;
41937          }
41938        }, {
41939          key: "_decodeByte",
41940          value: function (t, e) {
41941            if (e.bytePosition >= t.content.length) throw new d("attempted to read beyond end of block. this file seems truncated.");
41942            var r = t.content[e.bytePosition];
41943            return e.bytePosition += 1, r;
41944          }
41945        }]), e;
41946      }(p);
41947
41948      t.exports = v;
41949    }, function (t, e, r) {
41950
41951      var n = r(1),
41952          i = n(r(101)),
41953          o = n(r(7)),
41954          a = n(r(10)),
41955          s = n(r(32)),
41956          u = n(r(27)),
41957          f = n(r(33)),
41958          c = r(9),
41959          l = c.CramBufferOverrunError,
41960          h = c.CramMalformedError,
41961          d = function (t) {
41962        function e() {
41963          var t,
41964              r = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
41965              n = arguments.length > 1 ? arguments[1] : void 0;
41966          if ((0, o.default)(this, e), t = (0, s.default)(this, (0, u.default)(e).call(this, r, n)), "byteArray" !== n) throw new TypeError("byteArrayStop codec does not support data type ".concat(n));
41967          return t._decode = t._decodeByteArray, t;
41968        }
41969
41970        return (0, f.default)(e, t), (0, a.default)(e, [{
41971          key: "decode",
41972          value: function (t, e, r, n) {
41973            var i = this.parameters.blockContentId,
41974                o = r[i];
41975            if (!o) throw new h("no block found with content ID ".concat(i));
41976            var a = n.externalBlocks.getCursor(i);
41977            return this._decode(o, a);
41978          }
41979        }, {
41980          key: "_decodeByteArray",
41981          value: function (t, e) {
41982            for (var r = t.content, n = this.parameters.stopByte, o = e.bytePosition, a = e.bytePosition; r[a] !== n && a < r.length;) {
41983              if (a === r.length) throw new l("byteArrayStop reading beyond length of data buffer?");
41984              a += 1;
41985            }
41986
41987            return e.bytePosition = a + 1, (0, i.default)(r).call(r, o, a);
41988          }
41989        }]), e;
41990      }
41990(r(40));
41991
41992      t.exports = d;
41993    }, function (t, e, r) {
41994
41995      var n,
41996          i = r(1),
41997          o = i(r(16)),
41998          a = i(r(7)),
41999          s = i(r(10)),
42000          u = i(r(32)),
42001          f = i(r(27)),
42002          c = i(r(33)),
42003          l = r(58).tinyMemoize,
42004          h = function (t) {
42005        function e() {
42006          var t,
42007              r = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
42008              n = arguments.length > 1 ? arguments[1] : void 0,
42009              i = arguments.length > 2 ? arguments[2] : void 0;
42010          if ((0, a.default)(this, e), (t = (0, u.default)(this, (0, f.default)(e).call(this, r, n))).instantiateCodec = i, "byteArray" !== n) throw new TypeError("byteArrayLength does not support data type ".concat(n));
42011          return t;
42012        }
42013
42014        return (0, c.default)(e, t), (0, s.default)(e, [{
42015          key: "decode",
42016          value: function (t, e, r, n) {
42017            for (var i = this._getLengthCodec().decode(t, e, r, n), o = this._getDataCodec(), a = new Array(i), s = 0; s < i; s += 1) a[s] = o.decode(t, e, r, n);
42018
42019            return a;
42020          }
42021        }, {
42022          key: "_getLengthCodec",
42023          value: function () {
42024            var t = this.parameters.lengthsEncoding;
42025            return this.instantiateCodec(t, "int");
42026          }
42027        }, {
42028          key: "_getDataCodec",
42029          value: function () {
42030            var t = this.parameters.valuesEncoding;
42031            return this.instantiateCodec(t, "byte");
42032          }
42033        }]), e;
42034      }(r(40));
42035
42036      (0, o.default)(n = "_getLengthCodec _getDataCodec".split(" ")).call(n, function (t) {
42037        return l(h, t);
42038      }), t.exports = h;
42039    }, function (t, e, r) {
42040
42041      var n = r(1),
42042          i = n(r(7)),
42043          o = n(r(10)),
42044          a = n(r(32)),
42045          s = n(r(27)),
42046          u = n(r(33)),
42047          f = r(9).CramUnimplementedError,
42048          c = function (t) {
42049        function e() {
42050          var t,
42051              r = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
42052              n = arguments.length > 1 ? arguments[1] : void 0;
42053          if ((0, i.default)(this, e), "int" !== (t = (0, a.default)(this, (0, s.default)(e).call(this, r, n))).dataType) throw new f("".concat(t.dataType, " decoding not yet implemented by BETA codec"));
42054          return t;
42055        }
42056
42057        return (0, u.default)(e, t), (0, o.default)(e, [{
42058          key: "decode",
42059          value: function (t, e, r, n) {
42060            return this._getBits(e.content, n.coreBlock, this.parameters.length) - this.parameters.offset;
42061          }
42062        }]), e;
42063      }(r(40));
42064
42065      t.exports = c;
42066    }, function (t, e, r) {
42067
42068      var n = r(1),
42069          i = n(r(7)),
42070          o = n(r(10)),
42071          a = n(r(32)),
42072          s = n(r(27)),
42073          u = n(r(33)),
42074          f = r(9).CramUnimplementedError,
42075          c = function (t) {
42076        function e() {
42077          var t,
42078              r = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
42079              n = arguments.length > 1 ? arguments[1] : void 0;
42080          if ((0, i.default)(this, e), "int" !== (t = (0, a.default)(this, (0, s.default)(e).call(this, r, n))).dataType) throw new f("".concat(t.dataType, " decoding not yet implemented by GAMMA codec"));
42081          return t;
42082        }
42083
42084        return (0, u.default)(e, t), (0, o.default)(e, [{
42085          key: "decode",
42086          value: function (t, e, r, n) {
42087            for (var i = 1; 0 === this._getBits(e.content, n.coreBlock, 1);) i += 1;
42088
42089            return (this._getBits(e.content, n.coreBlock, i - 1) | 1 << i - 1) - this.parameters.offset;
42090          }
42091        }]), e;
42092      }(r(40));
42093
42094      t.exports = c;
42095    }, function (t, e, r) {
42096
42097      var n = r(1),
42098          i = n(r(7)),
42099          o = n(r(10)),
42100          a = n(r(32)),
42101          s = n(r(27)),
42102          u = n(r(33)),
42103          f = r(9).CramUnimplementedError,
42104          c = function (t) {
42105        function e() {
42106          var t,
42107              r = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
42108              n = arguments.length > 1 ? arguments[1] : void 0;
42109          if ((0, i.default)(this, e), "int" !== (t = (0, a.default)(this, (0, s.default)(e).call(this, r, n))).dataType) throw new f("".concat(t.dataType, " decoding not yet implemented by SUBEXP codec"));
42110          return t;
42111        }
42112
42113        return (0, u.default)(e, t), (0, o.default)(e, [{
42114          key: "decode",
42115          value: function (t, e, r, n) {
42116            for (var i, o, a = 0; this._getBits(e.content, n.coreBlock, 1);) a += 1;
42117
42118            return 0 === a ? (i = this.parameters.K, o = this._getBits(e.content, n.coreBlock, i)) : o = 1 << (i = a + this.parameters.K - 1) | this._getBits(e.content, n.coreBlock, i), o - this.parameters.offset;
42119          }
42120        }]), e;
42121      }
42121(r(40));
42122
42123      t.exports = c;
42124    }, function (t, e, r) {
42125
42126      var n = r(420),
42127          i = r(422);
42128
42129      function o() {
42130        this.protocol = null, this.slashes = null, this.auth = null, this.host = null, this.port = null, this.hostname = null, this.hash = null, this.search = null, this.query = null, this.pathname = null, this.path = null, this.href = null;
42131      }
42132
42133      e.parse = b, e.resolve = function (t, e) {
42134        return b(t, !1, !0).resolve(e);
42135      }, e.resolveObject = function (t, e) {
42136        return t ? b(t, !1, !0).resolveObject(e) : e;
42137      }, e.format = function (t) {
42138        i.isString(t) && (t = b(t));
42139        return t instanceof o ? t.format() : o.prototype.format.call(t);
42140      }, e.Url = o;
42141      var a = /^([a-z0-9.+-]+:)/i,
42142          s = /:[0-9]*$/,
42143          u = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
42144          f = ["{", "}", "|", "\\", "^", "`"].concat(["<", ">", '"', "`", " ", "\r", "\n", "\t"]),
42145          c = ["'"].concat(f),
42146          l = ["%", "/", "?", ";", "#"].concat(c),
42147          h = ["/", "?", "#"],
42148          d = /^[+a-z0-9A-Z_-]{0,63}$/,
42149          p = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
42150          g = {
42151        javascript: !0,
42152        "javascript:": !0
42153      },
42154          v = {
42155        javascript: !0,
42156        "javascript:": !0
42157      },
42158          y = {
42159        http: !0,
42160        https: !0,
42161        ftp: !0,
42162        gopher: !0,
42163        file: !0,
42164        "http:": !0,
42165        "https:": !0,
42166        "ftp:": !0,
42167        "gopher:": !0,
42168        "file:": !0
42169      },
42170          m = r(423);
42171
42172      function b(t, e, r) {
42173        if (t && i.isObject(t) && t instanceof o) return t;
42174        var n = new o();
42175        return n.parse(t, e, r), n;
42176      }
42177
42178      o.prototype.parse = function (t, e, r) {
42179        if (!i.isString(t)) throw new TypeError("Parameter 'url' must be a string, not " + typeof t);
42180        var o = t.indexOf("?"),
42181            s = -1 !== o && o < t.indexOf("#") ? "?" : "#",
42182            f = t.split(s);
42183        f[0] = f[0].replace(/\\/g, "/");
42184        var b = t = f.join(s);
42185
42186        if (b = b.trim(), !r && 1 === t.split("#").length) {
42187          var _ = u.exec(b);
42188
42189          if (_) return this.path = b, this.href = b, this.pathname = _[1], _[2] ? (this.search = _[2], this.query = e ? m.parse(this.search.substr(1)) : this.search.substr(1)) : e && (this.search = "", this.query = {}), this;
42190        }
42191
42192        var w = a.exec(b);
42193
42194        if (w) {
42195          var x = (w = w[0]).toLowerCase();
42196          this.protocol = x, b = b.substr(w.length);
42197        }
42198
42199        if (r || w || b.match(/^\/\/[^@\/]+@[^@\/]+/)) {
42200          var E = "//" === b.substr(0, 2);
42201          !E || w && v[w] || (b = b.substr(2), this.slashes = !0);
42202        }
42203
42204        if (!v[w] && (E || w && !y[w])) {
42205          for (var S, k, A = -1, C = 0; C < h.length; C++) {
42206            -1 !== (T = b.indexOf(h[C])) && (-1 === A || T < A) && (A = T);
42207          }
42208
42209          -1 !== (k = -1 === A ? b.lastIndexOf("@") : b.lastIndexOf("@", A)) && (S = b.slice(0, k), b = b.slice(k + 1), this.auth = decodeURIComponent(S)), A = -1;
42210
42211          for (C = 0; C < l.length; C++) {
42212            var T;
42213            -1 !== (T = b.indexOf(l[C])) && (-1 === A || T < A) && (A = T);
42214          }
42215
42216          -1 === A && (A = b.length), this.host = b.slice(0, A), b = b.slice(A), this.parseHost(), this.hostname = this.hostname || "";
42217          var R = "[" === this.hostname[0] && "]" === this.hostname[this.hostname.length - 1];
42218          if (!R) for (var O = this.hostname.split(/\./), I = (C = 0, O.length); C < I; C++) {
42219            var L = O[C];
42220
42221            if (L && !L.match(d)) {
42222              for (var B = "", P = 0, F = L.length; P < F; P++) L.charCodeAt(P) > 127 ? B += "x" : B += L[P];
42223
42224              if (!B.match(d)) {
42225                var N = O.slice(0, C),
42226                    M = O.slice(C + 1),
42227                    j = L.match(p);
42228                j && (N.push(j[1]), M.unshift(j[2])), M.length && (b = "/" + M.join(".") + b), this.hostname = N.join(".");
42229                break;
42230              }
42231            }
42232          }
42233          this.hostname.length > 255 ? this.hostname = "" : this.hostname = this.hostname.toLowerCase(), R || (this.hostname = n.toASCII(this.hostname));
42234          var z = this.port ? ":" + this.port : "",
42235              U = this.hostname || "";
42236          this.host = U + z, this.href += this.host, R && (this.hostname = this.hostname.substr(1, this.hostname.length - 2), "/" !== b[0] && (b = "/" + b));
42237        }
42238
42239        if (!g[x]) for (C = 0, I = c.length; C < I; C++) {
42240          var D = c[C];
42241
42242          if (-1 !== b.indexOf(D)) {
42243            var q = encodeURIComponent(D);
42244            q === D && (q = escape(D)), b = b.split(D).join(q);
42245          }
42246        }
42247        var Z = b.indexOf("#");
42248        -1 !== Z && (this.hash = b.substr(Z), b = b.slice(0, Z));
42249        var H = b.indexOf("?");
42250
42251        if (-1 !== H ? (this.search = b.substr(H), this.query = b.substr(H + 1), e && (this.query = m.parse(this.query)), b = b.slice(0, H)) : e && (this.search = "", this.query = {}), b && (this.pathname = b), y[x] && this.hostname && !this.pathname && (this.pathname = "/"), this.pathname || this.search) {
42252          z = this.pathname || "";
42253          var V = this.search || "";
42254          this.path = z + V;
42255        }
42256
42257        return this.href = this.format(), this;
42258      }, o.prototype.format = function () {
42259        var t = this.auth || "";
42260        t && (t = (t = encodeURIComponent(t)).replace(/%3A/i, ":"), t += "@");
42261        var e = this.protocol || "",
42262            r = this.pathname || "",
42263            n = this.hash || "",
42264            o = !1,
42265            a = "";
42266        this.host ? o = t + this.host : this.hostname && (o = t + (-1 === this.hostname.indexOf(":") ? this.hostname : "[" + this.hostname + "]"), this.port && (o += ":" + this.port)), this.query && i.isObject(this.query) && Object.keys(this.query).length && (a = m.stringify(this.query));
42267        var s = this.search || a && "?" + a || "";
42268        return e && ":" !== e.substr(-1) && (e += ":"), this.slashes || (!e || y[e]) && !1 !== o ? (o = "//" + (o || ""), r && "/" !== r.charAt(0) && (r = "/" + r)) : o || (
42268o = ""), n && "#" !== n.charAt(0) && (n = "#" + n), s && "?" !== s.charAt(0) && (s = "?" + s), e + o + (r = r.replace(/[?#]/g, function (t) {
42269          return encodeURIComponent(t);
42270        })) + (s = s.replace("#", "%23")) + n;
42271      }, o.prototype.resolve = function (t) {
42272        return this.resolveObject(b(t, !1, !0)).format();
42273      }, o.prototype.resolveObject = function (t) {
42274        if (i.isString(t)) {
42275          var e = new o();
42276          e.parse(t, !1, !0), t = e;
42277        }
42278
42279        for (var r = new o(), n = Object.keys(this), a = 0; a < n.length; a++) {
42280          var s = n[a];
42281          r[s] = this[s];
42282        }
42283
42284        if (r.hash = t.hash, "" === t.href) return r.href = r.format(), r;
42285
42286        if (t.slashes && !t.protocol) {
42287          for (var u = Object.keys(t), f = 0; f < u.length; f++) {
42288            var c = u[f];
42289            "protocol" !== c && (r[c] = t[c]);
42290          }
42291
42292          return y[r.protocol] && r.hostname && !r.pathname && (r.path = r.pathname = "/"), r.href = r.format(), r;
42293        }
42294
42295        if (t.protocol && t.protocol !== r.protocol) {
42296          if (!y[t.protocol]) {
42297            for (var l = Object.keys(t), h = 0; h < l.length; h++) {
42298              var d = l[h];
42299              r[d] = t[d];
42300            }
42301
42302            return r.href = r.format(), r;
42303          }
42304
42305          if (r.protocol = t.protocol, t.host || v[t.protocol]) r.pathname = t.pathname;else {
42306            for (var p = (t.pathname || "").split("/"); p.length && !(t.host = p.shift()););
42307
42308            t.host || (t.host = ""), t.hostname || (t.hostname = ""), "" !== p[0] && p.unshift(""), p.length < 2 && p.unshift(""), r.pathname = p.join("/");
42309          }
42310
42311          if (r.search = t.search, r.query = t.query, r.host = t.host || "", r.auth = t.auth, r.hostname = t.hostname || t.host, r.port = t.port, r.pathname || r.search) {
42312            var g = r.pathname || "",
42313                m = r.search || "";
42314            r.path = g + m;
42315          }
42316
42317          return r.slashes = r.slashes || t.slashes, r.href = r.format(), r;
42318        }
42319
42320        var b = r.pathname && "/" === r.pathname.charAt(0),
42321            _ = t.host || t.pathname && "/" === t.pathname.charAt(0),
42322            w = _ || b || r.host && t.pathname,
42323            x = w,
42324            E = r.pathname && r.pathname.split("/") || [],
42325            S = (p = t.pathname && t.pathname.split("/") || [], r.protocol && !y[r.protocol]);
42326
42327        if (S && (r.hostname = "", r.port = null, r.host && ("" === E[0] ? E[0] = r.host : E.unshift(r.host)), r.host = "", t.protocol && (t.hostname = null, t.port = null, t.host && ("" === p[0] ? p[0] = t.host : p.unshift(t.host)), t.host = null), w = w && ("" === p[0] || "" === E[0])), _) r.host = t.host || "" === t.host ? t.host : r.host, r.hostname = t.hostname || "" === t.hostname ? t.hostname : r.hostname, r.search = t.search, r.query = t.query, E = p;else if (p.length) E || (E = []), E.pop(), E = E.concat(p), r.search = t.search, r.query = t.query;else if (!i.isNullOrUndefined(t.search)) {
42328          if (S) r.hostname = r.host = E.shift(), (R = !!(r.host && r.host.indexOf("@") > 0) && r.host.split("@")) && (r.auth = R.shift(), r.host = r.hostname = R.shift());
42329          return r.search = t.search, r.query = t.query, i.isNull(r.pathname) && i.isNull(r.search) || (r.path = (r.pathname ? r.pathname : "") + (r.search ? r.search : "")), r.href = r.format(), r;
42330        }
42331        if (!E.length) return r.pathname = null, r.search ? r.path = "/" + r.search : r.path = null, r.href = r.format(), r;
42332
42333        for (var k = E.slice(-1)[0], A = (r.host || t.host || E.length > 1) && ("." === k || ".." === k) || "" === k, C = 0, T = E.length; T >= 0; T--) "." === (k = E[T]) ? E.splice(T, 1) : ".." === k ? (E.splice(T, 1), C++) : C && (E.splice(T, 1), C--);
42334
42335        if (!w && !x) for (; C--; C) E.unshift("..");
42336        !w || "" === E[0] || E[0] && "/" === E[0].charAt(0) || E.unshift(""), A && "/" !== E.join("/").substr(-1) && E.push("");
42337        var R,
42338            O = "" === E[0] || E[0] && "/" === E[0].charAt(0);
42339        S && (r.hostname = r.host = O ? "" : E.length ? E.shift() : "", (
42339R = !!(r.host && r.host.indexOf("@") > 0) && r.host.split("@")) && (r.auth = R.shift(), r.host = r.hostname = R.shift()));
42340        return (w = w || r.host && E.length) && !O && E.unshift(""), E.length ? r.pathname = E.join("/") : (r.pathname = null, r.path = null), i.isNull(r.pathname) && i.isNull(r.search) || (r.path = (r.pathname ? r.pathname : "") + (r.search ? r.search : "")), r.auth = t.auth || r.auth, r.slashes = r.slashes || t.slashes, r.href = r.format(), r;
42341      }, o.prototype.parseHost = function () {
42342        var t = this.host,
42343            e = s.exec(t);
42344        e && (":" !== (e = e[0]) && (this.port = e.substr(1)), t = t.substr(0, t.length - e.length)), t && (this.hostname = t);
42345      };
42346    }, function (t, e, r) {
42347      (function (t, n) {
42348        var i;
42349        /*! https://mths.be/punycode v1.4.1 by @mathias */
42350
42351        !function (o) {
42352          e && e.nodeType, t && t.nodeType;
42353          var a = "object" == typeof n && n;
42354          a.global !== a && a.window !== a && a.self;
42355          var s,
42356              u = 2147483647,
42357              f = 36,
42358              c = 1,
42359              l = 26,
42360              h = 38,
42361              d = 700,
42362              p = 72,
42363              g = 128,
42364              v = "-",
42365              y = /^xn--/,
42366              m = /[^\x20-\x7E]/,
42367              b = /[\x2E\u3002\uFF0E\uFF61]/g,
42368              _ = {
42369            overflow: "Overflow: input needs wider integers to process",
42370            "not-basic": "Illegal input >= 0x80 (not a basic code point)",
42371            "invalid-input": "Invalid input"
42372          },
42373              w = f - c,
42374              x = Math.floor,
42375              E = String.fromCharCode;
42376
42377          function S(t) {
42378            throw new RangeError(_[t]);
42379          }
42380
42381          function k(t, e) {
42382            for (var r = t.length, n = []; r--;) n[r] = e(t[r]);
42383
42384            return n;
42385          }
42386
42387          function A(t, e) {
42388            var r = t.split("@"),
42389                n = "";
42390            return r.length > 1 && (n = r[0] + "@", t = r[1]), n + k((t = t.replace(b, ".")).split("."), e).join(".");
42391          }
42392
42393          function C(t) {
42394            for (var e, r, n = [], i = 0, o = t.length; i < o;) (e = t.charCodeAt(i++)) >= 55296 && e <= 56319 && i < o ? 56320 == (64512 & (r = t.charCodeAt(i++))) ? n.push(((1023 & e) << 10) + (1023 & r) + 65536) : (n.push(e), i--) : n.push(e);
42395
42396            return n;
42397          }
42398
42399          function T(t) {
42400            return k(t, function (t) {
42401              var e = "";
42402              return t > 65535 && (e += E((t -= 65536) >>> 10 & 1023 | 55296), t = 56320 | 1023 & t), e += E(t);
42403            }).join("");
42404          }
42405
42406          function R(t, e) {
42407            return t + 22 + 75 * (t < 26) - ((0 != e) << 5);
42408          }
42409
42410          function O(t, e, r) {
42411            var n = 0;
42412
42413            for (t = r ? x(t / d) : t >> 1, t += x(t / e); t > w * l >> 1; n += f) t = x(t / w);
42414
42415            return x(n + (w + 1) * t / (t + h));
42416          }
42417
42418          function I(t) {
42419            var e,
42420                r,
42421                n,
42422                i,
42423                o,
42424                a,
42425                s,
42426                h,
42427                d,
42428                y,
42429                m,
42430                b = [],
42431                _ = t.length,
42432                w = 0,
42433                E = g,
42434                k = p;
42435
42436            for ((r = t.lastIndexOf(v)) < 0 && (r = 0), n = 0; n < r; ++n) t.charCodeAt(n) >= 128 && S("not-basic"), b.push(t.charCodeAt(n));
42437
42438            for (i = r > 0 ? r + 1 : 0; i < _;) {
42439              for (o = w, a = 1, s = f; i >= _ && S("invalid-input"), ((h = (m = t.charCodeAt(i++)) - 48 < 10 ? m - 22 : m - 65 < 26 ? m - 65 : m - 97 < 26 ? m - 97 : f) >= f || h > x((u - w) / a)) && S("overflow"), w += h * a, !(h < (d = s <= k ? c : s >= k + l ? l : s - k)); s += f) a > x(u / (y = f - d)) && S("overflow"), a *= y;
42440
42441              k = O(w - o, e = b.length + 1, 0 == o), x(w / e) > u - E && S("overflow"), E += x(w / e), w %= e, b.splice(w++, 0, E);
42442            }
42443
42444            return T(b);
42445          }
42446
42447          function L(t) {
42448            var e,
42449                r,
42450                n,
42451                i,
42452                o,
42453                a,
42454                s,
42455                h,
42456                d,
42457                y,
42458                m,
42459                b,
42460                _,
42461                w,
42462                k,
42463                A = [];
42464
42465            for (b = (t = C(t)).length, e = g, r = 0, o = p, a = 0; a < b; ++a) (m = t[a]) < 128 && A.push(E(m));
42466
42467            for (n = i = A.length, i && A.push(v); n < b;) {
42468              for (s = u, a = 0; a < b; ++a) (m = t[a]) >= e && m < s && (s = m);
42469
42470              for (s - e > x((u - r) / (_ = n + 1)) && S("overflow"), r += (s - e) * _, e = s, a = 0; a < b; ++a) if ((m = t[a]) < e && ++r > u && S("overflow"), m == e) {
42471                for (h = r, d = f; !(h < (y = d <= o ? c : d >= o + l ? l : d - o)); d += f) k = h - y, w = f - y, A.push(E(R(y + k % w, 0))), h = x(k / w);
42472
42473                A.push(E(R(h, 0))), o = O(r, _, n == i), r = 0, ++n;
42474              }
42475
42476              ++r, ++e;
42477            }
42478
42479            return A.join("");
42480          }
42481
42482          s = {
42483            version: "1.4.1",
42484            ucs2: {
42485              decode: C,
42486              encode: T
42487            },
42488            decode: I,
42489            encode: L,
42490            toASCII: function (t) {
42491              return A(t, function (t) {
42492                return m.test(t) ? "xn--" + L(t) : t;
42493              });
42494            },
42495            toUnicode: function (t) {
42496              return A(t, function (t) {
42497                return y.test(t) ? I(t.slice(4).toLowerCase()) : t;
42498              });
42499            }
42500          }, void 0 === (i = function () {
42501            return s;
42502          }.call(e, r, e, t)) || (t.exports = i);
42503        }();
42504      }).call(this, r(421)(t), r(23));
42505    }, function (t, e) {
42506      t.exports = function (t) {
42507        return t.webpackPolyfill || (t.deprecate = function () {}, t.paths = [], t.children || (t.children = []), Object.defineProperty(t, "loaded", {
42508          enumerable: !0,
42509          get: function () {
42510            return t.l;
42511          }
42512        }), Object.defineProperty(t, "id", {
42513          enumerable: !0,
42514          get: function () {
42515            return t.i;
42516          }
42517        }), t.webpackPolyfill = 1), t;
42518      };
42519    }, function (t, e, r) {
42520
42521      t.exports = {
42522        isString: function (t) {
42523          return "string" == typeof t;
42524        },
42525        isObject: function (t) {
42526          return "object" == typeof t && null !== t;
42527        },
42528        isNull: function (t) {
42529          return null === t;
42530        },
42531        isNullOrUndefined: function (t) {
42532          return null == t;
42533        }
42534      };
42535    }, function (t, e, r) {
42536
42537      e.decode = e.parse = r(424), e.encode = e.stringify = r(425);
42538    }, function (t, e, r) {
42539
42540      function n(t, e) {
42541        return Object.prototype.hasOwnProperty.call(t, e);
42542      }
42543
42544      t.exports = function (t, e, r, o) {
42545        e = e || "&", r = r || "=";
42546        var a = {};
42547        if ("string" != typeof t || 0 === t.length) return a;
42548        var s = /\+/g;
42549        t = t.split(e);
42550        var u = 1e3;
42551        o && "number" == typeof o.maxKeys && (u = o.maxKeys);
42552        var f = t.length;
42553        u > 0 && f > u && (f = u);
42554
42555        for (var c = 0; c < f; ++c) {
42556          var l,
42557              h,
42558              d,
42559              p,
42560              g = t[c].replace(s, "%20"),
42561              v = g.indexOf(r);
42562          v >= 0 ? (l = g.substr(0, v), h = g.substr(v + 1)) : (l = g, h = ""), d = decodeURIComponent(l), p = decodeURIComponent(h), n(a, d) ? i(a[d]) ? a[d].push(p) : a[d] = [a[d], p] : a[d] = p;
42563        }
42564
42565        return a;
42566      };
42567
42568      var i = Array.isArray || function (t) {
42569        return "[object Array]" === Object.prototype.toString.call(t);
42570      };
42571    }, function (t, e, r) {
42572
42573      var n = function (t) {
42574        switch (typeof t) {
42575          case "string":
42576            return t;
42577
42578          case "boolean":
42579            return t ? "true" : "false";
42580
42581          case "number":
42582            return isFinite(t) ? t : "";
42583
42584          default:
42585            return "";
42586        }
42587      };
42588
42589      t.exports = function (t, e, r, s) {
42590        return e = e || "&", r = r || "=", null === t && (t = void 0), "object" == typeof t ? o(a(t), function (a) {
42591          var s = encodeURIComponent(n(a)) + r;
42592          return i(t[a]) ? o(t[a], function (t) {
42593            return s + encodeURIComponent(n(t));
42594          }).join(e) : s + encodeURIComponent(n(t[a]));
42595        }).join(e) : s ? encodeURIComponent(n(s)) + r + encodeURIComponent(n(t)) : "";
42596      };
42597
42598      var i = Array.isArray || function (t) {
42599        return "[object Array]" === Object.prototype.toString.call(t);
42600      };
42601
42602      function o(t, e) {
42603        if (t.map) return t.map(e);
42604
42605        for (var r = [], n = 0; n < t.length; n++) r.push(e(t[n], n));
42606
42607        return r;
42608      }
42609
42610      var a = Object.keys || function (t) {
42611        var e = [];
42612
42613        for (var r in t) Object.prototype.hasOwnProperty.call(t, r) && e.push(r);
42614
42615        return e;
42616      };
42617    }, function (t, e, r) {
42618
42619      (function (e) {
42620        var n = r(1),
42621            i = n(r(30)),
42622            o = n(r(159)),
42623            a = n(r(37)),
42624            s = n(r(31)),
42625            u = n(r(7)),
42626            f = n(r(10)),
42627            c = r(427),
42628            l = r(428),
42629            h = function () {
42630          function t(e) {
42631            var r = this;
42632            (0, u.default)(this, t), this.position = 0, this.url = e, this.cache = new l({
42633              fetch: function (t, e) {
42634                return r._fetch(t, e);
42635              }
42636            });
42637          }
42638
42639          var r, n, h;
42640          return (0, f.default)(t, [{
42641            key: "_fetch",
42642            value: (h = (0, s.default)(i.default.mark(function t(r, n) {
42643              var s, u, f, l, h, d;
42644              return i.default.wrap(function (t) {
42645                for (;;) switch (t.prev = t.next) {
42646                  case 0:
42647                    return u = {}, n < 1 / 0 ? u.range = (0, a.default)(f = "bytes=".concat(r, "-")).call(f, r + n) : n === 1 / 0 && 0 !== r && (u.range = "bytes=".concat(r, "-")), t.next = 4, c(this.url, {
42648                      method: "GET",
42649                      headers: u,
42650                      redirect: "follow",
42651                      mode: "cors"
42652                    });
42653
42654                  case 4:
42655                    if ((200 !== (l = t.sent).status || 0 !== r) && 206 !== l.status) {
42656                      t.next = 14;
42657                      break;
42658                    }
42659
42660                    return t.t0 = e, t.next = 9, l.arrayBuffer();
42661
42662                  case 9:
42663                    return t.t1 = t.sent, h = t.t0.from.call(t.t0, t.t1), (d = /\/(\d+)$/.exec(l.headers.get("content-range")))[1] && (this._stat = {
42664                      size: (0, o.default)(d[1], 10)
42665                    }), t.abrupt("return", h);
42666
42667                  case 14:
42668                    throw new Error((0, a.default)(s = "HTTP ".concat(l.status, " fetching ")).call(s, this.url));
42669
42670                  case 15:
42671                  case "end":
42672                    return t.stop();
42673                }
42674              }, t, this);
42675            })), function (t, e) {
42676              return h.apply(this, arguments);
42677            })
42678          }, {
42679            key: "read",
42680            value: function (t) {
42681              var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 0,
42682                  r = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : 1 / 0,
42683                  n = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : 0,
42684                  i = n;
42685              return null === i && (i = this.position, this.position += r), this.cache.get(t, e, r, n);
42686            }
42687          }, {
42688            key: "readFile",
42689            value: (n = (0, s.default)(i.default.mark(function t() {
42690              var r;
42691              return i.default.wrap(function (t) {
42692                for (;;) switch (t.prev = t.next) {
42693                  case 0:
42694                    return t.next = 2, c(this.url, {
42695                      method: "GET",
42696                      redirect: "follow",
42697                      mode: "cors"
42698                    });
42699
42700                  case 2:
42701                    return r = t.sent, t.t0 = e, t.next = 6, r.arrayBuffer();
42702
42703                  case 6:
42704                    return t.t1 = t.sent, t.abrupt("return", t.t0.from.call(t.t0, t.t1));
42705
42706                  case 8:
42707                  case "end":
42708                    return t.stop();
42709                }
42710              }, t, this);
42711            })), function () {
42712              return n.apply(this, arguments);
42713            })
42714          }, {
42715            key: "stat",
42716            value: (r = (0, s.default)(i.default.mark(function t() {
42717              var r;
42718              return i.default.wrap(function (t) {
42719                for (;;) switch (t.prev = t.next) {
42720                  case 0:
42721                    if (this._stat) {
42722                      t.next = 6;
42723                      break;
42724                    }
42725
42726                    return r = e.allocUnsafe(10), t.next = 4, this.read(r, 0, 10, 0);
42727
42728                  case 4:
42729                    if (this._stat) {
42730                      t.next = 6;
42731                      break;
42732                    }
42733
42734                    throw new Error("unable to determine size of file at ".concat(this.url));
42735
42736                  case 6:
42737                    return t.abrupt("return", this._stat);
42738
42739                  case 7:
42740                  case "end":
42741                    return t.stop();
42742                }
42743              }, t, this);
42744            })), function () {
42745              return r.apply(this, arguments);
42746            })
42747          }]), t;
42748        }();
42749
42750        t.exports = h;
42751      }).call(this, r(19).Buffer);
42752    }, function (t, e) {
42753      var r = function (t) {
42754        function e() {
42755          this.fetch = !1, this.DOMException = t.DOMException;
42756        }
42757
42758        return e.prototype = t, new e();
42759      }("undefined" != typeof self ? self : this);
42760
42761      !function (t) {
42762        !function (e) {
42763          var r = {
42764            searchParams: "URLSearchParams" in t,
42765            iterable: "Symbol" in t && "iterator" in Symbol,
42766            blob: "FileReader" in t && "Blob" in t && function () {
42767              try {
42768                return new Blob(), !0;
42769              } catch (t) {
42770                return !1;
42771              }
42772            }(),
42773            formData: "FormData" in t,
42774            arrayBuffer: "ArrayBuffer" in t
42775          };
42776          if (r.arrayBuffer) var n = ["[object Int8Array]", "[object Uint8Array]", "[object Uint8ClampedArray]", "[object Int16Array]", "[object Uint16Array]", "[object Int32Array]", "[object Uint32Array]", "[object Float32Array]", "[object Float64Array
42776]"],
42777              i = ArrayBuffer.isView || function (t) {
42778            return t && n.indexOf(Object.prototype.toString.call(t)) > -1;
42779          };
42780
42781          function o(t) {
42782            if ("string" != typeof t && (t = String(t)), /[^a-z0-9\-#$%&'*+.^_`|~]/i.test(t)) throw new TypeError("Invalid character in header field name");
42783            return t.toLowerCase();
42784          }
42785
42786          function a(t) {
42787            return "string" != typeof t && (t = String(t)), t;
42788          }
42789
42790          function s(t) {
42791            var e = {
42792              next: function () {
42793                var e = t.shift();
42794                return {
42795                  done: void 0 === e,
42796                  value: e
42797                };
42798              }
42799            };
42800            return r.iterable && (e[Symbol.iterator] = function () {
42801              return e;
42802            }), e;
42803          }
42804
42805          function u(t) {
42806            this.map = {}, t instanceof u ? t.forEach(function (t, e) {
42807              this.append(e, t);
42808            }, this) : Array.isArray(t) ? t.forEach(function (t) {
42809              this.append(t[0], t[1]);
42810            }, this) : t && Object.getOwnPropertyNames(t).forEach(function (e) {
42811              this.append(e, t[e]);
42812            }, this);
42813          }
42814
42815          function f(t) {
42816            if (t.bodyUsed) return Promise.reject(new TypeError("Already read"));
42817            t.bodyUsed = !0;
42818          }
42819
42820          function c(t) {
42821            return new Promise(function (e, r) {
42822              t.onload = function () {
42823                e(t.result);
42824              }, t.onerror = function () {
42825                r(t.error);
42826              };
42827            });
42828          }
42829
42830          function l(t) {
42831            var e = new FileReader(),
42832                r = c(e);
42833            return e.readAsArrayBuffer(t), r;
42834          }
42835
42836          function h(t) {
42837            if (t.slice) return t.slice(0);
42838            var e = new Uint8Array(t.byteLength);
42839            return e.set(new Uint8Array(t)), e.buffer;
42840          }
42841
42842          function d() {
42843            return this.bodyUsed = !1, this._initBody = function (t) {
42844              var e;
42845              this._bodyInit = t, t ? "string" == typeof t ? this._bodyText = t : r.blob && Blob.prototype.isPrototypeOf(t) ? this._bodyBlob = t : r.formData && FormData.prototype.isPrototypeOf(t) ? this._bodyFormData = t : r.searchParams && URLSearchParams.prototype.isPrototypeOf(t) ? this._bodyText = t.toString() : r.arrayBuffer && r.blob && (e = t) && DataView.prototype.isPrototypeOf(e) ? (this._bodyArrayBuffer = h(t.buffer), this._bodyInit = new Blob([this._bodyArrayBuffer])) : r.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(t) || i(t)) ? this._bodyArrayBuffer = h(t) : this._bodyText = t = Object.prototype.toString.call(t) : this._bodyText = "", this.headers.get("content-type") || ("string" == typeof t ? this.headers.set("content-type", "text/plain;charset=UTF-8") : this._bodyBlob && this._bodyBlob.type ? this.headers.set("content-type", this._bodyBlob.type) : r.searchParams && URLSearchParams.prototype.isPrototypeOf(t) && this.headers.set("content-type", "application/x-www-form-urlencoded;charset=UTF-8"));
42846            }, r.blob && (this.blob = function () {
42847              var t = f(this);
42848              if (t) return t;
42849              if (this._bodyBlob) return Promise.resolve(this._bodyBlob);
42850              if (this._bodyArrayBuffer) return Promise.resolve(new Blob([this._bodyArrayBuffer]));
42851              if (this._bodyFormData) throw new Error("could not read FormData body as blob");
42852              return Promise.resolve(new Blob([this._bodyText]));
42853            }, this.arrayBuffer = function () {
42854              return this._bodyArrayBuffer ? f(this) || Promise.resolve(this._bodyArrayBuffer) : this.blob().then(l);
42855            }), this.text = function () {
42856              var t,
42857                  e,
42858                  r,
42859                  n = f(this);
42860              if (n) return n;
42861              if (this._bodyBlob) return t = this._bodyBlob, e = new FileReader(), r = c(e), e.readAsText(t), r;
42862              if (this._bodyArrayBuffer) return Promise.resolve(function (t) {
42863                for (var e = new Uint8Array(t), r = new Array(e.length), n = 0; n < e.length; n++) r[n] = String.fromCharCode(e[n]);
42864
42865                return r.join("");
42866              }(this._bodyArrayBuffer));
42867              if (this._bodyFormData) throw new Error("could not read FormData body as text");
42868              return Promise.resolve(this._bodyText);
42869            }, r.formData && (this.formData = function () {
42870              return this.text().then(v);
42871            }), this.json = function () {
42872              return this.text().then(JSON.parse);
42873            }, this;
42874          }
42875
42876          u.prototype.append = function (t, e) {
42877            t = o(t), e = a(e);
42878            var r = this.map[t];
42879            this.map[t] = r ? r + ", " + e : e;
42880          }, u.prototype.delete = function (t) {
42881            delete this.map[o(t)];
42882          }, u.prototype.get = function (t) {
42883            return t = o(t), this.has(t) ? this.map[t] : null;
42884          }, u.prototype.has = function (t) {
42885            return this.map.hasOwnProperty(o(t));
42886          }, u.prototype.set = function (t, e) {
42887            this.map[o(t)] = a(e);
42888          }, u.prototype.forEach = function (t, e) {
42889            for (var r in this.map) this.map.hasOwnProperty(r) && t.call(e, this.map[r], r, this);
42890          }, u.prototype.keys = function () {
42891            var t = [];
42892            return this.forEach(function (e, r) {
42893              t.push(r);
42894            }), s(t);
42895          }, u.prototype.values = function () {
42896            var t = [];
42897            return this.forEach(function (e) {
42898              t.push(e);
42899            }), s(t);
42900          }, u.prototype.entries = function () {
42901            var t = [];
42902            return this.forEach(function (e, r) {
42903              t.push([r, e]);
42904            }), s(t);
42905          }, r.iterable && (u.prototype[Symbol.iterator] = u.prototype.entries);
42906          var p = ["DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT"];
42907
42908          function g(t, e) {
42909            var r,
42910                n,
42911                i = (e = e || {}).body;
42912
42913            if (t instanceof g) {
42914              if (t.bodyUsed) throw new TypeError("Already read");
42915              this.url = t.url, this.credentials = t.credentials, e.headers || (this.headers = new u(t.headers)), this.method = t.method, this.mode = t.mode, this.signal = t.signal, i || null == t._bodyInit || (i = t._bodyInit, t.bodyUsed = !0);
42916            } else this.url = String(t);
42917
42918            if (this.credentials = e.credentials || this.credentials || "same-origin", !e.headers && this.headers || (this.headers = new u(e.headers)), this.method = (r = e.method || this.method || "GET", n = r.toUpperCase(), p.indexOf(n) > -1 ? n : r), this.mode = e.mode || this.mode || null, this.signal = e.signal || this.signal, this.referrer = null, ("GET" === this.method || "HEAD" === this.method) && i) throw new TypeError("Body not allowed for GET or HEAD requests");
42919
42920            this._initBody(i);
42921          }
42922
42923          function v(t) {
42924            var e = new FormData();
42925            return t.trim().split("&").forEach(function (t) {
42926              if (t) {
42927                var r = t.split("="),
42928                    n = r.shift().replace(/\+/g, " "),
42929                    i = r.join("=").replace(/\+/g, " ");
42930                e.append(decodeURIComponent(n), decodeURIComponent(i));
42931              }
42932            }), e;
42933          }
42934
42935          function y(t, e) {
42936            e || (e = {}), this.type = "default", this.status = void 0 === e.status ? 200 : e.status, this.ok = this.status >= 200 && this.status < 300, this.statusText = "statusText" in e ? e.statusText : "OK", this.headers = new u(e.headers), this.url = e.url || "", this._initBody(t);
42937          }
42938
42939          g.prototype.clone = function () {
42940            return new g(this, {
42941              body: this._bodyInit
42942            });
42943          }, d.call(g.prototype), d.call(y.prototype), y.prototype.clone = function () {
42944            return new y(this._bodyInit, {
42945              status: this.status,
42946              statusText: this.statusText,
42947              headers: new u(this.headers),
42948              url: this.url
42949            });
42950          }, y.error = function () {
42951            var t = new y(null, {
42952              status: 0,
42953              statusText: ""
42954            });
42955            return t.type = "error", t;
42956          };
42957          var m = [301, 302, 303, 307, 308];
42958          y.redirect = function (t, e) {
42959            if (-1 === m.indexOf(e)) throw new RangeError("Invalid status code");
42960            return new y(null, {
42961              status: e,
42962              headers: {
42963                location: t
42964              }
42965            });
42966          }, e.DOMException = t.DOMException;
42967
42968          try {
42969            new e.DOMException();
42970          } catch (t) {
42971            e.DOMException = function (t, e) {
42972              this.message = t, this.name = e;
42973              var r = Error(t);
42974              this.stack = r.stack;
42975            }, e.DOMException.prototype = Object.create(Error.prototype), e.DOMException.prototype.constructor = e.DOMException;
42976          }
42977
42978          function b(t, n) {
42979            return new Promise(function (i, o) {
42980              var a = new g(t, n);
42981              if (a.signal && a.signal.aborted) return o(new e.DOMException("Aborted", "AbortError"));
42982              var s = new XMLHttpRequest();
42983
42984              function f() {
42985                s.abort();
42986              }
42987
42988              s.onload = function () {
42989                var t,
42990                    e,
42991                    r = {
42992                  status: s.status,
42993                  statusText: s.statusText,
42994                  headers: (t = s.getAllResponseHeaders() || "", e = new u(), t.replace(/\r?\n[\t ]+/g, " ").split(/\r?\n/).forEac
42994h(function (t) {
42995                    var r = t.split(":"),
42996                        n = r.shift().trim();
42997
42998                    if (n) {
42999                      var i = r.join(":").trim();
43000                      e.append(n, i);
43001                    }
43002                  }), e)
43003                };
43004                r.url = "responseURL" in s ? s.responseURL : r.headers.get("X-Request-URL");
43005                var n = "response" in s ? s.response : s.responseText;
43006                i(new y(n, r));
43007              }, s.onerror = function () {
43008                o(new TypeError("Network request failed"));
43009              }, s.ontimeout = function () {
43010                o(new TypeError("Network request failed"));
43011              }, s.onabort = function () {
43012                o(new e.DOMException("Aborted", "AbortError"));
43013              }, s.open(a.method, a.url, !0), "include" === a.credentials ? s.withCredentials = !0 : "omit" === a.credentials && (s.withCredentials = !1), "responseType" in s && r.blob && (s.responseType = "blob"), a.headers.forEach(function (t, e) {
43014                s.setRequestHeader(e, t);
43015              }), a.signal && (a.signal.addEventListener("abort", f), s.onreadystatechange = function () {
43016                4 === s.readyState && a.signal.removeEventListener("abort", f);
43017              }), s.send(void 0 === a._bodyInit ? null : a._bodyInit);
43018            });
43019          }
43020
43021          b.polyfill = !0, t.fetch || (t.fetch = b, t.Headers = u, t.Request = g, t.Response = y), e.Headers = u, e.Request = g, e.Response = y, e.fetch = b;
43022        }({});
43023      }(r), delete r.fetch.polyfill, (e = r.fetch).default = r.fetch, e.fetch = r.fetch, e.Headers = r.Headers, e.Request = r.Request, e.Response = r.Response, t.exports = e;
43024    }, function (t, e, r) {
43025
43026      var n = r(1),
43027          i = n(r(30)),
43028          o = n(r(16)),
43029          a = n(r(76)),
43030          s = n(r(31)),
43031          u = n(r(7)),
43032          f = n(r(10)),
43033          c = r(94),
43034          l = function () {
43035        function t(e) {
43036          var r = e.fetch,
43037              n = e.size,
43038              i = void 0 === n ? 1e7 : n,
43039              o = e.chunkSize,
43040              a = void 0 === o ? 32768 : o;
43041          if ((0, u.default)(this, t), !r) throw new Error("fetch function required");
43042          this.fetch = r, this.chunkSize = a, this.lruCache = new c({
43043            maxSize: Math.floor(i / a)
43044          });
43045        }
43046
43047        var e;
43048        return (0, f.default)(t, [{
43049          key: "get",
43050          value: (e = (0, s.default)(i.default.mark(function t(e, r, n, s) {
43051            var u,
43052                f,
43053                c,
43054                l,
43055                h,
43056                d,
43057                p,
43058                g = this;
43059            return i.default.wrap(function (t) {
43060              for (;;) switch (t.prev = t.next) {
43061                case 0:
43062                  if (!(e.length < r + n)) {
43063                    t.next = 2;
43064                    break;
43065                  }
43066
43067                  throw new Error("output buffer not big enough for request");
43068
43069                case 2:
43070                  for (u = Math.floor(s / this.chunkSize), f = Math.floor((s + n) / this.chunkSize), c = new Array(f - u + 1), l = function (t) {
43071                    c[t - u] = g._getChunk(t).then(function (e) {
43072                      return {
43073                        data: e,
43074                        chunkNumber: t
43075                      };
43076                    });
43077                  }, h = u; h <= f; h += 1) l(h);
43078
43079                  return t.next = 9, a.default.all(c);
43080
43081                case 9:
43082                  d = t.sent, p = s - d[0].chunkNumber * this.chunkSize, (0, o.default)(d).call(d, function (t) {
43083                    var i = t.data,
43084                        o = t.chunkNumber,
43085                        a = o * g.chunkSize,
43086                        c = 0,
43087                        l = g.chunkSize,
43088                        h = r + (o - u) * g.chunkSize - p;
43089                    o === u && (h = r, c = p), o === f && (l = s + n - a), i.copy(e, h, c, l);
43090                  });
43091
43092                case 12:
43093                case "end":
43094                  return t.stop();
43095              }
43096            }, t, this);
43097          })), function (t, r, n, i) {
43098            return e.apply(this, arguments);
43099          })
43100        }, {
43101          key: "_getChunk",
43102          value: function (t) {
43103            var e = this.lruCache.get(t);
43104            if (e) return e;
43105            var r = this.fetch(t * this.chunkSize, this.chunkSize);
43106            return this.lruCache.set(t, r), r;
43107          }
43108        }]), t;
43109      }();
43110
43111      t.exports = l;
43112    }, function (t, e, r) {
43113
43114      var n = r(1),
43115          i = n(r(30)),
43116          o = n(r(31)),
43117          a = n(r(7)),
43118          s = n(r(10)),
43119          u = (r(161).promisify, null),
43120          f = u,
43121          c = function () {
43122        function t(e) {
43123          (0, a.default)(this, t), this.position = 0, this.filename = e, this.fd = f(this.filename, "r");
43124        }
43125
43126        var e, r, n;
43127        return (0, s.default)(t, [{
43128          key: "read",
43129          value: (n = (0, o.default)(i.default.mark(function t(e) {
43130            var r,
43131                n,
43132                o,
43133                a = arguments;
43134            return i.default.wrap(function (t) {
43135              for (;;) switch (t.prev = t.next) {
43136                case 0:
43137                  return r = a.length > 1 && void 0 !== a[1] ? a[1] : 0, n = a.length > 2 ? a[2] : void 0, null === (o = a.length >
43137 3 ? a[3] : void 0) && (this.position, this.position += n), t.t0 = null, t.next = 8, this.fd;
43138
43139                case 8:
43140                  return t.t1 = t.sent, t.t2 = e, t.t3 = r, t.t4 = n, t.t5 = o, t.abrupt("return", (0, t.t0)(t.t1, t.t2, t.t3, t.t4, t.t5));
43141
43142                case 14:
43143                case "end":
43144                  return t.stop();
43145              }
43146            }, t, this);
43147          })), function (t) {
43148            return n.apply(this, arguments);
43149          })
43150        }, {
43151          key: "readFile",
43152          value: (r = (0, o.default)(i.default.mark(function t() {
43153            return i.default.wrap(function (t) {
43154              for (;;) switch (t.prev = t.next) {
43155                case 0:
43156                  return t.t0 = null, t.next = 3, this.fd;
43157
43158                case 3:
43159                  return t.t1 = t.sent, t.abrupt("return", (0, t.t0)(t.t1));
43160
43161                case 5:
43162                case "end":
43163                  return t.stop();
43164              }
43165            }, t, this);
43166          })), function () {
43167            return r.apply(this, arguments);
43168          })
43169        }, {
43170          key: "stat",
43171          value: (e = (0, o.default)(i.default.mark(function t() {
43172            return i.default.wrap(function (t) {
43173              for (;;) switch (t.prev = t.next) {
43174                case 0:
43175                  if (this._stat) {
43176                    t.next = 8;
43177                    break;
43178                  }
43179
43180                  return t.t0 = null, t.next = 4, this.fd;
43181
43182                case 4:
43183                  return t.t1 = t.sent, t.next = 7, (0, t.t0)(t.t1);
43184
43185                case 7:
43186                  this._stat = t.sent;
43187
43188                case 8:
43189                  return t.abrupt("return", this._stat);
43190
43191                case 9:
43192                case "end":
43193                  return t.stop();
43194              }
43195            }, t, this);
43196          })), function () {
43197            return e.apply(this, arguments);
43198          })
43199        }]), t;
43200      }();
43201
43202      t.exports = c;
43203    }, function (t, e, r) {
43204
43205      var n = r(1),
43206          i = n(r(48)),
43207          o = n(r(77)),
43208          a = n(r(101)),
43209          s = n(r(431)),
43210          u = n(r(16));
43211      t.exports = {
43212        parseHeaderText: function (t) {
43213          var e = t.split(/\r?\n/),
43214              r = [];
43215          return (0, u.default)(e).call(e, function (t) {
43216            var e = t.split(/\t/),
43217                n = (0, s.default)(e),
43218                u = n[0],
43219                f = (0, a.default)(n).call(n, 1),
43220                c = (0, o.default)(f).call(f, function (t) {
43221              var e = t.split(":", 2),
43222                  r = (0, i.default)(e, 2);
43223              return {
43224                tag: r[0],
43225                value: r[1]
43226              };
43227            });
43228            u && r.push({
43229              tag: u.substr(1),
43230              data: c
43231            });
43232          }), r;
43233        }
43234      };
43235    }, function (t, e, r) {
43236      var n = r(157),
43237          i = r(152),
43238          o = r(158);
43239
43240      t.exports = function (t) {
43241        return n(t) || i(t) || o();
43242      };
43243    }, function (t, e, r) {
43244
43245      var n = r(1),
43246          i = n(r(30)),
43247          o = n(r(103)),
43248          a = n(r(150)),
43249          s = n(r(48)),
43250          u = n(r(102)),
43251          f = n(r(16)),
43252          c = n(r(59)),
43253          l = n(r(76)),
43254          h = n(r(37)),
43255          d = n(r(77)),
43256          p = n(r(433)),
43257          g = n(r(31)),
43258          v = n(r(7)),
43259          y = n(r(10)),
43260          m = r(9),
43261          b = m.CramUnimplementedError,
43262          _ = m.CramSizeLimitError,
43263          w = r(104),
43264          x = function () {
43265        function t(e) {
43266          if ((0, v.default)(this, t), e.cram ? this.cram = e.cram : this.cram = new w({
43267            url: e.cramUrl,
43268            path: e.cramPath,
43269            filehandle: e.cramFilehandle,
43270            seqFetch: e.seqFetch,
43271            checkSequenceMD5: e.checkSequenceMD5,
43272            cacheSize: e.cacheSize
43273          }), !(this.cram instanceof w)) throw new Error("invalid arguments: no cramfile");
43274          if (this.index = e.index, !this.index.getEntriesForRange) throw new Error("invalid arguments: not an index");
43275          this.fetchSizeLimit = e.fetchSizeLimit || 3e6;
43276        }
43277
43278        var e;
43279        return (0, y.default)(t, [{
43280          key: "getRecordsForRange",
43281          value: (e = (0, g.default)(i.default.mark(function t(e, r, n) {
43282            var g,
43283                v,
43284                y,
43285                m,
43286                w,
43287                x,
43288                E,
43289                S,
43290                k,
43291                A,
43292                C,
43293                T,
43294                R,
43295                O,
43296                I,
43297                L,
43298                B,
43299                P,
43300                F,
43301                N,
43302                M,
43303                j,
43304                z,
43305                U,
43306                D,
43307                q,
43308                Z,
43309                H,
43310                V,
43311                G,
43312                Y,
43313                W,
43314                K,
43315                Q,
43316                X,
43317                $ = this,
43318                J = arguments;
43319            return i.default.wrap(function (t) {
43320              for (;;) switch (t.prev = t.next) {
43321                case 0:
43322                  if ((x = J.length > 3 && void 0 !== J[3] ? J[3] : {}).viewAsPairs = x.viewAsPairs || !1, x.pairAcrossChr = x.pairAcrossChr || !1, x.maxInsertSize = x.maxInsertSize || 2e5, "string" != typeof e) {
43323                    t.next = 6;
43324                    break;
43325                  }
43326
43327                  throw new b("string sequence names not yet supported");
43328
43329                case 6:
43330                  return E = e, t.next = 9, this.index.getEntriesForRange(E, r, n);
43331
43332                case 9:
43333                  if (S = t.sent, !((k = (0, p.default)(g = (0, d.default)(S).call(S, function (t) {
43334                    return t.sliceBytes;
43335                  })).call(g, function (t, e) {
43336                    return t + e;
43337                  }, 0)) > this.fetchSizeLimit)) {
43338                    t.next = 13;
43339                    break;
43340                  }
43341
43342                  throw new _((0, h.default)(v = "data size of ".concat(k.toLocaleStr
43342ing(), " bytes exceeded fetch size limit of ")).call(v, this.fetchSizeLimit.toLocaleString(), " bytes"));
43343
43344                case 13:
43345                  return A = function (t) {
43346                    return t.sequenceId === e && t.alignmentStart <= n && t.alignmentStart + t.lengthOnRef - 1 >= r;
43347                  }, t.next = 16, l.default.all((0, d.default)(S).call(S, function (t) {
43348                    return $.getRecordsInSlice(t, A);
43349                  }));
43350
43351                case 16:
43352                  if (C = t.sent, T = (m = (0, h.default)(y = Array.prototype)).call.apply(m, (0, h.default)(w = [y]).call(w, (0, c.default)(C))), !x.viewAsPairs) {
43353                    t.next = 42;
43354                    break;
43355                  }
43356
43357                  for (L = {}, B = {}, P = 0; P < T.length; P += 1) F = T[P].readName, N = T[P].uniqueId, L[F] || (L[F] = 0), L[F] += 1, B[N] = 1;
43358
43359                  for (M = {}, (0, f.default)(R = (0, u.default)(L)).call(R, function (t) {
43360                    var e = (0, s.default)(t, 2),
43361                        r = e[0];
43362                    1 === e[1] && (M[r] = !0);
43363                  }), j = [], z = 0; z < T.length; z += 1) U = T[z].readName, M[U] && T[z].mate && (T[z].mate.sequenceId === E || x.pairAcrossChr) && Math.abs(T[z].alignmentStart - T[z].mate.alignmentStart) < x.maxInsertSize && (D = this.index.getEntriesForRange(T[z].mate.sequenceId, T[z].mate.alignmentStart, T[z].mate.alignmentStart + 1), j.push(D));
43364
43365                  return t.next = 28, l.default.all(j);
43366
43367                case 28:
43368                  for (q = t.sent, Z = [], H = 0; H < q.length; H += 1) (V = Z).push.apply(V, (0, c.default)(q[H]));
43369
43370                  if (Z = (0, a.default)(O = (0, o.default)(Z).call(Z, function (t, e) {
43371                    return t.toString().localeCompare(e.toString());
43372                  })).call(O, function (t, e, r) {
43373                    return !e || t.toString() !== r[e - 1].toString();
43374                  }), G = [], Y = [], !((W = (0, p.default)(I = (0, d.default)(Z).call(Z, function (t) {
43375                    return t.sliceBytes;
43376                  })).call(I, function (t, e) {
43377                    return t + e;
43378                  }, 0)) > this.fetchSizeLimit)) {
43379                    t.next = 37;
43380                    break;
43381                  }
43382
43383                  throw new Error((0, h.default)(K = "mate data size of ".concat(W.toLocaleString(), " bytes exceeded fetch size limit of ")).call(K, this.fetchSizeLimit.toLocaleString(), " bytes"));
43384
43385                case 37:
43386                  return (0, f.default)(Z).call(Z, function (t) {
43387                    var e = $.cram.featureCache.get(t.toString());
43388                    e || (e = $.getRecordsInSlice(t, function () {
43389                      return !0;
43390                    }), $.cram.featureCache.set(t.toString(), e)), G.push(e);
43391                    var r = e.then(function (t) {
43392                      for (var e = [], r = 0; r < t.length; r += 1) {
43393                        var n = t[r];
43394                        M[n.readName] && !B[n.uniqueId] && e.push(n);
43395                      }
43396
43397                      return e;
43398                    });
43399                    Y.push(r);
43400                  }), t.next = 40, l.default.all(Y);
43401
43402                case 40:
43403                  (Q = t.sent).length && (X = (0, p.default)(Q).c
43403all(Q, function (t, e) {
43404                    return (0, h.default)(t).call(t, e);
43405                  }), T = (0, h.default)(T).call(T, X));
43406
43407                case 42:
43408                  return t.abrupt("return", T);
43409
43410                case 43:
43411                case "end":
43412                  return t.stop();
43413              }
43414            }, t, this);
43415          })), function (t, r, n) {
43416            return e.apply(this, arguments);
43417          })
43418        }, {
43419          key: "getRecordsInSlice",
43420          value: function (t, e) {
43421            var r = t.containerStart,
43422                n = t.sliceStart,
43423                i = t.sliceBytes;
43424            return this.cram.getContainerAtPosition(r).getSlice(n, i).getRecords(e);
43425          }
43426        }, {
43427          key: "hasDataForReferenceSequence",
43428          value: function (t) {
43429            return this.index.hasDataForReferenceSequence(t);
43430          }
43431        }]), t;
43432      }();
43433
43434      t.exports = x;
43435    }, function (t, e, r) {
43436      t.exports = r(434);
43437    }, function (t, e, r) {
43438      t.exports = r(435);
43439    }, function (t, e, r) {
43440      var n = r(436),
43441          i = Array.prototype;
43442
43443      t.exports = function (t) {
43444        var e = t.reduce;
43445        return t === i || t instanceof Array && e === i.reduce ? n : e;
43446      };
43447    }, function (t, e, r) {
43448      r(437);
43449      var n = r(18);
43450      t.exports = n("Array").reduce;
43451    }, function (t, e, r) {
43452
43453      var n = r(0),
43454          i = r(438).left;
43455      n({
43456        target: "Array",
43457        proto: !0,
43458        forced: r(54)("reduce")
43459      }, {
43460        reduce: function (t) {
43461          return i(this, t, arguments.length, arguments.length > 1 ? arguments[1] : void 0);
43462        }
43463      });
43464    }, function (t, e, r) {
43465      var n = r(5),
43466          i = r(22),
43467          o = r(60),
43468          a = r(29),
43469          s = function (t) {
43470        return function (e, r, s, u) {
43471          n(r);
43472          var f = i(e),
43473              c = o(f),
43474              l = a(f.length),
43475              h = t ? l - 1 : 0,
43476              d = t ? -1 : 1;
43477          if (s < 2) for (;;) {
43478            if (h in c) {
43479              u = c[h], h += d;
43480              break;
43481            }
43482
43483            if (h += d, t ? h < 0 : l <= h) throw TypeError("Reduce of empty array with no initial value");
43484          }
43485
43486          for (; t ? h >= 0 : l > h; h += d) h in c && (u = r(u, c[h], h, f));
43487
43488          return u;
43489        };
43490      };
43491
43492      t.exports = {
43493        left: s(!1),
43494        right: s(!0)
43495      };
43496    }, function (t, e, r) {
43497
43498      var n = r(1),
43499          i = n(r(30)),
43500          o = n(r(31)),
43501          a = n(r(103)),
43502          s = n(r(102)),
43503          u = n(r(16)),
43504          f = n(r(154)),
43505          c = n(r(440)),
43506          l = n(r(48)),
43507          h = n(r(442)),
43508          d = n(r(37)),
43509          p = n(r(75)),
43510          g = n(r(7)),
43511          v = n(r(10)),
43512          y = r(447).default,
43513          m = r(94),
43514          b = (0, r(161).promisify)(r(126).gunzip),
43515          _ = r(160).open,
43516          w = r(9).CramMalformedError,
43517          x = function () {
43518        function t(e) {
43519          (0, g.default)(this, t), (0, p.default)(this, e);
43520        }
43521
43522        return (0, v.default)(t, [{
43523          key: "toString",
43524          value: function () {
43525            var t, e, r, n;
43526            return (0, d.default)(t = (0, d.default)(e = (0, d.default)(r = (0, d.default)(n = "".concat(this.start, ":")).call(n, this.span, ":")).call(r, this.containerStart, ":")).call(e, this.sliceStart, ":")).call(t, this.sliceBytes);
43527          }
43528        }]), t;
43529      }();
43530
43531      function E(t, e) {
43532        if ((0, h.default)(e).call(e, function (t) {
43533          return void 0 === t;
43534        })) throw new w("invalid .crai index file");
43535        var r = (0, l.default)(e, 6),
43536            n = r[0],
43537            i = r[1],
43538            o = r[2],
43539            a = r[3],
43540            s = r[4],
43541            u = r[5];
43542        t[n] || (t[n] = []), t[n].push(new x({
43543          start: i,
43544          span: o,
43545          containerStart: a,
43546          sliceStart: s,
43547          sliceBytes: u
43548        }));
43549      }
43550
43551      var S = function () {
43552        function t(e) {
43553          var r,
43554              n = this;
43555          (0, g.default)(this, t);
43556
43557          var i = _(e.url, e.path, e.filehandle);
43558
43559          this._parseCache = new y({
43560            cache: new m({
43561              maxSize: 1
43562            }),
43563            fill: function (t, e) {
43564              return n.parseIndex({
43565                signal: e
43566              });
43567            }
43568          }), this.readFile = (0, c.default)(r = i.readFile).call(r, i);
43569        }
43570
43571        var e, r;
43572        return (0, v.default)(t, [{
43573          key: "parseIndex",
43574          value: function () {
43575            var t = {};
43576            return this.readFile().then(function (t) {
43577              return 31 === t[0] && 139 === t[1] ? b(t) : t;
43578            }).then(function (e) {
43579              var r;
43580              if (e.length > 4 && 21578050 === e.readUInt32LE(0)) throw new w("invalid .crai index file. note: file appears to be a .bai index. this is technically legal but please open a github issue if you need support");
43581
43582              for (var n = [], i = "", o = 0; o < e.length; o += 1) {
43583                var c = e[o];
43584                if (c >= 48 && c <= 57 || !i && 45 === c) i += String.fromCharCode(c);else if (9 === c) n.push((0, f.default)(i, 10)), i = "";else if (10 === c) n.push((0, f.default)(i, 10)), i = "", E(t, n), n = [];else if (13 !== c && 32 !== c) throw new w("invalid .crai index file");
43585              }
43586
43587              return i && n.push((0, f.default)(i, 10)), 6 === n.length && E(t, n), (0, u.default)(r = (0, s.default)(t)).call(r, function (e) {
43588                var r = (0, l.default)(e, 2),
43589                    n = r[0],
43590                    i = r[1];
43591                t[n] = (0, a.default)(i).call(i, function (t, e) {
43592                  return t.start - e.start || t.span - e.span;
43593                });
43594              }), t;
43595            });
43596          }
43597        }, {
43598          key: "getIndex",
43599          value: function () {
43600            var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
43601            return this._parseCache.get("index", null, t.signal);
43602          }
43603        }, {
43604          key: "hasDataForReferenceSequence",
43605          value: (r = (0, o.default)(i.default.mark(function t(e) {
43606            return i.default.wrap(function (t) {
43607              for (;;) switch (t.prev = t.next) {
43608                case 0:
43609                  return t.next = 2, this.getIndex();
43610
43611                case 2:
43612                  return t.t0 = e, t.abrupt("return", !!t.sent[t.t0]);
43613
43614                case 4:
43615                case "end":
43616                  return t.stop();
43617              }
43618            }, t, this);
43619          })), function (t) {
43620            return r.apply(this, arguments);
43621          })
43622        }, {
43623          key: "getEntriesForRange",
43624          value: (e = (0, o.default)(i.default.mark(function t(e, r, n) {
43625            var o, a, s, u;
43626            return i.default.wrap(function (t) {
43627              for (;;) switch (t.prev = t.next) {
43628                case 0:
43629                  return t.next = 2, this.getIndex();
43630
43631                case 2:
43632                  if (t.t0 = e, o = t.sent[t.t0]) {
43633                    t.next = 6;
43634                    break;
43635                  }
43636
43637                  return t.abrupt("return", []);
43638
43639                case 6:
43640                  for (a = function (t) {
43641                    var e = t.start,
43642                        i = t.start + t.span;
43643                    return e >= n ? -1 : i <= r ? 1 : 0;
43644                  }, s = [], u = 0; u < o.length; u += 1) 0 === a(o[u]) && s.push(o[u]);
43645
43646                  return t.abrupt("return", s);
43647
43648                case 10:
43649                case "end":
43650                  return t.stop();
43651              }
43652            }, t, this);
43653          })), function (t, r, n) {
43654            return e.apply(this, arguments);
43655          })
43656        }]), t;
43657      }();
43658
43659      t.exports = S;
43660    }, function (t, e, r) {
43661      t.exports = r(441);
43662    }, function (t, e, r) {
43663      t.exports = r(144);
43664    }, function (t, e, r) {
43665      t.exports = r(443);
43666    }, function (t, e, r) {
43667      t.exports = r(444);
43668    }, function (t, e, r) {
43669      var n = r(445),
43670          i = Array.prototype;
43671
43672      t.exports = function (t) {
43673        var e = t.some;
43674        return t === i || t instanceof Array && e === i.some ? n : e;
43675      };
43676    }, function (t, e, r) {
43677      r(446);
43678      var n = r(18);
43679      t.exports = n("Array").some;
43680    }, function (t, e, r) {
43681
43682      var n = r(0),
43683          i = r(45).some;
43684      n({
43685        target: "Array",
43686        proto: !0,
43687        forced: r(54)("some")
43688      }, {
43689        some: function (t) {
43690          return i(this, t, arguments.length > 1 ? arguments[1] : void 0);
43691        }
43692      });
43693    }, function (t, e, r) {
43694
43695      var n = this && this.__importDefault || function (t) {
43696        return t && t.__esModule ? t : {
43697          default: t
43698        };
43699      };
43700
43701      Object.defineProperty(e, "__esModule", {
43702        value: !0
43703      });
43704      var i = n(r(448));
43705      e.default = i.default;
43706    }, function (t, e, r) {
43707
43708      var n = this && this.__importDefault || function (t) {
43709        return t && t.__esModule ? t : {
43710          default: t
43711        };
43712      };
43713
43714      Object.defineProperty(e, "__esModule", {
43715        value: !0
43716      });
43717
43718      var i = r(162),
43719          o = n(r(450)),
43720          a = function () {
43721        function t(t) {
43722          var e = t.fill,
43723              r = t.cache;
43724          if ("function" != typeof e) throw new TypeError("must pass a fill function");
43725          if ("object" != typeof r) throw new TypeError("must pass a cache object");
43726          if ("function" != typeof r.get || "function" != typeof r.set || "function" != typeof r.delete) throw new TypeError("cache must implement get(key), set(key, val), and and delete(key)");
43727          this.cache = r, this.fillCallback = e;
43728        }
43729
43730        return t.isAbortException = function (t) {
43731          return "AbortError" === t.name || "ERR_ABORTED" === t.code || "AbortError: aborted" === t.message || "Error: aborted" === t.message;
43732        }, t.prototype.evict = function (t, e) {
43733          this.cache.get(t) === e && this.cache.delete(t);
43734        }, t.prototype.fill = function (t, e, r) {
43735          var n = this,
43736              i = new o.default(),
43737              a = {
43738            aborter: i,
43739            promise: this.fillCallback(e, i.signal),
43740            settled: !1,
43741
43742            get aborted() {
43743              return this.aborter.signal.aborted;
43744            }
43745
43746          };
43747          a.aborter.addSignal(r), a.aborter.signal.addEventListener("abort", function () {
43748            n.evict(t, a);
43749          }), a.promise.then(function () {
43750            a.settled = !0;
43751          }, function (e) {
43752            a.settled = !0, n.evict(t, a);
43753          }).catch(function (t) {
43754            throw console.error(t), t;
43755          }), this.cache.set(t, a);
43756        }, t.checkSinglePromise = function (t, e) {
43757          function r() {
43758            if (e && e.aborted) throw Object.assign(new Error("aborted"), {
43759              code: "ERR_ABORTED"
43760            });
43761          }
43762
43763          return t.then(function (t) {
43764            return r(), t;
43765          }, function (t) {
43766            throw r(), t;
43767          });
43768        }, t.prototype.has = function (t) {
43769          return this.cache.has(t);
43770        }, t.prototype.get = function (e, r, n) {
43771          if (!n && r instanceof i.AbortSignal) throw new TypeError("second get argument appears to be an AbortSignal, perhaps y
43771ou meant to pass `null` for the fill data?");
43772          var o = this.cache.get(e);
43773          return o ? o.aborted ? (this.evict(e, o), this.get(e, r, n)) : o.settled ? o.promise : (o.aborter.addSignal(n), t.checkSinglePromise(o.promise, n)) : (this.fill(e, r, n), t.checkSinglePromise(this.cache.get(e).promise, n));
43774        }, t.prototype.delete = function (t) {
43775          var e = this.cache.get(t);
43776          e && (e.settled || e.aborter.abort(), this.cache.delete(t));
43777        }, t.prototype.clear = function () {
43778          for (var t = this.cache.keys(), e = 0, r = t.next(); !r.done; r = t.next()) this.delete(r.value), e += 1;
43779
43780          return e;
43781        }, t;
43782      }();
43783
43784      e.default = a;
43785    }, function (t, e, r) {
43786
43787      function n(t, e) {
43788        if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function");
43789      }
43790
43791      function i(t, e) {
43792        for (var r = 0; r < e.length; r++) {
43793          var n = e[r];
43794          n.enumerable = n.enumerable || !1, n.configurable = !0, "value" in n && (n.writable = !0), Object.defineProperty(t, n.key, n);
43795        }
43796      }
43797
43798      function o(t, e, r) {
43799        return e && i(t.prototype, e), r && i(t, r), t;
43800      }
43801
43802      function a(t) {
43803        return (a = Object.setPrototypeOf ? Object.getPrototypeOf : function (t) {
43804          return t.__proto__ || Object.getPrototypeOf(t);
43805        })(t);
43806      }
43807
43808      function s(t, e) {
43809        return (s = Object.setPrototypeOf || function (t, e) {
43810          return t.__proto__ = e, t;
43811        })(t, e);
43812      }
43813
43814      function u(t) {
43815        if (void 0 === t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
43816        return t;
43817      }
43818
43819      function f(t, e, r) {
43820        return (f = "undefined" != typeof Reflect && Reflect.get ? Reflect.get : function (t, e, r) {
43821          var n = function (t, e) {
43822            for (; !Object.prototype.hasOwnProperty.call(t, e) && null !== (t = a(t)););
43823
43824            return t;
43825          }(t, e);
43826
43827          if (n) {
43828            var i = Object.getOwnPropertyDescriptor(n, e);
43829            return i.get ? i.get.call(r) : i.value;
43830          }
43831        })(t, e, r || t);
43832      }
43833
43834      Object.defineProperty(e, "__esModule", {
43835        value: !0
43836      });
43837
43838      var c = function () {
43839        function t() {
43840          n(this, t), Object.defineProperty(this, "listeners", {
43841            value: {},
43842            writable: !0,
43843            configurable: !0
43844          });
43845        }
43846
43847        return o(t, [{
43848          key: "addEventListener",
43849          value: function (t, e) {
43850            t in this.listeners || (this.listeners[t] = []), this.listeners[t].push(e);
43851          }
43852        }, {
43853          key: "removeEventListener",
43854          value: function (t, e) {
43855            if (t in this.listeners) for (var r = this.listeners[t], n = 0, i = r.length; n < i; n++) if (r[n] === e) return void r.splice(n, 1);
43856          }
43857        }, {
43858          key: "dispatchEvent",
43859          value: function (t) {
43860            var e = this;
43861
43862            if (t.type in this.listeners) {
43863              for (var r = function (r) {
43864                setTimeout(function () {
43865                  return r.call(e, t);
43866                });
43867              }, n = this.listeners[t.type], i = 0, o = n.length; i < o; i++) r(n[i]);
43868
43869              return !t.defaultPrevented;
43870            }
43871          }
43872        }]), t;
43873      }(),
43874          l = function (t) {
43875        function e() {
43876          var t;
43877          return n(this, e), (t = function (t, e) {
43878            return !e || "object" != typeof e && "function" != typeof e ? u(t) : e;
43879          }(this, a(e).call(this))).listeners || c.call(u(t)), Object.defineProperty(u(t), "aborted", {
43880            value: !1,
43881            writable: !0,
43882            configurable: !0
43883          }), Object.defineProperty(u(t), "onabort", {
43884            value: null,
43885            writable: !0,
43886            configurable: !0
43887          }), t;
43888        }
43889
43890        return function (t, e) {
43891          if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
43892          t.prototype = Object.create(e && e.prototype, {
43893            constructor: {
43894              value: t,
43895              writable: !0,
43896              configurable: !0
43897            }
43898          }), e && s(t, e);
43899        }(e, t), o(e, [{
43900          key: "toString",
43901          value: function () {
43902            return "[object AbortSignal]";
43903          }
43904        }, {
43905          key: "dispatchEvent",
43906          value: function (t) {
43907            "abort" === t.type && (this.aborted = !0, "function" == typeof this.onabort && this.onabort.call(this, t)), f(a(e.prototype), "dispatchEvent", this).call(this, t);
43908          }
43909        }]), e;
43910      }(c),
43911          h = function () {
43912        function t() {
43913          n(this, t), Object.defineProperty(this, "signal", {
43914            value: new l(),
43915            writable: !0,
43916            configurable: !0
43917          });
43918        }
43919
43920        return o(t, [{
43921          key: "abort",
43922          value: function () {
43923            var t;
43924
43925            try {
43926              t = new Event("abort");
43927            } catch (e) {
43928              "undefined" != typeof document ? document.createEvent ? (t = document.createEvent("Event")).initEvent("abort", !1, !1) : (t = document.createEventObject()).type = "abort" : t = {
43929                type: "abort",
43930                bubbles: !1,
43931                cancelable: !1
43932              };
43933            }
43934
43935            this.signal.dispatchEvent(t);
43936          }
43937        }, {
43938          key: "toString",
43939          value: function () {
43940            return "[object AbortController]";
43941          }
43942        }]), t;
43943      }();
43944
43945      "undefined" != typeof Symbol && Symbol.toStringTag && (h.prototype[Symbol.toStringTag] = "AbortController", l.prototype[Symbol.toStringTag] = "AbortSignal"), e.AbortController = h, e.AbortSignal = l, e.abortableFetch = function (t) {
43946        "function" == typeof t && (t = {
43947          fetch: t
43948        });
43949        var e = t,
43950            r = e.fetch,
43951            n = e.Request,
43952            i = void 0 === n ? r.Request : n,
43953            o = e.AbortController,
43954            a = e.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL,
43955            s = void 0 !== a && a;
43956        if (!function (t) {
43957          return t.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL ? (console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"), !0) : "function" == typeof t.Request && !t.Request.prototype.hasOwnProperty("signal") || !t.AbortController;
43958        }({
43959          fetch: r,
43960          Request: i,
43961          AbortController: o,
43962          __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL: s
43963        })) return {
43964          fetch: r,
43965          Request: u
43966        };
43967        var u = i;
43968        (u && !u.prototype.hasOwnProperty("signal") || s) && ((u = function (t, e) {
43969          var r;
43970          e && e.signal && (r = e.signal, delete e.signal);
43971          var n = new i(t, e);
43972          return r && Object.defineProperty(n, "signal", {
43973            writable: !1,
43974            enumerable: !1,
43975            configurable: !0,
43976            value: r
43977          }), n;
43978        }).prototype = i.prototype);
43979        var f = r;
43980        return {
43981          fetch: function (t, e) {
43982            var r = u && u.prototype.isPrototypeOf(t) ? t.signal : e ? e.signal : void 0;
43983
43984            if (r) {
43985              var n;
43986
43987              try {
43988                n = new DOMException("Aborted", "AbortError");
43989              } catch (t) {
43990                (n = new Error("Aborted")).name = "AbortError";
43991              }
43992
43993              if (r.aborted) return Promise.reject(n);
43994              var i = new Promise(function (t, e) {
43995                r.addEventListener("abort", function () {
43996                  return e(n);
43997                }, {
43998                  once: !0
43999                });
44000              });
44001              return e && e.signal && delete e.signal, Promise.race([i, f(t, e)]);
44002            }
44003
44004            return f(t, e);
44005          },
44006          Request: u
44007        };
44008      };
44009    }, function (t, e, r) {
44010
44011      Object.defineProperty(e, "__esModule", {
44012        value: !0
44013      });
44014
44015      var n = r(162),
44016          i = function () {},
44017          o = function () {
44018        function t() {
44019          this.signals = new Set(), this.abortController = new n.AbortController();
44020        }
44021
44022        return t.prototype.addSignal = function (t) {
44023          var e = this;
44024          if (void 0 === t && (t = new i()), this.signal.aborted) throw new Error("cannot add a signal, already aborted!");
44025          this.signals.add(t), t.aborted ? this.handleAborted(t) : "function" == typeof t.addEventListener && t.addEventListener("abort", function () {
44026            e.handleAborted(t);
44027          });
44028        }, t.prototype.handleAborted = function (t) {
44029          this.signals.delete(t), 0 === this.signals.size && this.abortController.abort();
44030        }, Object.defineProperty(t.prototype, "signal", {
44031          get: function () {
44032            return this.abortController.signal;
44033          },
44034          enumerable: !0,
44035          configurable: !0
44036        }), t.prototype.abort = function () {
44037          this.abortController.abort();
44038        }, t;
44039      }();
44040
44041      e.default = o;
44042    }]);
44043
44044    /*
44045     * The MIT License (MIT)
44046     *
44047     * Copyright (c) 2018 The Regents of the University of California
44048     * Author: Jim Robinson
44049     *
44050     * Permission is hereby granted, free of charge, to any person obtaining a copy
44051     * of this software and associated documentation files (the "Software"), to deal
44052     * in the Software without restriction, including without limitation the rights
44053     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
44054     * copies of the Software, and to permit persons to whom the Software is
44055     * furnished to do so, subject to the following conditions:
44056     *
44057     * The above copyright notice and this permission notice shall be included in
44058     * all copies or substantial portions of the Software.
44059     *
44060     *
44061     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44062     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44063     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44064     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44065     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44066     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44067     * THE SOFTWARE.
44068     */
44069    const READ_STRAND_FLAG = 0x10;
44070    const MATE_STRAND_FLAG = 0x20;
44071    const CRAM_MATE_STRAND_FLAG = 0x1;
44072    /**
44073     * Class for reading a cram file.  Wraps the gMOD Cram package.
44074     *
44075     * @param config
44076     * @constructor
44077     */
44078
44079    class CramReader {
44080      constructor(config, genome, browser) {
44081        this.config = config;
44082        this.browser = browser;
44083        this.genome = genome;
44084        this.cramFile = new gmodCRAM.CramFile({
44085          filehandle: new FileHandler(config.url, config),
44086          seqFetch: config.seqFetch || seqFetch.bind(this),
44087          checkSequenceMD5: config.checkSequenceMD5 !== undefined ? config.checkSequenceMD5 : true
44088        });
44089        const indexFileHandle = new FileHandler(config.indexURL, config);
44090        this.indexedCramFile = new gmodCRAM.IndexedCramFile({
44091          cram: this.cramFile,
44092          index: new gmodCRAM.CraiIndex({
44093            filehandle: indexFileHandle
44094          }),
44095          fetchSizeLimit: 30000000
44096        });
44097        BamUtils.setReaderDefaults(this, config);
44098
44099        function seqFetch(seqID, start, end) {
44100          const sequence = this.genome.sequence;
44101          const genome = this.genome;
44102          return this.getHeader().then(function (header) {
44103            const chr = genome.getChromosomeName(header.chrNames[seqID]);
44104            return sequence.getSequence(chr, start - 1, end);
44105          });
44106        }
44107      }
44108      /**
44109       * Parse the sequence dictionary from the SAM header and build chr name tables.  This function
44110       * is public so it can be unit tested.
44111       *
44112       * @returns {PromiseLike<chrName, chrToIndex, chrAliasTable}>}
44113       */
44114
44115
44116      async getHeader() {
44117        if (!this.header) {
44118          const genome = this.genome;
44119          const samHeader = await this.cramFile.getSamHeader();
44120          const chrToIndex = {};
44121          const chrNames = [];
44122          const chrAliasTable = {};
44123          const readGroups = [];
44124
44125          for (let line of samHeader) {
44126            if ('SQ' === line.tag) {
44127              for (let d of line.data) {
44128                if (d.tag === "SN") {
44129                  const seq = d.value;
44130                  chrToIndex[seq] = chrNames.length;
44131                  chrNames.push(seq);
44132
44133                  if (genome) {
44134                    const alias = genome.getChromosomeName(seq);
44135                    chrAliasTable[alias] = seq;
44136                  }
44137
44138                  break;
44139                }
44140              }
44141            } else if ('RG' === line.tag) {
44142              readGroups.push(line.data);
44143            }
44144          }
44145
44146          this.header = {
44147            chrNames: chrNames,
44148            chrToIndex: chrToIndex,
44149            chrAliasTable: chrAliasTable,
44150            readGroups: readGroups
44151          };
44152        }
44153
44154        return this.header;
44155      }
44156
44157      async readAlignments(chr, bpStart, bpEnd) {
44158        this.browser;
44159        const header = await this.getHeader();
44160        const queryChr = header.chrAliasTable.hasOwnProperty(chr) ? header.chrAliasTable[chr] : chr;
44161        const chrIdx = header.chrToIndex[queryChr];
44162        const alignmentContainer = new AlignmentContainer(chr, bpStart, bpEnd, this.samplingWindowSize, this.samplingDepth, this.pairsSupported, this.alleleFreqThreshold);
44163
44164        if (chrIdx === undefined) {
44165          return alignmentContainer;
44166        } else {
44167          try {
44168            const records = await this.indexedCramFile.getRecordsForRange(chrIdx, bpStart, bpEnd);
44169
44170            for (let record of records) {
44171              const refID = record.sequenceId;
44172              const pos = record.alignmentStart;
44173              const alignmentEnd = pos + record.lengthOnRef;
44174
44175              if (refID < 0) {
44176                continue; // unmapped read
44177              } else if (refID > chrIdx || pos > bpEnd) {
44178                return; // off right edge, we're done
44179              } else if (refID < chrIdx) {
44180                continue; // Sequence to left of start, not sure this is possible
44181              }
44182
44183              if (alignmentEnd < bpStart) {
44184                continue;
44185              } // Record out-of-range "to the left", skip to next one
44186
44187
44188              const alignment = decodeCramRecord(record, header.chrNames);
44189
44190              if (this.filter.pass(alignment)) {
44191                alignmentContainer.push(alignment);
44192              }
44193            }
44194
44195            alignmentContainer.finish();
44196            return alignmentContainer;
44197          } catch (error) {
44198            let message = error.message;
44199
44200            if (message && message.indexOf("MD5") >= 0) {
44201              message = "Sequence mismatch. Is this the correct genome for the loaded CRAM?";
44202            }
44203
44204            Alert.presentAlert(new Error(message));
44205            throw error;
44206          }
44207        }
44208
44209        function decodeCramRecord(record, chrNames) {
44210          const alignment = new BamAlignment();
44211          alignment.chr = chrNames[record.sequenceId];
44212          alignment.start = record.alignmentStart - 1;
44213          alignment.lengthOnRef = record.lengthOnRef;
44214          alignment.flags = record.flags;
44215          alignment.strand = !(record.flags & READ_STRAND_FLAG);
44216          alignment.fragmentLength = record.templateLength || record.templateSize;
44217          alignment.mq = record.mappingQuality;
44218          alignment.end = record.alignmentStart + record.lengthOnRef;
44219          alignment.readGroupId = record.readGroupId;
44220
44221          if (record.mate && record.mate.sequenceId !== undefined) {
44222            const strand = record.mate.flags !== undefined ? !(record.mate.flags & CRAM_MATE_STRAND_FLAG) : !(record.flags & MATE_STRAND_FLAG);
44223            alignment.mate = {
44224              chr: chrNames[record.mate.sequenceId],
44225              position: record.mate.alignmentStart,
44226              strand: strand
44227            };
44228          }
44229
44230          alignment.seq = record.getReadBases();
44231          alignment.qual = record.qualityScores;
44232          alignment.tagDict = record.tags;
44233          alignment.readName = record.readName; // TODO -- cigar encoded in tag?
44234          // BamUtils.bam_tag2cigar(ba, blockEnd, p, lseq, alignment, cigarArray);
44235
44236          makeBlocks(record, alignment);
44237
44238          if (alignment.mate && alignment.start > alignment.mate.position && alignment.fragmentLength > 0) {
44239            alignment.fragmentLength = -alignment.fragmentLength;
44240          }
44241
44242          BamUtils.setPairOrientation(alignment);
44243          return alignment;
44244        }
44245
44246        function makeBlocks(cramRecord, alignment) {
44247          const blocks = [];
44248          let insertions;
44249          let gaps;
44250          let basesUsed = 0;
44251          let cigarString = '';
44252          alignment.scStart = alignment.start;
44253          alignment.scLengthOnRef = alignment.lengthOnRef;
44254
44255          if (cramRecord.readFeatures) {
44256            for (let feature of cramRecord.readFeatures) {
44257              const code = feature.code;
44258              const data = feature.data;
44259              const readPos = feature.pos - 1;
44260              const refPos = feature.refPos - 1;
44261
44262              switch (code) {
44263                case 'S':
44264                case 'I':
44265                case 'i':
44266                case 'N':
44267                case 'D':
44268                  if (readPos > basesUsed) {
44269                    const len = readPos - basesUsed;
44270                    blocks.push(new AlignmentBlock({
44271                      start: refPos - len,
44272                      seqOffset: basesUsed,
44273                      len: len,
44274                      type: 'M'
44275                    }));
44276                    basesUsed += len;
44277                    cigarString += len + 'M';
44278                  }
44279
44280                  if ('S' === code) {
44281                    let scPos = refPos;
44282                    alignment.scLengthOnRef += data.length;
44283
44284                    if (readPos === 0) {
44285                      alignment.scStart -= data.length;
44286                      scPos -= data.length;
44287                    }
44288
44289                    const len = data.length;
44290                    blocks.push(new AlignmentBlock({
44291                      start: scPos,
44292                      seqOffset: basesUsed,
44293                      len: len,
44294                      type: 'S'
44295                    }));
44296                    basesUsed += len;
44297                    cigarString += len + code;
44298                  } else if ('I' === code || 'i' === code) {
44299                    if (insertions === undefined) {
44300                      insertions = [];
44301                    }
44302
44303                    const len = 'i' === code ? 1 : data.length;
44304                    insertions.push(new AlignmentBlock({
44305                      start: refPos,
44306                      len: len,
44307                      seqOffset: basesUsed,
44308                      type: 'I'
44309                    }));
44310                    basesUsed += len;
44311                    cigarString += len + code;
44312                  } else if ('D' === code || 'N' === code) {
44313                    if (!gaps) {
44314                      gaps = [];
44315                    }
44316
44317                    gaps.push({
44318                      start: refPos,
44319                      len: data,
44320                      type: code
44321                    });
44322                    cigarString += data + code;
44323                  }
44324
44325                  break;
44326
44327                case 'H':
44328                case 'P':
44329                  cigarString += data + code;
44330                  break;
44331
44332              }
44333            }
44334          } // Last block
44335
44336
44337          const len = cramRecord.readLength - basesUsed;
44338
44339          if (len > 0) {
44340            blocks.push(new AlignmentBlock({
44341              start: cramRecord.alignmentStart + cramRecord.lengthOnRef - len - 1,
44342              seqOffset: basesUsed,
44343              len: len,
44344              type: 'M'
44345            }));
44346            cigarString += len + 'M';
44347          }
44348
44349          alignment.blocks = blocks;
44350          alignment.insertions = insertions;
44351          alignment.gaps = gaps;
44352          alignment.cigar = cigarString;
44353        }
44354      }
44355
44356    }
44357
44358    class FileHandler {
44359      constructor(source, config) {
44360        this.position = 0;
44361        this.url = source;
44362        this.config = config;
44363        this.cache = new BufferCache({
44364          fetch: (start, length) => this._fetch(start, length)
44365        });
44366      }
44367
44368      async _fetch(position, length) {
44369        const loadRange = {
44370          start: position,
44371          size: length
44372        };
44373        this._stat = {
44374          size: undefined
44375        };
44376        const arrayBuffer = await igvxhr.loadArrayBuffer(this.url, buildOptions(this.config, {
44377          range: loadRange
44378        }));
44379        return Buffer.from(arrayBuffer);
44380      }
44381
44382      async read(buffer) {
44383        let offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
44384        let length = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Infinity;
44385        let position = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
44386        let readPosition = position;
44387
44388        if (readPosition === null) {
44389          readPosition = this.position;
44390          this.position += length;
44391        }
44392
44393        return this.cache.get(buffer, offset, length, position);
44394      }
44395
44396      async readFile() {
44397        const arrayBuffer = await igvxhr.loadArrayBuffer(this.url, buildOptions(this.config));
44398        return Buffer.from(arrayBuffer);
44399      }
44400
44401      async stat() {
44402        if (!this._stat) {
44403          const buf = Buffer.allocUnsafe(10);
44404          await this.read(buf, 0, 10, 0);
44405          if (!this._stat) throw new Error(`unable to determine size of file at ${this.url}`);
44406        }
44407
44408        return this._stat;
44409      }
44410
44411    }
44412
44413    class BufferCache {
44414      constructor(_ref) {
44415        let {
44416          fetch,
44417          size = 10000000,
44418          chunkSize = 32768
44419        } = _ref;
44420        this.fetch = fetch;
44421        this.chunkSize = chunkSize;
44422        this.lruCache = new QuickLRU({
44423          maxSize: Math.floor(size / chunkSize)
44424        });
44425      }
44426
44427      async get(outputBuffer, offset, length, position) {
44428        if (outputBuffer.length < offset + length) throw new Error('output buffer not big enough for request'); // calculate the list of chunks involved in this fetch
44429
44430        const firstChunk = Math.floor(position / this.chunkSize);
44431        const lastChunk = Math.floor((position + length) / this.chunkSize); // fetch them all as necessary
44432
44433        const fetches = new Array(lastChunk - firstChunk + 1);
44434
44435        for (let chunk = firstChunk; chunk <= lastChunk; chunk += 1) {
44436          fetches[chunk - firstChunk] = this._getChunk(chunk).then(data => ({
44437            data,
44438            chunkNumber: chunk
44439          }));
44440        } // stitch together the response buffer using them
44441
44442
44443        const chunks = await Promise.all(fetches);
44444        const chunksOffset = position - chunks[0].chunkNumber * this.chunkSize;
44445        chunks.forEach(_ref2 => {
44446          let {
44447            data,
44448            chunkNumber
44449          } = _ref2;
44450          const chunkPositionStart = chunkNumber * this.chunkSize;
44451          let copyStart = 0;
44452          let copyEnd = this.chunkSize;
44453          let copyOffset = offset + (chunkNumber - firstChunk) * this.chunkSize - chunksOffset;
44454
44455          if (chunkNumber === firstChunk) {
44456            copyOffset = offset;
44457            copyStart = chunksOffset;
44458          }
44459
44460          if (chunkNumber === lastChunk) {
44461            copyEnd = position + length - chunkPositionStart;
44462          }
44463
44464          data.copy(outputBuffer, copyOffset, copyStart, copyEnd);
44465        });
44466      }
44467
44468      _getChunk(chunkNumber) {
44469        const cachedPromise = this.lruCache.get(chunkNumber);
44470        if (cachedPromise) return cachedPromise;
44471        const freshPromise = this.fetch(chunkNumber * this.chunkSize, this.chunkSize);
44472        this.lruCache.set(chunkNumber, freshPromise);
44473        return freshPromise;
44474      }
44475
44476    } // From https://github.com/sindresorhus/quick-lru
44477
44478    class QuickLRU {
44479      constructor() {
44480        let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
44481
44482        if (!(options.maxSize && options.maxSize > 0)) {
44483          throw new TypeError('`maxSize` must be a number greater than 0');
44484        }
44485
44486        this.maxSize = options.maxSize;
44487        this.cache = new Map();
44488        this.oldCache = new Map();
44489        this._size = 0;
44490      }
44491
44492      _set(key, value) {
44493        this.cache.set(key, value);
44494        this._size++;
44495
44496        if (this._size >= this.maxSize) {
44497          this._size = 0;
44498          this.oldCache = this.cache;
44499          this.cache = new Map();
44500        }
44501      }
44502
44503      get(key) {
44504        if (this.cache.has(key)) {
44505          return this.cache.get(key);
44506        }
44507
44508        if (this.oldCache.has(key)) {
44509          const value = this.oldCache.get(key);
44510
44511          this._set(key, value);
44512
44513          return value;
44514        }
44515      }
44516
44517      set(key, value) {
44518        if (this.cache.has(key)) {
44519          this.cache.set(key, value);
44520        } else {
44521          this._set(key, value);
44522        }
44523
44524        return this;
44525      }
44526
44527      has(key) {
44528        return this.cache.has(key) || this.oldCache.has(key);
44529      }
44530
44531      peek(key) {
44532        if (this.cache.has(key)) {
44533          return this.cache.get(key);
44534        }
44535
44536        if (this.oldCache.has(key)) {
44537          return this.oldCache.get(key);
44538        }
44539      }
44540
44541      delete(key) {
44542        const deleted = this.cache.delete(key);
44543
44544        if (deleted) {
44545          this._size--;
44546        }
44547
44548        return this.oldCache.delete(key) || deleted;
44549      }
44550
44551      clear() {
44552        this.cache.clear();
44553        this.oldCache.clear();
44554        this._size = 0;
44555      }
44556
44557      *keys() {
44558        for (const [key] of this) {
44559          yield key;
44560        }
44561      }
44562
44563      *values() {
44564        for (const [, value] of this) {
44565          yield value;
44566        }
44567      }
44568
44569      *[Symbol.iterator]() {
44570        for (const item of this.cache) {
44571          yield item;
44572        }
44573
44574        for (const item of this.oldCache) {
44575          const [key] = item;
44576
44577          if (!this.cache.has(key)) {
44578            yield item;
44579          }
44580        }
44581      }
44582
44583      get size() {
44584        let oldCacheSize = 0;
44585
44586        for (const key of this.oldCache.keys()) {
44587          if (!this.cache.has(key)) {
44588            oldCacheSize++;
44589          }
44590        }
44591
44592        return this._size + oldCacheSize;
44593      }
44594
44595    }
44596
44597    /*
44598     * The MIT License (MIT)
44599     *
44600     * Copyright (c) 2014 Broad Institute
44601     *
44602     * Permission is hereby granted, free of charge, to any person obtaining a copy
44603     * of this software and associated documentation files (the "Software"), to deal
44604     * in the Software without restriction, including without limitation the rights
44605     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
44606     * copies of the Software, and to permit persons to whom the Software is
44607     * furnished to do so, subject to the following conditions:
44608     *
44609     * The above copyright notice and this permission notice shall be included in
44610     * all copies or substantial portions of the Software.
44611     *
44612     *
44613     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44614     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44615     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44616     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44617     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44618     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44619     * THE SOFTWARE.
44620     */
44621    const apiKey = igvxhr.apiKey;
44622
44623    function ga4ghGet(options) {
44624      var url = options.url + "/" + options.entity + "/" + options.entity
44624Id;
44625      options.headers = ga4ghHeaders();
44626      return igvxhr.loadJson(url, options); // Returns a promise
44627    }
44628
44629    function ga4ghSearch(options) {
44630      return new Promise(function (fulfill, reject) {
44631        var results = options.results ? options.results : [],
44632            url = options.url,
44633            body = options.body,
44634            decode = options.decode,
44635            paramSeparator = "?",
44636            fields = options.fields; // Partial response
44637
44638        if (apiKey) {
44639          url = url + paramSeparator + "key=" + apiKey;
44640          paramSeparator = "&";
44641        }
44642
44643        if (fields) {
44644          url = url + paramSeparator + "fields=" + fields;
44645        } // Start the recursive load cycle.  Data is fetched in chunks, if more data is available a "nextPageToken" is returned.
44646
44647
44648        return loadChunk();
44649
44650        function loadChunk(pageToken) {
44651          if (pageToken) {
44652            body.pageToken = pageToken;
44653          } else {
44654            if (body.pageToken !== undefined) delete body.pageToken; // Remove previous page token, if any
44655          }
44656
44657          var sendData = JSON.stringify(body);
44658          igvxhr.loadJson(url, {
44659            sendData: sendData,
44660            contentType: "application/json",
44661            headers: ga4ghHeaders() //    oauthToken: ga4ghToken()
44662
44663          }).then(function (json) {
44664            var nextPageToken, tmp;
44665
44666            if (json) {
44667              tmp = decode ? decode(json) : json;
44668
44669              if (tmp) {
44670                tmp.forEach(function (a) {
44671
44672                  {
44673                    results.push(a);
44674                  }
44675                });
44676              }
44677
44678              nextPageToken = json["nextPageToken"];
44679
44680              if (nextPageToken) {
44681                loadChunk(nextPageToken);
44682              } else {
44683                fulfill(results);
44684              }
44685            } else {
44686              fulfill(results);
44687            }
44688          }).catch(function (error) {
44689            reject(error);
44690          });
44691        }
44692      });
44693    }
44694
44695    function ga4ghHeaders() {
44696      return {
44697        "Cache-Control": "no-cache"
44698      };
44699    }
44700
44701    /*
44702     * The MIT License (MIT)
44703     *
44704     * Copyright (c) 2014 Broad Institute
44705     *
44706     * Permission is hereby granted, free of charge, to any person obtaining a copy
44707     * of this software and associated documentation files (the "Software"), to deal
44708     * in the Software without restriction, including without limitation the rights
44709     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
44710     * copies of the Software, and to permit persons to whom the Software is
44711     * furnished to do so, subject to the following conditions:
44712     *
44713     * The above copyright notice and this permission notice shall be included in
44714     * all copies or substantial portions of the Software.
44715     *
44716     *
44717     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44718     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44719     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44720     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44721     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44722     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44723     * THE SOFTWARE.
44724     */
44725    var CigarOperationTable = {
44726      "ALIGNMENT_MATCH": "M",
44727      "INSERT": "I",
44728      "DELETE": "D",
44729      "SKIP": "N",
44730      "CLIP_SOFT": "S",
44731      "CLIP_HARD": "H",
44732      "PAD": "P",
44733      "SEQUENCE_MATCH": "=",
44734      "SEQUENCE_MISMATCH": "X"
44735    };
44736
44737    const Ga4ghAlignmentReader = function (config, genome) {
44738      this.config = config;
44739      this.genome = genome;
44740      this.url = config.url;
44741      this.filter = new BamFilter(config.filter);
44742      this.readGroupSetIds = config.readGroupSetIds;
44743      this.authKey = config.authKey; // Might be undefined or nill
44744
44745      this.samplingWindowSize = config.samplingWindowSize === undefined ? 100 : config.samplingWindowSize;
44746      this.samplingDepth = config.samplingDepth === undefined ? 1000 : config.samplingDepth;
44747
44748      if (config.viewAsPairs) {
44749        this.pairsSupported = true;
44750      } else {
44751        this.pairsSupported = config.pairsSupported === undefined ? true : config.pairsSupported;
44752      }
44753    };
44754
44755    Ga4ghAlignmentReader.prototype.readAlignments = function (chr, bpStart, bpEnd) {
44756      const genome = this.genome;
44757      const self = this;
44758      return getChrAliasTable().then(function (chrAliasTable) {
44759        var queryChr = chrAliasTable.hasOwnProperty(chr) ? chrAliasTable[chr] : chr,
44760            readURL = self.url + "/reads/search";
44761        return ga4ghSearch({
44762          url: readURL,
44763          body: {
44764            "readGroupSetIds": [self.readGroupSetIds],
44765            "referenceName": queryChr,
44766            "start": bpStart,
44767            "end": bpEnd,
44768            "pageSize": "10000"
44769          },
44770          decode: decodeGa4ghReads,
44771          results: new AlignmentContainer(chr, bpStart, bpEnd, self.samplingWindowSize, self.samplingDepth, self.pairsSupported, self.alleleFreqThreshold)
44772        });
44773      });
44774
44775      function getChrAliasTable() {
44776        if (self.chrAliasTable) {
44777          return Promise.resolve(self.chrAliasTable);
44778        } else {
44779          return self.readMetadata().then(function (json) {
44780            self.chrAliasTable = {};
44781
44782            if (genome && json.readGroups && json.readGroups.length > 0) {
44783              var referenceSetId = json.readGroups[0].referenceSetId;
44784
44785              if (referenceSetId) {
44786                // Query for reference names to build an alias table (map of genome ref names -> dataset ref names)
44787                var readURL = self.url + "/references/search";
44788                return ga4ghSearch({
44789                  url: readURL,
44790                  body: {
44791                    "referenceSetId": referenceSetId
44792                  },
44793                  decode: function (j) {
44794                    return j.references;
44795                  }
44796                }).then(function (references) {
44797                  references.forEach(function (ref) {
44798                    var refName = ref.name,
44799                        alias = genome.getChromosomeName(refName);
44800                    self.chrAliasTable[alias] = refName;
44801                  });
44802                  return self.chrAliasTable;
44803                });
44804              } else {
44805                // Try hardcoded constants -- workaround for non-compliant data at Google
44806                populateChrAliasTable(self.chrAliasTable, self.config.datasetId);
44807                return self.chrAliasTable;
44808              }
44809            } else {
44810              // No browser object, can't build map.  This can occur when run from unit tests
44811              return self.chrAliasTable;
44812            }
44813          });
44814        }
44815      }
44816      /**
44817       * Decode an array of ga4gh read records
44818       *
44819        */
44820
44821
44822      function decodeGa4ghReads(j) {
44823        var i,
44824            jsonRecords = j.alignments,
44825            len = jsonRecords.length,
44826            alignment,
44827            jsonAlignment,
44828            cigarDecoded,
44829            alignments = [],
44830            mate,
44831            blocks;
44832
44833        for (i = 0; i < len; i++) {
44834          let record = jsonRecords[i];
44835          alignment = new BamAlignment();
44836          alignment.readName = record.fragmentName;
44837          alignment.properPlacement = record.properPlacement;
44838          alignment.duplicateFragment = record.duplicateFragment;
44839          alignment.numberReads = record.numberReads;
44840          alignment.fragmentLength = record.fragmentLength;
44841          alignment.readNumber = record.readNumber;
44842          alignment.failedVendorQualityChecks = record.failedVendorQualityChecks;
44843          alignment.secondaryAlignment = record.secondaryAlignment;
44844          alignment.supplementaryAlignment = record.supplementaryAlignment;
44845          alignment.seq = record.alignedSequence;
44846          alignment.qual = record.alignedQuality;
44847          alignment.matePos = record.nextMatePosition;
44848          alignment.tagDict = record.info;
44849          alignment.flags = encodeFlags();
44850          jsonAlignment = record.alignment;
44851
44852          if (jsonAlignment) {
44853            alignment.mapped = true;
44854            alignment.chr = record.alignment.position.referenceName;
44855            if (genome) alignment.chr = genome.getChromosomeName(alignment.chr);
44856            alignment.start = parseInt(record.alignment.position.position);
44857            alignment.strand = !record.alignment.position.reverseStrand;
44858            alignment.mq = record.alignment.mappingQuality;
44859            alignment.cigar = encodeCigar(record.alignment.cigar);
44860            cigarDecoded = translateCigar(record.alignment.cigar);
44861            alignment.lengthOnRef = cigarDecoded.lengthOnRef;
44862            blocks = makeBlocks(alignment, cigarDecoded.array);
44863            alignment.blocks = blocks.blocks;
44864            alignment.insertions = blocks.insertions;
44865          } else {
44866            alignment.mapped = false;
44867          }
44868
44869          mate = record.nextMatePosition;
44870
44871          if (mate) {
44872            alignment.mate = {
44873              chr: mate.referenceFrame,
44874              position: parseInt(mate.position),
44875              strand: !mate.reverseStrand
44876            };
44877          }
44878
44879          if (self.filter.pass(alignment)) {
44880            alignments.push(alignment);
44881          }
44882        }
44883
44884        return alignments; // Encode a cigar string -- used for popup text
44885
44886        function encodeCigar(cigarArray) {
44887          var cigarString = "";
44888          cigarArray.forEach(function (cigarUnit) {
44889            var op = CigarOperationTable[cigarUnit.operation],
44890                len = cigarUnit.operationLength;
44891            cigarString = cigarString + (len + op);
44892          });
44893          return cigarString;
44894        } // TODO -- implement me
44895
44896
44897        function encodeFlags(json) {
44898          return 0;
44899        }
44900
44901        function translateCigar(cigar) {
44902          var cigarUnit,
44903              opLen,
44904              opLtr,
44905              lengthOnRef = 0,
44906              cigarArray = [],
44907              i;
44908
44909          for (i = 0; i < cigar.length; i++) {
44910            cigarUnit = cigar[i];
44911            opLtr = CigarOperationTable[cigarUnit.operation];
44912            opLen = parseInt(cigarUnit.operationLength); // Google represents long as a String
44913
44914            if (opLtr === 'M' || opLtr === 'EQ' || opLtr === 'X' || opLtr === 'D' || opLtr === 'N' || opLtr === '=') lengthOnRef += opLen;
44915            cigarArray.push({
44916              len: opLen,
44917              ltr: opLtr
44918            });
44919          }
44920
44921          return {
44922            lengthOnRef: lengthOnRef,
44923            array: cigarArray
44924          };
44925        }
44926        /**
44927         * Split the alignment record into blocks as specified in the cigarArray.  Each aligned block contains
44928         * its portion of the read sequence and base quality strings.  A read sequence or base quality string
44929         * of "*" indicates the value is not recorded.  In all other cases the length of the block sequence (block.seq)
44930         * and quality string (block.qual) must == the block length.
44931         *
44932         * NOTE: Insertions are not yet treated // TODO
44933         *
44934         * @param record
44935         * @param cigarArray
44936         * @returns array of blocks
44937         */
44938
44939
44940        function makeBlocks(record, cigarArray) {
44941          var blocks = [],
44942              gaps,
44943              insertions,
44944              seqOffset = 0,
44945              pos = record.start,
44946              len = cigarArray.length,
44947              gapType;
44948
44949          for (var i = 0; i < len; i++) {
44950            var c = cigarArray[i];
44951
44952            switch (c.ltr) {
44953              case 'H':
44954                break;
44955              // ignore hard clips
44956
44957              case 'P':
44958                break;
44959              // ignore pads
44960
44961              case 'S':
44962                seqOffset += c.len;
44963                gapType = 'S';
44964                break;
44965              // soft clip read bases
44966
44967              case 'N':
44968              case 'D':
44969                if (gaps === undefined) {
44970                  gaps = [];
44971                }
44972
44973                gaps.push({
44974                  start: pos,
44975                  len: c.len,
44976                  type: c.ltr
44977                });
44978                pos += c.len;
44979                break;
44980
44981              case 'I':
44982                if (insertions === undefined) insertions = [];
44983                insertions.push(new AlignmentBlock({
44984                  start: pos,
44985                  len: c.len,
44986                  seqOffset: seqOffset
44987                }));
44988                seqOffset += c.len;
44989                break;
44990
44991              case 'M':
44992              case 'EQ':
44993              case '=':
44994              case 'X':
44995                blocks.push(new AlignmentBlock({
44996                  start: pos,
44997                  len: c.len,
44998                  seqOffset: seqOffset,
44999                  gapType: gapType
45000                }));
45001                seqOffset += c.len;
45002                pos += c.len;
45003                break;
45004
45005              default:
45006                console.log("Error processing cigar element: " + c.len + c.ltr);
45007            }
45008          }
45009
45010          return {
45011            blocks: blocks,
45012            insertions: insertions,
45013            gaps: gaps
45014          };
45015        }
45016      }
45017    };
45018
45019    Ga4ghAlignmentReader.prototype.readMetadata = function () {
45020      return ga4ghGet({
45021        url: this.url,
45022        entity: "readgroupsets",
45023        entityId: this.readGroupSetIds
45024      });
45025    };
45026    /**
45027     * Hardcoded hack to work around some non-compliant google datasets
45028     *
45029     * @param chrAliasTable
45030     * @param datasetId
45031     */
45032
45033
45034    function populateChrAliasTable(chrAliasTable, datasetId) {
45035      var i;
45036
45037      if ("461916304629" === datasetId || "337315832689" === datasetId) {
45038        for (i = 1; i < 23; i++) {
45039          chrAliasTable["chr" + i] = i;
45040        }
45041
45042        chrAliasTable["chrX"] = "X";
45043        chrAliasTable["chrY"] = "Y";
45044        chrAliasTable["chrM"] = "MT";
45045      }
45046    }
45047
45048    /*
45049     * The MIT License (MIT)
45050     *
45051     * Copyright (c) 2014 Broad Institute
45052     *
45053     * Permission is hereby granted, free of charge, to any person obtaining a copy
45054     * of this software and associated documentation files (the "Software"), to deal
45055     * in the Software without restriction, including without limitation the rights
45056     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
45057     * copies of the Software, and to permit persons to whom the Software is
45058     * furnished to do so, subject to the following conditions:
45059     *
45060     * The above copyright notice and this permission notice shall be included in
45061     * all copies or substantial portions of the Software.
45062     *
45063     *
45064     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45065     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45066     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45067     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45068     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45069     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45070     * THE SOFTWARE.
45071     */
45072
45073    class BamSource {
45074      constructor(config, browser) {
45075        const genome = browser.genome;
45076        this.config = config;
45077        this.genome = genome;
45078        this.alignmentContainer = undefined;
45079
45080        if (isDataURL(config.url)) {
45081          if ("cram" === config.format) {
45082            throw "CRAM data uris are not supported";
45083          }
45084
45085          this.config.indexed = false;
45086        }
45087
45088        if ("ga4gh" === config.sourceType) {
45089          this.bamReader = new Ga4ghAlignmentReader(config, genome);
45090        } else if ("pysam" === config.sourceType) {
45091          this.bamReader = new BamWebserviceReader(config, genome);
45092        } else if ("htsget" === config.sourceType) {
45093          this.bamReader = new HtsgetBamReader(config, genome);
45094        } else if ("shardedBam" === config.sourceType) {
45095          this.bamReader = new ShardedBamReader(config, genome);
45096        } else if ("cram" === config.format) {
45097          this.bamReader = new CramReader(config, genome, browser);
45098        } else {
45099          if (!this.config.indexURL && config.indexed !== false) {
45100            if (isString$3(this.config.url)) {
45101              const inferIndexPath$1 = inferIndexPath(this.config.url, "bai");
45102
45103              if (inferIndexPath$1) {
45104                console.error(`Warning: no indexURL specified for ${this.config.url}.  Guessing ${this.baiPath}`);
45105                this.config.indexURL = inferIndexPath$1;
45106              } else {
45107                console.error(`Warning: no indexURL specified for ${this.config.url}.`);
45108                this.config.indexed = false;
45109              }
45110            } else {
45111              console.error(`Warning: no indexURL specified for ${this.config.name}.`);
45112              this.config.indexed = false;
45113            }
45114          }
45115
45116          if (this.config.indexed !== false) {
45117            // && this.config.indexURL) {
45118            this.bamReader = new BamReader(config, genome);
45119          } else {
45120            this.bamReader = new BamReaderNonIndexed(config, genome);
45121          }
45122        }
45123
45124        this.viewAsPairs = config.viewAsPairs;
45125        this.showSoftClips = config.showSoftClips;
45126      }
45127
45128      setViewAsPairs(bool) {
45129
45130        if (this.viewAsPairs !== bool) {
45131          this.viewAsPairs = bool; // if (this.alignmentContainer) {
45132          //     this.alignmentContainer.setViewAsPairs(bool);
45133          // }
45134        }
45135      }
45136
45137      setShowSoftClips(bool) {
45138        if (this.showSoftClips !== bool) {
45139          this.showSoftClips = bool;
45140        }
45141      }
45142
45143      async getAlignments(chr, bpStart, bpEnd) {
45144        const genome = this.genome;
45145        const showSoftClips = this.showSoftClips;
45146
45147        if (this.alignmentContainer && this.alignmentContainer.contains(chr, bpStart, bpEnd)) {
45148          return this.alignmentContainer;
45149        } else {
45150          const alignmentContainer = await this.bamReader.readAlignments(chr, bpStart, bpEnd);
45151          let alignments = alignmentContainer.alignments;
45152
45153          if (!this.viewAsPairs) {
45154            alignments = unpairAlignments([{
45155              alignments: alignments
45156            }]);
45157          }
45158
45159          const hasAlignments = alignments.length > 0;
45160          alignmentContainer.packedAlignmentRows = packAlignmentRows(alignments, alignmentContainer.start, alignmentContainer.end, showSoftClips);
45161          alignmentContainer.alignments = undefined; // Don't need to hold onto these anymore
45162
45163          this.alignmentContainer = alignmentContainer;
45164
45165          if (hasAlignments) {
45166            const sequence = await genome.sequence.getSequence(chr, alignmentContainer.start, alignmentContainer.end);
45167
45168            if (sequence) {
45169              alignmentContainer.coverageMap.refSeq = sequence; // TODO -- fix this
45170
45171              alignmentContainer.sequence = sequence; // TODO -- fix this
45172
45173              return alignmentContainer;
45174            } else {
45175              console.error("No sequence for: " + chr + ":" + alignmentContainer.start + "-" + alignmentContainer.end);
45176            }
45177          }
45178
45179          return alignmentContainer;
45180        }
45181      }
45182
45183    }
45184
45185    /*
45186     * The MIT License (MIT)
45187     *
45188     * Copyright (c) 2018 Regents of the University of California
45189     *
45190     * Permission is hereby granted, free of charge, to any person obtaining a copy
45191     * of this software and associated documentation files (the "Software"), to deal
45192     * in the Software without restriction, including without limitation the rights
45193     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
45194     * copies of the Software, and to permit persons to whom the Software is
45195     * furnished to do so, subject to the following conditions:
45196     *
45197     * The above copyright notice and this permission notice shall be included in
45198     * all copies or substantial portions of the Software.
45199     *
45200     *
45201     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45202     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45203     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45204     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45205     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45206     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45207     * THE SOFTWARE.
45208     */
45209    /**
45210     * A collection of properties and methods shared by all (or most) track types.
45211     *
45212     * @param config
45213     * @param browser
45214     * @constructor
45215     */
45216
45217    class TrackBase {
45218      constructor(config, browser) {
45219        this.browser = browser;
45220        this.init(config);
45221      }
45222      /**
45223       * Initialize track properties from the config object.  This method is typically overriden in subclasses, which
45224       * will call this implementation as super.init(config).
45225       *
45226       * @param config
45227       */
45228
45229
45230      init(config) {
45231        if (config.displayMode) {
45232          config.displayMode = config.displayMode.toUpperCase();
45233        }
45234
45235        this.config = config;
45236        this.url = config.url;
45237        this.type = config.type;
45238        this.description = config.description;
45239        this.supportHiDPI = config.supportHiDPI === undefined ? true : config.supportHiDPI;
45240
45241        if (config.name || config.label) {
45242          this.name = config.name || config.label;
45243        } else if (isFile(config.url)) {
45244          this.name = config.url.name;
45245        } else if (isString$3(config.url) && !config.url.startsWith("data:")) {
45246          this.name = getFilename$1(config.url);
45247        }
45248
45249        this.id = this.config.id === undefined ? this.name : this.config.id;
45250        this.order = config.order;
45251        this.color = config.color;
45252        this.altColor = config.altColor;
45253
45254        if ("civic-ws" === config.sourceType) {
45255          // Ugly proxy for specialized track type
45256          this.defaultColor = "rgb(155,20,20)";
45257        } else {
45258          this.defaultColor = "rgb(0,0,150)";
45259        }
45260
45261        this.autoscaleGroup = config.autoscaleGroup;
45262        this.removable = config.removable === undefined ? true : config.removable; // Defaults to true
45263
45264        this.height = config.height || 100;
45265        this.autoHeight = config.autoHeight;
45266        this.minHeight = config.minHeight || Math.min(25, this.height);
45267        this.maxHeight = config.maxHeight || Math.max(1000, this.height);
45268        this.visibilityWindow = config.visibilityWindow;
45269
45270        if (config.onclick) {
45271          this.onclick = config.onclick;
45272          config.onclick = undefined; // functions cannot be saved in sessions, clear it here.
45273        }
45274      }
45275
45276      get name() {
45277        return this._name;
45278      }
45279
45280      set name(name) {
45281        this._name = name;
45282
45283        if (this.trackView) {
45284          this.trackView.setTrackLabelName(name);
45285        }
45286      }
45287      /**
45288       * Update track properties from the config object.
45289       *
45290       * @param config
45291       */
45292
45293
45294      updateConfig(config) {
45295        this.init(config);
45296      }
45297      /**
45298       * Default implementation -- update config with current values.
45299       * to create session object for bookmarking, sharing.  Updates the track "config" object to reflect the
45300       * current state.  Only simple properties (string, number, boolean) are updated.
45301       */
45302
45303
45304      getState() {
45305        // Create copy of config, minus transient properties (convention is name starts with '_').  Also, all
45306        // function properties are transient as they cannot be saved in json
45307        const state = {};
45308
45309        for (let key of Object.keys(this.config)) {
45310          if (!key.startsWith("_") && typeof this.config[key] !== "function" && this.config[key] !== undefined) {
45311            state[key] = this.config[key];
45312          }
45313        } // Update original config values with any changes
45314
45315
45316        for (let key of Object.keys(state)) {
45317          if (key.startsWith("_")) continue; // transient property
45318
45319          const value = this[key];
45320
45321          if (value && (isSimpleType(value) || typeof value === "boolean")) {
45322            state[key] = value;
45323          }
45324        }
45325
45326        if (this.color) state.color = this.color;
45327        if (this.altColor) state.altColor = this.altColor; // Flatten dataRange if present
45328
45329        if (!this.autoscale && this.dataRange) {
45330          state.min = this.dataRange.min;
45331          state.max = this.dataRange.max;
45332        } // Check for non-json-if-yable properties.  Perhaps we should test what can be saved.
45333
45334
45335        for (let key of Object.keys(state)) {
45336          if (typeof state[key] === 'function') {
45337            throw Error(`Property '${key}' of track '${this.name} is a function. Functions cannot be saved in sessions.`);
45338          }
45339
45340          if (isFile(state[key])) {
45341            const str = `Track ${this.name} is a local file. Sessions cannot be saved with local file references.`;
45342            throw Error(str);
45343          }
45344
45345          if (state[key] instanceof Promise) {
45346            throw Error(`Property '${key}' of track '${this.name} is a Promise. Promises cannot be saved in sessions.`);
45347          }
45348        }
45349
45350        return state;
45351      }
45352
45353      supportsWholeGenome() {
45354        return false;
45355      }
45356      /**
45357       * Does the track support sample names.  Current sample aware tracks include VCF (with genotypes), MUT, MAF, and SEG
45358       * @returns {boolean}
45359       */
45360
45361
45362      hasSamples() {
45363        return false;
45364      }
45365
45366      getGenomeId() {
45367        return this.browser.genome ? this.browser.genome.id : undefined;
45368      }
45369      /**
45370       * Set certain track properties, usually from a "track" line.  Not all UCSC properties are supported.
45371       *
45372       * Track configuration settings have precendence over track line properties, so if both are present ignore the
45373       * track line.
45374       *
45375       * @param properties
45376       */
45377
45378
45379      setTrackProperties(properties) {
45380        const tracklineConfg = {};
45381        let tokens;
45382
45383        for (let key of Object.keys(properties)) {
45384          switch (key.toLowerCase()) {
45385            case "usescore":
45386              tracklineConfg.useScore = properties[key] === 1 || properties[key] === "1" || properties[key] === "on" || properties[key] === true;
45387              break;
45388
45389            case "visibility":
45390              //0 - hide, 1 - dense, 2 - full, 3 - pack, and 4 - squish
45391              switch (properties[key]) {
45392                case "2":
45393                case "3":
45394                case "pack":
45395                case "full":
45396                  tracklineConfg.displayMode = "EXPANDED";
45397                  break;
45398
45399                case "4":
45400                case "squish":
45401                  tracklineConfg.displayMode = "SQUISHED";
45402                  break;
45403
45404                case "1":
45405                case "dense":
45406                  tracklineConfg.displayMode = "COLLAPSED";
45407              }
45408
45409              break;
45410
45411            case "color":
45412            case "altcolor":
45413              tracklineConfg[key] = properties[key].startsWith("rgb(") ? properties[key] : "rgb(" + properties[key] + ")";
45414              break;
45415
45416            case "featurevisiblitywindow":
45417            case "visibilitywindow":
45418              tracklineConfg.visibilityWindow = Number.parseInt(properties[key]);
45419              break;
45420
45421            case "maxheightpixels":
45422              tokens = properties[key].split(":");
45423
45424              if (tokens.length === 3) {
45425                tracklineConfg.minHeight = Number.parseInt(tokens[2]);
45426                tracklineConfg.height = Number.parseInt(tokens[1]);
45427                tracklineConfg.maxHeight = Number.parseInt(tokens[0]);
45428              }
45429
45430              break;
45431
45432            case "viewlimits":
45433              if (!this.config.autoscale) {
45434                // autoscale in the config has precedence
45435                tokens = properties[key].split(":");
45436                let min = 0;
45437                let max;
45438
45439                if (tokens.length == 1) {
45440                  max = Number(tokens[0]);
45441                } else if (tokens.length == 2) {
45442                  min = Number(tokens[0]);
45443                  max = Number(tokens[1]);
45444                }
45445
45446                tracklineConfg.autoscale = false;
45447                tracklineConfg.dataRange = {
45448                  min,
45449                  max
45450                };
45451              }
45452
45453            case "name":
45454              tracklineConfg[key] = properties[key];
45455              break;
45456
45457            case "url":
45458              tracklineConfg["infoURL"] = properties[key];
45459              break;
45460
45461            case "type":
45462              const v = properties[key];
45463
45464              if (UCSCTypeMappings.has(v)) {
45465                tracklineConfg[key] = UCSCTypeMappings.get(v);
45466              } else {
45467                tracklineConfg[key] = v;
45468              }
45469
45470              break;
45471
45472            case "graphtype":
45473              tracklineConfg["graphType"] = properties[key];
45474              break;
45475
45476            default:
45477              tracklineConfg[key] = properties[key];
45478          }
45479        } // Track configuration objects have precedence over track line properties in general.  The "name" property
45480        // is an exception if it was derived and not explicitly entered (that is derived from the web app from filename).
45481
45482
45483        for (let key of Object.keys(tracklineConfg)) {
45484          if (!this.config.hasOwnProperty(key) || key === "name" && this.config._derivedName) {
45485            let value = tracklineConfg[key];
45486            if ("true" === value) value = true;
45487            if ("false" === value) value = false;
45488            this[key] = value;
45489
45490            if (key === "height" && this.trackView) {
45491              try {
45492                const h = Number.parseInt(value);
45493                this.trackView.setTrackHeight(h);
45494              } catch (e) {
45495                console.error(e);
45496              }
45497            }
45498          }
45499        }
45500      }
45501      /**
45502       * Return the features clicked over.  Default implementation assumes a single row of features and only considers
45503       * the genomic location.   Overriden by most subclasses.
45504       *
45505       * @param clickState
45506       * @param features
45507       * @returns {[]|*[]}
45508       */
45509
45510
45511      clickedFeatures(clickState, features) {
45512        // We use the cached features rather than method to avoid async load.  If the
45513        // feature is not already loaded this won't work,  but the user wouldn't be mousing over it either.
45514        if (!features) features = clickState.viewport.getCachedFeatures();
45515
45516        if (!features || features.length === 0) {
45517          return [];
45518        }
45519
45520        const genomicLocation = clickState.genomicLocation; // When zoomed out we need some tolerance around genomicLocation
45521
45522        const tolerance = clickState.referenceFrame.bpPerPixel > 0.2 ? 3 * clickState.referenceFrame.bpPerPixel : 0.2;
45523        const ss = genomicLocation - tolerance;
45524        const ee = genomicLocation + tolerance;
45525        return FeatureUtils.findOverlapping(features, ss, ee);
45526      }
45527      /**
45528       * Default popup text function -- just extracts string and number properties in random order.
45529       * @param feature
45530       * @returns {Array}
45531       */
45532
45533
45534      extractPopupData(feature, genomeId) {
45535        const filteredProperties = new Set(['row', 'color', 'chr', 'start', 'end', 'cdStart', 'cdEnd', 'strand', 'alpha']);
45536        const data = [];
45537        let alleles, alleleFreqs;
45538
45539        for (let property in feature) {
45540          if (feature.hasOwnProperty(property) && !filteredProperties.has(property) && isSimpleType(feature[property])) {
45541            let value = feature[property];
45542            data.push({
45543              name: capitalize(property),
45544              value: value
45545            });
45546
45547            if (property === "alleles") {
45548              alleles = feature[property];
45549            } else if (property === "alleleFreqs") {
45550              alleleFreqs = feature[property];
45551            }
45552          }
45553        }
45554
45555        if (alleles && alleleFreqs) {
45556          if (alleles.endsWith(",")) {
45557            alleles = alleles.substr(0, alleles.length - 1);
45558          }
45559
45560          if (alleleFreqs.endsWith(",")) {
45561            alleleFreqs = alleleFreqs.substr(0, alleleFreqs.length - 1);
45562          }
45563
45564          let a = alleles.split(",");
45565          let af = alleleFreqs.split(",");
45566
45567          if (af.length > 1) {
45568            let b = [];
45569
45570            for (let i = 0; i < af.length; i++) {
45571              b.push({
45572                a: a[i],
45573                af: Number(af[i])
45574              });
45575            }
45576
45577            b.sort(function (x, y) {
45578              return x.af - y.af;
45579            });
45580            let ref = b[b.length - 1].a;
45581
45582            if (ref.length === 1) {
45583              for (let i = b.length - 2; i >= 0; i--) {
45584                let alt = b[i].a;
45585
45586                if (alt.length === 1) {
45587                  if (!genomeId) genomeId = this.getGenomeId();
45588                  const cravatLink = TrackBase.getCravatLink(feature.chr, feature.start + 1, ref, alt, genomeId);
45589                  console.log(cravatLink);
45590
45591                  if (cravatLink) {
45592                    data.push('<hr/>');
45593                    data.push({
45594                      html: cravatLink
45595                    });
45596                    data.push('<hr/>');
45597                  }
45598                }
45599              }
45600            }
45601          }
45602        }
45603
45604        if (feature.attributes) {
45605          for (let key of Object.keys(feature.attributes)) {
45606            data.push({
45607              name: key,
45608              value: feature.attributes[key]
45609            });
45610          }
45611        } // final chr position
45612
45613
45614        let posString = `${feature.chr}:${numberFormatter$1(feature.start + 1)}
45614-${numberFormatter$1(feature.end)}`;
45615
45616        if (feature.strand) {
45617          posString += ` (${feature.strand})`;
45618        }
45619
45620        data.push({
45621          name: 'Location',
45622          value: posString
45623        });
45624        return data;
45625      }
45626
45627      static getCravatLink(chr, position, ref, alt, genomeID) {
45628        if ("hg38" === genomeID || "GRCh38" === genomeID) {
45629          const cravatChr = chr.startsWith("chr") ? chr : "chr" + chr;
45630          return `<a target="_blank" href="https://run.opencravat.org/result/nocache/variant.html` + `?chrom=${cravatChr}&pos=${position}&ref_base=${ref}&alt_base=${alt}"><b>Cravat ${ref}->${alt}</b></a>`;
45631        } else {
45632          return undefined;
45633        }
45634      }
45635
45636    }
45637    /**
45638     * Map UCSC track line "type" setting to file format.  In igv.js "type" refers to the track type, not the input file format
45639     * @type {Map<string, string>}
45640     */
45641
45642
45643    const UCSCTypeMappings = new Map([["wiggle_0", "wig"], ["bed", "bed"], ["bigBed", "bigBed"], ["bigWig", "bigWig"]]);
45644
45645    function paintAxis(ctx, pixelWidth, pixelHeight) {
45646      var x1,
45647          x2,
45648          y1,
45649          y2,
45650          a,
45651          b,
45652          reference,
45653          shim,
45654          font = {
45655        'font': 'normal 10px Arial',
45656        'textAlign': 'right',
45657        'strokeStyle': "black"
45658      };
45659
45660      if (undefined === this.dataRange || undefined === this.dataRange.max || undefined === this.dataRange.min) {
45661        return;
45662      }
45663
45664      IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {
45665        'fillStyle': "rgb(255, 255, 255)"
45666      });
45667      reference = 0.95 * pixelWidth;
45668      x1 = reference - 8;
45669      x2 = reference; //shim = 0.5 * 0.125;
45670
45671      shim = .01;
45672      y1 = y2 = shim * pixelHeight;
45673      a = {
45674        x: x2,
45675        y: y1
45676      }; // tick
45677
45678      IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, font);
45679      IGVGraphics.fillText(ctx, prettyPrint(this.dataRange.max), x1 + 4, y1 + 12, font); //shim = 0.25 * 0.125;
45680
45681      y1 = y2 = (1.0 - shim) * pixelHeight;
45682      b = {
45683        x: x2,
45684        y: y1
45685      }; // tick
45686
45687      IGVGraphics.strokeLine(ctx, x1, y1, x2, y2, font);
45688      IGVGraphics.fillText(ctx, prettyPrint(this.dataRange.min), x1 + 4, y1 - 4, font);
45689      IGVGraphics.strokeLine(ctx, a.x, a.y, b.x, b.y, font);
45690
45691      function prettyPrint(number) {
45692        // if number >= 100, show whole number
45693        // if >= 1 show 1 significant digits
45694        // if <  1 show 2 significant digits
45695        if (number === 0) {
45696          return "0";
45697        } else if (Math.abs(number) >= 10) {
45698          return number.toFixed();
45699        } else if (Math.abs(number) >= 1) {
45700          return number.toFixed(1);
45701        } else {
45702          return number.toFixed(2);
45703        }
45704      }
45705    }
45706
45707    const appleCrayonRGBPalette = {
45708      cantaloupe: {
45709        r: 255,
45710        g: 206,
45711        b: 110
45712      },
45713      honeydew: {
45714        r: 206,
45715        g: 250,
45716        b: 110
45717      },
45718      spindrift: {
45719        r: 104,
45720        g: 251,
45721        b: 208
45722      },
45723      sky: {
45724        r: 106,
45725        g: 207,
45726        b: 255
45727      },
45728      lavender: {
45729        r: 210,
45730        g: 120,
45731        b: 255
45732      },
45733      carnation: {
45734        r: 255,
45735        g: 127,
45736        b: 211
45737      },
45738      licorice: {
45739        r: 0,
45740        g: 0,
45741        b: 0
45742      },
45743      snow: {
45744        r: 255,
45745        g: 255,
45746        b: 255
45747      },
45748      salmon: {
45749        r: 255,
45750        g: 114,
45751        b: 110
45752      },
45753      banana: {
45754        r: 255,
45755        g: 251,
45756        b: 109
45757      },
45758      flora: {
45759        r: 104,
45760        g: 249,
45761        b: 110
45762      },
45763      ice: {
45764        r: 104,
45765        g: 253,
45766        b: 255
45767      },
45768      orchid: {
45769        r: 110,
45770        g: 118,
45771        b: 255
45772      },
45773      bubblegum: {
45774        r: 255,
45775        g: 122,
45776        b: 255
45777      },
45778      lead: {
45779        r: 30,
45780        g: 30,
45781        b: 30
45782      },
45783      mercury: {
45784        r: 232,
45785        g: 232,
45786        b: 232
45787      },
45788      tangerine: {
45789        r: 255,
45790        g: 136,
45791        b: 2
45792      },
45793      lime: {
45794        r: 131,
45795        g: 249,
45796        b: 2
45797      },
45798      sea_foam: {
45799        r: 3,
45800        g: 249,
45801        b: 135
45802      },
45803      aqua: {
45804        r: 0,
45805        g: 140,
45806        b: 255
45807      },
45808      grape: {
45809        r: 137,
45810        g: 49,
45811        b: 255
45812      },
45813      strawberry: {
45814        r: 255,
45815        g: 41,
45816        b: 135
45817      },
45818      tungsten: {
45819        r: 58,
45820        g: 58,
45821        b: 58
45822      },
45823      silver: {
45824        r: 208,
45825        g: 208,
45826        b: 208
45827      },
45828      maraschino: {
45829        r: 255,
45830        g: 33,
45831        b: 1
45832      },
45833      lemon: {
45834        r: 255,
45835        g: 250,
45836        b: 3
45837      },
45838      spring: {
45839        r: 5,
45840        g: 248,
45841        b: 2
45842      },
45843      turquoise: {
45844        r: 0,
45845        g: 253,
45846        b: 255
45847      },
45848      blueberry: {
45849        r: 0,
45850        g: 46,
45851        b: 255
45852      },
45853      magenta: {
45854        r: 255,
45855        g: 57,
45856        b: 255
45857      },
45858      iron: {
45859        r: 84,
45860        g: 84,
45861        b: 83
45862      },
45863      magnesium: {
45864        r: 184,
45865        g: 184,
45866        b: 184
45867      },
45868      mocha: {
45869        r: 137,
45870        g: 72,
45871        b: 0
45872      },
45873      fern: {
45874        r: 69,
45875        g: 132,
45876        b: 1
45877      },
45878      moss: {
45879        r: 1,
45880        g: 132,
45881        b: 72
45882      },
45883      ocean: {
45884        r: 0,
45885        g: 74,
45886        b: 136
45887      },
45888      eggplant: {
45889        r: 73,
45890        g: 26,
45891        b: 136
45892      },
45893      maroon: {
45894        r: 137,
45895        g: 22,
45896        b: 72
45897      },
45898      steel: {
45899        r: 110,
45900        g: 110,
45901        b: 110
45902      },
45903      aluminum: {
45904        r: 160,
45905        g: 159,
45906        b: 160
45907      },
45908      cayenne: {
45909        r: 137,
45910        g: 17,
45911        b: 0
45912      },
45913      aspargus: {
45914        r: 136,
45915        g: 133,
45916        b: 1
45917      },
45918      clover: {
45919        r: 2,
45920        g: 132,
45921        b: 1
45922      },
45923      teal: {
45924        r: 0,
45925        g: 134,
45926        b: 136
45927      },
45928      midnight: {
45929        r: 0,
45930        g: 24,
45931        b: 136
45932      },
45933      plum: {
45934        r: 137,
45935        g: 30,
45936        b: 136
45937      },
45938      tin: {
45939        r: 135,
45940        g: 134,
45941        b: 135
45942      },
45943      nickel: {
45944        r: 136,
45945        g: 135,
45946        b: 135
45947      }
45948    };
45949
45950    function appleCrayonRGB(name) {
45951      const {
45952        r,
45953        g,
45954        b
45955      } = appleCrayonRGBPalette[name];
45956      return `rgb(${r},${g},${b})`;
45957    }
45958
45959    const colorPalettes = {
45960      Set1: ["rgb(228,26,28)", "rgb(55,126,184)", "rgb(77,175,74)", "rgb(166,86,40)", "rgb(152,78,163)", "rgb(255,127,0)", "rgb(247,129,191)", "rgb(153,153,153)", "rgb(255,255,51)"],
45961      Dark2: ["rgb(27,158,119)", "rgb(217,95,2)", "rgb(117,112,179)", "rgb(231,41,138)", "rgb(102,166,30)", "rgb(230,171,2)", "rgb(166,118,29)", "rgb(102,102,102)"],
45962      Set2: ["rgb(102, 194,165)", "rgb(252,141,98)", "rgb(141,160,203)", "rgb(231,138,195)", "rgb(166,216,84)", "rgb(255,217,47)", "rgb(229,196,148)", "rgb(179,179,179)"],
45963      Set3: ["rgb(141,211,199)", "rgb(255,255,179)", "rgb(190,186,218)", "rgb(251,128,114)", "rgb(128,177,211)", "rgb(253,180,98)", "rgb(179,222,105)", "rgb(252,205,229)", "rgb(217,217,217)", "rgb(188,128,189)", "rgb(204,235,197)", "rgb(255,237,111)"],
45964      Pastel1: ["rgb(251,180,174)", "rgb(179,205,227)", "rgb(204,235,197)", "rgb(222,203,228)", "rgb(254,217,166)", "rgb(255,255,204)", "rgb(229,216,189)", "rgb(253,218,236)"],
45965      Pastel2: ["rgb(173,226,207)", "rgb(253,205,172)", "rgb(203,213,232)", "rgb(244,202,228)", "rgb(230,245,201)", "rgb(255,242,174)", "rgb(243,225,206)"],
45966      Accent: ["rgb(127,201,127)", "rgb(190,174,212)", "rgb(253,192,134)", "rgb(255,255,153)", "rgb(56,108,176)", "rgb(240,2,127)", "rgb(191,91,23)"]
45967    };
45968
45969    class PaletteColorTable {
45970      constructor(palette) {
45971        this.colors = colorPalettes[palette];
45972        if (!Array.isArray(this.colors)) this.colors = [];
45973        this.colorTable = {};
45974        this.nextIdx = 0;
45975        this.colorGenerator = new RandomColorGenerator();
45976      }
45977
45978      getColor(key) {
45979        if (!this.colorTable.hasOwnProperty(key)) {
45980          if (this.nextIdx < this.colors.length) {
45981            this.colorTable[key] = this.colors[this.nextIdx];
45982          } else {
45983            this.colorTable[key] = this.colorGenerator.get();
45984          }
45985
45986          this.nextIdx++;
45987        }
45988
45989        return this.colorTable[key];
45990      }
45991
45992    }
45993
45994    class ColorTable {
45995      constructor(colors) {
45996        this.colorTable = colors || {};
45997        this.nextIdx = 0;
45998        this.colorGenerator = new RandomColorGenerator();
45999      }
46000
46001      getColor(key) {
46002        if (!this.colorTable.hasOwnProperty(key)) {
46003          if (this.colorTable.hasOwnProperty("*")) {
46004            return this.colorTable["*"];
46005          }
46006
46007          this.colorTable[key] = this.colorGenerator.get();
46008        }
46009
46010        return this.colorTable[key];
46011      }
46012
46013    } // Random color generator from https://github.com/sterlingwes/RandomColor/blob/master/rcolor.js
46014    // Free to use & distribute under the MIT license
46015    // Wes Johnson (@SterlingWes)
46016    //
46017    // inspired by http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
46018
46019
46020    function RandomColorGenerator() {
46021      this.hue = Math.random();
46022      this.goldenRatio = 0.618033988749895;
46023      this.hexwidth = 2;
46024    }
46025
46026    RandomColorGenerator.prototype.hsvToRgb = function (h, s, v) {
46027      var h_i = Math.floor(h * 6),
46028          f = h * 6 - h_i,
46029          p = v * (1 - s),
46030          q = v * (1 - f * s),
46031          t = v * (1 - (1 - f) * s),
46032          r = 255,
46033          g = 255,
46034          b = 255;
46035
46036      switch (h_i) {
46037        case 0:
46038          r = v, g = t, b = p;
46039          break;
46040
46041        case 1:
46042          r = q, g = v, b = p;
46043          break;
46044
46045        case 2:
46046          r = p, g = v, b = t;
46047          break;
46048
46049        case 3:
46050          r = p, g = q, b = v;
46051          break;
46052
46053        case 4:
46054          r = t, g = p, b = v;
46055          break;
46056
46057        case 5:
46058          r = v, g = p, b = q;
46059          break;
46060      }
46061
46062      return [Math.floor(r * 256), Math.floor(g * 256), Math.floor(b * 256)];
46063    };
46064
46065    RandomColorGenerator.prototype.padHex = function (str) {
46066      if (str.length > this.hexwidth) return str;
46067      return new Array(this.hexwidth - str.length + 1).join('0') + str;
46068    };
46069
46070    RandomColorGenerator.prototype.get = function (saturation, value) {
46071      this.hue += this.goldenRatio;
46072      this.hue %= 1;
46073      if (typeof saturation !== "number") saturation = 0.5;
46074      if (typeof value !== "number") value = 0.95;
46075      var rgb = this.hsvToRgb(this.hue, saturation, value);
46076      return "#" + this.padHex(rgb[0].toString(16)) + this.padHex(rgb[1].toString(16)) + this.padHex(rgb[2].toString(16));
46077    };
46078
46079    const randomColorGenerator = new RandomColorGenerator();
46080
46081    function randomColor() {
46082      return randomColorGenerator.get();
46083    } // Returns a random number between min (inclusive) and max (exclusive)
46084
46085    class Locus {
46086      constructor(_ref) {
46087        let {
46088          chr,
46089          start,
46090          end
46091        } = _ref;
46092        this.chr = chr;
46093        this.start = start;
46094        this.end = end;
46095      }
46096
46097      contains(locus) {
46098        return locus.chr === this.chr && locus.start >= this.start && locus.end <= this.end;
46099      }
46100
46101      overlaps(locus) {
46102        return locus.chr === this.chr && !(locus.end < this.start || locus.start > this.end);
46103      }
46104
46105      extend(l) {
46106        if (l.chr !== this.chr) return;
46107        this.start = Math.min(l.start, this.start);
46108        this.end = Math.max(l.end, this.end);
46109      }
46110
46111      getLocusString() {
46112        if ('all' === this.chr) {
46113          return 'all';
46114        } else {
46115          const ss = numberFormatter$1(Math.floor(this.start) + 1);
46116          const ee = numberFormatter$1(Math.round(this.end));
46117          return `${this.chr}:${ss}-${ee}`;
46118        }
46119      }
46120
46121      static fromLocusString(str) {
46122        if ('all' === str) {
46123          return new Locus({
46124            chr: 'all'
46125          });
46126        }
46127
46128        const parts = str.split(':');
46129        const chr = parts[0];
46130        const se = parts[1].split("-");
46131        const start = Number.parseInt(se[0].replace(/,/g, "")) - 1;
46132        const end = Number.parseInt(se[1].replace(/,/g, ""));
46133        return new Locus({
46134          chr,
46135          start,
46136          end
46137        });
46138      }
46139
46140    }
46141
46142    /*!
46143     * vanilla-picker v2.12.1
46144     * https://vanilla-picker.js.org
46145     *
46146     * Copyright 2017-2021 Andreas Borgen (https://github.com/Sphinxxxx), Adam Brooks (https://github.com/dissimulate)
46147     * Released under the ISC license.
46148     */
46149    var classCallCheck = function (instance, Constructor) {
46150      if (!(instance instanceof Constructor)) {
46151        throw new TypeError("Cannot call a class as a function");
46152      }
46153    };
46154
46155    var createClass = function () {
46156      function defineProperties(target, props) {
46157        for (var i = 0; i < props.length; i++) {
46158          var descriptor = props[i];
46159          descriptor.enumerable = descriptor.enumerable || false;
46160          descriptor.configurable = true;
46161          if ("value" in descriptor) descriptor.writable = true;
46162          Object.defineProperty(target, descriptor.key, descriptor);
46163        }
46164      }
46165
46166      return function (Constructor, protoProps, staticProps) {
46167        if (protoProps) defineProperties(Constructor.prototype, protoProps);
46168        if (staticProps) defineProperties(Constructor, staticProps);
46169        return Constructor;
46170      };
46171    }();
46172
46173    var slicedToArray = function () {
46174      function sliceIterator(arr, i) {
46175        var _arr = [];
46176        var _n = true;
46177        var _d = false;
46178        var _e = undefined;
46179
46180        try {
46181          for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
46182            _arr.push(_s.value);
46183
46184            if (i && _arr.length === i) break;
46185          }
46186        } catch (err) {
46187          _d = true;
46188          _e = err;
46189        } finally {
46190          try {
46191            if (!_n && _i["return"]) _i["return"]();
46192          } finally {
46193            if (_d) throw _e;
46194          }
46195        }
46196
46197        return _arr;
46198      }
46199
46200      return function (arr, i) {
46201        if (Array.isArray(arr)) {
46202          return arr;
46203        } else if (Symbol.iterator in Object(arr)) {
46204          return sliceIterator(arr, i);
46205        } else {
46206          throw new TypeError("Invalid attempt to destructure non-iterable instance");
46207        }
46208      };
46209    }();
46210
46211    String.prototype.startsWith = String.prototype.startsWith || function (needle) {
46212      return this.indexOf(needle) === 0;
46213    };
46214
46215    String.prototype.padStart = String.prototype.padStart || function (len, pad) {
46216      var str = this;
46217
46218      while (str.length < len) {
46219        str = pad + str;
46220      }
46221
46222      return str;
46223    };
46224
46225    var colorNames = {
46226      cb: '0f8ff',
46227      tqw: 'aebd7',
46228      q: '-ffff',
46229      qmrn: '7fffd4',
46230      zr: '0ffff',
46231      bg: '5f5dc',
46232      bsq: 'e4c4',
46233      bck: '---',
46234      nch: 'ebcd',
46235      b: '--ff',
46236      bvt: '8a2be2',
46237      brwn: 'a52a2a',
46238      brw: 'deb887',
46239      ctb: '5f9ea0',
46240      hrt: '7fff-',
46241      chcT: 'd2691e',
46242      cr: '7f50',
46243      rnw: '6495ed',
46244      crns: '8dc',
46245      crms: 'dc143c',
46246      cn: '-ffff',
46247      Db: '--8b',
46248      Dcn: '-8b8b',
46249      Dgnr: 'b8860b',
46250      Dgr: 'a9a9a9',
46251      Dgrn: '-64-',
46252      Dkhk: 'bdb76b',
46253      Dmgn: '8b-8b',
46254      Dvgr: '556b2f',
46255      Drng: '8c-',
46256      Drch: '9932cc',
46257      Dr: '8b--',
46258      Dsmn: 'e9967a',
46259      Dsgr: '8fbc8f',
46260      DsTb: '483d8b',
46261      DsTg: '2f4f4f',
46262      Dtrq: '-ced1',
46263      Dvt: '94-d3',
46264      ppnk: '1493',
46265      pskb: '-bfff',
46266      mgr: '696969',
46267      grb: '1e90ff',
46268      rbrc: 'b22222',
46269      rwht: 'af0',
46270      stg: '228b22',
46271      chs: '-ff',
46272      gnsb: 'dcdcdc',
46273      st: '8f8ff',
46274      g: 'd7-',
46275      gnr: 'daa520',
46276      gr: '808080',
46277      grn: '-8-0',
46278      grnw: 'adff2f',
46279      hnw: '0fff0',
46280      htpn: '69b4',
46281      nnr: 'cd5c5c',
46282      ng: '4b-82',
46283      vr: '0',
46284      khk: '0e68c',
46285      vnr: 'e6e6fa',
46286      nrb: '0f5',
46287      wngr: '7cfc-',
46288      mnch: 'acd',
46289      Lb: 'add8e6',
46290      Lcr: '08080',
46291      Lcn: 'e0ffff',
46292      Lgnr: 'afad2',
46293      Lgr: 'd3d3d3',
46294      Lgrn: '90ee90',
46295      Lpnk: 'b6c1',
46296      Lsmn: 'a07a',
46297      Lsgr: '20b2aa',
46298      Lskb: '87cefa',
46299      LsTg: '778899',
46300      Lstb: 'b0c4de',
46301      Lw: 'e0',
46302      m: '-ff-',
46303      mgrn: '32cd32',
46304      nn: 'af0e6',
46305      mgnt: '-ff',
46306      mrn: '8--0',
46307      mqm: '66cdaa',
46308      mmb: '--cd',
46309      mmrc: 'ba55d3',
46310      mmpr: '9370db',
46311      msg: '3cb371',
46312      mmsT: '7b68ee',
46313      '': '-fa9a',
46314      mtr: '48d1cc',
46315      mmvt: 'c71585',
46316      mnLb: '191970',
46317      ntc: '5fffa',
46318      mstr: 'e4e1',
46319      mccs: 'e4b5',
46320      vjw: 'dead',
46321      nv: '--80',
46322      c: 'df5e6',
46323      v: '808-0',
46324      vrb: '6b8e23',
46325      rng: 'a5-',
46326      rngr: '45-',
46327      rch: 'da70d6',
46328      pgnr: 'eee8aa',
46329      pgrn: '98fb98',
46330      ptrq: 'afeeee',
46331      pvtr: 'db7093',
46332      ppwh: 'efd5',
46333      pchp: 'dab9',
46334      pr: 'cd853f',
46335      pnk: 'c0cb',
46336      pm: 'dda0dd',
46337      pwrb: 'b0e0e6',
46338      prp: '8-080',
46339      cc: '663399',
46340      r: '--',
46341      sbr: 'bc8f8f',
46342      rb: '4169e1',
46343      sbrw: '8b4513',
46344      smn: 'a8072',
46345      nbr: '4a460',
46346      sgrn: '2e8b57',
46347      ssh: '5ee',
46348      snn: 'a0522d',
46349      svr: 'c0c0c0',
46350      skb: '87ceeb',
46351      sTb: '6a5acd',
46352      sTgr: '708090',
46353      snw: 'afa',
46354      n: '-ff7f',
46355      stb: '4682b4',
46356      tn: 'd2b48c',
46357      t: '-8080',
46358      thst: 'd8bfd8',
46359      tmT: '6347',
46360      trqs: '40e0d0',
46361      vt: 'ee82ee',
46362      whT: '5deb3',
46363      wht: '',
46364      hts: '5f5f5',
46365      w: '-',
46366      wgrn: '9acd32'
46367    };
46368
46369    function printNum(num) {
46370      var decs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
46371      var str = decs > 0 ? num.toFixed(decs).replace(/0+$/, '').replace(/\.$/, '') : num.toString();
46372      return str || '0';
46373    }
46374
46375    var Color = function () {
46376      function Color(r, g, b, a) {
46377        classCallCheck(this, Color);
46378        var that = this;
46379
46380        function parseString(input) {
46381          if (input.startsWith('hsl')) {
46382            var _input$match$map = input.match(/([\-\d\.e]+)/g).map(Number),
46383                _input$match$map2 = slicedToArray(_input$match$map, 4),
46384                h = _input$match$map2[0],
46385                s = _input$match$map2[1],
46386                l = _input$match$map2[2],
46387                _a = _input$match$map2[3];
46388
46389            if (_a === undefined) {
46390              _a = 1;
46391            }
46392
46393            h /= 360;
46394            s /= 100;
46395            l /= 100;
46396            that.hsla = [h, s, l, _a];
46397          } else if (input.startsWith('rgb')) {
46398            var _input$match$map3 = input.match(/([\-\d\.e]+)/g).map(Number),
46399                _input$match$map4 = slicedToArray(_input$match$map3, 4),
46400                _r = _input$match$map4[0],
46401                _g = _input$match$map4[1],
46402                _b = _input$match$map4[2],
46403                _a2 = _input$match$map4[3];
46404
46405            if (_a2 === undefined) {
46406              _a2 = 1;
46407            }
46408
46409            that.rgba = [_r, _g, _b, _a2];
46410          } else {
46411            if (input.startsWith('#')) {
46412              that.rgba = Color.hexToRgb(input);
46413            } else {
46414              that.rgba = Color.nameToRgb(input) || Color.hexToRgb(input);
46415            }
46416          }
46417        }
46418
46419        if (r === undefined) ;else if (Array.isArray(r)) {
46420          this.rgba = r;
46421        } else if (b === undefined) {
46422          var color = r && '' + r;
46423
46424          if (color) {
46425            parseString(color.toLowerCase());
46426          }
46427        } else {
46428          this.rgba = [r, g, b, a === undefined ? 1 : a];
46429        }
46430      }
46431
46432      createClass(Color, [{
46433        key: 'printRGB',
46434        value: function printRGB(alpha) {
46435          var rgb = alpha ? this.rgba : this.rgba.slice(0, 3),
46436              vals = rgb.map(function (x, i) {
46437            return printNum(x, i === 3 ? 3 : 0);
46438          });
46439          return alpha ? 'rgba(' + vals + ')' : 'rgb(' + vals + ')';
46440        }
46441      }, {
46442        key: 'printHSL',
46443        value: function printHSL(alpha) {
46444          var mults = [360, 100, 100, 1],
46445              suff = ['', '%', '%', ''];
46446          var hsl = alpha ? this.hsla : this.hsla.slice(0, 3),
46447              vals = hsl.map(function (x, i) {
46448            return printNum(x * mults[i], i === 3 ? 3 : 1) + suff[i];
46449          });
46450          return alpha ? 'hsla(' + vals + ')' : 'hsl(' + vals + ')';
46451        }
46452      }, {
46453        key: 'printHex',
46454        value: function printHex(alpha) {
46455          var hex = this.hex;
46456          return alpha ? hex : hex.substring(0, 7);
46457        }
46458      }, {
46459        key: 'rgba',
46460        get: function get() {
46461          if (this._rgba) {
46462            return this._rgba;
46463          }
46464
46465          if (!this._hsla) {
46466            throw new Error('No color is set');
46467          }
46468
46469          return this._rgba = Color.hslToRgb(this._hsla);
46470        },
46471        set: function set(rgb) {
46472          if (rgb.length === 3) {
46473            rgb[3] = 1;
46474          }
46475
46476          this._rgba = rgb;
46477          this._hsla = null;
46478        }
46479      }, {
46480        key: 'rgbString',
46481        get: function get() {
46482          return this.printRGB();
46483        }
46484      }, {
46485        key: 'rgbaString',
46486        get: function get() {
46487          return this.printRGB(true);
46488        }
46489      }, {
46490        key: 'hsla',
46491        get: function get() {
46492          if (this._hsla) {
46493            return this._hsla;
46494          }
46495
46496          if (!this._rgba) {
46497            throw new Error('No color is set');
46498          }
46499
46500          return this._hsla = Color.rgbToHsl(this._rgba);
46501        },
46502        set: function set(hsl) {
46503          if (hsl.length === 3) {
46504            hsl[3] = 1;
46505          }
46506
46507          this._hsla = hsl;
46508          this._rgba = null;
46509        }
46510      }, {
46511        key: 'hslString',
46512        get: function get() {
46513          return this.printHSL();
46514        }
46515      }, {
46516        key: 'hslaString',
46517        get: function get() {
46518          return this.printHSL(true);
46519        }
46520      }, {
46521        key: 'hex',
46522        get: function get() {
46523          var rgb = this.rgba,
46524              hex = rgb.map(function (x, i) {
46525            return i < 3 ? x.toString(16) : Math.round(x * 255).toString(16);
46526          });
46527          return '#' + hex.map(function (x) {
46528            return x.padStart(2, '0');
46529          }).join('');
46530        },
46531        set: function set(hex) {
46532          this.rgba = Color.hexToRgb(hex);
46533        }
46534      }], [{
46535        key: 'hexToRgb',
46536        value: function hexToRgb(input) {
46537          var hex = (input.startsWith('#') ? input.slice(1) : input).replace(/^(\w{3})$/, '$1F').replace(/^(\w)(\w)(\w)(\w)$/, '$1$1$2$2$3$3$4$4').replace(/^(\w{6})$/, '$1FF');
46538
46539          if (!hex.match(/^([0-9a-fA-F]{8})$/)) {
46540            throw new Error('Unknown hex color; ' + input);
46541          }
46542
46543          var rgba = hex.match(/^(\w\w)(\w\w)(\w\w)(\w\w)$/).slice(1).map(function (x) {
46544            return parseInt(x, 16);
46545          });
46546          rgba[3] = rgba[3] / 255;
46547          return rgba;
46548        }
46549      }, {
46550        key: 'nameToRgb',
46551        value: function nameToRgb(input) {
46552          var hash = input.toLowerCase().replace('at', 'T').replace(/[aeiouyldf]/g, '').replace('ght', 'L').replace('rk', 'D').slice(-5, 4),
46553              hex = colorNames[hash];
46554          return hex === undefined ? hex : Color.hexToRgb(hex.replace(/\-/g, '00').padStart(6, 'f'));
46555        }
46556      }, {
46557        key: 'rgbToHsl',
46558        value: function rgbToHsl(_ref) {
46559          var _ref2 = slicedToArray(_ref, 4),
46560              r = _ref2[0],
46561              g = _ref2[1],
46562              b = _ref2[2],
46563              a = _ref2[3];
46564
46565          r /= 255;
46566          g /= 255;
46567          b /= 255;
46568          var max = Math.max(r, g, b),
46569              min = Math.min(r, g, b);
46570          var h = void 0,
46571              s = void 0,
46572              l = (max + min) / 2;
46573
46574          if (max === min) {
46575            h = s = 0;
46576          } else {
46577            var d = max - min;
46578            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
46579
46580            switch (max) {
46581              case r:
46582                h = (g - b) / d + (g < b ? 6 : 0);
46583                break;
46584
46585              case g:
46586                h = (b - r) / d + 2;
46587                break;
46588
46589              case b:
46590                h = (r - g) / d + 4;
46591                break;
46592            }
46593
46594            h /= 6;
46595          }
46596
46597          return [h, s, l, a];
46598        }
46599      }, {
46600        key: 'hslToRgb',
46601        value: function hslToRgb(_ref3) {
46602          var _ref4 = slicedToArray(_ref3, 4),
46603              h = _ref4[0],
46604              s = _ref4[1],
46605              l = _ref4[2],
46606              a = _ref4[3];
46607
46608          var r = void 0,
46609              g = void 0,
46610              b = void 0;
46611
46612          if (s === 0) {
46613            r = g = b = l;
46614          } else {
46615            var hue2rgb = function hue2rgb(p, q, t) {
46616              if (t < 0) t += 1;
46617              if (t > 1) t -= 1;
46618              if (t < 1 / 6) return p + (q - p) * 6 * t;
46619              if (t < 1 / 2) return q;
46620              if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
46621              return p;
46622            };
46623
46624            var q = l < 0.5 ? l * (1 + s) : l + s - l * s,
46625                p = 2 * l - q;
46626            r = hue2rgb(p, q, h + 1 / 3);
46627            g = hue2rgb(p, q, h);
46628            b = hue2rgb(p, q, h - 1 / 3);
46629          }
46630
46631          var rgba = [r * 255, g * 255, b * 255].map(Math.round);
46632          rgba[3] = a;
46633          return rgba;
46634        }
46635      }]);
46636      return Color;
46637    }();
46638
46639    var EventBucket = function () {
46640      function EventBucket() {
46641        classCallCheck(this, EventBucket);
46642        this._events = [];
46643      }
46644
46645      createClass(EventBucket, [{
46646        key: 'add',
46647        value: function add(target, type, handler) {
46648          target.addEventListener(type, handler, false);
46649
46650          this._events.push({
46651            target: target,
46652            type: type,
46653            handler: handler
46654          });
46655        }
46656      }, {
46657        key: 'remove',
46658        value: function remove(target, type, handler) {
46659          this._events = this._events.filter(function (e) {
46660            var isMatch = true;
46661
46662            if (target && target !== e.target) {
46663              isMatch = false;
46664            }
46665
46666            if (type && type !== e.type) {
46667              isMatch = false;
46668            }
46669
46670            if (handler && handler !== e.handler) {
46671              isMatch = false;
46672            }
46673
46674            if (isMatch) {
46675              EventBucket._doRemove(e.target, e.type, e.handler);
46676            }
46677
46678            return !isMatch;
46679          });
46680        }
46681      }, {
46682        key: 'destroy',
46683        value: function destroy() {
46684          this._events.forEach(function (e) {
46685            return EventBucket._doRemove(e.target, e.type, e.handler);
46686          });
46687
46688          this._events = [];
46689        }
46690      }], [{
46691        key: '_doRemove',
46692        value: function _doRemove(target, type, handler) {
46693          target.removeEventListener(type, handler, false);
46694        }
46695      }]);
46696      return EventBucket;
46697    }();
46698
46699    function parseHTML(htmlString) {
46700      var div = document.createElement('div');
46701      div.innerHTML = htmlString;
46702      return div.firstElementChild;
46703    }
46704
46705    function dragTrack(eventBucket, area, callback) {
46706      var dragging = false;
46707
46708      function clamp(val, min, max) {
46709        return Math.max(min, Math.min(val, max));
46710      }
46711
46712      function onMove(e, info, starting) {
46713        if (starting) {
46714          dragging = true;
46715        }
46716
46717        if (!dragging) {
46718          return;
46719        }
46720
46721        e.preventDefault();
46722        var bounds = area.getBoundingClientRect(),
46723            w = bounds.width,
46724            h = bounds.height,
46725            x = info.clientX,
46726            y = info.clientY;
46727        var relX = clamp(x - bounds.left, 0, w),
46728            relY = clamp(y - bounds.top, 0, h);
46729        callback(relX / w, relY / h);
46730      }
46731
46732      function onMouse(e, starting) {
46733        var button = e.buttons === undefined ? e.which : e.buttons;
46734
46735        if (button === 1) {
46736          onMove(e, e, starting);
46737        } else {
46738          dragging = false;
46739        }
46740      }
46741
46742      function onTouch(e, starting) {
46743        if (e.touches.length === 1) {
46744          onMove(e, e.touches[0], starting);
46745        } else {
46746          dragging = false;
46747        }
46748      }
46749
46750      eventBucket.add(area, 'mousedown', function (e) {
46751        onMouse(e, true);
46752      });
46753      eventBucket.add(area, 'touchstart', function (e) {
46754        onTouch(e, true);
46755      });
46756      eventBucket.add(window, 'mousemove', onMouse);
46757      eventBucket.add(area, 'touchmove', onTouch);
46758      eventBucket.add(window, 'mouseup', function (e) {
46759        dragging = false;
46760      });
46761      eventBucket.add(area, 'touchend', function (e) {
46762        dragging = false;
46763      });
46764      eventBucket.add(area, 'touchcancel', function (e) {
46765        dragging = false;
46766      });
46767    }
46768
46769    var BG_TRANSP = 'linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0 / 2em 2em,\n                   linear-gradient(45deg, lightgrey 25%,       white 25%,       white 75%, lightgrey 75%) 1em 1em / 2em 2em';
46770    var HUES = 360;
46771    var EVENT_KEY = 'keydown',
46772        EVENT_CLICK_OUTSIDE = 'mousedown',
46773        EVENT_TAB_MOVE = 'focusin';
46774
46775    function $(selector, context) {
46776      return (context || document).querySelector(selector);
46777    }
46778
46779    function stopEvent(e) {
46780      e.preventDefault();
46781      e.stopPropagation();
46782    }
46783
46784    function onKey(bucket, target, keys, handler, stop) {
46785      bucket.add(target, EVENT_KEY, function (e) {
46786        if (keys.indexOf(e.key) >= 0) {
46787          if (stop) {
46788            stopEvent(e);
46789          }
46790
46791          handler(e);
46792        }
46793      });
46794    }
46795
46796    var Picker = function () {
46797      function Picker(options) {
46798        classCallCheck(this, Picker);
46799        this.settings = {
46800          popup: 'right',
46801          layout: 'default',
46802          alpha: true,
46803          editor: true,
46804          editorFormat: 'hex',
46805          cancelButton: false,
46806          defaultColor: '#0cf'
46807        };
46808        this._events = new EventBucket();
46809        this.onChange = null;
46810        this.onDone = null;
46811        this.onOpen = null;
46812        this.onClose = null;
46813        this.setOptions(options);
46814      }
46815
46816      createClass(Picker, [{
46817        key: 'setOptions',
46818        value: function setOptions(options) {
46819          var _this = this;
46820
46821          if (!options) {
46822            return;
46823          }
46824
46825          var settings = this.settings;
46826
46827          function transfer(source, target, skipKeys) {
46828            for (var key in source) {
46829              if (skipKeys && skipKeys.indexOf(key) >= 0) {
46830                continue;
46831              }
46832
46833              target[key] = source[key];
46834            }
46835          }
46836
46837          if (options instanceof HTMLElement) {
46838            settings.parent = options;
46839          } else {
46840            if (settings.parent && options.parent && settings.parent !== options.parent) {
46841              this._events.remove(settings.parent);
46842
46843              this._popupInited = false;
46844            }
46845
46846            transfer(options, settings);
46847
46848            if (options.onChange) {
46849              this.onChange = options.onChange;
46850            }
46851
46852            if (options.onDone) {
46853              this.onDone = options.onDone;
46854            }
46855
46856            if (options.onOpen) {
46857              this.onOpen = options.onOpen;
46858            }
46859
46860            if (options.onClose) {
46861              this.onClose = options.onClose;
46862            }
46863
46864            var col = options.color || options.colour;
46865
46866            if (col) {
46867              this._setColor(col);
46868            }
46869          }
46870
46871          var parent = settings.parent;
46872
46873          if (parent && settings.popup && !this._popupInited) {
46874            var openProxy = function openProxy(e) {
46875              return _this.openHandler(e);
46876            };
46877
46878            this._events.add(parent, 'click', openProxy);
46879
46880            onKey(this._events, parent, [' ', 'Spacebar', 'Enter'], openProxy);
46881            this._popupInited = true;
46882          } else if (options.parent && !settings.popup) {
46883            this.show();
46884          }
46885        }
46886      }, {
46887        key: 'openHandler',
46888        value: function openHandler(e) {
46889          if (this.show()) {
46890            e && e.preventDefault();
46891            this.settings.parent.style.pointerEvents = 'none';
46892            var toFocus = e && e.type === EVENT_KEY ? this._domEdit : this.domElement;
46893            setTimeout(function () {
46894              return toFocus.focus();
46895            }, 100);
46896
46897            if (this.onOpen) {
46898              this.onOpen(this.colour);
46899            }
46900          }
46901        }
46902      }, {
46903        key: 'closeHandler',
46904        value: function closeHandler(e) {
46905          var event = e && e.type;
46906          var doHide = false;
46907
46908          if (!e) {
46909            doHide = true;
46910          } else if (event === EVENT_CLICK_OUTSIDE || event === EVENT_TAB_MOVE) {
46911            var knownTime = (this.__containedEvent || 0) + 100;
46912
46913            if (e.timeStamp > knownTime) {
46914              doHide = true;
46915            }
46916          } else {
46917            stopEvent(e);
46918            doHide = true;
46919          }
46920
46921          if (doHide && this.hide()) {
46922            this.settings.parent.style.pointerEvents = '';
46923
46924            if (event !== EVENT_CLICK_OUTSIDE) {
46925              this.settings.parent.focus();
46926            }
46927
46928            if (this.onClose) {
46929              this.onClose(this.colour);
46930            }
46931          }
46932        }
46933      }, {
46934        key: 'movePopup',
46935        value: function movePopup(options, open) {
46936          this.closeHandler();
46937          this.setOptions(options);
46938
46939          if (open) {
46940            this.openHandler();
46941          }
46942        }
46943      }, {
46944        key: 'setColor',
46945        value: function setColor(color, silent) {
46946          this._setColor(color, {
46947            silent: silent
46948          });
46949        }
46950      }, {
46951        key: '_setColor',
46952        value: function _setColor(color, flags) {
46953          if (typeof color === 'string') {
46954            color = color.trim();
46955          }
46956
46957          if (!color) {
46958            return;
46959          }
46960
46961          flags = flags || {};
46962          var c = void 0;
46963
46964          try {
46965            c = new Color(color);
46966          } catch (ex) {
46967            if (flags.failSilently) {
46968              return;
46969            }
46970
46971            throw ex;
46972          }
46973
46974          if (!this.settings.alpha) {
46975            var hsla = c.hsla;
46976            hsla[3] = 1;
46977            c.hsla = hsla;
46978          }
46979
46980          this.colour = this.color = c;
46981
46982          this._setHSLA(null, null, null, null, flags);
46983        }
46984      }, {
46985        key: 'setColour',
46986        value: function setColour(colour, silent) {
46987          this.setColor(colour, silent);
46988        }
46989      }, {
46990        key: 'show',
46991        value: function show() {
46992          var parent = this.settings.parent;
46993
46994          if (!parent) {
46995            return false;
46996          }
46997
46998          if (this.domElement) {
46999            var toggled = this._toggleDOM(true);
47000
47001            this._setPosition();
47002
47003            return toggled;
47004          }
47005
47006          var html = this.settings.template || '<div class="picker_wrapper" tabindex="-1"><div class="picker_arrow"></div><div class="picker_hue picker_slider"><div class="picker_selector"></div></div><div class="picker_sl"><div class="picker_selector"></div></div><div class="picker_alpha picker_slider"><div class="picker_selector"></div></div><div class="picker_editor"><input aria-label="Type a color name or hex value"/></div><div class="picker_sample"></div><div class="picker_done"><button>Ok</button></div><div class="picker_cancel"><button>Cancel</button></div></div>';
47007          var wrapper = parseHTML(html);
47008          this.domElement = wrapper;
47009          this._domH = $('.picker_hue', wrapper);
47010          this._domSL = $('.picker_sl', wrapper);
47011          this._domA = $('.picker_alpha', wrapper);
47012          this._domEdit = $('.picker_editor input', wrapper);
47013          this._domSample = $('.picker_sample', wrapper);
47014          this._domOkay = $('.picker_done button', wrapper);
47015          this._domCancel = $('.picker_cancel button', wrapper);
47016          wrapper.classList.add('layout_' + this.settings.layout);
47017
47018          if (!this.settings.alpha) {
47019            wrapper.classList.add('no_alpha');
47020          }
47021
47022          if (!this.settings.editor) {
47023            wrapper.classList.add('no_editor');
47024          }
47025
47026          if (!this.settings.cancelButton) {
47027            wrapper.classList.add('no_cancel');
47028          }
47029
47030          this._ifPopup(function () {
47031            return wrapper.classList.add('popup');
47032          });
47033
47034          this._setPosition();
47035
47036          if (this.colour) {
47037            this._updateUI();
47038          } else {
47039            this._setColor(this.settings.defaultColor);
47040          }
47041
47042          this._bindEvents();
47043
47044          return true;
47045        }
47046      }, {
47047        key: 'hide',
47048        value: function hide() {
47049          return this._toggleDOM(false);
47050        }
47051      }, {
47052        key: 'destroy',
47053        value: function destroy() {
47054          this._events.destroy();
47055
47056          if (this.domElement) {
47057            this.settings.parent.removeChild(this.domElement);
47058          }
47059        }
47060      }, {
47061        key: '_bindEvents',
47062        value: function _bindEvents() {
47063          var _this2 = this;
47064
47065          var that = this,
47066              dom = this.domElement,
47067              events = this._events;
47068
47069          function addEvent(target, type, handler) {
47070            events.add(target, type, handler);
47071          }
47072
47073          addEvent(dom, 'click', function (e) {
47074            return e.preventDefault();
47075          });
47076          dragTrack(events, this._domH, function (x, y) {
47077            return that._setHSLA(x);
47078          });
47079          dragTrack(events, this._domSL, function (x, y) {
47080            return that._setHSLA(null, x, 1 - y);
47081          });
47082
47083          if (this.settings.alpha) {
47084            dragTrack(events, this._domA, function (x, y) {
47085              return that._setHSLA(null, null, null, 1 - y);
47086            });
47087          }
47088
47089          var editInput = this._domEdit;
47090          {
47091            addEvent(editInput, 'input', function (e) {
47092              that._setColor(this.value, {
47093                fromEditor: true,
47094                failSilently: true
47095              });
47096            });
47097            addEvent(editInput, 'focus', function (e) {
47098              var input = this;
47099
47100              if (input.selectionStart === input.selectionEnd) {
47101                input.select();
47102              }
47103            });
47104          }
47105
47106          this._ifPopup(function () {
47107            var popupCloseProxy = function popupCloseProxy(e) {
47108              return _this2.closeHandler(e);
47109            };
47110
47111            addEvent(window, EVENT_CLICK_OUTSIDE, popupCloseProxy);
47112            addEvent(window, EVENT_TAB_MOVE, popupCloseProxy);
47113            onKey(events, dom, ['Esc', 'Escape'], popupCloseProxy);
47114
47115            var timeKeeper = function timeKeeper(e) {
47116              _this2.__containedEvent = e.timeStamp;
47117            };
47118
47119            addEvent(dom, EVENT_CLICK_OUTSIDE, timeKeeper);
47120            addEvent(dom, EVENT_TAB_MOVE, timeKeeper);
47121            addEvent(_this2._domCancel, 'click', popupCloseProxy);
47122          });
47123
47124          var onDoneProxy = function onDoneProxy(e) {
47125            _this2._ifPopup(function () {
47126              return _this2.closeHandler(e);
47127            });
47128
47129            if (_this2.onDone) {
47130              _this2.onDone(_this2.colour);
47131            }
47132          };
47133
47134          addEvent(this._domOkay, 'click', onDoneProxy);
47135          onKey(events, dom, ['Enter'], onDoneProxy);
47136        }
47137      }, {
47138        key: '_setPosition',
47139        value: function _setPosition() {
47140          var parent = this.settings.parent,
47141              elm = this.domElement;
47142
47143          if (parent !== elm.parentNode) {
47144            parent.appendChild(elm);
47145          }
47146
47147          this._ifPopup(function (popup) {
47148            if (getComputedStyle(parent).position === 'static') {
47149              parent.style.position = 'relative';
47150            }
47151
47152            var cssClass = popup === true ? 'popup_right' : 'popup_' + popup;
47153            ['popup_top', 'popup_bottom', 'popup_left', 'popup_right'].forEach(function (c) {
47154              if (c === cssClass) {
47155                elm.classList.add(c);
47156              } else {
47157                elm.classList.remove(c);
47158              }
47159            });
47160            elm.classList.add(cssClass);
47161          });
47162        }
47163      }, {
47164        key: '_setHSLA',
47165        value: function _setHSLA(h, s, l, a, flags) {
47166          flags = flags || {};
47167          var col = this.colour,
47168              hsla = col.hsla;
47169          [h, s, l, a].forEach(function (x, i) {
47170            if (x || x === 0) {
47171              hsla[i] = x;
47172            }
47173          });
47174          col.hsla = hsla;
47175
47176          this._updateUI(flags);
47177
47178          if (this.onChange && !flags.silent) {
47179            this.onChange(col);
47180          }
47181        }
47182      }, {
47183        key: '_updateUI',
47184        value: function _updateUI(flags) {
47185          if (!this.domElement) {
47186            return;
47187          }
47188
47189          flags = flags || {};
47190          var col = this.colour,
47191              hsl = col.hsla,
47192              cssHue = 'hsl(' + hsl[0] * HUES + ', 100%, 50%)',
47193              cssHSL = col.hslString,
47194              cssHSLA = col.hslaString;
47195          var uiH = this._domH,
47196              uiSL = this._domSL,
47197              uiA = this._domA,
47198              thumbH = $('.picker_selector', uiH),
47199              thumbSL = $('.picker_selector', uiSL),
47200              thumbA = $('.picker_selector', uiA);
47201
47202          function posX(parent, child, relX) {
47203            child.style.left = relX * 100 + '%';
47204          }
47205
47206          function posY(parent, child, relY) {
47207            child.style.top = relY * 100 + '%';
47208          }
47209
47210          posX(uiH, thumbH, hsl[0]);
47211          this._domSL.style.backgroundColor = this._domH.style.color = cssHue;
47212          posX(uiSL, thumbSL, hsl[1]);
47213          posY(uiSL, thumbSL, 1 - hsl[2]);
47214          uiSL.style.color = cssHSL;
47215          posY(uiA, thumbA, 1 - hsl[3]);
47216          var opaque = cssHSL,
47217              transp = opaque.replace('hsl', 'hsla').replace(')', ', 0)'),
47218              bg = 'linear-gradient(' + [opaque, transp] + ')';
47219          this._domA.style.background = bg + ', ' + BG_TRANSP;
47220
47221          if (!flags.fromEditor) {
47222            var format = this.settings.editorFormat,
47223                alpha = this.settings.alpha;
47224            var value = void 0;
47225
47226            switch (format) {
47227              case 'rgb':
47228                value = col.printRGB(alpha);
47229                break;
47230
47231              case 'hsl':
47232                value = col.printHSL(alpha);
47233                break;
47234
47235              default:
47236                value = col.printHex(alpha);
47237            }
47238
47239            this._domEdit.value = value;
47240          }
47241
47242          this._domSample.style.color = cssHSLA;
47243        }
47244      }, {
47245        key: '_ifPopup',
47246        value: function _ifPopup(actionIf, actionElse) {
47247          if (this.settings.parent && this.settings.popup) {
47248            actionIf && actionIf(this.settings.popup);
47249          } else {
47250            actionElse && actionElse();
47251          }
47252        }
47253      }, {
47254        key: '_toggleDOM',
47255        value: function _toggleDOM(toVisible) {
47256          var dom = this.domElement;
47257
47258          if (!dom) {
47259            return false;
47260          }
47261
47262          var displayStyle = toVisible ? '' : 'none',
47263              toggle = dom.style.display !== displayStyle;
47264
47265          if (toggle) {
47266            dom.style.display = displayStyle;
47267          }
47268
47269          return toggle;
47270        }
47271      }]);
47272      return Picker;
47273    }();
47274
47275    {
47276      var style = document.createElement('style');
47277      style.textContent = '.picker_wrapper.no_alpha .picker_alpha{display:none}.picker_wrapper.no_editor .picker_editor{position:absolute;z-index:-1;opacity:0}.picker_wrapper.no_cancel .picker_cancel{display:none}.layout_default.picker_wrapper{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:stretch;font-size:10px;width:25em;padding:.5em}.layout_default.picker_wrapper input,.layout_default.picker_wrapper button{font-size:1rem}.layout_default.picker_wrapper>*{margin:.5em}.layout_default.picker_wrapper::before{content:"";display:block;width:100%;height:0;order:1}.layout_default .picker_slider,.layout_default .picker_selector{padding:1em}.layout_default .picker_hue{width:100%}.layout_default .picker_sl{flex:1 1 auto}.layout_default .picker_sl::before{content:"";display:block;padding-bottom:100%}.layout_default .picker_editor{order:1;width:6.5rem}.layout_default .picker_editor input{width:100%;height:100%}.layout_default .picker_sample{order:1;flex:1 1 auto}.layout_default .picker_done,.layout_default .picker_cancel{order:1}.picker_wrapper{box-sizing:border-box;background:#f2f2f2;box-shadow:0 0 0 1px silver;cursor:default;font-family:sans-serif;color:#444;pointer-events:auto}.picker_wrapper:focus{outline:none}.picker_wrapper button,.picker_wrapper input{box-sizing:border-box;border:none;box-shadow:0 0 0 1px silver;outline:none}.picker_wrapper button:focus,.picker_wrapper button:active,.picker_wrapper input:focus,.picker_wrapper input:active{box-shadow:0 0 2px 1px #1e90ff}.picker_wrapper button{padding:.4em .6em;cursor:pointer;background-color:#f5f5f5;background-image:linear-gradient(0deg, gainsboro, transparent)}.picker_wrapper button:active{background-image:linear-gradient(0deg, transparent, gainsboro)}.picker_wrapper button:hover{background-color:#fff}.picker_selector{position:absolute;z-index:1;display:block;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);border:2px solid #fff;border-radius:100%;box-shadow:0 0 3px 1px #67b9ff;background:currentColor;cursor:pointer}.picker_slider .picker_selector{border-radius:2px}.picker_hue{position:relative;background-image:linear-gradient(90deg, red, yellow, lime, cyan, blue, magenta, red);box-shadow:0 0 0 1px silver}.picker_sl{position:relative;box-shadow:0 0 0 1px silver;background-image:linear-gradient(180deg, white, rgba(255, 255, 255, 0) 50%),linear-gradient(0deg, black, rgba(0, 0, 0, 0) 50%),linear-gradient(90deg, #808080, rgba(128, 128, 128, 0))}.picker_alpha,.picker_sample{position:relative;background:linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0/2em 2em,linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em/2em 2em;box-shadow:0 0 0 1px silver}.picker_alpha .picker_selector,.picker_sample .picker_selector{background:none}.picker_editor input{font-family:monospace;padding:.2em .4em}.picker_sample::before{content:"";position:absolute;display:block;width:100%;height:100%;background:currentColor}.picker_arrow{position:absolute;z-index:-1}.picker_wrapper.popup{position:absolute;z-index:2;margin:1.5em}.picker_wrapper.popup,.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{background:#f2f2f2;box-shadow:0 0 10px 1px rgba(0,0,0,.4)}.picker_wrapper.popup .picker_arrow{width:3em;height:3em;margin:0}.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{content:"";display:block;position:absolute;top:0;left:0;z-index:-99}.picker_wrapper.popup .picker_arrow::before{width:100%;height:100%;-webkit-transform:skew(45deg);transform:skew(45deg);-webkit-transform-origin:0 100%;transform-origin:0 100%}.picker_wrapper.popup .picker_arrow::after{width:150%;height:150%;box-shadow:none}.popup.popup_top{bottom:100%;left:0}.popup.popup_top .picker_arrow{bottom:0;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.popup.popup_bottom{top:100%;left:0}.popup.popup_bottom .picker_arrow{top:0;left:0;-webkit-transform:rotate(90deg) scale(1, -1);transform:rotate(90deg) scale(1, -1)}.popup.popup_left{top:0;right:100%}.popup.popup_left .picker_arrow{top:0;right:0;-webkit-transform:scale(-1, 1);transform:scale(-1, 1)}.popup.popup_right{top:0;left:100%}.popup.popup_right .picker_arrow{top:0;left:0}';
47278      document.documentElement.firstElementChild.appendChild(style);
47279      Picker.StyleElement = style;
47280    }
47281
47282    function getChrColor$1(chr) {
47283      if (chrColorMap$1[chr]) {
47284        return chrColorMap$1[chr];
47285      } else if (chrColorMap$1["chr" + chr]) {
47286        const color = chrColorMap$1["chr" + chr];
47287        chrColorMap$1[chr] = color;
47288        return color;
47289      } else {
47290        const color = randomRGB();
47291        chrColorMap$1[chr] = color;
47292        return color;
47293      }
47294    }
47295
47296    function randomRGB(min, max) {
47297      var r = Math.round(Math.random() * 255).toString(10);
47298      var g = Math.round(Math.random() * 255).toString(10);
47299      var b = Math.round(Math.random() * 255).toString(10);
47300      return "rgb(" + r + "," + g + "," + b + ")";
47301    }
47302
47303    const chrColorMap$1 = {
47304      "chrX": "rgb(204, 153, 0)",
47305      "chrY": "rgb(153, 204, 0",
47306      "chrUn": "rgb(50, 50, 50)",
47307      "chr1": "rgb(80, 80, 255)",
47308      "chrI": "rgb(139, 155, 187)",
47309      "chr2": "rgb(206, 61, 50)",
47310      "chrII": "rgb(206, 61, 50)",
47311      "chr2a": "rgb(216, 71, 60)",
47312      "chr2b": "rgb(226, 81, 70)",
47313      "chr3": "rgb(116, 155, 88)",
47314      "chrIII": "rgb(116, 155, 88)",
47315      "chr4": "rgb(240, 230, 133)",
47316      "chrIV": "rgb(240, 230, 133)",
47317      "chr5": "rgb(70, 105, 131)",
47318      "chr6": "rgb(186, 99, 56)",
47319      "chr7": "rgb(93, 177, 221)",
47320      "chr8": "rgb(128, 34, 104)",
47321      "chr9": "rgb(107, 215, 107)",
47322      "chr10": "rgb(213, 149, 167)",
47323      "chr11": "rgb(146, 72, 34)",
47324      "chr12": "rgb(131, 123, 141)",
47325      "chr13": "rgb(199, 81, 39)",
47326      "chr14": "rgb(213, 143, 92)",
47327      "chr15": "rgb(122, 101, 165)",
47328      "chr16": "rgb(228, 175, 105)",
47329      "chr17": "rgb(59, 27, 83)",
47330      "chr18": "rgb(205, 222, 183)",
47331      "chr19": "rgb(97, 42, 121)",
47332      "chr20": "rgb(174, 31, 99)",
47333      "chr21": "rgb(231, 199, 111)",
47334      "chr22": "rgb(90, 101, 94)",
47335      "chr23": "rgb(204, 153, 0)",
47336      "chr24": "rgb(153, 204, 0)",
47337      "chr25": "rgb(51, 204, 0)",
47338      "chr26": "rgb(0, 204, 51)",
47339      "chr27": "rgb(0, 204, 153)",
47340      "chr28": "rgb(0, 153, 204)",
47341      "chr29": "rgb(10, 71, 255)",
47342      "chr30": "rgb(71, 117, 255)",
47343      "chr31": "rgb(255, 194, 10)",
47344      "chr32": "rgb(255, 209, 71)",
47345      "chr33": "rgb(153, 0, 51)",
47346      "chr34": "rgb(153, 26, 0)",
47347      "chr35": "rgb(153, 102, 0)",
47348      "chr36": "rgb(128, 153, 0)",
47349      "chr37": "rgb(51, 153, 0)",
47350      "chr38": "rgb(0, 153, 26)",
47351      "chr39": "rgb(0, 153, 102)",
47352      "chr40": "rgb(0, 128, 153)",
47353      "chr41": "rgb(0, 51, 153)",
47354      "chr42": "rgb(26, 0, 153)",
47355      "chr43": "rgb(102, 0, 153)",
47356      "chr44": "rgb(153, 0, 128)",
47357      "chr45": "rgb(214, 0, 71)",
47358      "chr46": "rgb(255, 20, 99)",
47359      "chr47": "rgb(0, 214, 143)",
47360      "chr48": "rgb(20, 255, 177)"
47361    };
47362
47363    class CircularView {
47364      static isInstalled() {
47365        return window["JBrowseReactCircularGenomeView"] !== undefined && window["React"] !== undefined && window["ReactDOM"] !== undefined;
47366      }
47367      /**
47368       * Create a new CircularView
47369       *
47370       * @param parent
47371       * @param config - configuration options
47372       *   {
47373       *       assembly: {name: string, id: string, chromosomes: [{name: string, bpLength: integer, color: string}]
47374       *       onChordClick: function called upon chord click with chord feature as argument
47375       *   }
47376       */
47377
47378
47379      constructor(parent, config) {
47380        config = config || {};
47381        this.config = config;
47382
47383        if (CircularView.isInstalled()) {
47384          this.parent = parent; // wrapper for toolbar and circular-view container
47385
47386          const wrapper = document.createElement('div');
47387          wrapper.className = 'igv-circview-container';
47388          parent.appendChild(wrapper); // toolbar
47389
47390          this.createToolbarAndTrackPanel(wrapper); // circular view container
47391
47392          const element = document.createElement('div');
47393          element.className = 'igv-circview-circular-genome-view';
47394          wrapper.appendChild(element);
47395          this.container = element;
47396
47397          if (config.assembly) {
47398            this.setAssembly(config.assembly);
47399          }
47400
47401          this.tracks = config.tracks || [];
47402          this.width = config.width || 500;
47403          this.height = config.height || 500;
47404          this.setSize(this.width, this.height);
47405        } else {
47406          console.error("JBrowse circular view is not installed");
47407        }
47408      }
47409
47410      createToolbarAndTrackPanel(parent) {
47411        let element; // toolbar
47412
47413        element = document.createElement('div');
47414        element.className = 'igv-circview-toolbar';
47415        parent.appendChild(element);
47416        this.toolbar = element; // track panel
47417
47418        element = document.createElement('div');
47419        element.className = 'igv-circview-track-panel';
47420        parent.appendChild(element);
47421        this.trackPanel = element;
47422        this.trackPanel.style.display = 'none'; // toolbar button container - Track Options - Clear All
47423
47424        let buttonContainer = document.createElement('div');
47425        buttonContainer.className = 'igv-circview-toolbar-button-container';
47426        this.toolbar.appendChild(buttonContainer); // Track Options
47427
47428        this.trackPanelPresentationButton = document.createElement('div');
47429        this.trackPanelPresentationButton.className = 'igv-circview-button';
47430        buttonContainer.appendChild(this.trackPanelPresentationButton);
47431        this.trackPanelPresentationButton.innerText = 'none' === this.trackPanel.style.display ? 'Show Track Options' : 'Hide Track Options';
47432        this.trackPanelPresentationButton.addEventListener('click', event => {
47433          const trackPanelRows = this.trackPanel.querySelectorAll('div');
47434
47435          if (trackPanelRows.length > 0) {
47436            if ('none' === this.trackPanel.style.display) {
47437              this.trackPanel.style.display = 'flex';
47438              event.target.innerText = 'Hide Track Options';
47439            } else {
47440              this.trackPanel.style.display = 'none';
47441              event.target.innerText = 'Show Track Options';
47442            }
47443          }
47444        }); // Clear All Chords
47445
47446        let button = document.createElement('div');
47447        button.className = 'igv-circview-button';
47448        buttonContainer.appendChild(button);
47449        button.innerText = 'Clear All';
47450        button.addEventListener('click', () => {
47451          this.clearChords();
47452        }); // toolbar button container - Close Window
47453
47454        buttonContainer = document.createElement('div');
47455        buttonContainer.className = 'igv-circview-toolbar-button-container';
47456        this.toolbar.appendChild(buttonContainer); // Close Window
47457
47458        if (false !== this.config.showCloseButton) {
47459          button = document.createElement('div');
47460          button.className = 'igv-circview-button';
47461          buttonContainer.appendChild(button);
47462          button.innerText = 'Close';
47463          button.addEventListener('click', () => {
47464            this.visible = false;
47465          });
47466        }
47467      }
47468
47469      addToTrackPanel(track) {
47470        // single track row - container for hide-button | color-picker-swatch | track-name
47471        const trackPanelRow = document.createElement('div');
47472        this.trackPanel.appendChild(trackPanelRow);
47473        let element; // track hide|show
47474
47475        element = document.createElement('div');
47476        element.className = 'igv-circview-button';
47477        trackPanelRow.appendChild(element);
47478        element.innerText = true === track.visible ? 'Hide' : 'Show';
47479        element.addEventListener('click', event => {
47480          if (true === track.visible) {
47481            this.hideTrack(track.id);
47482            event.target.innerText = "Show";
47483          } else {
47484            this.showTrack(track.id);
47485            event.target.innerText = "Hide";
47486          }
47487        }); // track color
47488
47489        element.clientHeight;
47490        const pickerButton = document.createElement('div');
47491        pickerButton.className = 'igv-circview-button';
47492        pickerButton.innerHTML = '&nbsp;&nbsp;&nbsp;&nbsp;'; // <- important for button to size properly
47493
47494        trackPanelRow.appendChild(pickerButton);
47495        pickerButton.style.backgroundColor = setAlpha(track.color, 1);
47496        const pickerConfig = {
47497          parent: pickerButton,
47498          popup: 'right',
47499          editorFormat: 'rgb',
47500          color: track.color,
47501          onChange: ({
47502            rgbaString
47503          }) => {
47504            pickerButton.style.backgroundColor = setAlpha(rgbaString, 1);
47505            this.setTrackColor(track.id, rgbaString);
47506          }
47507        };
47508        new Picker(pickerConfig); // track name
47509
47510        element = document.createElement('div');
47511        element.style.color = 'black';
47512        trackPanelRow.appendChild(element);
47513        element.innerText = element.title = track.name;
47514      }
47515      /**
47516       * Reset view with a new set of chromosomes.
47517       *
47518       * @param igvGenome {name: string, id: string, chromosomes: [{name: string, bpLength: integer, color: string}
47519       */
47520
47521
47522      setAssembly(igvGenome) {
47523        if (this.genomeId === igvGenome.id) {
47524          return;
47525        }
47526
47527        this.tracks = [];
47528        this.genomeId = igvGenome.id;
47529        this.chrNames = new Set(igvGenome.chromosomes.map(chr => shortChrName$1(chr.name)));
47530        const regions = [];
47531        const colors = [];
47532
47533        for (let chr of igvGenome.chromosomes) {
47534          const shortName = shortChrName$1(chr.name);
47535          colors.push(chr.color || getChrColor$1(shortName));
47536          regions.push({
47537            refName: shortName,
47538            uniqueId: shortName,
47539            start: 0,
47540            end: chr.bpLength
47541          });
47542        }
47543
47544        this.assembly = {
47545          name: igvGenome.name,
47546          sequence: {
47547            trackId: igvGenome.id,
47548            type: 'ReferenceSequenceTrack',
47549            adapter: {
47550              type: 'FromConfigSequenceAdapter',
47551              features: regions
47552            }
47553          },
47554          refNameColors: colors
47555        };
47556        this.render();
47557      }
47558      /**
47559       * Append or replace current set of chords to the global set or a specific track.
47560       *
47561       * @param newChords array of chord feature objects.  Example:
47562       * [
47563       *   {
47564       *     "uniqueId": "chr1:129763372-129763376_chr1:129806775-129806790",
47565       *     "color": "rgba(0, 0, 255, 0.1)",
47566       *     "refName": "1",
47567       *     "start": 129763372,
47568       *     "end": 129763376,
47569       *     "mate": {
47570       *       "refName": "2",
47571       *       "start": 129806775,
47572       *       "end": 129806790
47573       *     }
47574       *   }
47575       * ]
47576       * @param options {
47577       *     name: string,    // Track name
47578       *     color: string,   // Track color
47579       *     append: boolean  // Replace or append chords to current set.  Default is append (true)
47580       * }
47581       */
47582
47583
47584      addChords(newChords, options = {}) {
47585        const name = options.track || options.name || "*";
47586        let track = this.tracks.find(t => name === t.name); // Override track options or create new track
47587
47588        if (track) {
47589          if (options.color) {
47590            track.color = options.color;
47591          }
47592        } else {
47593          track = {
47594            name,
47595            chords: [],
47596            color: options.color || "black",
47597            visible: true,
47598            id: options.id || guid()
47599          };
47600          this.tracks.push(track);
47601          this.addToTrackPanel(track);
47602        } // Append chords to track
47603
47604
47605        const currentIDs = new Set(track.chords.map(c => c.uniqueId));
47606
47607        for (let c of newChords) {
47608          if (!currentIDs.has(c.uniqueId) && this.chrNames.has(shortChrName$1(c.refName)) && this.chrNames.has(shortChrName$1(c.mate.refName))) {
47609            track.chords.push(c);
47610            currentIDs.add(c.uniqueId);
47611          }
47612        }
47613
47614        this.render();
47615      }
47616      /**
47617       * Set the nominal size of the view in pixels.  Size is reduced some aribtrary amount to account for borders and margins
47618       */
47619
47620
47621      setSize(width, height) {
47622        height = height || width;
47623        this.width = width;
47624        this.height = height;
47625
47626        if (this.viewState) {
47627          const view = this.viewState.session.view;
47628          view.setWidth(width);
47629          view.setHeight(height
47630          /* this is the height of the area inside the border in pixels */
47631          );
47632          view.setBpPerPx(view.minBpPerPx);
47633        }
47634      }
47635
47636      getSize() {
47637        return Math.min(this.width, this.height);
47638      }
47639
47640      clearChords() {
47641        this.tracks = [];
47642        this.trackPanel.innerHTML = '';
47643        this.render();
47644      }
47645
47646      clearSelection() {
47647        this.viewState.pluginManager.rootModel.session.clearSelection();
47648      }
47649
47650      getFeature(featureId) {
47651        // TODO -- broken
47652        // const display = this.viewState.pluginManager.rootModel.session.view.tracks[0].displays[0]
47653        // const feature = display.data.features.get(featureId)
47654        // return feature;
47655        const features = [...this.viewState.config.tracks[0].adapter.features.value];
47656
47657        for (let f of features) {
47658          if (featureId === f.uniqueId) {
47659            return f;
47660          }
47661        }
47662      }
47663      /**
47664       * Deprecated, use "visible" property
47665       */
47666
47667
47668      show() {
47669        this.parent.style.display = 'block';
47670      }
47671      /**
47672       * Deprecated, use "visible" property
47673       */
47674
47675
47676      hide() {
47677        this.parent.style.display = 'none';
47678      }
47679
47680      get visible() {
47681        return this.parent.style.display !== 'none';
47682      }
47683
47684      set visible(isVisible) {
47685        this.parent.style.display = isVisible ? 'block' : 'none';
47686      }
47687
47688      hideTrack(trackID) {
47689        let track = this.tracks.find(t => trackID === t.id);
47690
47691        if (track) {
47692          track.visible = false;
47693          this.render();
47694        } else {
47695          console.warn(`No track with name: ${name}`);
47696        }
47697      }
47698
47699      showTrack(trackID) {
47700        let idx = this.tracks.findIndex(t => trackID === t.id);
47701
47702        if (idx >= 0) {
47703          const track = this.tracks[idx];
47704          track.visible = true;
47705          this.tracks.splice(idx, 1); // Change z-order
47706
47707          this.tracks.push(track);
47708          this.render();
47709        } else {
47710          console.warn(`No track with name: ${name}`);
47711        }
47712      } // TODO -- remove corresponding row from track panel
47713
47714
47715      deleteTrack(trackID) {
47716        let idx = this.tracks.findIndex(t => trackID === t.id);
47717
47718        if (idx >= 0) {
47719          this.tracks.splice(idx, 1);
47720        }
47721
47722        this.render();
47723      }
47724
47725      getTrack(trackID) {
47726        return this.tracks.find(t => trackID === t.id);
47727      }
47728
47729      setTrackColor(trackID, color) {
47730        const t = this.getTrack(trackID);
47731
47732        if (t) {
47733          t.color = color;
47734          const trackID = t.id;
47735
47736          for (let jbrowseTrack of this.viewState.config.tracks) {
47737            if (trackID === jbrowseTrack.trackId) {
47738              jbrowseTrack.displays[0].renderer.strokeColor.set(color);
47739              break;
47740            }
47741          }
47742        }
47743      }
47744      /**
47745       * The main render function.  Render here means build the React DOM.  Trying to change react state dynamically
47746       * has been buggy, so we completely rebuild the DOM ("render") on any state change.
47747       */
47748
47749
47750      render() {
47751        const {
47752          createViewState,
47753          JBrowseCircularGenomeView
47754        } = JBrowseReactCircularGenomeView; // Remove all children from possible previous renders.  React might do this for us when we render, but just in case.
47755
47756        ReactDOM.unmountComponentAtNode(this.container);
47757        const visibleTracks = this.tracks.filter(t => false !== t.visible);
47758        const jbrowseTracks = [];
47759        const colors = [];
47760
47761        for (let trackConfig of visibleTracks) {
47762          jbrowseTracks.push({
47763            trackId: trackConfig.id,
47764            name: trackConfig.name,
47765            assemblyNames: ['forIGV'],
47766            type: 'VariantTrack',
47767            adapter: {
47768              type: 'FromConfigAdapter',
47769              features: trackConfig.chords
47770            }
47771          });
47772          colors.push(trackConfig.color);
47773        }
47774
47775        this.viewState = createViewState({
47776          assembly: this.assembly,
47777          tracks: jbrowseTracks
47778        }); // Set view colors
47779
47780        for (let i = 0; i < visibleTracks.length; i++) {
47781          this.viewState.config.tracks[i].displays[0].renderer.strokeColor.set(colors[i]); //this.viewState.config.tracks[i].displays[0].renderer.strokeColor.set("jexl:get(feature, 'color') || 'black'");
47782          //this.viewState.config.tracks[i].displays[0].renderer.strokeColorSelected.set("jexl:get(feature, 'highlightColor') || 'red'");
47783        }
47784
47785        this.element = React.createElement(JBrowseCircularGenomeView, {
47786          viewState: this.viewState
47787        });
47788        this.setSize(this.width, this.height);
47789        ReactDOM.render(this.element, this.container);
47790
47791        for (let i = 0; i < visibleTracks.length; i++) {
47792          this.viewState.session.view.showTrack(this.viewState.config.tracks[i].trackId);
47793
47794          if (this.config.onChordClick) {
47795            this.viewState.pluginManager.jexl.addFunction('onChordClick', this.config.onChordClick);
47796            this.viewState.config.tracks[i].displays[0].onChordClick.set('jexl:onChordClick(feature, track, pluginManager)');
47797          }
47798        }
47799      }
47800
47801    }
47802
47803    function setAlpha(rgba, alpha) {
47804      const [a, b, c, ignore] = rgba.split(','); // rgba(r g b alpha)
47805
47806      return `${a},${b},${c},${alpha})`;
47807    }
47808
47809    function shortChrName$1(chrName) {
47810      return chrName.startsWith("chr") ? chrName.substring(3) : chrName;
47811    }
47812
47813    function guid() {
47814      return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4);
47815    }
47816
47817    function embedCSS$1() {
47818      const css = '.igv-circview-container {\n  z-index: 2048;\n  position: absolute;\n  width: fit-content;\n  height: fit-content;\n  box-sizing: content-box;\n  color: dimgray;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: 12px;\n  background-color: white;\n  border-color: dimgray;\n  border-style: solid;\n  border-width: thin;\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: flex-start; }\n\n.igv-circview-toolbar {\n  position: relative;\n  width: 100%;\n  height: 32px;\n  background-color: lightgrey;\n  border-bottom-style: solid;\n  border-bottom-color: dimgray;\n  border-bottom-width: thin;\n  display: flex;\n  flex-flow: row;\n  flex-wrap: nowrap;\n  justify-content: space-between;\n  align-items: center; }\n\n.igv-circview-toolbar-button-container {\n  height: 100%;\n  width: fit-content;\n  display: flex;\n  flex-flow: row;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: center; }\n  .igv-circview-toolbar-button-container > div {\n    margin: 4px; }\n\n.igv-circview-track-panel {\n  z-index: 1024;\n  position: absolute;\n  top: 33px;\n  left: 0;\n  width: 100%;\n  height: fit-content;\n  border-bottom-style: solid;\n  border-bottom-color: dimgray;\n  border-bottom-width: thin;\n  background-color: white;\n  display: flex;\n  flex-flow: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: flex-start; }\n  .igv-circview-track-panel > div {\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: flex-start;
47818\n    align-items: center; }\n    .igv-circview-track-panel > div > div {\n      margin: 4px; }\n\n.igv-circview-swatch-button {\n  cursor: pointer;\n  padding: 5px;\n  width: 8px;\n  height: 8px;\n  border: 1px solid #8d8b8b;\n  border-radius: 16px; }\n\n.igv-circview-button {\n  cursor: pointer;\n  padding: 5px;\n  color: #444;\n  vertical-align: middle;\n  text-align: center;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: 12px;\n  border: 1px solid #8d8b8b;\n  border-radius: 4px;\n  background: #efefef;\n  box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.2); }\n\n.igv-circview-button:hover {\n  background: #efefef;\n  box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6); }\n\n.igv-circview-button:active {\n  color: #007bff;\n  box-shadow: 0 0 5px -1px rgba(0, 0, 0, 0.6); }\n\n/*# sourceMappingURL=circular-view.css.map */\n';
47819      const style = document.createElement('style');
47820      style.setAttribute('type', 'text/css');
47821      style.innerHTML = css;
47822      document.head.insertBefore(style, document.head.childNodes[document.head.childNodes.length - 1]);
47823    }
47824
47825    if (typeof document !== 'undefined') {
47826      if (!stylesheetExists("circular-view.css")) {
47827        embedCSS$1();
47828      }
47829
47830      function stylesheetExists(stylesheetName) {
47831        for (let ss of document.styleSheets) {
47832          ss = ss.href ? ss.href.replace(/^.*[\\\/]/, '') : '';
47833
47834          if (ss === stylesheetName) {
47835            return true;
47836          }
47837        }
47838
47839        return false;
47840      }
47841    }
47842
47843    /**
47844     * The minimum length for a VCF structural variant.  VCF records < this length are ignored in the circular view
47845     * @type {number}
47846     */
47847
47848    const MINIMUM_SV_LENGTH = 1000000;
47849
47850    const shortChrName = chrName => {
47851      return chrName.startsWith("chr") ? chrName.substring(3) : chrName;
47852    };
47853
47854    const makePairedAlignmentChords = alignments => {
47855      const chords = [];
47856
47857      for (let a of alignments) {
47858        const mate = a.mate;
47859
47860        if (mate && mate.chr && mate.position) {
47861          chords.push({
47862            uniqueId: a.readName,
47863            refName: shortChrName(a.chr),
47864            start: a.start,
47865            end: a.end,
47866            mate: {
47867              refName: shortChrName(mate.chr),
47868              start: mate.position - 1,
47869              end: mate.position
47870            }
47871          });
47872        }
47873      }
47874
47875      return chords;
47876    };
47877
47878    const makeSupplementalAlignmentChords = alignments => {
47879      const chords = [];
47880
47881      for (let a of alignments) {
47882        const sa = a.tags()['SA'];
47883        const supAl = createSupplementaryAlignments(sa);
47884        let n = 0;
47885
47886        for (let s of supAl) {
47887          if (s.start !== a.start) {
47888            chords.push({
47889              uniqueId: `${a.readName}_${n++}`,
47890              refName: shortChrName(a.chr),
47891              start: a.start,
47892              end: a.end,
47893              mate: {
47894                refName: shortChrName(s.chr),
47895                start: s.start,
47896                end: s.start + s.lenOnRef
47897              }
47898            });
47899          }
47900        }
47901      }
47902
47903      return chords;
47904    };
47905
47906    const makeBedPEChords = features => {
47907      return features.map(v => {
47908        // If v is a whole-genome feature, get the true underlying variant.
47909        const f = v._f || v;
47910        return {
47911          uniqueId: `${f.chr1}:${f.start1}-${f.end1}_${f.chr2}:${f.start2}-${f.end2}`,
47912          refName: shortChrName(f.chr1),
47913          start: f.start1,
47914          end: f.end1,
47915          mate: {
47916            refName: shortChrName(f.chr2),
47917            start: f.start2,
47918            end: f.end2
47919          }
47920        };
47921      });
47922    };
47923
47924    const makeVCFChords = features => {
47925      const svFeatures = features.filter(v => {
47926        const f = v._f || v;
47927        const isLargeEnough = f.info && f.info.CHR2 && f.info.END && (f.info.CHR2 !== f.chr || Math.abs(Number.parseInt(f.info.END) - f.pos) > MINIMUM_SV_LENGTH);
47928        return isLargeEnough;
47929      });
47930      return svFeatures.map(v => {
47931        // If v is a whole-genome feature, get the true underlying variant.
47932        const f = v._f || v;
47933        const pos2 = Number.parseInt(f.info.END);
47934        const start2 = pos2 - 100;
47935        const end2 = pos2 + 100;
47936        return {
47937          uniqueId: `${f.chr}:${f.start}-${f.end}_${f.info.CHR2}:${f.info.END}`,
47938          refName: shortChrName(f.chr),
47939          start: f.start,
47940          end: f.end,
47941          mate: {
47942            refName: shortChrName(f.info.CHR2),
47943            start: start2,
47944            end: end2
47945          }
47946        };
47947      });
47948    };
47949
47950    function makeCircViewChromosomes(genome) {
47951      const regions = [];
47952      const colors = [];
47953
47954      for (let chrName of genome.wgChromosomeNames) {
47955        const chr = genome.getChromosome(chrName);
47956        colors.push(getChrColor(chr.name));
47957        regions.push({
47958          name: chr.name,
47959          bpLength: chr.bpLength
47960        });
47961      }
47962
47963      return regions;
47964    }
47965
47966    function createCircularView(el, browser) {
47967      const circularView = new CircularView(el, {
47968        onChordClick: (feature, chordTrack, pluginManager) => {
47969          const f1 = feature.data;
47970          const f2 = f1.mate;
47971          const flanking = 2000;
47972          const l1 = new Locus({
47973            chr: browser.genome.getChromosomeName(f1.refName),
47974            start: f1.start,
47975            end: f1.end
47976          });
47977          const l2 = new Locus({
47978            chr: browser.genome.getChromosomeName(f2.refName),
47979            start: f2.start,
47980            end: f2.end
47981          });
47982          let loci; // If there is overlap with current loci
47983
47984          loci = browser.currentLoci().map(str => Locus.fromLocusString(str));
47985
47986          if (loci.some(locus => locus.contains(l1)) || loci.some(locus => locus.contains(l2))) {
47987            for (let l of [l1, l2]) {
47988              if (!loci.some(locus => {
47989                return locus.contains(l);
47990              })) {
47991                // add flanking
47992                l.start = Math.max(0, l.start - flanking);
47993                l.end += flanking;
47994                loci.push(l);
47995              }
47996            }
47997          } else {
47998            l1.start = Math.max(0, l1.start - flanking);
47999            l1.end += flanking;
48000            l2.start = Math.max(0, l2.start - flanking);
48001            l2.end += flanking;
48002            loci = [l1, l2];
48003          }
48004
48005          const searchString = loci.map(l => l.getLocusString()).join(" ");
48006          browser.search(searchString);
48007        }
48008      });
48009      return circularView;
48010    }
48011
48012    /*
48013     * The MIT License (MIT)
48014     *
48015     * Copyright (c) 2014 Broad Institute
48016     *
48017     * Permission is hereby granted, free of charge, to any person obtaining a copy
48018     * of this software and associated documentation files (the "Software"), to deal
48019     * in the Software without restriction, including without limitation the rights
48020     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
48021     * copies of the Software, and to permit persons to whom the Software is
48022     * furnished to do so, subject to the following conditions:
48023     *
48024     * The above copyright notice and this permission notice shall be included in
48025     * all copies or substantial portions of the Software.
48026     *
48027     *
48028     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48029     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48030     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48031     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48032     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
48033     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
48034     * THE SOFTWARE.
48035     */
48036    const alignmentStartGap = 5;
48037    const downsampleRowHeight = 5;
48038    const DEFAULT_COVERAGE_TRACK_HEIGHT = 50;
48039    const DEFAULT_TRACK_HEIGHT = 300;
48040    const DEFAULT_ALIGNMENT_COLOR = "rgb(185, 185, 185)";
48041    const DEFAULT_COVERAGE_COLOR = "rgb(150, 150, 150)";
48042    const DEFAULT_CONNECTOR_COLOR = "rgb(200, 200, 200)";
48043
48044    class BAMTrack extends TrackBase {
48045      constructor(config, browser) {
48046        super(config, browser);
48047      }
48048
48049      init(config) {
48050        super.init(config);
48051        this.type = "alignment";
48052
48053        if (config.alleleFreqThreshold === undefined) {
48054          config.alleleFreqThreshold = 0.2;
48055        }
48056
48057        this.featureSource = new BamSource(config, this.browser);
48058        this.showCoverage = config.showCoverage === undefined ? true : config.showCoverage;
48059        this.showAlignments = config.showAlignments === undefined ? true : config.showAlignments;
48060        this.coverageTrack = new CoverageTrack(config, this);
48061        this.alignmentTrack = new AlignmentTrack(config, this);
48062        this.alignmentTrack.setTop(this.coverageTrack, this.showCoverage);
48063        this.visibilityWindow = config.visibilityWindow || 30000;
48064        this.viewAsPairs = config.viewAsPairs;
48065        this.pairsSupported = config.pairsSupported !== false;
48066        this.showSoftClips = config.showSoftClips;
48067        this.showAllBases = config.showAllBases;
48068        this.showInsertions = false !== config.showInsertions;
48069        this.showMismatches = false !== config.showMismatches;
48070        this.color = config.color;
48071        this.coverageColor = config.coverageColor;
48072        this.minFragmentLength = config.minFragmentLength; // Optional, might be undefined
48073
48074        this.maxFragmentLength = config.maxFragmentLength || 1000; // The sort object can be an array in the case of multi-locus view, however if multiple sort positions
48075        // are present for a given reference frame the last one will take precedence
48076
48077        if (config.sort) {
48078          if (Array.isArray(config.sort)) {
48079            // Legacy support
48080            this.assignSort(config.sort[0]);
48081          } else {
48082            this.assignSort(config.sort);
48083          }
48084        } // Invoke height setter last to allocated to coverage and alignment tracks
48085
48086
48087        this.height = config.height !== undefined ? config.height : DEFAULT_TRACK_HEIGHT;
48088      }
48089
48090      set height(h) {
48091        this._height = h;
48092
48093        if (this.coverageTrack && this.showAlignments) {
48094          this.alignmentTrack.height = this.showCoverage ? h - this.coverageTrack.height : h;
48095        }
48096      }
48097
48098      get height() {
48099        return this._height;
48100      }
48101
48102      sort(options) {
48103        options = this.assignSort(options);
48104
48105        for (let vp of this.trackView.viewports) {
48106          if (vp.containsPosition(options.chr, options.position)) {
48107            const alignmentContainer = vp.getCachedFeatures();
48108
48109            if (alignmentContainer) {
48110              sortAlignmentRows(options, alignmentContainer);
48111              vp.repaint();
48112            }
48113          }
48114        }
48115      }
48116      /**
48117       * Fix syntax problems for sort options.
48118       * @param options
48119       */
48120
48121
48122      assignSort(options) {
48123        // convert old syntax
48124        if (options.locus) {
48125          const range = parseLocusString$1(options.locus);
48126          options.chr = range.chr;
48127          options.position = range.start;
48128        } else {
48129          options.position--;
48130        }
48131
48132        options.direction = options.direction === "ASC" || options.direction === true; // chr aliasing
48133
48134        options.chr = this.browser.genome.getChromosomeName(options.chr);
48135        this.sortObject = options;
48136        return this.sortObject;
48137      }
48138
48139      async getFeatures(chr, bpStart, bpEnd, bpPerPixel, viewport) {
48140        const alignmentContainer = await this.featureSource.getAlignments(chr, bpStart, bpEnd);
48141
48142        if (alignmentContainer.alignments && alignmentContainer.alignments.length > 99) {
48143          if (undefined === this.minFragmentLength) {
48144            this.minFragmentLength = alignmentContainer.pairedEndStats.lowerFragmentLength;
48145          }
48146
48147          if (undefined === this.maxFragmentLength) {
48148            this.maxFragmentLength = alignmentContainer.pairedEndStats.upperFragmentLength;
48149          }
48150        }
48151
48152        const sort = this.sortObject;
48153
48154        if (sort) {
48155          if (sort.chr === chr && sort.position >= bpStart && sort.position <= bpEnd) {
48156            sortAlignmentRows(sort, alignmentContainer);
48157          }
48158        }
48159
48160        return alignmentContainer;
48161      }
48162      /**
48163       * Compute the pixel height required to display all content.  This is not the same as the viewport height
48164       * (track.height) which might include a scrollbar.
48165       *
48166       * @param alignmentContainer
48167       * @returns {number}
48168       */
48169
48170
48171      computePixelHeight(alignmentContainer) {
48172        return (this.showCoverage ? this.coverageTrack.height : 0) + (this.showAlignments ? this.alignmentTrack.computePixelHeight(alignmentContainer) : 0) + 15;
48173      }
48174
48175      draw(options) {
48176        IGVGraphics.fillRect(options.context, 0, options.pixelTop, options.pixelWidth, options.pixelHeight, {
48177          'fillStyle': "rgb(255, 255, 255)"
48178        });
48179
48180        if (true === this.showCoverage && this.coverageTrack.height > 0) {
48181          this.trackView.axisCanvas.style.display = 'block';
48182          this.coverageTrack.draw(options);
48183        } else {
48184          this.trackView.axisCanvas.style.display = 'none';
48185        }
48186
48187        if (true === this.showAlignments) {
48188          this.alignmentTrack.setTop(this.coverageTrack, this.showCoverage);
48189          this.alignmentTrack.draw(options);
48190        }
48191      }
48192
48193      paintAxis(ctx, pixelWidth, pixelHeight) {
48194        this.coverageTrack.paintAxis(ctx, pixelWidth, this.coverageTrack.height); // if (this.browser.isMultiLocusMode()) {
48195        //     ctx.clearRect(0, 0, pixelWidth, pixelHeight);
48196        // } else {
48197        //     this.coverageTrack.paintAxis(ctx, pixelWidth, this.coverageTrack.height);
48198        // }
48199      }
48200
48201      contextMenuItemList(config) {
48202        return this.alignmentTrack.contextMenuItemList(config);
48203      }
48204
48205      popupData(clickState) {
48206        if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrack.height) {
48207          return this.coverageTrack.popupData(clickState);
48208        } else {
48209          return this.alignmentTrack.popupData(clickState);
48210        }
48211      }
48212      /**
48213       * Return the features (alignment, coverage, downsampled interval) clicked on.  Needed for "oncl
48213ick" event.
48214       * @param clickState
48215       * @param features
48216       */
48217
48218
48219      clickedFeatures(clickState) {
48220        if (true === this.showCoverage && clickState.y >= this.coverageTrack.top && clickState.y < this.coverageTrack.height) {
48221          return [this.coverageTrack.getClickedObject(clickState)];
48222        } else {
48223          return [this.alignmentTrack.getClickedObject(clickState)];
48224        }
48225      }
48226
48227      menuItemList() {
48228        // Start with overage track items
48229        let menuItems = [];
48230        menuItems = menuItems.concat(MenuUtils.numericDataMenuItems(this.trackView)); // Color by items
48231
48232        menuItems.push('<hr/>');
48233        const $e = $$1('<div class="igv-track-menu-category">');
48234        $e.text('Color by:');
48235        menuItems.push({
48236          name: undefined,
48237          object: $e,
48238          click: undefined,
48239          init: undefined
48240        });
48241        const colorByMenuItems = [{
48242          key: 'strand',
48243          label: 'read strand'
48244        }];
48245
48246        if (this.alignmentTrack.hasPairs) {
48247          colorByMenuItems.push({
48248            key: 'firstOfPairStrand',
48249            label: 'first-of-pair strand'
48250          });
48251          colorByMenuItems.push({
48252            key: 'pairOrientation',
48253            label: 'pair orientation'
48254          });
48255          colorByMenuItems.push({
48256            key: 'fragmentLength',
48257            label: 'insert size (TLEN)'
48258          });
48259          colorByMenuItems.push({
48260            key: 'unexpectedPair',
48261            label: 'pair orientation & insert size (TLEN)'
48262          });
48263        }
48264
48265        const tagLabel = 'tag' + (this.alignmentTrack.colorByTag ? ' (' + this.alignmentTrack.colorByTag + ')' : '');
48266        colorByMenuItems.push({
48267          key: 'tag',
48268          label: tagLabel
48269        });
48270
48271        for (let item of colorByMenuItems) {
48272          const selected = this.alignmentTrack.colorBy === item.key;
48273          menuItems.push(this.colorByCB(item, selected));
48274        } // Show coverage / alignment options
48275
48276
48277        const adjustTrackHeight = () => {
48278          if (!this.autoHeight) {
48279            const h = 15 + (this.showCoverage ? this.coverageTrack.height : 0) + (this.showAlignments ? this.alignmentTrack.height : 0);
48280            this.trackView.setTrackHeight(h);
48281          }
48282        };
48283
48284        menuItems.push('<hr/>');
48285        menuItems.push({
48286          object: $$1(createCheckbox$1("Show Coverage", this.showCoverage)),
48287          click: () => {
48288            this.showCoverage = !this.showCoverage;
48289            adjustTrackHeight();
48290            this.trackView.checkContentHeight();
48291            this.trackView.repaintViews();
48292          }
48293        });
48294        menuItems.push({
48295          object: $$1(createCheckbox$1("Show Alignments", this.showAlignments)),
48296          click: () => {
48297            this.showAlignments = !this.showAlignments;
48298            adjustTrackHeight();
48299            this.trackView.checkContentHeight();
48300            this.trackView.repaintViews();
48301          }
48302        }); // Show all bases
48303
48304        menuItems.push('<hr/>');
48305        menuItems.push({
48306          object: $$1(createCheckbox$1("Show all bases", this.showAllBases)),
48307          click: () => {
48308            this.showAllBases = !this.showAllBases;
48309            this.config.showAllBases = this.showAllBases;
48310            this.trackView.repaintViews();
48311          }
48312        }); // Show mismatches
48313
48314        menuItems.push('<hr/>');
48315        menuItems.push({
48316          object: $$1(createCheckbox$1("Show mismatches", this.showMismatches)),
48317          click: () => {
48318            this.showMismatches = !this.showMismatches;
48319            this.config.showMismatches = this.showMismatches;
48320            this.trackView.repaintViews();
48321          }
48322        }); // Insertions
48323
48324        menuItems.push({
48325          object: $$1(createCheckbox$1("Show insertions", this.showInsertions)),
48326          click: () => {
48327            this.showInsertions = !this.showInsertions;
48328            this.config.showInsertions = this.showInsertions;
48329            this.getCachedAlignmentContainers();
48330            this.trackView.repaintViews();
48331          }
48332        }); // Soft clips
48333
48334        menuItems.push({
48335          object: $$1(createCheckbox$1("Show soft clips", this.showSoftClips)),
48336          click: () => {
48337            this.showSoftClips = !this.showSoftClips;
48338            this.config.showSoftClips = this.showSoftClips;
48339            this.featureSource.setShowSoftClips(this.showSoftClips);
48340            const alignmentContainers = this.getCachedAlignmentContainers();
48341
48342            for (let ac of alignmentContainers) {
48343              ac.setShowSoftClips(this.showSoftClips);
48344            }
48345
48346            this.trackView.repaintViews();
48347          }
48348        }); // View as pairs
48349
48350        if (this.pairsSupported && this.alignmentTrack.hasPairs) {
48351          menuItems.push('<hr/>');
48352          menuItems.push({
48353            object: $$1(createCheckbox$1("View as pairs", this.viewAsPairs)),
48354            click: () => {
48355              this.viewAsPairs = !this.viewAsPairs;
48356              this.config.viewAsPairs = this.viewAsPairs;
48357              this.featureSource.setViewAsPairs(this.viewAsPairs);
48358              const alignmentContainers = this.getCachedAlignmentContainers();
48359
48360              for (let ac of alignmentContainers) {
48361                ac.setViewAsPairs(this.viewAsPairs);
48362              }
48363
48364              this.trackView.repaintViews();
48365            }
48366          });
48367        } // Experimental JBrowse feature
48368
48369
48370        if (this.browser.circularView && true === this.browser.circularViewVisible && (this.alignmentTrack.hasPairs || this.alignmentTrack.hasSupplemental)) {
48371          menuItems.push('<hr/>');
48372
48373          if (this.alignmentTrack.hasPairs) {
48374            menuItems.push({
48375              label: 'Add discordant pairs to circular view',
48376              click: () => {
48377                const maxFragmentLength = this.maxFragmentLength;
48378                const inView = [];
48379
48380                for (let viewport of this.trackView.viewports) {
48381                  for (let a of viewport.getCachedFeatures().allAlignments()) {
48382                    const referenceFrame = viewport.referenceFrame;
48383
48384                    if (a.end >= referenceFrame.start && a.start <= referenceFrame.end && a.mate && a.mate.chr && (a.mate.chr !== a.chr || Math.max(a.fragmentLength) > maxFragmentLength)) {
48385                      inView.push(a);
48386                    }
48387                  }
48388                }
48389
48390                this.browser.circularViewVisible = true;
48391                const chords = makePairedAlignmentChords(inView);
48392                const color = IGVColor.addAlpha(this.color || 'rgb(0,0,255)', 0.02);
48393                this.browser.circularView.addChords(chords, {
48394                  track: this.name,
48395                  color: color
48396                });
48397              }
48398            });
48399          }
48400
48401          if (this.alignmentTrack.hasSupplemental) {
48402            menuItems.push({
48403              label: 'Add split reads to circular view',
48404              click: () => {
48405                const inView = [];
48406
48407                for (let viewport of this.trackView.viewports) {
48408                  for (let a of viewport.getCachedFeatures().allAlignments()) {
48409                    const referenceFrame = viewport.referenceFrame;
48410                    const sa = a.hasTag('SA');
48411
48412                    if (a.end >= referenceFrame.start && a.start <= referenceFrame.end && sa) {
48413                      inView.push(a);
48414                    }
48415                  }
48416                }
48417
48418                const chords = makeSupplementalAlignmentChords(inView);
48419                const color = IGVColor.addAlpha(this.color || 'rgb(0,0,255)', 0.1);
48420                this.browser.circularView.addChords(chords, {
48421                  track: this.name,
48422                  color: color
48423                });
48424              }
48425            });
48426          }
48427        } // Display mode
48428
48429
48430        menuItems.push('<hr/>');
48431        const $dml = $$1('<div class="igv-track-menu-category">');
48432        $dml.text('Display mode:');
48433        menuItems.push({
48434          name: undefined,
48435          object: $dml,
48436          click: undefined,
48437          init: undefined
48438        });
48439        menuItems.push({
48440          object: $$1(createCheckbox$1("expand", this.alignmentTrack.displayMode === "EXPANDED")),
48441          click: () => {
48442            this.alignmentTrack.displayMode = "EXPANDED";
48443            this.config.displayMode = "EXPANDED";
48444            this.trackView.checkContentHeight();
48445            this.trackView.repaintViews();
48446          }
48447        });
48448        menuItems.push({
48449          object: $$1(createCheckbox$1("squish", this.alignmentTrack.displayMode === "SQUISHED")),
48450          click: () => {
48451            this.alignmentTrack.displayMode = "SQUISHED";
48452            this.config.displayMode = "SQUISHED";
48453            this.trackView.checkContentHeight();
48454            this.trackView.repaintViews();
48455          }
48456        });
48457        return menuItems;
48458      }
48459      /**
48460       * Create a "color by" checkbox menu item, optionally initially checked
48461       * @param menuItem
48462       * @param showCheck
48463       * @returns {{init: undefined, name: undefined, click: clickHandler, object: (jQuery|HTMLElement|jQuery.fn.init)}}
48464       */
48465
48466
48467      colorByCB(menuItem, showCheck) {
48468        const $e = $$1(createCheckbox$1(menuItem.label, showCheck));
48469
48470        const clickHandler = ev => {
48471          if (menuItem.key !== 'tag') {
48472            if (menuItem.key === this.alignmentTrack.colorBy) {
48473              this.alignmentTrack.colorBy = 'none';
48474              this.config.colorBy = 'none';
48475              this.trackView.repaintViews();
48476            } else {
48477              this.alignmentTrack.colorBy = menuItem.key;
48478              this.config.colorBy = menuItem.key;
48479              this.trackView.repaintViews();
48480            }
48481          } else {
48482            this.browser.inputDialog.present({
48483              label: 'Tag Name',
48484              value: this.alignmentTrack.colorByTag ? this.alignmentTrack.colorByTag : '',
48485              callback: tag => {
48486                if (tag) {
48487                  this.alignmentTrack.colorBy = 'tag';
48488                  this.alignmentTrack.colorByTag = tag;
48489
48490                  if (!this.alignmentTrack.tagColors) {
48491                    this.alignmentTrack.tagColors = new PaletteColorTable("Set1");
48492                  }
48493                } else {
48494                  this.alignmentTrack.colorBy = 'none';
48495                  this.alignmentTrack.colorByTag = '';
48496                }
48497
48498                this.trackView.repaintViews();
48499              }
48500            }, ev);
48501          }
48502        };
48503
48504        return {
48505          name: undefined,
48506          object: $e,
48507          click: clickHandler,
48508          init: undefined
48509        };
48510      }
48511      /**
48512       * Called when the track is removed.  Do any needed cleanup here
48513       */
48514
48515
48516      dispose() {
48517        this.trackView = undefined;
48518      }
48519      /**
48520       * Return the current state of the track.  Used to create sessions and bookmarks.
48521       *
48522       * @returns {*|{}}
48523       */
48524
48525
48526      getState() {
48527        const config = super.getState();
48528
48529        if (this.sortObject) {
48530          config.sort = {
48531            chr: this.sortObject.chr,
48532            position: this.sortObject.position + 1,
48533            option: this.sortObject.option,
48534            direction: this.sortObject.direction ? "ASC" : "DESC"
48535          };
48536        }
48537
48538        return config;
48539      }
48540
48541      getCachedAlignmentContainers() {
48542        return this.trackView.viewports.map(vp => vp.getCachedFeatures());
48543      }
48544
48545      get dataRange() {
48546        return this.coverageTrack.dataRange;
48547      }
48548
48549      set dataRange(dataRange) {
48550        this.coverageTrack.dataRange = dataRange;
48551      }
48552
48553      get logScale() {
48554        return this.coverageTrack.logScale;
48555      }
48556
48557      set logScale(logScale) {
48558        this.coverageTrack.logScale = logScale;
48559      }
48560
48561      get autoscale() {
48562        return this.coverageTrack.autoscale;
48563      }
48564
48565      set autoscale(autoscale) {
48566        this.coverageTrack.autoscale = autoscale;
48567      }
48568
48569    }
48570
48571    class CoverageTrack {
48572      constructor(config, parent) {
48573        this.parent = parent;
48574        this.featureSource = parent.featureSource;
48575        this.height = config.coverageTrackHeight !== undefined ? config.coverageTrackHeight : DEFAULT_COVERAGE_TRACK_HEIGHT;
48576        this.paintAxis = paintAxis;
48577        this.top = 0;
48578        this.autoscale = config.autoscale || config.max === undefined;
48579
48580        if (!this.autoscale) {
48581          this.dataRange = {
48582            min: config.min || 0,
48583            max: config.max
48584          };
48585        }
48586      }
48587
48588      draw(options) {
48589        const pixelTop = options.pixelTop;
48590        pixelTop + options.pixelHeight;
48591        const nucleotideColors = this.parent.browser.nucleotideColors;
48592
48593        if (pixelTop > this.height) {
48594          return; //scrolled out of view
48595        }
48596
48597        const ctx = options.context;
48598        const alignmentContainer = options.features;
48599        const coverageMap = alignmentContainer.coverageMap;
48600        let sequence;
48601
48602        if (coverageMap.refSeq) {
48603          sequence = coverageMap.refSeq.toUpperCase();
48604        }
48605
48606        const bpPerPixel = options.bpPerPixel;
48607        const bpStart = options.bpStart;
48608        const pixelWidth = options.pixelWidth;
48609        const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;
48609 // paint for all coverage buckets
48610        // If alignment track color is != default, use it
48611
48612        let color;
48613
48614        if (this.parent.coverageColor) {
48615          color = this.parent.coverageColor;
48616        } else if (this.parent.color !== undefined) {
48617          color = IGVColor.darkenLighten(this.parent.color, -35);
48618        } else {
48619          color = DEFAULT_COVERAGE_COLOR;
48620        }
48621
48622        IGVGraphics.setProperties(ctx, {
48623          fillStyle: color,
48624          strokeStyle: color
48625        });
48626        const w = Math.max(1, Math.ceil(1.0 / bpPerPixel));
48627
48628        for (let i = 0, len = coverageMap.coverage.length; i < len; i++) {
48629          const bp = coverageMap.bpStart + i;
48630          if (bp < bpStart) continue;
48631          if (bp > bpEnd) break;
48632          const item = coverageMap.coverage[i];
48633          if (!item) continue;
48634          const h = Math.round(item.total / this.dataRange.max * this.height);
48635          const y = this.height - h;
48636          const x = Math.floor((bp - bpStart) / bpPerPixel); // IGVGraphics.setProperties(ctx, {fillStyle: "rgba(0, 200, 0, 0.25)", strokeStyle: "rgba(0, 200, 0, 0.25)" });
48637
48638          IGVGraphics.fillRect(ctx, x, y, w, h);
48639        } // coverage mismatch coloring -- don't try to do this in above loop, color bar will be overwritten when w<1
48640
48641
48642        if (sequence) {
48643          for (let i = 0, len = coverageMap.coverage.length; i < len; i++) {
48644            const bp = coverageMap.bpStart + i;
48645            if (bp < bpStart) continue;
48646            if (bp > bpEnd) break;
48647            const item = coverageMap.coverage[i];
48648            if (!item) continue;
48649            const h = item.total / this.dataRange.max * this.height;
48650            let y = this.height - h;
48651            const x = Math.floor((bp - bpStart) / bpPerPixel);
48652            const refBase = sequence[i];
48653
48654            if (item.isMismatch(refBase)) {
48655              IGVGraphics.setProperties(ctx, {
48656                fillStyle: nucleotideColors[refBase]
48657              });
48658              IGVGraphics.fillRect(ctx, x, y, w, h);
48659              let accumulatedHeight = 0.0;
48660
48661              for (let nucleotide of ["A", "C", "T", "G"]) {
48662                const count = item["pos" + nucleotide] + item["neg" + nucleotide]; // non-logoritmic
48663
48664                const hh = count / this.dataRange.max * this.height;
48665                y = this.height - hh - accumulatedHeight;
48666                accumulatedHeight += hh;
48667                IGVGraphics.setProperties(ctx, {
48668                  fillStyle: nucleotideColors[nucleotide]
48669                });
48670                IGVGraphics.fillRect(ctx, x, y, w, hh);
48671              }
48672            }
48673          }
48674        }
48675      }
48676
48677      getClickedObject(clickState) {
48678        let features = clickState.viewport.getCachedFeatures();
48679        if (!features || features.length === 0) return;
48680        const genomicLocation = Math.floor(clickState.genomicLocation);
48681        const coverageMap = features.coverageMap;
48682        const coverageMapIndex = Math.floor(genomicLocation - coverageMap.bpStart);
48683        return coverageMap.coverage[coverageMapIndex];
48684      }
48685
48686      popupData(clickState) {
48687        const nameValues = [];
48688        const coverage = this.getClickedObject(clickState);
48689
48690        if (coverage) {
48691          const genomicLocation = Math.floor(clickState.genomicLocation);
48692          const referenceFrame = clickState.viewport.referenceFrame;
48693          nameValues.push(referenceFrame.chr + ":" + numberFormatter$1(1 + genomicLocation));
48694          nameValues.push({
48695            name: 'Total Count',
48696            value: coverage.total
48697          }); // A
48698
48699          let tmp = coverage.posA + coverage.negA;
48700          if (tmp > 0) tmp = tmp.toString() + " (" + Math.round(tmp / coverage.total * 100.0) + "%, " + coverage.posA + "+, " + coverage.negA + "- )";
48701          nameValues.push({
48702            name: 'A',
48703            value: tmp
48704          }); // C
48705
48706          tmp = coverage.posC + coverage.negC;
48707          if (tmp > 0) tmp = tmp.toString() + " (" + Math.round(tmp / coverage.total * 100.0) + "%, " + coverage.posC + "+, " + coverage.negC + "- )";
48708          nameValues.push({
48709            name: 'C',
48710            value: tmp
48711          }); // G
48712
48713          tmp = coverage.posG + coverage.negG;
48714          if (tmp > 0) tmp = tmp.toString() + " (" + Math.round(tmp / coverage.total * 100.0) + "%, " + coverage.posG + "+, " + coverage.negG + "- )";
48715          nameValues.push({
48716            name: 'G',
48717            value: tmp
48718          }); // T
48719
48720          tmp = coverage.posT + coverage.negT;
48721          if (tmp > 0) tmp = tmp.toString() + " (" + Math.round(tmp / coverage.total * 100.0) + "%, " + coverage.posT + "+, " + coverage.negT + "- )";
48722          nameValues.push({
48723            name: 'T',
48724            value: tmp
48725          }); // N
48726
48727          tmp = coverage.posN + coverage.negN;
48728          if (tmp > 0) tmp = tmp.toString() + " (" + Math.round(tmp / coverage.total * 100.0) + "%, " + coverage.posN + "+, " + coverage.negN + "- )";
48729          nameValues.push({
48730            name: 'N',
48731            value: tmp
48732          });
48733          nameValues.push('<HR/>');
48734          nameValues.push({
48735            name: 'DEL',
48736            value: coverage.del.toString()
48737          });
48738          nameValues.push({
48739            name: 'INS',
48740            value: coverage.ins.toString()
48741          });
48742        }
48743
48744        return nameValues;
48745      }
48746
48747    }
48748
48749    class AlignmentTrack {
48750      constructor(config, parent) {
48751        this.parent = parent;
48752        this.browser = parent.browser;
48753        this.featureSource = parent.featureSource;
48754        this.top = 0 === config.coverageTrackHeight ? 0 : config.coverageTrackHeight + 5;
48755        this.displayMode = config.displayMode || "EXPANDED";
48756        this.alignmentRowHeight = config.alignmentRowHeight || 14;
48757        this.squishedRowHeight = config.squishedRowHeight || 3;
48758        this.negStrandColor = config.negStrandColor || "rgba(150, 150, 230, 0.75)";
48759        this.posStrandColor = config.posStrandColor || "rgba(230, 150, 150, 0.75)";
48760        this.insertionColor = config.insertionColor || "rgb(138, 94, 
48760161)";
48761        this.deletionColor = config.deletionColor || "black";
48762        this.skippedColor = config.skippedColor || "rgb(150, 170, 170)";
48763        this.pairConnectorColor = config.pairConnectorColor;
48764        this.smallFragmentLengthColor = config.smallFragmentLengthColor || "rgb(0, 0, 150)";
48765        this.largeFragmentLengthColor = config.largeFragmentLengthColor || "rgb(200, 0, 0)";
48766        this.pairOrientation = config.pairOrienation || 'fr';
48767        this.pairColors = {};
48768        this.pairColors["RL"] = config.rlColor || "rgb(0, 150, 0)";
48769        this.pairColors["RR"] = config.rrColor || "rgb(20, 50, 200)";
48770        this.pairColors["LL"] = config.llColor || "rgb(0, 150, 150)";
48771        this.colorBy = config.colorBy || "pairOrientation";
48772        this.colorByTag = config.colorByTag ? config.colorByTag.toUpperCase() : undefined;
48773        this.bamColorTag = config.bamColorTag === undefined ? "YC" : config.bamColorTag;
48774        this.hideSmallIndels = config.hideSmallIndels;
48775        this.indelSizeThreshold = config.indelSizeThreshold || 1;
48776        this.hasPairs = false; // Until proven otherwise
48777
48778        this.hasSupplemental = false;
48779      }
48780
48781      setTop(coverageTrack, showCoverage) {
48782        this.top = 0 === coverageTrack.height || false === showCoverage ? 0 : 5 + coverageTrack.height;
48783      }
48784      /**
48785       * Compute the pixel height required to display all content.
48786       *
48787       * @param alignmentContainer
48788       * @returns {number|*}
48789       */
48790
48791
48792      computePixelHeight(alignmentContainer) {
48793        if (alignmentContainer.packedAlignmentRows) {
48794          const h = alignmentContainer.hasDownsampledIntervals() ? downsampleRowHeight + alignmentStartGap : 0;
48795          const alignmentRowHeight = this.displayMode === "SQUISHED" ? this.squishedRowHeight : this.alignmentRowHeight;
48796          return h + alignmentRowHeight * alignmentContainer.packedAlignmentRows.length + 5;
48797        } else {
48798          return 0;
48799        }
48800      }
48801
48802      draw(options) {
48803        const alignmentContainer = options.features;
48804        const ctx = options.context;
48805        const bpPerPixel = options.bpPerPixel;
48806        const bpStart = options.bpStart;
48807        const pixelWidth = options.pixelWidth;
48808        const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;
48809        const showSoftClips = this.parent.showSoftClips;
48810        const showAllBases = this.parent.showAllBases;
48811        const nucleotideColors = this.browser.nucleotideColors; //alignmentContainer.repack(bpPerPixel, showSoftClips);
48812
48813        const packedAlignmentRows = alignmentContainer.packedAlignmentRows;
48814        ctx.save();
48815        let referenceSequence = alignmentContainer.sequence;
48816
48817        if (referenceSequence) {
48818          referenceSequence = referenceSequence.toUpperCase();
48819        }
48820
48821        let alignmentRowYInset = 0;
48822        let pixelTop = options.pixelTop;
48823
48824        if (this.top) {
48825          ctx.translate(0, this.top);
48826        }
48827
48828        const pixelBottom = pixelTop + options.pixelHeight;
48829
48830        if (alignmentContainer.hasDownsampledIntervals()) {
48831          alignmentRowYInset = downsampleRowHeight + alignmentStartGap;
48832          alignmentContainer.downsampledIntervals.forEach(function (interval) {
48833            var xBlockStart = (interval.start - bpStart) / bpPerPixel,
48834                xBlockEnd = (interval.end - bpStart) / bpPerPixel;
48835
48836            if (xBlockEnd - xBlockStart > 5) {
48837              xBlockStart += 1;
48838              xBlockEnd -= 1;
48839            }
48840
48841            IGVGraphics.fillRect(ctx, xBlockStart, 2, xBlockEnd - xBlockStart, downsampleRowHeight - 2, {
48842              fillStyle: "black"
48843            });
48844          });
48845        } else {
48846          alignmentRowYInset = 0;
48847        } // Transient variable -- rewritten on every draw, used for click object selection
48848
48849
48850        this.alignmentsYOffset = alignmentRowYInset;
48851        const alignmentRowHeight = this.displayMode === "SQUISHED" ? this.squishedRowHeight : this.alignmentRowHeight;
48852
48853        if (packedAlignmentRows) {
48854          const nRows = packedAlignmentRows.length;
48855
48856          for (let rowIndex = 0; rowIndex < nRows; rowIndex++) {
48857            const alignmentRow = packedAlignmentRows[rowIndex];
48858            const alignmentY = alignmentRowYInset + alignmentRowHeight * rowIndex;
48859            const alignmentHeight = alignmentRowHeight <= 4 ? al
48859ignmentRowHeight : alignmentRowHeight - 2;
48860
48861            if (alignmentY > pixelBottom) {
48862              break;
48863            } else if (alignmentY + alignmentHeight < pixelTop) {
48864              continue;
48865            }
48866
48867            for (let alignment of alignmentRow.alignments) {
48868              this.hasPairs = this.hasPairs || alignment.isPaired();
48869
48870              if (this.browser.circularView && true === this.browser.circularViewVisible) {
48871                // This is an expensive check, only do it if needed
48872                this.hasSupplemental = this.hasSupplemental || alignment.hasTag('SA');
48873              }
48874
48875              if (alignment.start + alignment.lengthOnRef < bpStart) continue;
48876              if (alignment.start > bpEnd) break;
48877
48878              if (true === alignment.hidden) {
48879                continue;
48880              }
48881
48882              if (alignment instanceof PairedAlignment) {
48883                drawPairConnector.call(this, alignment, alignmentY, alignmentHeight);
48884                drawSingleAlignment.call(this, alignment.firstAlignment, alignmentY, alignmentHeight);
48885
48886                if (alignment.secondAlignment) {
48887                  drawSingleAlignment.call(this, alignment.secondAlignment, alignmentY, alignmentHeight);
48888                }
48889              } else {
48890                drawSingleAlignment.call(this, alignment, alignmentY, alignmentHeight);
48891              }
48892            }
48893          }
48894        }
48895
48896        ctx.restore(); // alignment is a PairedAlignment
48897
48898        function drawPairConnector(alignment, yRect, alignmentHeight) {
48899          var connectorColor = this.getConnectorColor(alignment.firstAlignment),
48900              xBlockStart = (alignment.connectingStart - bpStart) / bpPerPixel,
48901              xBlockEnd = (alignment.connectingEnd - bpStart) / bpPerPixel,
48902              yStrokedLine = yRect + alignmentHeight / 2;
48903
48904          if (alignment.connectingEnd < bpStart || alignment.connectingStart > bpEnd) {
48905            return;
48906          }
48907
48908          if (alignment.mq <= 0) {
48909            connectorColor = IGVColor.addAlpha(connectorColor, 0.15);
48910          }
48911
48912          IGVGraphics.setProperties(ctx, {
48913            fillStyle: connectorColor,
48914            strokeStyle: connectorColor
48915          });
48916          IGVGraphics.strokeLine(ctx, xBlockStart, yStrokedLine, xBlockEnd, yStrokedLine);
48917        }
48918
48919        function drawSingleAlignment(alignment, yRect, alignmentHeight) {
48920          if (alignment.start + alignment.lengthOnRef < bpStart || alignment.start > bpEnd) {
48921            return;
48922          }
48923
48924          const blocks = showSoftClips ? alignment.blocks : alignment.blocks.filter(b => 'S' !== b.type);
48925          let alignmentColor = this.getAlignmentColor(alignment);
48926          const outlineColor = alignmentColor;
48927
48928          if (alignment.mq <= 0) {
48929            alignmentColor = IGVColor.addAlpha(alignmentColor, 0.15);
48930          }
48931
48932          IGVGraphics.setProperties(ctx, {
48933            fillStyle: alignmentColor,
48934            strokeStyle: outlineColor
48935          });
48936
48937          for (let b = 0; b < blocks.length; b++) {
48938            // Can't use forEach here -- we need ability to break
48939            const block = blocks[b]; // Somewhat complex test, neccessary to insure gaps are drawn.
48940            // If this is not the last block, and the next block starts before the orign (off screen to left) then skip.
48941
48942            if (b !== blocks.length - 1 && blocks[b + 1].start < bpStart) continue;
48943            drawBlock.call(this, block, b);
48944
48945            if (block.start + block.len > bpEnd) {
48946              // Do this after drawBlock to insure gaps are drawn
48947              break;
48948            }
48949          }
48950
48951          if (alignment.insertions && this.parent.showInsertions) {
48952            let lastXBlockStart = -1;
48953
48954            for (let insertionBlock of alignment.insertions) {
48955              if (this.hideSmallIndels && insertionBlock.len <= this.indelSizeThreshold) {
48956                continue;
48957              }
48958
48959              if (insertionBlock.start < bpStart) {
48960                continue;
48961              }
48962
48963              if (insertionBlock.start > bpEnd) {
48964                break;
48965              }
48966
48967              const refOffset = insertionBlock.start - bpStart;
48968              const xBlockStart = refOffset / bpPerPixel - 1;
48969
48970              if (xBlockStart - lastXBlockStart > 2) {
48971                const widthBlock = 3;
48972                IGVGraphics.fillRect(ctx, xBlockStart, yRect - 1, widthBlock, alignmentHeight + 2, {
48973                  fillStyle: this.insertionColor
48974                });
48975                lastXBlockStart = xBlockStart;
48976              }
48977            }
48978          }
48979
48980          if (alignment.gaps) {
48981            const yStrokedLine = yRect + alignmentHeight / 2;
48982
48983            for (let gap of alignment.gaps) {
48984              const sPixel = (gap.start - bpStart) / bpPerPixel;
48985              const ePixel = (gap.start + gap.len - bpStart) / bpPerPixel;
48986              const color = "D" === gap.type ? this.deletionColor : this.skippedColor;
48987              IGVGraphics.strokeLine(ctx, sPixel, yStrokedLine, ePixel, yStrokedLine, {
48988                strokeStyle: color
48989              });
48990            }
48991          }
48992
48993          function drawBlock(block, b) {
48994            const offsetBP = block.start - alignmentContainer.start;
48995            const blockStartPixel = (block.start - bpStart) / bpPerPixel;
48996            const blockEndPixel = (block.start + block.len - bpStart) / bpPerPixel;
48997            const blockWidthPixel = Math.max(1, blockEndPixel - blockStartPixel); //const arrowHeadWidthPixel = alignmentRowHeight / 2.0;
48998
48999            const nomPixelWidthOnRef = 100 / bpPerPixel;
49000            const arrowHeadWidthPixel = Math.min(alignmentRowHeight / 2.0, nomPixelWidthOnRef / 6);
49001            const isSoftClip = 'S' === block.type;
49002            const strokeOutline = alignment.mq <= 0 || this.highlightedAlignmentReadNamed === alignment.readName || isSoftClip;
49003            let blockOutlineColor = outlineColor;
49004            if (this.highlightedAlignmentReadNamed === alignment.readName) blockOutlineColor = 'red';else if (isSoftClip) blockOutlineColor = 'rgb(50,50,50)';
49005            const lastBlockPositiveStrand = true === alignment.strand && b === blocks.length - 1;
49006            const lastBlockReverseStrand = false === alignment.strand && b === 0;
49007            const lastBlock = lastBlockPositiveStrand | lastBlockReverseStrand;
49008
49009            if (lastBlock) {
49010              let xListPixel;
49011              let yListPixel;
49012
49013              if (lastBlockPositiveStrand) {
49014                xListPixel = [blockStartPixel, blockEndPixel, blockEndPixel + arrowHeadWidthPixel, blockEndPixel, blockStartPixel, blockStartPixel];
49015                yListPixel = [yRect, yRect, yRect + alignmentHeight / 2.0, yRect + alignmentHeight, yRect + alignmentHeight, yRect];
49016              } // Last block on - strand ?
49017              else if (lastBlockReverseStrand) {
49018                xListPixel = [blockEndPixel, blockStartPixel, blockStartPixel - arrowHeadWidthPixel, blockStartPixel, blockEndPixel, blockEndPixel];
49019                yListPixel = [yRect, yRect, yRect + alignmentHeight / 2.0, yRect + alignmentHeight, yRect + alignmentHeight, yRect];
49020              }
49021
49022              IGVGraphics.fillPolygon(ctx, xListPixel, yListPixel, {
49023                fillStyle: alignmentColor
49024              });
49025
49026              if (strokeOutline) {
49027                IGVGraphics.strokePolygon(ctx, xListPixel, yListPixel, {
49028                  strokeStyle: blockOutlineColor
49029                });
49030              }
49031            } // Internal block
49032            else {
49033              IGVGraphics.fillRect(ctx, blockStartPixel, yRect, blockWidthPixel, alignmentHeight, {
49034                fillStyle: alignmentColor
49035              });
49036
49037              if (strokeOutline) {
49038                ctx.save();
49039                ctx.strokeStyle = blockOutlineColor;
49040                ctx.strokeRect(blockStartPixel, yRect, blockWidthPixel, alignmentHeight);
49041                ctx.restore();
49042              }
49043            } // Read base coloring coloring
49044
49045
49046            if (isSoftClip || showAllBases || this.parent.showMismatches && referenceSequence && alignment.seq && alignment.seq !== "*") {
49047              const seq = alignment.seq ? alignment.seq.toUpperCase() : undefined;
49048              const qual = alignment.qual;
49049              const seqOffset = block.seqOffset;
49050
49051              for (let i = 0, len = block.len; i < len; i++) {
49052                if (offsetBP + i < 0) continue;
49053                let readChar = seq ? seq.charAt(seqOffset + i) : '';
49054                const refChar = referenceSequence.charAt(offsetBP + i);
49055
49056                if (readChar === "=") {
49057                  readChar = refChar;
49058                }
49059
49060                if (readChar === "X" || refChar !== readChar || isSoftClip || showAllBases) {
49061                  let baseColor;
49062
49063                  if (!isSoftClip && qual !== undefined && qual.length > seqOffset + i) {
49064                    const readQual = qual[seqOffset + i];
49065                    baseColor = shadedBaseColor(readQual, nucleotideColors[readChar]);
49066                  } else {
49067                    baseColor = nucleotideColors[readChar];
49068                  }
49069
49070                  if (baseColor) {
49071                    const xPixel = (block.start + i - bpStart) / bpPerPixel;
49072                    const widthPixel = Math.max(1, 1 / bpPerPixel);
49073                    renderBlockOrReadChar(ctx, bpPerPixel, {
49074                      x: xPixel,
49075                      y: yRect,
49076                      width: widthPixel,
49077                      height: alignmentHeight
49078                    }, baseColor, readChar);
49079                  }
49080                }
49081              }
49082            }
49083          }
49084
49085          function renderBlockOrReadChar(context, bpp, bbox, color, char) {
49086            var threshold, center;
49087            threshold = 1.0 / 10.0;
49088
49089            if (bpp <= threshold && bbox.height >= 8) {
49090              // render letter
49091              const fontHeight = Math.min(10, bbox.height);
49092              context.font = '' + fontHeight + 'px sans-serif';
49093              center = bbox.x + bbox.width / 2.0;
49094              IGVGraphics.strokeText(context, char, center - context.measureText(char).width / 2, fontHeight - 1 + bbox.y, {
49095                strokeStyle: color
49096              });
49097            } else {
49098              // render colored block
49099              IGVGraphics.fillRect(context, bbox.x, bbox.y, bbox.width, bbox.height, {
49100                fillStyle: color
49101              });
49102            }
49103          }
49104        }
49105      }
49106
49107      popupData(clickState) {
49108        const clickedObject = this.getClickedObject(clickState);
49109        return clickedObject ? clickedObject.popupData(clickState.genomicLocation) : undefined;
49110      }
49111
49112      contextMenuItemList(clickState) {
49113        const viewport = clickState.viewport;
49114        const list = [];
49115
49116        const sortByOption = option => {
49117          const cs = this.parent.sortObject;
49118          const direction = cs && cs.position === Math.floor(clickState.genomicLocation) ? !cs.direction : true;
49119          const newSortObject = {
49120            chr: viewport.referenceFrame.chr,
49121            position: Math.floor(clickState.genomicLocation),
49122            option: option,
49123            direction: direction
49124          };
49125          this.parent.sortObject = newSortObject;
49126          sortAlignmentRows(newSortObject, viewport.getCachedFeatures());
49127          viewport.repaint();
49128        };
49129
49130        list.push('<b>Sort by...</b>');
49131        list.push({
49132          label: '&nbsp; base',
49133          click: () => sortByOption("BASE")
49134        });
49135        list.push({
49136          label: '&nbsp; read strand',
49137          click: () => sortByOption("STRAND")
49138        });
49139        list.push({
49140          label: '&nbsp; insert size',
49141          click: () => sortByOption("INSERT_SIZE")
49142        });
49143        list.push({
49144          label: '&nbsp; gap size',
49145          click: () => sortByOption("GAP_SIZE")
49146        });
49147        list.push({
49148          label: '&nbsp; chromosome of mate',
49149          click: () => sortByOption("MATE_CHR")
49150        });
49151        list.push({
49152          label: '&nbsp; mapping quality',
49153          click: () => sortByOption("MQ")
49154        });
49155        list.push({
49156          label: '&nbsp; read name',
49157          click: () => sortByOption("READ_NAME")
49158        });
49159        list.push({
49160          label: '&nbsp; tag',
49161          click: () => {
49162            const cs = this.parent.sortObject;
49163            const direction = cs && cs.position === Math.floor(clickState.genomicLocation) ? !cs.direction : true;
49164            const config = {
49165              label: 'Tag Name',
49166              value: this.sortByTag ? this.sortByTag : '',
49167              callback: tag => {
49168                if (tag) {
49169                  const newSortObject = {
49170                    chr: viewport.referenceFrame.chr,
49171                    position: Math.floor(clickState.genomicLocation),
49172                    option: "TAG",
49173                    tag: tag,
49174                    direction: direction
49175                  };
49176                  this.sortByTag = tag;
49177                  this.parent.sortObject = newSortObject;
49178                  sortAlignmentRows(newSortObject, viewport.getCachedFeatures());
49179                  viewport.repaint();
49180                }
49181              }
49182            };
49183            this.browser.inputDialog.present(config, clickState.event);
49184          }
49185        });
49186        list.push('<hr/>');
49187        const clickedObject = this.getClickedObject(clickState);
49188
49189        if (clickedObject) {
49190          const showSoftClips = this.parent.showSoftClips;
49191          const clickedAlignment = typeof clickedObject.alignmentContaining === 'function' ? clickedObject.alignmentContaining(clickState.genomicLocation, showSoftClips) : clickedObject;
49192
49193          if (clickedAlignment.isPaired() && clickedAlignment.isMateMapped()) {
49194            list.push({
49195              label: 'View mate in split screen',
49196              click: () => {
49197                if (clickedAlignment.mate) {
49198                  const referenceFrame = clickState.viewport.referenceFrame;
49199
49200                  if (this.browser.genome.getChromosome(clickedAlignment.mate.chr)) {
49201                    this.highlightedAlignmentReadNamed = clickedAlignment.readName;
49202                    this.browser.presentMultiLocusPanel(clickedAlignment, referenceFrame);
49203                  } else {
49204                    Alert.presentAlert(`Reference does not contain chromosome: ${clickedAlignment.mate.chr}`);
49205                  }
49206                }
49207              },
49208              init: undefined
49209            });
49210          }
49211
49212          list.push({
49213            label: 'View read sequence',
49214            click: () => {
49215              const alignment = clickedAlignment;
49216              if (!alignment) return;
49217              const seqstring = alignment.seq; //.map(b => String.fromCharCode(b)).join("");
49218
49219              if (!seqstring || "*" === seqstring) {
49220                Alert.presentAlert("Read sequence: *");
49221              } else {
49222                Alert.presentAlert(seqstring);
49223              }
49224            }
49225          });
49226
49227          if (isSecureContext()) {
49228            list.push({
49229              label: 'Copy read sequence',
49230              click: () => {
49231                const alignment = clickedAlignment;
49232                if (!alignment) return;
49233                const seqstring = alignment.seq; //.map(b => String.fromCharCode(b)).join("");
49234
49235                navigator.clipboard.writeText(seqstring);
49236              }
49237            });
49238          }
49239
49240          list.push('<hr/>');
49241        } // Experimental JBrowse feature
49242
49243
49244        if (this.browser.circularView && true === this.browser.circularViewVisible && (this.hasPairs || this.hasSupplemental)) {
49245          if (this.hasPairs) {
49246            list.push({
49247              label: 'Add discordant pairs to circular view',
49248              click: () => {
49249                const maxFragmentLength = this.parent.maxFragmentLength;
49250                const {
49251                  referenceFrame
49252                } = viewport;
49253                const inView = viewport.getCachedFeatures().allAlignments().filter(a => {
49254                  return a.end >= referenceFrame.start && a.start <= referenceFrame.end && a.mate && a.mate.chr && (a.mate.chr !== a.chr || Math.max(a.fragmentLength) > maxFragmentLength);
49255                });
49256                this.browser.circularViewVisible = true;
49257                const chords = makePairedAlignmentChords(inView);
49258                const color = IGVColor.addAlpha(this.parent.color || 'rgb(0,0,255)', 0.02);
49259                this.browser.circularView.addChords(chords, {
49260                  track: this.parent.name,
49261                  color: color
49262                });
49263              }
49264            });
49265          }
49266
49267          if (this.hasSupplemental) {
49268            list.push({
49269              label: 'Add split reads to circular view',
49270              click: () => {
49271                const inView = [];
49272
49273                for (let a of viewport.getCachedFeatures().allAlignments()) {
49274                  const referenceFrame = viewport.referenceFrame;
49275                  const sa = a.hasTag('SA');
49276
49277                  if (a.end >= referenceFrame.start && a.start <= referenceFrame.end && sa) {
49278                    inView.push(a);
49279                  }
49280                }
49281
49282                const chords = makeSupplementalAlignmentChords(inView);
49283                const color = IGVColor.addAlpha(this.color || 'rgb(0,0,255)', 0.1);
49284                this.browser.circularView.addChords(chords, {
49285                  track: this.name,
49286                  color: color
49287                });
49288              }
49289            });
49290          }
49291
49292          list.push('<hr/>');
49293        }
49294
49295        return list;
49296      }
49297
49298      getClickedObject(clickState) {
49299        const viewport = clickState.viewport;
49300        const y = clickState.y;
49301        const genomicLocation = clickState.genomicLocation;
49302        const showSoftClips = this.parent.showSoftClips;
49303        let features = viewport.getCachedFeatures();
49304        if (!features || features.length === 0) return;
49305        let packedAlignmentRows = features.packedAlignmentRows;
49306        let downsampledIntervals = features.downsampledIntervals;
49307        const alignmentRowHeight = this.displayMode === "SQUISHED" ? this.squishedRowHeight : this.alignmentRowHeight;
49308        let packedAlignmentsIndex = Math.floor((y - this.top - this.alignmentsYOffset) / alignmentRowHeight);
49309
49310        if (packedAlignmentsIndex < 0) {
49311          for (let i = 0; i < downsampledIntervals.length; i++) {
49312            if (downsampledIntervals[i].start <= genomicLocation && downsampledIntervals[i].end >= genomicLocation) {
49313              return downsampledIntervals[i];
49314            }
49315          }
49316        } else if (packedAlignmentsIndex < packedAlignmentRows.length) {
49317          const alignmentRow = packedAlignmentRows[packedAlignmentsIndex];
49318          const clicked = alignmentRow.alignments.filter(alignment => alignment.containsLocation(genomicLocation, showSoftClips));
49319          if (clicked.length > 0) return clicked[0];
49320        }
49321
49322        return undefined;
49323      }
49324
49325      /**
49326       * Return the color for connectors in paired alignment view.   If explicitly set return that, otherwise return
49327       * the alignment color, unless the color option can result in split colors (separte color for each mate).
49328       *
49329       * @param alignment
49330       * @returns {string}
49331       */
49332      getConnectorColor(alignment) {
49333        if (this.pairConnectorColor) {
49334          return this.pairConnectorColor;
49335        }
49336
49337        switch (this.colorBy) {
49338          case "strand":
49339          case "firstOfPairStrand":
49340          case "pairOrientation":
49341          case "tag":
49342            return this.parent.color || DEFAULT_CONNECTOR_COLOR;
49343
49344          default:
49345            return this.getAlignmentColor(alignment);
49346        }
49347      }
49348
49349      getAlignmentColor(alignment) {
49350        let color = this.parent.color || DEFAULT_ALIGNMENT_COLOR; // The default color if nothing else applies
49351
49352        const option = this.colorBy;
49353
49354        switch (option) {
49355          case "strand":
49356            color = alignment.strand ? this.posStrandColor : this.negStrandColor;
49357            break;
49358
49359          case "firstOfPairStrand":
49360            if (alignment instanceof PairedAlignment) {
49361              color = alignment.firstOfPairStrand() ? this.posStrandColor : this.negStrandColor;
49362            } else if (alignment.isPaired()) {
49363              if (alignment.isFirstOfPair()) {
49364                color = alignment.strand ? this.posStrandColor : this.negStrandColor;
49365              } else if (alignment.isSecondOfPair()) {
49366                color = alignment.strand ? this.negStrandColor : this.posStrandColor;
49367              } else {
49368                console.error("ERROR. Paired alignments are either first or second.");
49369              }
49370            }
49371
49372            break;
49373
49374          case "unexpectedPair":
49375          case "pairOrientation":
49376            if (this.pairOrientation && alignment.pairOrientation) {
49377              var oTypes = orientationTypes[this.pairOrientation];
49378
49379              if (oTypes) {
49380                var pairColor = this.pairColors[oTypes[alignment.pairOrientation]];
49381                if (pairColor) color = pairColor;
49382              }
49383            }
49384
49385            if ("pairOrientation" === option) {
49386              break;
49387            }
49388
49389          case "fragmentLength":
49390            if (alignment.mate && alignment.isMateMapped() && alignment.mate.chr !== alignment.chr) {
49391              color = getChrColor(alignment.mate.chr);
49392            } else if (this.parent.minFragmentLength && Math.abs(alignment.fragmentLength) < this.parent.minFragmentLength) {
49393              color = this.smallFragmentLengthColor;
49394            } else if (this.parent.maxFragmentLength && Math.abs(alignment.fragmentLength) > this.parent.maxFragmentLength) {
49395              color = this.largeFragmentLengthColor;
49396            }
49397
49398            break;
49399
49400          case "tag":
49401            const tagValue = alignment.tags()[this.colorByTag];
49402
49403            if (tagValue !== undefined) {
49404              if (this.bamColorTag === this.colorByTag) {
49405                // UCSC style color option
49406                color = "rgb(" + tagValue + ")";
49407              } else {
49408                if (!this.tagColors) {
49409                  this.tagColors = new PaletteColorTable("Set1");
49410                }
49411
49412                color = this.tagColors.getColor(tagValue);
49413              }
49414            }
49415
49416            break;
49417
49418          default:
49419            color = this.parent.color || DEFAULT_ALIGNMENT_COLOR;
49420        }
49421
49422        return color;
49423      }
49424
49425    }
49426
49427    function sortAlignmentRows(options, alignmentContainer) {
49428      const direction = options.direction;
49429
49430      for (let row of alignmentContainer.packedAlignmentRows) {
49431        row.updateScore(options, alignmentContainer);
49432      }
49433
49434      alignmentContainer.packedAlignmentRows.sort(function (rowA, rowB) {
49435        const i = rowA.score > rowB.score ? 1 : rowA.score < rowB.score ? -1 : 0;
49436        return true === direction ? i : -i;
49437      }); // For debugging
49438      // for(let r of alignmentContainer.packedAlignmentRows) {
49439      //     console.log(r.score);
49440      // }
49441    }
49442
49443    function shadedBaseColor(qual, baseColor) {
49444      const minQ = 5; //prefs.getAsInt(PreferenceManager.SAM_BASE_QUALITY_MIN),
49445
49446      const maxQ = 20; //prefs.getAsInt(PreferenceManager.SAM_BASE_QUALITY_MAX);
49447
49448      let alpha;
49449
49450      if (qual < minQ) {
49451        alpha = 0.1;
49452      } else {
49453        alpha = Math.max(0.1, Math.min(1.0, 0.1 + 0.9 * (qual - minQ) / (maxQ - minQ)));
49454      } // Round alpha to nearest 0.1
49455
49456
49457      alpha = Math.round(alpha * 10) / 10.0;
49458
49459      if (alpha < 1) {
49460        baseColor = IGVColor.addAlpha(baseColor, alpha);
49461      }
49462
49463      return baseColor;
49464    }
49465
49466    const orientationTypes = {
49467      "fr": {
49468        "F1R2": "LR",
49469        "F2R1": "LR",
49470        "F1F2": "LL",
49471        "F2F1": "LL",
49472        "R1R2": "RR",
49473        "R2R1": "RR",
49474        "R1F2": "RL",
49475        "R2F1": "RL"
49476      },
49477      "rf": {
49478        "R1F2": "LR",
49479        "R2F1": "LR",
49480        "R1R2": "LL",
49481        "R2R1": "LL",
49482        "F1F2": "RR",
49483        "F2F1": "RR",
49484        "F1R2": "RL",
49485        "F2R1": "RL"
49486      },
49487      "ff": {
49488        "F2F1": "LR",
49489        "R1R2": "LR",
49490        "F2R1": "LL",
49491        "R1F2": "LL",
49492        "R2F1": "RR",
49493        "F1R2": "RR",
49494        "R2R1": "RL",
49495        "F1F2": "RL"
49496      }
49497    };
49498    function getChrColor(chr) {
49499      if (chrColorMap[chr]) {
49500        return chrColorMap[chr];
49501      } else if (chrColorMap["chr" + chr]) {
49502        const color = chrColorMap["chr" + chr];
49503        chrColorMap[chr] = color;
49504        return color;
49505      } else {
49506        const color = IGVColor.randomRGB();
49507        chrColorMap[chr] = color;
49508        return color;
49509      }
49510    }
49511    const chrColorMap = {
49512      "chrX": "rgb(204, 153, 0)",
49513      "chrY": "rgb(153, 204, 0",
49514      "chrUn": "rgb(50, 50, 50)",
49515      "chr1": "rgb(80, 80, 255)",
49516      "chrI": "rgb(139, 155, 187)",
49517      "chr2": "rgb(206, 61, 50)",
49518      "chrII": "rgb(206, 61, 50)",
49519      "chr2a": "rgb(216, 71, 60)",
49520      "chr2b": "rgb(226, 81, 70)",
49521      "chr3": "rgb(116, 155, 88)",
49522      "chrIII": "rgb(116, 155, 88)",
49523      "chr4": "rgb(240, 230, 133)",
49524      "chrIV": "rgb(240, 230, 133)",
49525      "chr5": "rgb(70, 105, 131)",
49526      "chr6": "rgb(186, 99, 56)",
49527      "chr7": "rgb(93, 177, 221)",
49528      "chr8": "rgb(128, 34, 104)",
49529      "chr9": "rgb(107, 215, 107)",
49530      "chr10": "rgb(213, 149, 167)",
49531      "chr11": "rgb(146, 72, 34)",
49532      "chr12": "rgb(131, 123, 141)",
49533      "chr13": "rgb(199, 81, 39)",
49534      "chr14": "rgb(213, 143, 92)",
49535      "chr15": "rgb(122, 101, 165)",
49536      "chr16": "rgb(228, 175, 105)",
49537      "chr17": "rgb(59, 27, 83)",
49538      "chr18": "rgb(205, 222, 183)",
49539      "chr19": "rgb(97, 42, 121)",
49540      "chr20": "rgb(174, 31, 99)",
49541      "chr21": "rgb(231, 199, 111)",
49542      "chr22": "rgb(90, 101, 94)",
49543      "chr23": "rgb(204, 153, 0)",
49544      "chr24": "rgb(153, 204, 0)",
49545      "chr25": "rgb(51, 204, 0)",
49546      "chr26": "rgb(0, 204, 51)",
49547      "chr27": "rgb(0, 204, 153)",
49548      "chr28": "rgb(0, 153, 204)",
49549      "chr29": "rgb(10, 71, 255)",
49550      "chr30": "rgb(71, 117, 255)",
49551      "chr31": "rgb(255, 194, 10)",
49552      "chr32": "rgb(255, 209, 71)",
49553      "chr33": "rgb(153, 0, 51)",
49554      "chr34": "rgb(153, 26, 0)",
49555      "chr35": "rgb(153, 102, 0)",
49556      "chr36": "rgb(128, 153, 0)",
49557      "chr37": "rgb(51, 153, 0)",
49558      "chr38": "rgb(0, 153, 26)",
49559      "chr39": "rgb(0, 153, 102)",
49560      "chr40": "rgb(0, 128, 153)",
49561      "chr41": "rgb(0, 51, 153)",
49562      "chr42": "rgb(26, 0, 153)",
49563      "chr43": "rgb(102, 0, 153)",
49564      "chr44": "rgb(153, 0, 128)",
49565      "chr45": "rgb(214, 0, 71)",
49566      "chr46": "rgb(255, 20, 99)",
49567      "chr47": "rgb(0, 214, 143)",
49568      "chr48": "rgb(20, 255, 177)"
49569    };
49570
49571    let timer;
49572    let currentViewport = undefined;
49573    const toolTipTimeout = 1e4;
49574
49575    class RulerViewport extends TrackViewport {
49576      constructor(trackView, $viewportColumn, referenceFrame, width) {
49577        super(trackView, $viewportColumn, referenceFrame, width);
49578      }
49579
49580      initializationHelper() {
49581        this.rulerSweeper = new RulerSweeper(this);
49582        this.$multiLocusCloseButton = $$1('<div>', {
49583          class: 'igv-multi-locus-close-button'
49584        });
49585        this.$viewport.append(this.$multiLocusCloseButton);
49586        this.$multiLocusCloseButton.get(0).appendChild(createIcon$1("times-circle"));
49587        this.$multiLocusCloseButton.click(() => {
49588          this.browser.removeMultiLocusPanel(this.referenceFrame);
49589        });
49590        this.$rulerLabel = $$1('<div>', {
49591          class: 'igv-multi-locus-ruler-label'
49592        });
49593        this.$viewport.append(this.$rulerLabel);
49594        this.$rulerLabel.click(async () => {
49595          await this.browser.selectMultiLocusPanel(this.referenceFrame); // const removals = this.browser.referenceFrameList.filter(r => this.referenceFrame !== r)
49596          // for (let referenceFrame of removals) {
49597          //     await this.browser.removeMultiLocusPanel(referenceFrame)
49598          // }
49599        });
49600        this.$tooltip = $$1('<div>', {
49601          class: 'igv-ruler-tooltip'
49602        });
49603        this.$tooltip.height(this.$viewport.height());
49604        this.$viewport.append(this.$tooltip);
49605        this.$tooltipContent = $$1('<div>');
49606        this.$tooltip.append(this.$tooltipContent);
49607        this.attachMouseHandlers(GenomeUtils.isWholeGenomeView(this.referenceFrame.chr));
49608        this.$tooltip.hide();
49609        this.dismissLocusLabel();
49610      }
49611
49612      presentLocusLabel(viewportWidth) {
49613        const createRulerLabelString = () => {
49614          const html = `<div>${this.referenceFrame.getMultiLocusLabel(viewportWidth)}</div>`;
49615          return document.createRange().createContextualFragment(html).firstChild;
49616        };
49617
49618        this.$rulerLabel.get(0).innerHTML = '';
49619        this.$rulerLabel.get(0).style.backgroundColor = getChrColor(this.referenceFrame.chr);
49620        this.$rulerLabel.get(0).appendChild(createRulerLabelString());
49621        this.$rulerLabel.show();
49622        this.$multiLocusCloseButton.show();
49623      } // Use in conjuction with .igv-multi-locus-ruler-label-square-dot css class (_dom-misc.scss)
49624
49625
49626      presentLocusLabel_Square_Dot(viewportWidth) {
49627
49628        const createRulerLabelDot = () => {
49629          const html = `<div>
49630                                <?xml version="1.0" encoding="UTF-8"?>
49631                                <svg width="14px" height="14px" viewBox="0 0 89 89" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
49632                                    <g>
49633                                        <circle id="Oval" fill="${getChrColor(this.referenceFrame.chr)}" cx="44.5" cy="44.5" r="44.5"></circle>
49634                                    </g>
49635                                </svg>
49636                            </div>`;
49637          return document.createRange().createContextualFragment(html).firstChild;
49638        };
49639
49640        const createRulerLabelString = () => {
49641          const html = `<div>${this.referenceFrame.getMultiLocusLabel(viewportWidth)}</div>`;
49642          return document.createRange().createContextualFragment(html).firstChild;
49643        };
49644
49645        this.$rulerLabel.get(0).innerHTML = '';
49646        this.$rulerLabel.get(0).appendChild(createRulerLabelDot());
49647        this.$rulerLabel.get(0).appendChild(createRulerLabelString());
49648        this.$rulerLabel.show();
49649        this.$multiLocusCloseButton.show();
49650      }
49651
49652      dismissLocusLabel() {
49653        this.$rulerLabel.hide();
49654        this.$multiLocusCloseButton.hide();
49655      }
49656
49657      attachMouseHandlers(isWholeGenomeView) {
49658        this.namespace = `.ruler_track_viewport_${this.browser.referenceFrameList.indexOf(this.referenceFrame)}`;
49659        this.$viewport.off(this.namespace); // console.log(`Ruler track ${ true === isWholeGenomeView ? 'is' : 'is not' } whole genome.`)
49660
49661        if (true === isWholeGenomeView) {
49662          const index = this.browser.referenceFrameList.indexOf(this.referenceFrame);
49663          const click = `click${this.namespace}`;
49664          this.$viewport.on(click, e => {
49665            const {
49666              x: pixel
49667            } = translateMouseCoordinates$1(e, this.$viewport.get(0));
49668            const bp = Math.round(this.referenceFrame.start + this.referenceFrame.toBP(pixel));
49669            let searchString;
49670            const {
49671              chr
49672            } = this.browser.genome.getChromosomeCoordinate(bp);
49673
49674            if (1 === this.browser.referenceFrameList.length) {
49675              searchString = chr;
49676            } else {
49677              let loci = this.browser.referenceFrameList.map(_ref => {
49678                let {
49679                  locusSearchString
49680                } = _ref;
49681                return locusSearchString;
49682              });
49683              loci[index] = chr;
49684              searchString = loci.join(' ');
49685            }
49686
49687            this.browser.search(searchString);
49688          });
49689          this.$viewport.get(0).style.cursor = 'pointer';
49690        } else {
49691          this.$viewport.get(0).style.cursor = 'default';
49692        }
49693      }
49694
49695      mouseMove(event) {
49696        if (true === this.browser.cursorGuideVisible) {
49697          if (undefined === currentViewport) {
49698            currentViewport = this;
49699            this.$tooltip.show();
49700          } else if (currentViewport.guid !== this.guid) {
49701            currentViewport.$tooltip.hide();
49702            this.$tooltip.show();
49703            currentViewport = this;
49704          } else {
49705            this.$tooltip.show();
49706          }
49707
49708          const isWholeGenome = this.browser.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(this.referenceFrame.chr);
49709
49710          if (isWholeGenome) {
49711            this.$tooltip.hide();
49712            return;
49713          }
49714
49715          const {
49716            x
49717          } = translateMouseCoordinates$1(event, this.$viewport.get(0));
49718          const {
49719            start,
49720            bpPerPixel
49721          } = this.referenceFrame;
49722          const bp = Math.round(0.5 + start + Math.max(0, x) * bpPerPixel);
49723          this.$tooltipContent.text(numberFormatter$1(bp));
49724          const {
49725            width: ww
49726          } = this.$tooltipContent.get(0).getBoundingClientRect();
49727          const {
49728            width: w
49729          } = this.$viewport.get(0).getBoundingClientRect();
49730          this.$tooltip.css({
49731            left: `${IGVMath.clamp(x, 0, w - ww)}px`
49732          }); // hide tooltip when movement stops
49733
49734          clearTimeout(timer);
49735          timer = setTimeout(() => this.$tooltip.hide(), toolTipTimeout);
49736        }
49737      }
49738
49739      startSpinner() {}
49740
49741      stopSpinner() {}
49742
49743      dispose() {
49744        this.rulerSweeper.dispose();
49745        super.dispose();
49746      }
49747
49748    }
49749
49750    /*
49751     * The MIT License (MIT)
49752     *
49753     * Copyright (c) 2014 Broad Institute
49754     *
49755     * Permission is hereby granted, free of charge, to any person obtaining a copy
49756     * of this software and associated documentation files (the "Software"), to deal
49757     * in the Software without restriction, including without limitation the rights
49758     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
49759     * copies of the Software, and to permit persons to whom the Software is
49760     * furnished to do so, subject to the following conditions:
49761     *
49762     * The above copyright notice and this permission notice shall be included in
49763     * all copies or substantial portions of the Software.
49764     *
49765     *
49766     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49767     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49768     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49769     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49770     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49771     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
49772     * THE SOFTWARE.
49773     */
49774
49775    class IdeogramViewport extends TrackViewport {
49776      constructor(trackView, viewportColumn, referenceFrame, width) {
49777        super(trackView, viewportColumn, referenceFrame, width);
49778      }
49779
49780      initializationHelper() {
49781        this.$ideogramCanvas = $$1('<canvas>', {
49782          class: 'igv-ideogram-canvas'
49783        });
49784        this.$ideogramCanvas.insertBefore(this.$canvas);
49785        const canvas = this.$ideogramCanvas.get(0);
49786        this.ideogram_ctx = canvas.getContext('2d');
49787        this.$canvas.remove();
49788        this.canvas = undefined;
49789        this.ctx = undefined;
49790        this.addMouseHandlers();
49791      }
49792
49793      addMouseHandlers() {
49794        this.addViewportClickHandler(this.$viewport.get(0));
49795      }
49796
49797      removeMouseHandlers() {
49798        this.removeViewportClickHandler(this.$viewport.get(0));
49799      }
49800
49801      addViewportClickHandler(viewport) {
49802        this.boundClickHandler = clickHandler.bind(this);
49803        viewport.addEventListener('click', this.boundClickHandler);
49804
49805        function clickHandler(event) {
49806          const {
49807            xNormalized,
49808            width
49809          } = translateMouseCoordinates$1(event, this.ideogram_ctx.canvas);
49810          const {
49811            bpLength
49812          } = this.browser.genome.getChromosome(this.referenceFrame.chr);
49813          const locusLength = this.referenceFrame.bpPerPixel * width;
49814          const chrCoveragePercentage = locusLength / bpLength;
49815          let xPercentage = xNormalized;
49816
49817          if (xPercentage - chrCoveragePercentage / 2.0 < 0) {
49818            xPercentage = chrCoveragePercentage / 2.0;
49819          }
49820
49821          if (xPercentage + chrCoveragePercentage / 2.0 > 1.0) {
49822            xPercentage = 1.0 - chrCoveragePercentage / 2.0;
49823          }
49824
49825          const ss = Math.round((xPercentage - chrCoveragePercentage / 2.0) * bpLength);
49826          const ee = Math.round((xPercentage + chrCoveragePercentage / 2.0) * bpLength);
49827          this.referenceFrame.start = ss;
49828          this.referenceFrame.end = ee;
49829          this.referenceFrame.bpPerPixel = (ee - ss) / width;
49830          this.browser.updateViews(this.referenceFrame, this.browser.trackViews, true);
49831        }
49832      }
49833
49834      removeViewportClickHandler(viewport) {
49835        viewport.removeEventListener('click', this.boundClickHandler);
49836      }
49837
49838      setWidth(width) {
49839        this.$viewport.width(width);
49840      }
49841
49842      drawSVGWithContext(context, width, height, id, x, y, yClipOffset) {
49843        context.saveWithTranslationAndClipRect(id, x, y, width, height, yClipOffset);
49844        this.trackView.track.draw({
49845          context,
49846          referenceFrame: this.referenceFrame,
49847          pixelWidth: width,
49848          pixelHeight: height
49849        });
49850        context.restore();
49851      }
49852
49853      async repaint() {
49854        this.draw({
49855          referenceFrame: this.referenceFrame
49856        });
49857      }
49858
49859      draw(_ref) {
49860        let {
49861          referenceFrame
49862        } = _ref;
49863        this.$canvas.hide();
49864        IGVGraphics.configureHighDPICanvas(this.ideogram_ctx, this.$viewport.width(), this.$viewport.height());
49865        this.trackView.track.draw({
49866          context: this.ideogram_ctx,
49867          referenceFrame,
49868          pixelWidth: this.$viewport.width(),
49869          pixelHeight: this.$viewport.height()
49870        });
49871      }
49872
49873      startSpinner() {}
49874
49875      stopSpinner() {}
49876
49877    }
49878
49879    /*
49880     * The MIT License (MIT)
49881     *
49882     * Copyright (c) 2014 Broad Institute
49883     *
49884     * Permission is hereby granted, free of charge, to any person obtaining a copy
49885     * of this software and associated documentation files (the "Software"), to deal
49886     * in the Software without restriction, including without limitation the rights
49887     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
49888     * copies of the Software, and to permit persons to whom the Software is
49889     * furnished to do so, subject to the following conditions:
49890     *
49891     * The above copyright notice and this permission notice shall be included in
49892     * all copies or substantial portions of the Software.
49893     *
49894     *
49895     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49896     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49897     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49898     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49899     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49900     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
49901     * THE SOFTWARE.
49902     */
49903    /**
49904     * Test if the given value is a string or number.  Not using typeof as it fails on boxed primitives.
49905     *
49906     * @param value
49907     * @returns boolean
49908     */
49909
49910
49911    function isSimpleType(value) {
49912      const simpleTypes = new Set(["boolean", "number", "string", "symbol"]);
49913      const valueType = typeof value;
49914      return value !== undefined && (simpleTypes.has(valueType) || value.substring || value.toFixed);
49915    }
49916
49917    function buildOptions(config, options) {
49918      var defaultOptions = {
49919        oauthToken: config.oauthToken,
49920        headers: config.headers,
49921        withCredentials: config.withCredentials,
49922        filename: config.filename
49923      };
49924      return Object.assign(defaultOptions, options);
49925    }
49926    /**
49927     * isMobile test from http://detectmobilebrowsers.com
49928     * TODO -- improve UI design so this isn't neccessary
49929     * @returns {boolean}
49930     */
49931    // igv.isMobile = function () {
49932    //
49933    //     const a = (navigator.userAgent || navigator.vendor || window.opera);
49934    //     return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) ||
49935    //         /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
49935sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4)))
49936    //
49937    // }
49938
49939
49940    const doAutoscale = function (features) {
49941      var min, max;
49942
49943      if (features.length > 0) {
49944        min = Number.MAX_VALUE;
49945        max = -Number.MAX_VALUE;
49946        features.forEach(function (f) {
49947          if (!Number.isNaN(f.value)) {
49948            min = Math.min(min, f.value);
49949            max = Math.max(max, f.value);
49950          }
49951        }); // Insure we have a zero baseline
49952
49953        if (max > 0) min = Math.min(0, min);
49954        if (max < 0) max = 0;
49955      } else {
49956        // No features -- default
49957        min = 0;
49958        max = 100;
49959      }
49960
49961      return {
49962        min: min,
49963        max: max
49964      };
49965    };
49966
49967    const validateLocusExtent = function (chromosomeLengthBP, extent, minimumBP) {
49968      let ss = extent.start;
49969      let ee = extent.end;
49970
49971      if (undefined === ee) {
49972        ss -= minimumBP / 2;
49973        ee = ss + minimumBP;
49974
49975        if (ee > chromosomeLengthBP) {
49976          ee = chromosomeLengthBP;
49977          ss = ee - minimumBP;
49978        } else if (ss < 0) {
49979          ss = 0;
49980          ee = minimumBP;
49981        }
49982      } else if (ee - ss < minimumBP) {
49983        const center = (ee + ss) / 2;
49984
49985        if (center - minimumBP / 2 < 0) {
49986          ss = 0;
49987          ee = ss + minimumBP;
49988        } else if (center + minimumBP / 2 > chromosomeLengthBP) {
49989          ee = chromosomeLengthBP;
49990          ss = ee - minimumBP;
49991        } else {
49992          ss = center - minimumBP / 2;
49993          ee = ss + minimumBP;
49994        }
49995      }
49996
49997      extent.start = Math.ceil(ss);
49998      extent.end = Math.floor(ee);
49999    };
50000    /*!
50001     * is-number <https://github.com/jonschlinkert/is-number>
50002     *
50003     * Copyright (c) 2014-present, Jon Schlinkert.
50004     * Released under the MIT License.
50005     */
50006
50007
50008    const isNumber = function (num) {
50009      if (typeof num === 'number') {
50010        return num - num === 0;
50011      }
50012
50013      if (typeof num === 'string' && num.trim() !== '') {
50014        return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
50015      }
50016
50017      return false;
50018    };
50019
50020    async function getFilename(url) {
50021      if (isString$3(url) && url.startsWith("https://drive.google.com")) {
50022        // This will fail if Google API key is not defined
50023        if (getApiKey() === undefined) {
50024          throw Error("Google drive is referenced, but API key is not defined.  An API key is required for Google Drive access");
50025        }
50026
50027        const json = await getDriveFileInfo(url);
50028        return json.originalFileName || json.name;
50029      } else {
50030        return getFilename$1(url);
50031      }
50032    }
50033
50034    function prettyBasePairNumber(raw) {
50035      var denom, units, value, floored;
50036
50037      if (raw > 1e7) {
50038        denom = 1e6;
50039        units = " mb";
50040      } else if (raw > 1e4) {
50041        denom = 1e3;
50042        units = " kb";
50043        value = raw / denom;
50044        floored = Math.floor(value);
50045        return numberFormatter$1(floored) + units;
50046      } else {
50047        return numberFormatter$1(raw) + " bp";
50048      }
50049
50050      value = raw / denom;
50051      floored = Math.floor(value);
50052      return floored.toString() + units;
50053    }
50054
50055    function isDataURL(obj) {
50056      return isString$3(obj) && obj.startsWith("data:");
50057    }
50058
50059    function createColumn(columnContainer, className) {
50060      const column = div$1({
50061        class: className
50062      });
50063      columnContainer.appendChild(column);
50064    }
50065
50066    function insertElementBefore(element, referenceNode) {
50067      referenceNode.parentNode.insertBefore(element, referenceNode);
50068    }
50069
50070    function insertElementAfter(element, referenceNode) {
50071      referenceNode.parentNode.insertBefore(element, referenceNode.nextSibling);
50072    }
50073
50074    function createViewport(trackView, column, referenceFrame, width) {
50075      if ('ruler' === trackView.track.type) {
50076        return new RulerViewport(trackView, column, referenceFrame, width);
50077      } else if ('ideogram' === trackView.track.type) {
50078        return new IdeogramViewport(trackView, column, referenceFrame, width);
50079      } else {
50080        return new TrackViewport(trackView, column, referenceFrame, width);
50081      }
50082    }
50083    /**
50084     * Test to see if page is loaded in a secure context, that is by https or is localhost.
50085     */
50086
50087
50088    function isSecureContext() {
50089      return window.location.protocol === "https:" || window.location.hostname === "localhost";
50090    }
50091
50092    const maxFontSize = 10;
50093    const fontConfigureTemplate = {
50094      // font: '2pt sans-serif',
50095      textAlign: 'start',
50096      textBaseline: 'bottom',
50097      strokeStyle: 'black',
50098      fillStyle: 'black'
50099    };
50100
50101    class SampleNameViewport {
50102      constructor(trackView, column, unused, width) {
50103        this.guid = guid$1();
50104        this.trackView = trackView;
50105        this.browser = trackView.browser;
50106        this.viewport = div$1({
50107          class: 'igv-viewport'
50108        });
50109        column.appendChild(this.viewport);
50110
50111        if (trackView.track.height) {
50112          this.viewport.style.height = `${trackView.track.height}px`;
50113        }
50114
50115        this.canvas = document.createElement('canvas');
50116        this.viewport.appendChild(this.canvas);
50117        this.ctx = this.canvas.getContext("2d");
50118        this.trackScrollDelta = 0;
50119        this.contentTop = 0;
50120        this.setWidth(width);
50121
50122        if (false === this.browser.showSampleNames) {
50123          this.hide();
50124        }
50125
50126        this.addMouseHandlers();
50127      }
50128
50129      checkCanvas() {
50130        const dpi = window.devicePixelRatio;
50131        const requiredHeight = this.viewport.clientHeight;
50132        const requiredWidth = this.browser.sampleNameViewportWidth;
50133
50134        if (this.canvas.width !== requiredWidth * dpi || this.canvas.height !== requiredHeight * dpi) {
50135          const canvas = this.canvas;
50136          canvas.width = requiredWidth * dpi;
50137          canvas.height = requiredHeight * dpi;
50138          canvas.style.width = `${requiredWidth}px`;
50139          canvas.style.height = `${requiredHeight}px`;
50140          this.ctx = this.canvas.getContext("2d");
50141          this.ctx.scale(dpi, dpi);
50142        }
50143      }
50144
50145      setTop(contentTop) {
50146        if (typeof this.trackView.track.getSamples === 'function') {
50147          this.contentTop = contentTop;
50148          const samples = this.trackView.track.getSamples();
50149          this.repaint(samples);
50150        }
50151      }
50152
50153      setWidth(width) {
50154        this.viewport.innerWidth = width;
50155        this.checkCanvas();
50156      }
50157
50158      show() {
50159        this.viewport.style.display = 'block';
50160      }
50161
50162      hide() {
50163        this.viewport.style.display = 'none';
50164      }
50165
50166      async repaint(samples) {
50167        this.checkCanvas();
50168        this.draw({
50169          context: this.ctx,
50170          samples
50171        });
50172      }
50173
50174      draw(_ref) {
50175        let {
50176          context,
50177          samples
50178        } = _ref;
50179
50180        if (!samples || samples.names.length === 0
50181        /* || samples.height < 1*/
50182        ) {
50183          return;
50184        }
50185
50186        configureFont(context, fontConfigureTemplate, samples.height);
50187        const sampleNameXShim = 4;
50188        context.clearRect(0, 0, context.canvas.width, context.canvas.height);
50189        context.fillStyle = appleCrayonRGB('lead');
50190        const viewportHeight = this.viewport.getBoundingClientRect().height;
50191        let y = (samples.yOffset || 0) + this.contentTop; // contentTop will always be a negative number (top relative to viewport)
50192
50193        for (let name of samples.names) {
50194          if (y > viewportHeight) {
50195            break;
50196          }
50197
50198          if (y + samples.height > 0) {
50199            const text = name;
50200            const yFont = getYFont(context, text, y, samples.height);
50201            context.fillText(text, sampleNameXShim, yFont);
50202          }
50203
50204          y += samples.height;
50205        }
50206      }
50207
50208      renderSVGContext(context, _ref2) {
50209        let {
50210          deltaX,
50211          deltaY
50212        } = _ref2;
50213
50214        if (typeof this.trackView.track.getSamples === 'function') {
50215          const samples = this.trackView.track.getSamples();
50216          const yScrollDelta = 0; // This is not relevant, scrolling is handled in "draw"
50217
50218          const {
50219            width,
50220            height
50221          } = this.viewport.getBoundingClientRect();
50222          const str = (this.trackView.track.name || this.trackView.track.id).replace(/\W/g, '');
50223          const id = `${str}_sample_names_guid_${guid$1()}`;
50224          context.saveWithTranslationAndClipRect(id, deltaX, deltaY + yScrollDelta, width, height, -yScrollDelta);
50225          this.draw({
50226            context,
50227            samples
50228          });
50229          context.restore();
50230        }
50231      }
50232
50233      addMouseHandlers() {
50234        this.addViewportContextMenuHandler(this.viewport);
50235      }
50236
50237      removeMouseHandlers() {
50238        this.removeViewportContextMenuHandler(this.viewport);
50239      }
50240
50241      addViewportContextMenuHandler(viewport) {
50242        this.boundContextMenuHandler = contextMenuHandler.bind(this);
50243        viewport.addEventListener('contextmenu', this.boundContextMenuHandler);
50244
50245        function contextMenuHandler(event) {
50246          event.preventDefault();
50247          event.stopPropagation();
50248          const config = {
50249            label: 'Name Panel Width',
50250            value: this.browser.sampleNameViewportWidth,
50251            callback: newWidth => {
50252              this.browser.sampleNameViewportWidth = parseInt(newWidth);
50253
50254              for (let {
50255                sampleNameViewport
50256              } of this.browser.trackViews) {
50257                sampleNameViewport.setWidth(this.browser.sampleNameViewportWidth);
50258              }
50259
50260              this.browser.resize();
50261            }
50262          };
50263          this.browser.inputDialog.present(config, event);
50264        }
50265      }
50266
50267      removeViewportContextMenuHandler(viewport) {
50268        viewport.removeEventListener('contextmenu', this.boundContextMenuHandler);
50269      }
50270
50271      dispose() {
50272        this.removeMouseHandlers();
50273        this.viewport.remove();
50274      }
50275
50276    }
50277
50278    function getYFont(context, text, y, height) {
50279      return y + height - getSampleNameYShim(context, text, height);
50280    }
50281
50282    function getSampleNameYShim(context, text, h) {
50283      const {
50284        actualBoundingBoxAscent,
50285        actualBoundingBoxDescent
50286      } = context.measureText(text);
50287      return (h - (actualBoundingBoxAscent + actualBoundingBoxDescent)) / 2;
50288    }
50289
50290    function configureFont(ctx, _ref3, sampleHeight) {
50291      let {
50292        textAlign,
50293        textBaseline,
50294        strokeStyle,
50295        fillStyle
50296      } = _ref3;
50297      const pixels = Math.min(sampleHeight, maxFontSize);
50298      ctx.font = `${pixels}px sans-serif`;
50299      ctx.textAlign = textAlign;
50300      ctx.textBaseline = textBaseline;
50301      ctx.fillStyle = fillStyle;
50302    }
50303
50304    class GenericColorPicker extends GenericContainer {
50305      constructor(_ref) {
50306        let {
50307          parent,
50308          width
50309        } = _ref;
50310        super({
50311          parent,
50312          width,
50313          border: '1px solid gray'
50314        });
50315      }
50316
50317      configure(defaultColors, colorHandlers) {
50318        this.colorHandlers = colorHandlers; // active color handler defaults to handler with 'color' as key
50319
50320        this.setActiveColorHandler('color');
50321        this.createSwatches(defaultColors);
50322      }
50323
50324      setActiveColorHandler(option) {
50325        this.activeColorHandler = this.colorHandlers[option];
50326      }
50327
50328      createSwatches(defaultColors) {
50329        this.container.querySelectorAll('.igv-ui-color-swatch').forEach(swatch => swatch.remove());
50330        const hexColorStrings = Object.values(appleCrayonPalette$1);
50331
50332        for (let hexColorString of hexColorStrings) {
50333          const swatch = div$1({
50334            class: 'igv-ui-color-swatch'
50335          });
50336          this.container.appendChild(swatch);
50337          this.decorateSwatch(swatch, hexColorString);
50338        }
50339
50340        if (defaultColors) {
50341          for (let hexColorString of defaultColors) {
50342            const swatch = div$1({
50343              class: 'igv-ui-color-swatch'
50344            });
50345            this.container.appendChild(swatch);
50346            this.decorateSwatch(swatch, hexColorString);
50347          }
50348        }
50349      }
50350
50351      decorateSwatch(swatch, hexColorString) {
50352        swatch.style.backgroundColor = hexColorString;
50353        swatch.addEventListener('mouseenter', () => swatch.style.borderColor = hexColorString);
50354        swatch.addEventListener('mouseleave', () => swatch.style.borderColor = 'white');
50355        swatch.addEventListener('click', event => {
50356          event.stopPropagation();
50357          this.activeColorHandler(hexColorString);
50358        });
50359        swatch.addEventListener('touchend', event => {
50360          event.stopPropagation();
50361          this.activeColorHandler(hexColorString);
50362        });
50363      }
50364
50365    }
50366
50367    /*
50368     * The MIT License (MIT)
50369     *
50370     * Copyright (c) 2014 Broad Institute
50371     *
50372     * Permission is hereby granted, free of charge, to any person obtaining a copy
50373     * of this software and associated documentation files (the "Software"), to deal
50374     * in the Software without restriction, including without limitation the rights
50375     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
50376     * copies of the Software, and to permit persons to whom the Software is
50377     * furnished to do so, subject to the following conditions:
50378     *
50379     * The above copyright notice and this permission notice shall be included in
50380     * all copies or substantial portions of the Software.
50381     *
50382     *
50383     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50384     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50385     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
50386     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50387     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50388     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
50389     * THE SOFTWARE.
50390     */
50391
50392    const MenuPopup = function (parent) {
50393      this.popover = div$1({
50394        class: 'igv-menu-popup'
50395      });
50396      parent.appendChild(this.popover);
50397      const header = div$1({
50398        class: 'igv-menu-popup-header'
50399      });
50400      this.popover.appendChild(header);
50401      attachDialogCloseHandlerWithParent$1(header, () => this.hide());
50402      this.popoverContent = div$1();
50403      this.popover.appendChild(this.popoverContent);
50404      makeDraggable$1(this.popover, header);
50405      header.addEventListener('click', e => {
50406        e.stopPropagation();
50407        e.preventDefault(); // absorb click to prevent it leaking through to parent DOM element
50408      });
50409      this.hide();
50410    };
50411
50412    MenuPopup.prototype.hide = function () {
50413      this.popover.style.display = 'none';
50414    };
50415
50416    MenuPopup.prototype.presentMenuList = function (menuList) {
50417      hideAllMenuPopups();
50418
50419      if (menuList.length > 0) {
50420        this.popoverContent.innerHTML = '';
50421        menuList = MenuUtils.trackMenuItemListHelper(menuList, this);
50422
50423        for (let item of menuList) {
50424          if (item.init) {
50425            item.init();
50426          }
50427
50428          let $e = item.object;
50429
50430          if (0 === menuList.indexOf(item)) {
50431            $e.removeClass('igv-track-menu-border-top');
50432          }
50433
50434          if ($e.hasClass('igv-track-menu-border-top') || $e.hasClass('igv-menu-popup-check-container')) ; else if ($e.is('div')) {
50435            $e.addClass('igv-menu-popup-shim');
50436          }
50437
50438          this.popoverContent.appendChild($e.get(0));
50439        } // NOTE: style.display most NOT be 'none' when calculating width. a display = 'none' will always
50440        //       yield a width of zero (0).
50441
50442
50443        this.popover.style.display = 'flex';
50444        const {
50445          width
50446        } = this.popover.getBoundingClientRect();
50447        this.popover.style.left = `${-width}px`;
50448        this.popover.style.top = `${0}px`;
50449      }
50450    };
50451
50452    MenuPopup.prototype.presentTrackContextMenu = function (e, menuItems) {
50453      this.popoverContent.innerHTML = '';
50454      const menuElements = createMenuElements(menuItems, this.popover);
50455
50456      for (let {
50457        el
50458      } of menuElements) {
50459        this.popoverContent.appendChild(el);
50460      }
50461
50462      present(e, this.popover);
50463    };
50464
50465    MenuPopup.prototype.dispose = function () {
50466      this.popoverContent.innerHTML = '';
50467      this.popover.innerHTML = '';
50468      Object.keys(this).forEach(function (key) {
50469        this[key] = undefined;
50470      });
50471    };
50472
50473    function createMenuElements(itemList, popover) {
50474      return itemList.map(item => {
50475        let el;
50476
50477        if (typeof item === 'string' && '<hr/>' === item) {
50478          el = document.createElement('hr');
50479        } else if (typeof item === 'string') {
50480          el = div$1({
50481            class: 'context-menu'
50482          });
50483          el.innerHTML = item;
50484        } else if (typeof item === 'Node') {
50485          el = item;
50486        } else {
50487          if (typeof item.init === 'function') {
50488            item.init();
50489          }
50490
50491          if ("checkbox" === item.type) {
50492            el = createCheckbox$1("Show all bases", item.value);
50493          } else if ("color" === item.type) {
50494            const colorPicker = new GenericColorPicker({
50495              parent: popover.parentElement,
50496              width: 364
50497            });
50498            colorPicker.configure(undefined, {
50499              color: color => item.click(color)
50500            });
50501            el = div$1({
50502              class: 'context-menu'
50503            });
50504
50505            if (typeof item.label === 'string') {
50506              el.innerHTML = item.label;
50507            }
50508
50509            const clickHandler = e => {
50510              colorPicker.show();
50511              hide$1(popover);
50512              e.preventDefault();
50513              e.stopPropagation();
50514            };
50515
50516            el.addEventListener('click', clickHandler);
50517            el.addEventListener('touchend', clickHandler);
50518            el.addEventListener('mouseup', function (e) {
50519              e.preventDefault();
50520              e.stopPropagation();
50521            });
50522          } else {
50523            el = div$1({
50524              class: 'context-menu'
50525            });
50526
50527            if (typeof item.label === 'string') {
50528              el.innerHTML = item.label;
50529            }
50530          }
50531
50532          if (item.click && "color" !== item.type) {
50533            el.addEventListener('click', handleClick);
50534            el.addEventListener('touchend', handleClick);
50535            el.addEventListener('mouseup', function (e) {
50536              e.preventDefault();
50537              e.stopPropagation();
50538            }); // eslint-disable-next-line no-inner-declarations
50539
50540            function handleClick(e) {
50541              item.click();
50542              hide$1(popover);
50543              e.preventDefault();
50544              e.stopPropagation();
50545            }
50546          }
50547        }
50548
50549        return {
50550          el,
50551          init: item.init
50552        };
50553      });
50554    }
50555
50556    function present(e, popover) {
50557      // NOTE: style.display most NOT be 'none' when calculating width. a display = 'none' will always
50558      //       yield a width of zero (0).
50559      popover.style.display = 'flex';
50560      const {
50561        x,
50562        y
50563      } = translateMouseCoordinates$1(e, popover.parentNode);
50564      const {
50565        width
50566      } = popover.getBoundingClientRect();
50567      const xmax = x + width;
50568      const {
50569        width: parentWidth
50570      } = popover.parentNode.getBoundingClientRect();
50571      popover.style.left = `${xmax > parentWidth ? x - (xmax - parentWidth) : x}px`;
50572      popover.style.top = `${y}px`;
50573    }
50574
50575    const hideAllMenuPopups = () => {
50576      const menus = document.querySelectorAll('.igv-menu-popup');
50577
50578      for (let i = 0; i < menus.length; i++) {
50579        menus[i].style.display = 'none';
50580      }
50581    };
50582
50583    /*
50584     * The MIT License (MIT)
50585     *
50586     * Copyright (c) 2014 Broad Institute
50587     *
50588     * Permission is hereby granted, free of charge, to any person obtaining a copy
50589     * of this software and associated documentation files (the "Software"), to deal
50590     * in the Software without restriction, including without limitation the rights
50591     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
50592     * copies of the Software, and to permit persons to whom the Software is
50593     * furnished to do so, subject to the following conditions:
50594     *
50595     * The above copyright notice and this permission notice shall be included in
50596     * all copies or substantial portions of the Software.
50597     *
50598     *
50599     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50600     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50601     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
50602     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50603     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50604     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
50605     * THE SOFTWARE.
50606     */
50607    const scrollbarExclusionTypes = new Set(['ruler', 'sequence', 'ideogram']);
50608    const colorPickerExclusionTypes = new Set(['ruler', 'sequence', 'ideogram']);
50609
50610    class TrackView {
50611      constructor(browser, columnContainer, track) {
50612        this.namespace = `trackview-${guid$1()}`;
50613        this.browser = browser;
50614        this.track = track;
50615        track.trackView = this;
50616        this.addDOMToColumnContainer(browser, columnContainer, browser.referenceFrameList);
50617      }
50618      /**
50619       * Start a spinner for the track on any of its viewports.  In practice this is called during initialization
50620       * when there is only one.
50621       */
50622
50623
50624      startSpinner() {
50625        if (this.viewports && this.viewports.length > 0) {
50626          this.viewports[0].startSpinner();
50627        }
50628      }
50629
50630      stopSpinner() {
50631        if (this.viewports && this.viewports.length > 0) {
50632          this.viewports[0].stopSpinner();
50633        }
50634      }
50635
50636      addDOMToColumnContainer(browser, columnContainer, referenceFrameList) {
50637        // Axis
50638        this.axis = this.createAxis(browser, this.track); // Track Viewports
50639
50640        this.viewports = [];
50641        const viewportWidth = browser.calculateViewportWidth(referenceFrameList.length);
50642        const viewportColumns = columnContainer.querySelectorAll('.igv-column');
50643
50644        for (let i = 0; i < viewportColumns.length; i++) {
50645          const viewport = createViewport(this, viewportColumns[i], referenceFrameList[i], viewportWidth);
50646          this.viewports.push(viewport);
50647        } // SampleName Viewport
50648
50649
50650        this.sampleNameViewport = new SampleNameViewport(this, browser.columnContainer.querySelector('.igv-sample-name-column'), undefined, browser.sampleNameViewportWidth); // Track Scrollbar
50651
50652        this.createTrackScrollbar(browser); // Track Drag
50653
50654        this.createTrackDragHandle(browser); // Track Gear
50655
50656        this.createTrackGearPopup(browser);
50657      }
50658
50659      createAxis(browser, track) {
50660        const axis = div$1();
50661        browser.columnContainer.querySelector('.igv-axis-column').appendChild(axis);
50662        axis.style.height = `${track.height}px`;
50663
50664        if (typeof track.paintAxis === 'function') {
50665          if (track.dataRange) {
50666            axis.addEventListener('click', () => {
50667              browser.dataRangeDialog.configure(this);
50668              browser.dataRangeDialog.present($$1(browser.columnContainer));
50669            });
50670          }
50671
50672          const {
50673            width,
50674            height
50675          } = axis.getBoundingClientRect();
50676          this.axisCanvas = document.createElement('canvas');
50677          this.axisCanvas.style.width = `${width}px`;
50678          this.axisCanvas.style.height = `${height}px`;
50679          axis.appendChild(this.axisCanvas);
50680        }
50681
50682        return axis;
50683      }
50684
50685      resizeAxisCanvas(width, height) {
50686        this.axis.style.width = `${width}px`;
50687        this.axis.style.height = `${height}px`;
50688
50689        if (typeof this.track.paintAxis === 'function') {
50690          // Size the canvas in CSS (logical) pixels.  The buffer size will be set when painted.
50691          this.axisCanvas.style.width = `${width}px`;
50692          this.axisCanvas.style.height = `${height}px`;
50693        }
50694      }
50695
50696      removeDOMFromColumnContainer() {
50697        // Axis
50698        if (this.boundAxisClickHander) {
50699          this.removeAxisEventListener(this.axis);
50700        }
50701
50702        this.axis.remove(); // Track Viewports
50703
50704        for (let viewport of this.viewports) {
50705          viewport.removeMouseHandlers();
50706          viewport.$viewport.remove();
50707        } // SampleName Viewport
50708
50709
50710        this.sampleNameViewport.dispose(); // empty trackScrollbar Column
50711
50712        this.removeTrackScrollMouseHandlers();
50713        this.outerScroll.remove(); // empty trackDrag Column
50714
50715        this.removeTrackDragMouseHandlers();
50716        this.dragHandle.remove(); // empty trackGear Column
50717
50718        this.removeTrackGearMouseHandlers();
50719        this.gearContainer.remove();
50720      }
50721
50722      renderSVGContext(context, _ref) {
50723        let {
50724          deltaX,
50725          deltaY
50726        } = _ref;
50727        renderSVGAxis(context, this.track, this.axisCanvas, deltaX, deltaY);
50728        const {
50729          width: axisWidth
50730        } = this.axis.getBoundingClientRect();
50731        const {
50732          y
50733        } = this.viewports[0].$viewport.get(0).getBoundingClientRect();
50734        let delta = {
50735          deltaX: axisWidth + deltaX,
50736          deltaY: y + deltaY
50737        };
50738
50739        for (let viewport of this.viewports) {
50740          viewport.renderSVGContext(context, delta);
50741          const {
50742            width
50743          } = viewport.$viewport.get(0).getBoundingClientRect();
50744          delta.deltaX += width;
50745        }
50746
50747        if (true === this.browser.showSampleNames) {
50748          this.sampleNameViewport.renderSVGContext(context, delta);
50749        }
50750      }
50751
50752      dataRange() {
50753        return this.track.dataRange ? this.track.dataRange : undefined;
50754      }
50755
50756      setDataRange(min, max) {
50757        if (min !== undefined) {
50758          this.track.dataRange.min = min;
50759        }
50760
50761        if (max !== undefined) {
50762          this.track.dataRange.max = max;
50763        }
50764
50765        this.track.autoscale = false;
50766        this.repaintViews();
50767      }
50768
50769      presentColorPicker(key) {
50770        if (false === colorPickerExclusionTypes.has(this.track.type)) {
50771          const trackColors = [];
50772          const color = this.track.color || this.track.defaultColor;
50773
50774          if (isString$3(color)) {
50775            trackColors.push(color);
50776          }
50777
50778          if (this.track.altColor && isString$3(this.track.altColor)) {
50779            trackColors.push(this.track.altColor);
50780          }
50781
50782          const defaultColors = trackColors.map(c => c.startsWith("#") ? c : c.startsWith("rgb(") ? IGVColor.rgbToHex(c) : IGVColor.colorNameToHex(c));
50783          const colorHandlers = {
50784            color: color => {
50785              this.track.color = color;
50786              this.repaintViews();
50787            },
50788            altColor: color => {
50789              this.track.altColor = color;
50790              this.repaintViews();
50791            }
50792          };
50793          this.browser.genericColorPicker.configure(defaultColors, colorHandlers);
50794          this.browser.genericColorPicker.setActiveColorHandler(key);
50795          this.browser.genericColorPicker.show();
50796        }
50797      }
50798
50799      setTrackHeight(newHeight, force) {
50800        if (!force) {
50801          if (this.track.minHeight) {
50802            newHeight = Math.max(this.track.minHeight, newHeight);
50803          }
50804
50805          if (this.track.maxHeight) {
50806            newHeight = Math.min(this.track.maxHeight, newHeight);
50807          }
50808        }
50809
50810        this.track.height = newHeight;
50811        this.resizeAxisCanvas(this.axis.clientWidth, this.track.height);
50812
50813        if (typeof this.track.paintAxis === 'function') {
50814          this.paintAxis();
50815        }
50816
50817        for (let {
50818          $viewport
50819        } of this.viewports) {
50820          $viewport.height(newHeight);
50821        }
50822
50823        this.sampleNameViewport.viewport.style.height = `${newHeight}px`; // If the track does not manage its own content height set it here
50824
50825        if (typeof this.track.computePixelHeight !== "function") {
50826          for (let vp of this.viewports) {
50827            vp.setContentHeight(newHeight);
50828          }
50829        }
50830
50831        this.repaintViews();
50832
50833        if (false === scrollbarExclusionTypes.has(this.track.type)) {
50834          this.updateScrollbar();
50835        }
50836
50837        this.dragHandle.style.height = `${newHeight}px`;
50838        this.gearContainer.style.height = `${newHeight}px`;
50839      }
50840
50841      updateScrollbar() {
50842        const viewportHeight = this.viewports[0].$viewport.height();
50843        this.outerScroll.style.height = `${viewportHeight}px`;
50844        const viewportContentHeight = maxViewportContentHeight(this.viewports);
50845        const innerScrollHeight = Math.round(viewportHeight / viewportContentHeight * viewportHeight);
50846
50847        if (viewportContentHeight > viewportHeight) {
50848          this.innerScroll.style.display = 'block';
50849          this.innerScroll.style.height = `${innerScrollHeight}px`;
50850        } else {
50851          this.innerScroll.style.display = 'none';
50852        }
50853      }
50854
50855      moveScroller(delta) {
50856        const y = $$1(this.innerScroll).position().top + delta;
50857        const top = Math.min(Math.max(0, y), this.outerScroll.clientHeight - this.innerScroll.clientHeight);
50858        $$1(this.innerScroll).css('top', `${top}px`);
50859        const contentHeight = maxViewportContentHeight(this.viewports);
50860        const contentTop = -Math.round(top * (contentHeight / this.viewports[0].$viewport.height()));
50861
50862        for (let viewport of this.viewports) {
50863          viewport.setTop(contentTop);
50864        }
50865
50866        this.sampleNameViewport.trackScrollDelta = delta;
50867        this.sampleNameViewport.setTop(contentTop);
50868      }
50869
50870      isLoading() {
50871        for (let viewport of this.viewports) {
50872          if (viewport.isLoading()) return true;
50873        }
50874      }
50875
50876      resize(viewportWidth) {
50877        for (let viewport of this.viewports) {
50878          viewport.setWidth(viewportWidth);
50879        }
50880
50881        this.updateViews(true);
50882      }
50883      /**
50884       * Repaint all viewports without loading any new data.   Use this for events that change visual aspect of data,
50885       * e.g. color, sort order, etc, but do not change the genomic state.
50886       */
50887
50888
50889      repaintViews() {
50890        for (let viewport of this.viewports) {
50891          viewport.repaint();
50892        }
50893
50894        if (typeof this.track.paintAxis === 'function') {
50895          this.paintAxis();
50896        } // Repaint sample names last
50897
50898
50899        this.repaintSamples();
50900      }
50901
50902      repaintSamples() {
50903        if (typeof this.track.getSamples === 'function') {
50904          const samples = this.track.getSamples();
50905          this.sampleNameViewport.repaint(samples);
50906        }
50907      } // track labels
50908
50909
50910      setTrackLabelName(name) {
50911        this.viewports.forEach(viewport => viewport.setTrackLabel(name));
50912      }
50913      /**
50914       * Update viewports to reflect current genomic state, possibly loading additional data.
50915       */
50916
50917
50918      async updateViews(force) {
50919        if (!(this.browser && this.browser.referenceFrameList)) return;
50920        const visibleViewports = this.viewports.filter(viewport => viewport.isVisible()); // Shift viewports left/right to current genomic state (pans canvas)
50921
50922        visibleViewports.forEach(viewport => viewport.shift());
50923        const isDragging = this.browser.dragObject;
50924
50925        if (isDragging) {
50926          return;
50927        } // rpv: viewports whose image (canvas) does not fully cover current genomic range
50928
50929
50930        const reloadableViewports = this.viewportsToReload(force); // Trigger viewport to load features needed to cover current genomic range
50931        // NOTE: these must be loaded synchronously, do not user Promise.all,  not all file readers are thread safe
50932
50933        for (let viewport of reloadableViewports) {
50934          await viewport.loadFeatures();
50935        } // Very special case for variant tracks in multilocus view.  The # of rows to allocate to the variant (site)
50936        // section depends on data from all the views.  We only need to adjust this however if any data was loaded
50937        // (i.e. reloadableViewports.length > 0)
50938
50939
50940        if (typeof this.track.variantRowCount === 'function' && reloadableViewports.length > 0) {
50941          let maxRow = 0;
50942
50943          for (let viewport of this.viewports) {
50944            if (viewport.tile && viewport.tile.features) {
50945              maxRow = Math.max(maxRow, viewport.tile.features.reduce((a, f) => Math.max(a, f.row || 0), 0));
50946            }
50947          }
50948
50949          const current = this.track.nVariantRows;
50950
50951          if (current !== maxRow + 1) {
50952            this.track.variantRowCount(maxRow + 1);
50953
50954            for (let viewport of this.viewports) {
50955              viewport.checkContentHeight();
50956            }
50957          }
50958        }
50959
50960        if (this.disposed) return; // Track was removed during load
50961
50962        if (this.track.autoscale) {
50963          let allFeatures = [];
50964
50965          for (let visibleViewport of visibleViewports) {
50966            const referenceFrame = visibleViewport.referenceFrame;
50967            const start = referenceFrame.start;
50968            const end = start + referenceFrame.toBP($$1(visibleViewport.contentDiv).width());
50969
50970            if (visibleViewport.tile && visibleViewport.tile.features) {
50971              if (typeof visibleViewport.tile.features.getMax === 'function') {
50972                const max = visibleViewport.tile.features.getMax(start, end);
50973                allFeatures.push({
50974                  value: max
50975                });
50976              } else {
50977                allFeatures = allFeatures.concat(FeatureUtils.findOverlapping(visibleViewport.tile.features, start, end));
50978              }
50979            }
50980          }
50981
50982          if (typeof this.track.doAutoscale === 'function') {
50983            this.track.dataRange = this.track.doAutoscale(allFeatures);
50984          } else {
50985            this.track.dataRange = doAutoscale(allFeatures);
50986          }
50987        } // Must repaint all viewports if autoscaling
50988
50989
50990        if (!isDragging && (this.track.autoscale || this.track.autoscaleGroup)) {
50991          for (let visibleViewport of visibleViewports) {
50992            visibleViewport.repaint();
50993          }
50994        } else {
50995          for (let vp of reloadableViewports) {
50996            vp.repaint();
50997          }
50998        }
50999
51000        this.adjustTrackHeight(); // Repaint sample names last
51001
51002        this.repaintSamples();
51003        this.updateRulerViewportLabels();
51004      }
51005
51006      updateRulerViewportLabels() {
51007        const viewportWidth = this.browser.calculateViewportWidth(this.viewports.length);
51008
51009        for (let viewport of this.viewports) {
51010          if ('ruler' === this.track.type) {
51011            if (this.viewports.length > 1) {
51012              viewport.presentLocusLabel(viewportWidth);
51013            } else {
51014              viewport.dismissLocusLabel();
51015            }
51016          }
51017        }
51018      }
51019      /**
51020       * Return a promise to get all in-view features.  Used for group autoscaling.
51021       */
51022
51023
51024      async getInViewFeatures(force) {
51025        if (!(this.browser && this.browser.referenceFrameList)) {
51026          return [];
51027        } // List of viewports that need reloading
51028
51029
51030        const rpV = this.viewportsToReload(force);
51031        const promises = rpV.map(function (vp) {
51032          return vp.loadFeatures();
51033        });
51034        await Promise.all(promises);
51035        let allFeatures = [];
51036
51037        for (let vp of this.viewports) {
51038          if (vp.tile && vp.tile.features) {
51039            const referenceFrame = vp.referenceFrame;
51040            const start = referenceFrame.start;
51041            const end = start + referenceFrame.toBP($$1(vp.contentDiv).width());
51042
51043            if (typeof vp.tile.features.getMax === 'function') {
51044              const max = vp.tile.features.getMax(start, end);
51045              allFeatures.push({
51046                value: max
51047              });
51048            } else {
51049              allFeatures = allFeatures.concat(FeatureUtils.findOverlapping(vp.tile.features, start, end));
51050            }
51051          }
51052        }
51053
51054        return allFeatures;
51055      }
51056
51057      checkContentHeight() {
51058        for (let viewport of this.viewports) {
51059          viewport.checkContentHeight();
51060        }
51061
51062        this.adjustTrackHeight();
51063      }
51064
51065      adjustTrackHeight() {
51066        var maxHeight = maxViewportContentHeight(this.viewports);
51067
51068        if (this.track.autoHeight) {
51069          this.setTrackHeight(maxHeight, false);
51070        } else if (this.track.paintAxis) {
51071          // Avoid duplication, paintAxis is already called in setTrackHeight
51072          this.paintAxis();
51073        }
51074
51075        if (false === scrollbarExclusionTypes.has(this.track.type)) {
51076          const currentTop = this.viewports[0].getContentTop();
51077          const heights = this.viewports.map(viewport => viewport.getContentHeight());
51078          const minContentHeight = Math.min(...heights);
51079          const newTop = Math.min(0, this.viewports[0].$viewport.height() - minContentHeight);
51080
51081          if (currentTop < newTop) {
51082            for (let viewport of this.viewports) {
51083              viewport.$content.css('top', `${newTop}px`);
51084            }
51085          }
51086
51087          this.updateScrollbar();
51088        }
51089      }
51090
51091      viewportsToReload(force) {
51092        // List of viewports that need reloading
51093        const viewports = this.viewports.filter(viewport => {
51094          if (!viewport.isVisible()) {
51095            return false;
51096          }
51097
51098          if (!viewport.checkZoomIn()) {
51099            return false;
51100          } else {
51101            const referenceFrame = viewport.referenceFrame;
51102            const chr = viewport.referenceFrame.chr;
51103            const start = referenceFrame.start;
51104            const end = start + referenceFrame.toBP($$1(viewport.contentDiv).width());
51105            const bpPerPixel = referenceFrame.bpPerPixel;
51106            return force || !viewport.tile || viewport.tile.invalidate || !viewport.tile.containsRange(chr, start, end, bpPerPixel);
51107          }
51108        });
51109        return viewports;
51110      }
51111
51112      createTrackScrollbar(browser) {
51113        const outerScroll = div$1();
51114        browser.columnContainer.querySelector('.igv-scrollbar-column').appendChild(outerScroll);
51115        outerScroll.style.height = `${this.track.height}px`;
51116        this.outerScroll = outerScroll;
51117
51118        if (false === scrollbarExclusionTypes.has(this.track.type)) {
51119          const innerScroll = div$1();
51120          outerScroll.appendChild(innerScroll);
51121          this.innerScroll = innerScroll;
51122          this.addTrackScrollMouseHandlers(browser);
51123        }
51124      }
51125
51126      createTrackDragHandle(browser) {
51127        const className = 'ideogram' === this.track.type || 'ruler' === this.track.type ? 'igv-track-drag-shim' : 'igv-track-drag-handle';
51128        this.dragHandle = div$1({
51129          class: className
51130        });
51131        browser.columnContainer.querySelector('.igv-track-drag-column').appendChild(this.dragHandle);
51132        this.dragHandle.style.height = `${this.track.height}px`;
51133        this.addTrackDragMouseHandlers(browser);
51134      }
51135
51136      createTrackGearPopup(browser) {
51137        this.gearContainer = div$1();
51138        browser.columnContainer.querySelector('.igv-gear-menu-column').appendChild(this.gearContainer);
51139        this.gearContainer.style.height = `${this.track.height}px`;
51140
51141        if (true === this.track.ignoreTrackMenu) ; else {
51142          this.gear = div$1();
51143          this.gearContainer.appendChild(this.gear);
51144          this.gear.appendChild(createIcon$1('cog'));
51145          this.trackGearPopup = new MenuPopup(this.gear);
51146          this.addTrackGearMouseHandlers();
51147        }
51148      }
51149
51150      addAxisEventListener(axis) {
51151        this.boundAxisClickHander = axisClickHandler.bind(this);
51152        axis.addEventListener('click', this.boundAxisClickHander);
51153
51154        function axisClickHandler(event) {
51155          this.browser.dataRangeDialog.configure(this);
51156          this.browser.dataRangeDialog.present($$1(this.browser.columnContainer));
51157        }
51158      }
51159
51160      removeAxisEventListener(axis) {
51161        axis.removeEventListener('click', this.boundAxisClickHander);
51162      }
51163
51164      addTrackScrollMouseHandlers(browser) {
51165        // Mouse Down
51166        this.boundTrackScrollMouseDownHandler = trackScrollMouseDownHandler.bind(this);
51167        this.innerScroll.addEventListener('mousedown', this.boundTrackScrollMouseDownHandler);
51168
51169        function trackScrollMouseDownHandler(event) {
51170          event.stopPropagation();
51171          const {
51172            y
51173          } = pageCoordinates$1(event);
51174          $$1(this.innerScroll).data('yDown', y.toString());
51175          this.boundColumnContainerMouseMoveHandler = columnContainerMouseMoveHandler.bind(this);
51176          browser.columnContainer.addEventListener('mousemove', this.boundColumnContainerMouseMoveHandler);
51177
51178          function columnContainerMouseMoveHandler(event) {
51179            event.stopPropagation();
51180            const {
51181              y
51182            } = pageCoordinates$1(event);
51183            this.moveScroller(y - parseInt($$1(this.innerScroll).data('yDown')));
51184            $$1(this.innerScroll).data('yDown', y.toString());
51185          }
51186        }
51187
51188        this.boundColumnContainerMouseUpHandler = columnContainerMouseUpHandler.bind(this);
51189        browser.columnContainer.addEventListener('mouseup', this.boundColumnContainerMouseUpHandler);
51190
51191        function columnContainerMouseUpHandler(event) {
51192          browser.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler);
51193        }
51194      }
51195
51196      removeTrackScrollMouseHandlers() {
51197        if (false === scrollbarExclusionTypes.has(this.track.type)) {
51198          this.innerScroll.removeEventListener('mousedown', this.boundTrackScrollMouseDownHandler);
51199          this.browser.columnContainer.removeEventListener('mouseup', this.boundColumnContainerMouseUpHandler);
51200          this.browser.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler);
51201        }
51202      }
51203
51204      addTrackDragMouseHandlers(browser) {
51205        if ('ideogram' === this.track.type || 'ruler' === this.track.type) ; else {
51206          let currentDragHandle = undefined; // Mouse Down
51207
51208          this.boundTrackDragMouseDownHandler = trackDragMouseDownHandler.bind(this);
51209          this.dragHandle.addEventListener('mousedown', this.boundTrackDragMouseDownHandler);
51210
51211          function trackDragMouseDownHandler(event) {
51212            event.preventDefault();
51213            currentDragHandle = event.target;
51214            currentDragHandle.classList.add('igv-track-drag-handle-hover');
51215            browser.startTrackDrag(this);
51216          } // Mouse Up
51217
51218
51219          this.boundDocumentTrackDragMouseUpHandler = documentTrackDragMouseUpHandler.bind(this);
51220          document.addEventListener('mouseup', this.boundDocumentTrackDragMouseUpHandler);
51221
51222          function documentTrackDragMouseUpHandler(event) {
51223            // console.log(`${ Date.now() } TrackView - documentTrackDragMouseUpHandler - target ${ event.target.nodeName }`)
51224            browser.endTrackDrag();
51225
51226            if (currentDragHandle && event.target !== currentDragHandle) {
51227              currentDragHandle.classList.remove('igv-track-drag-handle-hover');
51228            }
51229
51230            currentDragHandle = undefined;
51231          } // Mouse Enter
51232
51233
51234          this.boundTrackDragMouseEnterHandler = trackDragMouseEnterHandler.bind(this);
51235          this.dragHandle.addEventListener('mouseenter', this.boundTrackDragMouseEnterHandler);
51236
51237          function trackDragMouseEnterHandler(event) {
51238            event.preventDefault();
51239
51240            if (undefined === currentDragHandle) {
51241              event.target.classList.add('igv-track-drag-handle-hover');
51242            }
51243
51244            browser.updateTrackDrag(this);
51245          } // Mouse Out
51246
51247
51248          this.dragHandle.addEventListener('mouseout', e => {
51249            e.preventDefault();
51250
51251            if (undefined === currentDragHandle) {
51252              e.target.classList.remove('igv-track-drag-handle-hover');
51253            }
51254          });
51255          this.boundTrackDragMouseOutHandler = trackDragMouseOutHandler.bind(this);
51256          this.dragHandle.addEventListener('mouseout', this.boundTrackDragMouseOutHandler);
51257
51258          function trackDragMouseOutHandler(event) {
51259            event.preventDefault();
51260
51261            if (undefined === currentDragHandle) {
51262              event.target.classList.remove('igv-track-drag-handle-hover');
51263            }
51264          }
51265        }
51266      }
51267
51268      removeTrackDragMouseHandlers() {
51269        if ('ideogram' === this.track.type || 'ruler' === this.track.type) ; else {
51270          this.dragHandle.removeEventListener('mousedown', this.boundTrackDragMouseDownHandler);
51271          document.removeEventListener('mouseup', this.boundDocumentTrackDragMouseUpHandler);
51272          this.dragHandle.removeEventListener('mouseup', this.boundTrackDragMouseEnterHandler);
51273          this.dragHandle.removeEventListener('mouseout', this.boundTrackDragMouseOutHandler);
51274        }
51275      }
51276
51277      addTrackGearMouseHandlers() {
51278        if (true === this.track.ignoreTrackMenu) ; else {
51279          this.boundTrackGearClickHandler = trackGearClickHandler.bind(this);
51280          this.gear.addEventListener('click', this.boundTrackGearClickHandler);
51281
51282          function trackGearClickHandler(event) {
51283            event.preventDefault();
51284            event.stopPropagation();
51285            this.trackGearPopup.presentMenuList(MenuUtils.trackMenuItemList(this));
51286          }
51287        }
51288      }
51289
51290      removeTrackGearMouseHandlers() {
51291        if (true === this.track.ignoreTrackMenu) ; else {
51292          this.gear.removeEventListener('click', this.boundTrackGearClickHandler);
51293        }
51294      }
51295      /**
51296       * Do any cleanup here
51297       */
51298
51299
51300      dispose() {
51301        this.removeAxisEventListener(this.axis);
51302        this.axis.remove();
51303
51304        for (let viewport of this.viewports) {
51305          viewport.dispose();
51306        }
51307
51308        this.sampleNameViewport.dispose();
51309        this.removeTrackScrollMouseHandlers();
51310        this.outerScroll.remove();
51311        this.removeTrackDragMouseHandlers();
51312        this.dragHandle.remove();
51313        this.removeTrackGearMouseHandlers();
51314        this.gearContainer.remove();
51315
51316        if (typeof this.track.dispose === "function") {
51317          this.track.dispose();
51318        } // TODO: Perhaps better done in track/trackBase
51319
51320
51321        const track = this.track;
51322
51323        if (typeof track.dispose === 'function') {
51324          track.dispose();
51325        }
51326
51327        for (let key of Object.keys(track)) {
51328          track[key] = undefined;
51329        }
51330
51331        for (let key of Object.keys(this)) {
51332          this[key] = undefined;
51333        }
51334
51335        if (this.alert) {
51336          this.alert.container.remove(); // This is quite obviously a hack, need a "dispose" method on AlertDialog
51337        }
51338
51339        this.disposed = true;
51340      }
51341
51342      paintAxis() {
51343        if (typeof this.track.paintAxis === 'function') {
51344          // Set the canvas buffer size, this is the resolution it is drawn at.  This is done here in case the browser
51345          // has been drug between screens at different dpi resolutions since the last repaint
51346          const {
51347            width,
51348            height
51349          } = this.axisCanvas.getBoundingClientRect();
51350          const dpi = window.devicePixelRatio || 1;
51351          this.axisCanvas.height = dpi * height;
51352          this.axisCanvas.width = dpi * width; // Get a scaled context to draw aon
51353
51354          const axisCanvasContext = this.axisCanvas.getContext('2d');
51355          axisCanvasContext.scale(dpi, dpi);
51356          this.track.paintAxis(axisCanvasContext, width, height);
51357        }
51358      }
51359
51360    }
51361
51362    function renderSVGAxis(context, track, axisCanvas, deltaX, deltaY) {
51363      if (typeof track.paintAxis === 'function') {
51364        const {
51365          y,
51366          width,
51367          height
51368        } = axisCanvas.getBoundingClientRect();
51369        const str = (track.name || track.id).replace(/\W/g, '');
51370        const id = `${str}_axis_guid_${guid$1()}`;
51371        context.saveWithTranslationAndClipRect(id, deltaX, y + deltaY, width, height, 0);
51372        track.paintAxis(context, width, height);
51373        context.restore();
51374      }
51375    } // css - $igv-axis-column-width: 50px;
51376
51377
51378    const igv_axis_column_width = 50;
51379
51380    function maxViewportContentHeight(viewports) {
51381      const heights = viewports.map(viewport => viewport.getContentHeight());
51382      return Math.max(...heights);
51383    }
51384
51385    /**
51386     * Decoder for bedpe records.
51387     *
51388     * Bedpe format was created by Aaron Quinlan et al as part of the bedtools project.
51389     * The spec is here:  https://bedtools.readthedocs.io/en/latest/content/general-usage.html,  however there
51390     * are off spec variants, an important one being a 7 column format with score in place of the standard
51391     * name column.
51392     *
51393     * Another common variant is a "hiccups" output file, which is standard bedpe with the exception of a header line
51394     * of the form
51395     * chr1    x1    x2    chr2    y1    y2    name    score    strand1    strand2    color    observed    expectedBL    expectedDonut    expectedH    expectedV    fdrBL    fdrDonut    fdrH    fdrV
51396     *
51397     * @param tokens
51398     * @param ignore
51399     * @returns {{start1: number, end2: number, end1: number, chr1: *, chr2: *, start2: number}|undefined}
51400     */
51401
51402    function decodeBedpe(tokens, header) {
51403      if (tokens.length < 6) {
51404        console.log("Skipping line: " + tokens.join(' '));
51405        return undefined;
51406      }
51407
51408      var feature = {
51409        chr1: tokens[0],
51410        start1: Number.parseInt(tokens[1]),
51411        end1: Number.parseInt(tokens[2]),
51412        chr2: tokens[3],
51413        start2: Number.parseInt(tokens[4]),
51414        end2: Number.parseInt(tokens[5])
51415      };
51416
51417      if (isNaN(feature.start1) || isNaN(feature.end1) || isNaN(feature.start2) || isNaN(feature.end2)) {
51418        //throw Error(`Error parsing line: ${tokens.join('\t')}`);
51419        return undefined;
51420      }
51421
51422      if (tokens.length > 6 && tokens[6] !== ".") {
51423        feature.name = tokens[6];
51424      }
51425
51426      if (tokens.length > 7 && tokens[7] !== ".") {
51427        feature.score = Number(tokens[7]);
51428      }
51429
51430      if (tokens.length > 8 && tokens[8] !== ".") {
51431        feature.strand1 = tokens[8];
51432      }
51433
51434      if (tokens.length > 9 && tokens[9] !== ".") {
51435        feature.strand2 = tokens[9];
51436      } // Optional extra columns
51437
51438
51439      if (header) {
51440        const colorColumn = header.colorColumn;
51441
51442        if (colorColumn && colorColumn < tokens.length) {
51443          feature.color = IGVColor.createColorString(tokens[colorColumn]);
51444        }
51445
51446        const thicknessColumn = header.thicknessColumn;
51447
51448        if (thicknessColumn && thicknessColumn < tokens.length) {
51449          feature.thickness = tokens[thicknessColumn];
51450        }
51451
51452        if (tokens.length > 10 && header.columnNames && header.columnNames.length === tokens.length) {
51453          feature.extras = tokens.slice(10);
51454        }
51455      } // Set total extent of feature
51456
51457
51458      if (feature.chr1 === feature.chr2) {
51459        feature.chr = feature.chr1;
51460        feature.start = Math.min(feature.start1, feature.start2);
51461        feature.end = Math.max(feature.end1, feature.end2);
51462      }
51463
51464      return feature;
51465    }
51466    /**
51467     * Hack for non-standard bedPE formats, where numeric score can be in column 7 (name field from spec)
51468     * @param features
51469     */
51470
51471
51472    function fixBedPE(features) {
51473      if (features.length == 0) return; // Assume all features have same properties
51474
51475      const firstFeature = features[0];
51476
51477      if (firstFeature.score === undefined && firstFeature.name !== undefined) {
51478        // Name field (col 7) is sometimes used for score.
51479        for (let f of features) {
51480          if (!(isNumber(f.name) || f.name === '.')) return;
51481        }
51482
51483        for (let f of features) {
51484          f.score = Number(f.name);
51485          delete f.name;
51486        }
51487      } // Make copies of inter-chr features, one for each chromosome
51488
51489
51490      const interChrFeatures = features.filter(f => f.chr1 !== f.chr2);
51491
51492      for (let f1 of interChrFeatures) {
51493        const f2 = Object.assign({}, f1);
51494        f2.dup = true;
51495        features.push(f2);
51496        f1.chr = f1.chr1;
51497        f1.start = f1.start1;
51498        f1.end = f1.end1;
51499        f2.chr = f2.chr2;
51500        f2.start = f2.start2;
51501        f2.end = f2.end2;
51502      }
51503    }
51504    /**
51505     * Special decoder for Hic Domain files.   In these files feature1 == feature2, they are really bed records.
51506     * @param tokens
51507     * @param ignore
51508     * @returns {*}
51509     */
51510
51511
51512    function decodeBedpeDomain(tokens, header) {
51513      if (tokens.length < 8) return undefined;
51514      return {
51515        chr: tokens[0],
51516        start: Number.parseInt(tokens[1]),
51517        end: Number.parseInt(tokens[2]),
51518        color: IGVColor.createColorString(tokens[6]),
51519        value: Number(tokens[7])
51520      };
51521    }
51522
51523    /**
51524     * Decode UCSC "interact" files.  See https://genome.ucsc.edu/goldenpath/help/interact.html
51525     *
51526     0  string chrom;        "Chromosome (or contig, scaffold, etc.). For interchromosomal, use 2 records"
51527     1  uint chromStart;     "Start position of lower region. For interchromosomal, set to chromStart of this region"
51528     2  uint chromEnd;       "End position of upper region. For interchromosomal, set to chromEnd of this region"
51529     3  string name;         "Name of item, for display.  Usually 'sourceName/targetName/exp' or empty"
51530     4  uint score;          "Score (0-1000)"
51531     5  double value;        "Strength of interaction or other data value. Typically basis for score"
51532     6  string exp;          "Experiment name (metadata for filtering). Use . if not applicable"
51533     7  string color;        "Item color.  Specified as r,g,b or hexadecimal #RRGGBB or html color name, as in //www.w3.org/TR/css3-color/#html4. Use 0 and spectrum setting to shade by score"
51534     8  string sourceChrom;  "Chromosome of source region (directional) or lower region. For non-directional interchromosomal, chrom of this region."
51535     9  uint sourceStart;    "Start position in chromosome of source/lower/this region"
51536     10 uint sourceEnd;      "End position in chromosome of source/lower/this region"
51537     11 string sourceName;   "Identifier of source/lower/this region"
51538     12 string sourceStrand; "Orientation of source/lower/this region: + or -.  Use . if not applicable"
51539     13 string targetChrom;  "Chromosome of target region (directional) or upper region. For non-directional interchromosomal, chrom of other region"
51540     14 uint targetStart;    "Start position in chromosome of target/upper/this region"
51541     15 uint targetEnd;      "End position in chromosome of target/upper/this region"
51542     16 string targetName;   "Identifier of target/upper/this region"
51543     17 string targetStrand; "Orientation of target/upper/this region: + or -.  Use . if not applicable"
51544     *
51545     * @param tokens
51546     * @param ignore
51547     * @returns {*}
51548     */
51549
51550    function decodeInteract(tokens, header) {
51551      if (tokens.length < 6) {
51552        console.log("Skipping line: " + tokens.join(' '));
51553        return undefined;
51554      }
51555
51556      var feature = {
51557        chr: tokens[0],
51558        start: tokens[1],
51559        end: tokens[2],
51560        chr1: tokens[8],
51561        start1: Number.parseInt(tokens[9]),
51562        end1: Number.parseInt(tokens[10]),
51563        chr2: tokens[13],
51564        start2: Number.parseInt(tokens[14]),
51565        end2: Number.parseInt(tokens[15]),
51566        name: tokens[3],
51567        score: Number(tokens[4]),
51568        value: Number(tokens[5]),
51569        color: tokens[7] === '.' ? undefined : tokens[7] === "0" ? "rgb(0,0,0)" : tokens[7]
51570      };
51571      return feature;
51572    }
51573
51574    /**
51575     * Some interpretations of the sequence ontology needed to assemble GFF transcripts.
51576     *
51577     */
51578    const transcriptTypes = new Set(['transcript', 'primary_transcript', 'processed_transcript', 'mRNA', 'mrna', 'lnc_RNA', 'miRNA', 'ncRNA', 'rRNA', 'scRNA', 'snRNA', 'snoRNA', 'tRNA']);
51579    const cdsTypes = new Set(['CDS', 'cds']);
51580    const codonTypes = new Set(['start_codon', 'stop_codon']);
51581    const utrTypes = new Set(['5UTR', '3UTR', 'UTR', 'five_prime_UTR', 'three_prime_UTR', "3'-UTR", "5'-UTR"]);
51582    const exonTypes = new Set(['exon', 'coding-exon']);
51583    const transcriptPartTypes = new Set();
51584
51585    for (let cltn of [cdsTypes, codonTypes, utrTypes, exonTypes]) {
51586      for (let t of cltn) {
51587        transcriptPartTypes.add(t);
51588      }
51589    }
51590
51591    function isExon(type) {
51592      return exonTypes.has(type);
51593    }
51594
51595    function isIntron(type) {
51596      return type.includes("intron");
51597    }
51598
51599    function isCoding(type) {
51600      return cdsTypes.has(type) || codonTypes.has(type);
51601    }
51602
51603    function isUTR(type) {
51604      return utrTypes.has(type);
51605    }
51606
51607    function isTranscript(type) {
51608      return transcriptTypes.has(type) || type.endsWith("RNA") || type.endsWith("transcript");
51609    }
51610
51611    function isTranscriptPart(type) {
51612      return transcriptPartTypes.has(type) || type.endsWith("RNA") || isIntron(type);
51613    }
51614
51615    const filterPopupProperties = new Set(["id", "parent", "name"]);
51616
51617    class GFFFeature {
51618      constructor(properties) {
51619        Object.assign(this, properties);
51620      }
51621
51622      popupData(genomicLocation) {
51623        const pd = this.geneObject ? this.geneObject.popupData() : [];
51624
51625        if (this.geneObject) {
51626          pd.push('<hr/>');
51627        }
51628
51629        if (this.name) {
51630          pd.push({
51631            name: 'Name',
51632            value: this.name
51633          });
51634        }
51635
51636        pd.push({
51637          name: 'Type',
51638          value: this.type
51639        });
51640        pd.push({
51641          name: 'Source',
51642          value: this.source
51643        });
51644
51645        if (this.attributeString) {
51646          const atts = parseAttributeString(this.attributeString, this.delim);
51647
51648          for (let [key, value] of atts) {
51649            if (value !== undefined && value.length > 0 && !filterPopupProperties.has(key.toLowerCase())) {
51650              pd.push({
51651                name: key + ":",
51652                value: value
51653              });
51654            }
51655          }
51656        }
51657
51658        pd.push({
51659          name: 'Location',
51660          value: `${this.chr}:${numberFormatter$1(this.start + 1)}-${numberFormatter$1(this.end)}`
51661        });
51662        return pd;
51663      }
51664
51665      getAttributeValue(attributeName) {
51666        if (this.hasOwnProperty(attributeName)) {
51667          return this[attributeName];
51668        } else {
51669          // TODO -- fetch from attribute string and cache
51670          if (!this._attributeCache) {
51671            this._attributeCache = new Map();
51672          }
51673
51674          if (this._attributeCache.has(attributeName)) {
51675            return this._attributeCache.get(attributeName);
51676          } else {
51677            const atts = parseAttributeString(this.attributeString, this.delim);
51678            let v;
51679
51680            for (let [key, value] of atts) {
51681              if (key === attributeName) {
51682                v = value;
51683                break;
51684              }
51685            }
51686
51687            this._attributeCache.set(attributeName, v);
51688
51689            return v;
51690          }
51691        }
51692      }
51693
51694    }
51695
51696    class GFFTranscript extends GFFFeature {
51697      constructor(feature) {
51698        super(feature);
51699        this.exons = [];
51700        this.parts = [];
51701      }
51702
51703      addExon(feature) {
51704        this.exons.push(feature); // Expand feature --  for transcripts not explicitly represented in the file (gtf)
51705
51706        this.start = Math.min(this.start, feature.start);
51707        this.end = Math.max(this.end, feature.end);
51708      }
51709
51710      addPart(feature) {
51711        this.parts.push(feature);
51712      }
51713
51714      assembleParts() {
51715        if (this.parts.length === 0) return;
51716        this.parts.sort(function (a, b) {
51717          return a.start - b.start;
51718        }); // Create exons, if neccessary
51719
51720        let lastStart = this.parts[0].start;
51721        let lastEnd = this.parts[0].end;
51722
51723        for (let i = 1; i < this.parts.length; i++) {
51724          const part = this.parts[i];
51725
51726          if (isIntron(part.type)) {
51727            continue;
51728          }
51729
51730          if (part.start <= lastEnd) {
51731            lastEnd = Math.max(lastEnd, part.end);
51732          } else {
51733            let exon = this.findExonContaining({
51734              start: lastStart,
51735              end: lastEnd
51736            });
51737
51738            if (!exon) {
51739              this.exons.push({
51740                start: lastStart,
51741                end: lastEnd,
51742                psuedo: true
51743              });
51744            }
51745
51746            lastStart = part.start;
51747            lastEnd = part.end;
51748          }
51749        }
51750
51751        let exon = this.findExonContaining({
51752          start: lastStart,
51753          end: lastEnd
51754        });
51755
51756        if (!exon) {
51757          this.exons.push({
51758            start: lastStart,
51759            end: lastEnd,
51760            psuedo: true
51761          });
51762          this.start = Math.min(this.start, lastStart);
51763          this.end = Math.max(this.end, lastEnd);
51764        }
51765
51766        for (let part of this.parts) {
51767          const type = part.type;
51768
51769          if (isCoding(type)) {
51770            this.addCDS(part);
51771          } else if (isUTR(type)) {
51772            this.addUTR(part);
51773          }
51774        }
51775      }
51776
51777      findExonContaining(_ref) {
51778        let {
51779          start,
51780          end
51781        } = _ref;
51782
51783        for (let exon of this.exons) {
51784          if (exon.end >= end && exon.start <= start) {
51785            return exon;
51786          }
51787        }
51788
51789        return undefined;
51790      }
51791
51792      addCDS(cds) {
51793        let exon;
51794        const exons = this.exons;
51795
51796        for (let e of exons) {
51797          if (e.start <= cds.start && e.end >= cds.end) {
51798            exon = e;
51799            break;
51800          }
51801        }
51802
51803        if (exon) {
51804          exon.cdStart = exon.cdStart ? Math.min(cds.start, exon.cdStart) : cds.start;
51805          exon.cdEnd = exon.cdEnd ? Math.max(cds.end, exon.cdEnd) : cds.end;
51806        } else {
51807          // cds.cdStart = cds.start
51808          // cds.cdEnd = cds.end
51809          // exons.push(cds)
51810          console.error("No exon found spanning " + cds.start + "-" + cds.end);
51811        } // Expand feature --  for transcripts not explicitly represented in the file (gtf files)
51812        // this.start = Math.min(this.start, cds.start);
51813        // this.end = Math.max(this.end, cds.end);
51814
51815
51816        this.cdStart = this.cdStart ? Math.min(cds.start, this.cdStart) : cds.start;
51817        this.cdEnd = this.cdEnd ? Math.max(cds.end, this.cdEnd) : cds.end;
51818      }
51819
51820      addUTR(utr) {
51821        let exon;
51822        const exons = this.exons; // Find exon containing CDS
51823
51824        for (let i = 0; i < exons.length; i++) {
51825          if (exons[i].start <= utr.start && exons[i].end >= utr.end) {
51826            exon = exons[i];
51827            break;
51828          }
51829        }
51830
51831        if (exon) {
51832          if (utr.start === exon.start && utr.end === exon.end) {
51833            exon.utr = true;
51834          } else {
51835            if (utr.end < exon.end) {
51836              exon.cdStart = utr.end;
51837            }
51838
51839            if (utr.start > exon.start) {
51840              exon.cdEnd = utr.start;
51841            }
51842          }
51843        } else {
51844          // utr.utr = true
51845          // exons.push(utr)
51846          console.error("No exon found spanning " + cds.start + "-" + cds.end);
51847        } // Expand feature --  for transcripts not explicitly represented in the file
51848        // this.start = Math.min(this.start, utr.start);
51849        // this.end = Math.max(this.end, utr.end);
51850
51851      }
51852
51853      finish() {
51854        this.assembleParts();
51855        var cdStart = this.cdStart;
51856        var cdEnd = this.cdEnd;
51857        this.exons.sort(function (a, b) {
51858          return a.start - b.start;
51859        }); // Search for UTR exons that were not explicitly tagged
51860
51861        if (cdStart) {
51862          this.exons.forEach(function (exon) {
51863            if (exon.end < cdStart || exon.start > cdEnd) exon.utr = true;
51864          });
51865        }
51866      }
51867
51868      popupData(genomicLocation) {
51869        const pd = super.popupData(genomicLocation); // If clicked over an exon add its attributes
51870
51871        for (let exon of this.exons) {
51872          if (exon.pseudo) continue; // An implicit exon
51873
51874          if (genomicLocation >= exon.start && genomicLocation < exon.end && typeof exon.popupData === 'function') {
51875            pd.push('<hr/>');
51876            const exonData = exon.popupData(genomicLocation);
51877
51878            for (let att of exonData) {
51879              pd.push(att);
51880            }
51881          }
51882        }
51883
51884        for (let part of this.parts) {
51885          if (genomicLocation >= part.start && genomicLocation < part.end && typeof part.popupData === 'function') {
51886            pd.push('<hr/>');
51887            const partData = part.popupData(genomicLocation);
51888
51889            for (let att of partData) {
51890              pd.push(att);
51891            }
51892          }
51893        }
51894
51895        return pd;
51896      }
51897
51898    }
51899
51900    function decode(tokens, header) {
51901      const format = header.format;
51902
51903      if (tokens.length < 9) {
51904        return undefined; // Not a valid gff record
51905      }
51906
51907      const delim = 'gff3' === format ? '=' : ' ';
51908      return new GFFFeature({
51909        source: tokens[1],
51910        type: tokens[2],
51911        chr: tokens[0],
51912        start: parseInt(tokens[3]) - 1,
51913        end: parseInt(tokens[4]),
51914        score: "." === tokens[5] ? 0 : Number(tokens[5]),
51915        strand: tokens[6],
51916        phase: "." === tokens[7] ? 0 : parseInt(tokens[7]),
51917        attributeString: tokens[8],
51918        delim: delim
51919      });
51920    }
51921    /**
51922     * Decode a single gff record (1 line in file).  Aggregations such as gene models are constructed at a higher level.
51923     *      ctg123 . mRNA            1050  9000  .  +  .  ID=mRNA00001;Parent=gene00001
51924     * @param tokens
51925     * @param ignore
51926     * @returns {*}
51927     */
51928
51929
51930    function decodeGFF3(tokens, header) {
51931      const feature = decode(tokens, header);
51932
51933      if (!feature) {
51934        return;
51935      }
51936
51937      const attributes = parseAttributeString(feature.attributeString, feature.delim); // Search for color value as case insenstivie key
51938
51939      for (let [key, value] of attributes) {
51940        const keyLower = key.toLowerCase();
51941
51942        if ("color" === keyLower || "colour" === keyLower) {
51943          feature.color = IGVColor.createColorString(value);
51944        } else if (key === "ID") {
51945          feature.id = value;
51946        } else if (key === "Parent") {
51947          feature.parent = value;
51948        }
51949      }
51950
51951      return feature;
51952    }
51953    /**
51954     * GTF format example:
51955     NC_000008.11    BestRefSeq    gene    127735434    127742951    .    +    .    gene_id "MYC"; transcript_id ""; db_xref "GeneID:4609"; db_xref "HGNC:HGNC:7553"; db_xref "MIM:190080"; description "MYC proto-oncogene, bHLH transcription factor"; gbkey "Gene"; gene "MYC"; gene_biotype "protein_coding"; gene_synonym "bHLHe39"; gene_synonym "c-Myc"; gene_synonym "MRTL"; gene_synonym "MYCC";
51956     NC_000008.11    BestRefSeq    transcript    127735434    127742951    .    +    .    gene_id "MYC"; transcript_id "NM_001354870.1"; db_xref "GeneID:4609"; gbkey "mRNA"; gene "MYC"; product "MYC proto-oncogene, bHLH transcription factor, transcript variant 2"; transcript_biotype "mRNA";
51957     NC_000008.11    BestRefSeq    exon    127735434    127736623    .    +    .    gene_id "MYC"; transcript_id "NM_001354870.1"; db_xref "GeneID:4609"; gene "MYC"; product "MYC proto-oncogene, bHLH transcription factor, transcript variant 2"; transcript_biotype "mRNA"; exon_number "1";
51958     *
51959     * @param tokens
51960     * @param ignore
51961     * @returns {*}
51962     */
51963
51964
51965    function decodeGTF(tokens, header) {
51966      const feature = decode(tokens, header);
51967
51968      if (!feature) {
51969        return;
51970      }
51971
51972      const attributes = parseAttributeString(feature.attributeString, feature.delim); // GTF files specify neither ID nor parent fields, but they can be inferred from common conventions
51973
51974      let idField;
51975      let parentField;
51976
51977      switch (feature.type) {
51978        case "gene":
51979          idField = "gene_id";
51980          break;
51981
51982        case "transcript":
51983          idField = "transcript_id";
51984          parentField = "gene_id";
51985          break;
51986
51987        default:
51988          parentField = "transcript_id";
51989      }
51990
51991      for (let [key, value] of attributes) {
51992        const keyLower = key.toLowerCase();
51993
51994        if ("color" === keyLower || "colour" === keyLower) {
51995          feature.color = IGVColor.createColorString(value);
51996        } else if (key === idField) {
51997          feature.id = value;
51998        } else if (key === parentField) {
51999          feature.parent = value;
52000        }
52001      }
52002
52003      return feature;
52004    }
52005    /**
52006     * Parse the attribute string, returning an array of key-value pairs.  An array is used rather than a map as attribute
52007     * keys are not required to be unique.
52008     *
52009     * @param attributeString
52010     * @param keyValueDelim
52011     * @returns {[]}
52012     */
52013
52014
52015    function parseAttributeString(attributeString, keyValueDelim) {
52016      // parse 'attributes' string (see column 9 docs in https://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md)
52017      var attributes = [];
52018
52019      for (let kv of attributeString.split(';')) {
52020        kv = kv.trim();
52021        const idx = kv.indexOf(keyValueDelim);
52022
52023        if (idx > 0 && idx < kv.length - 1) {
52024          const key = kv.substring(0, idx);
52025          let value = stripQuotes(decodeURIComponent(kv.substring(idx + 1).trim()));
52026          attributes.push([key, value]);
52027        }
52028      }
52029
52030      return attributes;
52031    }
52032
52033    function stripQuotes(value) {
52034      if (value.startsWith('"') && value.endsWith('"')) {
52035        value = value.substr(1, value.length - 2);
52036      }
52037
52038      return value;
52039    }
52040
52041    /**
52042     * Wrapper class to record a decoding error.
52043     */
52044    class DecodeError {
52045      constructor(message) {
52046        this.message = message;
52047      }
52048
52049    }
52050
52051    /**
52052     * Decode the UCSC bed format.  Only the first 3 columns (chr, start, end) are required.   The remaining columns
52053     * must follow standard bed order, but we will tolerate deviations after column 3.
52054     *
52055     * @param tokens
52056     * @param ignore
52057     * @returns decoded feature, or null if this is not a valid record
52058     */
52059
52060    function decodeBed(tokens, header) {
52061      if (tokens.length < 3) return undefined;
52062      header && header.gffTags;
52063      const chr = tokens[0];
52064      const start = parseInt(tokens[1]);
52065      const end = tokens.length > 2 ? parseInt(tokens[2]) : start + 1;
52066
52067      if (isNaN(start) || isNaN(end)) {
52068        return new DecodeError(`Unparsable bed record.`);
52069      }
52070
52071      const feature = new UCSCBedFeature({
52072        chr: chr,
52073        start: start,
52074        end: end,
52075        score: 1000
52076      });
52077
52078      try {
52079        if (tokens.length > 3) {
52080          // Potentially parse name field as GFF column 9 style streng.
52081          if (tokens[3].indexOf(';') > 0 && tokens[3].indexOf('=') > 0) {
52082            const attributeKVs = parseAttributeString(tokens[3], '=');
52083            feature.attributes = {};
52084
52085            for (let kv of attributeKVs) {
52086              feature.attributes[kv[0]] = kv[1];
52087            }
52088          }
52089
52090          if (!feature.name) {
52091            feature.name = tokens[3] === '.' ? '' : tokens[3];
52092          }
52093        }
52094
52095        if (tokens.length > 4) {
52096          feature.score = tokens[4] === '.' ? 0 : Number(tokens[4]);
52097
52098          if (isNaN(feature.score)) {
52099            return feature;
52100          }
52101        }
52102
52103        if (tokens.length > 5) {
52104          feature.strand = tokens[5];
52105
52106          if (!(feature.strand === '.' || feature.strand === '+' || feature.strand === '-')) {
52107            return feature;
52108          }
52109        }
52110
52111        if (tokens.length > 6) {
52112          feature.cdStart = parseInt(tokens[6]);
52113
52114          if (isNaN(feature.cdStart)) {
52115            return feature;
52116          }
52117        }
52118
52119        if (tokens.length > 7) {
52120          feature.cdEnd = parseInt(tokens[7]);
52121
52122          if (isNaN(feature.cdEnd)) {
52123            return feature;
52124          }
52125        }
52126
52127        if (tokens.length > 8) {
52128          if (tokens[8] !== "." && tokens[8] !== "0") feature.color = IGVColor.createColorString(tokens[8]);
52129        }
52130
52131        if (tokens.length > 11) {
52132          const exonCount = parseInt(tokens[9]); // Some basic validation
52133
52134          if (exonCount > 1000) {
52135            // unlikely
52136            return feature;
52137          }
52138
52139          const exonSizes = tokens[10].replace(/,$/, '').split(',');
52140          const exonStarts = tokens[11].replace(/,$/, '').split(',');
52141
52142          if (!(exonSizes.length === exonStarts.length && exonCount === exonSizes.length)) {
52143            return feature;
52144          }
52145
52146          const exons = [];
52147
52148          for (let i = 0; i < exonCount; i++) {
52149            const eStart = start + parseInt(exonStarts[i]);
52150            const eEnd = eStart + parseInt(exonSizes[i]);
52151            exons.push({
52152              start: eStart,
52153              end: eEnd
52154            });
52155          }
52156
52157          findUTRs(exons, feature.cdStart, feature.cdEnd);
52158          feature.exons = exons;
52159        } // Optional extra columns
52160
52161
52162        if (header) {
52163          let thicknessColumn = header.thicknessColumn;
52164          let colorColumn = header.colorColumn;
52165
52166          if (colorColumn && colorColumn < tokens.length) {
52167            feature.color = IGVColor.createColorString(tokens[colorColumn]);
52168          }
52169
52170          if (thicknessColumn && thicknessColumn < tokens.length) {
52171            feature.thickness = tokens[thicknessColumn];
52172          }
52173        }
52174      } catch (e) {}
52175
52176      return feature;
52177    }
52178    /**
52179     * Decode a UCSC repeat masker record.
52180     *
52181     * Columns, from UCSC documentation
52182     *
52183     * 0  bin    585    smallint(5) unsigned    Indexing field to speed chromosome range queries.
52184     * 1  swScore    1504    int(10) unsigned    Smith Waterman alignment score
52185     * 2  milliDiv    13    int(10) unsigned    Base mismatches in parts per thousand
52186     * 3  milliDel    4    int(10) unsigned    Bases deleted in parts per thousand
52187     * 4  milliIns    13    int(10) unsigned    Bases inserted in parts per thousand
52188     * 5  genoName    chr1    varchar(255)    Genomic sequence name
52189     * 6  genoStart    10000    int(10) unsigned    Start in genomic sequence
52190     * 7  genoEnd    10468    int(10) unsigned    End in genomic sequence
52191     * 8  genoLeft    -249240153    int(11)    -#bases after match in genomic sequence
52192     * 9  strand    +    char(1)    Relative orientation + or -
52193     * 10 repName    (CCCTAA)n    varchar(255)    Name of repeat
52194     * 11 repClass    Simple_repeat    varchar(255)    Class of repeat
52195     * 12 repFamily    Simple_repeat    varchar(255)    Family of repeat
52196     * 13 repStart    1    int(11)    Start (if strand is +) or -#bases after match (if strand is -) in repeat sequence
52197     * 14 repEnd    463    int(11)    End in repeat sequence
52198     * 15 repLeft    0    int(11)    -#bases after match (if strand is +) or start (if strand is -) in repeat sequence
52199     * 16 id    1    char(1)    First digit of id field in RepeatMasker .out file. Best ignored.
52200     */
52201
52202
52203    function decodeRepeatMasker(tokens, header) {
52204      if (tokens.length <= 15) return undefined;
52205      const feature = {
52206        swScore: Number.parseInt(tokens[1]),
52207        milliDiv: Number.parseInt(tokens[2]),
52208        milliDel: Number.parseInt(tokens[3]),
52209        milliIns: Number.parseInt(tokens[4]),
52210        chr: tokens[5],
52211        start: Number.parseInt(tokens[6]),
52212        end: Number.parseInt(tokens[7]),
52213        //genoLeft: tokens[8],
52214        strand: tokens[9],
52215        repName: tokens[10],
52216        repClass: tokens[11],
52217        repFamily: tokens[12],
52218        repStart: Number.parseInt(tokens[13]),
52219        repEnd: Number.parseInt(tokens[14]),
52220        repLeft: Number.parseInt(tokens[15])
52221      };
52222      return feature;
52223    }
52224    /**
52225     * Decode a UCSC "genePred" record.
52226     *
52227     * @param tokens
52228     * @param ignore
52229     * @returns {*}
52230     */
52231
52232
52233    function decodeGenePred(tokens, header) {
52234      var shift = header.shift === undefined ? 0 : 1;
52235      if (tokens.length <= 9 + shift) return undefined;
52236      const cdStart = parseInt(tokens[5 + shift]);
52237      const cdEnd = parseInt(tokens[6 + shift]);
52238      var feature = {
52239        name: tokens[0 + shift],
52240        chr: tokens[1 + shift],
52241        strand: tokens[2 + shift],
52242        start: parseInt(tokens[3 + shift]),
52243        end: parseInt(tokens[4 + shift]),
52244        cdStart: cdStart,
52245        cdEnd: cdEnd,
52246        id: tokens[0 + shift]
52247      },
52248          exonCount = parseInt(tokens[7 + shift]),
52249          exonStarts = tokens[8 + shift].split(','),
52250          exonEnds = tokens[9 + shift].split(','),
52251          exons = [];
52252
52253      for (let i = 0; i < exonCount; i++) {
52254        const start = parseInt(exonStarts[i]);
52255        const end = parseInt(exonEnds[i]);
52256        exons.push({
52257          start: start,
52258          end: end
52259        });
52260      }
52261
52262      findUTRs(exons, cdStart, cdEnd);
52263      feature.exons = exons;
52264      return feature;
52265    }
52266    /**
52267     * Decode a UCSC "genePredExt" record.  refGene files are in this format.
52268     *
52269     * @param tokens
52270     * @param ignore
52271     * @returns {*}
52272     */
52273
52274
52275    function decodeGenePredExt(tokens, header) {
52276      var shift = header.shift === undefined ? 0 : 1;
52277      if (tokens.length <= 11 + shift) return undefined;
52278      const cdStart = parseInt(tokens[5 + shift]);
52279      const cdEnd = parseInt(tokens[6 + shift]);
52280      const feature = {
52281        name: tokens[11 + shift],
52282        chr: tokens[1 + shift],
52283        strand: tokens[2 + shift],
52284        start: parseInt(tokens[3 + shift]),
52285        end: parseInt(tokens[4 + shift]),
52286        cdStart: cdStart,
52287        cdEnd: cdEnd,
52288        id: tokens[0 + shift]
52289      },
52290            exonCount = parseInt(tokens[7 + shift]),
52291            exonStarts = tokens[8 + shift].split(','),
52292            exonEnds = tokens[9 + shift].split(','),
52293            exons = [];
52294
52295      for (let i = 0; i < exonCount; i++) {
52296        const start = parseInt(exonStarts[i]);
52297        const end = parseInt(exonEnds[i]);
52298        exons.push({
52299          start: start,
52300          end: end
52301        });
52302      }
52303
52304      findUTRs(exons, cdStart, cdEnd);
52305      feature.exons = exons;
52306      return feature;
52307    }
52308    /**
52309     * Decode a UCSC "refFlat" record
52310     * @param tokens
52311     * @param ignore
52312     * @returns {*}
52313     */
52314
52315
52316    function decodeReflat(tokens, header) {
52317      var shift = header.shift === undefined ? 0 : 1;
52318      if (tokens.length <= 10 + shift) return undefined;
52319      const cdStart = parseInt(tokens[6 + shift]);
52320      const cdEnd = parseInt(tokens[7 + shift]);
52321      var feature = {
52322        name: tokens[0 + shift],
52323        id: tokens[1 + shift],
52324        chr: tokens[2 + shift],
52325        strand: tokens[3 + shift],
52326        start: parseInt(tokens[4 + shift]),
52327        end: parseInt(tokens[5 + shift]),
52328        cdStart: cdStart,
52329        cdEnd: cdEnd
52330      },
52331          exonCount = parseInt(tokens[8 + shift]),
52332          exonStarts = tokens[9 + shift].split(','),
52333          exonEnds = tokens[10 + shift].split(','),
52334          exons = [];
52335
52336      for (let i = 0; i < exonCount; i++) {
52337        const start = parseInt(exonStarts[i]);
52338        const end = parseInt(exonEnds[i]);
52339        exons.push({
52340          start: start,
52341          end: end
52342        });
52343      }
52344
52345      findUTRs(exons, cdStart, cdEnd);
52346      feature.exons = exons;
52347      return feature;
52348    }
52349
52350    function findUTRs(exons, cdStart, cdEnd) {
52351      for (let exon of exons) {
52352        const end = exon.end;
52353        const start = exon.start;
52354
52355        if (end < cdStart || start > cdEnd) {
52356          exon.utr = true;
52357        } else {
52358          if (cdStart >= start && cdStart <= end) {
52359            exon.cdStart = cdStart;
52360          }
52361
52362          if (cdEnd >= start && cdEnd <= end) {
52363            exon.cdEnd = cdEnd;
52364          }
52365        }
52366      }
52367    }
52368
52369    function decodePeak(tokens, header) {
52370      var tokenCount, chr, start, end, strand, name, score, qValue, signal, pValue;
52371      tokenCount = tokens.length;
52372
52373      if (tokenCount < 9) {
52374        return undefined;
52375      }
52376
52377      chr = tokens[0];
52378      start = parseInt(tokens[1]);
52379      end = parseInt(tokens[2]);
52380      name = tokens[3];
52381      score = Number(tokens[4]);
52382      strand = tokens[5].trim();
52383      signal = Number(tokens[6]);
52384      pValue = Number(tokens[7]);
52385      qValue = Number(tokens[8]);
52386      if (score === 0) score = signal;
52387      return {
52388        chr: chr,
52389        start: start,
52390        end: end,
52391        name: name,
52392        score: score,
52393        strand: strand,
52394        signal: signal,
52395        pValue: pValue,
52396        qValue: qValue
52397      };
52398    }
52399
52400    function decodeBedGraph(tokens, header) {
52401      var chr, start, end, value;
52402      if (tokens.length <= 3) return undefined;
52403      chr = tokens[0];
52404      start = parseInt(tokens[1]);
52405      end = parseInt(tokens[2]);
52406      value = Number(tokens[3]);
52407      const feature = {
52408        chr: chr,
52409        start: start,
52410        end: end,
52411        value: value
52412      }; // Optional extra columns
52413
52414      if (header) {
52415        let colorColumn = header.colorColumn;
52416
52417        if (colorColumn && colorColumn < tokens.length) {
52418          feature.color = IGVColor.createColorString(tokens[colorColumn]);
52419        }
52420      }
52421
52422      return feature;
52423    }
52424
52425    function decodeWig(tokens, header) {
52426      const wig = header.wig;
52427
52428      if (wig && wig.format === "fixedStep") {
52429        const ss = wig.index * wig.step + wig.start;
52430        const ee = ss + wig.span;
52431        const value = Number(tokens[0]);
52432        ++wig.index;
52433        return isNaN(value) ? null : {
52434          chr: wig.chrom,
52435          start: ss,
52436          end: ee,
52437          value: value
52438        };
52439      } else if (wig && wig.format === "variableStep") {
52440        if (tokens.length < 2) return null;
52441        const ss = parseInt(tokens[0], 10) - 1;
52442        const ee = ss + wig.span;
52443        const value = Number(tokens[1]);
52444        return isNaN(value) ? null : {
52445          chr: wig.chrom,
52446          start: ss,
52447          end: ee,
52448          value: value
52449        };
52450      } else {
52451        return decodeBedGraph(tokens);
52452      }
52453    }
52454
52455    function decodeSNP(tokens, header) {
52456      if (tokens.length < 6) return undefined;
52457      const autoSql = ['bin', 'chr', 'start', 'end', 'name', 'score', 'strand', 'refNCBI', 'refUCSC', 'observed', 'molType', 'class', 'valid', 'avHet', 'avHetSE', 'func', 'locType', 'weight', 'exceptions', 'submitterCount', 'submitters', 'alleleFreqCount', 'alleles', 'alleleNs', 'alleleFreqs', 'bitfields'];
52458      const feature = {
52459        chr: tokens[1],
52460        start: Number.parseInt(tokens[2]),
52461        end: Number.parseInt(tokens[3]),
52462        name: tokens[4],
52463        score: Number.parseInt(tokens[5])
52464      };
52465      const n = Math.min(tokens.length, autoSql.length);
52466
52467      for (let i = 6; i < n; i++) {
52468        feature[autoSql[i]] = tokens[i];
52469      }
52470
52471      return feature;
52472    }
52473
52474    class UCSCBedFeature {
52475      constructor(properties) {
52476        Object.assign(this, properties);
52477      }
52478
52479      getAttributeValue(attributeName) {
52480        if (this.hasOwnProperty(attributeName)) {
52481          return this[attributeName];
52482        } else if (this.attributes) {
52483          return this.attributes[attributeName];
52484        }
52485      }
52486
52487    }
52488
52489    function decodeFusionJuncSpan(tokens, header) {
52490      /*
52491       Format:
52492        0       #scaffold
52493       1       fusion_break_name
52494       2       break_left
52495       3       break_right
52496       4       num_junction_reads
52497       5       num_spanning_frags
52498       6       spanning_frag_coords
52499        0       B3GNT1--NPSR1
52500       1       B3GNT1--NPSR1|2203-10182
52501       2       2203
52502       3       10182
52503       4       189
52504       5       1138
52505       6       1860-13757,1798-13819,1391-18127,1443-17174,...
52506        */
52507      if (tokens.length < 7) return undefined;
52508      var chr = tokens[0];
52509      var fusion_name = tokens[1];
52510      var junction_left = parseInt(tokens[2]);
52511      var junction_right = parseInt(tokens[3]);
52512      var num_junction_reads = parseInt(tokens[4]);
52513      var num_spanning_frags = parseInt(tokens[5]);
52514      var spanning_frag_coords_text = tokens[6];
52515      var feature = {
52516        chr: chr,
52517        name: fusion_name,
52518        junction_left: junction_left,
52519        junction_right: junction_right,
52520        num_junction_reads: num_junction_reads,
52521        num_spanning_frags: num_spanning_frags,
52522        spanning_frag_coords: [],
52523        start: -1,
52524        end: -1
52525      }; // set start and end later based on min/max of span coords
52526
52527      var min_coord = junction_left;
52528      var max_coord = junction_right;
52529
52530      if (num_spanning_frags > 0) {
52531        var coord_pairs = spanning_frag_coords_text.split(',');
52532
52533        for (var i = 0; i < coord_pairs.length; i++) {
52534          var split_coords = coord_pairs[i].split('-');
52535          var span_left = split_coords[0];
52536          var span_right = split_coords[1];
52537
52538          if (span_left < min_coord) {
52539            min_coord = span_left;
52540          }
52541
52542          if (span_right > max_coord) {
52543            max_coord = span_right;
52544          }
52545
52546          feature.spanning_frag_coords.push({
52547            left: span_left,
52548            right: span_right
52549          });
52550        }
52551      }
52552
52553      feature.start = min_coord;
52554      feature.end = max_coord;
52555      return feature;
52556    }
52557
52558    function decodeGtexGWAS(tokens, header) {
52559      //chrom	chromStart	chromEnd	Strongest SNP-risk allele	Disease/Phe
52559notype	P-value	Odds ratio or beta	PUBMEDID
52560      //1	1247493	1247494	rs12103-A	Inflammatory bowel disease	8.00E-13	1.1	23128233
52561      const tokenCount = tokens.length;
52562
52563      if (tokenCount < 7) {
52564        return null;
52565      }
52566
52567      const feature = {
52568        chr: tokens[0],
52569        start: parseInt(tokens[1]) - 1,
52570        end: parseInt(tokens[2]),
52571        'Strongest SNP-risk allele': tokens[3],
52572        'Disease/Phenotype': tokens[4],
52573        'P-value': tokens[5],
52574        'Odds ratio or beta': tokens[6]
52575      };
52576
52577      if (tokens.length > 6) {
52578        feature['PUBMEDID'] = `<a target = "blank" href = "https://www.ncbi.nlm.nih.gov/pubmed/${tokens[7]}">${tokens[7]}</a>`;
52579      }
52580
52581      return feature;
52582    }
52583
52584    /**
52585     * Decode a custom columnar format.  Required columns are 'chr' and 'start'
52586     *
52587     * @param tokens
52588     * @param ignore
52589     * @returns decoded feature, or null if this is not a valid record
52590     */
52591    function decodeCustom(tokens, header) {
52592      const format = header.customFormat;
52593      if (tokens.length < format.fields.length) return undefined;
52594      const coords = format.coords || 0;
52595      const chr = tokens[format.chr];
52596      const start = parseInt(tokens[format.start]) - coords;
52597      const end = format.end !== undefined ? parseInt(tokens[format.end]) : start + 1;
52598      const feature = {
52599        chr: chr,
52600        start: start,
52601        end: end
52602      };
52603
52604      if (format.fields) {
52605        format.fields.forEach(function (field, index) {
52606          if (index !== format.chr && index !== format.start && index !== format.end) {
52607            feature[field] = tokens[index];
52608          }
52609        });
52610      }
52611
52612      return feature;
52613    } // function expandFormat(format) {
52614
52615    /**
52616     * Decode a gcnv record, a bed style format encoding copy number variation
52617     *
52618     * @param tokens
52619     * @param header
52620     */
52621    function decodeGcnv(tokens, header) {
52622      const columnNames = header.columnNames;
52623
52624      if (!columnNames) {
52625        throw Error("Sample names are not defined.   Missing column headers?");
52626      }
52627
52628      const sampleCount = columnNames.length - 3;
52629      const chr = tokens[0];
52630      const start = parseInt(tokens[1]);
52631      const end = parseInt(tokens[2]);
52632      const values = tokens.slice(3).map(Number);
52633
52634      if (values.length == sampleCount) {
52635        return {
52636          chr: chr,
52637          start: start,
52638          end: end,
52639          values: values
52640        };
52641      } else {
52642        // TODO Throw error?
52643        console.warn(`${chr}:${start}-${end} row contains ${values.length} sample columns instead of the expected ${sampleCount} columns. Skipping...`);
52644        return undefined;
52645      }
52646    }
52647
52648    /*
52649     * The MIT License (MIT)
52650     *
52651     * Copyright (c) 2014 Broad Institute
52652     *
52653     * Permission is hereby granted, free of charge, to any person obtaining a copy
52654     * of this software and associated documentation files (the "Software"), to deal
52655     * in the Software without restriction, including without limitation the rights
52656     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
52657     * copies of the Software, and to permit persons to whom the Software is
52658     * furnished to do so, subject to the following conditions:
52659     *
52660     * The above copyright notice and this permission notice shall be included in
52661     * all copies or substantial portions of the Software.
52662     *
52663     *
52664     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52665     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52666     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52667     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52668     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52669     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
52670     * THE SOFTWARE.
52671     */
52672    /**
52673     *  Parser for column style (tab delimited, etc) text file formats (bed, gff, vcf, etc).
52674     *
52675     *
52676     */
52677
52678    /**
52679     * Return a parser for the given file format.
52680     */
52681
52682    class FeatureParser {
52683      constructor(config) {
52684        this.config = config;
52685        this.header = {};
52686
52687        if (config.nameField) {
52688          this.header.nameField = config.nameField;
52689        }
52690
52691        this.skipRows = 0; // The number of fixed header rows to skip.  Override for specific types as needed
52692
52693        if (config.decode) {
52694          this.decode = config.decode;
52695          this.delimiter = config.delimiter || "\t";
52696        } else if (config.format) {
52697          this.header.format = config.format.toLowerCase();
52698          this.setDecoder(this.header.format);
52699        }
52700
52701        if (!this.delimiter) {
52702          this.delimiter = "\t";
52703        }
52704      }
52705      /**
52706       * Parse metadata from the file.   A variety of conventions are in use to supply metadata about file contents
52707       * through header lines (e.g. 'track') and # directives. This method unifies metadata as properties of a
52708       * 'header' object.
52709       *
52710       * @param data
52711       * @returns {{}}
52712       */
52713
52714
52715      async parseHeader(dataWrapper) {
52716        let header = this.header;
52717        let columnNames;
52718        let line;
52719
52720        while ((line = await dataWrapper.nextLine()) !== undefined) {
52721          if (line.startsWith("track") || line.startsWith("#track")) {
52722            let h = parseTrackLine$1(line);
52723            Object.assign(header, h);
52724          } else if (line.startsWith("browser")) ; else if (line.startsWith("#columns")) {
52725            let h = parseColumnsDirective$1(line);
52726            Object.assign(header, h);
52727          } else if (line.startsWith("##gff-version 3")) {
52728            header.format = "gff3";
52729          } else if (line.startsWith("#gffTags")) {
52730            header.gffTags = true;
52731          } else if (line.startsWith("fixedStep") || line.startsWith("variableStep")) {
52732            // Wig directives -- we are in the data section
52733            break;
52734          } else if (line.startsWith("#")) {
52735            const tokens = line.split(this.delimiter || "\t");
52736
52737            if (tokens.length > 1) {
52738              columnNames = tokens; // Possible column names
52739            }
52740          } else {
52741            // All directives that could change the format, and thus decoder, should have been read by now.
52742            this.setDecoder(header.format); // If the line can be parsed as a feature assume we are beyond the header, if any
52743
52744            const tokens = line.split(this.delimiter || "\t");
52745
52746            try {
52747              const tmpHeader = Object.assign({
52748                columnNames
52749              }, header);
52750
52751              if (this.decode(tokens, tmpHeader)) {
52752                break;
52753              } else {
52754                if (tokens.length > 1) {
52755                  columnNames = tokens; // possible column names
52756                }
52757              }
52758            } catch (e) {
52759              // Not a feature
52760              if (tokens.length > 1) {
52761                columnNames = tokens; // possible column names
52762              }
52763            }
52764          }
52765        }
52766
52767        if (columnNames) {
52768          header.columnNames = columnNames;
52769
52770          for (let n = 0; n < columnNames.length; n++) {
52771            if (columnNames[n] === "color" || columnNames[n] === "colour") {
52772              header.colorColumn = n;
52773            } else if (columnNames[n] === "thickness") {
52774              header.thicknessColumn = n;
52775            }
52776          }
52777        }
52778
52779        this.header = header; // Directives might be needed for parsing lines
52780
52781        return header;
52782      }
52783
52784      async parseFeatures(dataWrapper) {
52785        const allFeatures = [];
52786        const decode = this.decode;
52787        const format = this.header.format;
52788        const delimiter = this.delimiter || "\t";
52789        let i = 0;
52790        let errorCount = 0;
52791        let line;
52792
52793        while ((line = await dataWrapper.nextLine()) !== undefined) {
52794          i++;
52795          if (i <= this.skipRows) continue;
52796
52797          if (!line || line.startsWith("track") || line.startsWith("#") || line.startsWith("browser")) {
52798            continue;
52799          } else if (format === "wig" && line.startsWith("fixedStep")) {
52800            this.header.wig = parseFixedStep(line);
52801            continue;
52802          } else if (format === "wig" && line.startsWith("variableStep")) {
52803            this.header.wig = parseVariableStep(line);
52804            continue;
52805          }
52806
52807          const tokens = line.split(delimiter);
52808
52809          if (tokens.length < 1) {
52810            continue;
52811          }
52812
52813          const feature = decode(tokens, this.header);
52814
52815          if (feature instanceof DecodeError) {
52816            errorCount++;
52817
52818            if (errorCount > 0) {
52819              console.error(`Error parsing line '${line}': ${feature.message}`);
52820            }
52821
52822            continue;
52823          }
52824
52825          if (feature) {
52826            allFeatures.push(feature);
52827          }
52828        } // Special hack for bedPE
52829
52830
52831        if (decode === decodeBedpe) {
52832          fixBedPE(allFeatures);
52833        }
52834
52835        return allFeatures;
52836      }
52837
52838      setDecoder(format) {
52839        switch (format) {
52840          case "narrowpeak":
52841          case "broadpeak":
52842          case "regionpeak":
52843          case "peaks":
52844            this.decode = decodePeak;
52845            this.delimiter = this.config.delimiter || /\s+/;
52846            break;
52847
52848          case "bedgraph":
52849            this.decode = decodeBedGraph;
52850            this.delimiter = /\s+/;
52851            break;
52852
52853          case "wig":
52854            this.decode = decodeWig;
52855            this.delimiter = this.config.delimiter || /\s+/;
52856            break;
52857
52858          case "gff3":
52859          case "gff":
52860            this.decode = decodeGFF3;
52861            this.delimiter = "\t";
52862            break;
52863
52864          case "gtf":
52865            this.decode = decodeGTF;
52866            this.delimiter = "\t";
52867            break;
52868
52869          case "fusionjuncspan":
52870            // bhaas, needed for FusionInspector view
52871            this.decode = decodeFusionJuncSpan;
52872            this.delimiter = this.config.delimiter || /\s+/;
52873            break;
52874
52875          case "gtexgwas":
52876            this.skipRows = 1;
52877            this.decode = decodeGtexGWAS;
52878            this.delimiter = "\t";
52879            break;
52880
52881          case "refflat":
52882            this.decode = decodeReflat;
52883            this.delimiter = this.config.delimiter || /\s+/;
52884            break;
52885
52886          case "genepred":
52887            this.decode = decodeGenePred;
52888            this.delimiter = this.config.delimiter || /\s+/;
52889            break;
52890
52891          case "genepredext":
52892            this.decode = decodeGenePredExt;
52893            this.delimiter = this.config.delimiter || /\s+/;
52894            break;
52895
52896          case "ensgene":
52897            this.decode = decodeGenePred;
52898            this.header.shift = 1;
52899            this.delimiter = this.config.delimiter || /\s+/;
52900            break;
52901
52902          case "refgene":
52903            this.decode = decodeGenePredExt;
52904            this.delimiter = this.config.delimiter || /\s+/;
52905            this.header.shift = 1;
52906            break;
52907
52908          case "bed":
52909            this.decode = decodeBed;
52910            this.delimiter = this.config.delimiter || /\s+/;
52911            break;
52912
52913          case "bedpe":
52914            this.decode = decodeBedpe;
52915            this.delimiter = this.config.delimiter || "\t";
52916            break;
52917
52918          case "bedpe-domain":
52919            this.decode = decodeBedpeDomain;
52920            this.headerLine = true;
52921            this.delimiter = this.config.delimiter || "\t";
52922            break;
52923
52924          case "bedpe-loop":
52925            this.decode = decodeBedpe;
52926            this.delimiter = this.config.delimiter || "\t";
52927            this.header = {
52928              colorColumn: 7
52929            };
52930            break;
52931
52932          case "interact":
52933            this.decode = decodeInteract;
52934            this.delimiter = this.config.delimiter || /\s+/;
52935            break;
52936
52937          case "snp":
52938            this.decode = decodeSNP;
52939            this.delimiter = "\t";
52940            break;
52941
52942          case "rmsk":
52943            this.decode = decodeRepeatMasker;
52944            this.delimiter = "\t";
52945            break;
52946
52947          case "gcnv":
52948            this.decode = decodeGcnv;
52949            this.delimiter = "\t";
52950            break;
52951
52952          default:
52953            const customFormat = getFormat(format);
52954
52955            if (customFormat !== undefined) {
52956              this.decode = decodeCustom;
52957              this.header.customFormat = customFormat;
52958              this.delimiter = customFormat.delimiter || "\t";
52959            } else {
52960              this.decode = decodeBed;
52961              this.delimiter = this.config.delimiter || /\s+/;
52962            }
52963
52964        }
52965      }
52966
52967    }
52968
52969    function parseTrackLine$1(line) {
52970      const properties = {};
52971      const tokens = line.split(/(?:")([^"]+)(?:")|([^\s"]+)(?=\s+|$)/g); // Clean up tokens array
52972
52973      let curr;
52974      const tmp = [];
52975
52976      for (let tk of tokens) {
52977        if (!tk || tk.trim().length === 0) continue;
52978
52979        if (tk.endsWith("=")) {
52980          curr = tk;
52981        } else if (curr) {
52982          tmp.push(curr + tk);
52983          curr = undefined;
52984        } else {
52985          tmp.push(tk);
52986        }
52987      }
52988
52989      for (let str of tmp) {
52990        if (!str) return;
52991        var kv = str.split('=', 2);
52992
52993        if (kv.length === 2) {
52994          const key = kv[0].trim();
52995          const value = kv[1].trim();
52996
52997          if (properties.hasOwnProperty(key)) {
52998            let currentValue = properties[key];
52999
53000            if (Array.isArray(currentValue)) {
53001              currentValue.push(value);
53002            } else {
53003              properties[key] = [currentValue, value];
53004            }
53005          } else {
53006            properties[key] = value;
53007          }
53008        }
53009      }
53010
53011      if ("interact" == properties["type"]) {
53012        properties["format"] = "interact";
53013      } else if ("gcnv" === properties["type"]) {
53014        properties["format"] = "gcnv";
53015      }
53016
53017      return properties;
53018    }
53019
53020    function parseColumnsDirective$1(line) {
53021      let properties = {};
53022      let t1 = line.split(/\s+/);
53023
53024      if (t1.length === 2) {
53025        let t2 = t1[1].split(";");
53026        t2.forEach(function (keyValue) {
53027          let t = keyValue.split("=");
53028
53029          if (t[0] === "color") {
53030            properties.colorColumn = Number.parseInt(t[1]) - 1;
53031          } else if (t[0] === "thickness") {
53032            properties.thicknessColumn = Number.parseInt(t[1]) - 1;
53033          }
53034        });
53035      }
53036
53037      return properties;
53038    }
53039
53040    function parseFixedStep(line) {
53041      const tokens = line.split(/\s+/);
53042      const chrom = tokens[1].split("=")[1];
53043      const start = parseInt(tokens[2].split("=")[1], 10) - 1;
53044      const step = parseInt(tokens[3].split("=")[1], 10);
53045      const span = tokens.length > 4 ? parseInt(tokens[4].split("=")[1], 10) : 1;
53046      return {
53047        format: "fixedStep",
53048        chrom,
53049        start,
53050        step,
53051        span,
53052        index: 0
53053      };
53054    }
53055
53056    function parseVariableStep(line) {
53057      const tokens = line.split(/\s+/);
53058      const chrom = tokens[1].split("=")[1];
53059      const span = tokens.length > 2 ? parseInt(tokens[2].split("=")[1], 10) : 1;
53060      return {
53061        format: "variableStep",
53062        chrom,
53063        span
53064      };
53065    }
53066
53067    /*
53068     * The MIT License (MIT)
53069     *
53070     * Copyright (c) 2014 Broad Institute
53071     *
53072     * Permission is hereby granted, free of charge, to any person obtaining a copy
53073     * of this software and associated documentation files (the "Software"), to deal
53074     * in the Software without restriction, including without limitation the rights
53075     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
53076     * copies of the Software, and to permit persons to whom the Software is
53077     * furnished to do so, subject to the following conditions:
53078     *
53079     * The above copyright notice and this permission notice shall be included in
53080     * all copies or substantial portions of the Software.
53081     *
53082     *
53083     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53084     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53085     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53086     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53087     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53088     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53089     * THE SOFTWARE.
53090     */
53091    /**
53092     *  Define parser for seg files  (.bed, .gff, .vcf, etc).  A parser should implement 2 methods
53093     *
53094     *     parseHeader(data) - return an object representing a header.  Details are format specific
53095     *
53096     *     parseFeatures(data) - return a list of features
53097     *
53098     */
53099
53100    class SegParser {
53101      constructor(type) {
53102        this.type = type || 'seg'; // One of seg, mut, or maf
53103
53104        switch (this.type) {
53105          case 'mut':
53106            this.sampleColumn = 3;
53107            this.chrColumn = 0;
53108            this.startColumn = 1;
53109            this.endColumn = 2;
53110            this.dataColumn = 4;
53111            break;
53112
53113          case 'maf':
53114            this.sampleColumn = 15;
53115            this.chrColumn = 4;
53116            this.startColumn = 5;
53117            this.endColumn = 6;
53118            this.dataColumn = 8;
53119            break;
53120
53121          default:
53122            this.sampleColumn = 0;
53123            this.chrColumn = 1;
53124            this.startColumn = 2;
53125            this.endColumn = 3;
53126          // Data column determined after reading header
53127        }
53128      }
53129
53130      async parseHeader(dataWrapper) {
53131        let line;
53132
53133        while ((line = await dataWrapper.nextLine()) !== undefined) {
53134          if (line.startsWith("#")) ; else {
53135            const tokens = line.split("\t");
53136            this.header = {
53137              headings: tokens
53138            };
53139            break;
53140          }
53141        }
53142
53143        return this.header;
53144      }
53145
53146      async parseFeatures(dataWrapper) {
53147        const allFeatures = [];
53148        let extraHeaders;
53149
53150        if (!this.header) {
53151          this.header = await this.parseHeader(dataWrapper); // This will only work for non-indexed files
53152        }
53153
53154        if ('seg' === this.type) {
53155          this.dataColumn = this.header.headings.length - 1;
53156        }
53157
53158        if (this.header.headings.length > 5) {
53159          extraHeaders = this.extractExtraColumns(this.header.headings);
53160        }
53161
53162        const valueColumnName = this.header.headings[this.dataColumn];
53163        let line;
53164
53165        while ((line = await dataWrapper.nextLine()) !== undefined) {
53166          const tokens = line.split("\t");
53167          const value = 'seg' === this.type ? Number(tokens[this.dataColumn]) : tokens[this.dataColumn];
53168
53169          if (tokens.length > this.dataColumn) {
53170            const feature = new SegFeature({
53171              sample: tokens[this.sampleColumn],
53172              chr: tokens[this.chrColumn],
53173              start: parseInt(tokens[this.startColumn]) - 1,
53174              end: parseInt(tokens[this.endColumn]),
53175              value,
53176              valueColumnName
53177            });
53178
53179            if (extraHeaders) {
53180              const extraValues = this.extractExtraColumns(tokens);
53181              feature.setAttributes({
53182                names: extraHeaders,
53183                values: extraValues
53184              });
53185            }
53186
53187            allFeatures.push(feature);
53188          }
53189        }
53190
53191        return allFeatures;
53192      }
53193
53194      extractExtraColumns(tokens) {
53195        const extras = [];
53196
53197        for (let i = 0; i < tokens.length; i++) {
53198          if (i !== this.chrColumn && i !== this.startColumn && i !== this.endColumn && i !== this.sampleColumn) {
53199            extras.push(tokens[i]);
53200          }
53201        }
53202
53203        return extras;
53204      }
53205
53206    }
53207
53208    class SegFeature {
53209      constructor(_ref) {
53210        let {
53211          sample,
53212          chr,
53213          start,
53214          end,
53215          value,
53216          valueColumnName
53217        } = _ref;
53218        this.sample = sample;
53219        this.chr = chr;
53220        this.start = start;
53221        this.end = end;
53222        this.value = value;
53223        this.valueColumnName = valueColumnName;
53224      }
53225
53226      setAttributes(_ref2) {
53227        let {
53228          names,
53229          values
53230        } = _ref2;
53231        this.attributeNames = names;
53232        this.attributeValues = values;
53233      }
53234
53235      getAttribute(name) {
53236        if (this.attributeNames) {
53237          const idx = this.attributeNames.indexOf(name);
53238
53239          if (idx >= 0) {
53240            return this.attributeValues[idx];
53241          }
53242        }
53243
53244        return undefined;
53245      }
53246
53247      popupData(type, genomeID) {
53248        const filteredProperties = new Set(['chr', 'start', 'end', 'sample', 'value', 'row', 'color', 'sampleKey', 'uniqueSampleKey', 'sampleId', 'chromosome', 'uniquePatientKey']);
53249        const locationString = this.chr + ":" + numberFormatter$1(this.start + 1) + "-" + numberFormatter$1(this.end);
53250        const pd = [{
53251          name: "Sample",
53252          value: this.sample
53253        }, {
53254          name: "Location",
53255          value: locationString
53256        }, {
53257          name: this.valueColumnName ? capitalize(this.valueColumnName) : "Value",
53258          value: this.value
53259        }]; // TODO -- the Cravat stuff should probably be in the track (SegTrack)
53260
53261        if ("mut" === type && "hg38" === genomeID) {
53262          const l = this.extractCravatLink(genomeID);
53263
53264          if (l) {
53265            pd.push('<hr/>');
53266            pd.push({
53267              html: l
53268            });
53269            pd.push('<hr/>');
53270          }
53271        }
53272
53273        if (this.attributeNames && this.attributeNames.length > 0) {
53274          for (let i = 0; i < this.attributeNames.length; i++) {
53275            if (!filteredProperties.has(this.attributeNames[i]) & this.valueColumnName !== this.attributeNames[i]) {
53276              pd.push({
53277                name: capitalize(this.attributeNames[i]),
53278                value: this.attributeValues[i]
53279              });
53280            }
53281          }
53282        }
53283
53284        return pd;
53285      }
53286
53287      extractCravatLink(genomeId) {
53288        let ref, alt;
53289
53290        if (this.attributeNames && this.attributeNames.length > 0) {
53291          for (let i = 0; i < this.attributeNames.length; i++) {
53292            if (!ref && "Reference_Allele" === this.attributeNames[i]) {
53293              ref = this.attributeValues[i];
53294            }
53295
53296            if (!alt && this.attributeNames[i].startsWith("Tumor_Seq_Allele") && this.attributeValues[i] !== ref) {
53297              alt = this.attributeValues[i];
53298            }
53299
53300            if (ref && alt) {
53301              return TrackBase.getCravatLink(this.chr, this.start + 1, ref, alt, genomeId);
53302            }
53303          }
53304        }
53305      }
53306
53307    }
53308
53309    /*
53310     * The MIT License (MIT)
53311     *
53312     * Copyright (c) 2014 Broad Institute
53313     *
53314     * Permission is hereby granted, free of charge, to any person obtaining a copy
53315     * of this software and associated documentation files (the "Software"), to deal
53316     * in the Software without restriction, including without limitation the rights
53317     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
53318     * copies of the Software, and to permit persons to whom the Software is
53319     * furnished to do so, subject to the following conditions:
53320     *
53321     * The above copyright notice and this permission notice shall be included in
53322     * all copies or substantial portions of the Software.
53323     *
53324     *
53325     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53326     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53327     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53328     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53329     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53330     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53331     * THE SOFTWARE.
53332     */
53333    const knownAltBases = new Set(["A", "C", "T", "G"].map(c => c.charCodeAt(0)));
53334
53335    function createVCFVariant(tokens) {
53336      return new Variant(tokens);
53337    }
53338
53339    class Variant {
53340      constructor(tokens) {
53341        this.chr = tokens[0]; // TODO -- use genome aliases
53342
53343        this.pos = parseInt(tokens[1]);
53344        this.names = tokens[2]; // id in VCF
53345
53346        this.referenceBases = tokens[3];
53347        this.alternateBases = tokens[4];
53348        this.quality = tokens[5];
53349        this.filter = tokens[6];
53350        this.info = getInfoObject(tokens[7]);
53351        this.init();
53352      }
53353
53354      init() {
53355        const ref = this.referenceBases;
53356        const altBases = this.alternateBases;
53357
53358        if (this.info) {
53359          if (this.info["VT"]) {
53360            this.type = this.info["VT"];
53361          } else if (this.info["SVTYPE"]) {
53362            this.type = "SV";
53363          } else if (this.info["PERIOD"]) {
53364            this.type = "STR";
53365          }
53366        }
53367
53368        if (this.type === undefined) {
53369          this.type = determineType(ref, altBases);
53370        }
53371
53372        if (this.type === "NONVARIANT") {
53373          this.heterozygosity = 0;
53374        } // Determine start/end coordinates -- these are the coordinates representing the actual variant,
53375        // not the leading or trailing reference
53376
53377
53378        if (this.info["END"]) {
53379          this.start = this.pos - 1;
53380
53381          if (this.info["CHR2"] && this.info["CHR2"] !== this.chr) {
53382            this.end = this.start + 1;
53383          } else {
53384            this.end = Number.parseInt(this.info["END"]);
53385          }
53386        } else {
53387          if (this.type === "NONVARIANT") {
53388            this.start = this.pos - 1; // convert to 0-based coordinate convention
53389
53390            this.end = this.start + ref.length;
53391          } else {
53392            const altTokens = altBases.split(",").filter(token => token.length > 0);
53393            this.alleles = [];
53394            this.start = undefined;
53395            this.end = undefined;
53396
53397            for (let alt of altTokens) {
53398              this.alleles.push(alt); // We don't yet handle  SV and other special alt representations
53399
53400              if ("SV" !== this.type && isKnownAlt(alt)) {
53401                let altLength = alt.length;
53402                let lengthOnRef = ref.length;
53403                const lmin = Math.min(altLength, lengthOnRef); // Trim off matching bases.  Try first match, then right -> left,  then any remaining left -> right
53404
53405                let s = 0;
53406
53407                while (s < lmin && ref.charCodeAt(s) === alt.charCodeAt(s)) {
53408                  s++;
53409                  altLength--;
53410                  lengthOnRef--;
53411                } // right -> left from end
53412
53413
53414                while (altLength > 0 && lengthOnRef > 0) {
53415                  const altIdx = s + altLength - 1;
53416                  const refIdx = s + lengthOnRef - 1;
53417
53418                  if (alt.charCodeAt(altIdx) === ref.charCodeAt(refIdx)) {
53419                    altLength--;
53420                    lengthOnRef--;
53421                  } else {
53422                    break;
53423                  }
53424                } // if any remaining, left -> right
53425
53426
53427                while (altLength > 0 && lengthOnRef > 0) {
53428                  const altIdx = s;
53429                  const refIdx = s;
53430
53431                  if (alt.charCodeAt(altIdx) === ref.charCodeAt(refIdx)) {
53432                    s++;
53433                    altLength--;
53434                    lengthOnRef--;
53435                  } else {
53436                    break;
53437                  }
53438                }
53439
53440                const alleleStart = this.pos + s - 1; // -1 for zero based coordinates
53441
53442                const alleleEnd = alleleStart + lengthOnRef;
53443                this.start = this.start === undefined ? alleleStart : Math.min(this.start, alleleStart);
53444                this.end = this.end === undefined ? alleleEnd : Math.max(this.end, alleleEnd);
53445              }
53446            } // Default to single base representation @ position for variant types not otherwise handled
53447
53448
53449            if (this.start === undefined) {
53450              this.start = this.pos - 1;
53451              this.end = this.pos;
53452            }
53453          }
53454        }
53455      }
53456
53457      popupData(genomicLocation, genomeId) {
53458        const posString = `${numberFormatter$1(this.pos)}`;
53459        const locString = this.start === this.end ? `${numberFormatter$1(this.start)} | ${numberFormatter$1(this.start + 1)}` : `${numberFormatter$1(this.start + 1)}-${numberFormatter$1(this.end)}`;
53460        const fields = [{
53461          name: "Chr",
53462          value: this.chr
53463        }, {
53464          name: "Pos",
53465          value: posString
53466        }, {
53467          name: "Loc",
53468          value: locString
53469        }, {
53470          name: "Names",
53471          value: this.names ? this.names : ""
53472        }, {
53473          name: "Ref",
53474          value: this.referenceBases
53475        }, {
53476          name: "Alt",
53477          value: this.alternateBases.replace("<", "&lt;")
53478        }, {
53479          name: "Qual",
53480          value: this.quality
53481        }, {
53482          name: "Filter",
53483          value: this.filter
53484        }];
53485
53486        if ("SNP" === this.type) {
53487          let ref = this.referenceBases;
53488
53489          if (ref.length === 1) {
53490            let altArray = this.alternateBases.split(",");
53491
53492            for (let alt of altArray) {
53493              if (alt.length === 1) {
53494                let l = TrackBase.getCravatLink(this.chr, this.pos, ref, alt, genomeId);
53495
53496                if (l) {
53497                  fields.push('<hr/>');
53498                  fields.push({
53499                    html: l
53500                  });
53501                }
53502              }
53503            }
53504          }
53505        }
53506
53507        if (this.hasOwnProperty("heterozygosity")) {
53508          fields.push({
53509            name: "Heterozygosity",
53510            value: this.heterozygosity
53511          });
53512        }
53513
53514        if (this.info) {
53515          fields.push({
53516            html: '<hr style="border-top: dotted 1px;border-color: #c9c3ba" />'
53517          });
53518
53519          for (let key of Object.keys(this.info)) {
53520            fields.push({
53521              name: key,
53522              value: arrayToString(decodeURIComponent(this.info[key]))
53523            });
53524          }
53525        }
53526
53527        return fields;
53528      }
53529
53530      isRefBlock() {
53531        return "NONVARIANT" === this.type;
53532      }
53533
53534    }
53535
53536    function getInfoObject(infoStr) {
53537      var info = {};
53538
53539      if (infoStr) {
53540        infoStr.split(';').forEach(function (elem) {
53541          var element = elem.split('=');
53542          info[element[0]] = element[1];
53543        });
53544      }
53545
53546      return info;
53547    }
53548
53549    function isKnownAlt(alt) {
53550      for (let i = 0; i < alt.length; i++) {
53551        if (!knownAltBases.has(alt.charCodeAt(i))) {
53552          return false;
53553        }
53554      }
53555
53556      return true;
53557    }
53558
53559    function determineType(ref, altAlleles) {
53560      const refLength = ref.length;
53561
53562      if (altAlleles === undefined) {
53563        return "UNKNOWN";
53564      } else if (altAlleles.trim().length === 0 || altAlleles === "<NON_REF>" || altAlleles === "<*>" || altAlleles === ".") {
53565        return "NONVARIANT";
53566      } else {
53567        const alleles = altAlleles.split(",");
53568        const types = alleles.map(function (a) {
53569          if (refLength === 1 && a.length === 1) {
53570            return "SNP";
53571          } else {
53572            return "<NON_REF>" === a ? "NONVARIANT" : "OTHER";
53573          }
53574        });
53575        let type = types[0];
53576
53577        for (let t of types) {
53578          if (t !== type) {
53579            return "MIXED";
53580          }
53581        }
53582
53583        return type;
53584      }
53585    }
53586
53587    function arrayToString(value, delim) {
53588      if (delim === undefined) delim = ",";
53589
53590      if (!Array.isArray(value)) {
53591        return value;
53592      }
53593
53594      return value.join(delim);
53595    }
53596    /**
53597     * @deprecated - the GA4GH API has been deprecated.  This code no longer maintained.
53598     * @param json
53599     * @returns {Variant}
53600     */
53601
53602
53603    function createGAVariant(json) {
53604      var variant = new Variant();
53605      variant.chr = json.referenceName;
53606      variant.start = parseInt(json.start); // Might get overriden below
53607
53608      variant.end = parseInt(json.end); // Might get overriden below
53609
53610      variant.pos = variant.start + 1; // GA4GH is 0 based.
53611
53612      variant.names = arrayToString(json.names, "; ");
53613      variant.referenceBases = json.referenceBases;
53614      variant.alternateBases = arrayToString(json.alternateBases);
53615      variant.quality = json.quality;
53616      variant.filter = arrayToString(json.filter); // Flatten GA4GH attributes array
53617
53618      variant.info = {};
53619
53620      if (json.info) {
53621        Object.keys(json.info).forEach(function (key) {
53622          var value,
53623              valueArray = json.info[key];
53624
53625          if (Array.isArray(valueArray)) {
53626            value = valueArray.join(",");
53627          } else {
53628            value = valueArray;
53629          }
53630
53631          variant.info[key] = value;
53632        });
53633      } // Need to build a hash of calls for fast lookup
53634      // Note from the GA4GH spec on call ID:
53635      //
53636      // The ID of the call set this variant call belongs to. If this field is not present,
53637      // the ordering of the call sets from a SearchCallSetsRequest over this GAVariantSet
53638      // is guaranteed to match the ordering of the calls on this GAVariant.
53639      // The number of results will also be the same.
53640
53641
53642      variant.calls = {};
53643      var id;
53644
53645      if (json.calls) {
53646        json.calls.forEach(function (call) {
53647          id = call.callSetId;
53648          variant.calls[id] = call;
53649        });
53650      }
53651
53652      init(variant);
53653      return variant;
53654    }
53655
53656    /*
53657     * The MIT License (MIT)
53658     *
53659     * Copyright (c) 2014 Broad Institute
53660     *
53661     * Permission is hereby granted, free of charge, to any person obtaining a copy
53662     * of this software and associated documentation files (the "Software"), to deal
53663     * in the Software without restriction, including without limitation the rights
53664     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
53665     * copies of the Software, and to permit persons to whom the Software is
53666     * furnished to do so, subject to the following conditions:
53667     *
53668     * The above copyright notice and this permission notice shall be included in
53669     * all copies or substantial portions of the Software.
53670     *
53671     *
53672     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53673     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53674     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53675     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53676     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53677     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53678     * THE SOFTWARE.
53679     */
53680    /**
53681     * Parser for VCF files.
53682     */
53683
53684    class VcfParser {
53685      construtor() {}
53686
53687      async parseHeader(dataWrapper, genome) {
53688        const header = {};
53689        header.chrAliasTable = new Map(); // First line must be file format
53690
53691        let line = await dataWrapper.nextLine();
53692
53693        if (line.startsWith("##fileformat")) {
53694          header.version = line.substr(13);
53695        } else {
53696          throw new Error("Invalid VCF file: missing fileformat line");
53697        }
53698
53699        while ((line = await dataWrapper.nextLine()) !== undefined) {
53700          if (line.startsWith("#")) {
53701            let id;
53702            const values = {};
53703
53704            if (line.startsWith("##")) {
53705              if (line.startsWith("##INFO") || line.startsWith("##FILTER") || line.startsWith("##FORMAT")) {
53706                const ltIdx = line.indexOf("<");
53707                const gtIdx = line.lastIndexOf(">");
53708
53709                if (!(ltIdx > 2 && gtIdx > 0)) {
53710                  console.log("Malformed VCF header line: " + line);
53711                  continue;
53712                }
53713
53714                const type = line.substring(2, ltIdx - 1);
53715                if (!header[type]) header[type] = {}; //##INFO=<ID=AF,Number=A,Type=Float,Description="Allele frequency based on Flow Evaluator observation counts">
53716                // ##FILTER=<ID=NOCALL,Description="Generic filter. Filtering details stored in FR info tag.">
53717                // ##FORMAT=<ID=AF,Number=A,Type=Float,Description="Allele frequency based on Flow Evaluator observation counts">
53718
53719                const tokens = splitStringRespectingQuotes(line.substring(ltIdx + 1, gtIdx - 1), ",");
53720
53721                for (let token of tokens) {
53722                  var kv = token.split("=");
53723
53724                  if (kv.length > 1) {
53725                    if (kv[0] === "ID") {
53726                      id = kv[1];
53727                    } else {
53728                      values[kv[0]] = kv[1];
53729                    }
53730                  }
53731                }
53732
53733                if (id) {
53734                  header[type][id] = values;
53735                }
53736              } else if (line.startsWith("##contig") && genome) {
53737                const idx1 = line.indexOf("<ID=");
53738                let idx2 = line.indexOf(",", idx1);
53739
53740                if (idx2 == -1) {
53741                  idx2 = line.indexOf(">", idx1);
53742                }
53743
53744                const chr = line.substring(idx1 + 4, idx2);
53745                const canonicalChromosome = genome.getChromosomeName(chr);
53746                header.chrAliasTable.set(canonicalChromosome, chr);
53747              } else ;
53748            } else if (line.startsWith("#CHROM")) {
53749              const tokens = line.split("\t");
53750
53751              if (tokens.length > 8) {
53752                // call set names -- use column index for id
53753                header.callSets = [];
53754
53755                for (let j = 9; j < tokens.length; j++) {
53756                  header.callSets.push({
53757                    id: j,
53758                    name: tokens[j]
53759                  });
53760                }
53761              }
53762            }
53763          } else {
53764            break;
53765          }
53766        }
53767
53768        this.header = header; // Will need to intrepret genotypes and info field
53769
53770        return header;
53771      }
53772      /**
53773       * Parse data as a collection of Variant objects.
53774       *
53775       * @param data
53776       * @returns {Array}
53777       */
53778
53779
53780      async parseFeatures(dataWrapper) {
53781        const allFeatures = [];
53782        const callSets = this.header.callSets;
53783        const nExpectedColumns = 8 + (callSets ? callSets.length + 1 : 0);
53784        let line;
53785
53786        while ((line = await dataWrapper.nextLine()) !== undefined) {
53787          if (line && !line.startsWith("#")) {
53788            const tokens = line.split("\t");
53789
53790            if (tokens.length === nExpectedColumns) {
53791              const variant = createVCFVariant(tokens);
53792              variant.header = this.header; // Keep a pointer to the header to interpret fields for popup text
53793
53794              allFeatures.push(variant);
53795
53796              if (tokens.length > 9) {
53797                // Format
53798                const callFields = extractCallFields(tokens[8].split(":"));
53799                variant.calls = {};
53800
53801                for (let index = 9; index < tokens.length; index++) {
53802                  const token = tokens[index];
53803                  const callSet = callSets[index - 9];
53804                  const call = {
53805                    callSetName: callSet.name,
53806                    info: {}
53807                  };
53808                  variant.calls[callSet.id] = call;
53809                  token.split(":").forEach(function (callToken, idx) {
53810                    switch (idx) {
53811                      case callFields.genotypeIndex:
53812                        call.genotype = [];
53813                        callToken.split(/[\|\/]/).forEach(function (s) {
53814                          call.genotype.push('.' === s ? s : parseInt(s));
53815                        });
53816                        break;
53817
53818                      default:
53819                        call.info[callFields.fields[idx]] = callToken;
53820                    }
53821                  });
53822                }
53823              }
53824
53825              if (variant.info && variant.info.CHR2 && variant.info.END) {
53826                allFeatures.push(svComplement(variant));
53827              }
53828            }
53829          }
53830        }
53831
53832        return allFeatures;
53833      }
53834
53835    }
53836
53837    function extractCallFields(tokens) {
53838      const callFields = {
53839        genotypeIndex: -1,
53840        fields: tokens
53841      };
53842
53843      for (let i = 0; i < tokens.length; i++) {
53844        if ("GT" === tokens[i]) {
53845          callFields.genotypeIndex = i;
53846        }
53847      }
53848
53849      return callFields;
53850    }
53851
53852    function svComplement(v) {
53853      const chr2 = v.info.CHR2;
53854      const pos2 = Number.parseInt(v.info.END);
53855      return {
53856        chr: chr2,
53857        start: pos2 - 1,
53858        end: pos2,
53859        _f: v
53860      };
53861    }
53862
53863    /**
53864     * Parser for IGV desktop GWAS files.  See http://software.broadinstitute.org/software/igv/GWAS
53865     */
53866    class GWASParser {
53867      constructor(config) {
53868        // Defaults - can be overriden by header
53869        this.config = config;
53870
53871        if (config.columns) {
53872          if (config.columns.chromosome === undefined || config.columns.position === undefined || config.columns.value === undefined) {
53873            throw Error("columns property must define chrCol, posCol, and valueCol");
53874          }
53875
53876          this.posCol = config.columns.position - 1;
53877          this.chrCol = config.columns.chromosome - 1;
53878          this.pvalueCol = config.columns.value - 1;
53879        } else {
53880          // Defaults -- can be overriden in header
53881          this.posCol = 2;
53882          this.chrCol = 1;
53883          this.pvalueCol = 3;
53884        }
53885      }
53886
53887      async parseHeader(dataWrapper) {
53888        const headerLine = await dataWrapper.nextLine();
53889        return this.parseHeaderLine(headerLine);
53890      }
53891
53892      parseHeaderLine(headerLine) {
53893        this.columns = headerLine.split(/\t/);
53894
53895        if (!this.config.columns) {
53896          for (let i = 0; i < this.columns.length; i++) {
53897            const c = this.columns[i].toLowerCase();
53898
53899            switch (c) {
53900              case 'chr':
53901              case 'chromosome':
53902              case 'chr_id':
53903                this.chrCol = i;
53904                break;
53905
53906              case 'bp':
53907              case 'pos':
53908              case 'position':
53909              case 'chr_pos':
53910                this.posCol = i;
53911                break;
53912
53913              case 'p':
53914              case 'pval':
53915              case 'pvalue':
53916              case 'p-value':
53917              case 'p.value':
53918                this.valueCol = i;
53919                break;
53920            }
53921          }
53922        }
53923
53924        return this.columns;
53925      }
53926
53927      async parseFeatures(dataWrapper) {
53928        const allFeatures = [];
53929        const headerLine = dataWrapper.nextLine();
53930
53931        if (!this.columns) {
53932          this.parseHeaderLine(headerLine);
53933        }
53934
53935        let line;
53936
53937        while ((line = dataWrapper.nextLine()) !== undefined) {
53938          const tokens = line.split(/\t/);
53939
53940          if (tokens.length === this.columns.length) {
53941            const chr = tokens[this.chrCol];
53942            const start = parseInt(tokens[this.posCol]) - 1;
53943            const end = start + 1;
53944            const value = Number(tokens[this.valueCol]);
53945            allFeatures.push(new GWASFeature({
53946              chr: chr,
53947              start: start,
53948              end: end,
53949              value: value,
53950              line: line,
53951              columns: this.columns
53952            }));
53953          }
53954        }
53955
53956        return allFeatures;
53957      }
53958
53959    }
53960
53961    class GWASFeature {
53962      constructor(_ref) {
53963        let {
53964          chr,
53965          start,
53966          end,
53967          value,
53968          line,
53969          columns
53970        } = _ref;
53971        this.chr = chr;
53972        this.start = start;
53973        this.end = end;
53974        this.value = value;
53975        this.line = line;
53976        this.columns = columns;
53977      }
53978
53979      popupData() {
53980        const tokens = this.line.split(/\t/);
53981        return this.columns.map(function (c, index) {
53982          return {
53983            name: c,
53984            value: tokens[index]
53985          };
53986        });
53987      }
53988
53989      getAttribute(attrName) {
53990        const tokens = this.line.split(/\t/);
53991
53992        for (let i = 0; i < this.columns.length; i++) {
53993          if (this.columns[i] === attrName) {
53994            return tokens[i];
53995          }
53996        }
53997
53998        return undefined;
53999      }
54000
54001    }
54002
54003    /*
54004     * The MIT License (MIT)
54005     *
54006     * Copyright (c) 2014 Broad Institute
54007     *
54008     * Permission is hereby granted, free of charge, to any person obtaining a copy
54009     * of this software and associated documentation files (the "Software"), to deal
54010     * in the Software without restriction, including without limitation the rights
54011     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
54012     * copies of the Software, and to permit persons to whom the Software is
54013     * furnished to do so, subject to the following conditions:
54014     *
54015     * The above copyright notice and this permission notice shall be included in
54016     * all copies or substantial portions of the Software.
54017     *
54018     *
54019     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54020     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54021     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
54022     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54023     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54024     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
54025     * THE SOFTWARE.
54026     */
54027    /**
54028     *  Define parsers for bed-like files  (.bed, .gff, .vcf, etc).  A parser should implement 2 methods
54029     *
54030     *     parseHeader(data) - return an object representing a header or metadata.  Details are format specific
54031     *
54032     *     parseFeatures(data) - return an array of features
54033     *
54034     */
54035
54036    var aedRegexpNoNamespace = new RegExp("([^:]*)\\(([^)]*)\\)"); // name(type) for AED parsing (namespace undefined)
54037
54038    var aedRegexpNamespace = new RegExp("([^:]*):([^(]*)\\(([^)]*)\\)"); // namespace:name(type) for AED parsing
54039
54040    class AEDParser {
54041      constructor(config) {
54042        const decode = config ? config.decode : undefined;
54043        this.nameField = config ? config.nameField : undefined;
54044        this.skipRows = 0; // The number of fixed header rows to skip.  Override for specific types as needed
54045
54046        if (decode) {
54047          this.decode = decode;
54048        } else {
54049          this.decode = decodeAed;
54050        }
54051
54052        this.delimiter = "\t";
54053      }
54054
54055      async parseHeader(dataWrapper) {
54056        let line;
54057        let header;
54058
54059        while (line = await dataWrapper.nextLine()) {
54060          if (line.startsWith("track") || line.startsWith("#") || line.startsWith("browser")) {
54061            if (line.startsWith("track") || line.startsWith("#track")) {
54062              let h = parseTrackLine(line);
54063
54064              if (header) {
54065                Object.assign(header, h);
54066              } else {
54067                header = h;
54068              }
54069            } else if (line.startsWith("#columns")) {
54070              let h = parseColumnsDirective(line);
54071
54072              if (header) {
54073                Object.assign(header, h);
54074              } else {
54075                header = h;
54076              }
54077            } else if (line.startsWith("##gff-version 3")) {
54078              this.format = "gff3";
54079              if (!header) header = {};
54080              header["format"] = "gff3";
54081            }
54082          } else {
54083            break;
54084          }
54085        }
54086
54087        this.header = header; // Directives might be needed for parsing lines
54088
54089        return header;
54090      }
54091
54092      async parseFeatures(dataWrapper) {
54093        const allFeatures = [];
54094        const decode = this.decode;
54095        const delimiter = this.delimiter || "\t";
54096        let i = 0;
54097        let line;
54098        let wig;
54099
54100        while ((line = dataWrapper.nextLine()) !== undefined) {
54101          i++;
54102
54103          if (i <= this.skipRows || line.startsWith("track") || line.startsWith("#") || line.startsWith("browser")) {
54104            continue;
54105          }
54106
54107          let tokens = readTokensAed();
54108
54109          if (tokens.length < 1) {
54110            continue;
54111          }
54112
54113          if (!this.aed) {
54114            // Store information about the aed header in the parser itself
54115            // This is done only once - on the first row
54116            this.aed = parseAedHeaderRow(tokens);
54117            continue;
54118          }
54119
54120          const feature = decode.call(this, tokens, wig);
54121
54122          if (feature) {
54123            allFeatures.push(feature);
54124          }
54125        }
54126
54127        return allFeatures; // Double quoted strings can contain newlines in AED
54128        // "" is an escape for a ".
54129        // Parse all this, clean it up, split into tokens in a custom way
54130
54131        function readTokensAed() {
54132          var tokens = [],
54133              token = "",
54134              quotedString = false,
54135              n,
54136              c;
54137
54138          while (line || line === '') {
54139            for (n = 0; n < line.length; n++) {
54140              c = line.charAt(n);
54141
54142              if (c === delimiter) {
54143                if (!quotedString) {
54144                  tokens.push(token);
54145                  token = "";
54146                } else {
54147                  token += c;
54148                }
54149              } else if (c === "\"") {
54150                // Look ahead to the next character
54151                if (n + 1 < line.length && line.charAt(n + 1) === "\"") {
54152                  if (quotedString) {
54153                    // Turn "" into a single " in the output string
54154                    token += "\"";
54155                  } // Skip the next double quote
54156
54157
54158                  n++;
54159                } else {
54160                  // We know the next character is NOT a double quote, flip our state
54161                  quotedString = !quotedString;
54162                }
54163              } else {
54164                token += c;
54165              }
54166            } // We are at the end of the line
54167
54168
54169            if (quotedString) {
54170              token += '\n'; // Add newline to the token
54171
54172              line = nextLine(); // Keep going
54173            } else {
54174              // We can end the loop
54175              break;
54176            }
54177          } // Push the last token
54178
54179
54180          tokens.push(token);
54181          return tokens;
54182        }
54183      }
54184
54185    }
54186
54187    function parseAedToken(value) {
54188      // Example: refseq:accessionNumber(aed:String)
54189      // refseq - namespace, will be declared later
54190      // accessionNumber - name of the field
54191      // aed:String - type of the field
54192      // The namespace part may be missing
54193      var match = aedRegexpNamespace.exec(value);
54194
54195      if (match) {
54196        return {
54197          namespace: match[1],
54198          name: match[2],
54199          type: match[3]
54200        };
54201      }
54202
54203      match = aedRegexpNoNamespace.exec(value);
54204
54205      if (match) {
54206        return {
54207          namespace: '?',
54208          name: match[1],
54209          type: match[2]
54210        };
54211      } else {
54212        throw new Error("Error parsing the header row of AED file - column not in ns:name(ns:type) format");
54213      }
54214    }
54215
54216    function parseAedHeaderRow(tokens) {
54217      // First row of AED file defines column names
54218      // Each header item is an aed token - see parseAedToken
54219      var aed, k, token, aedToken; // Initialize aed section to be filled in
54220
54221      aed = {
54222        columns: [// Information about the namespace, name and type of each column
54223          // Example entry:
54224          // { namespace: 'bio', name: 'start', type: 'aed:Integer' }
54225        ],
54226        metadata: {// Metadata about the entire AED file
54227          // Example:
54228          // {
54229          //    aed: {
54230          //       application: { value: "CHaS Browser 3.3.0.139 (r10838)", type: "aed:String" },
54231          //       created: { value: "2018-01-02T10:20:30.123+01:00", type: "aed:DateTime" },
54232          //       modified: { value: "2018-03-04T11:22:33.456+01:00", type: "aed:DateTime" },
54233          //    }
54234          //    affx: {
54235          //       ucscGenomeVersion: { value: "hg19", type: "aed:String" }
54236          //    },
54237          //    namespace: {
54238          //       omim: { value: "http://affymetrix.com/ontology/www.ncbi.nlm.nih.gov/omim/", type: "aed:URI" },
54239          //       affx: { value: "http://affymetrix.com/ontology/", type: "aed:URI" },
54240          //       refseq: { value: "http://affymetrix.com/ontology/www.ncbi.nlm.nih.gov/RefSeq/", type: "aed:URI" }
54241          //    }
54242          // }
54243        }
54244      };
54245
54246      for (k = 0; k < tokens.length; k++) {
54247        token = tokens[k];
54248        aedToken = parseAedToken(token);
54249        aed.columns.push(aedToken);
54250      }
54251
54252      return aed;
54253    }
54254
54255    function parseTrackLine(line) {
54256      const properties = {};
54257      const tokens = line.split(/(?:")([^"]+)(?:")|([^\s"]+)(?=\s+|$)/g); // Clean up tokens array
54258
54259      let curr;
54260      const tmp = [];
54261
54262      for (let tk of tokens) {
54263        if (!tk || tk.trim().length === 0) continue;
54264
54265        if (tk.endsWith("=") > 0) {
54266          curr = tk;
54267        } else if (curr) {
54268          tmp.push(curr + tk);
54269          curr = undefined;
54270        } else {
54271          tmp.push(tk);
54272        }
54273      }
54274
54275      for (let str of tmp) {
54276        if (!str) return;
54277        var kv = str.split('=', 2);
54278
54279        if (kv.length === 2) {
54280          const key = kv[0].trim();
54281          const value = kv[1].trim();
54282          properties[key] = value;
54283        }
54284      }
54285
54286      return properties;
54287    }
54288
54289    function parseColumnsDirective(line) {
54290      let properties = {};
54291      let t1 = line.split(/\s+/);
54292
54293      if (t1.length === 2) {
54294        let t2 = t1[1].split(";");
54295        t2.forEach(function (keyValue) {
54296          let t = keyValue.split("=");
54297
54298          if (t[0] === "color") {
54299            properties.colorColumn = Number.parseInt(t[1]) - 1;
54300          } else if (t[0] === "thickness") {
54301            properties.thicknessColumn = Number.parseInt(t[1]) - 1;
54302          }
54303        });
54304      }
54305
54306      return properties;
54307    }
54308    /**
54309     * AED file feature.
54310     *
54311     * @param aed link to the AED file object containing file-level metadata and column descriptors
54312     * @param allColumns All columns as parsed from the AED
54313     *
54314     * Other values are parsed one by one
54315     */
54316
54317
54318    function AedFeature(aed, allColumns) {
54319      var token,
54320          aedColumn,
54321          aedColumns = aed.columns; // Link to AED file (for metadata)
54322
54323      this.aed = aed; // Unparsed columns from AED file
54324
54325      this.allColumns = allColumns; // Prepare space for the parsed values
54326
54327      this.chr = null;
54328      this.start = null;
54329      this.end = null;
54330      this.score = 1000;
54331      this.strand = '.';
54332      this.cdStart = null;
54333      this.cdEnd = null;
54334      this.name = null;
54335      this.color = null;
54336
54337      for (let i = 0; i < allColumns.length; i++) {
54338        token = allColumns[i];
54339
54340        if (!token) {
54341          // Skip empty fields
54342          continue;
54343        }
54344
54345        aedColumn = aedColumns[i];
54346
54347        if (aedColumn.type === 'aed:Integer') {
54348          token = parseInt(token);
54349        }
54350
54351        var arr = [];
54352
54353        if (aedColumn.namespace.length > 0) {
54354          for (let j = 0; j < aedColumn.namespace.length; j++) {
54355            arr.push(aedColumn.namespace.charCodeAt(j));
54356          }
54357        }
54358
54359        if (aedColumn.namespace.trim() === 'bio') {
54360          if (aedColumn.name === 'sequence') {
54361            this.chr = token;
54362          } else if (aedColumn.name === 'start') {
54363            this.start = token;
54364          } else if (aedColumn.name === 'end') {
54365            this.end = token;
54366          } else if (aedColumn.name === 'cdsMin') {
54367            this.cdStart = token;
54368          } else if (aedColumn.name === 'cdsMax') {
54369            this.cdEnd = token;
54370          } else if (aedColumn.name === 'strand') {
54371            this.strand = token;
54372          }
54373        } else if (aedColumn.namespace === 'aed') {
54374          if (aedColumn.name === 'name') {
54375            this.name = token;
54376          }
54377        } else if (aedColumn.namespace === 'style') {
54378          if (aedColumn.name === 'color') {
54379            this.color = IGVColor.createColorString(token);
54380          }
54381        }
54382      }
54383    }
54384
54385    AedFeature.prototype.popupData = function () {
54386      var data = [],
54387          aed = this.aed; // Just dump everything we have for now
54388
54389      for (var i = 0; i < this.allColumns.length; i++) {
54390        var featureValue = this.allColumns[i];
54391        var name = aed.columns[i].name; // Skip columns that are not interesting - you know the sequence, and you can see color
54392
54393        if (name !== 'sequence' && name !== 'color') {
54394          if (featureValue) {
54395            data.push({
54396              name: name,
54397              value: featureValue
54398            });
54399          }
54400        }
54401      }
54402
54403      return data;
54404    };
54405    /**
54406     * Decode the AED file format
54407     * @param tokens
54408     * @param ignore
54409     * @returns decoded feature, or null if this is not a valid record
54410     */
54411
54412
54413    function decodeAed(tokens, ignore) {
54414      var name,
54415          value,
54416          token,
54417          nonEmptyTokens = 0,
54418          aedColumns = this.aed.columns,
54419          aedColumn,
54420          aedKey,
54421          i; // Each aed row must match the exact number of columns or we skip it
54422
54423      if (tokens.length !== aedColumns.length) {
54424        console.log('Corrupted AED file row: ' + tokens.join(','));
54425        return undefined;
54426      }
54427
54428      for (i = 0; i < tokens.length; i++) {
54429        aedColumn = aedColumns[i];
54430        token = tokens[i];
54431
54432        if (token !== '') {
54433          nonEmptyTokens++;
54434        }
54435
54436        if (aedColumn.name === 'name' && aedColumn.namespace === 'aed') {
54437          name = token;
54438        } else if (aedColumn.name === 'value' && aedColumn.namespace === 'aed') {
54439          value = token;
54440        }
54441      }
54442
54443      if (nonEmptyTokens === 2 && name && value) {
54444        // Special row that defines metadata for the entire file
54445        aedKey = parseAedToken(name); // Store in the metadata section
54446
54447        if (!this.aed.metadata[aedKey.namespace]) {
54448          this.aed.metadata[aedKey.namespace] = {};
54449        }
54450
54451        if (!this.aed.metadata[aedKey.namespace][aedKey.name]) {
54452          this.aed.metadata[aedKey.namespace][aedKey.name] = {
54453            type: aedKey.type,
54454            value: value
54455          };
54456        } // Ignore this value
54457
54458
54459        return undefined;
54460      }
54461
54462      var feature = new AedFeature(this.aed, tokens);
54463
54464      if (!feature.chr || !feature.start && feature.start !== 0 || !feature.end
54464) {
54465        console.log('Cannot parse feature: ' + tokens.join(','));
54466        return undefined;
54467      }
54468
54469      return feature;
54470    }
54471
54472    /*
54473     * The MIT License (MIT)
54474     *
54475     * Copyright (c) 2016-2017 The Regents of the University of California
54476     * Author: Jim Robinson
54477     *
54478     * Permission is hereby granted, free of charge, to any person obtaining a copy
54479     * of this software and associated documentation files (the "Software"), to deal
54480     * in the Software without restriction, including without limitation the rights
54481     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
54482     * copies of the Software, and to permit persons to whom the Software is
54483     * furnished to do so, subject to the following conditions:
54484     *
54485     * The above copyright notice and this permission notice shall be included in
54486     * all copies or substantial portions of the Software.
54487     *
54488     *
54489     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54490     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54491     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
54492     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54493     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54494     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
54495     * THE SOFTWARE.
54496     */
54497    function getDataWrapper(data) {
54498      if (typeof data == 'string' || data instanceof String) {
54499        return new StringDataWrapper(data);
54500      } else {
54501        return new ByteArrayDataWrapper(data);
54502      }
54503    } // Data might be a string, or an UInt8Array
54504
54505
54506    class StringDataWrapper {
54507      constructor(string) {
54508        this.data = string;
54509        this.ptr = 0;
54510      }
54511
54512      nextLine() {
54513        var start = this.ptr,
54514            idx = this.data.indexOf('\n', start),
54515            data = this.data;
54516
54517        if (idx > 0) {
54518          this.ptr = idx + 1; // Advance pointer for next line
54519
54520          if (idx > start && data.charAt(idx - 1) === '\r') {
54521            // Trim CR manually in CR/LF sequence
54522            return data.substring(start, idx - 1);
54523          }
54524
54525          return data.substring(start, idx);
54526        } else {
54527          var length = data.length;
54528          this.ptr = length; // Return undefined only at the very end of the data
54529
54530          return start >= length ? undefined : data.substring(start);
54531        }
54532      }
54533
54534    }
54535
54536    class ByteArrayDataWrapper {
54537      constructor(array) {
54538        this.data = array;
54539        this.length = this.data.length;
54540        this.ptr = 0;
54541      }
54542
54543      nextLine() {
54544        var c, result;
54545        result = "";
54546        if (this.ptr >= this.length) return undefined;
54547
54548        for (var i = this.ptr; i < this.length; i++) {
54549          c = String.fromCharCode(this.data[i]);
54550          if (c === '\r') continue;
54551          if (c === '\n') break;
54552          result = result + c;
54553        }
54554
54555        this.ptr = i + 1;
54556        return result;
54557      }
54558
54559    }
54560
54561    class BGZipLineReader {
54562      constructor(config) {
54563        this.config = config;
54564        this.filePtr = 0;
54565        this.bufferPtr = 0;
54566        this.buffer;
54567      }
54568
54569      async nextLine() {
54570        let result = undefined;
54571
54572        try {
54573          while (true) {
54574            const length = this.buffer ? this.buffer.length : 0;
54575
54576            while (this.bufferPtr < length) {
54577              const c = String.fromCharCode(this.buffer[this.bufferPtr++]);
54578              if (c === '\r') continue;
54579
54580              if (c === '\n') {
54581                return result;
54582              }
54583
54584              result = result ? result + c : c;
54585            }
54586
54587            if (this.eof) {
54588              return result;
54589            } else {
54590              await this.readNextBlock();
54591            }
54592          }
54593        } catch (e) {
54594          console.warn(e);
54595          this.eof = true;
54596          return result;
54597        }
54598      }
54599
54600      async readNextBlock() {
54601        const bsizeOptions = buildOptions(this.config, {
54602          range: {
54603            start: this.filePtr,
54604            size: 26
54605          }
54606        });
54607        const abuffer = await igvxhr.loadArrayBuffer(this.config.url, bsizeOptions);
54608        const bufferSize = bgzBlockSize(abuffer); //console.log(`next block ${this.filePtr}  ${bufferSize}`);
54609
54610        if (bufferSize === 0) {
54611          this.eof = true;
54612          this.buffer = undefined;
54613        } else {
54614          const options = buildOptions(this.config, {
54615            range: {
54616              start: this.filePtr,
54617              size: bufferSize
54618            }
54619          });
54620          const data = await igvxhr.loadArrayBuffer(this.config.url, options);
54621
54622          if (data.byteLength < bufferSize) {
54623            this.eof = true; // Assumption
54624          }
54625
54626          this.buffer = unbgzf(data);
54627          this.bufferPtr = 0;
54628          this.filePtr += data.byteLength; //data.byteLength;
54629        }
54630      }
54631
54632    }
54633
54634    /*
54635     * The MIT License (MIT)
54636     *
54637     * Copyright (c) 2014 Broad Institute
54638     *
54639     * Permission is hereby granted, free of charge, to any person obtaining a copy
54640     * of this software and associated documentation files (the "Software"), to deal
54641     * in the Software without restriction, including without limitation the rights
54642     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
54643     * copies of the Software, and to permit persons to whom the Software is
54644     * furnished to do so, subject to the following conditions:
54645     *
54646     * The above copyright notice and this permission notice shall be included in
54647     * all copies or substantial portions of the Software.
54648     *
54649     *
54650     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54651     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54652     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
54653     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54654     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54655     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
54656     * THE SOFTWARE.
54657     */
54658    /**
54659     * Reader for "bed like" files (tab delimited files with 1 feature per line: bed, gff, vcf, etc)
54660     *
54661     * @param config
54662     * @constructor
54663     */
54664
54665    class FeatureFileReader {
54666      constructor(config, genome) {
54667        var uriParts;
54668        this.config = config || {};
54669        this.genome = genome;
54670        this.indexURL = config.indexURL;
54671        this.indexed = config.indexed;
54672
54673        if (isFile(this.config.url)) {
54674          this.filename = this.config.url.name;
54675        } else if (isDataURL(this.config.url)) {
54676          this.indexed = false; // by definition
54677
54678          this.dataURI = config.url;
54679        } else {
54680          uriParts = parseUri(this.config.url);
54681          this.filename = config.filename || uriParts.file;
54682        }
54683
54684        this.parser = this.getParser(this.config);
54685
54686        if (this.config.format === "vcf" && !this.config.indexURL) {
54687          console.warn("Warning: index file not specified.  The entire vcf file will be loaded.");
54688        }
54689      }
54690
54691      async defaultVisibilityWindow() {
54692        if (this.config.indexURL) {
54693          const index = await this.getIndex();
54694
54695          if (index && index.lastBlockPosition) {
54696            let gl = 0;
54697            const s = 10000;
54698
54699            for (let c of index.chromosomeNames) {
54700              const chromosome = this.genome.getChromosome(c);
54701
54702              if (chromosome) {
54703                gl += chromosome.bpLength;
54704              }
54705            }
54706
54707            return Math.round(gl / index.lastBlockPosition * s);
54708          }
54709        }
54710      }
54711      /**
54712       * Return a promise to load features for the genomic interval
54713       * @param chr
54714       * @param start
54715       * @param end
54716       */
54717
54718
54719      async readFeatures(chr, start, end) {
54720        const index = await this.getIndex();
54721
54722        if (index) {
54723          this.indexed = true;
54724          return this.loadFeaturesWithIndex(chr, start, end);
54725        } else if (this.dataURI) {
54726          this.indexed = false;
54727          return this.loadFeaturesFromDataURI();
54728        } else {
54729          this.indexed = false;
54730          return this.loadFeaturesNoIndex();
54731        }
54732      }
54733
54734      async readHeader() {
54735        if (this.dataURI) {
54736          await this.loadFeaturesFromDataURI(this.dataURI);
54737          return this.header;
54738        } else {
54739          if (this.config.indexURL) {
54740            const index = await this.getIndex();
54741
54742            if (!index) {
54743              // Note - it should be impossible to get here
54744              throw new Error("Unable to load index: " + this.config.indexURL);
54745            }
54746
54747            let dataWrapper;
54748
54749            if (index.tabix) {
54750              dataWrapper = new BGZipLineReader(this.config);
54751            } else {
54752              // Tribble
54753              const maxSize = Object.values(index.chrIndex).flatMap(chr => chr.blocks).map(block => block.max).reduce((previous, current) => Math.min(previous, current), Number.MAX_SAFE_INTEGER);
54754              const options = buildOptions(this.config, {
54755                bgz: index.tabix,
54756                range: {
54757                  start: 0,
54758                  size: maxSize
54759                }
54760              });
54761              const data = await igvxhr.loadString(this.config.url, options);
54762              dataWrapper = getDataWrapper(data);
54763            }
54764
54765            this.header = await this.parser.parseHeader(dataWrapper); // Cache header, might be needed to parse features
54766
54767            return this.header;
54768          } else {
54769            // If this is a non-indexed file we will load all features in advance
54770            const options = buildOptions(this.config);
54771            const data = await igvxhr.loadString(this.config.url, options);
54772            let dataWrapper = getDataWrapper(data);
54773            this.header = await this.parser.parseHeader(dataWrapper); // Reset data wrapper and parse features
54774
54775            dataWrapper = getDataWrapper(data);
54776            this.features = await this.parser.parseFeatures(dataWrapper); // cache features
54777
54778            return this.header;
54779          }
54780        }
54781      }
54782
54783      getParser(config) {
54784        switch (config.format) {
54785          case "vcf":
54786            return new VcfParser(config);
54787
54788          case "seg":
54789            return new SegParser("seg");
54790
54791          case "mut":
54792            return new SegParser("mut");
54793
54794          case "maf":
54795            return new SegParser("maf");
54796
54797          case "gwas":
54798            return new GWASParser(config);
54799
54800          case "aed":
54801            return new AEDParser(config);
54802
54803          default:
54804            return new FeatureParser(config);
54805        }
54806      }
54807
54808      async loadFeaturesNoIndex() {
54809        if (this.features) {
54810          // An optimization hack for non-indexed files, features are temporarily cached when header is read.
54811          const tmp = this.features;
54812          delete this.features;
54813          return tmp;
54814        } else {
54815          const options = buildOptions(this.config); // Add oauth token, if any
54816
54817          const data = await igvxhr.loadString(this.config.url, options);
54818
54819          if (!this.header) {
54820            const dataWrapper = getDataWrapper(data);
54821            this.header = await this.parser.parseHeader(dataWrapper);
54822          }
54823
54824          const dataWrapper = getDataWrapper(data);
54825          const features = await this.parser.parseFeatures(dataWrapper); // <= PARSING DONE HERE
54826
54827          return features;
54828        }
54829      }
54830
54831      async loadFeaturesWithIndex(chr, start, end) {
54832        //console.log("Using index"
54833        const config = this.config;
54834        const parser = this.parser;
54835        const tabix = this.index.tabix;
54836        const refId = tabix ? this.index.sequenceIndexMap[chr] : chr;
54837
54838        if (refId === undefined) {
54839          return [];
54840        }
54841
54842        const genome = this.genome;
54843        const blocks = this.index.blocksForRange(refId, start, end);
54844
54845        if (!blocks || blocks.length === 0) {
54846          return [];
54847        } else {
54848          const allFeatures = [];
54849
54850          for (let block of blocks) {
54851            const startPos = block.minv.block;
54852            const startOffset = block.minv.offset;
54853            const endOffset = block.maxv.offset;
54854            let endPos;
54855
54856            if (tabix) {
54857              let lastBlockSize = 0;
54858
54859              if (endOffset > 0) {
54860                const bsizeOptions = buildOptions(config, {
54861                  range: {
54862                    start: block.maxv.block,
54863                    size: 26
54864                  }
54865                });
54866                const abuffer = await igvxhr.loadArrayBuffer(config.url, bsizeOptions);
54867                lastBlockSize = bgzBlockSize(abuffer);
54868              }
54869
54870              endPos = block.maxv.block + lastBlockSize;
54871            } else {
54872              endPos = block.maxv.block;
54873            }
54874
54875            const options = buildOptions(config, {
54876              range: {
54877                start: startPos,
54878                size: endPos - startPos + 1
54879              }
54880            });
54881            let inflated;
54882
54883            if (tabix) {
54884              const data = await igvxhr.loadArrayBuffer(config.url, options);
54885              inflated = unbgzf(data);
54886            } else {
54887              inflated = await igvxhr.loadString(config.url, options);
54888            }
54889
54890            const slicedData = startOffset ? inflated.slice(startOffset) : inflated;
54891            const dataWrapper = getDataWrapper(slicedData);
54892            let slicedFeatures = await parser.parseFeatures(dataWrapper); // Filter psuedo-features (e.g. created mates for VCF SV records)
54893
54894            slicedFeatures = slicedFeatures.filter(f => f._f === undefined); // Filter features not in requested range.
54895
54896            let inInterval = false;
54897
54898            for (let i = 0; i < slicedFeatures.length; i++) {
54899              const f = slicedFeatures[i];
54900              const canonicalChromosome = genome ? genome.getChromosomeName(f.chr) : f.chr;
54901
54902              if (canonicalChromosome !== chr) {
54903                if (allFeatures.length === 0) {
54904                  continue; //adjacent chr to the left
54905                } else {
54906                  break; //adjacent chr to the right
54907                }
54908              }
54909
54910              if (f.start > end) {
54911                allFeatures.push(f); // First feature beyond interval
54912
54913                break;
54914              }
54915
54916              if (f.end >= start && f.start <= end) {
54917                if (!inInterval) {
54918                  inInterval = true;
54919
54920                  if (i > 0) {
54921                    allFeatures.push(slicedFeatures[i - 1]);
54922                  }
54923                }
54924
54925                allFeatures.push(f);
54926              }
54927            }
54928          }
54929
54930          allFeatures.sort(function (a, b) {
54931            return a.start - b.start;
54932          });
54933          return allFeatures;
54934        }
54935      }
54936
54937      async getIndex() {
54938        if (this.index) {
54939          return this.index;
54940        } else if (this.config.indexURL) {
54941          this.index = await this.loadIndex();
54942          return this.index;
54943        }
54944      }
54945      /**
54946       * Return a Promise for the async loaded index
54947       */
54948
54949
54950      async loadIndex() {
54951        const indexURL = this.config.indexURL;
54952        return loadIndex(indexURL, this.config, this.genome);
54953      }
54954
54955      async loadFeaturesFromDataURI() {
54956        if (this.features) {
54957          // An optimization hack for non-indexed files, features are temporarily cached when header is read.
54958          const tmp = this.features;
54959          delete this.features;
54960          return tmp;
54961        } else {
54962          const plain = decodeDataURI$1(this.dataURI);
54963          let dataWrapper = getDataWrapper(plain);
54964          this.header = await this.parser.parseHeader(dataWrapper);
54965
54966          if (this.header instanceof String && this.header.startsWith("##gff-version 3")) {
54967            this.format = 'gff3';
54968          }
54969
54970          dataWrapper = getDataWrapper(plain);
54971          this.features = await this.parser.parseFeatures(dataWrapper);
54972          return this.features;
54973        }
54974      }
54975
54976    }
54977
54978    /*
54979     * The MIT License (MIT)
54980     *
54981     * Copyright (c) 2016 University of California San Diego
54982     * Author: Jim Robinson
54983     *
54984     * Permission is hereby granted, free of charge, to any person obtaining a copy
54985     * of this software and associated documentation files (the "Software"), to deal
54986     * in the Software without restriction, including without limitation the rights
54987     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
54988     * copies of the Software, and to permit persons to whom the Software is
54989     * furnished to do so, subject to the following conditions:
54990     *
54991     * The above copyright notice and this permission notice shall be included in
54992     * all copies or substantial portions of the Software.
54993     *
54994     *
54995     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
54996     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54997     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
54998     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54999     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55000     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55001     * THE SOFTWARE.
55002     */
55003    const isString$1 = isString$3;
55004
55005    class CustomServiceReader {
55006      constructor(config) {
55007        this.config = config;
55008      }
55009
55010      async readFeatures(chr, start, end) {
55011        let url;
55012
55013        if (typeof this.config.url === 'function') {
55014          url = this.config.url({
55015            chr,
55016            start,
55017            end
55018          });
55019        } else {
55020          url = this.config.url.replace("$CHR", chr).replace("$START", start).replace("$END", end);
55021        }
55022
55023        let config = Object.assign({}, this.config);
55024
55025        if (this.config.body !== undefined) {
55026          if (typeof this.config.body === 'function') {
55027            config.body = this.config.body({
55028              chr,
55029              start,
55030              end
55031            });
55032          } else {
55033            config.body = this.config.body.replace("$CHR", chr).replace("$START", start).replace("$END", end);
55034          }
55035        }
55036
55037        let features;
55038        const data = await igvxhr.load(url, config);
55039
55040        if (data) {
55041          if (typeof this.config.parser === "function") {
55042            features = this.config.parser(data);
55043          } else if (isString$1(data)) {
55044            features = JSON.parse(data);
55045          } else {
55046            features = data;
55047          }
55048        }
55049
55050        if (this.config.mappings) {
55051          let mappingKeys = Object.keys(this.config.mappings);
55052
55053          for (let f of features) {
55054            for (let key of mappingKeys) {
55055              f[key] = f[this.config.mappings[key]];
55056            }
55057          }
55058        }
55059
55060        return features;
55061      }
55062
55063    }
55064
55065    /*
55066     * The MIT License (MIT)
55067     *
55068     * Copyright (c) 2016-2017 The Regents of the University of California
55069     * Author: Jim Robinson
55070     *
55071     * Permission is hereby granted, free of charge, to any person obtaining a copy
55072     * of this software and associated documentation files (the "Software"), to deal
55073     * in the Software without restriction, including without limitation the rights
55074     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55075     * copies of the Software, and to permit persons to whom the Software is
55076     * furnished to do so, subject to the following conditions:
55077     *
55078     * The above copyright notice and this permission notice shall be included in
55079     * all copies or substantial portions of the Software.
55080     *
55081     *
55082     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55083     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55084     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55085     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55086     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55087     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55088     * THE SOFTWARE.
55089     */
55090
55091    const UCSCServiceReader = function (config, genome) {
55092      this.config = config;
55093      this.genome = genome;
55094      this.expandQueryInterval = false;
55095    };
55096
55097    UCSCServiceReader.prototype.readFeatures = function (chr, start, end) {
55098      const s = Math.max(0, Math.floor(start));
55099      let e = Math.ceil(end);
55100
55101      if (this.genome) {
55102        const c = this.genome.getChromosome(chr);
55103
55104        if (c && e > c.bpLength) {
55105          e = c.bpLength;
55106        }
55107      }
55108
55109      const url = this.config.url + '?db=' + this.config.db + '&table=' + this.config.tableName + '&chr=' + chr + '&start=' + s + '&end=' + e;
55110      return igvxhr.loadJson(url, this.config).then(function (data) {
55111        if (data) {
55112          data.forEach(function (sample) {
55113            if (sample.hasOwnProperty('exonStarts') && sample.hasOwnProperty('exonEnds') && sample.hasOwnProperty('exonCount') && sample.hasOwnProperty('cdsStart') && sample.hasOwnProperty('cdsEnd')) {
55114              addExons(sample);
55115            }
55116          });
55117          return data;
55118        } else {
55119          return null;
55120        }
55121      });
55122    };
55123
55124    function addExons(sample) {
55125      var exonCount, exonStarts, exonEnds, exons, eStart, eEnd;
55126      exonCount = sample['exonCount'];
55127      exonStarts = sample['exonStarts'].split(',');
55128      exonEnds = sample['exonEnds'].split(',');
55129      exons = [];
55130
55131      for (var i = 0; i < exonCount; i++) {
55132        eStart = parseInt(exonStarts[i]);
55133        eEnd = parseInt(exonEnds[i]);
55134        var exon = {
55135          start: eStart,
55136          end: eEnd
55137        };
55138        if (sample.cdsStart > eEnd || sample.cdsEnd < sample.cdsStart) exon.utr = true; // Entire exon is UTR
55139
55140        if (sample.cdsStart >= eStart && sample.cdsStart <= eEnd) exon.cdStart = sample.cdsStart;
55141        if (sample.cdsEnd >= eStart && sample.cdsEnd <= eEnd) exon.cdEnd = sample.cdsEnd;
55142        exons.push(exon);
55143      }
55144
55145      sample.exons = exons;
55146    }
55147
55148    /*
55149     * The MIT License (MIT)
55150     *
55151     * Copyright (c) 2021 University of California San Diego
55152     * Author: Jim Robinson
55153     *
55154     * Permission is hereby granted, free of charge, to any person obtaining a copy
55155     * of this software and associated documentation files (the "Software"), to deal
55156     * in the Software without restriction, including without limitation the rights
55157     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55158     * copies of the Software, and to permit persons to whom the Software is
55159     * furnished to do so, subject to the following conditions:
55160     *
55161     * The above copyright notice and this permission notice shall be included in
55162     * all copies or substantial portions of the Software.
55163     *
55164     *
55165     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55166     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55167     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55168     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55169     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55170     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55171     * THE SOFTWARE.
55172     */
55173    const gffNameFields = ["Name", "gene_name", "gene", "gene_id", "alias", "locus", "name"];
55174
55175    class GFFHelper {
55176      constructor(options) {
55177        this.format = options.format;
55178        this.nameField = options.nameField;
55179        this.filterTypes = options.filterTypes === undefined ? new Set(['chromosome']) : new Set(options.filterTypes);
55180      }
55181
55182      combineFeatures(features, genomicInterval) {
55183        let combinedFeatures;
55184        const filterTypes = this.filterTypes;
55185        features = features.filter(f => filterTypes === undefined || !filterTypes.has(f.type));
55186
55187        if ("gff3" === this.format) {
55188          const tmp = this.combineFeaturesById(features);
55189          combinedFeatures = this.combineFeaturesByType(tmp);
55190        } else {
55191          combinedFeatures = this.combineFeaturesByType(features);
55192        }
55193
55194        combinedFeatures.sort(function (a, b) {
55195          return a.start - b.start;
55196        });
55197        this.numberExons(combinedFeatures, genomicInterval);
55198        this.nameFeatures(combinedFeatures);
55199        return combinedFeatures;
55200      }
55201      /**
55202       * Combine multiple non-transcript model features with the same ID on the same chromosome into a single feature.
55203       * Features that are part of the transcript model (e.g. exon, mRNA, etc) are combined later.
55204       *
55205       * @param features
55206       * @returns {[]}
55207       */
55208
55209
55210      combineFeaturesById(features) {
55211        const chrIdMap = new Map();
55212        const combinedFeatures = [];
55213
55214        for (let f of features) {
55215          if (isTranscriptPart(f.type) || isTranscript(f.type) || !f.id) {
55216            combinedFeatures.push(f);
55217          } else {
55218            let idMap = chrIdMap.get(f.chr);
55219
55220            if (!idMap) {
55221              idMap = new Map();
55222              chrIdMap.set(f.chr, idMap);
55223            }
55224
55225            let featureArray = idMap.get(f.id);
55226
55227            if (featureArray) {
55228              featureArray.push(f);
55229            } else {
55230              idMap.set(f.id, [f]);
55231            }
55232          }
55233        }
55234
55235        for (let idMap of chrIdMap.values()) {
55236          for (let featureArray of idMap.values()) {
55237            if (featureArray.length > 1) {
55238              // Use the first feature as prototypical (for column 9 attributes), and adjust start/end
55239              // Parts are represented as "exons", as that is how they are presented visually
55240              const cf = featureArray[0];
55241              cf.exons = [];
55242
55243              for (let f of featureArray) {
55244                cf.start = Math.min(cf.start, f.start);
55245                cf.end = Math.max(cf.end, f.end);
55246                cf.exons.push({
55247                  start: f.start,
55248                  end: f.end
55249                });
55250              }
55251
55252              combinedFeatures.push(cf);
55253            } else {
55254              combinedFeatures.push(featureArray[0]);
55255            }
55256          }
55257        }
55258
55259        return combinedFeatures;
55260      }
55261
55262      combineFeaturesByType(features) {
55263        // Build dictionary of genes
55264        const genes = features.filter(f => "gene" === f.type || f.type.endsWith("_gene"));
55265        const geneMap = Object.create(null);
55266
55267        for (let g of genes) {
55268          geneMap[g.id] = g;
55269        } // 1. Build dictionary of transcripts
55270
55271
55272        const transcripts = Object.create(null);
55273        const combinedFeatures = [];
55274        const consumedFeatures = new Set();
55275        const filterTypes = this.filterTypes;
55276        features = features.filter(f => filterTypes === undefined || !filterTypes.has(f.type));
55277
55278        for (let f of features) {
55279          if (f.type === "biological_region") {
55280            console.log();
55281          }
55282
55283          if (isTranscript(f.type)) {
55284            const transcriptId = f.id; // getAttribute(f.attributeString, "transcript_id", /\s+/);
55285
55286            if (undefined !== transcriptId) {
55287              const gffTranscript = new GFFTranscript(f);
55288              transcripts[transcriptId] = gffTranscript;
55289              combinedFeatures.push(gffTranscript);
55290              consumedFeatures.add(f);
55291              const g = geneMap[f.parent];
55292
55293              if (g) {
55294                gffTranscript.geneObject = g;
55295                consumedFeatures.add(g);
55296              }
55297            }
55298          }
55299        } // Add exons and transcript parts
55300
55301
55302        for (let f of features) {
55303          if (isTranscriptPart(f.type)) {
55304            const parents = getParents(f);
55305
55306            if (parents) {
55307              for (let id of parents) {
55308                let transcript = transcripts[id];
55309
55310                if (!transcript && this.format === "gtf") {
55311                  // GTF does not require explicit transcript record, start one with this feature.
55312                  const psuedoTranscript = Object.assign({}, f);
55313                  psuedoTranscript.type = "transcript";
55314                  transcript = new GFFTranscript(psuedoTranscript);
55315                  transcripts[id] = transcript;
55316                  combinedFeatures.push(transcript);
55317                }
55318
55319                if (transcript !== undefined) {
55320                  if (isExon(f.type)) {
55321                    if (parents.length > 1) {
55322                      // Make a copy as exon can be modified differently by CDS, etc, for each transcript
55323                      const e2 = new GFFFeature(f);
55324                      transcript.addExon(e2);
55325                    } else {
55326                      transcript.addExon(f);
55327                    }
55328                  } else {
55329                    transcript.addPart(f);
55330                  }
55331
55332                  consumedFeatures.add(f);
55333                }
55334              }
55335            }
55336          }
55337        }
55337 // Finish transcripts
55338
55339
55340        combinedFeatures.forEach(function (f) {
55341          if (typeof f.finish === "function") {
55342            f.finish();
55343          }
55344        }); // Add other features
55345
55346        const others = features.filter(f => !consumedFeatures.has(f));
55347
55348        for (let f of others) {
55349          combinedFeatures.push(f);
55350        }
55351
55352        return combinedFeatures;
55353
55354        function getParents(f) {
55355          if (f.parent && f.parent.trim() !== "") {
55356            return f.parent.trim().split(",");
55357          } else {
55358            return null;
55359          }
55360        }
55361      }
55362
55363      numberExons(features, genomicInterval) {
55364        for (let f of features) {
55365          if (f.exons && (!genomicInterval || f.end <= genomicInterval.end && f.start > genomicInterval.start)) {
55366            for (let i = 0; i < f.exons.length; i++) {
55367              const exon = f.exons[i];
55368              exon.number = f.strand === "-" ? f.exons.length - i : i + 1;
55369            }
55370          }
55371        }
55372      }
55373
55374      nameFeatures(features) {
55375        // Find name (label) property
55376        for (let f of features) {
55377          if (f.attributeString) {
55378            const delim = 'gff3' === this.format ? '=' : ' ';
55379            const attributes = parseAttributeString(f.attributeString, delim);
55380            const attributesMap = new Map(attributes);
55381
55382            if (this.nameField) {
55383              f.name = attributesMap.get(this.nameField);
55384            } else {
55385              for (let nameField of gffNameFields) {
55386                if (attributesMap.has(nameField)) {
55387                  f.name = attributesMap.get(nameField);
55388                  break;
55389                }
55390              }
55391            }
55392          }
55393        }
55394      }
55395
55396    }
55397
55398    /*
55399     * The MIT License (MIT)
55400     *
55401     * Copyright (c) 2015 UC San Diego
55402     *
55403     * Permission is hereby granted, free of charge, to any person obtaining a copy
55404     * of this software and associated documentation files (the "Software"), to deal
55405     * in the Software without restriction, including without limitation the rights
55406     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55407     * copies of the Software, and to permit persons to whom the Software is
55408     * furnished to do so, subject to the following conditions:
55409     *
55410     * The above copyright notice and this permission notice shall be included in
55411     * all copies or substantial portions of the Software.
55412     *
55413     *
55414     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55415     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55416     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55417     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55418     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55419     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55420     * THE SOFTWARE.
55421     */
55422
55423    const GtexReader = function (config) {
55424      this.config = config;
55425      this.url = config.url;
55426      this.tissueId = config.tissueSiteDetailId;
55427      this.indexed = true;
55428      this.datasetId = config.datasetId || "gtex_v8";
55429    };
55430
55431    GtexReader.prototype.readFeatures = async function (chr, bpStart, bpEnd) {
55432      let self = this,
55433          queryChr = chr.startsWith("chr") ? chr : "chr" + chr,
55434          queryStart = Math.floor(bpStart),
55435          queryEnd = Math.ceil(bpEnd),
55436          datasetId = this.datasetId,
55437          queryURL = this.url + "?chromosome=" + queryChr + "&start=" + queryStart + "&end=" + queryEnd + "&tissueSiteDetailId=" + this.tissueId + "&datasetId=" + datasetId;
55438      const json = await igvxhr.loadJson(queryURL, {
55439        withCredentials: self.config.withCredentials
55440      });
55441
55442      if (json && json.singleTissueEqtl) {
55443        //variants = json.variants;
55444        //variants.sort(function (a, b) {
55445        //    return a.POS - b.POS;
55446        //});
55447        //source.cache = new FeatureCache(chr, queryStart, queryEnd, variants);
55448        json.singleTissueEqtl.forEach(function (eqtl) {
55449          eqtl.chr = eqtl.chromosome;
55450          eqtl.position = eqtl.pos;
55451          eqtl.start = eqtl.pos - 1;
55452          eqtl.end = eqtl.start + 1;
55453          eqtl.snp = eqtl.snpId;
55454          eqtl.geneName = eqtl.geneSymbol;
55455          eqtl.geneId = eqtl.gencodeId;
55456        });
55457        return json.singleTissueEqtl;
55458      } else {
55459        return undefined;
55460      }
55461    };
55462
55463    /*
55464     * The MIT License (MIT)
55465     *
55466     * Copyright (c) 2014 Broad Institute
55467     *
55468     * Permission is hereby granted, free of charge, to any person obtaining a copy
55469     * of this software and associated documentation files (the "Software"), to deal
55470     * in the Software without restriction, including without limitation the rights
55471     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55472     * copies of the Software, and to permit persons to whom the Software is
55473     * furnished to do so, subject to the following conditions:
55474     *
55475     * The above copyright notice and this permission notice shall be included in
55476     * all copies or substantial portions of the Software.
55477     *
55478     *
55479     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55480     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55481     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55482     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55483     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55484     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55485     * THE SOFTWARE.
55486     */
55487    // http://immvar.broadinstitute.org:3000/load_data?chromosome=&start=&end=&categories=
55488
55489    const ImmVarReader = function (config) {
55490      this.config = config;
55491      this.url = config.url;
55492      this.cellConditionId = config.cellConditionId;
55493      this.valueThreshold = config.valueThreshold ? config.valueThreshold : 5E-2;
55494    };
55495
55496    ImmVarReader.prototype.readFeatures = function (queryChr, queryStart, queryEnd) {
55497      var self = this,
55498          queryURL = this.url + "?chromosome=" + queryChr + "&start=" + queryStart + "&end=" + queryEnd + "&cell_condition_id=" + this.cellConditionId;
55499      return new Promise(function (fulfill, reject) {
55500        igvxhr.loadJson(queryURL, {
55501          withCredentials: self.config.withCredentials
55502        }).then(function (json) {
55503          if (json) {
55504            //variants = json.variants;
55505            //variants.sort(function (a, b) {
55506            //    return a.POS - b.POS;
55507            //});
55508            //source.cache = new FeatureCache(chr, queryStart, queryEnd, variants);
55509            json.eqtls.forEach(function (eqtl) {
55510              eqtl.chr = eqtl.chromosome;
55511              eqtl.start = eqtl.position;
55512              eqtl.end = eqtl.position + 1;
55513            });
55514            fulfill(json.eqtls);
55515          } else {
55516            fulfill(null);
55517          }
55518        }).catch(function (error) {
55519          reject(error);
55520        });
55521      });
55522    };
55523
55524    /*
55525     * The MIT License (MIT)
55526     *
55527     * Copyright (c) 2014 Broad Institute
55528     *
55529     * Permission is hereby granted, free of charge, to any person obtaining a copy
55530     * of this software and associated documentation files (the "Software"), to deal
55531     * in the Software without restriction, including without limitation the rights
55532     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55533     * copies of the Software, and to permit persons to whom the Software is
55534     * furnished to do so, subject to the following conditions:
55535     *
55536     * The above copyright notice and this permission notice shall be included in
55537     * all copies or substantial portions of the Software.
55538     *
55539     *
55540     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55541     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55542     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55543     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55544     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55545     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55546     * THE SOFTWARE.
55547     */
55548
55549    const Ga4ghVariantReader = function (config, genome) {
55550      this.config = config;
55551      this.genome = genome;
55552      this.url = config.url;
55553      this.variantSetId = config.variantSetId;
55554      this.callSetIds = config.callSetIds;
55555      this.includeCalls = config.includeCalls === undefined ? true : config.includeCalls;
55556    }; // Simulate a VCF file header
55557
55558
55559    Ga4ghVariantReader.prototype.readHeader = function () {
55560      var self = this;
55561
55562      if (self.header) {
55563        return Promise.resolve(self.header);
55564      } else {
55565        self.header = {};
55566
55567        if (self.includeCalls === false) {
55568          return Promise.resolve(self.header);
55569        } else {
55570          var readURL = self.url + "/callsets/search";
55571          return ga4ghSearch({
55572            url: readURL,
55573            fields: "nextPageToken,callSets(id,name)",
55574            body: {
55575              "variantSetIds": Array.isArray(self.variantSetId) ? self.variantSetId : [self.variantSetId],
55576              "pageSize": "10000"
55577            },
55578            decode: function (json) {
55579              // If specific callSetIds are specified filter to those
55580              if (self.callSetIds) {
55581                var callSets = [],
55582                    csIdSet = new Set();
55583                self.callSetIds.forEach(function (csid) {
55584                  csIdSet.add(csid);
55585                });
55586                json.callSets.forEach(function (cs) {
55587                  if (csIdSet.has(cs.id)) {
55588                    callSets.push(cs);
55589                  }
55590                });
55591                return callSets;
55592              } else {
55593                return json.callSets;
55594              }
55595            }
55596          }).then(function (callSets) {
55597            self.header.callSets = callSets;
55598            return self.header;
55599          });
55600        }
55601      }
55602    };
55603
55604    Ga4ghVariantReader.prototype.readFeatures = function (chr, bpStart, bpEnd) {
55605      const self = this;
55606      const genome = this.genome;
55607      return self.readHeader().then(function (header) {
55608        return getChrAliasTable();
55609      }).then(function (chrAliasTable) {
55610        var queryChr = chrAliasTable.hasOwnProperty(chr) ? chrAliasTable[chr] : chr,
55611            readURL = self.url + "/variants/search";
55612        return ga4ghSearch({
55613          url: readURL,
55614          fields: self.includeCalls ? undefined : "nextPageToken,variants(id,variantSetId,names,referenceName,start,end,referenceBases,alternateBases,quality,filter,info)",
55615          body: {
55616            "variantSetIds": Array.isArray(self.variantSetId) ? self.variantSetId : [self.variantSetId],
55617            "callSetIds": self.callSetIds ? self.callSetIds : undefined,
55618            "referenceName": queryChr,
55619            "start": bpStart.toString(),
55620            "end": bpEnd.toString(),
55621            "pageSize": "10000"
55622          },
55623          decode: function (json) {
55624            var v;
55625            var variants = [];
55626            json.variants.forEach(function (json) {
55627              v = createGAVariant(json);
55628
55629              if (!v.isRefBlock()) {
55630                variants.push(v);
55631              }
55632            });
55633            return variants;
55634          }
55635        });
55636      });
55637
55638      function getChrAliasTable() {
55639        return new Promise(function (fulfill, reject) {
55640          if (self.chrAliasTable) {
55641            fulfill(self.chrAliasTable);
55642          } else {
55643            self.readMetadata().then(function (json) {
55644              self.metadata = json.metadata;
55645              self.chrAliasTable = {};
55646
55647              if (json.referenceBounds && genome) {
55648                json.referenceBounds.forEach(function (rb) {
55649                  var refName = rb.referenceName,
55650                      alias = genome.getChromosomeName(refName);
55651                  self.chrAliasTable[alias] = refName;
55652                });
55653              }
55654
55655              fulfill(self.chrAliasTable);
55656            });
55657          }
55658        });
55659      }
55660    };
55661
55662    Ga4ghVariantReader.prototype.readMetadata = function () {
55663      return ga4ghGet({
55664        url: this.url,
55665        entity: "variantsets",
55666        entityId: this.variantSetId
55667      });
55668    };
55669
55670    class CivicReader {
55671      constructor(config) {
55672        this.config = config;
55673      }
55674
55675      async readFeatures(chr, start, end) {
55676        const json = await igvxhr.loadJson(this.config.url + "/variants/?count=50000");
55677        const records = json.records;
55678        const features = [];
55679
55680        for (let record of records) {
55681          if (record.coordinates) {
55682            record.id;
55683            const coordinates = record.coordinates;
55684
55685            if (coordinates.chromosome) {
55686              features.push(new CivicVariant(coordinates.chromosome, coordinates.start - 1, // UCSC 0 convention
55687              coordinates.stop, record));
55688            }
55689
55690            if (coordinates.chromosome2) {
55691              features.push(new CivicVariant(coordinates.chromosome2, coordinates.start2 - 1, // UCSC 0 convention
55692              coordinates.stop2, record));
55693            }
55694          }
55695        }
55696
55697        return features;
55698      }
55699
55700    }
55701
55702    class CivicVariant {
55703      constructor(chr, start, end, record) {
55704        this.chr = chr;
55705        this.start = start;
55706        this.end = end;
55707        this.id = record.id;
55708        this.entrezName = record.entrez_name;
55709        this.name = record.name;
55710        this.actionabilityScore = record.civic_actionability_score;
55711
55712        if (record.coordinates.reference_bases) {
55713          this.refBases = record.coordinates.reference_bases;
55714        }
55715
55716        if (record.coordinates.variant_bases) {
55717          this.altBases = record.coordinates.variant_bases;
55718        }
55719
55720        if (record.variant_types) {
55721          this.variant_types = record.variant_types;
55722        }
55723
55724        this.locationString = this.chr + ":" + numberFormatter$1(this.start + 1) + "-" + numberFormatter$1(this.end); // Color based on actionability score
55725
55726        if (this.actionabilityScore !== undefined) {
55727          let alpha;
55728
55729          if (this.actionabilityScore <= 10) {
55730            alpha = 0.2;
55731          } else {
55732            const v = Math.min(30, this.actionabilityScore);
55733            alpha = 0.2 + 0.8 * Math.log10((v - 10) / 2);
55734          }
55735
55736          this.alpha = alpha;
55737        }
55738      }
55739
55740      popupData() {
55741        const link = createLink("CIViC", "https://civicdb.org/links/variants/" + this.id);
55742        this.refBases !== this.altBases && this.refBases && this.refBases.length === 1 && this.altBases && this.altBases.length === 1;
55743        const pd = [link];
55744        pd.push({
55745          name: "Entrez",
55746          value: createLink(this.entrezName, "https://ghr.nlm.nih.gov/gene/" + this.entrezName)
55747        });
55748        pd.push({
55749          name: "Name",
55750          value: this.name
55751        });
55752
55753        if (this.variant_types && this.variant_types.length > 0) {
55754          const name = this.variant_types.length === 1 ? "Type" : "Types";
55755          let typeString;
55756
55757          for (let vt of this.variant_types) {
55758            if (!typeString) typeString = vt.display_name;else typeString += ", " + vt.display_name;
55759          }
55760
55761          pd.push({
55762            name: name,
55763            value: typeString
55764          });
55765        }
55766
55767        pd.push({
55768          name: "Actionability",
55769          value: this.actionabilityScore
55770        });
55771        pd.push({
55772          name: "Location",
55773          value: this.locationString
55774        });
55775        return pd;
55776
55777        function createLink(text, href) {
55778          return "<a target='_blank' " + "href='" + href + "'>
55778" + text + "</a>";
55779        }
55780      }
55781
55782    }
55783
55784    // Assigns a row # to each feature.  If the feature does not fit in any row and #rows == maxRows no
55785    // row number is assigned.
55786    function pack(featureList, maxRows) {
55787      maxRows = maxRows || Number.MAX_SAFE_INTEGER;
55788      const rows = [];
55789      featureList.sort(function (a, b) {
55790        return a.start - b.start;
55791      });
55792      rows.push(-1000);
55793
55794      for (let feature of featureList) {
55795        let r = 0;
55796        const len = Math.min(rows.length, maxRows);
55797
55798        for (r = 0; r < len; r++) {
55799          if (feature.start > rows[r]) {
55800            feature.row = r;
55801            rows[r] = feature.end;
55802            break;
55803          }
55804        }
55805
55806        feature.row = r;
55807        rows[r] = feature.end;
55808      }
55809    }
55810
55811    /*
55812     * The MIT License (MIT)
55813     *
55814     * Copyright (c) 2016-2017 The Regents of the University of California
55815     * Author: Jim Robinson
55816     *
55817     * Permission is hereby granted, free of charge, to any person obtaining a copy
55818     * of this software and associated documentation files (the "Software"), to deal
55819     * in the Software without restriction, including without limitation the rights
55820     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55821     * copies of the Software, and to permit persons to whom the Software is
55822     * furnished to do so, subject to the following conditions:
55823     *
55824     * The above copyright notice and this permission notice shall be included in
55825     * all copies or substantial portions of the Software.
55826     *
55827     *
55828     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55829     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55830     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55831     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55832     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55833     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55834     * THE SOFTWARE.
55835     */
55836
55837    class HtsgetVariantReader extends HtsgetReader {
55838      constructor(config, genome) {
55839        super(config, genome);
55840        this.parser = new VcfParser();
55841      }
55842
55843      async readHeader() {
55844        if (!this.header) {
55845          const data = await this.readHeaderData();
55846          const dataWrapper = getDataWrapper(data);
55847          this.header = await this.parser.parseHeader(dataWrapper, this.genome);
55848          this.chrAliasTable = this.header.chrAliasTable;
55849        }
55850
55851        return this.header;
55852      }
55853
55854      async readFeatures(chr, start, end) {
55855        if (this.config.format && this.config.format.toUpperCase() !== "VCF") {
55856          throw Error(`htsget format ${this.config.format} is not supported`);
55857        }
55858
55859        if (!this.chrAliasTable) {
55860          await this.readHeader();
55861        }
55862
55863        let queryChr = this.chrAliasTable.has(chr) ? this.chrAliasTable.get(chr) : chr;
55864        const data = await this.readData(queryChr, start, end);
55865        const dataWrapper = getDataWrapper(data);
55866        return this.parser.parseFeatures(dataWrapper); //  return dataWrapper;
55867      }
55868
55869    }
55870
55871    /*
55872     * The MIT License (MIT)
55873     *
55874     * Copyright (c) 2014-2015 Broad Institute
55875     *
55876     * Permission is hereby granted, free of charge, to any person obtaining a copy
55877     * of this software and associated documentation files (the "Software"), to deal
55878     * in the Software without restriction, including without limitation the rights
55879     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
55880     * copies of the Software, and to permit persons to whom the Software is
55881     * furnished to do so, subject to the following conditions:
55882     *
55883     * The above copyright notice and this permission notice shall be included in
55884     * all copies or substantial portions of the Software.
55885     *
55886     *
55887     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55888     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
55889     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55890     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55891     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55892     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
55893     * THE SOFTWARE.
55894     */
55895    /**
55896     * feature source for "bed like" files (tab or whitespace delimited files with 1 feature per line: bed, gff, vcf, etc)
55897     *
55898     * @param config
55899     * @constructor
55900     */
55901
55902    class TextFeatureSource {
55903      constructor(config, genome) {
55904        this.config = config || {};
55905        this.genome = genome;
55906        this.sourceType = config.sourceType === undefined ? "file" : config.sourceType;
55907        const queryableFormats = new Set(["bigwig", "bw", "bigbed", "bb", "tdf"]);
55908
55909        if (config.features && Array.isArray(config.features)) {
55910          // Explicit array of features
55911          let features = fixFeatures(config.features, genome);
55912          packFeatures(features);
55913
55914          if (config.mappings) {
55915            mapProperties(features, config.mappings);
55916          }
55917
55918          this.queryable = false;
55919          this.featureCache = new FeatureCache(features, genome);
55920        } else if (config.reader) {
55921          // Explicit reader implementation
55922          this.reader = config.reader;
55923          this.queryable = config.queryable !== false;
55924        } else if (config.sourceType === "ga4gh") {
55925          this.reader = new Ga4ghVariantReader(config, genome);
55926          this.queryable = true;
55927        } else if (config.sourceType === "immvar") {
55928          this.reader = new ImmVarReader(config);
55929          this.queryable = true;
55930        } else if (config.type === "eqtl" && config.sourceType === "gtex-ws") {
55931          this.reader = new GtexReader(config);
55932          this.queryable = true;
55933        } else if ("htsget" === config.sourceType) {
55934          this.reader = new HtsgetVariantReader(config, genome);
55935        } else if (config.sourceType === 'ucscservice') {
55936          this.reader = new UCSCServiceReader(config.source);
55937          this.queryable = true;
55938        } else if (config.sourceType === 'custom') {
55939          this.reader = new CustomServiceReader(config.source);
55940          this.queryable = false !== config.source.queryable;
55941        } else if ("civic-ws" === config.sourceType) {
55942          this.reader = new CivicReader(config);
55943          this.queryable = false;
55944        } else {
55945          // File of some type (i.e. not a webservice)
55946          this.reader = new FeatureFileReader(config, genome);
55947
55948          if (config.queryable !== undefined) {
55949            this.queryable = config.queryable;
55950          } else if (queryableFormats.has(config.format) || this.reader.indexed) {
55951            this.queryable = true;
55952          } else ;
55953        }
55954      }
55955
55956      async defaultVisibilityWindow() {
55957        if (this.reader && typeof this.reader.defaultVisibilityWindow === 'function') {
55958          return this.reader.defaultVisibilityWindow();
55959        }
55960      }
55961
55962      async trackType() {
55963        const header = await this.getHeader();
55964
55965        if (header) {
55966          return header.type;
55967        } else {
55968          return undefined; // Convention for unknown or unspecified
55969        }
55970      }
55971
55972      async getHeader() {
55973        if (!this.header) {
55974          if (this.reader && typeof this.reader.readHeader === "function") {
55975            const header = await this.reader.readHeader();
55976
55977            if (header) {
55978              this.header = header;
55979
55980              if (header.format) {
55981                this.config.format = header.format;
55982              }
55983            } else {
55984              this.header = {};
55985            }
55986          } else {
55987            this.header = {};
55988          }
55989        }
55990
55991        return this.header;
55992      }
55993      /**
55994       * Required function for all data source objects.  Fetches features for the
55995       * range requested.
55996       *
55997       * This function is quite complex due to the variety of reader types backing it, some indexed, some queryable,
55998       * some not.  The whole scheme could use a refactoring.
55999       *
56000       * @param chr
56001       * @param start
56002       * @param end
56003       * @param bpPerPixel
56004       */
56005
56006
56007      async getFeatures(_ref) {
56008        let {
56009          chr,
56010          start,
56011          end,
56012          bpPerPixel,
56013          visibilityWindow
56014        } = _ref;
56015        const genome = this.genome;
56016        const queryChr = genome ? genome.getChromosomeName(chr) : chr;
56017        const isWholeGenome = "all" === queryChr.toLowerCase(); // Various conditions that can create a feature load
56018        // * view is "whole genome" but no features are loaded
56019        // * cache is disabled
56020        // * cache does not contain requested range
56021
56022        if (isWholeGenome && !this.getWGFeatures || this.config.disableCache || !this.featureCache || !this.featureCache.containsRange(new GenomicInterval(queryChr, start, end))) {
56023          await this.loadFeatures(queryChr, start, end, visibilityWindow);
56024        }
56025
56026        if (isWholeGenome) {
56027          if (!this.wgFeatures) {
56028            if (this.queryable) {
56029              // queryable sources don't support whole genome view
56030              this.wgFeatures = [];
56031            } else {
56032              this.wgFeatures = this.getWGFeatures(this.featureCache.getAllFeatures());
56033            }
56034          }
56035
56036          return this.wgFeatures;
56037        } else {
56038          return this.featureCache.queryFeatures(queryChr, start, end);
56039        }
56040      } // TODO -- experimental, will only work for non-indexed sources
56041
56042
56043      getAllFeatures() {
56044        if (this.queryable) {
56045          // queryable sources don't support all features
56046          return [];
56047        } else {
56048          return this.getWGFeatures(this.featureCache.getAllFeatures());
56049        }
56050      }
56051
56052      async loadFeatures(queryChr, start, end, visibilityWindow) {
56053        const reader = this.reader;
56054        let intervalStart = start;
56055        let intervalEnd = end; // Use visibility window to potentially expand query interval.
56056        // This can save re-queries as we zoom out.  Visibility window <= 0 is a special case
56057        // indicating whole chromosome should be read at once.
56058
56059        if ((!visibilityWindow || visibilityWindow <= 0) && this.config.expandQuery !== false) {
56060          // Whole chromosome
56061          const chromosome = this.genome ? this.genome.getChromosome(queryChr) : undefined;
56062          intervalStart = 0;
56063          intervalEnd = Math.max(chromosome ? chromosome.bpLength : Number.MAX_SAFE_INTEGER, end);
56064        } else if (visibilityWindow > end - start && this.config.expandQuery !== false) {
56065          const expansionWindow = Math.min(4.1 * (end - start), visibilityWindow);
56066          intervalStart = Math.max(0, (start + end) / 2 - expansionWindow);
56067          intervalEnd = start + expansionWindow;
56068        }
56069
56070        let features = await reader.readFeatures(queryChr, intervalStart, intervalEnd);
56071
56072        if (this.queryable === undefined) {
56073          this.queryable = reader.indexed;
56074        }
56075
56076        const genomicInterval = this.queryable ? new GenomicInterval(queryChr, intervalStart, intervalEnd) : undefined;
56077
56078        if (features) {
56079          if (this.config.assembleGFF !== false && ("gtf" === this.config.format || "gff3" === this.config.format || "gff" === this.config.format)) {
56080            features = new GFFHelper(this.config).combineFeatures(features, genomicInterval);
56081          } // Assign overlapping features to rows
56082
56083
56084          if (this.config.format !== "wig" && this.config.type !== "junctions") {
56085            const maxRows = this.config.maxRows || Number.MAX_SAFE_INTEGER;
56086            packFeatures(features, maxRows);
56087          } // Note - replacing previous cache with new one.  genomicInterval is optional (might be undefined => includes all features)
56088
56089
56090          this.featureCache = new FeatureCache(features, this.genome, genomicInterval); // If track is marked "searchable"< cache features by name -- use this with caution, memory intensive
56091
56092          if (this.config.searchable || this.config.searchableFields) {
56093            this.addFeaturesToDB(features);
56094          }
56095        } else {
56096          this.featureCache = new FeatureCache([], genomicInterval); // Empty cache
56097        }
56098      }
56099
56100      addFeaturesToDB(featureList) {
56101        for (let feature of featureList) {
56102          if (feature.name) {
56103            this.genome.featureDB[feature.name.toUpperCase()] = feature;
56104          }
56105
56106          if (feature.gene && feature.gene.name) {
56107            this.genome.featureDB[feature.gene.name.toUpperCase()] = feature;
56108          }
56109
56110          if (this.config.searchableFields) {
56111            for (let f of this.config.searchableFields) {
56112              const value = feature.getAttributeValue(f);
56113
56114              if (value) {
56115                if (value.indexOf(" ") > 0) {
56116                  this.genome.featureDB[value.replaceAll(" ", "+").toUpperCase()] = feature;
56117                  this.genome.featureDB[value.replaceAll(" ", "%20").toUpperCase()] = feature;
56118                } else {
56119                  this.genome.featureDB[value.toUpperCase()] = feature;
56120                }
56121              }
56122            }
56123          }
56124        }
56125      } // TODO -- filter by pixel size
56126
56127
56128      getWGFeatures(allFeatures) {
56129        const genome = this.genome;
56130        const wgChromosomeNames = new Set(genome.wgChromosomeNames);
56131        const wgFeatures = [];
56132
56133        for (let c of genome.wgChromosomeNames) {
56134          const features = allFeatures[c];
56135
56136          if (features) {
56137            for (let f of features) {
56138              let queryChr = genome.getChromosomeName(f.chr);
56139
56140              if (wgChromosomeNames.has(queryChr)) {
56141                const wg = Object.assign({}, f);
56142                wg.chr = "all";
56143                wg.start = genome.getGenomeCoordinate(f.chr, f.start);
56144                wg.end = genome.getGenomeCoordinate(f.chr, f.end);
56145                wg._f = f; // Don't draw exons in whole genome view
56146
56147                if (wg["exons"]) delete wg["exons"];
56148                wgFeatures.push(wg);
56149              }
56150            }
56151          }
56152        }
56153
56154        wgFeatures.sort(function (a, b) {
56155          return a.start - b.start;
56156        });
56157        return wgFeatures;
56158      }
56159
56160    }
56161
56162    function packFeatures(features, maxRows) {
56163      maxRows = maxRows || 1000;
56164
56165      if (features == null || features.length === 0) {
56166        return;
56167      } // Segregate by chromosome
56168
56169
56170      const chrFeatureMap = {};
56171      const chrs = [];
56172
56173      for (let feature of features) {
56174        const chr = feature.chr;
56175        let flist = chrFeatureMap[chr];
56176
56177        if (!flist) {
56178          flist = [];
56179          chrFeatureMap[chr] = flist;
56180          chrs.push(chr);
56181        }
56182
56183        flist.push(feature);
56184      }
56184 // Loop through chrosomosomes and pack features;
56185
56186
56187      for (let chr of chrs) {
56188        pack(chrFeatureMap[chr], maxRows);
56189      }
56190    }
56191    /**
56192     * This function is used to apply properties normally added during parsing to  features supplied directly in the
56193     * config as an array of objects.   At the moment the only application is bedpe type features.
56194     * @param features
56195     */
56196
56197
56198    function fixFeatures(features, genome) {
56199      if (!features || features.length === 0) return [];
56200      const isBedPE = features[0].chr === undefined && features[0].chr1 !== undefined;
56201
56202      if (isBedPE) {
56203        const interChrFeatures = [];
56204
56205        for (let feature of features) {
56206          if (genome) {
56207            feature.chr1 = genome.getChromosomeName(feature.chr1);
56208            feature.chr2 = genome.getChromosomeName(feature.chr2);
56209          } // Set total extent of feature
56210
56211
56212          if (feature.chr1 === feature.chr2) {
56213            feature.chr = feature.chr1;
56214            feature.start = Math.min(feature.start1, feature.start2);
56215            feature.end = Math.max(feature.end1, feature.end2);
56216          } else {
56217            interChrFeatures.push(feature);
56218          }
56219        } // Make copies of inter-chr features, one for each chromosome
56220
56221
56222        for (let f1 of interChrFeatures) {
56223          const f2 = Object.assign({
56224            dup: true
56225          }, f1);
56226          features.push(f2);
56227          f1.chr = f1.chr1;
56228          f1.start = f1.start1;
56229          f1.end = f1.end1;
56230          f2.chr = f2.chr2;
56231          f2.start = f2.start2;
56232          f2.end = f2.end2;
56233        }
56234      } else if (genome) {
56235        for (let feature of features) {
56236          feature.chr = genome.getChromosomeName(feature.chr);
56237        }
56238      }
56239
56240      return features;
56241    }
56242
56243    function mapProperties(features, mappings) {
56244      let mappingKeys = Object.keys(mappings);
56245      features.forEach(function (f) {
56246        mappingKeys.forEach(function (key) {
56247          f[key] = f[mappings[key]];
56248        });
56249      });
56250    }
56251
56252    class BufferedReader {
56253      constructor(config, contentLength, bufferSize) {
56254        this.path = config.url;
56255        this.bufferSize = bufferSize ? bufferSize : 512000;
56256        this.range = {
56257          start: -1,
56258          size: -1
56259        };
56260        this.config = config;
56261      }
56262      /**
56263       *
56264       * @param requestedRange - byte rangeas {start, size}
56265       * @param fulfill - function to receive result
56266       * @param asUint8 - optional flag to return result as an UInt8Array
56267       */
56268
56269
56270      async dataViewForRange(requestedRange, asUint8) {
56271        const hasData = this.data && this.range.start <= requestedRange.start && this.range.start + this.range.size >= requestedRange.start + requestedRange.size;
56272
56273        if (!hasData) {
56274          let bufferSize; // If requested range size is specified, potentially expand buffer size
56275
56276          if (requestedRange.size) {
56277            bufferSize = Math.max(this.bufferSize, requestedRange.size);
56278          } else {
56279            bufferSize = this.bufferSize;
56280          }
56281
56282          const loadRange = {
56283            start: requestedRange.start,
56284            size: bufferSize
56285          };
56286          const arrayBuffer = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {
56287            range: loadRange
56288          }));
56289          this.data = arrayBuffer;
56290          this.range = loadRange;
56291        }
56292
56293        const len = this.data.byteLength;
56294        const bufferStart = requestedRange.start - this.range.start;
56295        return asUint8 ? new Uint8Array(this.data, bufferStart, len - bufferStart) : new DataView(this.data, bufferStart, len - bufferStart);
56296      }
56297
56298    }
56299
56300    //table chromatinInteract
56301
56302    function getDecoder(definedFieldCount, fieldCount, autoSql) {
56303      if (autoSql && 'chromatinInteract' === autoSql.table) {
56304        return decodeInteract;
56305      } else {
56306        const standardFieldCount = definedFieldCount - 3;
56307        return function (feature, tokens) {
56308          if (standardFieldCount > 0) {
56309            feature.name = tokens[0];
56310          }
56311
56312          if (standardFieldCount > 1) {
56313            feature.score = Number(tokens[1]);
56314          }
56315
56316          if (standardFieldCount > 2) {
56317            feature.strand = tokens[2];
56318          }
56319
56320          if (standardFieldCount > 3) {
56321            feature.cdStart = parseInt(tokens[3]);
56322          }
56323
56324          if (standardFieldCount > 4) {
56325            feature.cdEnd = parseInt(tokens[4]);
56326          }
56327
56328          if (standardFieldCount > 5) {
56329            if (tokens[5] !== "." && tokens[5] !== "0" && tokens[5] !== "-1") {
56330              const c = IGVColor.createColorString(tokens[5]);
56331              feature.color = c.startsWith("rgb") ? c : undefined;
56332            }
56333          }
56334
56335          if (standardFieldCount > 8) {
56336            const exonCount = parseInt(tokens[6]);
56337            const exonSizes = tokens[7].split(',');
56338            const exonStarts = tokens[8].split(',');
56339            const exons = [];
56340
56341            for (let i = 0; i < exonCount; i++) {
56342              const eStart = feature.start + parseInt(exonStarts[i]);
56343              const eEnd = eStart + parseInt(exonSizes[i]);
56344              exons.push({
56345                start: eStart,
56346                end: eEnd
56347              });
56348            }
56349
56350            feature.exons = exons;
56351          }
56352
56353          if (autoSql) {
56354            // TODO -- these should be equal, validate?  fieldCount-definedFieldCount, as.fields.length, tokens.length-3
56355            const extraStart = definedFieldCount;
56356
56357            for (let i = extraStart; i < fieldCount; i++) {
56358              if (i < autoSql.fields.length) {
56359                const name = autoSql.fields[i].name;
56360                const value = tokens[i - 3];
56361                feature[name] = value;
56362              }
56363            }
56364          }
56365        };
56366      }
56367
56368      function decodeInteract(feature, tokens) {
56369        feature.chr1 = tokens[5];
56370        feature.start1 = Number.parseInt(tokens[6]);
56371        feature.end1 = Number.parseInt(tokens[7]);
56372        feature.chr2 = tokens[10];
56373        feature.start2 = Number.parseInt(tokens[11]);
56374        feature.end2 = Number.parseInt(tokens[12]);
56375        feature.name = tokens[0];
56376        feature.score = Number(tokens[1]);
56377        feature.value = Number(tokens[2]);
56378        feature.color = tokens[4] === '.' ? undefined : tokens[4] === "0" ? "rgb(0,0,0)" : tokens[4];
56379        return feature;
56380      }
56381    }
56382
56383    function scoreShade(score, color) {
56384      const alpha = Math.min(1, 0.11 + 0.89 * (score / 779));
56385      return alpha.toString();
56386    }
56387
56388    function parseAutoSQL(str) {
56389      let table;
56390      const fields = [];
56391      let startDecoding = false;
56392      const lines = str.trim().split(/\s*[\r\n]+\s*/g);
56393
56394      for (let line of lines) {
56395        if (line.startsWith('table')) {
56396          table = line.split(/\s+/)[1].trim();
56397        } else if (line.startsWith('(')) {
56398          startDecoding = true;
56399        } else if (line.startsWith(')')) ; else if (startDecoding) {
56400          if (line.length > 0) {
56401            const idx = line.indexOf(';');
56402            const tokens = line.substr(0, idx).split(/\s+/);
56403            const description = line.substr(idx + 1).replace(/"/g, '').trim();
56404            fields.push({
56405              type: tokens[0],
56406              name: tokens[1],
56407              description: description
56408            });
56409          }
56410        }
56411      }
56412
56413      return {
56414        table: table,
56415        fields: fields
56416      };
56417    }
56418
56419    let BIGWIG_MAGIC_LTH = 0x888FFC26; // BigWig Magic Low to High
56420
56421    let BIGWIG_MAGIC_HTL = 0x26FC8F66; // BigWig Magic High to Low
56422
56423    let BIGBED_MAGIC_LTH = 0x8789F2EB; // BigBed Magic Low to High
56424
56425    let BIGBED_MAGIC_HTL = 0xEBF28987; // BigBed Magic High to Low
56426
56427    let BBFILE_HEADER_SIZE = 64;
56428    let RPTREE_HEADER_SIZE = 48;
56429    let RPTREE_NODE_LEAF_ITEM_SIZE = 32; // leaf item size
56430
56431    let RPTREE_NODE_CHILD_ITEM_SIZE = 24; // child item size
56432
56433    let BUFFER_SIZE = 512000; //  buffer
56434
56435    class BWReader {
56436      constructor(config, genome) {
56437        this.path = config.url;
56438        this.genome = genome;
56439        this.rpTreeCache = {};
56440        this.config = config;
56441        this.loader = isDataURL(this.path) ? new DataBuffer(this.path) : igvxhr;
56442      }
56443
56444      async readWGFeatures(bpPerPixel, windowFunction) {
56445        await this.loadHeader();
56446        const chrIdx1 = 0;
56447        const chrIdx2 = this.chromTree.idToChrom.length - 1;
56448        const chr1 = this.chromTree.idToChrom[chrIdx1];
56449        const chr2 = this.chromTree.idToChrom[chrIdx2];
56450        return this.readFeatures(chr1, 0, chr2, Number.MAX_VALUE, bpPerPixel, windowFunction);
56451      }
56452
56453      async readFeatures(chr1, bpStart, chr2, bpEnd, bpPerPixel, windowFunction) {
56454        await this.loadHeader();
56455        const chrIdx1 = this.chromTree.chromToID[chr1];
56456        const chrIdx2 = this.chromTree.chromToID[chr2];
56457
56458        if (chrIdx1 === undefined || chrIdx2 === undefined) {
56459          return [];
56460        }
56461
56462        let treeOffset;
56463        let decodeFunction;
56464
56465        if (this.type === "bigwig") {
56466          // Select a biwig "zoom level" appropriate for the current resolution.
56467          const zoomLevelHeaders = await this.getZoomHeaders();
56468          let zoomLevelHeader = bpPerPixel ? zoomLevelForScale$1(bpPerPixel, zoomLevelHeaders) : undefined;
56469
56470          if (zoomLevelHeader) {
56471            treeOffset = zoomLevelHeader.indexOffset;
56472            decodeFunction = decodeZoomData;
56473          } else {
56474            treeOffset = this.header.fullIndexOffset;
56475            decodeFunction = decodeWigData;
56476          }
56477        } else {
56478          // bigbed, zoom data is not currently used in igv for bed type features
56479          treeOffset = this.header.fullIndexOffset;
56480          decodeFunction = getBedDataDecoder.call(this);
56481        } // Load the R Tree and fine leaf items
56482
56483
56484        const rpTree = await this.loadRPTree(treeOffset);
56485        const leafItems = await rpTree.findLeafItemsOverlapping(chrIdx1, bpStart, chrIdx2, bpEnd);
56486
56487        if (!leafItems || leafItems.length === 0) {
56488          return [];
56489        } else {
56490          // Consolidate leaf items and get all data at once
56491          let start = Number.MAX_VALUE;
56492          let end = 0;
56493
56494          for (let item of leafItems) {
56495            start = Math.min(start, item.dataOffset);
56496            end = Math.max(end, item.dataOffset + item.dataSize);
56497          }
56498
56499          const size = end - start;
56500          const arrayBuffer = await this.loader.loadArrayBuffer(this.config.url, buildOptions(this.config, {
56501            range: {
56502              start: start,
56503              size: size
56504            }
56505          })); // Parse data and return features
56506
56507          const allFeatures = [];
56508
56509          for (let item of leafItems) {
56510            const uint8Array = new Uint8Array(arrayBuffer, item.dataOffset - start, item.dataSize);
56511            let plain;
56512            const isCompressed = this.header.uncompressBuffSize > 0;
56513
56514            if (isCompressed) {
56515              plain = inflate(uint8Array);
56516            } else {
56517              plain = uint8Array;
56518            }
56519
56520            decodeFunction.call(this, new DataView(plain.buffer), chrIdx1, bpStart, chrIdx2, bpEnd, allFeatures, this.chromTree.idToChrom, windowFunction);
56521          }
56522
56523          allFeatures.sort(function (a, b) {
56524            return a.start - b.start;
56525          });
56526          return allFeatures;
56527        }
56528      }
56529
56530      async getZoomHeaders() {
56531        if (this.zoomLevelHeaders) {
56532          return this.zoomLevelHeaders;
56533        } else {
56534          await this.loadHeader();
56535          return this.zoomLevelHeaders;
56536        }
56537      }
56538
56539      async loadHeader() {
56540        if (this.header) {
56541          return this.header;
56542        } else {
56543          let data = await this.loader.loadArrayBuffer(this.path, buildOptions(this.config, {
56544            range: {
56545              start: 0,
56546              size: BBFILE_HEADER_SIZE
56547            }
56548          }));
56549          let header; // Assume low-to-high unless proven otherwise
56550
56551          this.littleEndian = true;
56552          let binaryParser = new BinaryParser(new DataView(data));
56553          let magic = binaryParser.getUInt();
56554
56555          if (magic === BIGWIG_MAGIC_LTH) {
56556            this.type = "bigwig";
56557          } else if (magic === BIGBED_MAGIC_LTH) {
56558            this.type = "bigbed";
56559          } else {
56560            //Try big endian order
56561            this.littleEndian = false;
56562            binaryParser.littleEndian = false;
56563            binaryParser.position = 0;
56564            let magic = binaryParser.getUInt();
56565
56566            if (magic === BIGWIG_MAGIC_HTL) {
56567              this.type = "bigwig";
56568            } else if (magic === BIGBED_MAGIC_HTL) {
56569              this.type = "bigbed";
56570            } else ;
56571          } // Table 5  "Common header for bigwig and bigbed files"
56572
56573
56574          header = {
56575            bwVersion: binaryParser.getUShort(),
56576            nZoomLevels: binaryParser.getUShort(),
56577            chromTreeOffset: binaryParser.getLong(),
56578            fullDataOffset: binaryParser.getLong(),
56579            fullIndexOffset: binaryParser.getLong(),
56580            fieldCount: binaryParser.getUShort(),
56581            definedFieldCount: binaryParser.getUShort(),
56582            autoSqlOffset: binaryParser.getLong(),
56583            totalSummaryOffset: binaryParser.getLong(),
56584            uncompressBuffSize: binaryParser.getInt(),
56585            extensionOffset: binaryParser.getLong()
56586          }; ///////////
56587
56588          const startOffset = BBFILE_HEADER_SIZE;
56589          let range = {
56590            start: startOffset,
56591            size: header.fullDataOffset - startOffset + 5
56592          };
56593          data = await this.loader.loadArrayBuffer(this.path, buildOptions(this.config, {
56594            range: range
56595          }));
56596          const nZooms = header.nZoomLevels;
56597          binaryParser = new BinaryParser(new DataView(data));
56598          this.zoomLevelHeaders = [];
56599          this.firstZoomDataOffset = Number.MAX_SAFE_INTEGER;
56600
56601          for (let i = 1; i <= nZooms; i++) {
56602            const zoomNumber = nZooms - i;
56603            const zlh = new ZoomLevelHeader(zoomNumber, binaryParser);
56604            this.firstZoomDataOffset = Math.min(zlh.dataOffset, this.firstZoomDataOffset);
56605            this.zoomLevelHeaders[zoomNumber] = zlh;
56606          } // Autosql
56607
56608
56609          if (header.autoSqlOffset > 0) {
56610            binaryParser.position = header.autoSqlOffset - startOffset;
56611            const autoSqlString = binaryParser.getString();
56612
56613            if (autoSqlString) {
56614              this.autoSql = parseAutoSQL(autoSqlString);
56615            }
56616          } // Total summary
56617
56618
56619          if (header.totalSummaryOffset > 0) {
56620            binaryParser.position = header.totalSummaryOffset - startOffset;
56621            this.totalSummary = new BWTotalSummary(binaryParser);
56622          } // Chrom data index
56623
56624
56625          if (header.chromTreeOffset > 0) {
56626            binaryParser.position = header.chromTreeOffset - startOffset;
56627            this.chromTree = new BPTree(binaryParser, startOffset, this.genome);
56628          } else {
56629            // TODO -- this is an error, not expected
56630            throw "BigWig chromosome tree offset <= 0";
56631          } //Finally total data count
56632
56633
56634          binaryParser.position = header.fullDataOffset - startOffset;
56635          header.dataCount = binaryParser.getInt(); ///////////
56636
56637          this.setDefaultVisibilityWindow(header);
56638          this.header = header;
56639          return this.header;
56640        }
56641      }
56642
56643      async loadRPTree(offset) {
56644        let rpTree = this.rpTreeCache[offset];
56645
56646        if (rpTree) {
56647          return rpTree;
56648        } else {
56649          rpTree = new RPTree(offset, this.config, this.littleEndian, this.loader);
56650          await rpTree.load();
56651          this.rpTreeCache[offset] = rpTree;
56652          return rpTree;
56653        }
56654      }
56655
56656      async getType() {
56657        await this.loadHeader();
56658        return this.type;
56659      }
56660
56661      async getTrackType() {
56662        await this.loadHeader();
56663
56664        if (this.type === "bigwig") {
56665          return "wig";
56666        } else {
56667          return this.autoSql && this.autoSql.table === "chromatinInteract" ? "interact" : "annotation";
56668        }
56669      }
56670
56671      setDefaultVisibilityWindow(header) {
56672        if (this.type === "bigwig") {
56673          this.visibilityWindow = -1;
56674        } else {
56675          // bigbed
56676          let genomeSize = this.genome ? this.genome.getGenomeLength() : 3088286401; // Estimate window size to return ~ 1,000 features, assuming even distribution across the genome
56677
56678          this.visibilityWindow = header.dataCount < 1000 ? -1 : 1000 * (genomeSize / header.dataCount);
56679        }
56680      }
56681
56682    }
56683
56684    class ZoomLevelHeader {
56685      constructor(index, byteBuffer) {
56686        this.index = index;
56687        this.reductionLevel = byteBuffer.getInt();
56688        this.reserved = byteBuffer.getInt();
56689        this.dataOffset = byteBuffer.getLong();
56690        this.indexOffset = byteBuffer.getLong();
56691      }
56692
56693    }
56694
56695    class RPTree {
56696      constructor(fileOffset, config, littleEndian, loader) {
56697        this.config = config;
56698        this.loader = loader;
56699        this.fileOffset = fileOffset; // File offset to beginning of tree
56700
56701        this.path = config.url;
56702        this.littleEndian = littleEndian;
56703      }
56704
56705      async load() {
56706        const rootNodeOffset = this.fileOffset + RPTREE_HEADER_SIZE;
56707        const bufferedReader = isDataURL(this.path) ? this.loader : new BufferedReader(this.config, BUFFER_SIZE);
56708        this.rootNode = await this.readNode(rootNodeOffset, bufferedReader);
56709        return this;
56710      }
56711
56712      async readNode(filePosition, bufferedReader) {
56713        let dataView = await bufferedReader.dataViewForRange({
56714          start: filePosition,
56715          size: 4
56716        }, false);
56717        let binaryParser = new BinaryParser(dataView, this.littleEndian);
56718        const type = binaryParser.getByte();
56719        const isLeaf = type === 1;
56720        binaryParser.getByte();
56721        const count = binaryParser.getUShort();
56722        filePosition += 4;
56723        let bytesRequired = count * (isLeaf ? RPTREE_NODE_LEAF_ITEM_SIZE : RPTREE_NODE_CHILD_ITEM_SIZE);
56724        let range2 = {
56725          start: filePosition,
56726          size: bytesRequired
56727        };
56728        dataView = await bufferedReader.dataViewForRange(range2, false);
56729        const items = new Array(count);
56730        binaryParser = new BinaryParser(dataView);
56731
56732        if (isLeaf) {
56733          for (let i = 0; i < count; i++) {
56734            let item = {
56735              isLeaf: true,
56736              startChrom: binaryParser.getInt(),
56737              startBase: binaryParser.getInt(),
56738              endChrom: binaryParser.getInt(),
56739              endBase: binaryParser.getInt(),
56740              dataOffset: binaryParser.getLong(),
56741              dataSize: binaryParser.getLong()
56742            };
56743            items[i] = item;
56744          }
56745
56746          return new RPTreeNode(items);
56747        } else {
56748          // non-leaf
56749          for (let i = 0; i < count; i++) {
56750            let item = {
56751              isLeaf: false,
56752              startChrom: binaryParser.getInt(),
56753              startBase: binaryParser.getInt(),
56754              endChrom: binaryParser.getInt(),
56755              endBase: binaryParser.getInt(),
56756              childOffset: binaryParser.getLong()
56757            };
56758            items[i] = item;
56759          }
56760
56761          return new RPTreeNode(items);
56762        }
56763      }
56764
56765      async findLeafItemsOverlapping(chrIdx1, startBase, chrIdx2, endBase) {
56766        let self = this;
56767        return new Promise(function (fulfill, reject) {
56768          let leafItems = [],
56769              processing = new Set(),
56770              bufferedReader = isDataURL(self.path) ? self.loader : new BufferedReader(self.config, BUFFER_SIZE);
56771          processing.add(0); // Zero represents the root node
56772
56773          findLeafItems(self.rootNode, 0);
56774
56775          function findLeafItems(node, nodeId) {
56776            if (overlaps(node, chrIdx1, startBase, chrIdx2, endBase)) {
56777              let items = node.items;
56778              items.forEach(function (item) {
56779                if (overlaps(item, chrIdx1, startBase, chrIdx2, endBase)) {
56780                  if (item.isLeaf) {
56781                    leafItems.push(item);
56782                  } else {
56783                    if (item.childNode) {
56784                      findLeafItems(item.childNode);
56785                    } else {
56786                      processing.add(item.childOffset); // Represent node to-be-loaded by its file position
56787
56788                      self.readNode(item.childOffset, bufferedReader).then(function (node) {
56789                        item.childNode = node;
56790                        findLeafItems(node, item.childOffset);
56791                      }).catch(reject);
56792                    }
56793                  }
56794                }
56795              });
56796            }
56797
56798            if (nodeId !== undefined) processing.delete(nodeId); // Wait until all nodes are processed
56799
56800            if (processing.size === 0) {
56801              fulfill(leafItems);
56802            }
56803          }
56804        });
56805      }
56806
56807    }
56808
56809    class RPTreeNode {
56810      constructor(items) {
56811        this.items = items;
56812        let minChromId = Number.MAX_SAFE_INTEGER,
56813            maxChromId = 0,
56814            minStartBase = Number.MAX_SAFE_INTEGER,
56815            maxEndBase = 0,
56816            i,
56817            item;
56818
56819        for (i = 0; i < items.length; i++) {
56820          item = items[i];
56821          minChromId = Math.min(minChromId, item.startChrom);
56822          maxChromId = Math.max(maxChromId, item.endChrom);
56823          minStartBase = Math.min(minStartBase, item.startBase);
56824          maxEndBase = Math.max(maxEndBase, item.endBase);
56825        }
56826
56827        this.startChrom = minChromId;
56828        this.endChrom = maxChromId;
56829        this.startBase = minStartBase;
56830        this.endBase = maxEndBase;
56831      }
56832
56833    }
56834
56835    class BPTree {
56836      constructor(binaryParser, startOffset, genome) {
56837        let magic = binaryParser.getInt();
56838        let blockSize = binaryParser.getInt();
56839        let keySize = binaryParser.getInt();
56840        let valSize = binaryParser.getInt();
56841        let itemCount = binaryParser.getLong();
56842        let reserved = binaryParser.getLong();
56843        let chromToId = {};
56844        let idToChrom = [];
56845        this.header = {
56846          magic: magic,
56847          blockSize: blockSize,
56848          keySize: keySize,
56849          valSize: valSize,
56850          itemCount: itemCount,
56851          reserved: reserved
56852        };
56853        this.chromToID = chromToId;
56854        this.idToChrom = idToChrom; // Recursively walk tree to populate dictionary
56855
56856        readTreeNode(binaryParser, -1);
56857
56858        function readTreeNode(byteBuffer, offset) {
56859          if (offset >= 0) byteBuffer.position = offset;
56860          let type = byteBuffer.getByte();
56861              byteBuffer.getByte();
56862              let count = byteBuffer.getUShort(),
56863              i,
56864              key,
56865              chromId,
56866              childOffset,
56867              bufferOffset,
56868              currOffset;
56869
56870          if (type === 1) {
56871            for (i = 0; i < count; i++) {
56872              key = byteBuffer.getFixedLengthTrimmedString(keySize);
56873              chromId = byteBuffer.getInt();
56874              byteBuffer.getInt();
56875              if (genome) key = genome.getChromosomeName(key); // Translate to canonical chr name
56876
56877              chromToId[key] = chromId;
56878              idToChrom[chromId] = key;
56879            }
56880          } else {
56881            // non-leaf
56882            for (i = 0; i < count; i++) {
56883              key = byteBuffer.getFixedLengthTrimmedString(keySize);
56884              childOffset = byteBuffer.getLong();
56885              bufferOffset = childOffset - startOffset;
56886              currOffset = byteBuffer.position;
56887              readTreeNode(byteBuffer, bufferOffset);
56888              byteBuffer.position = currOffset;
56889            }
56890          }
56891        }
56892      }
56893
56894    }
56895    /**
56896     * Return true if {chrIdx1:startBase-chrIdx2:endBase} overlaps item's interval
56897     * @returns {boolean}
56898     */
56899
56900
56901    function overlaps(item, chrIdx1, startBase, chrIdx2, endBase) {
56902      if (!item) {
56903        console.log("null item for " + chrIdx1 + " " + startBase + " " + endBase);
56904        return false;
56905      }
56906
56907      return (chrIdx2 > item.startChrom || chrIdx2 === item.startChrom && endBase >= item.startBase) && (chrIdx1 < item.endChrom || chrIdx1 === item.endChrom && startBase <= item.endBase);
56908    }
56909
56910    class BWTotalSummary {
56911      constructor(byteBuffer) {
56912        if (byteBuffer) {
56913          this.basesCovered = byteBuffer.getLong();
56914          this.minVal = byteBuffer.getDouble();
56915          this.maxVal = byteBuffer.getDouble();
56916          this.sumData = byteBuffer.getDouble();
56917          this.sumSquares = byteBuffer.getDouble();
56918          computeStats.call(this);
56919        } else {
56920          this.basesCovered = 0;
56921          this.minVal = 0;
56922          this.maxVal = 0;
56923          this.sumData = 0;
56924          this.sumSquares = 0;
56925          this.mean = 0;
56926          this.stddev = 0;
56927        }
56928      }
56929
56930    }
56931
56932    function computeStats() {
56933      let n = this.basesCovered;
56934
56935      if (n > 0) {
56936        this.mean = this.sumData / n;
56937        this.stddev = Math.sqrt(this.sumSquares / (n - 1));
56938        let min = this.minVal < 0 ? this.mean - 2 * this.stddev : 0,
56939            max = this.maxVal > 0 ? this.mean + 2 * this.stddev : 0;
56940        this.defaultRange = {
56941          min: min,
56942          max: max
56943        };
56944      }
56945    }
56946
56947    function zoomLevelForScale$1(bpPerPixel, zoomLevelHeaders) {
56948      let level;
56949
56950      for (let i = 0; i < zoomLevelHeaders.length; i++) {
56951        const zl = zoomLevelHeaders[i];
56952
56953        if (zl.reductionLevel < bpPerPixel) {
56954          level = zl;
56955          break;
56956        }
56957      }
56958
56959      return level;
56960    }
56961
56962    function decodeWigData(data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict) {
56963      const binaryParser = new BinaryParser(data);
56964      const chromId = binaryParser.getInt();
56965      let chromStart = binaryParser.getInt();
56966      let chromEnd = binaryParser.getInt();
56967      const itemStep = binaryParser.getInt();
56968      const itemSpan = binaryParser.getInt();
56969      const type = binaryParser.getByte();
56970      binaryParser.getByte();
56971      let itemCount = binaryParser.getUShort();
56972
56973      if (chromId >= chrIdx1 && chromId <= chrIdx2) {
56974        while (itemCount-- > 0) {
56975          let value;
56976
56977          switch (type) {
56978            case 1:
56979              chromStart = binaryParser.getInt();
56980              chromEnd = binaryParser.getInt();
56981              value = binaryParser.getFloat();
56982              break;
56983
56984            case 2:
56985              chromStart = binaryParser.getInt();
56986              value = binaryParser.getFloat();
56987              chromEnd = chromStart + itemSpan;
56988              break;
56989
56990            case 3:
56991              // Fixed step
56992              value = binaryParser.getFloat();
56993              chromEnd = chromStart + itemSpan;
56994              chromStart += itemStep;
56995              break;
56996          }
56997
56998          if (chromId < chrIdx1 || chromId === chrIdx1 && chromEnd < bpStart) continue;else if (chromId > chrIdx2 || chromId === chrIdx2 && chromStart >= bpEnd) break;
56999
57000          if (Number.isFinite(value)) {
57001            const chr = chrDict[chromId];
57002            featureArray.push({
57003              chr: chr,
57004              start: chromStart,
57005              end: chromEnd,
57006              value: value
57007            });
57008          }
57009        }
57010      }
57011    }
57012
57013    function getBedDataDecoder() {
57014      const minSize = 3 * 4 + 1; // Minimum # of bytes required for a bed record
57015
57016      const decoder = getDecoder(this.header.definedFieldCount, this.header.fieldCount, this.autoSql);
57017      return function (data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict) {
57018        const binaryParser = new BinaryParser(data);
57019
57020        while (binaryParser.remLength() >= minSize) {
57021          const chromId = binaryParser.getInt();
57022          const chr = chrDict[chromId];
57023          const chromStart = binaryParser.getInt();
57024          const chromEnd = binaryParser.getInt();
57025          const rest = binaryParser.getString();
57026          if (chromId < chrIdx1 || chromId === chrIdx1 && chromEnd < bpStart) continue;else if (chromId > chrIdx2 || chromId === chrIdx2 && chromStart >= bpEnd) break;
57027
57028          if (chromEnd > 0) {
57029            const feature = {
57030              chr: chr,
57031              start: chromStart,
57032              end: chromEnd
57033            };
57034            featureArray.push(feature);
57035            const tokens = rest.split("\t");
57036            decoder(feature, tokens);
57037          }
57038        }
57039      };
57040    }
57041
57042    function decodeZoomData(data, chrIdx1, bpStart, chrIdx2, bpEnd, featureArray, chrDict, windowFunction) {
57043      const binaryParser = new BinaryParser(data);
57044      const minSize = 8 * 4; // Minimum # of bytes required for a zoom record
57045
57046      while (binaryParser.remLength() >= minSize) {
57047        const chromId = binaryParser.getInt();
57048        const chr = chrDict[chromId];
57049        const chromStart = binaryParser.getInt();
57050        const chromEnd = binaryParser.getInt();
57051        const validCount = binaryParser.getInt();
57052        const minVal = binaryParser.getFloat();
57053        const maxVal = binaryParser.getFloat();
57054        const sumData = binaryParser.getFloat();
57055        binaryParser.getFloat();
57056        let value;
57057
57058        switch (windowFunction) {
57059          case "min":
57060            value = minVal;
57061            break;
57062
57063          case "max":
57064            value = maxVal;
57065            break;
57066
57067          default:
57068            value = validCount === 0 ? 0 : sumData / validCount;
57069        }
57070
57071        if (chromId < chrIdx1 || chromId === chrIdx1 && chromEnd < bpStart) continue;else if (chromId > chrIdx2 || chromId === chrIdx2 && chromStart >= bpEnd) break;
57072
57073        if (Number.isFinite(value)) {
57074          featureArray.push({
57075            chr: chr,
57076            start: chromStart,
57077            end: chromEnd,
57078            value: value
57079          });
57080        }
57081      }
57082    }
57083
57084    class DataBuffer {
57085      constructor(dataURI) {
57086        this.data = decodeDataURI$1(dataURI).buffer;
57087      }
57088      /**
57089       * igvxhr interface
57090       * @param ignore
57091       * @param options
57092       * @returns {any}
57093       */
57094
57095
57096      loadArrayBuffer(ignore, options) {
57097        const range = options.range;
57098        return range ? this.data.slice(range.start, range.start + range.size) : this.data;
57099      }
57100      /**
57101       * BufferedReader interface
57102       *
57103       * @param requestedRange - byte rangeas {start, size}
57104       * @param fulfill - function to receive result
57105       * @param asUint8 - optional flag to return result as an UInt8Array
57106       */
57107
57108
57109      async dataViewForRange(requestedRange, asUint8) {
57110        const len = Math.min(this.data.byteLength - requestedRange.start, requestedRange.size);
57111        return asUint8 ? new Uint8Array(this.data, requestedRange.start, len) : new DataView(this.data, requestedRange.start, len);
57112      }
57113
57114    }
57115
57116    /*
57117     * The MIT License (MIT)
57118     *
57119     * Copyright (c) 2014 Broad Institute
57120     *
57121     * Permission is hereby granted, free of charge, to any person obtaining a copy
57122     * of this software and associated documentation files (the "Software"), to deal
57123     * in the Software without restriction, including without limitation the rights
57124     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57125     * copies of the Software, and to permit persons to whom the Software is
57126     * furnished to do so, subject to the following conditions:
57127     *
57128     * The above copyright notice and this permission notice shall be included in
57129     * all copies or substantial portions of the Software.
57130     *
57131     *
57132     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57133     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57134     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57135     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57136     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57137     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
57138     * THE SOFTWARE.
57139     */
57140
57141    class BWSource {
57142      constructor(config, genome) {
57143        this.reader = new BWReader(config, genome);
57144        this.genome = genome;
57145        this.format = config.format || "bigwig";
57146        this.wgValues = {};
57147      }
57148
57149      async getFeatures(_ref) {
57150        let {
57151          chr,
57152          start,
57153          end,
57154          bpPerPixel,
57155          windowFunction
57156        } = _ref;
57157        const features = chr.toLowerCase() === "all" ? await this.getWGValues(windowFunction) : await this.reader.readFeatures(chr, start, chr, end, bpPerPixel, windowFunction);
57158        const isBigWig = this.reader.type === "bigwig";
57159
57160        if (!isBigWig) {
57161          pack(features);
57162        }
57163
57164        return features;
57165      }
57166
57167      async getHeader() {
57168        return this.reader.loadHeader();
57169      }
57170
57171      getDefaultRange() {
57172        if (this.reader.totalSummary !== undefined) {
57173          return this.reader.totalSummary.defaultRange;
57174        } else {
57175          return undefined;
57176        }
57177      }
57178
57179      async defaultVisibilityWindow() {
57180        return this.reader.defaultVisibilityWindow;
57181      }
57182
57183      async getWGValues(windowFunction) {
57184        const nominalScreenWidth = 1000; // This doesn't need to be precise
57185
57186        const genome = this.genome;
57187
57188        if (this.wgValues[windowFunction]) {
57189          return this.wgValues[windowFunction];
57190        } else {
57191          const bpPerPixel = genome.getGenomeLength() / nominalScreenWidth;
57192          const features = await this.reader.readWGFeatures(bpPerPixel, windowFunction);
57193          let wgValues = [];
57194
57195          for (let f of features) {
57196            const chr = f.chr;
57197            const offset = genome.getCumulativeOffset(chr);
57198            const wgFeature = Object.assign({}, f);
57199            wgFeature.chr = "all";
57200            wgFeature.start = offset + f.start;
57201            wgFeature.end = offset + f.end;
57202            wgValues.push(wgFeature);
57203          }
57204
57205          this.wgValues[windowFunction] = wgValues;
57206          return wgValues;
57207        }
57208      }
57209
57210      supportsWholeGenome() {
57211        return this.reader.type === "bigwig" || this.defaultVisibilityWindow() <= 0;
57212      }
57213
57214      async trackType() {
57215        return this.reader.getTrackType();
57216      }
57217
57218    }
57219
57220    /*
57221     * The MIT License (MIT)
57222     *
57223     * Copyright (c) 2016 University of California San Diego
57224     * Author: Jim Robinson
57225     *
57226     * Permission is hereby granted, free of charge, to any person obtaining a copy
57227     * of this software and associated documentation files (the "Software"), to deal
57228     * in the Software without restriction, including without limitation the rights
57229     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57230     * copies of the Software, and to permit persons to whom the Software is
57231     * furnished to do so, subject to the following conditions:
57232     *
57233     * The above copyright notice and this permission notice shall be included in
57234     * all copies or substantial portions of the Software.
57235     *
57236     *
57237     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57238     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57239     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57240     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57241     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57242     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
57243     * THE SOFTWARE.
57244     */
57245    const GZIP_FLAG = 0x1;
57246
57247    class TDFReader {
57248      constructor(config, genome) {
57249        this.config = config;
57250        this.genome = genome;
57251        this.path = config.url;
57252        this.groupCache = {};
57253        this.datasetCache = {};
57254      }
57255
57256      async readHeader() {
57257        if (this.magic !== undefined) {
57258          return this; // Already read
57259        }
57260
57261        let data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {
57262          range: {
57263            start: 0,
57264            size: 64000
57265          }
57266        }));
57267        let binaryParser = new BinaryParser(new DataView(data));
57268        this.magic = binaryParser.getInt();
57269        this.version = binaryParser.getInt();
57270        this.indexPos = binaryParser.getLong();
57271        this.indexSize = binaryParser.getInt();
57272        binaryParser.getInt();
57273
57274        if (this.version >= 2) {
57275          let nWindowFunctions = binaryParser.getInt();
57276          this.windowFunctions = [];
57277
57278          while (nWindowFunctions-- > 0) {
57279            this.windowFunctions.push(binaryParser.getString());
57280          }
57281        }
57282
57283        this.trackType = binaryParser.getString();
57284        this.trackLine = binaryParser.getString();
57285        let nTracks = binaryParser.getInt();
57286        this.trackNames = [];
57287
57288        while (nTracks-- > 0) {
57289          this.trackNames.push(binaryParser.getString());
57290        }
57291
57292        this.genomeID = binaryParser.getString();
57293        this.flags = binaryParser.getInt();
57294        this.compressed = (this.flags & GZIP_FLAG) !== 0; // Now read index
57295
57296        data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {
57297          range: {
57298            start: this.indexPos,
57299            size: this.indexSize
57300          }
57301        }));
57302        binaryParser = new BinaryParser(new DataView(data));
57303        this.datasetIndex = {};
57304        let nEntries = binaryParser.getInt();
57305
57306        while (nEntries-- > 0) {
57307          const name = binaryParser.getString();
57308          const pos = binaryParser.getLong();
57309          const size = binaryParser.getInt();
57310          this.datasetIndex[name] = {
57311            position: pos,
57312            size: size
57313          };
57314        }
57315
57316        this.groupIndex = {};
57317        nEntries = binaryParser.getInt();
57318
57319        while (nEntries-- > 0) {
57320          const name = binaryParser.getString();
57321          const pos = binaryParser.getLong();
57322          const size = binaryParser.getInt();
57323          this.groupIndex[name] = {
57324            position: pos,
57325            size: size
57326          };
57327        }
57328
57329        return this;
57330      }
57331
57332      async readDataset(chr, windowFunction, zoom) {
57333        const key = chr + "_" + windowFunction + "_" + zoom;
57334
57335        if (this.datasetCache[key]) {
57336          return this.datasetCache[key];
57337        } else {
57338          await this.readHeader();
57339          const wf = this.version < 2 ? "" : "/" + windowFunction;
57340          const zoomString = chr.toLowerCase() === "all" || zoom === undefined ? "0" : zoom.toString();
57341          let dsName;
57342
57343          if (windowFunction === "raw") {
57344            dsName = "/" + chr + "/raw";
57345          } else {
57346            dsName = "/" + chr + "/z" + zoomString + wf;
57347          }
57348
57349          const indexEntry = this.datasetIndex[dsName];
57350
57351          if (indexEntry === undefined) {
57352            return undefined;
57353          }
57354
57355          const data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {
57356            range: {
57357              start: indexEntry.position,
57358              size: indexEntry.size
57359            }
57360          }));
57361
57362          if (!data) {
57363            return undefined;
57364          }
57365
57366          const binaryParser = new BinaryParser(new DataView(data));
57367          let nAttributes = binaryParser.getInt();
57368          const attributes = {};
57369
57370          while (nAttributes-- > 0) {
57371            attributes[binaryParser.getString()] = binaryParser.getString();
57372          }
57373
57374          const dataType = binaryParser.getString();
57375          const tileWidth = binaryParser.getFloat();
57376          let nTiles = binaryParser.getInt();
57377          const tiles = [];
57378
57379          while (nTiles-- > 0) {
57380            tiles.push({
57381              position: binaryParser.getLong(),
57382              size: binaryParser.getInt()
57383            });
57384          }
57385
57386          const dataset = {
57387            name: dsName,
57388            attributes: attributes,
57389            dataType: dataType,
57390            tileWidth: tileWidth,
57391            tiles: tiles
57392          };
57393          this.datasetCache[key] = dataset;
57394          return dataset;
57395        }
57396      }
57397
57398      async readRootGroup() {
57399        const genome = this.genome;
57400        const rootGroup = this.groupCache["/"];
57401
57402        if (rootGroup) {
57403          return rootGroup;
57404        } else {
57405          const group = await this.readGroup("/");
57406          const names = group["chromosomes"];
57407          const maxZoomString = group["maxZoom"]; // Now parse out interesting attributes.
57408
57409          if (maxZoomString) {
57410            this.maxZoom = Number(maxZoomString);
57411          }
57412
57413          const totalCountString = group["totalCount"];
57414
57415          if (totalCountString) {
57416            group.totalCount = Number(totalCountString);
57417          } // Chromosome names
57418
57419
57420          const chrAliasTable = {};
57421
57422          if (names) {
57423            names.split(",").forEach(function (chr) {
57424              const canonicalName = genome.getChromosomeName(chr);
57425              chrAliasTable[canonicalName] = chr;
57426            });
57427          }
57428
57429          this.chrAliasTable = chrAliasTable;
57430          this.groupCache["/"] = group;
57431          return group;
57432        }
57433      }
57434
57435      async readGroup(name) {
57436        const group = this.groupCache[name];
57437
57438        if (group) {
57439          return group;
57440        } else {
57441          await this.readHeader();
57442          const indexEntry = this.groupIndex[name];
57443
57444          if (indexEntry === undefined) {
57445            return undefined;
57446          }
57447
57448          const data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {
57449            range: {
57450              start: indexEntry.position,
57451              size: indexEntry.size
57452            }
57453          }));
57454
57455          if (!data) {
57456            return undefined;
57457          }
57458
57459          const binaryParser = new BinaryParser(new DataView(data));
57460          const group = {
57461            name: name
57462          };
57463          let nAttributes = binaryParser.getInt();
57464
57465          while (nAttributes-- > 0) {
57466            const key = binaryParser.getString();
57467            const value = binaryParser.getString();
57468            group[key] = value;
57469          }
57470
57471          this.groupCache[name] = group;
57472          return group;
57473        }
57474      }
57475
57476      async readTiles(tileIndeces, nTracks) {
57477        tileIndeces.sort(function (a, b) {
57478          return a.position - b.position;
57479        });
57480        tileIndeces = tileIndeces.filter(function (idx) {
57481          return idx.size > 0;
57482        });
57483
57484        if (tileIndeces.length === 0) {
57485          return Promise.resolve([]);
57486        }
57487
57488        const firstEntry = tileIndeces[0];
57489        const lastEntry = tileIndeces[tileIndeces.length - 1];
57490        const position = firstEntry.position;
57491        const size = lastEntry.position + lastEntry.size - position;
57492        const data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {
57493          range: {
57494            start: position,
57495            size: size
57496          }
57497        }));
57498        const tiles = []; // Loop through and decode tiles
57499
57500        for (let indexEntry of tileIndeces) {
57501          const start = indexEntry.position - position;
57502          const size = indexEntry.size;
57503
57504          if (size > 0) {
57505            let tileData;
57506
57507            if (this.compressed) {
57508              const plain = inflate(data.slice(start, start + size));
57509              tileData = plain.buffer;
57510            } else {
57511              tileData = data.slice(start, start + size);
57512            }
57513
57514            const binaryParser = new BinaryParser(new DataView(tileData));
57515            const type = binaryParser.getString();
57516            let tile;
57517
57518            switch (type) {
57519              case "fixedStep":
57520                tile = createFixedStep(binaryParser, nTracks);
57521                break;
57522
57523              case "variableStep":
57524                tile = createVariableStep(binaryParser, nTracks);
57525                break;
57526
57527              case "bed":
57528              case "bedWithName":
57529                tile = createBed(binaryParser, nTracks, type);
57530                break;
57531
57532              default:
57533                throw "Unknown tile type: " + type;
57534            }
57535
57536            tiles.push(tile);
57537          }
57538        }
57539
57540        return tiles;
57541      }
57542
57543      async readTile(indexEntry, nTracks) {
57544        let data = await igvxhr.loadArrayBuffer(this.path, buildOptions(this.config, {
57545          range: {
57546            start: indexEntry.position,
57547            size: indexEntry.size
57548          }
57549        }));
57550
57551        if (this.compressed) {
57552          const plain = inflate(data);
57553          data = plain.buffer;
57554        }
57555
57556        const binaryParser = new BinaryParser(new DataView(data));
57557        const type = binaryParser.getString();
57558
57559        switch (type) {
57560          case "fixedStep":
57561            return createFixedStep(binaryParser, nTracks);
57562
57563          case "variableStep":
57564            return createVariableStep(binaryParser, nTracks);
57565
57566          case "bed":
57567          case "bedWithName":
57568            return createBed(binaryParser, nTracks, type);
57569
57570          default:
57571            throw "Unknown tile type: " + type;
57572        }
57573      }
57574
57575    }
57576
57577    function createFixedStep(binaryParser, nTracks) {
57578      const nPositions = binaryParser.getInt();
57579      const start = binaryParser.getInt();
57580      const span = binaryParser.getFloat();
57581      const data = [];
57582      let nt = nTracks;
57583
57584      while (nt-- > 0) {
57585        let np = nPositions;
57586        const dtrack = [];
57587
57588        while (np-- > 0) {
57589          dtrack.push(binaryParser.getFloat());
57590        }
57591
57592        data.push(dtrack);
57593      }
57594
57595      return {
57596        type: "fixedStep",
57597        start: start,
57598        span: span,
57599        data: data,
57600        nTracks: nTracks,
57601        nPositions: nPositions
57602      };
57603    }
57604
57605    function createVariableStep(binaryParser, nTracks) {
57606      const tileStart = binaryParser.getInt();
57607      const span = binaryParser.getFloat();
57608      const nPositions = binaryParser.getInt();
57609      const start = [];
57610      let np = nPositions;
57611
57612      while (np-- > 0) {
57613        start.push(binaryParser.getInt());
57614      }
57615
57616      binaryParser.getInt(); // # of samples, ignored but should === nTracks
57617
57618      const data = [];
57619      let nt = nTracks;
57620
57621      while (nt-- > 0) {
57622        np = nPositions;
57623        const dtrack = [];
57624
57625        while (np-- > 0) {
57626          dtrack.push(binaryParser.getFloat());
57627        }
57628
57629        data.push(dtrack);
57630      }
57631
57632      return {
57633        type: "variableStep",
57634        tileStart: tileStart,
57635        span: span,
57636        start: start,
57637        data: data,
57638        nTracks: nTracks,
57639        nPositions: nPositions
57640      };
57641    }
57642
57643    function createBed(binaryParser, nTracks, type) {
57644      const nPositions = binaryParser.getInt();
57645      let n = nPositions;
57646      const start = [];
57647
57648      while (n-- > 0) {
57649        start.push(binaryParser.getInt());
57650      }
57651
57652      n = nPositions;
57653      const end = [];
57654
57655      while (n-- > 0) {
57656        end.push(binaryParser.getInt());
57657      }
57658
57659      binaryParser.getInt(); // # of samples, ignored but should === nTracks
57660
57661      const data = [];
57662      let nt = nTracks;
57663
57664      while (nt-- > 0) {
57665        let np = nPositions;
57666        const dtrack = [];
57667
57668        while (np-- > 0) {
57669          dtrack.push(binaryParser.getFloat());
57670        }
57671
57672        data.push(dtrack);
57673      }
57674
57675      if (type === "bedWithName") {
57676        n = nPositions;
57677        const name = [];
57678
57679        while (n-- > 0) {
57680          name.push(binaryParser.getString());
57681        }
57682      }
57683
57684      return {
57685        type: type,
57686        start: start,
57687        end: end,
57688        data: data,
57689        nTracks: nTracks,
57690        nPositions: nPositions
57691      };
57692    }
57693
57694    /*
57695     * The MIT License (MIT)
57696     *
57697     * Copyright (c) 2016 University of California San Diego
57698     * Author: Jim Robinson
57699     *
57700     * Permission is hereby granted, free of charge, to any person obtaining a copy
57701     * of this software and associated documentation files (the "Software"), to deal
57702     * in the Software without restriction, including without limitation the rights
57703     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57704     * copies of the Software, and to permit persons to whom the Software is
57705     * furnished to do so, subject to the following conditions:
57706     *
57707     * The above copyright notice and this permission notice shall be included in
57708     * all copies or substantial portions of the Software.
57709     *
57710     *
57711     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57712     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57713     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57714     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57715     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57716     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
57717     * THE SOFTWARE.
57718     */
57719
57720    class TDFSource {
57721      constructor(config, genome) {
57722        this.genome = genome;
57723        this.windowFunction = config.windowFunction || "mean";
57724        this.reader = new TDFReader(config, genome);
57725      }
57726
57727      async getFeatures(_ref) {
57728        let {
57729          chr,
57730          start,
57731          end,
57732          bpPerPixel
57733        } = _ref;
57734
57735        if (chr.toLowerCase() === "all") {
57736          const wgFeatures = [];
57737          const genome = this.genome;
57738          const chrNames = this.genome.wgChromosomeNames;
57739
57740          if (chrNames) {
57741            for (let c of genome.wgChromosomeNames) {
57742              const len = genome.getChromosome(c).bpLength;
57743              bpPerPixel = len / 1000;
57744              const chrFeatures = await this._getFeatures(c, 0, len, bpPerPixel);
57745
57746              if (chrFeatures) {
57747                for (let f of chrFeatures) {
57748                  const wg = Object.assign({}, f);
57749                  wg.chr = "all";
57750                  wg.start = genome.getGenomeCoordinate(f.chr, f.start);
57751                  wg.end = genome.getGenomeCoordinate(f.chr, f.end);
57752                  wg._f = f;
57753                  wgFeatures.push(wg);
57754                }
57755              }
57756            }
57757          }
57758
57759          return wgFeatures;
57760        } else {
57761          return this._getFeatures(chr, start, end, bpPerPixel);
57762        }
57763      }
57764
57765      async _getFeatures(chr, start, end, bpPerPixel) {
57766        const genomicInterval = new GenomicInterval(chr, start, end);
57767        const genome = this.genome;
57768
57769        if (!this.rootGroup) {
57770          this.rootGroup = await this.reader.readRootGroup();
57771
57772          if (!this.normalizationFactor) {
57773            const totalCount = this.rootGroup.totalCount;
57774
57775            if (totalCount) {
57776              this.normalizationFactor = 1.0e6 / totalCount;
57777            }
57778          }
57779        }
57780
57781        genomicInterval.bpPerPixel = bpPerPixel;
57782        const zoom = zoomLevelForScale(chr, bpPerPixel, genome);
57783        let queryChr = this.reader.chrAliasTable[chr];
57784        let maxZoom = this.reader.maxZoom;
57785        if (queryChr === undefined) queryChr = chr;
57786        if (maxZoom === undefined) maxZoom = -1;
57787        const wf = zoom > maxZoom ? "raw" : this.windowFunction;
57788        const dataset = await this.reader.readDataset(queryChr, wf, zoom);
57789
57790        if (dataset == null) {
57791          return [];
57792        }
57793
57794        const tileWidth = dataset.tileWidth;
57795        const startTile = Math.floor(start / tileWidth);
57796        const endTile = Math.floor(end / tileWidth);
57797        const NTRACKS = 1; // TODO read this
57798
57799        const tiles = await this.reader.readTiles(dataset.tiles.slice(startTile, endTile + 1), NTRACKS);
57800        const features = [];
57801
57802        for (let tile of tiles) {
57803          switch (tile.type) {
57804            case "bed":
57805              decodeBedTile(tile, chr, start, end, bpPerPixel, features);
57806              break;
57807
57808            case "variableStep":
57809              decodeVaryTile(tile, chr, start, end, bpPerPixel, features);
57810              break;
57811
57812            case "fixedStep":
57813              decodeFixedTile(tile, chr, start, end, bpPerPixel, features);
57814              break;
57815
57816            default:
57817              throw "Unknown tile type: " + tile.type;
57818          }
57819        }
57820
57821        features.sort(function (a, b) {
57822          return a.start - b.start;
57823        });
57824        return features;
57825      }
57826
57827      supportsWholeGenome() {
57828        return true;
57829      }
57830
57831    }
57832
57833    function decodeBedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) {
57834      const nPositions = tile.nPositions;
57835      const starts = tile.start;
57836      const ends = tile.end;
57837      const data = tile.data[0]; // Single track for now
57838
57839      for (let i = 0; i < nPositions; i++) {
57840        const s = starts[i];
57841        const e = ends[i];
57842        if (e < bpStart) continue;
57843        if (s > bpEnd) break;
57844        features.push({
57845          chr: chr,
57846          start: s,
57847          end: e,
57848          value: data[i]
57849        });
57850      }
57851    }
57852
57853    function decodeVaryTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) {
57854      const nPositions = tile.nPositions;
57855      const starts = tile.start;
57856      const span = tile.span;
57857      const data = tile.data[0]; // Single track for now
57858
57859      for (let i = 0; i < nPositions; i++) {
57860        const s = starts[i];
57861        const e = s + span;
57862        if (e < bpStart) continue;
57863        if (s > bpEnd) break;
57864        features.push({
57865          chr: chr,
57866          start: s,
57867          end: e,
57868          value: data[i]
57869        });
57870      }
57871    }
57872
57873    function decodeFixedTile(tile, chr, bpStart, bpEnd, bpPerPixel, features) {
57874      const nPositions = tile.nPositions;
57875      let s = tile.start;
57876      const span = tile.span;
57877      const data = tile.data[0]; // Single track for now
57878
57879      for (let i = 0; i < nPositions; i++) {
57880        const e = s + span;
57881        if (s > bpEnd) break;
57882
57883        if (e >= bpStart) {
57884          if (!Number.isNaN(data[i])) {
57885            features.push({
57886              chr: chr,
57887              start: s,
57888              end: e,
57889              value: data[i]
57890            });
57891          }
57892        }
57893
57894        s = e;
57895      }
57896    }
57897
57898    var log2 = Math.log(2);
57899
57900    function zoomLevelForScale(chr, bpPerPixel, genome) {
57901      // Convert bpPerPixel to IGV "zoom" level.   This is a bit convoluted,  IGV computes zoom levels assuming
57902      // display in a 700 pixel window.  The fully zoomed out view of a chromosome is zoom level "0".
57903      // Zoom level 1 is magnified 2X,  and so forth
57904      var chrSize = genome.getChromosome(chr).bpLength;
57905      return Math.ceil(Math.log(Math.max(0, chrSize / (bpPerPixel * 700))) / log2);
57906    }
57907
57908    /*
57909     * The MIT License (MIT)
57910     *
57911     * Copyright (c) 2014-2015 Broad Institute
57912     *
57913     * Permission is hereby granted, free of charge, to any person obtaining a copy
57914     * of this software and associated documentation files (the "Software"), to deal
57915     * in the Software without restriction, including without limitation the rights
57916     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57917     * copies of the Software, and to permit persons to whom the Software is
57918     * furnished to do so, subject to the following conditions:
57919     *
57920     * The above copyright notice and this permission notice shall be included in
57921     * all copies or substantial portions of the Software.
57922     *
57923     *
57924     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
57925     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57926     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57927     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
57928     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57929     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
57930     * THE SOFTWARE.
57931     */
57932
57933    function FeatureSource(config, genome) {
57934      const format = config.format ? config.format.toLowerCase() : undefined;
57935
57936      if ('bigwig' === format || 'bigbed' === format || 'bb' === format) {
57937        return new BWSource(config, genome);
57938      } else if ("tdf" === format) {
57939        return new TDFSource(config, genome);
57940      } else {
57941        return new TextFeatureSource(config, genome);
57942      }
57943    }
57944
57945    const pairs = [['A', 'T'], ['G', 'C'], ['Y', 'R'], ['W', 'S'], ['K', 'M'], ['D', 'H'], ['B', 'V']];
57946    const complements = new Map();
57947
57948    for (let p of pairs) {
57949      const p1 = p[0];
57950      const p2 = p[1];
57951      complements.set(p1, p2);
57952      complements.set(p2, p1);
57953      complements.set(p1.toLowerCase(), p2.toLowerCase());
57954      complements.set(p2.toLowerCase(), p1.toLowerCase());
57955    }
57956
57957    function reverseComplementSequence(sequence) {
57958      let comp = '';
57959      let idx = sequence.length;
57960
57961      while (idx-- > 0) {
57962        const base = sequence[idx];
57963        comp += complements.has(base) ? complements.get(base) : base;
57964      }
57965
57966      return comp;
57967    }
57968
57969    const GtexUtils = {
57970      getTissueInfo: function (datasetId, baseURL) {
57971        datasetId = datasetId || 'gtex_v8';
57972        baseURL = baseURL || 'https://gtexportal.org/rest/v1';
57973        let url = baseURL + '/dataset/tissueInfo?datasetId=' + datasetId;
57974        return igvxhr.loadJson(url, {});
57975      },
57976      //https://gtexportal.org/rest/v1/association/singleTissueEqtlByLocation?chromosome=7&start=98358766&end=101523798&tissueName=Liver&datasetId=gtex_v7
57977      //https://gtexportal.org/rest/v1/association/singleTissueEqtlByLocation?chromosome=7&start=98358766&end=101523798&tissueSiteDetailId=Liver&datasetId=gtex_v8
57978      trackConfiguration: function (tissueSummary, baseURL) {
57979        baseURL = baseURL || 'https://gtexportal.org/rest/v1';
57980        return {
57981          type: "eqtl",
57982          sourceType: "gtex-ws",
57983          url: baseURL + '/association/singleTissueEqtlByLocation',
57984          tissueSiteDetailId: tissueSummary.tissueSiteDetailId,
57985          name: tissueSummary.tissueSiteDetailId.split('_').join(' '),
57986          visibilityWindow: 250000
57987        };
57988      }
57989    };
57990
57991    /**
57992     * @param feature
57993     * @param bpStart  genomic location of the left edge of the current canvas
57994     * @param xScale  scale in base-pairs per pixel
57995     * @returns {{px: number, px1: number, pw: number, h: number, py: number}}
57996     */
57997
57998    function calculateFeatureCoordinates(feature, bpStart, xScale) {
57999      let px = (feature.start - bpStart) / xScale;
58000      let px1 = (feature.end - bpStart) / xScale; //px = Math.round((feature.start - bpStart) / xScale),
58001      //px1 = Math.round((feature.end - bpStart) / xScale),
58002
58003      let pw = px1 - px;
58004
58005      if (pw < 3) {
58006        pw = 3;
58007        px -= 1.5;
58008      }
58009
58010      return {
58011        px: px,
58012        px1: px1,
58013        pw: pw
58014      };
58015    }
58016    /**
58017     *
58018     * @param feature
58019     * @param bpStart  genomic location of the left edge of the current canvas
58020     * @param xScale  scale in base-pairs per pixel
58021     * @param pixelHeight  pixel height of the current canvas
58022     * @param ctx  the canvas 2d context
58023     * @param options  genomic state
58024     */
58025
58026    function renderFeature(feature, bpStart, xScale, pixelHeight, ctx, options) {
58027      try {
58028        ctx.save(); // Set ctx color to a known valid color.  If getColorForFeature returns an invalid color string it is ignored, and
58029        // this default will be used.
58030
58031        ctx.fillStyle = this.defaultColor;
58032        ctx.strokeStyle = this.defaultColor;
58033        const color = getColorForFeature.call(this, feature);
58034        ctx.fillStyle = color;
58035        ctx.strokeStyle = color;
58036        let h;
58037        let py;
58038
58039        if (this.displayMode === "SQUISHED" && feature.row !== undefined) {
58040          h = this.featureHeight / 2;
58041          py = this.margin + this.squishedRowHeight * feature.row;
58042        } else if (this.displayMode === "EXPANDED" && feature.row !== undefined) {
58043          h = this.featureHeight;
58044          py = this.margin + this.expandedRowHeight * feature.row;
58045        } else {
58046          // collapsed
58047          h = this.featureHeight;
58048          py = this.margin;
58049        }
58050
58051        const pixelWidth = options.pixelWidth;
58052        const cy = py + h / 2;
58053        const h2 = h / 2;
58054        const py2 = cy - h2 / 2;
58055        const exonCount = feature.exons ? feature.exons.length : 0;
58056        const coord = calculateFeatureCoordinates(feature, bpStart, xScale);
58057        const step = this.arrowSpacing;
58058        const direction = feature.strand === '+' ? 1 : feature.strand === '-' ? -1 : 0;
58059
58060        if (exonCount === 0) {
58061          // single-exon transcript
58062          const xLeft = Math.max(0, coord.px);
58063          const xRight = Math.min(pixelWidth, coord.px1);
58064          const width = Math.max(coord.pw, xRight - xLeft);
58065          ctx.fillRect(xLeft, py, width, h); // Arrows
58066          // Do not draw if strand is not +/-
58067
58068          if (direction !== 0) {
58069            ctx.fillStyle = "white";
58070            ctx.strokeStyle = "white";
58071
58072            for (let x = xLeft + step / 2; x < xRight; x += step) {
58073              // draw arrowheads along central line indicating transcribed orientation
58074              IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy);
58075              IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy);
58076            }
58077
58078            ctx.fillStyle = color;
58079            ctx.strokeStyle = color;
58080          }
58081        } else {
58082          // multi-exon transcript
58083          IGVGraphics.strokeLine(ctx, coord.px + 1, cy, coord.px1 - 1, cy); // center line for introns
58084
58085          const xLeft = Math.max(0, coord.px) + step / 2;
58086          const xRight = Math.min(pixelWidth, coord.px1);
58087
58088          for (let x = xLeft; x < xRight; x += step) {
58089            // draw arrowheads along central line indicating transcribed orientation
58090            IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy);
58091            IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy);
58092          }
58093
58094          for (let e = 0; e < exonCount; e++) {
58095            // draw the exons
58096            const exon = feature.exons[e];
58097            let ePx = Math.round((exon.start - bpStart) / xScale);
58098            let ePx1 = Math.round((exon.end - bpStart) / xScale);
58099            let ePw = Math.max(1, ePx1 - ePx);
58100            let ePxU;
58101
58102            if (ePx + ePw < 0) {
58103              continue; // Off the left edge
58104            }
58105
58106            if (ePx > pixelWidth) {
58107              break; // Off the right edge
58108            }
58109
58110            if (exon.utr) {
58111              ctx.fillRect(ePx, py2, ePw, h2); // Entire exon is UTR
58112            } else {
58113              if (exon.cdStart) {
58114                ePxU = Math.round((exon.cdStart - bpStart) / xScale);
58115                ctx.fillRect(ePx, py2, ePxU - ePx, h2); // start is UTR
58116
58117                ePw -= ePxU - ePx;
58118                ePx = ePxU;
58119              }
58120
58121              if (exon.cdEnd) {
58122                ePxU = Math.round((exon.cdEnd - bpStart) / xScale);
58123                ctx.fillRect(ePxU, py2, ePx1 - ePxU, h2); // start is UTR
58124
58125                ePw -= ePx1 - ePxU;
58126                ePx1 = ePxU;
58127              }
58128
58129              ePw = Math.max(ePw, 1);
58130              ctx.fillRect(ePx, py, ePw, h); // Arrows
58131
58132              if (ePw > step + 5 && direction !== 0) {
58133                ctx.fillStyle = "white";
58134                ctx.strokeStyle = "white";
58135
58136                for (let x = ePx + step / 2; x < ePx1; x += step) {
58137                  // draw arrowheads along central line indicating transcribed orientation
58138                  IGVGraphics.strokeLine(ctx, x - direction * 2, cy - 2, x, cy);
58139                  IGVGraphics.strokeLine(ctx, x - direction * 2, cy + 2, x, cy);
58140                }
58141
58142                ctx.fillStyle = color;
58143                ctx.strokeStyle = color;
58144              }
58145            }
58146          }
58147        }
58148
58149        if (options.drawLabel && this.displayMode !== "SQUISHED") {
58150          renderFeatureLabel.call(this, ctx, feature, coord.px, coord.px1, py, options.referenceFrame, options);
58151        }
58152      } finally {
58153        ctx.restore();
58154      }
58155    }
58156    /**
58157     * @param ctx       the canvas 2d context
58158     * @param feature
58159     * @param featureX  feature start x-coordinate
58160     * @param featureX1 feature end x-coordinate
58161     * @param featureY  feature y-coordinate
58162     * @param windowX   visible window start x-coordinate
58163     * @param windowX1  visible window end x-coordinate
58164     * @param referenceFrame  genomic state
58165     * @param options  options
58166     */
58167
58168    function renderFeatureLabel(ctx, feature, featureX, featureX1, featureY, referenceFrame, options) {
58169      try {
58170        ctx.save();
58171        let name = feature.name;
58172        if (name === undefined && feature.gene) name = feature.gene.name;
58173        if (name === undefined) name = feature.id || feature.ID;
58174        if (!name || name === '.') return;
58175        let pixelXOffset = options.pixelXOffset || 0;
58176        const t1 = Math.max(featureX, -pixelXOffset);
58177        const t2 = Math.min(featureX1, -pixelXOffset + options.viewportWidth);
58178        const centerX = (t1 + t2) / 2;
58179        let transform;
58180
58181        if (this.displayMode === "COLLAPSED" && this.labelDisplayMode === "SLANT") {
58182          transform = {
58183            rotate: {
58184              angle: 45
58185            }
58186          };
58187        }
58188
58189        const labelY = getFeatureLabelY(featureY, transform);
58190        let color = getColorForFeature.call(this, feature);
58191        let geneColor;
58192        let gtexSelection = false;
58193
58194        if (referenceFrame.selection && GtexUtils.gtexLoaded) {
58195          // TODO -- for gtex, figure out a better way to do this
58196          gtexSelection = true;
58197          geneColor = referenceFrame.selection.colorForGene(name);
58198        }
58199
58200        const geneFontStyle = {
58201          textAlign: "SLANT" === this.labelDisplayMode ? undefined : 'center',
58202          fillStyle: geneColor || color,
58203          strokeStyle: geneColor || color
58204        };
58205        const textBox = ctx.measureText(name);
58206        const xleft = centerX - textBox.width / 2;
58207        const xright = centerX + textBox.width / 2;
58208
58209        if (options.labelAllFeatures || xleft > options.rowLastX[feature.row] || gtexSelection) {
58210          options.rowLastX[feature.row] = xright;
58211          IGVGraphics.fillText(ctx, name, centerX, labelY, geneFontStyle, transform);
58212        }
58213      } finally {
58214        ctx.restore();
58215      }
58216    }
58217
58218    function getFeatureLabelY(featureY, transform) {
58219      return transform ? featureY + 20 : featureY + 25;
58220    }
58221    /**
58222     * Return color for feature.  Called in the context of a FeatureTrack instance.
58223     * @param feature
58224     * @returns {string}
58225     */
58226
58227
58228    function getColorForFeature(feature) {
58229      let color;
58230
58231      if (this.altColor && "-" === feature.strand) {
58232        color = typeof this.altColor === "function" ? this.altColor(feature) : this.altColor;
58233      } else if (this.color) {
58234        color = typeof this.color === "function" ? this.color(feature) : this.color; // Explicit setting via menu, or possibly track line if !config.color
58235      } else if (this.colorBy) {
58236        const value = feature.getAttributeValue ? feature.getAttributeValue(this.colorBy) : feature[this.colorBy];
58237        color = this.colorTable.getColor(value);
58238      } else if (feature.color) {
58239        color = feature.color; // Explicit color for feature
58240      } else {
58241        color = this.defaultColor; // Track default
58242      }
58243
58244      if (feature.alpha && feature.alpha !== 1) {
58245        color = IGVColor.addAlpha(color, feature.alpha);
58246      } else if (this.useScore && feature.score && !Number.isNaN(feature.score)) {
58247        // UCSC useScore option, for scores between 0-1000.  See https://genome.ucsc.edu/goldenPath/help/customTrack.html#TRACK
58248        const min = this.config.min ? this.config.min : 0; //getViewLimitMin(track);
58249
58250        const max = this.config.max ? this.config.max : 1000; //getViewLimitMax(track);
58251
58252        const alpha = getAlpha(min, max, feature.score);
58253        feature.alpha = alpha; // Avoid computing again
58254
58255        color = IGVColor.addAlpha(color, alpha);
58256      }
58257
58258      function getAlpha(min, max, score) {
58259        const binWidth = (max - min) / 9;
58260        const binNumber = Math.floor((score - min) / binWidth);
58261        return Math.min(1.0, 0.2 + binNumber * 0.8 / 9);
58262      }
58263
58264      return color;
58265    }
58266
58267    // SNP constants
58268    const codingNonSynonSet = new Set(['nonsense', 'missense', 'stop-loss', 'frameshift', 'cds-indel']);
58269    const codingSynonSet = new Set(['coding-synon']);
58270    const spliceSiteSet = new Set(['splice-3', 'splice-5']);
58271    const untranslatedSet = new Set(['untranslated-5', 'untranslated-3']);
58272    /**
58273     * Renderer for a UCSC snp track
58274     *
58275     * @param snp
58276     * @param bpStart  genomic location of the left edge of the current canvas
58277     * @param xScale  scale in base-pairs per pixel
58278     * @param pixelHeight  pixel height of the current canvas
58279     * @param ctx  the canvas 2d context
58280     */
58281
58282    function renderSnp(snp, bpStart, xScale, pixelHeight, ctx) {
58283      var coord = calculateFeatureCoordinates(snp, bpStart, xScale),
58284          py = this.margin,
58285          h,
58286          colorArrLength = this.snpColors.length,
58287          colorPriority;
58288      h = this.displayMode === "squished" ? this.squishedRowHeight : this.expandedRowHeight;
58289
58290      switch (this.colorBy) {
58291        case 'function':
58292          colorPriority = colorByFunc(snp.func);
58293          break;
58294
58295        case 'class':
58296          colorPriority = colorByClass(snp['class']);
58297      }
58298
58299      ctx.fillStyle = this.snpColors[colorPriority];
58300      ctx.fillRect(coord.px, py, coord.pw, h); // Coloring functions, convert a value to a priority
58301
58302      function colorByFunc(theFunc) {
58303        var priorities;
58304        var funcArray = theFunc.split(','); // possible func values
58305
58306        priorities = funcArray.map(function (func) {
58307          if (codingNonSynonSet.has(func) || spliceSiteSet.has(func)) {
58308            return colorArrLength - 1;
58309          } else if (codingSynonSet.has(func)) {
58310            return colorArrLength - 2;
58311          } else if (untranslatedSet.has(func)) {
58312            return colorArrLength - 3;
58313          } else {
58314            // locusSet.has(func) || intronSet.has(func)
58315            return 0;
58316          }
58317        });
58318        return priorities.reduce(function (a, b) {
58319          return Math.max(a, b);
58320        });
58321      }
58322
58323      function colorByClass(cls) {
58324        if (cls === 'deletion') {
58325          return colorArrLength - 1;
58326        } else if (cls === 'mnp') {
58327          return colorArrLength - 2;
58328        } else if (cls === 'microsatellite' || cls === 'named') {
58329          return colorArrLength - 3;
58330        } else {
58331          // cls === 'single' || cls === 'in-del' || cls === 'insertion'
58332          return 0;
58333        }
58334      }
58335    }
58336
58337    /**
58338     *
58339     * @param feature
58340     * @param bpStart  genomic location of the left edge of the current canvas
58341     * @param xScale  scale in base-pairs per pixel
58342     * @param pixelHeight  pixel height of the current canvas
58343     * @param ctx  the canvas 2d context
58344     */
58345    function renderFusionJuncSpan(feature, bpStart, xScale, pixelHeight, ctx) {
58346      const rowHeight = this.displayMode === "EXPANDED" ? this.expandedRowHeight : this.squishedRowHeight;
58347      let py = this.margin;
58348
58349      if (this.displayMode !== "COLLAPSED" && feature.row !== undefined) {
58350        py += feature.row * rowHeight;
58351      }
58352
58353      const cy = py + 0.5 * rowHeight;
58354      const topY = cy - 0.5 * rowHeight;
58355      const bottomY = cy + 0.5 * rowHeight; // draw the junction arc
58356
58357      const junctionLeftPx = Math.round((feature.junction_left - bpStart) / xScale);
58358      const junctionRightPx = Math.round((feature.junction_right - bpStart) / xScale);
58359      ctx.beginPath();
58360      ctx.moveTo(junctionLeftPx, cy);
58361      ctx.bezierCurveTo(junctionLeftPx, topY, junctionRightPx, topY, junctionRightPx, cy);
58362      ctx.lineWidth = 1 + Math.log(feature.num_junction_reads) / Math.log(2);
58363      ctx.strokeStyle = 'blue';
58364      ctx.stroke(); // draw the spanning arcs
58365
58366      const spanningCoords = feature.spanning_frag_coords;
58367
58368      for (let i = 0; i < spanningCoords.length; i++) {
58369        const spanningInfo = spanningCoords[i];
58370        const spanLeftPx = Math.round((spanningInfo.left - bpStart) / xScale);
58371        const spanRightPx = Math.round((spanningInfo.right - bpStart) / xScale);
58372        ctx.beginPath();
58373        ctx.moveTo(spanLeftPx, cy);
58374        ctx.bezierCurveTo(spanLeftPx, bottomY, spanRightPx, bottomY, spanRightPx, cy);
58375        ctx.lineWidth = 1;
58376        ctx.strokeStyle = 'purple';
58377        ctx.stroke();
58378      }
58379    }
58380
58381    /*
58382     * The MIT License (MIT)
58383     *
58384     * Copyright (c) 2014 Broad Institute
58385     *
58386     * Permission is hereby granted, free of charge, to any person obtaining a copy
58387     * of this software and associated documentation files (the "Software"), to deal
58388     * in the Software without restriction, including without limitation the rights
58389     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
58390     * copies of the Software, and to permit persons to whom the Software is
58391     * furnished to do so, subject to the following conditions:
58392     *
58393     * The above copyright notice and this permission notice shall be included in
58394     * all copies or substantial portions of the Software.
58395     *
58396     *
58397     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
58398     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
58399     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
58400     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58401     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
58402     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58403     * THE SOFTWARE.
58404     */
58405
58406    class FeatureTrack extends TrackBase {
58407      constructor(config, browser) {
58408        super(config, browser);
58409      }
58410
58411      init(config) {
58412        super.init(config);
58413        this.type = config.type || "annotation"; // Set maxRows -- protects against pathological feature packing cases (# of rows of overlapping feaures)
58414
58415        this.maxRows = config.maxRows === undefined ? 1000 : config.maxRows;
58416        this.displayMode = config.displayMode || "EXPANDED"; // COLLAPSED | EXPANDED | SQUISHED
58417
58418        this.labelDisplayMode = config.labelDisplayMode;
58419
58420        if (config._featureSource) {
58421          this.featureSource = config._featureSource;
58422          delete config._featureSource;
58423        } else {
58424          this.featureSource = config.featureSource ? config.featureSource : FeatureSource(config, this.browser.genome);
58425        } // Set default heights
58426
58427
58428        this.autoHeight = config.autoHeight;
58429        this.margin = config.margin === undefined ? 10 : config.margin;
58430        this.featureHeight = config.featureHeight || 14;
58431
58432        if ("FusionJuncSpan" === config.type) {
58433          this.render = config.render || renderFusionJuncSpan;
58434          this.squishedRowHeight = config.squishedRowHeight || 50;
58435          this.expandedRowHeight = config.expandedRowHeight || 50;
58436          this.height = config.height || this.margin + 2 * this.expandedRowHeight;
58437        } else if ('snp' === config.type) {
58438          this.render = config.render || renderSnp; // colors ordered based on priority least to greatest
58439
58440          this.snpColors = ['rgb(0,0,0)', 'rgb(0,0,255)', 'rgb(0,255,0)', 'rgb(255,0,0)'];
58441          this.colorBy = 'function';
58442          this.expandedRowHeight = config.expandedRowHeight || 10;
58443          this.squishedRowHeight = config.squishedRowHeight || 5;
58444          this.height = config.height || 30;
58445        } else {
58446          this.render = config.render || renderFeature;
58447          this.arrowSpacing = 30; // adjust label positions to make sure they're always visible
58448
58449          monitorTrackDrag(this);
58450          this.squishedRowHeight = config.squishedRowHeight || 15;
58451          this.expandedRowHeight = config.expandedRowHeight || 30;
58452          this.height = config.height || this.margin + 2 * this.expandedRowHeight; // Set colorBy fields considering legacy options for backward compatibility
58453
58454          if (config.colorBy) {
58455            if (config.colorBy.field) {
58456              config.colorTable = config.colorBy.pallete || config.colorBy.palette;
58457              config.colorBy = config.colorBy.field;
58458            }
58459
58460            this.colorBy = config.colorBy; // Can be undefined => default
58461
58462            if (config.colorTable) {
58463              this.colorTable = new ColorTable(config.colorTable);
58464            } else {
58465              this.colorTable = new PaletteColorTable("Set1");
58466            }
58467          }
58468        } //UCSC useScore option
58469
58470
58471        this.useScore = config.useScore;
58472      }
58473
58474      async postInit() {
58475        if (typeof this.featureSource.getHeader === "function") {
58476          this.header = await this.featureSource.getHeader();
58477        } // Set properties from track line
58478
58479
58480        if (this.header) {
58481          this.setTrackProperties(this.header);
58482        }
58483
58484        if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') {
58485          this.visibilityWindow = await this.featureSource.defaultVisibilityWindow();
58486        }
58487
58488        return this;
58489      }
58490
58491      supportsWholeGenome() {
58492        return (this.config.indexed === false || !this.config.indexURL) && this.config.supp
58492ortsWholeGenome !== false;
58493      }
58494
58495      async getFeatures(chr, start, end, bpPerPixel) {
58496        const visibilityWindow = this.visibilityWindow;
58497        return this.featureSource.getFeatures({
58498          chr,
58499          start,
58500          end,
58501          bpPerPixel,
58502          visibilityWindow
58503        });
58504      }
58505
58506      /**
58507       * The required height in pixels required for the track content.   This is not the visible track height, which
58508       * can be smaller (with a scrollbar) or larger.
58509       *
58510       * @param features
58511       * @returns {*}
58512       */
58513      computePixelHeight(features) {
58514        if (this.displayMode === "COLLAPSED") {
58515          return this.margin + this.expandedRowHeight;
58516        } else {
58517          let maxRow = 0;
58518
58519          if (features && typeof features.forEach === "function") {
58520            for (let feature of features) {
58521              if (feature.row && feature.row > maxRow) {
58522                maxRow = feature.row;
58523              }
58524            }
58525          }
58526
58527          const height = this.margin + (maxRow + 1) * ("SQUISHED" === this.displayMode ? this.squishedRowHeight : this.expandedRowHeight);
58528          return height;
58529        }
58530      }
58531
58532      draw(options) {
58533        const featureList = options.features;
58534        const ctx = options.context;
58535        const bpPerPixel = options.bpPerPixel;
58536        const bpStart = options.bpStart;
58537        const pixelWidth = options.pixelWidth;
58538        const pixelHeight = options.pixelHeight;
58539        const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;
58540
58541        if (!this.config.isMergedTrack) {
58542          IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {
58543            'fillStyle': "rgb(255, 255, 255)"
58544          });
58545        }
58546
58547        if (featureList) {
58548          const rowFeatureCount = [];
58549          options.rowLastX = [];
58550
58551          for (let feature of featureList) {
58552            const row = feature.row || 0;
58553
58554            if (rowFeatureCount[row] === undefined) {
58555              rowFeatureCount[row] = 1;
58556            } else {
58557              rowFeatureCount[row]++;
58558            }
58559
58560            options.rowLastX[row] = -Number.MAX_SAFE_INTEGER;
58561          }
58562
58563          let lastPxEnd = [];
58564
58565          for (let feature of featureList) {
58566            if (feature.end < bpStart) continue;
58567            if (feature.start > bpEnd) break;
58568            const row = this.displayMode === 'COLLAPSED' ? 0 : feature.row;
58569            const featureDensity = pixelWidth / rowFeatureCount[row];
58570            options.drawLabel = options.labelAllFeatures || featureDensity > 10;
58571            const pxEnd = Math.ceil((feature.end - bpStart) / bpPerPixel);
58572            const last = lastPxEnd[row];
58573
58574            if (!last || pxEnd > last) {
58575              this.render.call(this, feature, bpStart, bpPerPixel, pixelHeight, ctx, options); // Ensure a visible gap between features
58576
58577              const pxStart = Math.floor((feature.start - bpStart) / bpPerPixel);
58578
58579              if (last && pxStart - last <= 0) {
58580                ctx.globalAlpha = 0.5;
58581                IGVGraphics.strokeLine(ctx, pxStart, 0, pxStart, pixelHeight, {
58582                  'strokeStyle': "rgb(255, 255, 255)"
58583                });
58584                ctx.globalAlpha = 1.0;
58585              }
58586
58587              lastPxEnd[row] = pxEnd;
58588            }
58589          }
58590        } else {
58591          console.log("No feature list");
58592        }
58593      }
58594
58595      clickedFeatures(clickState, features) {
58596        const y = clickState.y - this.margin;
58597        const allFeatures = super.clickedFeatures(clickState, features);
58598        let row;
58599
58600        switch (this.displayMode) {
58601          case 'SQUISHED':
58602            row = Math.floor(y / this.squishedRowHeight);
58603            break;
58604
58605          case 'EXPANDED':
58606            row = Math.floor(y / this.expandedRowHeight);
58607            break;
58608
58609          default:
58610            row = undefined;
58611        }
58612
58613        return allFeatures.filter(function (feature) {
58614          return row === undefined || feature.row === undefined || row === feature.row;
58615        });
58616      }
58617      /**
58618       * Return "popup data" for feature @ genomic location.  Data is an array of key-value pairs
58619       */
58620
58621
58622      popupData(clickState, features) {
58623        features = this.clickedFeatures(clickState, features);
58624        const genomicLocation = clickState.genomicLocation;
58625        const data = [];
58626
58627        for (let feature of features) {
58628          // Whole genome hack, whole-genome psuedo features store the "real" feature in an _f field
58629          const f = feature._f || feature;
58630          const featureData = typeof f.popupData === "function" ? f.popupData(genomicLocation) : this.extractPopupData(f);
58631
58632          if (featureData) {
58633            if (data.length > 0) {
58634              data.push("<hr/><hr/>");
58635            } // If we have an infoURL, find the name property and create the link.  We do this at this level
58636            // to catch name properties in both custom popupData functions and the generic extractPopupData function
58637
58638
58639            const infoURL = this.infoURL || this.config.infoURL;
58640
58641            for (let fd of featureData) {
58642              data.push(fd);
58643
58644              if (infoURL) {
58645                if (fd.name && fd.name.toLowerCase() === "name" && fd.value && isString$3(fd.value) && !fd.value.startsWith("<")) {
58646                  const url = this.infoURL || this.config.infoURL;
58647                  const href = url.replace("$$", feature.name);
58648                  data.push({
58649                    name: "Info",
58650                    value: `<a target="_blank" href=${href}>${fd.value}</a>`
58651                  });
58652                }
58653              }
58654            } //Array.prototype.push.apply(data, featureData);
58655            // If we have clicked over an exon number it.
58656            // Disabled for GFF and GTF files if the visibility window is < the feature length since we don't know if we have all exons
58657
58658
58659            const isGFF = "gff" === this.config.format || "gff3" === this.config.format || "gtf" === this.config.format;
58660
58661            if (f.exons) {
58662              for (let i = 0; i < f.exons.length; i++) {
58663                const exon = f.exons[i];
58664
58665                if (genomicLocation >= exon.start && genomicLocation <= exon.end) {
58666                  const exonNumber = isGFF ? exon.number : f.strand === "-" ? f.exons.length - i : i + 1;
58667
58668                  if (exonNumber) {
58669                    data.push('<hr/>');
58670                    data.push({
58671                      name: "Exon Number",
58672                      value: exonNumber
58673                    });
58674                  }
58675
58676                  break;
58677                }
58678              }
58679            }
58680          }
58681        }
58682
58683        return data;
58684      }
58685
58686      menuItemList() {
58687        const menuItems = [];
58688
58689        if (this.render === renderSnp) {
58690          menuItems.push('<hr/>');
58691
58692          for (let colorScheme of ["function", "class"]) {
58693            menuItems.push({
58694              object: $$1(createCheckbox$1('Color by ' + colorScheme, colorScheme === this.colorBy)),
58695              click: () => {
58696                this.colorBy = colorScheme;
58697                this.trackView.repaintViews();
58698              }
58699            });
58700          }
58701        }
58702
58703        menuItems.push('<hr/>');
58704
58705        for (let displayMode of ["COLLAPSED", "SQUISHED", "EXPANDED"]) {
58706          const lut = {
58707            "COLLAPSED": "Collapse",
58708            "SQUISHED": "Squish",
58709            "EXPANDED": "Expand"
58710          };
58711          menuItems.push({
58712            object: $$1(createCheckbox$1(lut[displayMode], displayMode === this.displayMode)),
58713            click: () => {
58714              this.displayMode = displayMode;
58715              this.config.displayMode = displayMode;
58716              this.trackView.checkContentHeight();
58717              this.trackView.repaintViews();
58718            }
58719          });
58720        }
58721
58722        return menuItems;
58723      }
58724
58725      contextMenuItemList(clickState) {
58726        if (isSecureContext()) {
58727          const features = this.clickedFeatures(clickState);
58728
58729          if (features.length > 1) {
58730            features.sort((a, b) => a.end - a.start - (b.end - b.start));
58731          }
58732
58733          const f = features[0]; // The longest feature
58734
58735          if (f.end - f.start <= 1000000) {
58736            return [{
58737              label: 'Copy feature sequence',
58738              click: async () => {
58739                let seq = await this.browser.genome.getSequence(f.chr, f.start, f.end);
58740
58741                if (f.strand === '-') {
58742                  seq = reverseComplementSequence(seq);
58743                }
58744
58745                navigator.clipboard.writeText(seq);
58746              }
58747            }, '<hr/>'];
58748          }
58749        } // Either not a secure context (i.e. http: protocol), or feature is too long
58750
58751
58752        return undefined;
58753      }
58754
58755      description() {
58756        // if('snp' === this.type) {
58757        if (renderSnp === this.render) {
58758          let desc = "<html>" + this.name + '<hr/>';
58759          desc += '<em>Color By Function:</em><br>';
58760          desc += '<span style="color:red">Red</span>: Coding-Non-Synonymous, Splice Site<br>';
58761          desc += '<span style="color:green">Green</span>: Coding-Synonymous<br>';
58762          desc += '<span style="color:blue">Blue</span>: Untranslated<br>';
58763          desc += '<span style="color:black">Black</span>: Intron, Locus, Unknown<br><br>';
58764          desc += '<em>Color By Class:</em><br>';
58765          desc += '<span style="color:red">Red</span>: Deletion<br>';
58766          desc += '<span style="color:green">Green</span>: MNP<br>';
58767          desc += '<span style="color:blue">Blue</span>: Microsatellite, Named<br>';
58768          desc += '<span style="color:black">Black</span>: Indel, Insertion, SNP';
58769          desc += "</html>";
58770          return desc;
58771        } else {
58772          return this.name;
58773        }
58774      }
58775
58776      /**
58777       * Called when the track is removed.  Do any needed cleanup here
58778       */
58779      dispose() {
58780        this.trackView = undefined;
58781      }
58782
58783    }
58784    /**
58785     * Monitors track drag events, updates label position to ensure that they're always visible.
58786     * @param track
58787     */
58788
58789
58790    function monitorTrackDrag(track) {
58791      if (track.browser.on) {
58792        track.browser.on('trackdragend', onDragEnd);
58793        track.browser.on('trackremoved', unSubscribe);
58794      }
58795
58796      function onDragEnd() {
58797        if (track.trackView && track.displayMode !== "SQUISHED") {
58798          track.trackView.repaintViews(); // TODO -- refine this to the viewport that was dragged after DOM refactor
58799        }
58800      }
58801
58802      function unSubscribe(removedTrack) {
58803        if (track.browser.un && track === removedTrack) {
58804          track.browser.un('trackdragend', onDragEnd);
58805          track.browser.un('trackremoved', unSubscribe);
58806        }
58807      }
58808    }
58809
58810    /*
58811     * The MIT License (MIT)
58812     *
58813     * Copyright (c) 2014 Broad Institute
58814     *
58815     * Permission is hereby granted, free of charge, to any person obtaining a copy
58816     * of this software and associated documentation files (the "Software"), to deal
58817     * in the Software without restriction, including without limitation the rights
58818     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
58819     * copies of the Software, and to permit persons to whom the Software is
58820     * furnished to do so, subject to the following conditions:
58821     *
58822     * The above copyright notice and this permission notice shall be included in
58823     * all copies or substantial portions of the Software.
58824     *
58825     *
58826     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
58827     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
58828     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
58829     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58830     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
58831     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58832     * THE SOFTWARE.
58833     */
58834    const DEFAULT_COLOR = "rgb(150,150,150)";
58835
58836    class WigTrack extends TrackBase {
58837      constructor(config, browser) {
58838        super(config, browser);
58839      }
58840
58841      init(config) {
58842        super.init(config);
58843        this.type = "wig";
58844        this.height = config.height || 50;
58845        this.featureType = 'numeric';
58846        this.paintAxis = paintAxis;
58847        const format = config.format ? config.format.toLowerCase() : config.format;
58848
58849        if ("bigwig" === format) {
58850          this.featureSource = new BWSource(config, this.browser.genome);
58851        } else if ("tdf" === format) {
58852          this.featureSource = new TDFSource(config, this.browser.genome);
58853        } else {
58854          this.featureSource = FeatureSource(config, this.browser.genome);
58855        }
58856
58857        this.autoscale = config.autoscale || config.max === undefined;
58858
58859        if (!this.autoscale) {
58860          this.dataRange = {
58861            min: config.min || 0,
58862            max: config.max
58863          };
58864        }
58865
58866        this.windowFunction = config.windowFunction || "mean";
58867        this.graphType = config.graphType || "bar";
58868        this.normalize = config.normalize; // boolean, for use with "TDF" files
58869
58870        this.scaleFactor = config.scaleFactor; // optional scale factor, ignored if normalize === true;
58871      }
58872
58873      async postInit() {
58874        const header = await this.getHeader();
58875        if (header) this.setTrackProperties(header);
58876      }
58877
58878      async getFeatures(chr, start, end, bpPerPixel) {
58879        const features = await this.featureSource.getFeatures({
58880          chr,
58881          start,
58882          end,
58883          bpPerPixel,
58884          windowFunction: this.windowFunction
58885        });
58886
58887        if (this.normalize && this.featureSource.normalizationFactor) {
58888          const scaleFactor = this.featureSource.normalizationFactor;
58889
58890          for (let f of features) {
58891            f.value *= scaleFactor;
58892          }
58893        }
58894
58895        if (this.scaleFactor) {
58896          const scaleFactor = this.scaleFactor;
58897
58898          for (let f of features) {
58899            f.value *= scaleFactor;
58900          }
58901        }
58902
58903        return features;
58904      }
58905
58906      menuItemList() {
58907        return MenuUtils.numericDataMenuItems(this.trackView);
58908      }
58909
58910      async getHeader() {
58911        if (typeof this.featureSource.getHeader === "function") {
58912          this.header = await this.featureSource.getHeader();
58913        }
58914
58915        return this.header;
58916      }
58917
58918      draw(options) {
58919        const features = options.features;
58920        const ctx = options.context;
58921        const bpPerPixel = options.bpPerPixel;
58922        const bpStart = options.bpStart;
58923        const pixelWidth = options.pixelWidth;
58924        const pixelHeight = options.pixelHeight;
58925        const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;
58926        let lastPixelEnd = -1;
58927        let lastValue = -1;
58928        let lastNegValue = 1;
58929        const posColor = this.color || DEFAULT_COLOR;
58930        let baselineColor;
58931
58932        if (typeof posColor === "string" && posColor.startsWith("rgb(")) {
58933          baselineColor = IGVColor.addAlpha(posColor, 0.1);
58934        }
58935
58936        const yScale = yValue => {
58937          return (this.dataRange.max - yValue) / (this.dataRange.max - this.dataRange.min) * pixelHeight;
58938        };
58939
58940        if (features && features.length > 0) {
58941          if (this.dataRange.min === undefined) this.dataRange.min = 0;
58941 // Max can be less than min if config.min is set but max left to autoscale.   If that's the case there is
58942          // nothing to paint.
58943
58944          if (this.dataRange.max > this.dataRange.min) {
58945            const y0 = this.dataRange.min == 0 ? pixelHeight : yScale(0);
58946
58947            for (let f of features) {
58948              if (f.end < bpStart) continue;
58949              if (f.start > bpEnd) break;
58950              const x = Math.floor((f.start - bpStart) / bpPerPixel);
58951              if (isNaN(x)) continue;
58952              let y = yScale(f.value);
58953              const rectEnd = Math.ceil((f.end - bpStart) / bpPerPixel);
58954              const width = Math.max(1, rectEnd - x);
58955              let c = f.value < 0 && this.altColor ? this.altColor : posColor;
58956              const color = typeof c === "function" ? c(f.value) : c;
58957
58958              if (this.graphType === "points") {
58959                const pointSize = this.config.pointSize || 3;
58960                const px = x + width / 2;
58961                IGVGraphics.fillCircle(ctx, px, y, pointSize / 2, {
58962                  "fillStyle": color,
58963                  "strokeStyle": color
58964                });
58965              } else {
58966                let height = y - y0;
58967
58968                if (Math.abs(height) < 1) {
58969                  height = height < 0 ? -1 : 1;
58970                }
58971
58972                const pixelEnd = x + width;
58973
58974                if (pixelEnd > lastPixelEnd || f.value >= 0 && f.value > lastValue || f.value < 0 && f.value < lastNegValue) {
58975                  IGVGraphics.fillRect(ctx, x, y0, width, height, {
58976                    fillStyle: color
58977                  });
58978                }
58979
58980                lastValue = f.value;
58981                lastPixelEnd = pixelEnd;
58982              }
58983            } // If the track includes negative values draw a baseline
58984
58985
58986            if (this.dataRange.min < 0) {
58987              const basepx = this.dataRange.max / (this.dataRange.max - this.dataRange.min) * options.pixelHeight;
58988              IGVGraphics.strokeLine(ctx, 0, basepx, options.pixelWidth, basepx, {
58989                strokeStyle: baselineColor
58990              });
58991            }
58992          }
58993        } // Draw guidelines
58994
58995
58996        if (this.config.hasOwnProperty('guideLines')) {
58997          for (let line of this.config.guideLines) {
58998            if (line.hasOwnProperty('color') && line.hasOwnProperty('y') && line.hasOwnProperty('dotted')) {
58999              let y = yScale(line.y);
59000              let props = {
59001                'strokeStyle': line['color'],
59002                'strokeWidth': 2
59003              };
59004              if (line['dotted']) IGVGraphics.dashedLine(options.context, 0, y, options.pixelWidth, y, 5, props);else IGVGraphics.strokeLine(options.context, 0, y, options.pixelWidth, y, props);
59005            }
59006          }
59007        }
59008      }
59009
59010      popupData(clickState, features) {
59011        // We use the featureCache property rather than method to avoid async load.  If the
59012        // feature is not already loaded this won't work,  but the user wouldn't be mousing over it either.
59013        features = this.clickedFeatures(clickState, features);
59014
59015        if (features && features.length > 0) {
59016          const genomicLocation = clickState.genomicLocation;
59017          const popupData = []; // Sort features based on distance from click
59018
59019          features.sort(function (a, b) {
59020            const distA = Math.abs((a.start + a.end) / 2 - genomicLocation);
59021            const distB = Math.abs((b.start + b.end) / 2 - genomicLocation);
59022            return distA - distB;
59023          }); // Display closest 10
59024
59025          const displayFeatures = features.length > 10 ? features.slice(0, 10) : features; // Resort in ascending order
59026
59027          displayFeatures.sort(function (a, b) {
59028            return a.start - b.start;
59029          });
59030
59031          for (let selectedFeature of displayFeatures) {
59032            if (selectedFeature) {
59033              if (popupData.length > 0) {
59034                popupData.push('<hr/>');
59035              }
59036
59037              let posString = selectedFeature.end - selectedFeature.start === 1 ? numberFormatter$1(selectedFeature.start + 1) : numberFormatter$1(selectedFeature.start + 1) + "-" + numberFormatter$1(selectedFeature.end
59037);
59038              popupData.push({
59039                name: "Position:",
59040                value: posString
59041              });
59042              popupData.push({
59043                name: "Value:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",
59044                value: numberFormatter$1(selectedFeature.value)
59045              });
59046            }
59047          }
59048
59049          if (displayFeatures.length < features.length) {
59050            popupData.push("<hr/>...");
59051          }
59052
59053          return popupData;
59054        } else {
59055          return [];
59056        }
59057      }
59058
59059      supportsWholeGenome() {
59060        return !this.config.indexURL && this.config.supportsWholeGenome !== false;
59061      }
59062      /**
59063       * Called when the track is removed.  Do any needed cleanup here
59064       */
59065
59066
59067      dispose() {
59068        this.trackView = undefined;
59069      }
59070
59071    }
59072
59073    /**
59074     *
59075     * @param cs - object containing
59076     * 1) array of threshold values defining bin boundaries in ascending order
59077     * 2) array of colors for bins  (length == thresholds.length + 1)
59078     * @constructor
59079     */
59080    function BinnedColorScale(cs) {
59081      this.thresholds = cs.thresholds;
59082      this.colors = cs.colors;
59083    }
59084
59085    BinnedColorScale.prototype.getColor = function (value) {
59086      for (let threshold of this.thresholds) {
59087        if (value < threshold) {
59088          return this.colors[this.thresholds.indexOf(threshold)];
59089        }
59090      }
59091
59092      return this.colors[this.colors.length - 1];
59093    };
59094    /**
59095     *
59096     * @param scale - object with the following properties
59097     *           low
59098     *           lowR
59099     *           lowG
59100     *           lowB
59101     *           high
59102     *           highR
59103     *           highG
59104     *           highB
59105     *
59106     * @constructor
59107     */
59108
59109
59110    function GradientColorScale(scale) {
59111      this.scale = scale;
59112      this.lowColor = "rgb(" + scale.lowR + "," + scale.lowG + "," + scale.lowB + ")";
59113      this.highColor = "rgb(" + scale.highR + "," + scale.highG + "," + scale.highB + ")";
59114      this.diff = scale.high - scale.low;
59115    }
59116
59117    GradientColorScale.prototype.getColor = function (value) {
59118      var scale = this.scale,
59119          r,
59120          g,
59121          b,
59122          frac;
59123      if (value <= scale.low) return this.lowColor;else if (value >= scale.high) return this.highColor;
59124      frac = (value - scale.low) / this.diff;
59125      r = Math.floor(scale.lowR + frac * (scale.highR - scale.lowR));
59126      g = Math.floor(scale.lowG + frac * (scale.highG - scale.lowG));
59127      b = Math.floor(scale.lowB + frac * (scale.highB - scale.lowB));
59128      return "rgb(" + r + "," + g + "," + b + ")";
59129    };
59130
59131    class ConstantColorScale {
59132      constructor(color) {
59133        this.color = color;
59134      }
59135
59136      getColor() {
59137        return this.color;
59138      }
59139
59140    }
59141
59142    /*
59143     * The MIT License (MIT)
59144     *
59145     * Copyright (c) 2014 Broad Institute
59146     *
59147     * Permission is hereby granted, free of charge, to any person obtaining a copy
59148     * of this software and associated documentation files (the "Software"), to deal
59149     * in the Software without restriction, including without limitation the rights
59150     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
59151     * copies of the Software, and to permit persons to whom the Software is
59152     * furnished to do so, subject to the following conditions:
59153     *
59154     * The above copyright notice and this permission notice shall be included in
59155     * all copies or substantial portions of the Software.
59156     *
59157     *
59158     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59159     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
59160     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
59161     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59162     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
59163     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
59164     * THE SOFTWARE.
59165     */
59166
59167    class SegTrack extends TrackBase {
59168      constructor(config, browser) {
59169        super(config, browser);
59170      }
59171
59172      init(config) {
59173        super.init(config);
59174        this.type = config.type || "seg";
59175        if (this.type === 'maf') this.type = 'mut';
59176        this.isLog = config.isLog;
59177        this.displayMode = config.displayMode || "EXPANDED"; // EXPANDED | SQUISHED
59178
59179        this.height = config.height || 300;
59180        this.maxHeight = config.maxHeight || 500;
59181        this.squishedRowHeight = config.sampleSquishHeight || config.squishedRowHeight || 2;
59182        this.expandedRowHeight = config.sampleExpandHeight || config.expandedRowHeight || 13;
59183        this.sampleHeight = this.squishedRowHeight; // Initial value, will get overwritten when rendered
59184
59185        if (config.color) {
59186          this.color = config.color;
59187        } else {
59188          // Color scales for "seg" (copy number) tracks.
59189          this.posColorScale = config.posColorScale || new GradientColorScale({
59190            low: 0.1,
59191            lowR: 255,
59192            lowG: 255,
59193            lowB: 255,
59194            high: 1.5,
59195            highR: 255,
59196            highG: 0,
59197            highB: 0
59198          });
59199          this.negColorScale = config.negColorScale || new GradientColorScale({
59200            low: -1.5,
59201            lowR: 0,
59202            lowG: 0,
59203            lowB: 255,
59204            high: -0.1,
59205            highR: 255,
59206            highG: 255,
59207            highB: 255
59208          }); // Default color table for mutation (mut and maf) tracks
59209
59210          if (this.type === "mut") {
59211            this.colorTable = new ColorTable(config.colorTable || MUT_COLORS);
59212          }
59213        }
59214
59215        this.sampleKeys = [];
59216        this.sampleNames = new Map();
59217
59218        if (config.samples) {
59219          // Explicit setting, keys == names
59220          for (let s of config.samples) {
59221            this.sampleKeys.push(s);
59222            this.sampleNames.set(s, s);
59223          }
59224
59225          this.explicitSamples = true;
59226        } //   this.featureSource = config.sourceType === "bigquery" ?
59227        //       new igv.BigQueryFeatureSource(this.config) :
59228
59229
59230        this.featureSource = FeatureSource(this.config, this.browser.genome);
59231        this.initialSort = config.sort;
59232      }
59233
59234      async postInit() {
59235        if (typeof this.featureSource.getHeader === "function") {
59236          this.header = await this.featureSource.getHeader();
59237        } // Set properties from track line
59238
59239
59240        if (this.header) {
59241          this.setTrackProperties(this.header);
59242        }
59243      }
59244
59245      menuItemList() {
59246        const menuItems = [];
59247        const lut = {
59248          "SQUISHED": "Squish",
59249          "EXPANDED": "Expand",
59250          "FILL": "Fill"
59251        };
59252        menuItems.push('<hr/>');
59253        menuItems.push("DisplayMode:");
59254        const displayOptions = this.type === 'seg' ? ["SQUISHED", "EXPANDED", "FILL"] : ["SQUISHED", "EXPANDED"];
59255
59256        for (let displayMode of displayOptions) {
59257          const checkBox = createCheckbox$1(lut[displayMode], displayMode === this.displayMode);
59258          menuItems.push({
59259            object: $$1(checkBox),
59260            click: () => {
59261              this.displayMode = displayMode;
59262              this.config.displayMode = displayMode;
59263              this.trackView.checkContentHeight();
59264              this.trackView.repaintViews();
59265              this.trackView.moveScroller(this.trackView.sampleNameViewport.trackScrollDelta);
59266            }
59267          });
59268        }
59269
59270        return menuItems;
59271      }
59272
59273      hasSamples() {
59274        return true; // SEG, MUT, and MAF tracks have samples by definition
59275      }
59276
59277      getSamples() {
59278        return {
59279          names: this.sampleKeys.map(key => this.sampleNames.get(key)),
59280          height: this.sampleHeight,
59281          yOffset: 0
59282        };
59283      }
59284
59285      async getFeatures(chr, start, end) {
59286        const features = await this.featureSource.getFeatures({
59287          chr,
59288          start,
59289          end
59290        });
59291
59292        if (this.initialSort) {
59293          const sort = this.initialSort;
59294          this.sortSamples(sort.chr, sort.start, sort.end, sort.direction, features);
59295          this.initialSort = undefined; // Sample order is sorted,
59296        }
59297
59298        return features;
59299      }
59300
59301      draw(_ref) {
59302        let {
59303          context,
59304          renderSVG,
59305          pixelTop,
59306          pixelWidth,
59307          pixelHeight,
59308          features,
59309          bpPerPixel,
59310          bpStart
59311        } = _ref;
59312        IGVGraphics.fillRect(context, 0, 0, pixelWidth, pixelHeight, {
59313          'fillStyle': "rgb(255, 255, 255)"
59314        });
59315
59316        if (features && features.length > 0) {
59317          this.checkForLog(features); // New segments could conceivably add new samples
59318
59319          this.updateSampleKeys(features); // Create a map for fast id -> row lookup
59320
59321          const samples = {};
59322          this.sampleKeys.forEach(function (id, index) {
59323            samples[id] = index;
59324          });
59325          let border;
59326
59327          switch (this.displayMode) {
59328            case "FILL":
59329              this.sampleHeight = pixelHeight / this.sampleKeys.length;
59330              border = 0;
59331              break;
59332
59333            case "SQUISHED":
59334              this.sampleHeight = this.squishedRowHeight;
59335              border = 0;
59336              break;
59337
59338            default:
59339              // EXPANDED
59340              this.sampleHeight = this.expandedRowHeight;
59341              border = 1;
59342          }
59343
59344          const rowHeight = this.sampleHeight; // this.featureMap = new Map()
59345
59346          for (let segment of features) {
59347            segment.pixelRect = undefined; // !important, reset this in case segment is not drawn
59348          }
59349
59350          const pixelBottom = pixelTop + pixelHeight;
59351          const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;
59352          const xScale = bpPerPixel;
59353          this.sampleYStart = undefined;
59354
59355          for (let f of features) {
59356            if (f.end < bpStart) continue;
59357            if (f.start > bpEnd) break;
59358            const sampleKey = f.sampleKey || f.sample;
59359            f.row = samples[sampleKey];
59360            const y = f.row * rowHeight + border;
59361
59362            if (undefined === this.sampleYStart) {
59363              this.sampleYStart = y;
59364            }
59365
59366            const bottom = y + rowHeight;
59367
59368            if (bottom < pixelTop || y > pixelBottom) {
59369              continue;
59370            }
59371
59372            const segmentStart = Math.max(f.start, bpStart); // const segmentStart = segment.start;
59373
59374            let x = Math.round((segmentStart - bpStart) / xScale);
59375            const segmentEnd = Math.min(f.end, bpEnd); // const segmentEnd = segment.end;
59376
59377            const x1 = Math.round((segmentEnd - bpStart) / xScale);
59378            let w = Math.max(1, x1 - x);
59379            let color;
59380
59381            if (this.color) {
59382              if (typeof this.color === "function") {
59383                color = this.color(f);
59384              } else {
59385                color = this.color;
59386              }
59387            } else if (this.colorTable) {
59388              color = this.colorTable.getColor(f.value.toLowerCase());
59389            }
59390
59391            let h;
59392
59393            if ("mut" === this.type) {
59394              h = rowHeight - 2 * border;
59395
59396              if (w < 3) {
59397                w = 3;
59398                x -= 1;
59399              }
59400            } else {
59401              // Assume seg track
59402              let value = f.value;
59403
59404              if (!this.isLog) {
59405                value = IGVMath.log2(value / 2);
59406              }
59407
59408              if (value < -0.1) {
59409                color = this.negColorScale.getColor(value);
59410              } else if (value > 0.1) {
59411                color = this.posColorScale.getColor(value);
59412              } else {
59413                color = "white";
59414              }
59415
59416              let sh = rowHeight;
59417
59418              if (rowHeight < 0.25) {
59419                const f = 0.1 + 2 * Math.abs(value);
59420                sh = Math.min(1, f * rowHeight);
59421              }
59422
59423              h = sh - 2 * border;
59424            }
59425
59426            f.pixelRect = {
59427              x,
59428              y,
59429              w,
59430              h
59431            }; // Use for diagnostic rendering
59432            // context.fillStyle = randomRGB(180, 240)
59433            // context.fillStyle = randomGrey(200, 255)
59434
59435            context.fillStyle = color;
59436            context.fillRect(x, y, w, h);
59437          }
59438        }
59439      }
59440
59441      checkForLog(features) {
59442        if (this.isLog === undefined) {
59443          this.isLog = false;
59444
59445          for (let feature of features) {
59446            if (feature.value < 0) {
59447              this.isLog = true;
59448              return;
59449            }
59450          }
59451        }
59452      }
59453      /**
59454       * Optional method to compute pixel height to accomodate the list of features.  The implementation below
59455       * has side effects (modifiying the samples hash).  This is unfortunate, but harmless.
59456       *
59457       * Note displayMode "FILL" is handled by the viewport
59458       *
59459       * @param features
59460       * @returns {number}
59461       */
59462
59463
59464      computePixelHeight(features) {
59465        if (!features) return 0;
59466        const sampleHeight = "SQUISHED" === this.displayMode ? this.squishedRowHeight : this.expandedRowHeight;
59467        this.updateSampleKeys(features);
59468        return this.sampleKeys.length * sampleHeight;
59469      }
59470      /**
59471       * Sort samples by the average value over the genomic range in the direction indicated (1 = ascending, -1 descending)
59472       */
59473
59474
59475      async sortSamples(chr, start, end, direction, featureList) {
59476        if (!featureList) {
59477          featureList = await this.featureSource.getFeatures({
59478            chr,
59479            start,
59480            end
59481          });
59482        }
59483
59484        if (!featureList) return;
59485        this.updateSampleKeys(featureList);
59486        const scores = {};
59487        const d2 = direction === "ASC" ? 1 : -1;
59488
59489        const sortSeg = () => {
59490          // Compute weighted average score for each sample
59491          const bpLength = end - start + 1;
59492
59493          for (let segment of featureList) {
59494            if (segment.end < start) continue;
59495            if (segment.start > end) break;
59496            const min = Math.max(start, segment.start);
59497            const max = Math.min(end, segment.end);
59498            const f = (max - min) / bpLength;
59499            const sampleKey = segment.sampleKey || segment.sample;
59500            const s = scores[sampleKey] || 0;
59501            scores[sampleKey] = s + f * segment.value;
59502          } // Now sort sample names by score
59503
59504
59505          this.sampleKeys.sort(function (a, b) {
59506            let s1 = scores[a];
59507            let s2 = scores[b];
59508            if (!s1) s1 = d2 * Number.MAX_VALUE;
59509            if (!s2) s2 = d2 * Number.MAX_VALUE;
59510            if (s1 === s2) return 0;else if (s1 > s2) return d2;else return d2 * -1;
59511          });
59512        };
59513
59514        const sortMut = () => {
59515          // Compute weighted average score for each sample
59516          for (let segment of featureList) {
59517            if (segment.end < start) continue;
59518            if (segment.start > end) break;
59519            const sampleKey = segment.sampleKey || segment.sample;
59520
59521            if (!scores.hasOwnProperty(sampleKey) || segment.value.localeCompare(scores[sampleKey]) > 0) {
59522              scores[sampleKey] = segment.value;
59523            }
59524          } // Now sort sample names by score
59525
59526
59527          this.sampleKeys.sort(function (a, b) {
59528            let sa = scores[a] || "";
59529            let sb = scores[b] || "";
59530            return d2 * sa.localeCompare(sb);
59531          });
59532        };
59533
59534        if ("mut" === this.type) {
59535          sortMut();
59536        } else {
59537          sortSeg();
59538        }
59539
59540        this.trackView.repaintViews();
59541      }
59542
59543      clickedFeatures(clickState, features) {
59544        const allFeatures = super.clickedFeatures(clickState, features);
59545        const y = clickState.y;
59546        return allFeatures.filter(function (feature) {
59547          const rect = feature.pixelRect;
59548          return rect && y >= rect.y && y <= rect.y + rect.h;
59549        });
59550      }
59551
59552      popupData(clickState, featureList) {
59553        featureList = this.clickedFeatures(clickState);
59554        const items = [];
59555
59556        for (let feature of featureList) {
59557          // Double line divider between features
59558          if (items.length > 0) {
59559            items.push('<hr/>');
59560            items.push('<hr/>');
59561          } // hack for whole genome features, which save the original feature as "_f"
59562
59563
59564          const f = feature._f || feature;
59565          const data = typeof f.popupData === 'function' ? f.popupData(this.type, this.browser.genome.id) : this.extractPopupData(f);
59566          Array.prototype.push.apply(items, data);
59567        }
59568
59569        return items;
59570      }
59571
59572      contextMenuItemList(clickState) {
59573        const referenceFrame = clickState.viewport.referenceFrame;
59574        const genomicLocation = clickState.genomicLocation; // Define a region 5 "pixels" wide in genomic coordinates
59575
59576        const sortDirection = this.config.sort ? this.config.sort.direction === "ASC" ? "DESC" : "ASC" : // Toggle from previous sort
59577        "DESC";
59578        const bpWidth = referenceFrame.toBP(2.5);
59579
59580        const sortHandler = sort => {
59581          const viewport = clickState.viewport;
59582          const features = viewport.getCachedFeatures();
59583          this.sortSamples(sort.chr, sort.start, sort.end, sort.direction, features);
59584        };
59585
59586        const sortLabel = this.type === 'seg' ? 'Sort by value' : 'Sort by type';
59587        return [{
59588          label: sortLabel,
59589          click: e => {
59590            const sort = {
59591              direction: sortDirection,
59592              chr: clickState.viewport.referenceFrame.chr,
59593              start: genomicLocation - bpWidth,
59594              end: genomicLocation + bpWidth
59595            };
59596            sortHandler(sort);
59597            this.config.sort = sort;
59598          }
59599        }];
59600      }
59601
59602      supportsWholeGenome() {
59603        return (this.config.indexed === false || !this.config.indexURL) && this.config.supportsWholeGenome !== false;
59604      }
59605
59606      updateSampleKeys(featureList) {
59607        if (this.explicitSamples) return;
59608
59609        for (let feature of featureList) {
59610          const sampleKey = feature.sampleKey || feature.sample;
59611
59612          if (!this.sampleNames.has(sampleKey)) {
59613            this.sampleNames.set(sampleKey, feature.sample);
59614            this.sampleKeys.push(sampleKey);
59615          }
59616        }
59617      }
59618
59619    } // Mut and MAF file default color table
59620
59621
59622    const MUT_COLORS = {
59623      "indel": "rgb(0,200,0)",
59624      "targeted region": "rgb(236,155,43)",
59625      "truncating": "rgb(	150,0,0)",
59626      "non-coding transcript": "rgb(0,0,150)",
59627      // Colors from https://www.nature.com/articles/nature11404
59628      "synonymous": "rgb(109,165,95)",
59629      "silent": "rgb(109,135,80)",
59630      "missense_mutation": "rgb(72,130,187)",
59631      "missense": "rgb(72,130,187)",
59632      "splice site": "rgb(143,83,155)",
59633      "splice_region": "rgb(143,83,155)",
59634      "nonsense": "rgb(216, 57,81)",
59635      "nonsense_mutation": "rgb(216, 57,81)",
59636      "frame_shift_del": "rgb(226,135,65)",
59637      "frame_shift_ins": "rgb(226,135,65)",
59638      "in_frame_del": "rgb(247,235,94)",
59639      "in_frame_ins": "rgb(247,235,94)",
59640      "*other*": "rgb(159,91,50)" //
59641      // 3'Flank
59642      // 3'UTR
59643      // 5'Flank
59644      // 5'UTR
59645      // Frame_Shift_Del
59646      // Frame_Shift_Ins
59647      // IGR
59648      // In_Frame_Del
59649      // In_Frame_Ins
59650      // Intron
59651      // Missense_Mutation
59652      // Nonsense_Mutation
59653      // Nonstop_Mutation
59654      // RNA
59655      // Silent
59656      // Splice_Region
59657      // Splice_Site
59658      // Translation_Start_Site
59659      // Variant_Classification
59660
59661    };
59662
59663    /*
59664     * The MIT License (MIT)
59665     *
59666     * Copyright (c) 2016-2017 The Regents of the University of California
59667     * Author: Jim Robinson
59668     *
59669     * Permission is hereby granted, free of charge, to any person obtaining a copy
59670     * of this software and associated documentation files (the "Software"), to deal
59671     * in the Software without restriction, including without limitation the rights
59672     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
59673     * copies of the Software, and to permit persons to whom the Software is
59674     * furnished to do so, subject to the following conditions:
59675     *
59676     * The above copyright notice and this permission notice shall be included in
59677     * all copies or substantial portions of the Software.
59678     *
59679     *
59680     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59681     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
59682     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
59683     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59684     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
59685     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
59686     * THE SOFTWARE.
59687     */
59688
59689    class MergedTrack extends TrackBase {
59690      constructor(config, browser) {
59691        super(config, browser);
59692      }
59693
59694      init(config) {
59695        if (!config.tracks) {
59696          throw Error("Error: no tracks defined for merged track" + config);
59697        }
59698
59699        super.init(config);
59700      }
59701
59702      get height() {
59703        return this._height;
59704      }
59705
59706      set height(h) {
59707        this._height = h;
59708
59709        if (this.tracks) {
59710          for (let t of this.tracks) {
59711            t.height = h;
59712            t.config.height = h;
59713          }
59714        }
59715      }
59716
59717      async postInit() {
59718        this.tracks = [];
59719        const p = [];
59720
59721        for (let tconf of this.config.tracks) {
59722          tconf.isMergedTrack = true;
59723          const t = await this.browser.createTrack(tconf);
59724
59725          if (t) {
59726            t.autoscale = false; // Scaling done from merged track
59727
59728            this.tracks.push(t);
59729          } else {
59730            console.warn("Could not create track " + tconf);
59731          }
59732
59733          if (typeof t.postInit === 'function') {
59734            p.push(t.postInit());
59735          }
59736        }
59737
59738        this.height = this.config.height || 100;
59739        return Promise.all(p);
59740      }
59741
59742      async getFeatures(chr, bpStart, bpEnd, bpPerPixel) {
59743        const promises = this.tracks.map(t => t.getFeatures(chr, bpStart, bpEnd, bpPerPixel));
59744        return Promise.all(promises);
59745      }
59746
59747      draw(options) {
59748        var i, len, mergedFeatures, trackOptions, dataRange;
59749        mergedFeatures = options.features; // Array of feature arrays, 1 for each track
59750
59751        dataRange = autoscale(options.referenceFrame.chr, mergedFeatures); //IGVGraphics.fillRect(options.context, 0, options.pixelTop, options.pixelWidth, options.pixelHeight, {'fillStyle': "rgb(255, 255, 255)"});
59752
59753        for (i = 0, len = this.tracks.length; i < len; i++) {
59754          trackOptions = Object.assign({}, options);
59755          trackOptions.features = mergedFeatures[i];
59756          this.tracks[i].dataRange = dataRange;
59757          this.tracks[i].draw(trackOptions);
59758        }
59759      }
59760
59761      paintAxis(ctx, pixelWidth, pixelHeight) {
59762        var i, len, autoscale, track;
59763        autoscale = true; // Hardcoded for now
59764
59765        for (i = 0, len = this.tracks.length; i < len; i++) {
59766          track = this.tracks[i];
59767
59768          if (typeof track.paintAxis === 'function') {
59769            track.paintAxis(ctx, pixelWidth, pixelHeight);
59770            if (autoscale) break;
59771          }
59772        }
59773      }
59774
59775      popupData(clickState, features) {
59776        const featuresArray = features || clickState.viewport.getCachedFeatures();
59777
59778        if (featuresArray && featuresArray.length === this.tracks.length) {
59779          // Array of feature arrays, 1 for each track
59780          const popupData = [];
59781
59782          for (let i = 0; i < this.tracks.length; i++) {
59783            if (i > 0) popupData.push('<hr/>');
59784            popupData.push(`<div style=background-color:rgb(245,245,245);border-bottom-style:dashed;border-bottom-width:1px;padding-bottom:5px;padding-top:10px;font-weight:bold;font-size:larger >${this.tracks[i].name}</div>`);
59785            const trackPopupData = this.tracks[i].popupData(clickState, featuresArray[i]);
59786            popupData.push(...trackPopupData);
59787          }
59788
59789          return popupData;
59790        }
59791      }
59792
59793      supportsWholeGenome() {
59794        const b = this.tracks.every(track => track.supportsWholeGenome());
59795        return b;
59796      }
59797
59798    }
59799
59800    function autoscale(chr, featureArrays) {
59801      var min = 0,
59802          max = -Number.MAX_VALUE;
59803     // if (chr === 'all') {
59804      //     allValues = [];
59805      //     featureArrays.forEach(function (features) {
59806      //         features.forEach(function (f) {
59807      //             if (!Number.isNaN(f.value)) {
59808      //                 allValues.push(f.value);
59809      //             }
59810      //         });
59811      //     });
59812      //
59813      //     min = Math.min(0, IGVMath.percentile(allValues, .1));
59814      //     max = IGVMath.percentile(allValues, 99.9);
59815      //
59816      // }
59817      // else {
59818
59819      featureArrays.forEach(function (features, i) {
59820        features.forEach(function (f) {
59821          if (typeof f.value !== 'undefined' && !Number.isNaN(f.value)) {
59822            min = Math.min(min, f.value);
59823            max = Math.max(max, f.value);
59824          }
59825        });
59826      }); //  }
59827
59828      return {
59829        min: min,
59830        max: max
59831      };
59832    }
59833
59834    /*
59835     * The MIT License (MIT)
59836     *
59837     * Copyright (c) 2016-2018 The Regents of the University of California
59838     * Author: Jim Robinson
59839     *
59840     * Permission is hereby granted, free of charge, to any person obtaining a copy
59841     * of this software and associated documentation files (the "Software"), to deal
59842     * in the Software without restriction, including without limitation the rights
59843     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
59844     * copies of the Software, and to permit persons to whom the Software is
59845     * furnished to do so, subject to the following conditions:
59846     *
59847     * The above copyright notice and this permission notice shall be included in
59848     * all copies or substantial portions of the Software.
59849     *
59850     *
59851     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59852     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
59853     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
59854     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59855     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
59856     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
59857     * THE SOFTWARE.
59858     */
59859
59860    class InteractionTrack extends TrackBase {
59861      constructor(config, browser) {
59862        super(config, browser);
59863      }
59864
59865      init(config) {
59866        super.init(config);
59867        this.theta = config.theta || Math.PI / 4;
59868        this.sinTheta = Math.sin(this.theta);
59869        this.cosTheta = Math.cos(this.theta);
59870        this.height = config.height || 250;
59871        this.arcType = config.arcType || "nested"; // nested | proportional
59872
59873        this.arcOrientation = config.arcOrientation === undefined ? true : config.arcOrientation; // true for up, false for down
59874
59875        this.showBlocks = config.showBlocks === undefined ? true : config.showBlocks;
59876        this.blockHeight = config.blockHeight || 3;
59877        this.thickness = config.thickness || 1;
59878        this.color = config.color || "rgb(180,25,137)";
59879        this.alpha = config.alpha || 0.15;
59880
59881        if (config.valueColumn) {
59882          this.valueColumn = config.valueColumn;
59883          this.hasValue = true;
59884        } else if (config.useScore) {
59885          this.hasValue = true;
59886          this.valueColumn = "score";
59887        }
59888
59889        this.logScale = config.logScale !== false; // i.e. defaul to true (undefined => true)
59890
59891        if (config.max) {
59892          this.dataRange = {
59893            min: config.min || 0,
59894            max: config.max
59895          };
59896          this.autoscale = false;
59897        } else {
59898          this.autoscale = true;
59899        } // Create the FeatureSource and override the default whole genome method
59900
59901
59902        this.featureSource = FeatureSource(config, this.browser.genome);
59903        this.featureSource.getWGFeatures = getWGFeatures;
59904      }
59905
59906      async postInit() {
59907        if (typeof this.featureSource.getHeader === "function") {
59908          this.header = await this.featureSource.getHeader();
59909        } // Set properties from track line
59910
59911
59912        if (this.header) {
59913          this.setTrackProperties(this.header);
59914        }
59915
59916        if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') {
59917          this.visibilityWindow = await this.featureSource.defaultVisibilityWindow();
59918          this.featureSource.visibilityWindow = this.visibilityWindow; // <- this looks odd
59919        }
59920
59921        return this;
59922      }
59923
59924      supportsWholeGenome() {
59925        return true;
59926      }
59927
59928      async getFeatures(chr, start, end) {
59929        const visibilityWindow = this.visibilityWindow;
59930        const features = await this.featureSource.getFeatures({
59931          chr,
59932          start,
59933          end,
59934          visibilityWindow
59935        }); // Check for score or value
59936
59937        if (this.hasValue === undefined && features && features.length > 0) {
59938          this.hasValue = features[0].score !== undefined;
59939        }
59940
59941        return features;
59942      }
59943
59944      draw(options) {
59945        if (this.arcType === "proportional") {
59946          this.drawProportional(options);
59947        } else {
59948          this.drawNested(options);
59949        }
59950      }
59951
59952      drawNested(options) {
59953        const ctx = options.context;
59954        const pixelWidth = options.pixelWidth;
59955        const pixelHeight = options.pixelHeight;
59956        const viewportWidth = options.viewportWidth;
59957        const bpPerPixel = options.bpPerPixel;
59958        const bpStart = options.bpStart;
59959        const xScale = bpPerPixel;
59960        IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {
59961          'fillStyle': "rgb(255, 255, 255)"
59962        });
59963        const featureList = options.features;
59964
59965        if (featureList) {
59966          // Autoscale theta
59967          autoscaleNested.call(this);
59968          const y = this.arcOrientation ? options.pixelHeight : 0;
59969          const direction = this.arcOrientation;
59970          ctx.font = "8px sans-serif";
59971          ctx.textAlign = "center";
59972
59973          for (let feature of featureList) {
59974            let color = feature.color || this.color;
59975
59976            if (color && this.config.useScore) {
59977              color = getAlphaColor(color, scoreShade(feature.score));
59978            }
59979
59980            ctx.lineWidth = feature.thickness || this.thickness || 1;
59981
59982            if (feature.chr1 === feature.chr2 || feature.chr === 'all') {
59983              const {
59984                m1,
59985                m2
59986              } = getMidpoints(feature, this.browser.genome);
59987              let pixelStart = Math.round((m1 - bpStart) / xScale);
59988              let pixelEnd = Math.round((m2 - bpStart) / xScale);
59989              if (pixelEnd < 0 || pixelStart > pixelWidth) continue;
59990              let w = pixelEnd - pixelStart;
59991
59992              if (w < 3) {
59993                w = 3;
59994                pixelStart--;
59995              }
59996
59997              const a = w / 2;
59998              const r = a / this.sinTheta;
59999              const b = this.cosTheta * r;
60000              const xc = pixelStart + a;
60001              let yc, startAngle, endAngle;
60002
60003              if (direction) {
60004                // UP
60005                yc = this.height + b;
60006                startAngle = Math.PI + Math.PI / 2 - this.theta;
60007                endAngle = Math.PI + Math.PI / 2 + this.theta;
60008              } else {
60009                // DOWN
60010                yc = -b;
60011                startAngle = Math.PI / 2 - this.theta;
60012                endAngle = Math.PI / 2 + this.theta;
60013              }
60014
60015              if (this.showBlocks && feature.chr !== 'all') {
60016                const s1 = (feature.start1 - bpStart) / xScale;
60017                const e1 = (feature.end1 - bpStart) / xScale;
60018                const s2 = (feature.start2 - bpStart) / xScale;
60019                const e2 = (feature.end2 - bpStart) / xScale;
60020                const hb = this.arcOrientation ? -this.blockHeight : this.blockHeight;
60021                ctx.fillRect(s1, y, e1 - s1, hb);
60022                ctx.fillRect(s2, y, e2 - s2, hb);
60023              } // Alpha shade (de-emphasize) arcs that extend beyond viewport, unless alpha shading is used for score.
60024
60025
60026              if (color && !this.config.useScore && w > viewportWidth) {
60027                color = getAlphaColor(color, this.alpha);
60028              }
60029
60030              ctx.strokeStyle = color;
60031              ctx.fillStyle = color;
60032              ctx.beginPath();
60033              ctx.arc(xc, yc, r, startAngle, endAngle, false);
60034              ctx.stroke();
60035              feature.drawState = {
60036                xc,
60037                yc,
60038                r
60039              };
60040            } else {
60041              let pixelStart = Math.round((feature.start - bpStart) / xScale);
60042              let pixelEnd = Math.round((feature.end - bpStart) / xScale);
60043              if (pixelEnd < 0 || pixelStart > pixelWidth) continue;
60044              let w = pixelEnd - pixelStart;
60045
60046              if (w < 3) {
60047                w = 3;
60048                pixelStart--;
60049              }
60050
60051              const otherChr = feature.chr === feature.chr1 ? feature.chr2 : feature.chr1;
60052              ctx.strokeStyle = color;
60053              ctx.fillStyle = color;
60054
60055              if (direction) {
60056                // UP
60057                ctx.fillRect(pixelStart, this.height / 2, w, this.height / 2);
60058                ctx.fillText(otherChr, pixelStart + w / 2, this.height / 2 - 5);
60059                feature.drawState = {
60060                  x: pixelStart,
60061                  y: this.height / 2,
60062                  w: w,
60063                  h: this.height / 2
60064                };
60065              } else {
60066                ctx.fillRect(pixelStart, 0, w, this.height / 2);
60067                ctx.fillText(otherChr, pixelStart + w / 2, this.height / 2 + 13);
60068                feature.drawState = {
60069                  x: pixelStart,
60070                  y: 0,
60071                  w: w,
60072                  h: this.height / 2
60073                };
60074              }
60075            }
60076          }
60077        }
60078
60079        function autoscaleNested() {
60080          let max = 0;
60081
60082          for (let feature of featureList) {
60083            let pixelStart = (feature.start - bpStart) / xScale;
60084            let pixelEnd = (feature.end - bpStart) / xScale;
60085
60086            if (pixelEnd >= 0 && pixelStart <= pixelWidth) {
60087              max = Math.max(max, pixelEnd - pixelStart);
60088            }
60089          }
60090
60091          let a = Math.min(viewportWidth, max) / 2;
60092
60093          if (max > 0) {
60094            let coa = (pixelHeight - 10) / a;
60095            this.theta = estimateTheta(coa);
60096            this.sinTheta = Math.sin(this.theta);
60097            this.cosTheta = Math.cos(this.theta);
60098          }
60099        }
60100      }
60101
60102      drawProportional(options) {
60103        const ctx = options.context;
60104        const pixelWidth = options.pixelWidth;
60105        const pixelHeight = options.pixelHeight;
60106        const bpPerPixel = options.bpPerPixel;
60107        const bpStart = options.bpStart;
60108        const xScale = bpPerPixel; // SVG output for proportional arcs are currently not supported because "ellipse" is not implemented
60109        // if(typeof ctx.ellipse !== 'function') {
60110        //     Alert.presentAlert("SVG output of proportional arcs is currently not supported.")
60111        //     return;
60112        // }
60113
60114        IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {
60115          'fillStyle': "rgb(255, 255, 255)"
60116        });
60117        const featureList = options.features;
60118
60119        if (featureList && featureList.length > 0) {
60120          const yScale = this.logScale ? options.pixelHeight / Math.log10(this.dataRange.max + 1) : options.pixelHeight / (this.dataRange.max - this.dataRange.min);
60121          const y = this.arcOrientation ? options.pixelHeight : 0;
60122
60123          for (let feature of featureList) {
60124            const value = this.valueColumn ? feature[this.valueColumn] : feature.score;
60125            if (value === undefined || Number.isNaN(value)) continue;
60126            const radiusY = this.logScale ? Math.log10(value + 1) * yScale : value * yScale;
60127
60128            if (feature.chr1 === feature.chr2 || feature.chr === 'all') {
60129              const {
60130                m1,
60131                m2
60132              } = getMidpoints(feature, this.browser.genome);
60133              let pixelStart = (m1 - bpStart) / xScale;
60134              let pixelEnd = (m2 - bpStart) / xScale;
60135              let w = pixelEnd - pixelStart;
60136
60137              if (w < 3) {
60138                w = 3;
60139                pixelStart--;
60140              }
60141
60142              if (pixelEnd < 0 || pixelStart > pixelWidth || value < this.dataRange.min) continue;
60143              const radiusX = w / 2;
60144              const xc = pixelStart + w / 2;
60145              const counterClockwise = this.arcOrientation ? true : false;
60146              const color = feature.color || this.color;
60147              ctx.strokeStyle = color;
60148              ctx.lineWidth = feature.thickness || this.thickness || 1;
60149
60150              if (true === ctx.isSVG) {
60151                ctx.strokeEllipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise);
60152              } else {
60153                ctx.beginPath();
60154                ctx.ellipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise);
60155                ctx.stroke();
60156              }
60157
60158              if (this.showBlocks && feature.chr !== 'all') {
60159                ctx.fillStyle = color;
60160                const s1 = (feature.start1 - bpStart) / xScale;
60161                const e1 = (feature.end1 - bpStart) / xScale;
60162                const s2 = (feature.start2 - bpStart) / xScale;
60163                const e2 = (feature.end2 - bpStart) / xScale;
60164                const hb = this.arcOrientation ? -this.blockHeight : this.blockHeight;
60165                ctx.fillRect(s1, y, e1 - s1, hb);
60166                ctx.fillRect(s2, y, e2 - s2, hb);
60167              }
60168
60169              if (this.alpha) {
60170                ctx.fillStyle = getAlphaColor(color, this.alpha);
60171
60172                if (true === ctx.isSVG) {
60173                  ctx.fillEllipse(xc, y, radiusX, radiusY, 0, 0, Math.PI, counterClockwise);
60174                } else {
60175                  ctx.fill();
60176                }
60177              }
60178
60179              feature.drawState = {
60180                xc,
60181                yc: y,
60182                radiusX,
60183                radiusY
60184              };
60185            } else {
60186              let pixelStart = Math.round((feature.start - bpStart) / xScale);
60187              let pixelEnd = Math.round((feature.end - bpStart) / xScale);
60188              if (pixelEnd < 0 || pixelStart > pixelWidth || value < this.dataRange.min) continue;
60189              const h = Math.min(radiusY, this.height - 13); // Leave room for text
60190
60191              let w = pixelEnd - pixelStart;
60192
60193              if (w < 3) {
60194                w = 3;
60195                pixelStart--;
60196              }
60197
60198              const otherChr = feature.chr === feature.chr1 ? feature.chr2 : feature.chr1;
60199              ctx.font = "8px sans-serif";
60200              ctx.textAlign = "center";
60201
60202              if (this.arcOrientation) {
60203                // UP
60204                const y = this.height - h;
60205                ctx.fillRect(pixelStart, y, w, h);
60206                ctx.fillText(otherChr, pixelStart + w / 2, y - 5);
60207                feature.drawState = {
60208                  x: pixelStart,
60209                  y,
60210                  w,
60211                  h
60212                };
60213              } else {
60214                ctx.fillRect(pixelStart, 0, w, h);
60215                ctx.fillText(otherChr, pixelStart + w / 2, h + 13);
60216                feature.drawState = {
60217                  x: pixelStart,
60218                  y: 0,
60219                  w,
60220                  h
60221                };
60222              }
60223            }
60224          }
60225        }
60226      }
60227
60228      menuItemList() {
60229        let items = [{
60230          name: "Set track color",
60231          click: () => {
60232            this.trackView.presentColorPicker();
60233          }
60234        }, '<hr/>'];
60235
60236        if (this.hasValue) {
60237          const lut = {
60238            "nested": "Nested Arcs",
60239            "proportional": "Proportional Arcs"
60240          };
60241
60242          for (let arcType of ["nested", "proportional"]) {
60243            items.push({
60244              object: $$1(createCheckbox$1(lut[arcType], arcType === this.arcType)),
60245              click: () => {
60246                this.arcType = arcType;
60247                this.trackView.repaintViews();
60248              }
60249            });
60250          }
60251        }
60252
60253        items.push({
60254          object: $$1(createCheckbox$1("Show Blocks", this.showBlocks)),
60255          click: () => {
60256            this.showBlocks = !this.showBlocks;
60257            this.trackView.repaintViews();
60258          }
60259        });
60260        items.push({
60261          name: "Toggle arc direction",
60262          click: () => {
60263            this.arcOrientation = !this.arcOrientation;
60264            this.trackView.repaintViews();
60265          }
60266        });
60267
60268        if (this.arcType === "proportional") {
60269          items.push("<HR>");
60270          items = items.concat(MenuUtils.numericDataMenuItems(this.trackView));
60271        }
60272
60273        if (this.browser.circularView && true === this.browser.circularViewVisible) {
60274          items.push({
60275            label: 'Add interactions to circular view',
60276            click: () => {
60277              const inView = [];
60278
60279              for (let viewport of this.trackView.viewports) {
60280                const refFrame = viewport.referenceFrame;
60281
60282                for (let f of viewport.getCachedFeatures()) {
60283                  if (f.end >= refFrame.start && f.start <= refFrame.end) {
60284                    inView.push(f);
60285                  }
60286                }
60287              }
60288
60289              const chords = makeBedPEChords(inView);
60290              const color = IGVColor.addAlpha(this.color, 0.5);
60291              this.browser.circularView.addChords(chords, {
60292                track: this.name,
60293                color: color
60294              });
60295            }
60296          });
60297        }
60298
60299        return items;
60300      }
60301
60302      contextMenuItemList(clickState) {
60303        // Experimental JBrowse feature
60304        if (this.browser.circularView && true === this.browser.circularViewVisible) {
60305          const viewport = clickState.viewport;
60306          const list = [];
60307          list.push({
60308            label: 'Add interactions to circular view',
60309            click: () => {
60310              const refFrame = viewport.referenceFrame;
60311              const inView = "all" === refFrame.chr ? this.featureSource.getAllFeatures() : this.featureSource.featureCache.queryFeatures(refFrame.chr, refFrame.start, refFrame.end);
60312              this.browser.circularViewVisible = true;
60313              const chords = makeBedPEChords(inView);
60314              const color = IGVColor.addAlpha(this.color, 0.5);
60315              this.browser.circularView.addChords(chords, {
60316                track: this.name,
60317                color: color
60318              });
60319            }
60320          });
60321          list.push('<hr/>');
60322          return list;
60323        }
60324      }
60325
60326      doAutoscale(features) {
60327        // if ("proportional" === this.arcType) {
60328        let max = 0;
60329
60330        if (features) {
60331          for (let f of features) {
60332            const v = this.valueColumn ? f[this.valueColumn] : f.score;
60333
60334            if (!Number.isNaN(v)) {
60335              max = Math.max(max, v);
60336            }
60337          }
60338        }
60339
60340        return {
60341          min: 0,
60342          max: max
60343        }; // }
60344      }
60345
60346      popupData(clickState, features) {
60347        features = this.clickedFeatures(clickState);
60348        const data = [];
60349
60350        for (let feature of features) {
60351          const f = feature._ || feature; // For "whole genome" features, which keeps a pointer to the original
60352
60353          data.push({
60354            name: "Region 1",
60355            value: positionString(f.chr1, f.start1, f.end1, f.strand1)
60356          });
60357          data.push({
60358            name: "Region 2",
60359            value: positionString(f.chr2, f.start2, f.end2, f.strand2)
60360          });
60361
60362          if (f.name) {
60363            data.push({
60364              name: "Name",
60365              value: f.name
60366            });
60367          }
60368
60369          if (f.value !== undefined) {
60370            data.push({
60371              name: "Value",
60372              value: f.value
60373            });
60374          }
60375
60376          if (f.score !== undefined) {
60377            data.push({
60378              name: "Score",
60379              value: f.score
60380            });
60381          }
60382
60383          if (f.extras && this.header && this.header.columnNames) {
60384            const columnNames = this.header.columnNames;
60385
60386            for (let i = 10; i < columnNames.length; i++) {
60387              if (columnNames[i] === 'info') {
60388                extractInfoColumn(data, f.extras[i - 10]);
60389              } else {
60390                data.push({
60391                  name: columnNames[i],
60392                  value: f.extras[i - 10]
60393                });
60394              }
60395            }
60396          } // For now just return the top hit
60397
60398
60399          break; //if (data.length > 0) {
60400          //     data.push("<HR>");
60401          // }
60402        }
60403
60404        return data;
60405      }
60406
60407      clickedFeatures(clickState, features) {
60408        // We use the cached features rather than method to avoid async load.  If the
60409        // feature is not already loaded this won't work,  but the user wouldn't be mousing over it either.
60410        const featureList = features || clickState.viewport.getCachedFeatures();
60411        const candidates = [];
60412
60413        if (featureList) {
60414          const proportional = this.arcType === "proportional";
60415
60416          for (let feature of featureList) {
60417            if (!feature.drawState) continue;
60418
60419            if (feature.chr1 === feature.chr2 || feature.chr === 'all') {
60420              if (proportional) {
60421                //(x-xc)^2/radiusX^2 + (y-yc)^2/radiusY^2 <= 1
60422                const {
60423                  xc,
60424                  yc,
60425                  radiusX,
60426                  radiusY
60427                } = feature.drawState;
60428                const dx = clickState.canvasX - xc;
60429                const dy = clickState.canvasY - yc;
60430                const score = dx / radiusX * (dx / radiusX) + dy / radiusY * (dy / radiusY);
60431
60432                if (score <= 1) {
60433                  candidates.push({
60434                    score: 1 / score,
60435                    feature
60436                  });
60437                }
60438              } else {
60439                const {
60440                  xc,
60441                  yc,
60442                  r
60443                } = feature.drawState;
60444                const dx = clickState.canvasX - xc;
60445                const dy = clickState.canvasY - yc;
60446                const score = Math.abs(Math.sqrt(dx * dx + dy * dy) - r);
60447
60448                if (score < 5) {
60449                  candidates.push({
60450                    score,
60451                    feature
60452                  });
60453                }
60454              }
60455            } else {
60456              const {
60457                x,
60458                y,
60459                w,
60460                h
60461              } = feature.drawState;
60462              const tolerance = 5;
60463
60464              if (clickState.canvasX >= x - tolerance && clickState.canvasX <= x + w + tolerance && clickState.canvasY >= y && clickState.canvasY <= y + h) {
60465                const score = -Math.abs(clickState.canvasX - (x + w / 2));
60466                candidates.push({
60467                  score,
60468                  feature
60469                });
60470                break;
60471              }
60472            }
60473          }
60474        }
60475
60476        if (candidates.length > 1) {
60477          candidates.sort((a, b) => a.score - b.score);
60478        }
60479
60480        return candidates.map(c => c.feature);
60481      }
60482
60483    }
60484
60485    function getMidpoints(feature, genome) {
60486      let m1 = (feature.start1 + feature.end1) / 2;
60487      let m2 = (feature.start2 + feature.end2) / 2;
60488
60489      if (feature.chr === 'all') {
60490        m1 = genome.getGenomeCoordinate(feature.chr1, m1);
60491        m2 = genome.getGenomeCoordinate(feature.chr2, m2);
60492      }
60493
60494      if (m1 > m2) {
60495        const tmp = m1;
60496        m1 = m2;
60497        m2 = tmp;
60498      }
60499
60500      return {
60501        m1,
60502        m2
60503      };
60504    }
60505
60506    function positionString(chr, start, end, strand) {
60507      return strand && strand !== '.' ? `${chr}:${numberFormatter$1(start + 1)}-${numberFormatter$1(end)} (${strand})` : `${chr}:${numberFormatter$1(start + 1)}-${numberFormatter$1(end)}`;
60508    }
60509    /**
60510     * Estimate theta given the ratio of track height to 1/2 the feature width (coa).  This relationship is a
60510pproximately linear.
60511     */
60512
60513
60514    function estimateTheta(x) {
60515      let coa = [0.01570925532366355, 0.15838444032453644, 0.3249196962329063, 0.5095254494944288, 0.7265425280053609, 0.9999999999999999];
60516      let theta = [0.031415926535897934, 0.3141592653589793, 0.6283185307179586, 0.9424777960769379, 1.2566370614359172, 1.5707963267948966];
60517      let idx;
60518
60519      for (idx = 0; idx < coa.length; idx++) {
60520        if (coa[idx] > x) {
60521          break;
60522        }
60523      }
60524
60525      let left = idx === 0 ? 0 : coa[idx - 1];
60526      let right = idx < coa.length ? coa[idx] : 1;
60527      let r = (x - left) / (right - left);
60528      let thetaLeft = idx === 0 ? 0 : theta[idx - 1];
60529      let thetaRight = idx < theta.length ? theta[idx] : Math.PI / 2;
60530      return thetaLeft + r * (thetaRight - thetaLeft);
60531    }
60532
60533    const colorAlphaCache = new Map();
60534
60535    function getAlphaColor(color, alpha) {
60536      const key = `${color}_${alpha}`;
60537      let c = colorAlphaCache.get(key);
60538
60539      if (!c) {
60540        c = IGVColor.addAlpha(color, alpha);
60541        colorAlphaCache.set(key, c);
60542      }
60543
60544      return c;
60545    }
60546    /**
60547     * Called in the context of FeatureSource
60548     * @param allFeatures
60549     * @returns {[]}
60550     */
60551
60552
60553    function getWGFeatures(allFeatures) {
60554      const genome = this.genome;
60555      const wgFeatures = [];
60556
60557      for (let c of genome.wgChromosomeNames) {
60558        const chrFeatures = allFeatures[c];
60559
60560        if (chrFeatures) {
60561          for (let f of chrFeatures) {
60562            if (!f.dup) {
60563              const wg = Object.assign({}, f);
60564              wg.chr = "all";
60565              wg.start = genome.getGenomeCoordinate(f.chr1, f.start1);
60566              wg.end = genome.getGenomeCoordinate(f.chr2, f.end2);
60567              wgFeatures.push(wg);
60568            }
60569          }
60570        }
60571      }
60572
60573      return wgFeatures;
60574    }
60575    /**
60576     * Extract a gff style info column for popup text.  This convention used by 10X for bedpe files
60577     *     ALLELIC_FRAC=0.0375670840787;BLACK1=.;BLACK2=.;...
60578     * @param data
60579     * @param str
60580     */
60581
60582
60583    function extractInfoColumn(data, str) {
60584      const kvs = str.split(';');
60585
60586      for (let t of kvs) {
60587        const kv = t.split('=');
60588
60589        if (kv.length === 2) {
60590          data.push({
60591            name: kv[0],
60592            value: kv[1]
60593          });
60594        }
60595      }
60596    }
60597
60598    /*
60599     * The MIT License (MIT)
60600     *
60601     * Copyright (c) 2016 University of California San Diego
60602     * Author: Jim Robinson
60603     *
60604     * Permission is hereby granted, free of charge, to any person obtaining a copy
60605     * of this software and associated documentation files (the "Software"), to deal
60606     * in the Software without restriction, including without limitation the rights
60607     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
60608     * copies of the Software, and to permit persons to whom the Software is
60609     * furnished to do so, subject to the following conditions:
60610     *
60611     * The above copyright notice and this permission notice shall be included in
60612     * all copies or substantial portions of the Software.
60613     *
60614     *
60615     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60616     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60617     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
60618     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
60619     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
60620     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
60621     * THE SOFTWARE.
60622     */
60623    const isString = isString$3;
60624    const DEFAULT_VISIBILITY_WINDOW = 1000000;
60625    const TOP_MARGIN = 10;
60626
60627    class VariantTrack extends TrackBase {
60628      constructor(config, browser) {
60629        super(config, browser);
60630      }
60631
60632      init(config) {
60633        super.init(config);
60634        this.visibilityWindow = config.visibilityWindow;
60635        this.displayMode = config.displayMode || "EXPANDED"; // COLLAPSED | EXPANDED | SQUISHED
60636
60637        this.labelDisplayMode = config.labelDisplayMode;
60638        this.expandedVariantHeight = config.expandedVariantHeight || config.variantHeight || 10;
60639        this.squishedVariantHeight = config.squishedVariantHeight || 2;
60640        this.squishedCallHeight = config.squishedCallHeight || 1;
60641        this.expandedCallHeight = config.expandedCallHeight || 10;
60642        this.expandedVGap = config.expandedVGap !== undefined ? config.expandedVGap : 2;
60643        this.squishedVGap = config.squishedVGap !== undefined ? config.squishedVGap : 1;
60644        this.expandedGroupGap = config.expandedGroupGap || 10;
60645        this.squishedGroupGap = config.squishedGroupGap || 5;
60646        this.featureHeight = config.featureHeight || 14;
60647        this.visibilityWindow = config.visibilityWindow;
60648        this.featureSource = FeatureSource(config, this.browser.genome);
60649        this.noGenotypeColor = config.noGenotypeColor || "rgb(200,180,180)";
60650        this.noCallColor = config.noCallColor || "rgb(225, 225, 225)";
60651        this.nonRefColor = config.nonRefColor || "rgb(200, 200, 215)";
60652        this.mixedColor = config.mixedColor || "rgb(200, 220, 200)";
60653        this.homrefColor = config.homrefColor || "rgb(200, 200, 200)";
60654        this.homvarColor = config.homvarColor || "rgb(17,248,254)";
60655        this.hetvarColor = config.hetvarColor || "rgb(34,12,253)";
60656        this.sortDirection = "ASC";
60657        this.type = config.type || "variant";
60658        this.colorBy = config.colorBy; // Can be undefined => default
60659
60660        this._initColorBy = config.colorBy;
60661
60662        if (config.colorTable) {
60663          this.colorTables = new Map();
60664          this.colorTables.set(config.colorBy, new ColorTable(config.colorTable));
60665        }
60666
60667        this._color = config.color;
60668        this.showGenotypes = config.showGenotypes === undefined ? true : config.showGenotypes; // The number of variant rows are computed dynamically, but start with "1" by default
60669
60670        this.variantRowCount(1);
60671      }
60672
60673      async postInit() {
60674        this.header = await this.getHeader(); // cricital, don't remove'
60675
60676        if (undefined === this.visibilityWindow && this.config.indexed !== false) {
60677          const fn = isFile(this.config.url) ? this.config.url.name : this.config.url;
60678
60679          if (isString(fn) && fn.toLowerCase().includes("gnomad")) {
60680            this.visibilityWindow = 1000; // these are known to be very dense
60681          } else if (typeof this.featureSource.defaultVisibilityWindow === 'function') {
60682            this.visibilityWindow = await this.featureSource.defaultVisibilityWindow();
60683          } else {
60684            this.visibilityWindow = DEFAULT_VISIBILITY_WINDOW;
60685          }
60686        }
60687
60688        return this;
60689      }
60690
60691      supportsWholeGenome() {
60692        return this.config.indexed === false || this.config.supp
60692ortsWholeGenome === true;
60693      }
60694
60695      get color() {
60696        return this._color;
60697      }
60698
60699      set color(c) {
60700        this._color = c;
60701        this.colorBy = undefined;
60702      }
60703
60704      async getHeader() {
60705        if (!this.header) {
60706          if (typeof this.featureSource.getHeader === "function") {
60707            const header = await this.featureSource.getHeader();
60708
60709            if (header) {
60710              this.callSets = header.callSets || [];
60711            }
60712
60713            this.header = header;
60714          }
60715
60716          this.sampleNames = this.callSets ? this.callSets.map(cs => cs.name) : [];
60717        }
60718
60719        return this.header;
60720      }
60721
60722      getCallsetsLength() {
60723        return this.callSets ? this.callSets.length : 0;
60724      }
60725
60726      async getFeatures(chr, start, end, bpPerPixel) {
60727        if (this.header === undefined) {
60728          this.header = await this.getHeader();
60729        }
60730
60731        return this.featureSource.getFeatures({
60732          chr,
60733          start,
60734          end,
60735          bpPerPixel,
60736          visibilityWindow: this.visibilityWindow
60737        });
60738      }
60739
60740      hasSamples() {
60741        return this.getCallsetsLength() > 0;
60742      }
60743
60744      getSamples() {
60745        return {
60746          yOffset: this.sampleYOffset,
60747          names: this.sampleNames,
60748          height: this.sampleHeight
60749        };
60750      }
60751      /**
60752       * The required height in pixels required for the track content.   This is not the visible track height, which
60753       * can be smaller (with a scrollbar) or larger.
60754       *
60755       * @param features
60756       * @returns {*}
60757       */
60758
60759
60760      computePixelHeight(features) {
60761        if (!features || features.length == 0) return TOP_MARGIN;
60762        const nVariantRows = this.displayMode === "COLLAPSED" ? 1 : this.nVariantRows;
60763        const vGap = this.displayMode === "SQUISHED" ? this.squishedVGap : this.expandedVGap;
60764        const variantHeight = this.displayMode === "SQUISHED" ? this.squishedVariantHeight : this.expandedVariantHeight;
60765        const callHeight = this.displayMode === "SQUISHED" ? this.squishedCallHeight : this.expandedCallHeight;
60766        const nCalls = this.showGenotypes === false ? 0 : this.getCallsetsLength() * nVariantRows;
60767        const h = TOP_MARGIN + nVariantRows * (variantHeight + vGap);
60768        return h + vGap + (nCalls + 1) * (callHeight + vGap);
60769      }
60770
60771      variantRowCount(count) {
60772        this.nVariantRows = count;
60773      }
60774
60775      draw(_ref) {
60776        let {
60777          context,
60778          pixelWidth,
60779          pixelHeight,
60780          bpPerPixel,
60781          bpStart,
60782          pixelTop,
60783          features
60784        } = _ref;
60785        IGVGraphics.fillRect(context, 0, pixelTop, pixelWidth, pixelHeight, {
60786          'fillStyle': "rgb(255, 255, 255)"
60787        });
60788        const vGap = "SQUISHED" === this.displayMode ? this.squishedVGap : this.expandedVGap;
60789        const rc = "COLLAPSED" === this.displayMode ? 1 : this.nVariantRows;
60790        const variantHeight = "SQUISHED" === this.displayMode ? this.squishedVariantHeight : this.expandedVariantHeight;
60791        this.variantBandHeight = TOP_MARGIN + rc * (variantHeight + vGap);
60792        const callSets = this.callSets;
60793        const nCalls = this.getCallsetsLength();
60794
60795        if (callSets && nCalls > 0 && this.showGenotypes !== false) {
60796          IGVGraphics.strokeLine(context, 0, this.variantBandHeight, pixelWidth, this.variantBandHeight, {
60797            strokeStyle: 'rgb(224,224,224) '
60798          });
60799        }
60800
60801        if (features) {
60802          const callHeight = "SQUISHED" === this.displayMode ? this.squishedCallHeight : this.expandedCallHeight;
60803          const vGap = "SQUISHED" === this.displayMode ? this.squishedVGap : this.expandedVGap;
60804          const bpEnd = bpStart + pixelWidth * bpPerPixel + 1; // Loop through variants.  A variant == a row in a VCF file
60805
60806          for (let variant of features) {
60807            if (variant.end < bpStart) continue;
60808            if (variant.start > bpEnd) break;
60809            const variantHeight = "SQUISHED" === this.displayMode ? this.squishedVariantHeight : this.expandedVariantHeight;
60810            const y = TOP_MARGIN + ("COLLAPSED" === this.displayMode ? 0 : variant.row * (variantHeight + vGap));
60811            const h = variantHeight; // Compute pixel width.   Minimum width is 3 pixels,  if > 5 pixels create gap between variants
60812
60813            let x = Math.round((variant.start - bpStart) / bpPerPixel);
60814            let x1 = Math.round((variant.end - bpStart) / bpPerPixel);
60815            let w = Math.max(1, x1 - x);
60816
60817            if (w < 3) {
60818              w = 3;
60819              x -= 1;
60820            } else if (w > 5) {
60821              x += 1;
60822              w -= 2;
60823            }
60824
60825            context.fillStyle = this.getVariantColor(variant);
60826            context.fillRect(x, y, w, h);
60827            variant.pixelRect = {
60828              x,
60829              y,
60830              w,
60831              h
60832            }; // Loop though the calls for this variant.  There will potentially be a call for each sample.
60833
60834            if (nCalls > 0 && this.showGenotypes !== false) {
60835              const nVariantRows = "COLLAPSED" === this.displayMode ? 1 : this.nVariantRows;
60836              this.sampleYOffset = this.variantBandHeight + vGap;
60837              this.sampleHeight = nVariantRows * (callHeight + vGap); // For each sample, there is a call for each variant at this position
60838
60839              let sampleNumber = 0;
60840
60841              for (let callSet of callSets) {
60842                const call = variant.calls[callSet.id];
60843
60844                if (call) {
60845                  const row = "COLLAPSED" === this.displayMode ? 0 : variant.row;
60846                  const py = this.sampleYOffset + sampleNumber * this.sampleHeight + row * (callHeight + vGap);
60847                  let allVar = true; // until proven otherwise
60848
60849                  let allRef = true;
60850                  let noCall = false;
60851
60852                  if (call.genotype) {
60853                    for (let g of call.genotype) {
60854                      if ('.' === g) {
60855                        noCall = true;
60856                        break;
60857                      } else {
60858                        if (g !== 0) allRef = false;
60859                        if (g === 0) allVar = false;
60860                      }
60861                    }
60862                  }
60863
60864                  if (!call.genotype) {
60865                    context.fillStyle = this.noGenotypeColor;
60866                  } else if (noCall) {
60867                    context.fillStyle = this.noCallColor;
60868                  } else if (allRef) {
60869                    context.fillStyle = this.homrefColor;
60870                  } else if (allVar) {
60871                    context.fillStyle = this.homvarColor;
60872                  } else {
60873                    context.fillStyle = this.hetvarColor;
60874                  }
60875
60876                  context.fillRect(x, py, w, callHeight);
60877                  callSet.pixelRect = {
60878                    x,
60879                    y: py,
60880                    w,
60881                    h: callHeight
60882                  };
60883                }
60884
60885                sampleNumber++;
60886              }
60887            }
60888          }
60889        } else {
60890          console.log("No feature list");
60891        }
60892      }
60893
60894      getVariantColor(variant) {
60895        const v = variant._f || variant;
60896        let variantColor;
60897
60898        if (this.colorBy) {
60899          const value = v.info[this.colorBy];
60900          variantColor = this.getVariantColorTable(this.colorBy).getColor(value);
60901
60902          if (!variantColor) {
60903            variantColor = "gray";
60904          }
60905        } else if (this._color) {
60906          variantColor = typeof this._color === "function" ? this._color(v) : this._color;
60907        } else if ("NONVARIANT" === v.type) {
60908          variantColor = this.nonRefColor;
60909        } else if ("MIXED" === v.type) {
60910          variantColor = this.mixedColor;
60911        } else {
60912          variantColor = this.defaultColor;
60913        }
60914
60915        return variantColor;
60916      }
60917
60918      clickedFeatures(clickState, features) {
60919        let featureList = super.clickedFeatures(clickState, features);
60920        const vGap = this.displayMode === 'EXPANDED' ? this.expandedVGap : this.squishedVGap;
60921        const callHeight = vGap + ("SQUISHED" === this.displayMode ? this.squishedCallHeight : this.expandedCallHeight); // Find the variant row (i.e. row assigned during feature packing)
60922
60923        const yOffset = clickState.y;
60924
60925        if (yOffset <= this.variantBandHeight) {
60926          // Variant
60927          const variantHeight = "SQUISHED" === this.displayMode ? this.squishedVariantHeight : this.expandedVariantHeight;
60928          const variantRow = Math.floor((yOffset - TOP_MARGIN) / (variantHeight + vGap));
60929          featureList = featureList.filter(f => f.row === variantRow);
60930        } else if (this.callSets) {
60931          const callSets = this.callSets;
60932          const sampleY = yOffset - this.variantBandHeight;
60933          const sampleRow = Math.floor(sampleY / this.sampleHeight);
60934
60935          if (sampleRow >= 0 && sampleRow < callSets.length) {
60936            const variantRow = Math.floor((sampleY - sampleRow * this.sampleHeight) / callHeight);
60937            const variants = featureList.filter(f => f.row === variantRow);
60938            const cs = callSets[sampleRow];
60939            featureList = variants.map(v => {
60940              const call = v.calls[cs.id];
60941              expandGenotype(call, v);
60942              return call;
60943            });
60944          }
60945        }
60946
60947        return featureList;
60948      }
60949      /**
60950       * Return "popup data" for feature @ genomic location.  Data is an array of key-value pairs
60951       */
60952
60953
60954      popupData(clickState, features) {
60955        const featureList = this.clickedFeatures(clickState, features);
60956        const genomicLocation = clickState.genomicLocation;
60957        const genomeID = this.browser.genome.id;
60958        const sampleInformation = this.browser.sampleInformation;
60959        let popupData = [];
60960
60961        for (let v of featureList) {
60962          const f = v._f || v; // Get real variant from psuedo-variant, e.g. whole genome or SV mate
60963
60964          if (popupData.length > 0) {
60965            popupData.push({
60966              html: '<hr style="border-top-width:2px ;border-color: #c9c3ba" />'
60967            });
60968          }
60969
60970          if (typeof f.popupData === 'function') {
60971            const v = f.popupData(genomicLocation, genomeID);
60972            Array.prototype.push.apply(popupData, v);
60973          } else {
60974            // Assume this is a call (genotype)
60975            const call = f;
60976
60977            if (call.callSetName !== undefined) {
60978              popupData.push({
60979                name: 'Name',
60980                value: call.callSetName
60981              });
60982            }
60983
60984            if (call.genotypeName) {
60985              popupData.push({
60986                name: 'Genotype',
60987                value: call.genotypeName
60988              });
60989            }
60990
60991            if (call.phaseset !== undefined) {
60992              popupData.push({
60993                name: 'Phase set',
60994                value: call.phaseset
60995              });
60996            }
60997
60998            if (call.genotypeLikelihood !== undefined) {
60999              popupData.push({
61000                name: 'genotypeLikelihood',
61001                value: call.genotypeLikelihood.toString()
61002              });
61003            }
61004
61005            if (sampleInformation) {
61006              var attr = sampleInformation.getAttributes(call.callSetName);
61007
61008              if (attr) {
61009                Object.keys(attr).forEach(function (attrName) {
61010                  var displayText = attrName.replace(/([A-Z])/g, " $1");
61011                  displayText = displayText.charAt(0).toUpperCase() + displayText.slice(1);
61012                  popupData.push({
61013                    name: displayText,
61014                    value: attr[attrName]
61015                  });
61016                });
61017              }
61018            }
61019
61020            var infoKeys = Object.keys(call.info);
61021
61022            if (infoKeys.length) {
61023              popupData.push('<hr/>');
61024            }
61025
61026            infoKeys.forEach(function (key) {
61027              popupData.push({
61028                name: key,
61029                value: decodeURIComponent(call.info[key])
61030              });
61031            });
61032          }
61033        }
61034
61035        return popupData;
61036      } // VariantTrack.prototype.contextMenuItemList = function (clickState) {
61037      //
61038      //     const self = this;
61039      //     const menuItems = [];
61040      //
61041      //     const featureList = this.clickedFeatures(clickState);
61042      //
61043      //     if (this.callSets && featureList && featureList.length > 0) {
61044      //
61045      //         featureList.forEach(function (variant) {
61046      //
61047      //             if ('str' === variant.type) {
61048      //
61049      //                 menuItems.push({
61050      //                     label: 'Sort by allele length',
61051      //                     click: function () {
61052      //                         sortCallSetsByAlleleLength(self.callSets, variant, self.sortDirection);
61053      //                         self.sortDirection = (self.sortDirection === "ASC") ? "DESC" : "ASC";
61054      //                         self.trackView.repaintViews();
61055      //                     }
61056      //                 });
61057      //
61058      //             }
61059      //
61060      //         });
61061      //     }
61062      //
61063      //
61064      //     function sortCallSetsByAlleleLength(callSets, variant, direction) {
61065      //         var d = (direction === "DESC") ? 1 : -1;
61066      //         Object.keys(callSets).forEach(function (property) {
61067      //             callSets[property].sort(function (a, b) {
61068      //                 var aNan = isNaN(variant.calls[a.id].genotype[0]);
61069      //                 var bNan = isNaN(variant.calls[b.id].genotype[0]);
61070      //                 if (aNan && bNan) {
61071      //                     return 0;
61072      //                 } else if (aNan) {
61073      //                     return 1;
61074      //                 } else if (bNan) {
61075      //                     return -1;
61076      //                 } else {
61077      //                     var a0 = getAlleleString(variant.calls[a.id], variant, 0);
61078      //                     var a1 = getAlleleString(variant.calls[a.id], variant, 1);
61079      //                     var b0 = getAlleleString(variant.calls[b.id], variant, 0);
61080      //                     var b1 = getAlleleString(variant.calls[b.id], variant, 1);
61081      //                     var result = Math.max(b0.length, b1.length) - Math.max(a0.length, a1.length);
61082      //                     if (result === 0) {
61083      //                         result = Math.min(b0.length, b1.length) - Math.min(a0.length, a1.length);
61084      //                     }
61085      //                     return d * result;
61086      //                 }
61087      //             });
61088      //         });
61089      //     }
61090      //
61091      //
61092      //     return menuItems;
61093      //
61094      // };
61095
61096
61097      menuItemList() {
61098        const menuItems = []; // color-by INFO attribute
61099
61100        if (this.header.INFO) {
61101          //Code below will present checkboxes for all info fields of type "String".   Wait until this is requested
61102          //const stringInfoKeys = Object.keys(this.header.INFO).filter(key => "String" === this.header.INFO[key].Type);
61103          // For now stick to explicit info fields (well, exactly 1 for starters)
61104          if (this.header.INFO) {
61105            //const stringInfoKeys = Object.keys(this.header.INFO).filter(key => this.header.INFO[key].Type === "String")
61106            const stringInfoKeys = this.header.INFO.SVTYPE ? ['SVTYPE'] : [];
61107
61108            if (this._initColorBy && this._initColorBy !== 'SVTYPE') {
61109              stringInfoKeys.push(this._initColorBy);
61110            }
61111
61112            if (stringInfoKeys.length > 0) {
61113              menuItems.push('<hr/>');
61114              const $e = $$1('<div class="igv-track-menu-category igv-track-menu-border-top">');
61115              $e.text('Color by:');
61116              menuItems.push({
61117                name: undefined,
61118                object: $e,
61119                click: undefined,
61120                init: undefined
61121              });
61122              stringInfoKeys.sort();
61123
61124              for (let item of stringInfoKeys) {
61125                const selected = this.colorBy === item;
61126                const label = item ? item : 'None';
61127                menuItems.push(this.colorByCB({
61128                  key: item,
61129                  label: label
61130                }, selected));
61131              }
61132
61133              menuItems.push(this.colorByCB({
61134                key: undefined,
61135                label: 'None'
61136              }, this.colorBy === undefined));
61137              menuItems.push('<hr/>');
61138            }
61139          }
61140        }
61141
61142        if (this.getCallsetsLength() > 0) {
61143          menuItems.push({
61144            object: $$1('<div class="igv-track-menu-border-top">')
61145          });
61146          menuItems.push({
61147            object: $$1(createCheckbox$1("Show Genotypes", this.showGenotypes)),
61148            click: () => {
61149              this.showGenotypes = !this.showGenotypes; //adjustTrackHeight();
61150
61151              this.trackView.checkContentHeight();
61152              this.trackView.repaintViews();
61153            }
61154          });
61155        }
61156
61157        menuItems.push({
61158          object: $$1('<div class="igv-track-menu-border-top">')
61159        });
61160
61161        for (let displayMode of ["COLLAPSED", "SQUISHED", "EXPANDED"]) {
61162          var lut = {
61163            "COLLAPSED": "Collapse",
61164            "SQUISHED": "Squish",
61165            "EXPANDED": "Expand"
61166          };
61167          menuItems.push({
61168            object: $$1(createCheckbox$1(lut[displayMode], displayMode === this.displayMode)),
61169            click: () => {
61170              this.displayMode = displayMode;
61171              this.trackView.checkContentHeight();
61172              this.trackView.repaintViews();
61173            }
61174          });
61175        } // Experimental JBrowse circular view integration
61176
61177
61178        if (this.browser.circularView && true === this.browser.circularViewVisible) {
61179          menuItems.push('<hr>');
61180          menuItems.push({
61181            label: 'Add SVs to circular view',
61182            click: () => {
61183              const inView = [];
61184
61185              for (let viewport of this.trackView.viewports) {
61186                const refFrame = viewport.referenceFrame;
61187
61188                for (let f of viewport.getCachedFeatures()) {
61189                  if (f.end >= refFrame.start && f.start <= refFrame.end) {
61190                    inView.push(f);
61191                  }
61192                }
61193              }
61194
61195              const chords = makeVCFChords(inView);
61196              const color = IGVColor.addAlpha(this._color || this.defaultColor, 0.5);
61197              this.browser.circularView.addChords(chords, {
61198                track: this.name,
61199                color: color
61200              });
61201            }
61202          });
61203        }
61204
61205        return menuItems;
61206      }
61207
61208      contextMenuItemList(clickState) {
61209        // Experimental JBrowse circular view integration
61210        if (this.browser.circularView && true === this.browser.circularViewVisible) {
61211          const viewport = clickState.viewport;
61212          const list = [];
61213          list.push({
61214            label: 'Add SVs to Circular View',
61215            click: () => {
61216              const refFrame = viewport.referenceFrame;
61217              const inView = "all" === refFrame.chr ? this.featureSource.getAllFeatures() : this.featureSource.featureCache.queryFeatures(refFrame.chr, refFrame.start, refFrame.end);
61218              const chords = makeVCFChords(inView);
61219              const color = IGVColor.addAlpha(this._color || this.defaultColor, 0.5);
61220              this.browser.circularView.addChords(chords, {
61221                track: this.name,
61222                color: color
61223              });
61224            }
61225          });
61226          list.push('<hr/>');
61227          return list;
61228        }
61229      }
61230      /**
61231       * Create a "color by" checkbox menu item, optionally initially checked
61232       * @param menuItem
61233       * @param showCheck
61234       * @returns {{init: undefined, name: undefined, click: clickHandler, object: (jQuery|HTMLElement|jQuery.fn.init)}}
61235       */
61236
61237
61238      colorByCB(menuItem, showCheck) {
61239        const $e = $$1(createCheckbox$1(menuItem.label, showCheck));
61240
61241        const clickHandler = () => {
61242          if (menuItem.key === this.colorBy) {
61243            this.colorBy = undefined;
61244            delete this.config.colorBy;
61245            this.trackView.repaintViews();
61246          } else {
61247            this.colorBy = menuItem.key;
61248            this.config.colorBy = menuItem.key;
61249            this.trackView.repaintViews();
61250          }
61251        };
61252
61253        return {
61254          name: undefined,
61255          object: $e,
61256          click: clickHandler,
61257          init: undefined
61258        };
61259      }
61260
61261      getState() {
61262        const config = super.getState();
61263
61264        if (this._color && typeof this._color !== "function") {
61265          config.color = this._color;
61266        }
61267
61268        return config;
61269      }
61270
61271      getVariantColorTable(key) {
61272        if (!this.colorTables) {
61273          this.colorTables = new Map();
61274        }
61275
61276        if (!this.colorTables.has(key)) {
61277          let tbl;
61278
61279          switch (key) {
61280            case "SVTYPE":
61281              tbl = SV_COLOR_TABLE;
61282              break;
61283
61284            default:
61285              tbl = new PaletteColorTable("Set1");
61286          }
61287
61288          this.colorTables.set(key, tbl);
61289        }
61290
61291        return this.colorTables.get(key);
61292      }
61293
61294    }
61295
61296    function expandGenotype(call, variant) {
61297      if (call.genotype) {
61298        let gt = '';
61299
61300        if (variant.alternateBases === ".") {
61301          gt = "No Call";
61302        } else {
61303          const altArray = variant.alternateBases.split(",");
61304
61305          for (let allele of call.genotype) {
61306            if (gt.length > 0) {
61307              gt += "|";
61308            }
61309
61310            if ('.' === allele) {
61311              gt += '.';
61312            } else if (allele === 0) {
61313              gt += variant.referenceBases;
61314            } else {
61315              let alt = altArray[allele - 1].replace("<", "&lt;");
61316              gt += alt;
61317            }
61318          }
61319        }
61320
61321        call.genotypeName = gt;
61322      }
61323    }
61324
61325    const SV_COLOR_TABLE = new ColorTable({
61326      'DEL': '#ff2101',
61327      'INS': '#001888',
61328      'DUP': '#028401',
61329      'INV': '#008688',
61330      'CNV': '#8931ff',
61331      'BND': '#891100',
61332      '*': '#002eff'
61333    });
61334
61335    /*
61336     * The MIT License (MIT)
61337     *
61338     * Copyright (c) 2014 Broad Institute
61339     *
61340     * Permission is hereby granted, free of charge, to any person obtaining a copy
61341     * of this software and associated documentation files (the "Software"), to deal
61342     * in the Software without restriction, including without limitation the rights
61343     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
61344     * copies of the Software, and to permit persons to whom the Software is
61345     * furnished to do so, subject to the following conditions:
61346     *
61347     * The above copyright notice and this permission notice shall be included in
61348     * all copies or substantial portions of the Software.
61349     *
61350     *
61351     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
61352     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
61353     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
61354     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
61355     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
61356     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
61357     * THE SOFTWARE.
61358     */
61359
61360    class EqtlTrack extends TrackBase {
61361      constructor(config, browser) {
61362        super(config, browser);
61363      }
61364
61365      init(config) {
61366        super.init(config);
61367        this.name = config.name;
61368        this.pValueField = config.pValueField || "pValue";
61369        this.geneField = config.geneField || "geneSymbol";
61370        this.snpField = config.snpField || "snp";
61371        const min = config.minLogP || config.min;
61372        const max = config.maxLogP || config.max;
61373        this.dataRange = {
61374          min: min || 3.5,
61375          max: max || 25
61376        };
61377
61378        if (!max) {
61379          this.autoscale = true;
61380        } else {
61381          this.autoscale = config.autoscale;
61382        }
61383
61384        this.autoscalePercentile = config.autoscalePercentile === undefined ? 98 : config.autoscalePercentile;
61385        this.background = config.background; // No default
61386
61387        this.divider = config.divider || "rgb(225,225,225)";
61388        this.dotSize = config.dotSize || 2;
61389        this.height = config.height || 100;
61390        this.autoHeight = false;
61391        this.disableButtons = config.disableButtons; // Limit visibility window to 2 mb,  gtex server gets flaky beyond that
61392
61393        this.visibilityWindow = config.visibilityWindow === undefined ? 2000000 : config.visibilityWindow >= 0 ? Math.min(2000000, config.visibilityWindow) : 2000000;
61394        this.featureSource = FeatureSource(config, this.browser.genome);
61395        GtexUtils.gtexLoaded = true;
61396      }
61397
61398      paintAxis(ctx, pixelWidth, pixelHeight) {
61399        const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight;
61400        const font = {
61401          'font': 'normal 10px Arial',
61402          'textAlign': 'right',
61403          'strokeStyle': "black"
61404        };
61405        IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {
61406          'fillStyle': "rgb(255, 255, 255)"
61407        }); // Determine a tick spacing such that there is at least 10 pixels between ticks
61408
61409        const n = Math.ceil((this.dataRange.max - this.dataRange.min) * 10 / pixelHeight);
61410
61411        for (let p = 4; p <= this.dataRange.max; p += n) {
61412          // TODO: Dashes may not actually line up with correct scale. Ask Jim about this
61413          const ref = 0.85 * pixelWidth;
61414          const x1 = ref - 5;
61415          const x2 = ref;
61416          const y = pixelHeight - (p - this.dataRange.min) / yScale;
61417          IGVGraphics.strokeLine(ctx, x1, y, x2, y, font); // Offset dashes up by 2 pixel
61418
61419          if (y > 8) {
61420            IGVGraphics.fillText(ctx, p, x1 - 1, y + 2, font);
61421          } // Offset numbers down by 2 pixels;
61422
61423        }
61424
61425        font['textAlign'] = 'center';
61426        IGVGraphics.fillText(ctx, "-log10(pvalue)", pixelWidth / 4, pixelHeight / 2, font, {
61427          rotate: {
61428            angle: -90
61429          }
61430        });
61431      }
61432
61433      async getFeatures(chr, start, end) {
61434        const pValueField = this.pValueField;
61435        const visibilityWindow = this.visibilityWindow;
61436        const features = await this.featureSource.getFeatures({
61437          chr,
61438          start,
61439          end,
61440          visibilityWindow
61441        });
61442        features.forEach(function (f) {
61443          f.value = f[pValueField];
61444        });
61445        return features;
61446      }
61447
61448      draw(options) {
61449        const ctx = options.context;
61450        const pixelWidth = options.pixelWidth;
61451        const pixelHeight = options.pixelHeight;
61452
61453        if (this.background) {
61454          IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {
61455            'fillStyle': this.background
61456          });
61457        }
61458
61459        IGVGraphics.strokeLine(ctx, 0, pixelHeight - 1, pixelWidth, pixelHeight - 1, {
61460          'strokeStyle': this.divider
61461        });
61462
61463        const drawEqtls = drawSelected => {
61464          const radius = drawSelected ? 2 * this.dotSize : this.dotSize;
61465          const bpStart = options.bpStart;
61466          const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight;
61467          const selection = options.referenceFrame.selection;
61468
61469          for (let eqtl of options.features) {
61470            const px = (eqtl.start - bpStart + 0.5) / options.bpPerPixel;
61471            if (px < 0) continue;else if (px > pixelWidth) break;
61472            const snp = eqtl.snp.toUpperCase();
61473            const geneName = eqtl[this.geneField].toUpperCase();
61474            const isSelected = selection && (selection.snp === snp || selection.gene === geneName);
61475
61476            if (!drawSelected || isSelected) {
61477              // Add eqtl's gene to the selection if this is the selected snp.
61478              // TODO -- this should not be done here in the rendering code.
61479              if (selection && selection.snp === snp) {
61480                selection.addGene(geneName);
61481              }
61482
61483              var mLogP = -Math.log(eqtl[this.pValueField]) / Math.LN10;
61484
61485              if (mLogP >= this.dataRange.min) {
61486                let capped;
61487
61488                if (mLogP > this.dataRange.max) {
61489                  mLogP = this.dataRange.max;
61490                  capped = true;
61491                } else {
61492                  capped = false;
61493                }
61494
61495                const py = Math.max(0 + radius, pixelHeight - Math.round((mLogP - this.dataRange.min) / yScale));
61496                eqtl.px = px;
61497                eqtl.py = py;
61498                eqtl.radius = radius;
61499                let color;
61500
61501                if (drawSelected && selection) {
61502                  color = selection.colorForGene(geneName);
61503                  IGVGraphics.setProperties(ctx, {
61504                    fillStyle: color,
61505                    strokeStyle: "black"
61506                  });
61507                } else {
61508                  color = capped ? "rgb(150, 150, 150)" : "rgb(180, 180, 180)";
61509                  IGVGraphics.setProperties(ctx, {
61510                    fillStyle: color,
61511                    strokeStyle: color
61512                  });
61513                }
61514
61515                IGVGraphics.fillCircle(ctx, px, py, radius);
61516                IGVGraphics.strokeCircle(ctx, px, py, radius);
61517              }
61518            }
61519          }
61520        }; // Draw in two passes, with "selected" eqtls drawn last
61521
61522
61523        drawEqtls(false);
61524        drawEqtls(true);
61525      }
61526      /**
61527       * Return "popup data" for feature @ genomic location.  Data is an array of key-value pairs
61528       */
61529
61530
61531      popupData(clickState) {
61532        let features = clickState.viewport.getCachedFeatures();
61533        if (!features || features.length === 0) return [];
61534        const tolerance = 3;
61535        const tissue = this.name;
61536        const popupData = [];
61537
61538        for (let feature of features) {
61539          // Hit test --use square vs circle for efficiency (no sqrt)
61540          if (Math.abs(feature.px - clickState.canvasX) < feature.radius + tolerance && Math.abs(feature.py - clickState.canvasY) < feature.radius + tolerance) {
61541            if (popupData.length > 0) {
61542              popupData.push('<hr/>');
61543            }
61544
61545            popupData.push({
61546              name: "snp id",
61547              value: feature.snp
61548            }, {
61549              name: "gene id",
61550              value: feature.geneId
61551            }, {
61552              name: "gene name",
61553              value: feature.geneName
61554            }, {
61555              name: "p value",
61556              value: feature.pValue
61557            }, {
61558              name: "tissue",
61559              value: tissue
61560            });
61561          }
61562        }
61563
61564        return popupData;
61565      }
61566
61567      menuItemList() {
61568        return MenuUtils.numericDataMenuItems(this.trackView);
61569      }
61570
61571      doAutoscale(featureList) {
61572        if (featureList.length > 0) {
61573          var values = featureList.map(function (eqtl) {
61574            return -Math.log(eqtl.value) / Math.LN10;
61575          });
61576          this.dataRange.max = IGVMath.percentile(values, this.autoscalePercentile);
61577        } else {
61578          // No features -- default
61579          const max = this.config.maxLogP || this.config.max;
61580          this.dataRange.max = max || 25;
61581        }
61582
61583        return this.dataRange;
61584      }
61585
61586    }
61587
61588    /**
61589     * Colors used for coding omosomes
61590     */
61591    const Colors = {
61592      "X": "rgb(204, 153, 0)",
61593      "Y": "rgb(153, 204, 0)",
61594      "Un": "darkGray)",
61595      "1": "rgb(80, 80, 255)",
61596      //"1": Color.red);
61597      "I": "rgb(139, 155, 187)",
61598      "2": "rgb(206, 61, 50)",
61599      "II": "rgb(206, 61, 50)",
61600      "2a": "rgb(210, 65, 55)",
61601      "2b": "rgb(215, 70, 60)",
61602      "3": "rgb(116, 155, 88)",
61603      "III": "rgb(116, 155, 88)",
61604      "4": "rgb(240, 230, 133)",
61605      "IV": "rgb(240, 230, 133)",
61606      "5": "rgb(70, 105, 131)",
61607      "6": "rgb(186, 99, 56)",
61608      "7": "rgb(93, 177, 221)",
61609      "8": "rgb(128, 34, 104)",
61610      "9": "rgb(107, 215, 107)",
61611      "10": "rgb(213, 149, 167)",
61612      "11": "rgb(146, 72, 34)",
61613      "12": "rgb(131, 123, 141)",
61614      "13": "rgb(199, 81, 39)",
61615      "14": "rgb(213, 143, 92)",
61616      "15": "rgb(122, 101, 165)",
61617      "16": "rgb(228, 175, 105)",
61618      "17": "rgb(59, 27, 83)",
61619      "18": "rgb(205, 222, 183)",
61620      "19": "rgb(97, 42, 121)",
61621      "20": "rgb(174, 31, 99)",
61622      "21": "rgb(231, 199, 111)",
61623      "22": "rgb(90, 101, 94)",
61624      "23": "rgb(204, 153, 0)",
61625      "24": "rgb(153, 204, 0)",
61626      "25": "rgb(51, 204, 0)",
61627      "26": "rgb(0, 204, 51)",
61628      "27": "rgb(0, 204, 153)",
61629      "28": "rgb(0, 153, 204)",
61630      "29": "rgb(10, 71, 255)",
61631      "30": "rgb(71, 117, 255)",
61632      "31": "rgb(255, 194, 10)",
61633      "32": "rgb(255, 209, 71)",
61634      "33": "rgb(153, 0, 51)",
61635      "34": "rgb(153, 26, 0)",
61636      "35": "rgb(153, 102, 0)",
61637      "36": "rgb(128, 153, 0)",
61638      "37": "rgb(51, 153, 0)",
61639      "38": "rgb(0, 153, 26)",
61640      "39": "rgb(0, 153, 102)",
61641      "40": "rgb(0, 128, 153)",
61642      "41": "rgb(0, 51, 153)",
61643      "42": "rgb(26, 0, 153)",
61644      "43": "rgb(102, 0, 153)",
61645      "44": "rgb(153, 0, 128)",
61646      "45": "rgb(214, 0, 71)",
61647      "46": "rgb(255, 20, 99)",
61648      "47": "rgb(0, 214, 143)",
61649      "48": "rgb(20, 255, 177)"
61650    }; //  aliasing
61651
61652    for (let key of Object.keys(Colors)) {
61653      const altName = "chr" + key;
61654      Colors[altName] = Colors[key];
61655    }
61656
61657    /*
61658     * The MIT License (MIT)
61659     *
61660     * Copyright (c) 2014 Broad Institute
61661     *
61662     * Permission is hereby granted, free of charge, to any person obtaining a copy
61663     * of this software and associated documentation files (the "Software"), to deal
61664     * in the Software without restriction, including without limitation the rights
61665     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
61666     * copies of the Software, and to permit persons to whom the Software is
61667     * furnished to do so, subject to the following conditions:
61668     *
61669     * The above copyright notice and this permission notice shall be included in
61670     * all copies or substantial portions of the Software.
61671     *
61672     *
61673     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
61674     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
61675     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
61676     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
61677     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
61678     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
61679     * THE SOFTWARE.
61680     */
61681    const DEFAULT_POPOVER_WINDOW = 100000000; //const type = "gwas";
61682
61683    class GWASTrack extends TrackBase {
61684      constructor(config, browser) {
61685        super(config, browser);
61686      }
61687
61688      init(config) {
61689        super.init(config);
61690        this.useChrColors = config.useChrColors === undefined ? true : config.useChrColors;
61691        this.trait = config.trait;
61692        this.posteriorProbability = config.posteriorProbability;
61693        this.valueProperty = "bed" === config.format ? "score" : "value";
61694        this.height = config.height || 100; // The preferred height
61695
61696        this.autoscale = config.autoscale;
61697        this.autoscalePercentile = config.autoscalePercentile === undefined ? 98 : config.autoscalePercentile;
61698        this.background = config.background; // No default
61699
61700        this.divider = config.divider || "rgb(225,225,225)";
61701        this.dotSize = config.dotSize || 3;
61702        this.popoverWindow = config.popoverWindow === undefined ? DEFAULT_POPOVER_WINDOW : config.popoverWindow;
61703        this.description = config.description; // might be null
61704
61705        this.colorScales = config.color ? new ConstantColorScale(config.color) : {
61706          "*": new BinnedColorScale(config.colorScale || {
61707            thresholds: [5e-8, 5e-4, 0.5],
61708            colors: ["rgb(255,50,50)", "rgb(251,100,100)", "rgb(251,170,170)", "rgb(227,238,249)"]
61709          })
61710        };
61711        this.featureSource = FeatureSource(config, this.browser.genome);
61712      }
61713
61714      async postInit() {
61715        if (typeof this.featureSource.getHeader === "function") {
61716          this.header = await this.featureSource.getHeader();
61717        } // Set properties from track line
61718
61719
61720        if (this.header) {
61721          this.setTrackProperties(this.header); // setTrackProperties defined in TrackBase
61722        } // Set initial range if specfied, unless autoscale == true
61723
61724
61725        if (!this.autoscale) {
61726          if (this.posteriorProbability) {
61727            this.dataRange = {
61728              min: this.config.min === undefined ? 0 : this.config.min,
61729              max: this.config.max === undefined ? 1 : this.config.max
61730            };
61731          } else {
61732            this.dataRange = {
61733              min: this.config.min === undefined ? 0 : this.config.min,
61734              max: this.config.max === undefined ? 25 : this.config.max
61735            };
61736          }
61737        }
61738
61739        return this;
61740      }
61741
61742      supportsWholeGenome() {
61743        return true;
61744      }
61745
61746      async getFeatures(chr, start, end) {
61747        const visibilityWindow = this.visibilityWindow;
61748        return this.featureSource.getFeatures({
61749          chr,
61750          start,
61751          end,
61752          visibilityWindow
61753        });
61754      }
61755
61756      draw(options) {
61757        const featureList = options.features;
61758        const ctx = options.context;
61759        const pixelWidth = options.pixelWidth;
61760        const pixelHeight = options.pixelHeight;
61761
61762        if (this.background) {
61763          IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {
61764            'fillStyle': this.background
61765          });
61766        }
61767
61768        IGVGraphics.strokeLine(ctx, 0, pixelHeight - 1, pixelWidth, pixelHeight - 1, {
61769          'strokeStyle': this.divider
61770        });
61771
61772        if (featureList) {
61773          const bpPerPixel = options.bpPerPixel;
61774          const bpStart = options.bpStart;
61775          const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;
61776
61777          for (let variant of featureList) {
61778            const pos = variant.start;
61779            if (pos < bpStart) continue;
61780            if (pos > bpEnd) break;
61781            const colorScale = this.getColorScale(variant._f ? variant._f.chr : variant.chr);
61782            let color;
61783            let val;
61784
61785            if (this.posteriorProbability) {
61786              val = variant[this.valueProperty];
61787              color = colorScale.getColor(val);
61788            } else {
61789              const pvalue = variant[this.valueProperty];
61790              if (!pvalue) continue;
61791              val = -Math.log10(pvalue);
61792              color = colorScale.getColor(val);
61793            }
61794
61795            const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight;
61796            const px = Math.round((pos - bpStart) / bpPerPixel);
61797            const py = Math.max(this.dotSize, pixelHeight - Math.round((val - this.dataRange.min) / yScale));
61798
61799            if (color) {
61800              IGVGraphics.setProperties(ctx, {
61801                fillStyle: color,
61802                strokeStyle: "black"
61803              });
61804            }
61805
61806            IGVGraphics.fillCircle(ctx, px, py, this.dotSize);
61807            variant.px = px;
61808            variant.py = py;
61809          }
61810        }
61811      }
61812
61813      getColorScale(chr) {
61814        if (this.useChrColors) {
61815          let cs = this.colorScales[chr];
61816
61817          if (!cs) {
61818            const color = Colors[chr] || randomColor();
61819            cs = new ConstantColorScale(color);
61820            this.colorScales[chr] = cs;
61821          }
61822
61823          return cs;
61824        } else {
61825          return this.colorScales("*");
61826        }
61827      }
61828
61829      paintAxis(ctx, pixelWidth, pixelHeight) {
61830        IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {
61831          'fillStyle': "rgb(255, 255, 255)"
61832        });
61833        var font = {
61834          'font': 'normal 10px Arial',
61835          'textAlign': 'right',
61836          'strokeStyle': "black"
61837        };
61838        const yScale = (this.dataRange.max - this.dataRange.min) / pixelHeight;
61839
61840        if (this.posteriorProbability) {
61841          const n = 0.1;
61842
61843          for (let p = this.dataRange.min; p < this.dataRange.max; p += n) {
61844            const yp = pixelHeight - Math.round((p - this.dataRange.min) / yScale);
61845            IGVGraphics.strokeLine(ctx, 45, yp - 2, 50, yp - 2, font); // Offset dashes up by 2 pixel
61846
61847            IGVGraphics.fillText(ctx, p.toFixed(1), 44, yp + 2, font); // Offset numbers down by 2 pixels;
61848          }
61849        } else {
61850          const n = Math.ceil((this.dataRange.max - this.dataRange.min) * 10 / pixelHeight);
61851
61852          for (let p = this.dataRange.min; p < this.dataRange.max; p += n) {
61853            const yp = pixelHeight - Math.round((p - this.dataRange.min) / yScale);
61854            IGVGraphics.strokeLine(ctx, 45, yp, 50, yp, font); // Offset dashes up by 2 pixel
61855
61856            IGVGraphics.fillText(ctx, Math.floor(p), 44, yp + 4, font); // Offset numbers down by 2 pixels;
61857          }
61858        }
61859
61860        font['textAlign'] = 'center';
61861
61862        if (this.posteriorProbability) {
61863          IGVGraphics.fillText(ctx, "PPA", pixelWidth / 2, pixelHeight / 2, font, {
61864            rotate: {
61865              angle: -90
61866            }
61867          });
61868        } else {
61869          IGVGraphics.fillText(ctx, "-log10(pvalue)", pixelWidth / 2, pixelHeight / 2, font, {
61870            rotate: {
61871              angle: -90
61872            }
61873          });
61874        }
61875      }
61876
61877      popupData(clickState) {
61878        let data = [];
61879        const track = clickState.viewport.trackView.track;
61880        const features = clickState.viewport.getCachedFeatures();
61881
61882        if (features) {
61883          let count = 0;
61884
61885          for (let f of features) {
61886            const xDelta = Math.abs(clickState.canvasX - f.px);
61887            const yDelta = Math.abs(clickState.canvasY - f.py);
61888            const value = f[this.valueProperty];
61889
61890            if (xDelta < this.dotSize && yDelta < this.dotSize) {
61891              if (count > 0) {
61892                data.push("<HR/>");
61893              }
61894
61895              if (count == 5) {
61896                data.push("...");
61897                break;
61898              }
61899
61900              if (typeof f.popupData === 'function') {
61901                data = data.concat(f.popupData());
61902              } else {
61903                const chr = f.realChr || f.chr;
61904                const pos = (f.realStart || f.start) + 1;
61905                data.push({
61906                  name: 'chromosome',
61907                  value: chr
61908                });
61909                data.push({
61910                  name: 'position',
61911                  value: pos
61912                });
61913                data.push({
61914                  name: 'name',
61915                  value: f.name
61916                });
61917
61918                if (track.posteriorProbability) {
61919                  data.push({
61920                    name: 'posterior probability',
61921                    value: value
61922                  });
61923                } else {
61924                  data.push({
61925                    name: 'pValue',
61926                    value: value
61927                  });
61928                }
61929              }
61930
61931              count++;
61932            }
61933          }
61934        }
61935
61936        return data;
61937      }
61938
61939      menuItemList() {
61940        return MenuUtils.numericDataMenuItems(this.trackView);
61941      }
61942
61943      doAutoscale(featureList) {
61944        if (featureList.length > 0) {
61945          // posterior probabilities are treated without modification, but we need to take a negative logarithm of P values
61946          const valueProperty = this.valueProperty;
61947          const posterior = this.posteriorProbability;
61948          const features = featureList.map(function (feature) {
61949            const v = feature[valueProperty];
61950            return {
61951              value: posterior ? v : -Math.log(v) / Math.LN10
61952            };
61953          });
61954          this.dataRange = doAutoscale(features);
61955        } else {
61956          // No features -- pick something reasonable for PPAs and p-values
61957          if (this.posteriorProbability) {
61958            this.dataRange.min = this.config.min || 0;
61959            this.dataRange.max = this.config.max || 1;
61960          } else {
61961            this.dataRange.max = this.config.max || 25;
61962            this.dataRange.min = this.config.min || 0;
61963          }
61964        }
61965
61966        return this.dataRange;
61967      }
61968
61969    }
61970
61971    const X_PIXEL_DIFF_THRESHOLD = 1;
61972
61973    class GCNVTrack extends TrackBase {
61974      constructor(config, browser) {
61975        super(config, browser);
61976      }
61977
61978      init(config) {
61979        super.init(config);
61980        this.autoscale = config.autoscale || config.max === undefined;
61981        this.dataRange = {
61982          min: config.min || 0,
61983          max: config.max
61984        };
61985        this.windowFunction = config.windowFunction || "mean";
61986        this.paintAxis = paintAxis;
61987        this.graphType = config.graphType || "bar"; //hack to avoid creating feature source multiple times.  If config.type is not set the file must be read
61988        //to determine type, which results in creation of a feature source.
61989
61990        if (config._featureSource) {
61991          this.featureSource = config._featureSource;
61992          delete config._featureSource;
61993        } else {
61994          this.featureSource = FeatureSource(this.config, this.browser.genome);
61995        } // Visibility window hardcoded to -1  (== whole chromosome).  Draw method needs feature beyond current view,
61996        // when/if this is resolved visibilityWindow can be used.
61997
61998
61999        this.visibilityWindow = -1;
62000        this.featureSource.visibilityWindow = this.visibilityWindow;
62001      }
62002
62003      async postInit() {
62004        if (typeof this.featureSource.getHeader === "function") {
62005          this.header = await this.featureSource.getHeader();
62006          this.sampleNames = this.header.columnNames.slice(3); // Set generic properties from track line
62007
62008          this.setTrackProperties(this.header); // setTrackProperties defined in TrackBase
62009          // set option to highlight sample track line on click
62010
62011          if (this.header.hasOwnProperty("clickToHighlight")) {
62012            let colour = this.header["clickToHighlight"];
62013            this.config.clickToHighlight = colour;
62014            this.config.samplesClickedToHighlight = {};
62015          } // Special track line properties
62016
62017
62018          if (this.header.hasOwnProperty("highlight")) {
62019            this.config.highlightSamples = {};
62020            let v = this.header["highlight"];
62021            if (!Array.isArray(v)) v = [v];
62022
62023            for (let h of v) {
62024              const tokens = h.split(";");
62025
62026              if (tokens.length === 2) {
62027                this.config.highlightSamples[tokens[0]] = tokens[1];
62028              }
62029            }
62030          }
62031        }
62032      }
62033
62034      menuItemList() {
62035        return MenuUtils.numericDataMenuItems(this.trackView);
62036      }
62037
62038      async getFeatures(chr, start, end) {
62039        const chrFeatures = await this.featureSource.getFeatures({
62040          chr,
62041          start: 0,
62042          end: Number.MAX_SAFE_INTEGER,
62043          visibilityWindow: this.visibilityWindow
62044        });
62045        let prevIndex = undefined;
62046        let nextIndex = undefined;
62047
62048        for (let i = 1; i < chrFeatures.length - 1; i++) {
62049          if (prevIndex === undefined && chrFeatures[i].end > start) {
62050            prevIndex = i - 1;
62051          }
62052
62053          if (nextIndex === undefined && chrFeatures[i].start > end) {
62054            nextIndex = i + 1;
62055            break;
62056          }
62057        }
62058
62059        if (prevIndex === undefined) prevIndex = 0;
62060        if (nextIndex === undefined) nextIndex = chrFeatures.length;
62061        return chrFeatures.slice(prevIndex, nextIndex);
62062      }
62063
62064      draw(options) {
62065        const {
62066          features,
62067          context,
62068          bpPerPixel,
62069          bpStart,
62070          pixelWidth,
62071          pixelHeight
62072        } = options; ///let baselineColor;
62073        //if (typeof self.color === "string" && self.color.startsWith("rgb(")) {
62074        //    baselineColor = IGVColor.addAlpha(self.color, 0.1);
62075        //}
62076
62077        const yScale = yValue => {
62078          return (this.dataRange.max - yValue) / (this.dataRange.max - this.dataRange.min) * pixelHeight;
62079        };
62080
62081        const getX = function (bpPosition) {
62082          let x = Math.floor((bpPosition - bpStart) / bpPerPixel);
62083          if (isNaN(x)) console.warn('isNaN(x). feature start ' + numberFormatter$1(bpPosition) + ' bp start ' + numberFormatter$1(bpStart));
62084          return x;
62085        };
62086
62087        const drawGuideLines = options => {
62088          if (this.config.hasOwnProperty('guideLines')) {
62089            for (let line of this.config.guideLines) {
62090              if (line.hasOwnProperty('color') && line.hasOwnProperty('y') && line.hasOwnProperty('dotted')) {
62091                let y = yScale(line.y);
62092                let props = {
62093                  'strokeStyle': line['color'],
62094                  'strokeWidth': 2
62095                };
62096                if (line['dotted']) IGVGraphics.dashedLine(options.context, 0, y, options.pixelWidth, y, 5, props);else IGVGraphics.strokeLine(options.context, 0, y, options.pixelWidth, y, props);
62097              }
62098            }
62099          }
62100        };
62101
62102        if (features && features.length > 0) {
62103          if (this.dataRange.min === undefined) this.dataRange.min = 0;
62103 // Max can be less than min if config.min is set but max left to autoscale. If that's the case there is
62104          // nothing to paint.
62105
62106          if (this.dataRange.max > this.dataRange.min) {
62107            const highlightSamples = this.config.highlightSamples;
62108            const onlyHandleClicksForHighlightedSamples = this.config.onlyHandleClicksForHighlightedSamples;
62109            const clickToHighlight = this.config.clickToHighlight;
62110            let previousEnd = -1;
62111            let previousValues = {};
62112            let highlightConnectorLines = [];
62113            let highlightFeatureLines = []; // clickDetectorCache allows fast retrieval of whether a mouse click hits a rendered line segment
62114            // by storing lists of rendered line segments, keyed by their right x coordinate in canvas pixel space.
62115            // this cache is regenerated on every draw.
62116
62117            this.clickDetectorCache = {};
62118
62119            for (let feature of features) {
62120              const x1 = getX(feature.start);
62121              const x2 = getX(feature.end);
62122              const previousX = previousEnd >= 0 ? getX(previousEnd) : x1;
62123              if (isNaN(x1) || isNaN(x2)) continue; // if ((x1 - previousX < X_PIXEL_DIFF_THRESHOLD) && (x2 - x1 < X_PIXEL_DIFF_THRESHOLD)) continue;
62124
62125              this.clickDetectorCache[x1] = [];
62126              this.clickDetectorCache[x2] = [];
62127
62128              for (let i = 0; i < feature.values.length; i++) {
62129                const sampleName = this.sampleNames[i];
62130                const value = feature.values[i];
62131                const y = yScale(value);
62132
62133                if (x1 - previousX >= X_PIXEL_DIFF_THRESHOLD) {
62134                  const previousValue = previousValues[sampleName];
62135                  const previousY = yScale(previousValue);
62136                  const highlightColor = highlightSamples && highlightSamples[sampleName];
62137
62138                  if (highlightColor) {
62139                    highlightConnectorLines.push([previousX, previousY, x1, y, highlightColor]);
62140                  } else if (clickToHighlight && sampleName in this.config.samplesClickedToHighlight) {
62141                    highlightConnectorLines.push([previousX, previousY, x1, y, this.config.samplesClickedToHighlight[sampleName]]);
62142                  } else {
62143                    IGVGraphics.strokeLine(context, previousX, previousY, x1, y, {
62144                      strokeStyle: '#D9D9D9'
62145                    });
62146                  }
62147
62148                  if (!onlyHandleClicksForHighlightedSamples || sampleName in highlightSamples) {
62149                    this.clickDetectorCache[x1].push([previousX, previousY, x1, y, sampleName, highlightColor || 'gray']);
62150                  }
62151                }
62152
62153                if (x2 - x1 >= X_PIXEL_DIFF_THRESHOLD) {
62154                  const highlightColor = highlightSamples && highlightSamples[sampleName];
62155
62156                  if (highlightColor) {
62157                    highlightFeatureLines.push([x1, y, x2, y, highlightColor]);
62158                  } else if (clickToHighlight && sampleName in this.config.samplesClickedToHighlight) {
62159                    highlightFeatureLines.push([x1, y, x2, y, this.config.samplesClickedToHighlight[sampleName]]);
62160                  } else {
62161                    IGVGraphics.strokeLine(context, x1, y, x2, y, {
62162                      strokeStyle: 'gray'
62163                    });
62164                  }
62165
62166                  if (!onlyHandleClicksForHighlightedSamples || sampleName in highlightSamples) {
62167                    this.clickDetectorCache[x2].push([x1, y, x2, y, sampleName, highlightColor || 'gray']);
62168                  }
62169                }
62170
62171                previousValues[sampleName] = value; //IGVGraphics.fillCircle(ctx, px, y, pointSize / 2, {"fillStyle": color, "strokeStyle": color});
62172                //IGVGraphics.fillRect(ctx, x, y, width, height, {fillStyle: color});
62173              }
62174
62175              previousEnd = feature.end;
62176            }
62177
62178            for (let f of highlightConnectorLines) {
62179              IGVGraphics.strokeLine(context, f[0], f[1], f[2], f[3], {
62180                strokeStyle: f[4],
62181                lineWidth: 1.3
62182              });
62183            }
62184
62185            for (let f of highlightFeatureLines) {
62186              IGVGraphics.strokeLine(context, f[0], f[1], f[2], f[3], {
62187                strokeStyle: f[4],
62188                lineWidth: 2
62189              });
62190            }
62191            /*
62192            // If the track includes negative values draw a baseline
62193            if (this.dataRange.min < 0) {
62194                const basepx = (self.dataRange.max / (this.dataRange.max - this.dataRange.min)) * options.pixelHeight;
62195                IGVGraphics.strokeLine(context, 0, basepx, options.pixelWidth, basepx, {strokeStyle: baselineColor});
62196            }
62197            */
62198
62199          }
62200        }
62201
62202        drawGuideLines(options);
62203      }
62204
62205      doAutoscale(features) {
62206        let min, max;
62207
62208        if (features.length > 0) {
62209          min = Number.MAX_VALUE;
62210          max = -Number.MAX_VALUE;
62211          features.forEach(function (feature) {
62212            min = Math.min(min, ...feature.values);
62213            max = Math.max(max, ...feature.values);
62214          });
62215          min -= 0.01;
62216          max += 0.01;
62217        } else {
62218          // No features -- default
62219          min = 0;
62220          max = 100;
62221        }
62222
62223        return {
62224          min: min,
62225          max: max
62226        };
62227      }
62228
62229      clickedFeatures(clickState) {
62230        //console.warn('click', clickState.canvasX, clickState.canvasY, clickState)
62231        const BOUNDING_BOX_PADDING = 10;
62232        const MIN_DISTANCE_TO_SEGMENT = 5;
62233        const clickX = clickState.canvasX;
62234        const clickY = clickState.canvasY;
62235        let key = null;
62236
62237        for (key of Object.keys(this.clickDetectorCache)) {
62238          key = parseInt(key);
62239
62240          if (key >= clickX) {
62241            break;
62242          }
62243        }
62244
62245        if (key) {
62246          let closestDistanceSoFar = Number.MAX_VALUE;
62247          let closestResult = [];
62248          const segments = this.clickDetectorCache[key];
62249
62250          for (let segment of segments) {
62251            const x1 = segment[0];
62252            const x2 = segment[2];
62253            if (clickX < x1 || clickX > x2) return [];
62254            const y1 = segment[1];
62255            const y2 = segment[3];
62256            if (clickY < Math.min(y1, y2) - BOUNDING_BOX_PADDING || clickY > Math.max(y1, y2) + BOUNDING_BOX_PADDING) continue;
62257            const distance = distanceToLine(clickX, clickY, x1, y1, x2, y2);
62258
62259            if (distance < closestDistanceSoFar) {
62260              closestResult = [{
62261                'name': segment[4],
62262                'color': segment[5]
62263              }];
62264              closestDistanceSoFar = distance; //console.warn('closest:', 'name', segment[4], 'color', segment[5], distance);
62265            }
62266          }
62267
62268          if (closestDistanceSoFar < MIN_DISTANCE_TO_SEGMENT) {
62269            // clickToHighlight set, add sample to dict of clicked lines
62270            if (this.config.clickToHighlight) {
62271              if (closestResult[0]['name'] in this.config.samplesClickedToHighlight) {
62272                // clicked sample already highlighted => remove if clicked again
62273                delete this.config.samplesClickedToHighlight[closestResult[0]['name']];
62274              } else if (this.config.clickToHighlight === 'any') {
62275                var colourList = ['red', 'darkblue', 'green', 'teal', 'olivedrab', 'orange', 'maroon', 'purple', 'blue', 'gold'];
62276                var colour = colourList[Math.floor(Math.random() * (colourList.length + 1))];
62277                this.config.samplesClickedToHighlight[closestResult[0]['name']] = colour;
62278              } else {
62279                this.config.samplesClickedToHighlight[closestResult[0]['name']] = this.config.clickToHighlight;
62280              }
62281
62282              this.trackView.repaintViews(); // prompt redraw to change colour of clicked sample
62283            }
62284
62285            return closestResult;
62286          }
62287        }
62288
62289        return [];
62290      }
62291
62292      popupData(clickState, featureList) {
62293        featureList = this.clickedFeatures(clickState, featureList);
62294        const items = [];
62295        featureList.forEach(function (f) {
62296          for (let property of Object.keys(f)) {
62297            if (isSimpleType(f[property])) {
62298              items.push({
62299                name: property,
62300                value: f[property]
62301              });
62302            }
62303          }
62304        });
62305        return items;
62306      }
62307
62308      supportsWholeGenome() {
62309        return false;
62310      }
62311
62312    }
62313
62314    function distanceToLine(x, y, ax, ay, bx, by) {
62315      /*
62316          Finds distance between point (x, y) and line defined by points (ax, ay) (bx, by)
62317          based on http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
62318      */
62319      const bx_minus_ax = bx - ax;
62320      const by_minus_ay = by - ay;
62321      const v = Math.abs(bx_minus_ax * (ay - y) - (ax - x) * by_minus_ay);
62322      const r = Math.sqrt(bx_minus_ax * bx_minus_ax + by_minus_ay * by_minus_ay);
62323      const distance = r > 0 ? v / r : 0; //console.warn('Check if', x, y, 'is within', ax, ay, bx, by, '. Distance from line: ', distance);
62324
62325      return distance;
62326    }
62327
62328    /*
62329     * The MIT License (MIT)
62330     *
62331     * Copyright (c) 2014 Broad Institute
62332     *
62333     * Permission is hereby granted, free of charge, to any person obtaining a copy
62334     * of this software and associated documentation files (the "Software"), to deal
62335     * in the Software without restriction, including without limitation the rights
62336     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
62337     * copies of the Software, and to permit persons to whom the Software is
62338     * furnished to do so, subject to the following conditions:
62339     *
62340     * The above copyright notice and this permission notice shall be included in
62341     * all copies or substantial portions of the Software.
62342     *
62343     *
62344     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62345     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
62346     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
62347     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
62348     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
62349     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
62350     * THE SOFTWARE.
62351     */
62352
62353    class RnaStructTrack extends TrackBase {
62354      constructor(config, browser) {
62355        super(config, browser); // Set defaults
62356
62357        if (!config.height) {
62358          this.height = 300;
62359        }
62360
62361        this.arcOrientation = false;
62362        this.theta = Math.PI / 2;
62363
62364        if ("bp" === config.format) {
62365          this.featureSource = new RNAFeatureSource(config, browser.genome);
62366        } else {
62367          this.featureSource = new TextFeatureSource(config, browser.genome);
62368        }
62369      }
62370
62371      async getFeatures(chr, start, end) {
62372        const visibilityWindow = this.visibilityWindow;
62373        return this.featureSource.getFeatures({
62374          chr,
62375          start,
62376          end,
62377          visibilityWindow
62378        });
62379      }
62380
62381      draw(options) {
62382        const ctx = options.context;
62383        const theta = Math.PI / 2;
62384        const pixelWidth = options.pixelWidth;
62385        const pixelHeight = options.pixelHeight;
62386        options.viewportWidth;
62387        const bpPerPixel = options.bpPerPixel;
62388        const bpStart = options.bpStart;
62389        const xScale = bpPerPixel;
62390        const orienation = this.arcOrientation;
62391        IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {
62392          'fillStyle': "rgb(255, 255, 255)"
62393        });
62394        const featureList = options.features;
62395
62396        if (featureList) {
62397          // Sort by score -- draw lowest scored features first
62398          sortByScore(featureList, 1);
62399
62400          for (let feature of featureList) {
62401            if (feature.startLeft) {
62402              let sl = Math.round((feature.startLeft - bpStart) / xScale);
62403              let sr = Math.round((feature.startRight - bpStart) / xScale);
62404              let el = Math.round((feature.endLeft - bpStart) / xScale);
62405              let er = Math.round((feature.endRight - bpStart) / xScale);
62406              ctx.fillStyle = feature.color;
62407              ctx.strokeStyle = feature.color;
62408              ctx.beginPath(); // First arc
62409
62410              let x1 = (sl + er) / 2;
62411              let r1 = (er - sl) / 2;
62412              let y1 = this.height;
62413              let sa = Math.PI + (Math.PI / 2 - theta);
62414              let ea = 2 * Math.PI - (Math.PI / 2 - theta);
62415
62416              if (orienation) {
62417                y1 = 0;
62418                ctx.arc(x1, y1, r1, ea, sa);
62419                ctx.lineTo(er, y1);
62420              } else {
62421                ctx.arc(x1, y1, r1, sa, ea);
62422                ctx.lineTo(el, y1);
62423              } // Second arc
62424
62425
62426              const x2 = (sr + el) / 2;
62427              const r2 = (el - sr) / 2;
62428              const y2 = y1; // Only for theta == pi/2
62429
62430              if (orienation) {
62431                ctx.arc(x2, y2, r2, sa, ea, true);
62432                ctx.lineTo(el, y2);
62433              } else {
62434                ctx.arc(x2, y2, r2, ea, sa, true);
62435                ctx.lineTo(sl, y2);
62436              }
62437
62438              ctx.stroke();
62439              ctx.fill();
62440              feature.drawState = {
62441                x1: x1,
62442                y1: y1,
62443                r1: r1,
62444                x2: x2,
62445                y2: y2,
62446                r2: r2,
62447                sa: sa,
62448                ea: ea
62449              };
62450            } else {
62451              let s = Math.round((feature.start - bpStart) / xScale);
62452              let e = Math.round((feature.end - bpStart) / xScale);
62453              ctx.strokeStyle = feature.color;
62454              ctx.beginPath(); // First arc
62455
62456              let x = (s + e) / 2;
62457              let r = (e - s) / 2;
62458              let y = this.height;
62459              let sa = Math.PI + (Math.PI / 2 - theta);
62460              let ea = 2 * Math.PI - (Math.PI / 2 - theta);
62461
62462              if (orienation) {
62463                y = 0;
62464                ctx.arc(x, y, r, ea, sa);
62465              } else {
62466                ctx.arc(x, y, r, sa, ea);
62467              }
62468
62469              ctx.stroke();
62470              feature.drawState = {
62471                x1: x,
62472                y1: y,
62473                r1: r,
62474                sa: sa,
62475                ea: ea
62476              };
62477            }
62478          }
62479        }
62480      }
62481
62482      clickedFeatures(clickState, features) {
62483        features = super.clickedFeatures(clickState, features);
62484        const clicked = []; // Sort by score in descending order   (opposite order than drawn)
62485
62486        sortByScore(features, -1);
62487
62488        for (let f of features) {
62489          const ds = f.drawState;
62489 // Distance from arc radius, or outer arc for type ".bp"
62490
62491          const dx1 = clickState.canvasX - ds.x1;
62492          const dy1 = clickState.canvasY - ds.y1;
62493          const d1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
62494          const outerLim = ds.r1 + 3;
62495          let d2;
62496          let innerLim;
62497
62498          if (ds.x2 === undefined) {
62499            d2 = d1;
62500            innerLim = ds.r1 - 3;
62501          } else {
62502            const dx2 = clickState.canvasX - ds.x2;
62503            const dy2 = clickState.canvasY - ds.y2;
62504            d2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
62505            innerLim = ds.r2 - 3;
62506          } // Between outer and inner arcs, with some tolerance
62507
62508
62509          if (d1 < outerLim && d2 > innerLim) {
62510            clicked.push(f);
62511            break;
62512          }
62513        }
62514
62515        return clicked;
62516      }
62517
62518      popupData(clickState, features) {
62519        // We use the featureCache property rather than method to avoid async load.  If the
62520        // feature is not already loaded this won't work,  but the user wouldn't be mousing over it either.
62521        features = this.clickedFeatures(clickState, features);
62522
62523        if (features && features.length > 0) {
62524          return TrackBase.extractPopupData(features[0], this.getGenomeId());
62525        }
62526      }
62527
62528      menuItemList() {
62529        var self = this;
62530        return [{
62531          name: "Toggle arc direction",
62532          click: function () {
62533            self.arcOrientation = !self.arcOrientation;
62534            self.trackView.repaintViews();
62535          }
62536        }];
62537      }
62538
62539    }
62540
62541    function sortByScore(featureList, direction) {
62542      featureList.sort(function (a, b) {
62543        const s1 = a.score === undefined ? -Number.MAX_VALUE : a.score;
62544        const s2 = b.score === undefined ? -Number.MAX_VALUE : b.score;
62545        const d = direction === undefined ? 1 : direction;
62546        return d * (s1 - s2);
62547      });
62548    }
62549
62550    class RNAFeatureSource {
62551      constructor(config, genome) {
62552        this.config = config;
62553        this.genome = genome;
62554      }
62555
62556      async getFeatures(_ref) {
62557        let {
62558          chr,
62559          start,
62560          end,
62561          bpPerPixel,
62562          visibilityWindow
62563        } = _ref;
62564        const genome = this.genome;
62565
62566        if (!this.featureCache) {
62567          const options = buildOptions(this.config);
62568          const data = await igvxhr.loadString(this.config.url, options);
62569          this.featureCache = new FeatureCache(parseBP(data), genome);
62570          return this.featureCache.queryFeatures(chr, start, end);
62571        } else {
62572          return this.featureCache.queryFeatures(chr, start, end);
62573        }
62574
62575        function parseBP(data) {
62576          if (!data) return null;
62577          const dataWrapper = getDataWrapper(data);
62578          let header = true;
62579          let line;
62580          const colors = [];
62581          const descriptors = [];
62582          const features = [];
62583
62584          while ((line = dataWrapper.nextLine()) !== undefined) {
62585            const tokens = line.split('\t');
62586
62587            if (header && line.startsWith("color:")) {
62588              const color = "rgb(" + tokens[1] + "," + tokens[2] + "," + tokens[3] + ")";
62589              colors.push(color);
62590
62591              if (tokens.length > 4) {
62592                descriptors.push(tokens[4]);
62593              } // TODO - use label
62594
62595            } else {
62596              header = false;
62597              const chr = tokens[0];
62598              const startLeftNuc = Number.parseInt(tokens[1]) - 1;
62599              const startRightNuc = Number.parseInt(tokens[2]) - 1;
62600              const endLeftNuc = Number.parseInt(tokens[3]);
62601              const endRightNuc = Number.parseInt(tokens[4]);
62602              var colorIdx = Number.parseInt(tokens[5]);
62603              const color = colors[colorIdx];
62604              let feature;
62605
62606              if (startLeftNuc <= endRightNuc) {
62607                feature = {
62608                  chr: chr,
62609                  startLeft: Math.min(startLeftNuc, startRightNuc),
62610                  startRight: Math.max(startLeftNuc, startRightNuc),
62611                  endLeft: Math.min(endLeftNuc, endRightNuc),
62612                  endRight: Math.max(endLeftNuc, endRightNuc),
62613                  color: color,
62614                  score: colorIdx
62615                };
62616              } else {
62617                feature = {
62618                  chr: chr,
62619                  startLeft: Math.min(endLeftNuc, endRightNuc),
62620                  startRight: Math.max(endLeftNuc, endRightNuc),
62621                  endLeft: Math.min(startLeftNuc, startRightNuc),
62622                  endRight: Math.max(startLeftNuc, startRightNuc),
62623                  color: color,
62624                  score: colorIdx
62625                };
62626              }
62627
62628              feature.start = feature.startLeft;
62629              feature.end = feature.endRight;
62630
62631              if (descriptors.length > colorIdx) {
62632                feature.description = descriptors[colorIdx];
62633              }
62634
62635              features.push(feature);
62636            }
62637          }
62638
62639          return features;
62640        }
62641      }
62642
62643    }
62644
62645    /*
62646     * The MIT License (MIT)
62647     *
62648     * Copyright (c) 2014 Broad Institute
62649     *
62650     * Permission is hereby granted, free of charge, to any person obtaining a copy
62651     * of this software and associated documentation files (the "Software"), to deal
62652     * in the Software without restriction, including without limitation the rights
62653     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
62654     * copies of the Software, and to permit persons to whom the Software is
62655     * furnished to do so, subject to the following conditions:
62656     *
62657     * The above copyright notice and this permission notice shall be included in
62658     * all copies or substantial portions of the Software.
62659     *
62660     *
62661     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62662     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
62663     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
62664     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
62665     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
62666     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
62667     * THE SOFTWARE.
62668     */
62669
62670    class IdeogramTrack {
62671      constructor(browser) {
62672        this.browser = browser;
62673        this.type = 'ideogram';
62674        this.id = this.type;
62675        this.height = 16;
62676        this.order = Number.MIN_SAFE_INTEGER;
62677        this.disableButtons = true;
62678        this.ignoreTrackMenu = true;
62679      }
62680
62681      async getFeatures(chr, start, end) {
62682        return [];
62683      }
62684
62685      computePixelHeight(ignore) {
62686        return this.height;
62687      }
62688
62689      draw(_ref) {
62690        let {
62691          context,
62692          referenceFrame,
62693          pixelWidth,
62694          pixelHeight
62695        } = _ref;
62696        const chr = referenceFrame.chr;
62697        const chromosome = referenceFrame.genome.getChromosome(chr);
62698
62699        if (undefined === chromosome || pixelWidth <= 0 || pixelHeight <= 0 || 'all' === chr.toLowerCase()) {
62700          return;
62701        }
62702
62703        const stainColors = [];
62704        drawIdeogram({
62705          ctx: context,
62706          chr,
62707          referenceFrame,
62708          genome: referenceFrame.genome,
62709          width: pixelWidth,
62710          height: pixelHeight,
62711          stainColors
62712        });
62713        const widthBP = Math.round(referenceFrame.bpPerPixel * pixelWidth);
62714        const xBP = referenceFrame.start; // Total chromosome length can be > chromosome.bpLength for partial fastas.
62715
62716        let chrLength = chromosome.bpLength;
62717        const cytobands = referenceFrame.genome.getCytobands(chr);
62718
62719        if (cytobands && cytobands.length > 0 && cytobands[cytobands.length - 1].end) {
62720          chrLength = Math.max(chrLength, cytobands[cytobands.length - 1].end);
62721          chromosome.bpLength = chrLength; // Correct bp length, bit of a hack
62722        }
62723
62724        if (widthBP < chrLength) {
62725          const percentWidth = widthBP / chrLength;
62726          const percentX = xBP / chrLength;
62727          let x = Math.floor(percentX * pixelWidth);
62728          let ww = Math.floor(percentWidth * pixelWidth);
62729          x = Math.max(0, x);
62730          x = Math.min(pixelWidth - ww, x); // Push current context
62731
62732          context.save(); // Draw red box
62733
62734          context.strokeStyle = "red";
62735          context.lineWidth = ww < 2 ? 1 : 2;
62736          const xx = x + context.lineWidth / 2;
62737          ww = ww < 2 ? 1 : ww - context.lineWidth;
62738          const yy = context.lineWidth / 2;
62739          const hh = pixelHeight - context.lineWidth;
62740          context.strokeRect(xx, yy, ww, hh); // Pop current context
62741
62742          context.restore();
62743        }
62744      }
62745
62746      dispose() {
62747        this.trackView = undefined;
62748      }
62749
62750    }
62751
62752    function drawIdeogram(_ref2) {
62753      let {
62754        ctx,
62755        chr,
62756        referenceFrame,
62757        genome,
62758        width,
62759        height,
62760        stainColors
62761      } = _ref2;
62762      const shim = 1;
62763      const shim2 = 0.5 * shim;
62764      const ideogramTop = 0;
62765
62766      if (undefined === genome) {
62767        return;
62768      }
62769
62770      IGVGraphics.fillRect(ctx, 0, 0, width, height, {
62771        fillStyle: IGVColor.greyScale(255)
62772      });
62773      const cytobands = genome.getCytobands(chr);
62774
62775      if (cytobands) {
62776        const center = ideogramTop + height / 2;
62777        const xC = [];
62778        const yC = [];
62779
62780        if (0 === cytobands.length) {
62781          return;
62782        } // Get chrLength from the cytobands -- chromsome.bpLength might not work for igv-reports fasta files, which
62783        // contain only a portion of the chromosome sequence
62784        // *DOESNT WORK* const chrLength = referenceFrame.genome.getChromosome(chr).bpLength;
62785
62786
62787        const chrLength = cytobands[cytobands.length - 1].end;
62788        const scale = width / chrLength; // round rect clipping path
62789
62790        ctx.beginPath();
62791        IGVGraphics.roundRect(ctx, shim2, shim2 + ideogramTop, width - 2 * shim2, height - 2 * shim2, (height - 2 * shim2) / 2, 0, 1);
62792        ctx.clip();
62793
62794        for (let i = 0; i < cytobands.length; i++) {
62795          const cytoband = cytobands[i];
62796          const start = scale * cytoband.start;
62797          const end = scale * cytoband.end;
62798
62799          if (cytoband.type === 'c') {
62800            if (cytoband.name.charAt(0) === 'p') {
62801              xC[0] = start;
62802              yC[0] = height + ideogramTop;
62803              xC[1] = start;
62804              yC[1] = ideogramTop;
62805              xC[2] = end;
62806              yC[2] = center;
62807            } else {
62808              xC[0] = end;
62809              yC[0] = height + ideogramTop;
62810              xC[1] = end;
62811              yC[1] = ideogramTop;
62812              xC[2] = start;
62813              yC[2] = center;
62814            }
62815
62816            ctx.fillStyle = "rgb(150, 0, 0)";
62817            ctx.strokeStyle = "rgb(150, 0, 0)";
62818            IGVGraphics.polygon(ctx, xC, yC, 1, 0);
62819          } else {
62820            ctx.fillStyle = getCytobandColor(stainColors, cytoband);
62821            IGVGraphics.fillRect(ctx, start, shim + ideogramTop, end - start, height - 2 * shim);
62822          }
62823        }
62824      } // round rect border
62825
62826
62827      ctx.strokeStyle = IGVColor.greyScale(41);
62828      IGVGraphics.roundRect(ctx, shim2, shim2 + ideogramTop, width - 2 * shim2, height - 2 * shim2, (height - 2 * shim2) / 2, 0, 1);
62829    }
62830
62831    function getCytobandColor(colors, data) {
62832      if (data.type === 'c') {
62833        // centermere: "acen"
62834        return "rgb(150, 10, 10)";
62835      } else {
62836        var stain = data.stain; // + 4;
62837
62838        var shade = 230;
62839
62840        if (data.type === 'p') {
62841          shade = Math.floor(230 - stain / 100.0 * 230);
62842        }
62843
62844        var c = colors[shade];
62845
62846        if (!c) {
62847          c = "rgb(" + shade + "," + shade + "," + shade + ")";
62848          colors[shade] = c;
62849        }
62850
62851        return c;
62852      }
62853    }
62854
62855    /*
62856     * The MIT License (MIT)
62857     *
62858     * Copyright (c) 2014 Broad Institute
62859     *
62860     * Permission is hereby granted, free of charge, to any person obtaining a copy
62861     * of this software and associated documentation files (the "Software"), to deal
62862     * in the Software without restriction, including without limitation the rights
62863     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
62864     * copies of the Software, and to permit persons to whom the Software is
62865     * furnished to do so, subject to the following conditions:
62866     *
62867     * The above copyright notice and this permission notice shall be included in
62868     * all copies or substantial portions of the Software.
62869     *
62870     *
62871     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62872     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
62873     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
62874     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
62875     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
62876     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
62877     * THE SOFTWARE.
62878     */
62879    let JUNCTION_MOTIF_PALETTE = new PaletteColorTable("Dark2"); // Lock in color-to-motif mapping so it's independent of data loading order. This list may not include all possible
62880    // motif values as this varies depending on the RNA-seq pipeline. The current list is based on STAR v2.4 docs.
62881
62882    const someMotifValues = ['GT/AG', 'CT/AC', 'GC/AG', 'CT/GC', 'AT/AC', 'GT/AT', 'non-canonical'];
62883    someMotifValues.forEach(motif => {
62884      JUNCTION_MOTIF_PALETTE.getColor(motif);
62885    }); // rendering context with values that only need to be computed once per render, rather than for each splice junction
62886
62887    const junctionRenderingContext = {};
62888
62889    class SpliceJunctionTrack extends TrackBase {
62890      constructor(config, browser) {
62891        super(config, browser);
62892      }
62893
62894      init(config) {
62895        super.init(config);
62896        this.type = config.type || 'junctions';
62897
62898        if (config._featureSource) {
62899          this.featureSource = config._featureSource;
62900          delete config._featureSource;
62901        } else {
62902          this.featureSource = config.featureSource ? config.featureSource : FeatureSource(config, this.browser.genome);
62903        }
62904
62905        this.margin = config.margin === undefined ? 10 : config.margin;
62906
62907        if (!this.height) {
62908          this.height = 100;
62909        } //set defaults
62910
62911
62912        if (config.colorByNumReadsThreshold === undefined) {
62913          config.colorByNumReadsThreshold = 5;
62914        }
62915      }
62916
62917      async postInit() {
62918        if (typeof this.featureSource.getHeader === "function") {
62919          this.header = await this.featureSource.getHeader();
62920        } // Set properties from track line
62921
62922
62923        if (this.header) {
62924          this.setTrackProperties(this.header);
62925        }
62926
62927        if (this.visibilityWindow === undefined && typeof this.featureSource.defaultVisibilityWindow === 'function') {
62928          this.visibilityWindow = await this.featureSource.defaultVisibilityWindow();
62929        }
62930
62931        return this;
62932      }
62933
62934      supportsWholeGenome() {
62935        return false;
62936      }
62937
62938      async getFeatures(chr, start, end, bpPerPixel) {
62939        const visibilityWindow = this.visibilityWindow;
62940        return this.featureSource.getFeatures({
62941          chr,
62942          start,
62943          end,
62944          bpPerPixel,
62945          visibilityWindow
62946        });
62947      }
62948
62949      /**
62950       * The required height in pixels required for the track content.   This is not the visible track height, which
62951       * can be smaller (with a scrollbar) or larger.
62952       *
62953       * @param features
62954       * @returns {*}
62955       */
62956      computePixelHeight(features) {
62957        return this.height;
62958      }
62959
62960      draw(options) {
62961        const featureList = options.features;
62962        const ctx = options.context;
62963        const bpPerPixel = options.bpPerPixel;
62964        const bpStart = options.bpStart;
62965        const pixelWidth = options.pixelWidth;
62966        const pixelHeight = options.pixelHeight;
62967        const bpEnd = bpStart + pixelWidth * bpPerPixel + 1;
62968
62969        if (!this.config.isMergedTrack) {
62970          IGVGraphics.fillRect(ctx, 0, options.pixelTop, pixelWidth, pixelHeight, {
62971            'fillStyle': "rgb(255, 255, 255)"
62972          });
62973        }
62974
62975        if (featureList) {
62976          junctionRenderingContext.referenceFrame = options.viewport.referenceFrame;
62977          junctionRenderingContext.referenceFrameStart = junctionRenderingContext.referenceFrame.start;
62978          junctionRenderingContext.referenceFrameEnd = junctionRenderingContext.referenceFrameStart + junctionRenderingContext.referenceFrame.toBP($$1(options.viewport.contentDiv).width()); // For a given viewport, records where features that are < 2px in width have been rendered already.
62979          // This prevents wasteful rendering of multiple such features onto the same pixels.
62980
62981          junctionRenderingContext.featureZoomOutTracker = {};
62982
62983          for (let feature of featureList) {
62984            if (feature.end < bpStart) continue;
62985            if (feature.start > bpEnd) break;
62986            this.renderJunction(feature, bpStart, bpPerPixel, pixelHeight, ctx);
62987          }
62988        } else {
62989          console.log("No feature list");
62990        }
62991      }
62992
62993      /**
62994       *
62995       * @param feature
62996       * @param bpStart  genomic location of the left edge of the current canvas
62997       * @param xScale  scale in base-pairs per pixel
62998       * @param pixelHeight  pixel height of the current canvas
62999       * @param ctx  the canvas 2d context
63000       */
63001      renderJunction(feature, bpStart, xScale, pixelHeight, ctx) {
63002        // cache whether this junction is rendered or filtered out. Use later to exclude non-rendered junctions from click detection.
63003        feature.isVisible = false;
63004        const junctionLeftPx = Math.round((feature.start - bpStart) / xScale);
63005        const junctionRightPx = Math.round((feature.end - bpStart) / xScale);
63006        const junctionMiddlePx = (junctionLeftPx + junctionRightPx) / 2;
63007
63008        if (junctionRightPx - junctionLeftPx <= 3) {
63009          if (junctionMiddlePx in junctionRenderingContext.featureZoomOutTracker) {
63010            return;
63011          }
63012
63013          junctionRenderingContext.featureZoomOutTracker[junctionMiddlePx] = true;
63014        } // TODO: cache filter and pixel calculations by doing them earlier when features are initially parsed?
63015
63016
63017        if (this.config.hideAnnotatedJunctions && feature.attributes.annotated_junction === "true") {
63018          return;
63019        }
63020
63021        if (this.config.hideUnannotatedJunctions && feature.attributes.annotated_junction === "false") {
63022          return;
63023        }
63024
63025        if (this.config.hideMotifs && this.config.hideMotifs.includes(feature.attributes.motif)) {
63026          return;
63027        }
63028
63029        if (this.config.hideStrand === feature.strand) {
63030          return;
63031        } // check if splice junction is inside viewport
63032
63033
63034        if (this.config.minJunctionEndsVisible) {
63035          let numJunctionEndsVisible = 0;
63036
63037          if (feature.start >= junctionRenderingContext.referenceFrameStart && feature.start <= junctionRenderingContext.referenceFrameEnd) {
63038            numJunctionEndsVisible += 1;
63039          }
63040
63041          if (feature.end >= junctionRenderingContext.referenceFrameStart && feature.end <= junctionRenderingContext.referenceFrameEnd) {
63042            numJunctionEndsVisible += 1;
63043          }
63044
63045          if (numJunctionEndsVisible < this.config.minJunctionEndsVisible) {
63046            return;
63047          }
63048        }
63049
63050        let uniquelyMappedReadCount;
63051        let multiMappedReadCount;
63052        let totalReadCount;
63053
63054        if (feature.attributes.uniquely_mapped) {
63055          uniquelyMappedReadCount = parseInt(feature.attributes.uniquely_mapped);
63056
63057          if (uniquelyMappedReadCount < this.config.minUniquelyMappedReads) {
63058            return;
63059          }
63060
63061          multiMappedReadCount = parseInt(feature.attributes.multi_mapped);
63062          totalReadCount = uniquelyMappedReadCount + multiMappedReadCount;
63063
63064          if (totalReadCount < this.config.minTotalReads) {
63065            return;
63066          }
63067
63068          if (totalReadCount > 0 && multiMappedReadCount / totalReadCount > this.config.maxFractionMultiMappedReads) {
63069            return;
63070          }
63071
63072          if (feature.attributes.maximum_spliced_alignment_overhang && parseInt(feature.attributes.maximum_spliced_alignment_overhang) < this.config.minSplicedAlignmentOverhang) {
63073            return;
63074          }
63075        }
63076
63077        let numSamplesWithThisJunction;
63078
63079        if (feature.attributes.num_samples_with_this_junction) {
63080          numSamplesWithThisJunction = parseInt(feature.attributes.num_samples_with_this_junction);
63081
63082          if (this.config.minSamplesWithThisJunction && numSamplesWithThisJunction < this.config.minSamplesWithThisJunction) {
63083            return;
63084          }
63085
63086          if (this.config.maxSamplesWithThisJunction && numSamplesWithThisJunction > this.config.maxSamplesWithThisJunction) {
63087            return;
63088          }
63089
63090          if (feature.attributes.num_samples_total) {
63091            feature.attributes.percent_samples_with_this_junction = 100 * numSamplesWithThisJunction / Number(feature.attributes.num_samples_total);
63092
63093            if (this.config.minPercentSamplesWithThisJunction) {
63094              if (feature.attributes.percent_samples_with_this_junction < this.config.minPercentSamplesWithThisJunction || feature.attributes.percent_samples_with_this_junction > this.config.maxPercentSamplesWithThisJunction) {
63095                return;
63096              }
63097            }
63098          }
63099        }
63100
63101        const py = this.margin;
63102        const rowHeight = this.height;
63103        const cy = py + 0.5 * rowHeight;
63104        let topY = py;
63105        const bottomY = py + rowHeight;
63106        const bezierBottomY = bottomY - 10; // draw the junction arc
63107
63108        const bezierControlLeftPx = (junctionLeftPx + junctionMiddlePx) / 2;
63109        const bezierControlRightPx = (junctionMiddlePx + junctionRightPx) / 2;
63110        let lineWidth = 1;
63111
63112        if (feature.attributes.line_width) {
63113          lineWidth = Number(feature.attributes.line_width);
63114        } else {
63115          if (this.config.thicknessBasedOn === undefined || this.config.thicknessBasedOn === 'numUniqueReads') {
63116            lineWidth = uniquelyMappedReadCount;
63117          } else if (this.config.thicknessBasedOn === 'numReads') {
63118            lineWidth = totalReadCount;
63119          } else if (this.config.thicknessBasedOn === 'numSamplesWithThisJunction') {
63120            if (numSamplesWithThisJunction !== undefined) {
63121              lineWidth = numSamplesWithThisJunction;
63122            }
63123          }
63124
63125          lineWidth = 1 + Math.log(lineWidth + 1) / Math.log(12);
63126        }
63127
63128        let bounceHeight;
63129
63130        if (this.config.bounceHeightBasedOn === undefined || this.config.bounceHeightBasedOn === 'random') {
63131          // randomly but deterministically stagger topY coordinates to reduce overlap
63132          bounceHeight = (feature.start + feature.end) % 7;
63133        } else if (this.config.bounceHeightBasedOn === 'distance') {
63134          bounceHeight = 6 * (feature.end - feature.start) / (junctionRenderingContext.referenceFrameEnd - junctionRenderingContext.referenceFrameStart);
63135        } else if (this.config.bounceHeightBasedOn === 'thickness') {
63136          bounceHeight = 2 * lineWidth;
63137        }
63138
63139        topY += rowHeight * Math.max(7 - bounceHeight, 0) / 10;
63140        let color;
63141
63142        if (feature.attributes.color) {
63143          color = feature.attributes.color; // Explicit setting
63144        } else if (this.config.colorBy === undefined || this.config.colorBy === 'numUniqueReads') {
63145          color = uniquelyMappedReadCount > this.config.colorByNumReadsThreshold ? 'blue' : '#AAAAAA'; // color gradient?
63146        } else if (this.config.colorBy === 'numReads') {
63147          color = totalReadCount > this.config.colorByNumReadsThreshold ? 'blue' : '#AAAAAA';
63148        } else if (this.config.colorBy === 'isAnnotatedJunction') {
63149          color = feature.attributes.annotated_junction === "true" ? '#b0b0ec' : 'orange';
63150        } else if (this.config.colorBy === 'strand') {
63151          color = feature.strand === "+" ? '#b0b0ec' : '#ecb0b0';
63152        } else if (this.config.colorBy === 'motif') {
63153          color = JUNCTION_MOTIF_PALETTE.getColor(feature.attributes.motif);
63154        } else {
63155          color = '#AAAAAA';
63156        }
63157
63158        let label = "";
63159
63160        if (feature.attributes.label) {
63161          label = feature.attributes.label.replace(/_/g, " ");
63162        } else if (this.config.labelWith === undefined || this.config.labelWith === 'uniqueReadCount') {
63163          //default label
63164          label = uniquelyMappedReadCount;
63165        } else if (this.config.labelWith === 'totalReadCount') {
63166          label = totalReadCount;
63167        } else if (this.config.labelWith === 'numSamplesWithThisJunction') {
63168          if (numSamplesWithThisJunction !== undefined) {
63169            label = numSamplesWithThisJunction;
63170          }
63171        } else if (this.config.labelWith === 'percentSamplesWithThisJunction') {
63172          if (feature.attributes.percent_samples_with_this_junction !== undefined) {
63173            label = feature.attributes.percent_samples_with_this_junction.toFixed(0) + '%';
63174          }
63175        } else if (this.config.labelWith === 'motif') {
63176          if (feature.attributes.motif !== undefined) {
63177            label += feature.attributes.motif;
63178          }
63179        }
63180
63181        if (this.config.labelWithInParen === 'uniqueReadCount') {
63182          label += ' (' + uniquelyMappedReadCount + ')';
63183        } else if (this.config.labelWithInParen === 'totalReadCount') {
63184          label += ' (' + totalReadCount + ')';
63185        } else if (this.config.labelWithInParen === 'multiMappedReadCount') {
63186          if (multiMappedReadCount > 0) {
63187            label += ' (+' + multiMappedReadCount + ')';
63188          }
63189        } else if (this.config.labelWithInParen === 'numSamplesWithThisJunction') {
63190          if (numSamplesWithThisJunction !== undefined) {
63191            label += ' (' + numSamplesWithThisJunction + ')';
63192          }
63193        } else if (this.config.labelWithInParen === 'percentSamplesWithThisJunction') {
63194          if (feature.attributes.percent_samples_with_this_junction !== undefined) {
63195            label += ' (' + feature.attributes.percent_samples_with_this_junction.toFixed(0) + '%)';
63196          }
63197        } else if (this.config.labelWithInParen === 'motif') {
63198          if (feature.attributes.motif !== undefined) {
63199            label += ` ${feature.attributes.motif}`;
63200          }
63201        } // data source: STAR splice junctions (eg. SJ.out.tab file converted to bed).
63202        // .bed "name" field used to store unique + multi-mapped read counts, so:
63203        // feature.score:  unique spanning read counts
63204        // feature.name:   unique + multi-mapped spanning read counts
63205        //example feature:  { chr: "chr17", start: 39662344, end: 39662803, name: "59", row: 0, score: 38, strand: "+"}
63206
63207
63208        feature.isVisible = true;
63209        ctx.beginPath();
63210        ctx.moveTo(junctionLeftPx, bezierBottomY);
63211        ctx.bezierCurveTo(bezierControlLeftPx, topY, bezierControlRightPx, topY, junctionRightPx, bezierBottomY);
63212        ctx.lineWidth = lineWidth;
63213        ctx.strokeStyle = color;
63214        ctx.stroke();
63215
63216        const drawArrowhead = (ctx, x, y, size) => {
63217          //TODO draw better arrow heads: https://stackoverflow.com/questions/21052972/curved-thick-arrows-on-canvas
63218          ctx.beginPath();
63219          ctx.moveTo(x, y);
63220          ctx.lineTo(x - size / 2, y - size);
63221          ctx.lineTo(x + size / 2, y - size);
63222          ctx.lineTo(x, y);
63223          ctx.closePath();
63224          ctx.fill();
63225        };
63226
63227        if (feature.attributes.left_shape || feature.attributes.right_shape) {
63228          ctx.fillStyle = color;
63229          const arrowSize = ctx.lineWidth > 2 ? 10 : 7;
63230
63231          if (feature.attributes.left_shape) {
63232            drawArrowhead(ctx, junctionLeftPx, bezierBottomY, arrowSize);
63233          }
63234
63235          if (feature.attributes.right_shape) {
63236            drawArrowhead(ctx, junctionRightPx, bezierBottomY, arrowSize);
63237          }
63238        }
63239
63240        ctx.fillText(label, junctionMiddlePx - ctx.measureText(label).width / 2, (7 * topY + cy) / 8);
63241      }
63242
63243      clickedFeatures(clickState, features) {
63244        const allFeatures = super.clickedFeatures(clickState, features);
63245        return allFeatures.filter(function (feature) {
63246          return feature.isVisible && feature.attributes;
63247        });
63248      }
63249      /**
63250       * Return "popup data" for feature @ genomic location.  Data is an array of key-value pairs
63251       */
63252
63253
63254      popupData(clickState, features) {
63255        features = this.clickedFeatures(clickState, features);
63256        const genomicLocation = clickState.genomicLocation;
63257        const data = [];
63258
63259        for (let feature of features) {
63260          const featureData = typeof feature.popupData === "function" ? feature.popupData(genomicLocation) : this.extractPopupData(feature._f || feature, this.getGenomeId());
63261
63262          if (featureData) {
63263            if (data.length > 0) {
63264              data.push("<hr/><hr/>");
63265            }
63266
63267            Array.prototype.push.apply(data, featureData);
63268          }
63269        }
63270
63271        return data;
63272      }
63273
63274      description() {
63275        return this.name;
63276      }
63277      /**
63278       * Called when the track is removed.  Do any needed cleanup here
63279       */
63280
63281
63282      dispose() {
63283        this.trackView = undefined;
63284      }
63285
63286    }
63287
63288    const trackFunctions = new Map([['ideogram', (config, browser) => new IdeogramTrack(config, browser)], ['sequence', (config, browser) => new SequenceTrack(config, browser)], ['feature', (config, browser) => new FeatureTrack(config, browser)], ['seg', (config, browser) => new SegTrack(config, browser)], ['mut', (config, browser) => new SegTrack(config, browser)], ['maf', (config, browser) => new SegTrack(config, browser)], ['wig', (config, browser) => new WigTrack(config, browser)], ['merged', (config, browser) => new MergedTrack(config, browser)], ['alignment', (config, browser) => new BAMTrack(config, browser)], ['interaction', (config, browser) => new InteractionTrack(config, browser)], ['interact', (config, browser) => new InteractionTrack(config, browser)], ['variant', (config, browser) => new VariantTrack(config, browser)], ['eqtl', (config, browser) => new EqtlTrack(config, browser)], ['gwas', (config, browser) => new GWASTrack(config, browser)], ['arc', (config, browser) => new RnaStructTrack(config, browser)], ['gcnv', (config, browser) => new GCNVTrack(config, browser)], ['junction', (config, browser) => new SpliceJunctionTrack(config, browser)]]);
63289    /**
63290     * Add a track constructor  the the factory lookup table.
63291     *
63292     * @param type
63293     * @param track
63294     */
63295
63296    const addTrackCreatorFunction = function (type, track) {
63297      trackFunctions.set(type, track);
63298    };
63299
63300    const getTrack = function (type, config, browser) {
63301      let trackKey;
63302
63303      switch (type) {
63304        case "annotation":
63305        case "genes":
63306        case "fusionjuncspan":
63307        case "snp":
63308          trackKey = "feature";
63309          break;
63310
63311        case 'seg':
63312        case 'maf':
63313        case 'mut':
63314          trackKey = 'seg';
63315          break;
63316
63317        case 'junctions':
63318        case 'splicejunctions':
63319          trackKey = 'junction';
63320          break;
63321
63322        default:
63323          trackKey = type;
63324      }
63325
63326      return trackFunctions.has(trackKey) ? trackFunctions.get(trackKey)(config, browser) : undefined;
63327    };
63328
63329    var TrackFactory = {
63330      tracks: trackFunctions,
63331      addTrack: addTrackCreatorFunction,
63332      getTrack
63333    };
63334
63335    /*
63336     * The MIT License (MIT)
63337     *
63338     * Copyright (c) 2016-2017 The Regents of the University of California
63339     * Author: Jim Robinson
63340     *
63341     * Permission is hereby granted, free of charge, to any person obtaining a copy
63342     * of this software and associated documentation files (the "Software"), to deal
63343     * in the Software without restriction, including without limitation the rights
63344     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
63345     * copies of the Software, and to permit persons to whom the Software is
63346     * furnished to do so, subject to the following conditions:
63347     *
63348     * The above copyright notice and this permission notice shall be included in
63349     * all copies or substantial portions of the Software.
63350     *
63351     *
63352     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63353     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63354     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
63355     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
63356     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
63357     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
63358     * THE SOFTWARE.
63359     */
63360    var defaultHighlightColor = "rgba(68, 134, 247, 0.25)";
63361
63362    class ROI {
63363      constructor(config, genome) {
63364        this.config = config;
63365        this.name = config.name;
63366        this.roiSource = FeatureSource(config, genome);
63367        this.color = config.color || defaultHighlightColor;
63368      }
63369
63370      async getFeatures(chr, start, end) {
63371        return this.roiSource.getFeatures({
63372          chr,
63373          start,
63374          end
63375        });
63376      }
63377
63378      draw(drawConfiguration) {
63379        var endBP, region, coord, regions;
63380        regions = drawConfiguration.features;
63381
63382        if (!regions) {
63383          return;
63384        }
63385
63386        endBP = drawConfiguration.bpStart + (drawConfiguration.pixelWidth * drawConfiguration.bpPerPixel + 1);
63387
63388        for (var i = 0, len = regions.length; i < len; i++) {
63389          region = regions[i];
63390
63391          if (region.end < drawConfiguration.bpStart) {
63392            continue;
63393          }
63394
63395          if (region.start > endBP) {
63396            break;
63397          }
63398
63399          coord = coordinates(region, drawConfiguration.bpStart, drawConfiguration.bpPerPixel);
63400          IGVGraphics.fillRect(drawConfiguration.context, coord.x, drawConfiguration.pixelTop, coord.width, drawConfiguration.pixelHeight, {
63401            fillStyle: this.color
63402          });
63403        }
63404      }
63405
63406    }
63407
63408    function coordinates(region, startBP, bpp) {
63409      var ss, ee, width;
63410      ss = Math.round((region.start - startBP) / bpp);
63411      ee = Math.round((region.end - startBP) / bpp);
63412      width = ee - ss;
63413
63414      if (width < 3) {
63415        width = 3;
63416        ss -= 1;
63417      }
63418
63419      return {
63420        x: ss,
63421        width: width
63422      };
63423    }
63424
63425    /*
63426     * The MIT License (MIT)
63427     *
63428     * Copyright (c) 2016-2017 The Regents of the University of California
63429     * Author: Jim Robinson
63430     *
63431     * Permission is hereby granted, free of charge, to any person obtaining a copy
63432     * of this software and associated documentation files (the "Software"), to deal
63433     * in the Software without restriction, including without limitation the rights
63434     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
63435     * copies of the Software, and to permit persons to whom the Software is
63436     * furnished to do so, subject to the following conditions:
63437     *
63438     * The above copyright notice and this permission notice shall be included in
63439     * all copies or substantial portions of the Software.
63440     *
63441     *
63442     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63443     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63444     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
63445     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
63446     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
63447     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
63448     * THE SOFTWARE.
63449     */
63450
63451    /**
63452     * Minimal support for the legacy IGV desktop session format.
63453     */
63454    class XMLSession {
63455      constructor(xmlString, knownGenomes) {
63456        const parser = new DOMParser();
63457        const xmlDoc = parser.parseFromString(xmlString, "text/xml");
63458        this.processRootNode(xmlDoc, knownGenomes);
63459        const resourceElements = xmlDoc.getElementsByTagName("Resource");
63460        const trackElements = xmlDoc.getElementsByTagName("Track");
63461        const hasTrackElements = trackElements && trackElements.length > 0;
63462        const tracks = [];
63463        this.tracks = tracks;
63464        const resourceMap = new Map();
63465        Array.from(resourceElements).forEach(function (r, idx) {
63466          var config = {
63467            url: r.getAttribute("path"),
63468            indexURL: r.getAttribute("index"),
63469            order: idx
63470          };
63471          resourceMap.set(config.url, config);
63472
63473          if (!hasTrackElements) {
63474            tracks.push(config);
63475          }
63476        }); // Check for optional Track section
63477
63478        if (hasTrackElements) {
63479          Array.from(trackElements).forEach(function (track) {
63480            const subtracks = track.getElementsByTagName("Track");
63481
63482            if (subtracks && subtracks.length > 0) {
63483              const mergedTrack = {
63484                type: 'merged',
63485                tracks: []
63486              };
63487              extractTrackAttributes(track, mergedTrack);
63488              tracks.push(mergedTrack);
63489              Array.from(subtracks).forEach(function (t) {
63490                t.processed = true;
63491                const id = t.getAttribute("id");
63492                const config = resourceMap.get(id);
63493
63494                if (config) {
63495                  mergedTrack.tracks.push(config);
63496                  extractTrackAttributes(t, config);
63497                  config.autoscale = false;
63498                  mergedTrack.height = config.height; // Add alpha for merged track colors.  Alpha is not recorded by IGV desktop in XML session
63499                  //const color = t.getAttribute("color");
63500                  //if (color) {
63501                  //    config.color = "rgba(" + color + ",0.5)";
63502                  //}
63503                }
63504              });
63505            } else if (!track.processed) {
63506              const id = track.getAttribute("id");
63507              const res = resourceMap.get(id);
63508
63509              if (res) {
63510                tracks.push(res);
63511                extractTrackAttributes(track, res);
63512              }
63513            }
63514          });
63515        }
63516      }
63517
63518      processRootNode(xmlDoc, knownGenomes) {
63519        const elements = xmlDoc.getElementsByTagName("Session");
63520
63521        if (!elements || elements.length === 0) ;
63522
63523        const session = elements.item(0);
63524        const genome = session.getAttribute("genome");
63525        const locus = session.getAttribute("locus");
63526        const ucscID = session.getAttribute("ucscID");
63527
63528        if (knownGenomes && knownGenomes.hasOwnProperty(genome)) {
63529          this.genome = genome;
63530        } else {
63531          this.reference = {
63532            fastaURL: genome
63533          };
63534
63535          if (ucscID) {
63536            this.reference.id = ucscID;
63537          }
63538        }
63539
63540        if (locus) {
63541          this.locus = locus;
63542        }
63543      }
63544
63545    }
63546
63547    function extractTrackAttributes(track, config) {
63548      config.name = track.getAttribute("name");
63549      const color = track.getAttribute("color");
63550
63551      if (color) {
63552        config.color = "rgb(" + color + ")";
63553      }
63554
63555      const altColor = track.getAttribute("altColor");
63556
63557      if (color) {
63558        config.altColor = "rgb(" + altColor + ")";
63559      }
63560
63561      const height = track.getAttribute("height");
63562
63563      if (height) {
63564        config.height = parseInt(height);
63565      }
63566
63567      const autoScale = track.getAttribute("autoScale");
63568
63569      if (autoScale) {
63570        config.autoscale = autoScale === "true";
63571      }
63572
63573      const autoscaleGroup = track.getAttribute("autoscaleGroup");
63574
63575      if (autoscaleGroup) {
63576        config.autoscaleGroup = autoscaleGroup;
63577      }
63578
63579      const windowFunction = track.getAttribute("windowFunction");
63580
63581      if (windowFunction) {
63582        config.windowFunction = windowFunction;
63583      }
63584
63585      const visWindow = track.getAttribute("visibilityWindow") || track.getAttribute("featureVisibilityWindow");
63586
63587      if (visWindow) {
63588        config.visibilityWindow = visWindow;
63589      }
63590
63591      const indexed = track.getAttribute("indexed");
63592
63593      if (indexed) {
63594        config.indexed = indexed === "true";
63595      }
63596
63597      const normalize = track.getAttribute("normalize");
63598
63599      if (normalize) {
63600        config.normalize = normalize === "true";
63601      }
63602
63603      const dataRangeCltn = track.getElementsByTagName("DataRange");
63604
63605      if (dataRangeCltn.length > 0) {
63606        const dataRange = dataRangeCltn.item(0);
63607        config.min = Number(dataRange.getAttribute("minimum"));
63608        config.max = Number(dataRange.getAttribute("maximum"));
63609        config.logScale = dataRange.getAttribute("type") === "LOG";
63610      }
63611    }
63612
63613    /*
63614     * The MIT License (MIT)
63615     *
63616     * Copyright (c) 2014-2015 Broad Institute
63617     *
63618     * Permission is hereby granted, free of charge, to any person obtaining a copy
63619     * of this software and associated documentation files (the "Software"), to deal
63620     * in the Software without restriction, including without limitation the rights
63621     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
63622     * copies of the Software, and to permit persons to whom the Software is
63623     * furnished to do so, subject to the following conditions:
63624     *
63625     * The above copyright notice and this permission notice shall be included in
63626     * all copies or substantial portions of the Software.
63627     *
63628     *
63629     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63630     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63631     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
63632     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
63633     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
63634     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
63635     * THE SOFTWARE.
63636     */
63637    const splitLines = splitLines$5;
63638
63639    class SampleInformation {
63640      constructor() {
63641        this.attributes = {};
63642        this.plinkLoaded = false;
63643      }
63644
63645      async loadPlinkFile(url, config) {
63646        if (!config) config = {};
63647        var options = buildOptions(config); // Add oauth token, if any
63648
63649        const data = await igvxhr.loadString(url, options);
63650        var lines = splitLines(data);
63651
63652        for (let line of lines) {
63653          var line_arr = line.split(' ');
63654          this.attributes[line_arr[1]] = {
63655            familyId: line_arr[0],
63656            fatherId: line_arr[2],
63657            motherId: line_arr[3],
63658            sex: line_arr[4],
63659            phenotype: line_arr[5]
63660          };
63661        }
63662
63663        this.plinkLoaded = true;
63664        return this;
63665      }
63666      /**
63667       * Return the attributes for the given sample as a map-like object (key-value pairs)
63668       * @param sample
63669       */
63670
63671
63672      getAttributes(sample) {
63673        return this.attributes[sample];
63674      }
63675
63676      getAttributeNames() {
63677        if (this.hasAttributes()) {
63678          return Object.keys(this.attributes[Object.keys(this.attributes)[0]]);
63679        } else return [];
63680      }
63681
63682      hasAttributes() {
63683        return Object.keys(this.attributes).length > 0;
63684      }
63685
63686    }
63687
63688    function loadPlinkFile(url, config) {
63689      const si = new SampleInformation();
63690      return si.loadPlinkFile(url, config);
63691    }
63692
63693    /*
63694     * The MIT License (MIT)
63695     *
63696     * Copyright (c) 2014 Broad Institute
63697     *
63698     * Permission is hereby granted, free of charge, to any person obtaining a copy
63699     * of this software and associated documentation files (the "Software"), to deal
63700     * in the Software without restriction, including without limitation the rights
63701     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
63702     * copies of the Software, and to permit persons to whom the Software is
63703     * furnished to do so, subject to the following conditions:
63704     *
63705     * The above copyright notice and this permission notice shall be included in
63706     * all copies or substantial portions of the Software.
63707     *
63708     *
63709     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63710     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63711     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
63712     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
63713     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
63714     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
63715     * THE SOFTWARE.
63716     */
63717    class GtexSelection {
63718      constructor(gene, snp) {
63719        this.geneColors = {};
63720        this.gene = null;
63721        this.snp = null;
63722        this.genesCount = 0;
63723
63724        if (gene) {
63725          this.gene = gene.toUpperCase();
63726          this.geneColors[this.gene] = brewer[this.genesCount++];
63727        }
63728
63729        if (snp) {
63730          this.snp = snp.toUpperCase();
63731        }
63732      }
63733
63734      addGene(geneName) {
63735        if (!this.geneColors[geneName.toUpperCase()]) {
63736          this.geneColors[geneName.toUpperCase()] = brewer[this.genesCount++];
63737        }
63738      }
63739
63740      colorForGene(geneName) {
63741        return this.geneColors[geneName.toUpperCase()];
63742      }
63743
63744    }
63745
63746    var brewer = []; // Set +!
63747
63748    brewer.push("rgb(228,26,28)");
63749    brewer.push("rgb(55,126,184)");
63750    brewer.push("rgb(77,175,74)");
63751    brewer.push("rgb(166,86,40)");
63752    brewer.push("rgb(152,78,163)");
63753    brewer.push("rgb(255,127,0)");
63754    brewer.push("rgb(247,129,191)");
63755    brewer.push("rgb(153,153,153)");
63756    brewer.push("rgb(255,255,51)"); // #Set 2
63757
63758    brewer.push("rgb(102, 194, 165");
63759    brewer.push("rgb(252, 141, 98");
63760    brewer.push("rgb(141, 160, 203");
63761    brewer.push("rgb(231, 138, 195");
63762    brewer.push("rgb(166, 216, 84");
63763    brewer.push("rgb(255, 217, 47");
63764    brewer.push("rgb(229, 196, 148");
63765    brewer.push("rgb(179, 179, 179"); //#Set 3
63766
63767    brewer.push("rgb( 141, 211, 199");
63768    brewer.push("rgb(255, 255, 179");
63769    brewer.push("rgb(190, 186, 218");
63770    brewer.push("rgb(251, 128, 114");
63771    brewer.push("rgb(128, 177, 211");
63772    brewer.push("rgb(253, 180, 98");
63773    brewer.push("rgb(179, 222, 105");
63774    brewer.push("rgb(252, 205, 229");
63775    brewer.push("rgb(217, 217, 217");
63776    brewer.push("rgb(188, 128, 189");
63777    brewer.push("rgb(204, 235, 197");
63778    brewer.push("rgb(255, 237, 111");
63779
63780    /*
63781     * The MIT License (MIT)
63782     *
63783     * Copyright (c) 2014 Broad Institute
63784     *
63785     * Permission is hereby granted, free of charge, to any person obtaining a copy
63786     * of this software and associated documentation files (the "Software"), to deal
63787     * in the Software without restriction, including without limitation the rights
63788     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
63789     * copies of the Software, and to permit persons to whom the Software is
63790     * furnished to do so, subject to the following conditions:
63791     *
63792     * The above copyright notice and this permission notice shall be included in
63793     * all copies or substantial portions of the Software.
63794     *
63795     *
63796     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63797     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63798     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
63799     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
63800     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
63801     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
63802     * THE SOFTWARE.
63803     */
63804
63805    class ReferenceFrame {
63806      constructor(genome, chr, start, end, bpPerPixel) {
63807        this.genome = genome;
63808        this.chr = chr;
63809        this.start = start; // TODO WARNING THIS IS NOT UPDATED !!!
63810
63811        this.end = end;
63812        this.bpPerPixel = bpPerPixel;
63813        this.id = guid$1();
63814      }
63815
63816      calculateEnd(pixels) {
63817        return this.start + this.bpPerPixel * pixels;
63818      }
63819
63820      calculateBPP(end, pixels) {
63821        return (end - this.start) / pixels;
63822      }
63823
63824      set(json) {
63825        this.chr = json.chr;
63826        this.start = json.start;
63827        this.bpPerPixel = json.bpPerPixel;
63828      }
63829
63830      toPixels(bp) {
63831        return bp / this.bpPerPixel;
63832      }
63833
63834      toBP(pixels) {
63835        return this.bpPerPixel * pixels;
63836      }
63837      /**
63838       * Shift frame by stated pixels.  Return true if view changed, false if not.
63839       * @param pixels
63840       * @param viewportWidth
63841       */
63842
63843
63844      shiftPixels(pixels, viewportWidth) {
63845        const currentStart = this.start;
63846        const deltaBP = pixels * this.bpPerPixel;
63847        this.start += deltaBP;
63848        this.clampStart(viewportWidth);
63849        this.end += deltaBP;
63850        const {
63851          bpLength
63852        } = this.genome.getChromosome(this.chr);
63853        this.end = Math.min(bpLength, this.end);
63854        return currentStart !== this.start;
63855      }
63856
63857      clampStart(viewportWidth) {
63858        // clamp left
63859        const min = this.genome.getChromosome(this.chr).bpStart || 0;
63860        this.start = Math.max(min, this.start); // clamp right
63861
63862        if (viewportWidth) {
63863          const {
63864            bpLength
63865          } = this.genome.getChromosome(this.chr);
63866          const maxStart = bpLength - viewportWidth * this.bpPerPixel;
63867
63868          if (this.start > maxStart) {
63869            this.start = maxStart;
63870          }
63871        }
63872      }
63873
63874      async zoomWithScaleFactor(browser, scaleFactor, viewportWidth, centerBPOrUndefined) {
63875        const centerBP = undefined === centerBPOrUndefined ? this.start + this.toBP(viewportWidth / 2.0) : centerBPOrUndefined; // save initial start and bpp
63876
63877        const {
63878          start,
63879          bpPerPixel
63880        } = this.start;
63881        const {
63882          bpLength
63883        } = this.getChromosome();
63884        const bppThreshold = scaleFactor < 1.0 ? browser.minimumBases() / viewportWidth : bpLength / viewportWidth; // update bpp
63885
63886        if (scaleFactor < 1.0) {
63887          this.bpPerPixel = Math.max(this.bpPerPixel * scaleFactor, bppThreshold);
63888        } else {
63889          this.bpPerPixel = Math.min(this.bpPerPixel * scaleFactor, bppThreshold);
63890        } // update start and end
63891
63892
63893        const widthBP = this.bpPerPixel * viewportWidth;
63894        this.start = centerBP - 0.5 * widthBP;
63895        this.clampStart(viewportWidth);
63896        this.end = this.start + widthBP;
63897        const viewChanged = start !== this.start || bpPerPixel !== this.bpPerPixel;
63898
63899        if (viewChanged) {
63900          await browser.updateViews(this);
63901        }
63902      }
63903
63904      getChromosome() {
63905        return this.genome.getChromosome(this.chr);
63906      }
63907
63908      getMultiLocusLabel(pixels) {
63909        const margin = '&nbsp';
63910        const space = '&nbsp &nbsp &nbsp';
63911        const ss = Math.floor(this.start) + 1;
63912        const ee = Math.round(this.start + this.bpPerPixel * pixels);
63913        return `${margin}${this.chr}${space}${prettyBasePairNumber(ee - ss)}${margin}`;
63914      }
63915
63916      getPresentationLocusComponents(pixels) {
63917        if ('all' === this.chr) {
63918          return {
63919            chr: this.chr
63920          };
63921        } else {
63922          const ss = numberFormatter$1(Math.floor(this.start) + 1);
63923          const ee = numberFormatter$1(Math.round(this.start + this.bpPerPixel * pixels));
63924          return {
63925            chr: this.chr,
63926            start: ss,
63927            end: ee
63928          };
63929        }
63930      }
63931
63932      getLocusString() {
63933        if ('all' === this.chr) {
63934          return 'all';
63935        } else {
63936          const ss = numberFormatter$1(Math.floor(this.start) + 1);
63937          const ee = numberFormatter$1(Math.round(this.end));
63938          return `${this.chr}:${ss}-${ee}`;
63939        }
63940      }
63941
63942      description(blurb) {
63943        console.log(` ${blurb || ''} referenceFrame - ${this.chr} bpp ${this.bpPerPixel.toFixed(3)} start ${numberFormatter$1(Math.round(this.start))} end ${numberFormatter$1(Math.round(this.end))} `);
63944      }
63945
63946    }
63947
63948    function createReferenceFrameList(loci, genome, browserFlanking, minimumBases, viewportWidth) {
63949      return loci.map(locus => {
63950        // If a flanking region is defined, and the search object is a symbol ("gene") type, adjust start and end
63951        if (browserFlanking && locus.gene) {
63952          locus.start = Math.max(0, locus.start - browserFlanking);
63953          locus.end += browserFlanking;
63954        } // Validate the range.  This potentionally modifies start & end of locus.
63955
63956
63957        const chromosome = genome.getChromosome(locus.chr);
63958        validateLocusExtent(chromosome.bpLength, locus, minimumBases);
63959        const referenceFrame = new ReferenceFrame(genome, locus.chr, locus.start, locus.end, (locus.end - locus.start) / viewportWidth);
63960        referenceFrame.locusSearchString = locus.locusSearchString; // GTEX hack
63961
63962        if (locus.gene || locus.snp) {
63963          referenceFrame.selection = new GtexSelection(locus.gene, locus.snp);
63964        }
63965
63966        return referenceFrame;
63967      });
63968    }
63969
63970    function adjustReferenceFrame(scaleFactor, referenceFrame, viewportWidth, alignmentStart, alignmentLength) {
63971      referenceFrame.bpPerPixel *= scaleFactor;
63972      const alignmentEE = alignmentStart + alignmentLength;
63973      const alignmentCC = (alignmentStart + alignmentEE) / 2;
63974      referenceFrame.start = alignmentCC - referenceFrame.bpPerPixel * (viewportWidth / 2);
63975      referenceFrame.end = referenceFrame.start + referenceFrame.bpPerPixel * viewportWidth;
63976      referenceFrame.locusSearchString = referenceFrame.getLocusString();
63977    }
63978
63979    function createReferenceFrameWithAlignment(genome, chromosomeName, bpp, viewportWidth, alignmentStart, alignmentLength) {
63980      const alignmentEE = alignmentStart + alignmentLength;
63981      const alignmentCC = (alignmentStart + alignmentEE) / 2;
63982      const ss = alignmentCC - bpp * (viewportWidth / 2);
63983      const ee = ss + bpp * viewportWidth;
63984      return new ReferenceFrame(genome, chromosomeName, ss, ee, bpp);
63985    }
63986
63987    const defaultNucleotideColors = {
63988      "A": "rgb(  0, 200,   0)",
63989      "C": "rgb(  0,0,200)",
63990      "T": "rgb(255,0,0)",
63991      "G": "rgb(209,113,  5)",
63992      "N": "rgb(80,80,80)"
63993    };
63994
63995    const DEFAULT_SEARCH_CONFIG = {
63996      timeout: 5000,
63997      type: "plain",
63998      // Legacy plain text support -- deprecated
63999      url: 'https://igv.org/genomes/locus.php?genome=$GENOME$&name=$FEATURE$',
64000      coords: 0,
64001      chromosomeField: "chromosome",
64002      startField: "start",
64003      endField: "end",
64004      geneField: "gene",
64005      snpField: "snp"
64006    };
64007    /**
64008     * Return an object representing the locus of the given string.  Object is of the form
64009     * {
64010     *   chr,
64011     *   start,
64012     *   end,
64013     *   locusSearchString,
64014     *   gene,
64015     *   snp
64016     * }
64017     * @param browser
64018     * @param string
64019     * @returns {Promise<*>}
64020     */
64021
64022    async function search(browser, string) {
64023      if (undefined === string || '' === string.trim()) {
64024        return;
64025      }
64026
64027      if (string && string.trim().toLowerCase() === "all" || string === "*") {
64028        string = "all";
64029      }
64030
64031      const loci = string.split(' ');
64032      let searchConfig = browser.searchConfig || DEFAULT_SEARCH_CONFIG;
64033      let list = [];
64034
64035      const searchLocus = async locus => {
64036        let locusObject = parseLocusString(browser, locus);
64037
64038        if (!locusObject) {
64039          const feature = browser.genome.featureDB[locus.toUpperCase()];
64040
64041          if (feature) {
64042            locusObject = {
64043              chr: feature.chr,
64044              start: feature.start,
64045              end: feature.end,
64046              gene: feature.name,
64047              locusSearchString: string
64048            };
64049          }
64050        }
64051
64052        if (!locusObject && browser.config && false !== browser.config.search) {
64053          try {
64054            locusObject = await searchWebService(browser, locus, searchConfig);
64055          } catch (error) {
64056            console.error(error);
64057            throw Error("Search service currently unavailable.");
64058          }
64059        }
64060
64061        return locusObject;
64062      };
64063
64064      for (let locus of loci) {
64065        const locusObject = await searchLocus(locus);
64066
64067        if (locusObject) {
64068          locusObject.locusSearchString = locus;
64069          list.push(locusObject);
64070        }
64071      } // If nothing is found, consider possibility that loci name itself has spaces
64072
64073
64074      if (list.length === 0) {
64075        const locusObject = await searchLocus(string);
64076
64077        if (locusObject) {
64078          locusObject.locusSearchString = string;
64079          list.push(locusObject);
64080        }
64081      }
64082
64083      return 0 === list.length ? undefined : list;
64084    }
64085
64086    function parseLocusString(browser, locus) {
64087      const a = locus.split(':');
64088      const chr = a[0];
64089
64090      if ('all' === chr && browser.genome.getChromosome(chr)) {
64091        return {
64092          chr,
64093          start: 0,
64094          end: browser.genome.getChromosome(chr).bpLength
64095        };
64096      } else if (undefined === browser.genome.getChromosome(chr)) {
64097        return undefined;
64098      } else {
64099        const queryChr = browser.genome.getChromosomeName(chr);
64100        const extent = {
64101          chr: queryChr,
64102          start: 0,
64103          end: browser.genome.getChromosome(chr).bpLength
64104        };
64105
64106        if (a.length > 1) {
64107          const b = a[1].split('-');
64108
64109          if (b.length > 2) {
64110            return undefined;
64111          } else {
64112            let numeric;
64113            numeric = b[0].replace(/,/g, '');
64114
64115            if (isNaN(numeric)) {
64116              return undefined;
64117            }
64118
64119            extent.start = parseInt(numeric, 10) - 1;
64120            extent.end = extent.start + 1;
64121
64122            if (1 === b.length) {
64123              extent.start -= 20;
64124              extent.end += 20;
64125            }
64126
64127            if (2 === b.length) {
64128              numeric = b[1].replace(/,/g, '');
64129
64130              if (isNaN(numeric)) {
64131                return undefined;
64132              } else {
64133                extent.end = parseInt(numeric, 10);
64134              }
64135            }
64136          }
64137        }
64138
64139        return extent;
64140      }
64141    }
64142
64143    async function searchWebService(browser, locus, searchConfig) {
64144      let path = searchConfig.url.replace("$FEATURE$", locus.toUpperCase());
64145
64146      if (path.indexOf("$GENOME$") > -1) {
64147        path = path.replace("$GENOME$", browser.genome.id ? browser.genome.id : "hg19");
64148      }
64149
64150      const options = searchConfig.timeout ? {
64151        timeout: searchConfig.timeout
64152      } : undefined;
64153      const result = await igvxhr.loadString(path, options);
64154      const locusObject = processSearchResult(browser, result, searchConfig);
64155
64156      if (locusObject) {
64157        locusObject.locusSearchString = locus;
64158      }
64159
64160      return locusObject;
64161    }
64162
64163    function processSearchResult(browser, result, searchConfig) {
64164      let results;
64165
64166      if ('plain' === searchConfig.type) {
64167        results = parseSearchResults(browser, result);
64168      } else {
64169        results = JSON.parse(result);
64170      }
64171
64172      if (searchConfig.resultsField) {
64173        results = results[searchConfig.resultsField];
64174      }
64175
64176      if (!results || 0 === results.length) {
64177        return undefined;
64178      } else {
64179        const chromosomeField = searchConfig.chromosomeField || "chromosome";
64180        const startField = searchConfig.startField || "start";
64181        const endField = searchConfig.endField || "end";
64182        const coords = searchConfig.coords || 1;
64183        let result;
64184
64185        if (Array.isArray(results)) {
64186          // Ignoring all but first result for now
64187          // TODO -- present all and let user select if results.length > 1
64188          result = results[0];
64189        } else {
64190          // When processing search results from Ensembl REST API
64191          // Example: https://rest.ensembl.org/lookup/symbol/macaca_fascicularis/BRCA2?content-type=application/json
64192          result = results;
64193        }
64194
64195        if (!(result.hasOwnProperty(chromosomeField) && result.hasOwnProperty(startField))) {
64196          console.error("Search service results must include chromosome and start fields: " + result);
64197        }
64198
64199        const chrResult = result[chromosomeField];
64200        const chromosome = browser.genome.getChromosome(chrResult);
64201
64202        if (!chromosome) {
64203          return undefined;
64204        }
64205
64206        const chr = chromosome.name;
64207        let start = result[startField] - coords;
64208        let end = result[endField];
64209
64210        if (undefined === end) {
64211          end = start + 1;
64212        }
64213
64214        const locusObject = {
64215          chr,
64216          start,
64217          end
64218        }; // Some GTEX hacks
64219
64220        const type = result.type ? result.type : "gene";
64221
64222        if (searchConfig.geneField && type === "gene") {
64223          locusObject.gene = result[searchConfig.geneField];
64224        }
64225
64226        if (searchConfig.snpField && type === "snp") {
64227          locusObject.snp = result[searchConfig.snpField];
64228        }
64229
64230        return locusObject;
64231      }
64232    }
64233    /**
64234     * Parse the igv line-oriented (non json) search results.
64235     * Example
64236     *    EGFR    chr7:55,086,724-55,275,031    refseq
64237     *
64238     */
64239
64240
64241    function parseSearchResults(browser, data) {
64242      const linesTrimmed = [];
64243      const results = [];
64244      const lines = splitLines$5(data);
64245      lines.forEach(function (item) {
64246        if ("" === item) ; else {
64247          linesTrimmed.push(item);
64248        }
64249      });
64250      linesTrimmed.forEach(function (line) {
64251        var tokens = line.split("\t"),
64252            source,
64253            locusTokens,
64254            rangeTokens,
64255            obj;
64256
64257        if (tokens.length >= 3) {
64258          locusTokens = tokens[1].split(":");
64259          rangeTokens = locusTokens[1].split("-");
64260          source = tokens[2].trim();
64261          obj = {
64262            gene: tokens[0],
64263            chromosome: browser.genome.getChromosomeName(locusTokens[0].trim()),
64264            start: parseInt(rangeTokens[0].replace(/,/g, '')),
64265            end: parseInt(rangeTokens[1].replace(/,/g, '')),
64266            type: "gtex" === source ? "snp" : "gene"
64267          };
64268          results.push(obj);
64269        }
64270      });
64271      return results;
64272    } // Export some functions for unit testing
64273
64274    /*
64275     * The MIT License (MIT)
64276     *
64277     * Copyright (c) 2014 Broad Institute
64278     *
64279     * Permission is hereby granted, free of charge, to any person obtaining a copy
64280     * of this software and associated documentation files (the "Software"), to deal
64281     * in the Software without restriction, including without limitation the rights
64282     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64283     * copies of the Software, and to permit persons to whom the Software is
64284     * furnished to do so, subject to the following conditions:
64285     *
64286     * The above copyright notice and this permission notice shall be included in
64287     * all copies or substantial portions of the Software.
64288     *
64289     *
64290     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64291     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64292     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
64293     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
64294     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
64295     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64296     * THE SOFTWARE.
64297     */
64298
64299    class NavbarManager {
64300      constructor(browser) {
64301        this.browser = browser;
64302      }
64303
64304      navbarDidResize(width, isWholeGenomeView) {
64305        this.updateNavbar(this.createResponsiveClassSchedule(width, isWholeGenomeView));
64306      }
64307
64308      updateNavbar(responsiveClassSchedule) {
64309        this.browser.$toggle_button_container.removeClass();
64310        this.browser.$toggle_button_container.addClass(responsiveClassSchedule.$toggle_button_container);
64311        $$1(this.browser.zoomWidget.zoomContainer).removeClass();
64312        $$1(this.browser.zoomWidget.zoomContainer).addClass(responsiveClassSchedule.zoomContainer);
64313      }
64314
64315      createResponsiveClassSchedule(navbarWidth, isWholeGenomeView) {
64316        let candidates = {};
64317
64318        if (isWholeGenomeView) {
64319          this.browser.windowSizePanel.hide();
64320        } else {
64321          this.browser.windowSizePanel.show();
64322        }
64323
64324        if (navbarWidth > 990) {
64325          candidates.$toggle_button_container = 'igv-navbar-toggle-button-container';
64326          candidates.zoomContainer = 'igv-zoom-widget';
64327        } else if (navbarWidth > 860) {
64328          candidates.$toggle_button_container = 'igv-navbar-toggle-button-container';
64329          candidates.zoomContainer = 'igv-zoom-widget-900';
64330        } else if (navbarWidth > 540) {
64331          candidates.$toggle_button_container = 'igv-navbar-toggle-button-container-750';
64332          candidates.zoomContainer = 'igv-zoom-widget-900';
64333        } else {
64334          candidates.$toggle_button_container = 'igv-navbar-toggle-button-container-750';
64335          candidates.zoomContainer = 'igv-zoom-widget-900';
64336          this.browser.windowSizePanel.hide();
64337        }
64338
64339        if (isWholeGenomeView) {
64340          candidates['zoomContainer'] = 'igv-zoom-widget-hidden';
64341        }
64342
64343        return candidates;
64344      }
64345
64346    }
64347
64348    /*
64349     * The MIT License (MIT)
64350     *
64351     * Copyright (c) 2016-2017 The Regents of the University of California
64352     * Author: Jim Robinson
64353     *
64354     * Permission is hereby granted, free of charge, to any person obtaining a copy
64355     * of this software and associated documentation files (the "Software"), to deal
64356     * in the Software without restriction, including without limitation the rights
64357     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64358     * copies of the Software, and to permit persons to whom the Software is
64359     * furnished to do so, subject to the following conditions:
64360     *
64361     * The above copyright notice and this permission notice shall be included in
64362     * all copies or substantial portions of the Software.
64363     *
64364     *
64365     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64366     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64367     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
64368     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
64369     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
64370     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64371     * THE SOFTWARE.
64372     */
64373
64374    const ChromosomeSelectWidget = function (browser, parent) {
64375      this.container = div$1({
64376        class: 'igv-chromosome-select-widget-container'
64377      });
64378      parent.appendChild(this.container);
64379      this.select = document.createElement('select');
64380      this.select.setAttribute('name', 'chromosome-select-widget');
64381      this.container.appendChild(this.select);
64382      this.select.addEventListener('change', () => {
64383        this.select.blur();
64384
64385        if (this.select.value !== '') {
64386          browser.search(this.select.value);
64387        }
64388      });
64389      this.showAllChromosomes = browser.config.showAllChromosomes !== false; // i.e. default to true
64390    };
64391
64392    ChromosomeSelectWidget.prototype.show = function () {
64393      this.container.style.display = 'flex';
64394    };
64395
64396    ChromosomeSelectWidget.prototype.hide = function () {
64397      this.container.style.display = 'none';
64398    };
64399
64400    ChromosomeSelectWidget.prototype.update = function (genome) {
64401      const list = this.showAllChromosomes ? genome.chromosomeNames.slice() : genome.wgChromosomeNames.slice(); // console.log(`${ this.showAllChromosomes ? 'Do' : 'Do not'} show all chromosomes. List ${ list }`)
64402
64403      if (genome.showWholeGenomeView()) {
64404        list.unshift('all');
64405        list.unshift('');
64406      }
64407
64408      this.select.innerHTML = '';
64409
64410      for (let name of list) {
64411        const option = document.createElement('option');
64412        option.setAttribute('value', name);
64413        option.innerText = name;
64414        this.select.appendChild(option);
64415      }
64416    };
64417
64418    /*
64419     * The MIT License (MIT)
64420     *
64421     * Copyright (c) 2014 Broad Institute
64422     *
64423     * Permission is hereby granted, free of charge, to any person obtaining a copy
64424     * of this software and associated documentation files (the "Software"), to deal
64425     * in the Software without restriction, including without limitation the rights
64426     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64427     * copies of the Software, and to permit persons to whom the Software is
64428     * furnished to do so, subject to the following conditions:
64429     *
64430     * The above copyright notice and this permission notice shall be included in
64431     * all copies or substantial portions of the Software.
64432     *
64433     *
64434     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64435     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64436     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
64437     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
64438     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
64439     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64440     * THE SOFTWARE.
64441     */
64442
64443    class WindowSizePanel {
64444      constructor(parent, browser) {
64445        this.container = div$1({
64446          class: 'igv-windowsize-panel-container'
64447        });
64448        parent.appendChild(this.container);
64449        browser.on('locuschange', referenceFrameList => {
64450          this.updatePanel(referenceFrameList);
64451        });
64452        this.browser = browser;
64453      }
64454
64455      show() {
64456        this.container.style.display = 'block';
64457      }
64458
64459      hide() {
64460        this.container.style.display = 'none';
64461      }
64462
64463      updatePanel(referenceFrameList) {
64464        const width = this.browser.calculateViewportWidth(this.browser.referenceFrameList.length);
64465        this.container.innerText = 1 === referenceFrameList.length ? prettyBasePairNumber(Math.round(width * referenceFrameList[0].bpPerPixel)) : '';
64466      }
64467
64468    }
64469
64470    /*
64471     * The MIT License (MIT)
64472     *
64473     * Copyright (c) 2016 University of California San Diego
64474     * Author: Jim Robinson
64475     *
64476     * Permission is hereby granted, free of charge, to any person obtaining a copy
64477     * of this software and associated documentation files (the "Software"), to deal
64478     * in the Software without restriction, including without limitation the rights
64479     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64480     * copies of the Software, and to permit persons to whom the Software is
64481     * furnished to do so, subject to the following conditions:
64482     *
64483     * The above copyright notice and this permission notice shall be included in
64484     * all copies or substantial portions of the Software.
64485     *
64486     *
64487     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64488     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64489     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
64490     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
64491     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
64492     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64493     * THE SOFTWARE.
64494     */
64495
64496    class CursorGuide {
64497      constructor(columnContainer, browser) {
64498        this.browser = browser;
64499        this.columnContainer = columnContainer;
64500        this.horizontalGuide = div$1({
64501          class: 'igv-cursor-guide-horizontal'
64502        });
64503        columnContainer.appendChild(this.horizontalGuide);
64504        this.verticalGuide = div$1({
64505          class: 'igv-cursor-guide-vertical'
64506        });
64507        columnContainer.appendChild(this.verticalGuide);
64508        this.addMouseHandler(browser);
64509        this.setVisibility(browser.config.showCursorTrackingGuide);
64510      }
64511
64512      addMouseHandler(browser) {
64513        this.boundMouseMoveHandler = mouseMoveHandler.bind(this);
64514        this.columnContainer.addEventListener('mousemove', this.boundMouseMoveHandler);
64515
64516        function mouseMoveHandler(event) {
64517          const {
64518            x,
64519            y
64520          } = translateMouseCoordinates$1(event, this.columnContainer);
64521          this.horizontalGuide.style.top = `${y}px`;
64522          const target = document.elementFromPoint(event.clientX, event.clientY);
64523          let viewport = undefined;
64524
64525          if (target.parentElement.classList.contains('igv-viewport-content')) {
64526            viewport = target.parentElement.parentElement;
64527          } else if (target.parentElement.classList.contains('igv-viewport') && target.classList.contains('igv-viewport-content')) {
64528            viewport = target.parentElement;
64529          }
64530
64531          if (viewport && browser.getRulerTrackView()) {
64532            this.verticalGuide.style.left = `${x}px`;
64533            const columns = browser.root.querySelectorAll('.igv-column');
64534            let index = undefined;
64535            const viewportParent = viewport.parentElement;
64536
64537            for (let i = 0; i < columns.length; i++) {
64538              if (undefined === index && viewportParent === columns[i]) {
64539                index = i;
64540              }
64541            }
64542
64543            const rulerViewport = browser.getRulerTrackView().viewports[index];
64544            const result = rulerViewport.mouseMove(event);
64545
64546            if (result) {
64547              const {
64548                start,
64549                bp,
64550                end
64551              } = result;
64552              const interpolant = (bp - start) / (end - start);
64553
64554              if (this.customMouseHandler) {
64555                this.customMouseHandler({
64556                  start,
64557                  bp,
64558                  end,
64559                  interpolant
64560                });
64561              }
64562            }
64563          }
64564        }
64565      }
64566
64567      removeMouseHandler() {
64568        this.columnContainer.removeEventListener('mousemove', this.boundMouseMoveHandler);
64569      }
64570
64571      setVisibility(showCursorTrackingGuide) {
64572        if (true === showCursorTrackingGuide) {
64573          this.show();
64574        } else {
64575          this.hide();
64576        }
64577      }
64578
64579      show() {
64580        this.verticalGuide.style.display = 'block';
64581        this.horizontalGuide.style.display = 'block';
64582      }
64583
64584      hide() {
64585        this.verticalGuide.style.display = 'none';
64586        this.horizontalGuide.style.display = 'none';
64587
64588        if (this.browser.getRulerTrackView()) {
64589          for (let viewport of this.browser.getRulerTrackView().viewports) {
64590            viewport.$tooltip.hide();
64591          }
64592        }
64593      }
64594
64595    }
64596
64597    /*
64598     * The MIT License (MIT)
64599     *
64600     * Copyright (c) 2016 University of California San Diego
64601     * Author: Jim Robinson
64602     *
64603     * Permission is hereby granted, free of charge, to any person obtaining a copy
64604     * of this software and associated documentation files (the "Software"), to deal
64605     * in the Software without restriction, including without limitation the rights
64606     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64607     * copies of the Software, and to permit persons to whom the Software is
64608     * furnished to do so, subject to the following conditions:
64609     *
64610     * The above copyright notice and this permission notice shall be included in
64611     * all copies or substantial portions of the Software.
64612     *
64613     *
64614     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64615     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64616     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
64617     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
64618     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
64619     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64620     * THE SOFTWARE.
64621     */
64622
64623    class CursorGuideButton {
64624      constructor(browser, parent) {
64625        this.browser = browser;
64626        this.button = div$1({
64627          class: 'igv-navbar-button'
64628        });
64629        parent.appendChild(this.button);
64630        this.button.textContent = 'cursor guide';
64631        this.button.addEventListener('click', () => {
64632          browser.cursorGuideVisible = !browser.cursorGuideVisible;
64633          browser.setCursorGuideVisibility(browser.cursorGuideVisible);
64634          this.setButtonState(browser.cursorGuideVisible);
64635        });
64636        this.setButtonState(browser.cursorGuideVisible);
64637
64638        if (browser.config.showCursorTrackingGuideButton) {
64639          this.show();
64640        } else {
64641          this.hide();
64642        }
64643      }
64644
64645      setButtonState(cursorGuideVisible) {
64646        if (true === cursorGuideVisible) {
64647          this.button.classList.add('igv-navbar-button-clicked');
64648        } else {
64649          this.button.classList.remove('igv-navbar-button-clicked');
64650        }
64651      }
64652
64653      show() {
64654        this.button.style.display = 'block';
64655        this.setButtonState(this.browser.cursorGuideVisible);
64656      }
64657
64658      hide() {
64659        this.button.style.display = 'none';
64660      }
64661
64662    }
64663
64664    class CenterLineButton {
64665      constructor(browser, parent) {
64666        this.browser = browser;
64667        this.button = div$1({
64668          class: 'igv-navbar-button'
64669        });
64670        parent.appendChild(this.button);
64671        this.button.textContent = 'center line';
64672        this.button.addEventListener('click', () => {
64673          browser.isCenterLineVisible = !browser.isCenterLineVisible;
64674          browser.setCenterLineVisibility(browser.isCenterLineVisible);
64675   
64675       this.setButtonState(browser.isCenterLineVisible);
64676        });
64677        this.setButtonState(browser.isCenterLineVisible);
64678
64679        if (browser.config.showCenterGuideButton) {
64680          this.show();
64681        } else {
64682          this.hide();
64683        }
64684      }
64685
64686      setButtonState(isCenterLineVisible) {
64687        if (true === isCenterLineVisible) {
64688          this.button.classList.add('igv-navbar-button-clicked');
64689        } else {
64690          this.button.classList.remove('igv-navbar-button-clicked');
64691        }
64692      }
64693
64694      show() {
64695        this.isVisible = true;
64696        this.button.style.display = 'block';
64697        this.setButtonState(this.browser.isCenterLineVisible);
64698      }
64699
64700      hide() {
64701        this.isVisible = false;
64702        this.button.style.display = 'none';
64703      }
64704
64705    }
64706
64707    /*
64708     * The MIT License (MIT)
64709     *
64710     * Copyright (c) 2016 University of California San Diego
64711     * Author: Jim Robinson
64712     *
64713     * Permission is hereby granted, free of charge, to any person obtaining a copy
64714     * of this software and associated documentation files (the "Software"), to deal
64715     * in the Software without restriction, including without limitation the rights
64716     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64717     * copies of the Software, and to permit persons to whom the Software is
64718     * furnished to do so, subject to the following conditions:
64719     *
64720     * The above copyright notice and this permission notice shall be included in
64721     * all copies or substantial portions of the Software.
64722     *
64723     *
64724     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64725     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64726     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
64727     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
64728     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
64729     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64730     * THE SOFTWARE.
64731     */
64732
64733    const TrackLabelControl = function (parent, browser) {
64734      this.button = div$1({
64735        class: 'igv-navbar-button'
64736      });
64737      parent.appendChild(this.button);
64738      this.button.textContent = 'track labels';
64739      this.button.addEventListener('click', () => {
64740        browser.trackLabelsVisible = !browser.trackLabelsVisible;
64741        this.setState(browser.trackLabelsVisible);
64742        browser.setTrackLabelVisibility(browser.trackLabelsVisible);
64743      });
64744      this.browser = browser;
64745      this.setVisibility(browser.config.showTrackLabelButton);
64746      this.setState(browser.trackLabelsVisible);
64747    };
64748
64749    TrackLabelControl.prototype.setVisibility = function (showTrackLabelButton) {
64750      if (true === showTrackLabelButton) {
64751        this.show();
64752      } else {
64753        this.hide();
64754      }
64755    };
64756
64757    TrackLabelControl.prototype.setState = function (trackLabelsVisible) {
64758      if (true === trackLabelsVisible) {
64759        this.button.classList.add('igv-navbar-button-clicked');
64760      } else {
64761        this.button.classList.remove('igv-navbar-button-clicked');
64762      }
64763    };
64764
64765    TrackLabelControl.prototype.show = function () {
64766      this.button.style.display = 'block';
64767      this.setState(this.browser.trackLabelsVisible);
64768    };
64769
64770    TrackLabelControl.prototype.hide = function () {
64771      this.button.style.display = 'none';
64772    };
64773
64774    /*
64775     * The MIT License (MIT)
64776     *
64777     * Copyright (c) 2016 University of California San Diego
64778     * Author: Jim Robinson
64779     *
64780     * Permission is hereby granted, free of charge, to any person obtaining a copy
64781     * of this software and associated documentation files (the "Software"), to deal
64782     * in the Software without restriction, including without limitation the rights
64783     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64784     * copies of the Software, and to permit persons to whom the Software is
64785     * furnished to do so, subject to the following conditions:
64786     *
64787     * The above copyright notice and this permission notice shall be included in
64788     * all copies or substantial portions of the Software.
64789     *
64790     *
64791     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64792     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64793     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
64794     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
64795     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
64796     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64797     * THE SOFTWARE.
64798     */
64799
64800    class SampleNameControl {
64801      constructor(parent, browser) {
64802        this.button = div$1({
64803          class: 'igv-navbar-button'
64804        });
64805        parent.appendChild(this.button);
64806        this.button.innerText = 'Sample Names';
64807        this.setState(browser.showSampleNames);
64808        this.setVisibility(browser.showSampleNameButton);
64809        this.button.addEventListener('click', () => {
64810          browser.showSampleNames = !browser.showSampleNames;
64811          this.setState(browser.showSampleNames);
64812
64813          for (let {
64814            sampleNameViewport
64815          } of browser.trackViews) {
64816            if (false === browser.showSampleNames) {
64817              sampleNameViewport.hide();
64818            } else {
64819              sampleNameViewport.show();
64820            }
64821          }
64822
64823          browser.resize();
64824        });
64825      }
64826
64827      setVisibility(showSampleNameButton) {
64828        if (true === showSampleNameButton) {
64829          this.show();
64830        } else {
64831          this.hide();
64832        }
64833      }
64834
64835      setState(showSampleNames) {
64836        if (true === showSampleNames) {
64837          this.button.classList.add('igv-navbar-button-clicked');
64838        } else {
64839          this.button.classList.remove('igv-navbar-button-clicked');
64840        }
64841      }
64842
64843      hide() {
64844        this.button.style.display = 'none';
64845      }
64846
64847      show() {
64848        this.button.style.display = 'block';
64849      }
64850
64851    }
64852
64853    /*
64854     * The MIT License (MIT)
64855     *
64856     * Copyright (c) 2016 University of California San Diego
64857     * Author: Jim Robinson
64858     *
64859     * Permission is hereby granted, free of charge, to any person obtaining a copy
64860     * of this software and associated documentation files (the "Software"), to deal
64861     * in the Software without restriction, including without limitation the rights
64862     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
64863     * copies of the Software, and to permit persons to whom the Software is
64864     * furnished to do so, subject to the following conditions:
64865     *
64866     * The above copyright notice and this permission notice shall be included in
64867     * all copies or substantial portions of the Software.
64868     *
64869     *
64870     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64871     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64872     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
64873     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
64874     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
64875     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
64876     * THE SOFTWARE.
64877     */
64878    const sliderMin = 0;
64879    let sliderMax = 23;
64880    let sliderValueRaw = 0;
64881
64882    const ZoomWidget = function (browser, parent) {
64883      this.browser = browser;
64884      this.zoomContainer = div$1({
64885        class: 'igv-zoom-widget'
64886      });
64887      parent.appendChild(this.zoomContainer); // zoom out
64888
64889      this.zoomOutButton = div$1();
64890      this.zoomContainer.appendChild(this.zoomOutButton);
64891      this.zoomOutButton.appendChild(createIcon$1('minus-circle'));
64892      this.zoomOutButton.addEventListener('click', () => {
64893        // browser.zoomWithScaleFactor(2.0)
64894        browser.zoomOut();
64895      }); // Range slider
64896
64897      const el = div$1();
64898      this.zoomContainer.appendChild(el);
64899      this.slider = document.createElement('input');
64900      this.slider.type = 'range';
64901      this.slider.min = `${sliderMin}`;
64902      this.slider.max = `${sliderMax}`;
64903      el.appendChild(this.slider);
64904      this.slider.addEventListener('change', e => {
64905        e.preventDefault();
64906        e.stopPropagation();
64907        const referenceFrame = browser.referenceFrameList[0];
64908        const {
64909          bpLength
64910        } = referenceFrame.genome.getChromosome(referenceFrame.chr);
64911        const {
64912          end,
64913          start
64914        } = referenceFrame;
64915        const extent = end - start; // bpLength/(end - start)
64916
64917        const scaleFactor = Math.pow(2, e.target.valueAsNumber); // (end - start) = bpLength/scaleFactor
64918
64919        const zoomedExtent = bpLength / scaleFactor; // console.log(`zoom-widget - slider ${ e.target.value } scaleFactor ${ scaleFactor } extent-zoomed ${ StringUtils.numberFormatter(Math.round(zoomedExtent)) }`)
64920
64921        browser.zoomWithScaleFactor(zoomedExtent / extent);
64922      }); // zoom in
64923
64924      this.zoomInButton = div$1();
64925      this.zoomContainer.appendChild(this.zoomInButton);
64926      this.zoomInButton.appendChild(createIcon$1('plus-circle'));
64927      this.zoomInButton.addEventListener('click', () => {
64928        // browser.zoomWithScaleFactor(0.5)
64929        browser.zoomIn();
64930      });
64931      browser.on('locuschange', referenceFrameList => {
64932        if (this.browser.isMultiLocusMode()) {
64933          this.disable();
64934        } else {
64935          this.enable();
64936          this.update(referenceFrameList);
64937        }
64938      });
64939    };
64940
64941    ZoomWidget.prototype.update = function (referenceFrameList) {
64942      const referenceFrame = referenceFrameList[0];
64943      const {
64944        bpLength
64945      } = referenceFrame.genome.getChromosome(referenceFrame.chr);
64946      const {
64947        start,
64948        end
64949      } = referenceFrame;
64950      sliderMax = Math.ceil(Math.log2(bpLength / this.browser.minimumBases()));
64951      this.slider.max = `${sliderMax}`;
64952      const scaleFactor = bpLength / (end - start);
64953      sliderValueRaw = Math.log2(scaleFactor);
64954      this.slider.value = `${Math.round(sliderValueRaw)}`;
64955      // console.log(`${ Date.now() } update - slider ${ this.slider.value } scaleFactor ${ Math.round(scaleFactor) } extent ${ StringUtils.numberFormatter(Math.round(extent)) }`)
64956      // console.log(`update - sliderMin ${ sliderMin } sliderValue ${ this.slider.value } sliderMax ${ sliderMax } scaleFactor ${ scaleFactor.toFixed(3) } derived-scaleFactor ${ derivedScalefactor.toFixed(3) }`)
64957    };
64958
64959    ZoomWidget.prototype.enable = function () {
64960      // this.zoomInButton.style.color = appleCrayonPalette[ 'steel' ];
64961      // this.zoomInButton.style.pointerEvents = 'auto';
64962      //
64963      // this.zoomOutButton.style.color = appleCrayonPalette[ 'steel' ];
64964      // this.zoomOutButton.style.pointerEvents = 'auto';
64965      this.slider.disabled = false;
64966    };
64967
64968    ZoomWidget.prototype.disable = function () {
64969      // this.zoomInButton.style.color = appleCrayonPalette[ 'silver' ];
64970      // this.zoomInButton.style.pointerEvents = 'none';
64971      //
64972      // this.zoomOutButton.style.color = appleCrayonPalette[ 'silver' ];
64973      // this.zoomOutButton.style.pointerEvents = 'none';
64974      this.slider.disabled = true;
64975    };
64976
64977    ZoomWidget.prototype.hide = function () {
64978      this.zoomContainer.style.display = 'none';
64979    };
64980
64981    ZoomWidget.prototype.show = function () {
64982      this.zoomContainer.style.display = 'block';
64983    };
64984
64985    ZoomWidget.prototype.hideSlider = function () {
64986      this.slider.style.display = 'none';
64987    };
64988
64989    ZoomWidget.prototype.showSlider = function () {
64990      this.slider.style.display = 'block';
64991    };
64992
64993    /*
64994     * The MIT License (MIT)
64995     *
64996     * Copyright (c) 2016 University of California San Diego
64997     * Author: Jim Robinson
64998     *
64999     * Permission is hereby granted, free of charge, to any person obtaining a copy
65000     * of this software and associated documentation files (the "Software"), to deal
65001     * in the Software without restriction, including without limitation the rights
65002     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
65003     * copies of the Software, and to permit persons to whom the Software is
65004     * furnished to do so, subject to the following conditions:
65005     *
65006     * The above copyright notice and this permission notice shall be included in
65007     * all copies or substantial portions of the Software.
65008     *
65009     *
65010     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
65011     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65012     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65013     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
65014     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
65015     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
65016     * THE SOFTWARE.
65017     */
65018
65019    const SVGSaveControl = function (parent, browser) {
65020      const button = div$1({
65021        class: 'igv-navbar-button'
65022      });
65023      parent.append(button);
65024      button.textContent = 'Save SVG';
65025      button.addEventListener('click', () => browser.saveSVGtoFile({}));
65026    };
65027
65028    const viewportColumnManager = {
65029      createColumns: (columnContainer, count) => {
65030        for (let i = 0; i < count; i++) {
65031          if (0 === i) {
65032            createColumn(columnContainer, 'igv-column');
65033          } else {
65034            columnContainer.appendChild(div$1({
65035              class: 'igv-column-shim'
65036            }));
65037            createColumn(columnContainer, 'igv-column');
65038          }
65039        }
65040      },
65041      removeColumnAtIndex: (i, column) => {
65042        const shim = 0 === i ? column.nextElementSibling : column.previousElementSibling;
65043        column.remove();
65044        shim.remove();
65045      },
65046      insertAfter: referenceElement => {
65047        const shim = div$1({
65048          class: 'igv-column-shim'
65049        });
65050        insertElementAfter(shim, referenceElement);
65051        const column = div$1({
65052          class: 'igv-column'
65053        });
65054        insertElementAfter(column, shim);
65055        return column;
65056      },
65057      insertBefore: (referenceElement, count) => {
65058        for (let i = 0; i < count; i++) {
65059          const column = div$1({
65060            class: 'igv-column'
65061          });
65062          insertElementBefore(column, referenceElement);
65063
65064          if (count > 1 && i > 0) {
65065            const columnShim = div$1({
65066              class: 'igv-column-shim'
65067            });
65068            insertElementBefore(columnShim, column);
65069          }
65070        }
65071      }
65072    };
65073
65074    /*
65075     * The MIT License (MIT)
65076     *
65077     * Copyright (c) 2016 University of California San Diego
65078     * Author: Jim Robinson
65079     *
65080     * Permission is hereby granted, free of charge, to any person obtaining a copy
65081     * of this software and associated documentation files (the "Software"), to deal
65082     * in the Software without restriction, including without limitation the rights
65083     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
65084     * copies of the Software, and to permit persons to whom the Software is
65085     * furnished to do so, subject to the following conditions:
65086     *
65087     * The above copyright notice and this permission notice shall be included in
65088     * all copies or substantial portions of the Software.
65089     *
65090     *
65091     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
65092     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65093     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65094     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
65095     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
65096     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
65097     * THE SOFTWARE.
65098     */
65099
65100    class ViewportCenterLine {
65101      constructor(browser, referenceFrame, column) {
65102        this.browser = browser;
65103        this.referenceFrame = referenceFrame;
65104        this.column = column;
65105        this.container = div$1({
65106          class: 'igv-center-line'
65107        });
65108        column.appendChild(this.container);
65109
65110        if (browser.isCenterLineVisible) {
65111          this.show();
65112        } else {
65113          this.hide();
65114        }
65115      }
65116
65117      repaint() {
65118        const left = Math.floor(this.browser.calculateViewportWidth(this.browser.referenceFrameList.length) / 2);
65119
65120        if (this.referenceFrame) {
65121          const ppb = 1.0 / this.referenceFrame.bpPerPixel;
65122
65123          if (ppb > 1) {
65124            this.container.style.left = `${left}px`;
65125            this.container.style.width = `${Math.floor(this.referenceFrame.toPixels(1))}px`;
65126            this.container.classList.remove('igv-center-line-thin');
65127            this.container.classList.add('igv-center-line-wide');
65128          } else {
65129            this.container.style.left = `${left}px`;
65130            this.container.style.width = '1px';
65131            this.container.classList.remove('igv-center-line-wide');
65132            this.container.classList.add('igv-center-line-thin');
65133          }
65134        }
65135      }
65136
65137      show() {
65138        this.isVisible = true;
65139        this.container.style.display = 'block';
65140        this.repaint();
65141      }
65142
65143      hide() {
65144        this.isVisible = false;
65145        this.container.style.display = 'none';
65146      }
65147
65148      resize() {
65149        this.repaint();
65150      }
65151
65152    }
65153
65154    /*
65155     * The MIT License (MIT)
65156     *
65157     * Copyright (c) 2014 Broad Institute
65158     *
65159     * Permission is hereby granted, free of charge, to any person obtaining a copy
65160     * of this software and associated documentation files (the "Software"), to deal
65161     * in the Software without restriction, including without limitation the rights
65162     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
65163     * copies of the Software, and to permit persons to whom the Software is
65164     * furnished to do so, subject to the following conditions:
65165     *
65166     * The above copyright notice and this permission notice shall be included in
65167     * all copies or substantial portions of the Software.
65168     *
65169     *
65170     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
65171     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65172     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65173     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
65174     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
65175     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
65176     * THE SOFTWARE.
65177     */
65178    const numberFormatter = numberFormatter$1;
65179
65180    class RulerTrack {
65181      constructor(browser) {
65182        this.browser = browser;
65183        this.height = 40;
65184        this.name = "";
65185        this.id = "ruler";
65186        this.disableButtons = true;
65187        this.ignoreTrackMenu = true;
65188        this.order = Number.MIN_SAFE_INTEGER * 1e-2;
65189        this.removable = false;
65190        this.type = 'ruler';
65191      }
65192
65193      async getFeatures(chr, start, end) {
65194        return [];
65195      }
65196
65197      computePixelHeight(ignore) {
65198        return this.height;
65199      }
65200
65201      draw(_ref) {
65202        let {
65203          context,
65204          referenceFrame,
65205          pixelWidth,
65206          pixelHeight,
65207          bpPerPixel,
65208          bpStart
65209        } = _ref;
65210
65211        if (GenomeUtils.isWholeGenomeView(referenceFrame.chr)) {
65212          this.drawWholeGenome({
65213            context,
65214            pixelWidth,
65215            pixelHeight,
65216            bpPerPixel
65217          });
65218        } else {
65219          this.doDraw({
65220            context,
65221            referenceFrame,
65222            pixelWidth,
65223            pixelHeight,
65224            bpStart
65225          });
65226        }
65227      }
65228
65229      drawWholeGenome(_ref2) {
65230        let {
65231          context,
65232          pixelWidth,
65233          pixelHeight,
65234          bpPerPixel
65235        } = _ref2;
65236        context.save();
65237        IGVGraphics.fillRect(context, 0, 0, pixelWidth, pixelHeight, {
65238          'fillStyle': 'white'
65239        });
65240
65241        for (let name of this.browser.genome.wgChromosomeNames) {
65242          let xBP = this.browser.genome.getCumulativeOffset(name);
65243          let wBP = this.browser.genome.getChromosome(name).bpLength;
65244          let x = Math.round(xBP / bpPerPixel);
65245          let w = Math.round(wBP / bpPerPixel);
65246          this.renderChromosomeRect(context, x, 0, w, pixelHeight, name);
65247        }
65248
65249        context.restore();
65250      }
65251
65252      doDraw(_ref3) {
65253        let {
65254          context,
65255          referenceFrame,
65256          pixelWidth,
65257          pixelHeight,
65258          bpStart
65259        } = _ref3;
65260        context.clearRect(0, 0, pixelWidth, pixelHeight);
65261        const tickHeight = 6;
65262        const shim = 2;
65263        const bpLength = Math.floor(referenceFrame.toBP(pixelWidth));
65264        const tick = findSpacing(bpLength, context.isSVG);
65265        let nTick = Math.floor(bpStart / tick.majorTick) - 1;
65266        const {
65267          tickDelta,
65268          labelLength
65269        } = calculateDeltas(context, referenceFrame, bpStart, nTick, tick);
65270        this.browser.referenceFrameList.indexOf(referenceFrame); // console.log(`ruler(${ index }) label-length ${ labelLength > tickDelta ? 'clobbers' : 'less than' } tick-delta ${ StringUtils.numberFormatter(tickDelta)} `)
65271
65272        let xTick;
65273        let bp;
65274        let accumulatedTickDelta = tickDelta;
65275        const labelLengthShim = 0.25 * labelLength;
65276
65277        do {
65278          bp = Math.floor(nTick * tick.majorTick);
65279          const rulerLabel = `${numberFormatter$1(Math.floor(bp / tick.unitMultiplier))} ${tick.majorUnit}`;
65280          xTick = Math.round(referenceFrame.toPixels(bp - 1 - bpStart + 0.5));
65281          const xLabel = Math.round(xTick - context.measureText(rulerLabel).width / 2);
65282
65283          if (xLabel > 0 && labelLengthShim + labelLength <= accumulatedTickDelta) {
65284            IGVGraphics.fillText(context, rulerLabel, xLabel, this.height - tickHeight / 0.75);
65285            accumulatedTickDelta = 0;
65286          }
65287
65288          if (xTick > 0) {
65289            IGVGraphics.strokeLine(context, xTick, this.height - tickHeight, xTick, this.height - shim);
65290          }
65291
65292          bp = Math.floor((1 + nTick) * tick.majorTick);
65293          let pixel = Math.round(referenceFrame.toPixels(bp - 1 - bpStart + 0.5));
65294          let delta = (pixel - xTick) / 2;
65295          let xx = xTick + delta;
65296
65297          if (xx > 0) {
65298            IGVGraphics.strokeLine(context, xx, this.height - tickHeight, xx, this.height - shim);
65299          }
65300
65301          ++nTick;
65302          accumulatedTickDelta += tickDelta;
65303        } while (xTick < pixelWidth);
65304
65305        IGVGraphics.strokeLine(context, 0, this.height - shim, pixelWidth, this.height - shim);
65306      }
65307
65308      renderChromosomeRect(ctx, x, y, w, h, name) {
65309        ctx.textAlign = 'center';
65310        ctx.textBaseline = 'middle';
65311        ctx.font = '12px sans-serif';
65312        IGVGraphics.strokeLine(ctx, x + w, y, x + w, y + h, {
65313          strokeStyle: IGVColor.greyScale(191)
65314        });
65315        const shortName = name.startsWith("chr") ? name.substring(3) : name;
65316
65317        if (w > ctx.measureText(shortName).width) {
65318          IGVGraphics.fillText(ctx, shortName, x + w / 2, y + h / 2, {
65319            fillStyle: IGVColor.greyScale(68)
65320          });
65321        }
65322      }
65323
65324      supportsWholeGenome() {
65325        return true;
65326      }
65327
65328      dispose() {// do stuff
65329      }
65330
65331    }
65332
65333    function findSpacing(bpLength, isSVG) {
65334      if (bpLength < 10) {
65335        return new Tick(1, 'bp', 1);
65336      }
65337
65338      const nZeroes = Math.floor(Math.log10(bpLength));
65339      let majorUnit = 'bp';
65340      let unitMultiplier = 1;
65341
65342      if (nZeroes > 9) {
65343        majorUnit = 'gb';
65344        unitMultiplier = 1e9;
65345      } else if (nZeroes > 6) {
65346        majorUnit = 'mb';
65347        unitMultiplier = 1e6;
65348      } else if (nZeroes > 3) {
65349        majorUnit = 'kb';
65350        unitMultiplier = 1e3;
65351      }
65352
65353      const denom = Math.pow(10, nZeroes - 1);
65354      const nMajorTicks = bpLength / denom; // const threshold = 25
65355
65356      const threshold = 3 * 25;
65357      const belowThresholdTick = Math.pow(10, nZeroes - 1);
65358      const aboveThresholdTick = Math.pow(10, nZeroes) / 2; // console.log(`zeros ${ nZeroes } tick-threshold ${ threshold }
65358 ticks ${ nMajorTicks } belowTick ${ StringUtils.numberFormatter(belowThresholdTick) } aboveTick ${ StringUtils.numberFormatter(aboveThresholdTick) }`)
65359
65360      const majorTick = nMajorTicks < threshold && isSVG !== true ? belowThresholdTick : aboveThresholdTick;
65361      return new Tick(majorTick, majorUnit, unitMultiplier);
65362    }
65363
65364    function calculateDeltas(context, referenceFrame, bpStart, nTick, tick) {
65365      const tickDelta = getX(referenceFrame, getBP(1 + nTick, tick), bpStart) - getX(referenceFrame, getBP(nTick, tick), bpStart);
65366      const label = `${numberFormatter$1(Math.floor(getBP(nTick, tick) / tick.unitMultiplier))} ${tick.majorUnit}`;
65367      const labelLength = Math.floor(context.measureText(label).width);
65368      return {
65369        tickDelta,
65370        labelLength
65371      };
65372
65373      function getBP(nTick, tick) {
65374        return Math.floor(nTick * tick.majorTick);
65375      }
65376
65377      function getX(referenceFrame, bp, bpStart) {
65378        return Math.round(referenceFrame.toPixels(bp - 1 - bpStart + 0.5));
65379      }
65380    }
65381
65382    class Tick {
65383      constructor(majorTick, majorUnit, unitMultiplier) {
65384        this.majorTick = majorTick;
65385        this.minorTick = majorTick / 10.0;
65386        this.majorUnit = majorUnit;
65387        this.unitMultiplier = unitMultiplier;
65388      }
65389
65390      description(blurb) {
65391        console.log((blurb || '') + ' tick ' + numberFormatter(this.majorTick) + ' label width ' + numberFormatter(this.labelWidthBP) + ' multiplier ' + this.unitMultiplier);
65392      }
65393
65394    }
65395
65396    /*
65397     * The MIT License (MIT)
65398     *
65399     * Copyright (c) 2016 University of California San Diego
65400     * Author: Jim Robinson
65401     *
65402     * Permission is hereby granted, free of charge, to any person obtaining a copy
65403     * of this software and associated documentation files (the "Software"), to deal
65404     * in the Software without restriction, including without limitation the rights
65405     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
65406     * copies of the Software, and to permit persons to whom the Software is
65407     * furnished to do so, subject to the following conditions:
65408     *
65409     * The above copyright notice and this permission notice shall be included in
65410     * all copies or substantial portions of the Software.
65411     *
65412     *
65413     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
65414     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65415     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65416     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
65417     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
65418     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
65419     * THE SOFTWARE.
65420     */
65421
65422    const CircularViewControl = function (parent, browser) {
65423      this.button = div$1({
65424        class: 'igv-navbar-button'
65425      });
65426      parent.appendChild(this.button);
65427      this.button.textContent = 'circular view';
65428      this.button.addEventListener('click', () => {
65429        browser.circularViewVisible = !browser.circularViewVisible; //this.setState(browser.circularViewVisible)
65430      });
65431      this.browser = browser;
65432      this.setVisibility(browser.config.showCircularViewButton);
65433      this.setState(browser.circularViewVisible);
65434    };
65435
65436    CircularViewControl.prototype.setVisibility = function (showCircularViewButton) {
65437      if (true === showCircularViewButton) {
65438        this.show();
65439      } else {
65440        this.hide();
65441      }
65442    };
65443
65444    CircularViewControl.prototype.setState = function (circularViewVisible) {
65445      if (true === circularViewVisible) {
65446        this.button.classList.add('igv-navbar-button-clicked');
65447      } else {
65448        this.button.classList.remove('igv-navbar-button-clicked');
65449      }
65450    };
65451
65452    CircularViewControl.prototype.show = function () {
65453      this.button.style.display = 'block';
65454      this.setState(this.browser.circularViewVisible);
65455    };
65456
65457    CircularViewControl.prototype.hide = function () {
65458      this.button.style.display = 'none';
65459    };
65460
65461    /*
65462     * The MIT License (MIT)
65463     *
65464     * Copyright (c) 2014 Broad Institute
65465     *
65466     * Permission is hereby granted, free of charge, to any person obtaining a copy
65467     * of this software and associated documentation files (the "Software"), to deal
65468     * in the Software without restriction, including without limitation the rights
65469     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
65470     * copies of the Software, and to permit persons to whom the Software is
65471     * furnished to do so, subject to the following conditions:
65472     *
65473     * The above copyright notice and this permission notice shall be included in
65474     * all copies or substantial portions of the Software.
65475     *
65476     *
65477     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
65478     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65479     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65480     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
65481     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
65482     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
65483     * THE SOFTWARE.
65484     */
65485
65486    const igv_scrollbar_outer_width = 14; // css - $igv-track-drag-column-width: 12px;
65487
65488    const igv_track_manipulation_handle_width = 12; // css - $igv-track-gear-menu-column-width: 28px;
65489
65490    const igv_track_gear_menu_column_width = 28; // $igv-column-shim-width: 1px;
65491    // $igv-column-shim-margin: 2px;
65492
65493    const column_multi_locus_shim_width = 2 + 1 + 2;
65494    const defaultSampleNameViewportWidth = 200;
65495
65496    class Browser {
65497      constructor(config, parentDiv) {
65498        this.config = config;
65499        this.guid = guid$1();
65500        this.namespace = '.browser_' + this.guid;
65501        this.parent = parentDiv;
65502        this.root = div$1({
65503          class: 'igv-container'
65504        });
65505        parentDiv.appendChild(this.root);
65506        Alert.init(this.root);
65507        this.columnContainer = div$1({
65508          class: 'igv-column-container'
65509        });
65510        this.root.appendChild(this.columnContainer);
65511        this.menuPopup = new MenuPopup(this.columnContainer);
65512        this.initialize(config);
65513        this.trackViews = [];
65514        this.constants = {
65515          dragThreshold: 3,
65516          scrollThreshold: 5,
65517          defaultColor: "rgb(0,0,150)",
65518          doubleClickDelay: config.doubleClickDelay || 500
65519        }; // Map of event name -> [ handlerFn, ... ]
65520
65521        this.eventHandlers = {};
65522        this.addMouseHandlers();
65523        this.setControls(config);
65524      }
65525
65526      initialize(config) {
65527        if (config.gtex) {
65528          GtexUtils.gtexLoaded = true;
65529        }
65530
65531        this.flanking = config.flanking;
65532        this.crossDomainProxy = config.crossDomainProxy;
65533        this.formats = config.formats;
65534        this.trackDefaults = config.trackDefaults;
65535        this.nucleotideColors = config.nucleotideColors || defaultNucleotideColors;
65536
65537        for (let key of Object.keys(this.nucleotideColors)) {
65538          this.nucleotideColors[key.toLowerCase()] = this.nucleotideColors[key];
65539        }
65540
65541        this.trackLabelsVisible = config.showTrackLabels;
65542        this.isCenterLineVisible = config.showCenterGuide;
65543        this.cursorGuideVisible = config.showCursorTrackingGuide;
65544        this.showSampleNames = config.showSampleNames;
65545        this.showSampleNameButton = config.showSampleNameButton;
65546        this.sampleNameViewportWidth = config.sampleNameViewportWidth || defaultSampleNameViewportWidth;
65547
65548        if (config.search) {
65549          this.searchConfig = {
65550            type: "json",
65551            url: config.search.url,
65552            coords: config.search.coords === undefined ? 1 : config.search.coords,
65553            chromosomeField: config.search.chromosomeField || "chromosome",
65554            startField: config.search.startField || "start",
65555            endField: config.search.endField || "end",
65556            geneField: config.search.geneField || "gene",
65557            snpField: config.search.snpField || "snp",
65558            resultsField: config.search.resultsField
65559          };
65560        }
65561      }
65562
65563      setControls(config) {
65564        const $navBar = this.createStandardControls(config);
65565        $navBar.insertBefore($$1(this.columnContainer));
65566        this.$navigation = $navBar;
65567
65568        if (false === config.showControls) {
65569          $navBar.hide();
65570        }
65571      }
65572
65573      createStandardControls(config) {
65574        this.navbarManager = new NavbarManager(this);
65575        const $navBar = $$1('<div>', {
65576          class: 'igv-navbar'
65577        });
65578        this.$navigation = $navBar;
65579        const $navbarLeftContainer = $$1('<div>', {
65580          class: 'igv-navbar-left-container'
65581        });
65582        $navBar.append($navbarLeftContainer); // IGV logo
65583
65584        const $logo = $$1('<div>', {
65585          class: 'igv-logo'
65586        });
65587        $navbarLeftContainer.append($logo);
65588        const logoSvg = logo();
65589        logoSvg.css("width", "34px");
65590        logoSvg.css("height", "32px");
65591        $logo.append(logoSvg);
65592        this.$current_genome = $$1('<div>', {
65593          class: 'igv-current-genome'
65594        });
65595        $navbarLeftContainer.append(this.$current_genome);
65596        this.$current_genome.text('');
65597        const $genomicLocation = $$1('<div>', {
65598          class: 'igv-navbar-genomic-location'
65599        });
65600        $navbarLeftContainer.append($genomicLocation); // chromosome select widget
65601
65602        this.chromosomeSelectWidget = new ChromosomeSelectWidget(this, $genomicLocation.get(0));
65603
65604        if (undefined === config.showChromosomeWidget) {
65605          config.showChromosomeWidget = true; // Default to true
65606        }
65607
65608        if (true === config.showChromosomeWidget) {
65609          this.chromosomeSelectWidget.show();
65610        } else {
65611          this.chromosomeSelectWidget.hide();
65612        }
65613
65614        const $locusSizeGroup = $$1('<div>', {
65615          class: 'igv-locus-size-group'
65616        });
65617        $genomicLocation.append($locusSizeGroup);
65618        const $searchContainer = $$1('<div>', {
65619          class: 'igv-search-container'
65620        });
65621        $locusSizeGroup.append($searchContainer); // browser.$searchInput = $('<input type="text" placeholder="Locus Search">');
65622
65623        this.$searchInput = $$1('<input>', {
65624          class: 'igv-search-input',
65625          type: 'text',
65626          placeholder: 'Locus Search'
65627        });
65628        $searchContainer.append(this.$searchInput);
65629        this.$searchInput.change(() => this.doSearch(this.$searchInput.val()));
65630        const searchIconContainer = div$1({
65631          class: 'igv-search-icon-container'
65632        });
65633        $searchContainer.append($$1(searchIconContainer));
65634        searchIconContainer.appendChild(createIcon$1("search"));
65635        searchIconContainer.addEventListener('click', () => this.doSearch(this.$searchInput.val()));
65636        this.windowSizePanel = new WindowSizePanel($locusSizeGroup.get(0), this);
65637        const $navbarRightContainer = $$1('<div>', {
65638          class: 'igv-navbar-right-container'
65639        });
65640        $navBar.append($navbarRightContainer);
65641        const $toggle_button_container = $$1('<div class="igv-navbar-toggle-button-container">');
65642        $navbarRightContainer.append($toggle_button_container);
65643        this.$toggle_button_container = $toggle_button_container;
65644        this.cursorGuide = new CursorGuide(this.columnContainer, this);
65645        this.cursorGuideButton = new CursorGuideButton(this, $toggle_button_container.get(0));
65646        this.centerLineButton = new CenterLineButton(this, $toggle_button_container.get(0));
65647        this.setTrackLabelVisibility(config.showTrackLabels);
65648        this.trackLabelControl = new TrackLabelControl($toggle_button_container.get(0), this);
65649        this.sampleNameControl = new SampleNameControl($toggle_button_container.get(0), this);
65650
65651        if (true === config.showSVGButton) {
65652          this.svgSaveControl = new SVGSaveControl($toggle_button_container.get(0), this);
65653        }
65654
65655        this.zoomWidget = new ZoomWidget(this, $navbarRightContainer.get(0));
65656
65657        if (false === config.showNavigation) {
65658          this.$navigation.hide();
65659        }
65660
65661        this.inputDialog = new InputDialog(this.root);
65662        this.inputDialog.container.id = `igv-input-dialog-${guid$1()}`;
65663        this.dataRangeDialog = new DataRangeDialog($$1(this.root));
65664        this.dataRangeDialog.$container.get(0).id = `igv-data-range-dialog-${guid$1()}`;
65665        this.genericColorPicker = new GenericColorPicker({
65666          parent: this.columnContainer,
65667          width: 432
65668        });
65669        this.genericColorPicker.container.id = `igv-track-color-picker-${guid$1()}`;
65670        return $navBar;
65671      }
65672
65673      getSampleNameViewportWidth() {
65674        return false === this.showSampleNames ? 0 : this.sampleNameViewportWidth;
65675      }
65676
65677      isMultiLocusMode() {
65678        return this.referenceFrameList && this.referenceFrameList.length > 1;
65679      }
65680
65681      addTrackToFactory(name, track) {
65682        TrackFactory.addTrack(name, track);
65683      }
65684
65685      isMultiLocusWholeGenomeView() {
65686        if (undefined === this.referenceFrameList || 1 === this.referenceFrameList.length) {
65687          return false;
65688        }
65689
65690        for (let referenceFrame of this.referenceFrameList) {
65691          if ('all' === referenceFrame.chr.toLowerCase()) {
65692            return true;
65693          }
65694        }
65695
65696        return false;
65697      }
65698
65699      /**
65700       * Render browse display as SVG
65701       * @returns {string}
65702       */
65703      toSVG() {
65704        let {
65705          x,
65706          y,
65707          width,
65708          height
65709        } = this.columnContainer.getBoundingClientRect();
65710        const h_render = 8000;
65711        let context = new ctx({
65712          width,
65713          height: h_render,
65714          backdropColor: 'white',
65715          multiLocusGap: 0,
65716          viewbox: {
65717            x: 0,
65718            y: 0,
65719            width,
65720            height: h_render
65721          }
65722        });
65723
65724        for (let trackView of this.trackViews) {
65725          trackView.renderSVGContext(context, {
65726            deltaX: 0,
65727            deltaY: -y
65728          });
65729        } // reset height to trim away unneeded svg canvas real estate. Yes, a bit of a hack.
65730
65731
65732        context.setHeight(height);
65733        return context.getSerializedSvg(true);
65734      }
65735
65736      renderSVG($container) {
65737        const svg = this.toSVG();
65738        $container.empty();
65739        $container.append(svg);
65740        return svg;
65741      }
65742
65743      saveSVGtoFile(config) {
65744        let svg = this.toSVG();
65745
65746        if (config.$container) {
65747          config.$container.empty();
65748          config.$container.append(svg);
65749        }
65750
65751        const path = config.filename || 'igvjs.svg';
65752        const data = URL.createObjectURL(new Blob([svg], {
65753          type: "application/octet-stream"
65754        }));
65755        download(path, data);
65756      }
65757      /**
65758       * Initialize a session from an object, json, or by loading from a file.
65759       *
65760       * TODO Really should be split into at least 2 functions, load from file and load from object/json
65761       *
65762       * @param options
65763       * @returns {*}
65764       */
65765
65766
65767      async loadSession(options) {
65768        this.roi = [];
65769        let session;
65770
65771        if (options.url || options.file) {
65772          session = await loadSessionFile(options);
65773        } else {
65774          session = options;
65775        }
65776
65777        return this.loadSessionObject(session);
65778
65779        async function loadSessionFile(options) {
65780          const urlOrFile = options.url || options.file;
65781
65782          if (options.url && (options.url.startsWith("blob:") || options.url.startsWith("data:"))) {
65783            const json = Browser.uncompressSession(options.url);
65784            return JSON.parse(json);
65785          } else {
65786            let filename = options.filename;
65787
65788            if (!filename) {
65789              filename = options.url ? await getFilename(options.url) : options.file.name;
65790            }
65791
65792            if (filename.endsWith(".xml")) {
65793              const knownGenomes = GenomeUtils.KNOWN_GENOMES;
65794              const string = await igvxhr.loadString(urlOrFile);
65795              return new XMLSession(string, knownGenomes);
65796            } else if (filename.endsWith(".json")) {
65797              return igvxhr.loadJson(urlOrFile);
65798            } else {
65799              return undefined;
65800            }
65801          }
65802        }
65803      }
65804      /**
65805       * Note:  public API function
65806       * @param session
65807       * @returns {Promise<void>}
65808       */
65809
65810
65811      async loadSessionObject(session) {
65812        // prepare to load a new session, discarding DOM and state
65813        this.cleanHouseForSession();
65814        this.showSampleNames = session.showSampleNames || false;
65815        this.sampleNameControl.setState(this.showSampleNames === true);
65816
65817        if (session.sampleNameViewportWidth) {
65818          this.sampleNameViewportWidth = session.sampleNameViewportWidth;
65819        } // axis column
65820
65821
65822        createColumn(this.columnContainer, 'igv-axis-column'); // SampleName column
65823
65824        createColumn(this.columnContainer, 'igv-sample-name-column'); // Track scrollbar column
65825
65826        createColumn(this.columnContainer, 'igv-scrollbar-column'); // Track drag/reorder column
65827
65828        createColumn(this.columnContainer, 'igv-track-drag-column'); // Track gear column
65829
65830        createColumn(this.columnContainer, 'igv-gear-menu-column');
65831        const genomeConfig = await GenomeUtils.expandReference(session.reference || session.genome);
65832        await this.loadReference(genomeConfig, session.locus);
65833        this.centerLineList = this.createCenterLineList(this.columnContainer); // Create ideogram and ruler track.  Really this belongs in browser initialization, but creation is
65834        // deferred because ideogram and ruler are treated as "tracks", and tracks require a reference frame
65835
65836        if (false !== session.showIdeogram) {
65837          this.trackViews.push(new TrackView(this, this.columnContainer, new IdeogramTrack(this)));
65838        }
65839
65840        if (false !== session.showRuler) {
65841          this.trackViews.push(new TrackView(this, this.columnContainer, new RulerTrack(this)));
65842        } // Restore gtex selections.
65843
65844
65845        if (session.gtexSelections) {
65846          for (let referenceFrame of this.referenceFrameList) {
65847            for (let s of Object.keys(session.gtexSelections)) {
65848              const gene = session.gtexSelections[s].gene;
65849              const snp = session.gtexSelections[s].snp;
65850              referenceFrame.selection = new GtexSelection(gene, snp);
65851            }
65852          }
65853        }
65854
65855        if (session.roi) {
65856          this.roi = [];
65857
65858          for (let r of session.roi) {
65859            this.roi.push(new ROI(r, this.genome));
65860          }
65861        } // Tracks.  Start with genome tracks, if any, then append session tracks
65862
65863
65864        const genomeTracks = genomeConfig.tracks || [];
65865        const trackConfigurations = session.tracks ? genomeTracks.concat(session.tracks) : genomeTracks; // Insure that we always have a sequence track
65866
65867        const pushSequenceTrack = trackConfigurations.filter(track => track.type === 'sequence').length === 0;
65868
65869        if (pushSequenceTrack
65870        /*&& false !== this.config.showSequence*/
65871        ) {
65872          trackConfigurations.push({
65873            type: "sequence",
65874            order: defaultSequenceTrackOrder
65875          });
65876        } // Maintain track order unless explicitly set
65877
65878
65879        let trackOrder = 1;
65880
65881        for (let t of trackConfigurations) {
65882          if (undefined === t.order) {
65883            t.order = trackOrder++;
65884          }
65885        }
65886
65887        await this.loadTrackList(trackConfigurations);
65888        this.updateUIWithReferenceFrameList();
65889      }
65890
65891      createCenterLineList(columnContainer) {
65892        const centerLines = columnContainer.querySelectorAll('.igv-center-line');
65893
65894        for (let i = 0; i < centerLines.length; i++) {
65895          centerLines[i].remove();
65896        }
65897
65898        const centerLineList = [];
65899        const viewportColumns = columnContainer.querySelectorAll('.igv-column');
65900
65901        for (let i = 0; i < viewportColumns.length; i++) {
65902          centerLineList.push(new ViewportCenterLine(this, this.referenceFrameList[i], viewportColumns[i]));
65903        }
65904
65905        return centerLineList;
65906      }
65907      /**
65908       * Load a reference genome object.  This includes the fasta, and optional cytoband, but no tracks.  This method
65909       * is used by loadGenome and loadSession.
65910       *
65911       * @param genomeConfig
65912       * @param initialLocus
65913       */
65914
65915
65916      async loadReference(genomeConfig, initialLocus) {
65917        const genome = await GenomeUtils.loadGenome(genomeConfig);
65918        const genomeChange = undefined === this.genome || this.genome.id !== genome.id;
65919        this.genome = genome;
65920        this.updateNavbarDOMWithGenome(genome);
65921
65922        if (genomeChange) {
65923          this.removeAllTracks();
65924        }
65925
65926        let locus = getInitialLocus(initialLocus, genome);
65927        const locusFound = await this.search(locus, true);
65928
65929        if (!locusFound) {
65930          console.log("Initial locus not found: " + locus);
65931          locus = genome.getHomeChromosomeName();
65932          const locusFound = await this.search(locus, true);
65933
65934          if (!locusFound) {
65935            throw new Error("Cannot set initial locus");
65936          }
65937        }
65938
65939        if (genomeChange && this.circularView) {
65940          this.circularView.setAssembly({
65941            name: this.genome.id,
65942            id: this.genome.id,
65943            chromosomes: makeCircViewChromosomes(this.genome)
65944          });
65945        }
65946      }
65947
65948      cleanHouseForSession() {
65949        for (let trackView of this.trackViews) {
65950          // empty axis column, viewport columns, sampleName column, scroll column, drag column, gear column
65951          trackView.removeDOMFromColumnContainer();
65952        } // discard all columns
65953
65954
65955        const elements = this.columnContainer.querySelectorAll('.igv-axis-column, .igv-column-shim, .igv-column, .igv-sample-name-column, .igv-scrollbar-column, .igv-track-drag-column, .igv-gear-menu-column');
65956        elements.forEach(column => column.remove());
65957        this.trackViews = [];
65958
65959        if (this.circularView) {
65960          this.circularView.clearChords();
65961        }
65962      }
65963
65964      updateNavbarDOMWithGenome(genome) {
65965        this.$current_genome.text(genome.id || '');
65966        this.$current_genome.attr('title', genome.id || '');
65967        this.chromosomeSelectWidget.update(genome);
65968      }
65969      /**
65970       * Load a genome, defined by a string ID or a json-like configuration object. This includes a fasta reference
65971       * as well as optional cytoband and annotation tracks.
65972       *
65973       * @param idOrConfig
65974       * @returns genome
65975       */
65976
65977
65978      async loadGenome(idOrConfig) {
65979        const genomeConfig = await GenomeUtils.expandReference(idOrConfig);
65980        await this.loadReference(genomeConfig, undefined);
65981        const tracks = genomeConfig.tracks || []; // Insure that we always have a sequence track
65982
65983        const pushSequenceTrack = tracks.filter(track => track.type === 'sequence').length === 0;
65984
65985        if (pushSequenceTrack) {
65986          tracks.push({
65987            type: "sequence",
65988            order: defaultSequenceTrackOrder
65989          });
65990        }
65991
65992        await this.loadTrackList(tracks);
65993        await this.updateViews();
65994        return this.genome;
65995      }
65996      /**
65997       * Called after a session load, search, pan (horizontal drag), or resize
65998       *
65999       * @param referenceFrameList
66000       */
66001
66002
66003      updateUIWithReferenceFrameList() {
66004        const referenceFrameList = this.referenceFrameList;
66005        this.updateLocusSearchWidget();
66006        const isWGV = this.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr);
66007        this.navbarManager.navbarDidResize(this.$navigation.width(), isWGV);
66008        toggleTrackLabels(this.trackViews, this.trackLabelsVisible);
66009        this.setCenterLineAndCenterLineButtonVisibility(!GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr));
66010      }
66011
66012      setTrackLabelVisibility(isVisible) {
66013        toggleTrackLabels(this.trackViews, isVisible);
66014      } // cursor guide
66015
66016
66017      setCursorGuideVisibility(cursorGuideVisible) {
66018        if (cursorGuideVisible) {
66019          this.cursorGuide.show();
66020        } else {
66021          this.cursorGuide.hide();
66022        }
66023      }
66024
66025      setCustomCursorGuideMouseHandler(mouseHandler) {
66026        this.cursorGuide.customMouseHandler = mouseHandler;
66027      } // center line
66028
66029
66030      setCenterLineVisibility(isCenterLineVisible) {
66031        for (let centerLine of this.centerLineList) {
66032          if (true === isCenterLineVisible) {
66033            centerLine.show();
66034            centerLine.repaint();
66035          } else {
66036            centerLine.hide();
66037          }
66038        }
66039      }
66040
66041      setCenterLineAndCenterLineButtonVisibility(isCenterLineVisible) {
66042        for (let centerLine of this.centerLineList) {
66043          const isShown = isCenterLineVisible && centerLine.isVisible;
66044          isShown ? centerLine.show() : centerLine.container.style.display = 'none';
66045        }
66046
66047        const isShown = isCenterLineVisible && this.centerLineButton.isVisible;
66048        isShown ? this.centerLineButton.show() : this.centerLineButton.button.style.display = 'none';
66049      }
66050
66051      async loadTrackList(configList) {
66052        try {
66053          const promises = [];
66054
66055          for (let config of configList) {
66056            promises.push(this.loadTrack(config, false));
66057          }
66058
66059          const loadedTracks = await Promise.all(promises);
66060          const groupAutoscaleViews = this.trackViews.filter(function (trackView) {
66061            return trackView.track.autoscaleGroup;
66062          });
66063
66064          if (groupAutoscaleViews.length > 0) {
66065            this.updateViews(groupAutoscaleViews);
66066          }
66067
66068          return loadedTracks;
66069        } finally {
66070          await this.resize();
66071        }
66072      }
66073
66074      async loadROI(config) {
66075        if (!this.roi) {
66076          this.roi = [];
66077        }
66078
66079        if (Array.isArray(config)) {
66080          for (let c of config) {
66081            this.roi.push(new ROI(c, this.genome));
66082          }
66083        } else {
66084          this.roi.push(new ROI(config, this.genome));
66085        }
66086
66087        await this.updateViews(true);
66088      }
66089
66090      removeROI(roiToRemove) {
66091        for (let i = 0; i < this.roi.length; i++) {
66092          if (this.roi[i].name === roiToRemove.name) {
66093            this.roi.splice(i, 1);
66094            break;
66095          }
66096        }
66097
66098        for (let tv of this.trackViews) {
66099          tv.updateViews(true);
66100        }
66101      }
66102
66103      clearROIs() {
66104        this.roi = [];
66105
66106        for (let tv of this.trackViews) {
66107          tv.updateViews(true);
66108        }
66109      }
66110
66111      getRulerTrackView() {
66112        const list = this.trackViews.filter(_ref => {
66113          let {
66114            track
66115          } = _ref;
66116          return 'ruler' === track.id;
66117        });
66118        return list.length > 0 ? list[0] : undefined;
66119      }
66120      /**
66121       * Return a promise to load a track.
66122       *
66123       * Each track is associated with the following DOM elements
66124       *
66125       *      leftHandGutter  - div on the left for track controls and legend
66126       *      contentDiv  - a div element wrapping all the track content.  Height can be > viewportDiv height
66127       *      viewportDiv - a div element through which the track is viewed.  This might have a vertical scrollbar
66128       *      canvas     - canvas element upon which the track is drawn.  Child of contentDiv
66129       *
66130       * The width of all elements should be equal.  Height of the viewportDiv is controlled by the user, but never
66131       * greater than the contentDiv height.   Height of contentDiv and canvas are equal, and governed by the data
66132       * loaded.
66133       *
66134       *
66135       * @param config
66136       * @param doResize - undefined by default
66137       * @returns {*}
66138       */
66139
66140
66141      async loadTrack(config, doResize) {
66142        // config might be json
66143        if (isString$3(config)) {
66144          config = JSON.parse(config);
66145        }
66146
66147        try {
66148          const newTrack = await this.createTrack(config);
66149
66150          if (undefined === newTrack) {
66151            Alert.presentAlert(new Error(`Unknown file type: ${config.url || config}`), undefined);
66152            return newTrack;
66153          } // Set order field of track here.  Otherwise track order might get shuffled during asynchronous load
66154
66155
66156          if (undefined === newTrack.order) {
66157            newTrack.order = this.trackViews.length;
66158          }
66159
66160          const trackView = new TrackView(this, this.columnContainer, newTrack);
66161          this.trackViews.push(trackView);
66162          toggleTrackLabels(this.trackViews, this.trackLabelsVisible);
66163          this.reorderTracks();
66164          this.fireEvent('trackorderchanged', [this.getTrackOrder()]);
66165
66166          if (typeof newTrack.postInit === 'function') {
66167            try {
66168              trackView.startSpinner();
66169              await newTrack.postInit();
66170            } finally {
66171              trackView.stopSpinner();
66172            }
66173          }
66174
66175          if (!newTrack.autoscaleGroup) {
66176            // Group autoscale will get updated later (as a group)
66177            if (config.sync) {
66178              await trackView.updateViews();
66179            } else {
66180              trackView.updateViews();
66181            }
66182          }
66183
66184          if (typeof newTrack.hasSamples === 'function' && newTrack.hasSamples()) {
66185            if (this.config.showSampleNameButton !== false) {
66186              this.sampleNameControl.show(); // If not explicitly set
66187            }
66188          }
66189
66190          return newTrack;
66191        } catch (error) {
66192          const httpMessages = {
66193            "401": "Access unauthorized",
66194            "403": "Access forbidden",
66195            "404": "Not found"
66196          };
66197          console.error(error);
66198          let msg = error.message || error.error || error.toString();
66199
66200          if (httpMessages.hasOwnProperty(msg)) {
66201            msg = httpMessages[msg];
66202          }
66203
66204          msg += ": " + config.url;
66205          Alert.presentAlert(new Error(msg), undefined);
66206        } finally {
66207          // TODO: If loadTrack() is called individually - not via loadTrackList() - call this.resize()
66208          if (false === doResize) ; else {
66209            await this.resize();
66210          }
66211        }
66212      }
66213      /**
66214       * Create a Track object.
66215       * @param config
66216       * @returns {Promise<*>}
66217       */
66218
66219
66220      async createTrack(config) {
66221        // Resolve function and promise urls
66222        let url = await resolveURL(config.url);
66223
66224        if (isString$3(url)) {
66225          url = url.trim();
66226        }
66227
66228        if (url) {
66229          if (config.format) {
66230            config.format = config.format.toLowerCase();
66231          } else {
66232            let filename = config.filename;
66233
66234            if (!filename) {
66235              filename = await getFilename(url);
66236            }
66237
66238            config.format = inferFileFormat(filename);
66239
66240            if (!config.format && (config.sourceType === undefined || config.sourceType === "htsget")) {
66241              // Check for htsget URL.  This is a longshot
66242              await HtsgetReader.inferFormat(config);
66243            }
66244          }
66245        }
66246
66247        let type = config.type ? config.type.toLowerCase() : undefined;
66248
66249        if (!type) {
66250          type = inferTrackType(config);
66251
66252          if ("bedtype" === type) {
66253            // Bed files must be read to determine track type
66254            const featureSource = FeatureSource(config, this.genome);
66255            config._featureSource = featureSource; // This is a temp variable, bit of a hack
66256
66257            const trackType = await featureSource.trackType();
66258
66259            if (trackType) {
66260              type = trackType;
66261            } else {
66262              type = "annotation";
66263            }
66264          } // Record in config to make type persistent in session
66265
66266
66267          config.type = type;
66268        } // Set defaults if specified
66269
66270
66271        if (this.trackDefaults && type) {
66272          const settings = this.trackDefaults[type];
66273
66274          if (settings) {
66275            for (let property in settings) {
66276              if (settings.hasOwnProperty(property) && config[property] === undefined) {
66277                config[property] = settings[property];
66278              }
66279            }
66280          }
66281        }
66282
66283        const track = TrackFactory.getTrack(type, config, this);
66284
66285        if (track && config.roi) {
66286          track.roi = [];
66287
66288          for (let r of config.roi) {
66289            track.roi.push(new ROI(r, this.genome));
66290          }
66291        }
66292
66293        return track;
66294      }
66295
66296      reorderTracks() {
66297        this.trackViews.sort(function (a, b) {
66298          const firstSortOrder = tv => {
66299            return 'ideogram' === tv.track.id ? 1 : 'ruler' === tv.track.id ? 2 : 3;
66300          };
66301
66302          const aOrder1 = firstSortOrder(a);
66303          const bOrder1 = firstSortOrder(b);
66304
66305          if (aOrder1 === bOrder1) {
66306            const aOrder2 = a.track.order || 0;
66307            const bOrder2 = b.track.order || 0;
66308            return aOrder2 - bOrder2;
66309          } else {
66310            return aOrder1 - bOrder1;
66311          }
66312        }); // discard current track order
66313
66314        for (let {
66315          axis,
66316          viewports,
66317          sampleNameViewport,
66318          outerScroll,
66319          dragHandle,
66320          gearContainer
66321        } of this.trackViews) {
66322          axis.remove();
66323
66324          for (let {
66325            $viewport
66326          } of viewports) {
66327            $viewport.detach();
66328          }
66329
66330          sampleNameViewport.viewport.remove();
66331          outerScroll.remove();
66332          dragHandle.remove();
66333          gearContainer.remove();
66334        } // Reattach the divs to the dom in the correct order
66335
66336
66337        const viewportColumns = this.columnContainer.querySelectorAll('.igv-column');
66338
66339        for (let {
66340          axis,
66341          viewports,
66342          sampleNameViewport,
66343          outerScroll,
66344          dragHandle,
66345          gearContainer
66346        } of this.trackViews) {
66347          this.columnContainer.querySelector('.igv-axis-column').appendChild(axis);
66348
66349          for (let i = 0; i < viewportColumns.length; i++) {
66350            const {
66351              $viewport
66352            } = viewports[i];
66353            viewportColumns[i].appendChild($viewport.get(0));
66354          }
66355
66356          this.columnContainer.querySelector('.igv-sample-name-column').appendChild(sampleNameViewport.viewport);
66357          this.columnContainer.querySelector('.igv-scrollbar-column').appendChild(outerScroll);
66358          this.columnContainer.querySelector('.igv-track-drag-column').appendChild(dragHandle);
66359          this.columnContainer.querySelector('.igv-gear-menu-column').appendChild(gearContainer);
66360        }
66361      }
66362
66363      getTrackOrder() {
66364        return this.trackViews.filter(tv => tv.track && tv.track.name).map(tv => tv.track.name);
66365      }
66366
66367      removeTrackByName(name) {
66368        const copy = this.trackViews.slice();
66369
66370        for (let trackView of copy) {
66371          if (name === trackView.track.name) {
66372            this.removeTrack(trackView.track);
66373          }
66374        }
66375      }
66376
66377      removeTrack(track) {
66378        this.trackViews.splice(this.trackViews.indexOf(track.trackView), 1);
66379        this.fireEvent('trackremoved', [track]);
66380        this.fireEvent('trackorderchanged', [this.getTrackOrder()]);
66381        track.trackView.dispose();
66382      }
66383      /**
66384       * API function
66385       */
66386
66387
66388      removeAllTracks() {
66389        const remainingTrackViews = [];
66390
66391        for (let trackView of this.trackViews) {
66392          if (trackView.track.id !== 'ruler' && trackView.track.id !== 'ideogram') {
66393            this.fireEvent('trackremoved', [trackView.track]);
66394            trackView.dispose();
66395          } else {
66396            remainingTrackViews.push(trackView);
66397          }
66398        }
66399
66400        this.trackViews = remainingTrackViews;
66401      }
66402      /**
66403       *
66404       * @param property
66405       * @param value
66406       * @returns {Array}  tracks with given property value.  e.g. findTracks("type", "annotation")
66407       */
66408
66409
66410      findTracks(property, value) {
66411        let f = typeof property === 'function' ? trackView => property(trackView.track) : trackView => value === trackView.track[property];
66412        return this.trackViews.filter(f).map(tv => tv.track);
66413      }
66414      /**
66415       * Set the track height globally for all tracks.  (Note: Its not clear why this is useful).
66416       * @param newHeight
66417       */
66418
66419
66420      setTrackHeight(newHeight) {
66421        this.trackHeight = newHeight;
66422        this.trackViews.forEach(function (trackView) {
66423          trackView.setTrackHeight(newHeight);
66424        });
66425      }
66426
66427      async visibilityChange() {
66428        const status = this.referenceFrameList.find(referenceFrame => referenceFrame.bpPerPixel < 0);
66429
66430        if (status) {
66431          const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);
66432
66433          for (let referenceFrame of this.referenceFrameList) {
66434            referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / viewportWidth;
66435          }
66436        }
66437
66438        if (this.referenceFrameList) {
66439          const isWGV = this.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(this.referenceFrameList[0].chr);
66440          this.navbarManager.navbarDidResize(this.$navigation.width(), isWGV);
66441        }
66442
66443        await this.resize();
66444      }
66445
66446      async resize() {
66447        const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);
66448
66449        for (let referenceFrame of this.referenceFrameList) {
66450          const index = this.referenceFrameList.indexOf(referenceFrame);
66451          const {
66452            chr,
66453            genome
66454          } = referenceFrame;
66455          const {
66456            bpLength
66457          } = genome.getChromosome(referenceFrame.chr);
66458          const viewportWidthBP = referenceFrame.toBP(viewportWidth); // viewportWidthBP > bpLength occurs when locus is full chromosome and user widens browser
66459
66460          if (GenomeUtils.isWholeGenomeView(chr) || viewportWidthBP > bpLength) {
66461            // console.log(`${ Date.now() }
66461 Recalc referenceFrame(${ index }) bpp. viewport ${ StringUtils.numberFormatter(viewportWidthBP) } > ${ StringUtils.numberFormatter(bpLength) }.`)
66462            referenceFrame.bpPerPixel = bpLength / viewportWidth;
66463          } else {
66464            // console.log(`${ Date.now() } Recalc referenceFrame(${ index }) end.`)
66465            referenceFrame.end = referenceFrame.start + referenceFrame.toBP(viewportWidth);
66466          }
66467
66468          for (let {
66469            viewports
66470          } of this.trackViews) {
66471            viewports[index].setWidth(viewportWidth);
66472          }
66473        }
66474
66475        await this.updateViews(true);
66476        this.updateUIWithReferenceFrameList();
66477      }
66478
66479      async updateViews(force) {
66480        const trackViews = this.trackViews;
66481        this.updateLocusSearchWidget();
66482
66483        for (let centerGuide of this.centerLineList) {
66484          centerGuide.repaint();
66485        } // Don't autoscale while dragging.
66486
66487
66488        if (this.dragObject) {
66489          for (let trackView of trackViews) {
66490            await trackView.updateViews(force);
66491          }
66492        } else {
66493          // Group autoscale
66494          const groupAutoscaleTracks = {};
66495          const otherTracks = [];
66496
66497          for (let trackView of trackViews) {
66498            const group = trackView.track.autoscaleGroup;
66499
66500            if (group) {
66501              var l = groupAutoscaleTracks[group];
66502
66503              if (!l) {
66504                l = [];
66505                groupAutoscaleTracks[group] = l;
66506              }
66507
66508              l.push(trackView);
66509            } else {
66510              otherTracks.push(trackView);
66511            }
66512          }
66513
66514          if (Object.entries(groupAutoscaleTracks).length > 0) {
66515            const keys = Object.keys(groupAutoscaleTracks);
66516
66517            for (let group of keys) {
66518              const groupTrackViews = groupAutoscaleTracks[group];
66519              const promises = [];
66520
66521              for (let trackView of groupTrackViews) {
66522                promises.push(trackView.getInViewFeatures());
66523              }
66524
66525              const featureArray = await Promise.all(promises);
66526              var allFeatures = [],
66527                  dataRange;
66528
66529              for (let features of featureArray) {
66530                allFeatures = allFeatures.concat(features);
66531              }
66532
66533              dataRange = doAutoscale(allFeatures);
66534              const p = [];
66535
66536              for (let trackView of groupTrackViews) {
66537                trackView.track.dataRange = dataRange;
66538                trackView.track.autoscale = false;
66539                p.push(trackView.updateViews(force));
66540              }
66541
66542              await Promise.all(p);
66543            }
66544          }
66545
66546          await Promise.all(otherTracks.map(tv => tv.updateViews(force))); // for (let trackView of otherTracks) {
66547          //     await trackView.updateViews(force);
66548          // }
66549        }
66550      }
66551
66552      updateLocusSearchWidget() {
66553        const referenceFrameList = this.referenceFrameList; // Update end position of reference frames based on pixel widths.  This is hacky, but its been done here
66554        // for a long time, although indirectly.
66555
66556        const width = this.calculateViewportWidth(this.referenceFrameList.length);
66557
66558        for (let referenceFrame of referenceFrameList) {
66559          referenceFrame.end = referenceFrame.start + referenceFrame.bpPerPixel * width;
66560        }
66561
66562        this.chromosomeSelectWidget.select.value = referenceFrameList.length === 1 ? this.referenceFrameList[0].chr : '';
66563        const loc = this.referenceFrameList.map(rf => rf.getLocusString()).join(' '); //const loc = this.referenceFrameList.length === 1 ?   this.referenceFrameList[0].getLocusString() : '';
66564
66565        this.$searchInput.val(loc);
66566        this.fireEvent('locuschange', [this.referenceFrameList]);
66567      }
66568
66569      calculateViewportWidth(columnCount) {
66570        let {
66571          width
66572        } = this.columnContainer.getBoundingClientRect();
66573        const sampleNameViewportWidth = this.getSampleNameViewportWidth();
66574        width -= igv_axis_column_width + sampleNameViewportWidth + igv_scrollbar_outer_width + igv_track_manipulation_handle_width + igv_track_gear_menu_column_width;
66575        width -= column_multi_locus_shim_width * (columnCount - 1);
66576        return Math.floor(width / columnCount);
66577      }
66578
66579      getCenterLineXOffset() {
66580        let {
66581          width: columnContainerWidth
66582        } = this.columnContainer.getBoundingClientRect();
66583        columnContainerWidth -= igv_axis_column_width + this.get
66583SampleNameViewportWidth() + igv_scrollbar_outer_width + igv_track_manipulation_handle_width + igv_track_gear_menu_column_width;
66584        return Math.floor(columnContainerWidth / 2 + igv_axis_column_width);
66585      }
66586
66587      minimumBases() {
66588        return this.config.minimumBases;
66589      } // Zoom in by a factor of 2, keeping the same center location
66590
66591
66592      zoomIn() {
66593        this.zoomWithScaleFactor(0.5);
66594      }
66595
66596      // Zoom out by a factor of 2, keeping the same center location if possible
66597      zoomOut() {
66598        this.zoomWithScaleFactor(2.0);
66599      }
66600
66601      async zoomWithScaleFactor(scaleFactor, centerBPOrUndefined, referenceFrameOrUndefined) {
66602        const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);
66603        let referenceFrames = referenceFrameOrUndefined ? [referenceFrameOrUndefined] : this.referenceFrameList;
66604
66605        for (let referenceFrame of referenceFrames) {
66606          referenceFrame.zoomWithScaleFactor(this, scaleFactor, viewportWidth, centerBPOrUndefined);
66607        }
66608      }
66609
66610      async presentMultiLocusPanel(alignment, referenceFrameLeft) {
66611        // account for reduced viewport width as a result of adding right mate pair panel
66612        const viewportWidth = this.calculateViewportWidth(1 + this.referenceFrameList.length);
66613        const scaleFactor = this.calculateViewportWidth(this.referenceFrameList.length) / this.calculateViewportWidth(1 + this.referenceFrameList.length);
66614        adjustReferenceFrame(scaleFactor, referenceFrameLeft, viewportWidth, alignment.start, alignment.lengthOnRef); // create right mate pair reference frame
66615
66616        const mateChrName = this.genome.getChromosomeName(alignment.mate.chr);
66617        const referenceFrameRight = createReferenceFrameWithAlignment(this.genome, mateChrName, referenceFrameLeft.bpPerPixel, viewportWidth, alignment.mate.position, alignment.lengthOnRef); // add right mate panel beside left mate panel
66618
66619        const indexLeft = this.referenceFrameList.indexOf(referenceFrameLeft);
66620        const indexRight = 1 + this.referenceFrameList.indexOf(referenceFrameLeft);
66621        const {
66622          $viewport
66623        } = this.trackViews[0].viewports[indexLeft];
66624        const viewportColumn = viewportColumnManager.insertAfter($viewport.get(0).parentElement);
66625
66626        if (indexRight === this.referenceFrameList.length) {
66627          this.referenceFrameList.push(referenceFrameRight);
66628
66629          for (let trackView of this.trackViews) {
66630            const viewport = createViewport(trackView, viewportColumn, referenceFrameRight);
66631            trackView.viewports.push(viewport);
66632          }
66633        } else {
66634          this.referenceFrameList.splice(indexRight, 0, referenceFrameRight);
66635
66636          for (let trackView of this.trackViews) {
66637            const viewport = createViewport(trackView, viewportColumn, referenceFrameRight);
66638            trackView.viewports.splice(indexRight, 0, viewport);
66639          }
66640        }
66641
66642        this.centerLineList = this.createCenterLineList(this.columnContainer);
66643        await this.resize();
66644      }
66645
66646      async removeMultiLocusPanel(referenceFrame) {
66647        // find the $column corresponding to this referenceFrame and remove it
66648        const index = this.referenceFrameList.indexOf(referenceFrame);
66649        const {
66650          $viewport
66651        } = this.trackViews[0].viewports[index];
66652        viewportColumnManager.removeColumnAtIndex(index, $viewport.parent().get(0));
66653
66654        for (let {
66655          viewports
66656        } of this.trackViews) {
66657          viewports[index].dispose();
66658          viewports.splice(index, 1);
66659        }
66660
66661        this.referenceFrameList.splice(index, 1);
66662
66663        if (1 === this.referenceFrameList.length && this.getRulerTrackView()) {
66664          for (let rulerViewport of this.getRulerTrackView().viewports) {
66665            rulerViewport.dismissLocusLabel();
66666          }
66667        }
66668
66669        const scaleFactor = this.calculateViewportWidth(1 + this.referenceFrameList.length) / this.calculateViewportWidth(this.referenceFrameList.length);
66670        await this.rescaleForMultiLocus(scaleFactor);
66671      }
66672
66673      async selectMultiLocusPanel(referenceFrame) {
66674        const referenceFrameIndex = this.referenceFrameList.indexOf(referenceFrame);
66674 // Remove columns for unselected panels
66675
66676        this.columnContainer.querySelectorAll('.igv-column').forEach((column, c) => {
66677          if (c === referenceFrameIndex) ; else {
66678            column.remove();
66679          }
66680        }); // Remove all column shims
66681
66682        this.columnContainer.querySelectorAll('.igv-column-shim').forEach(shim => shim.remove()); // Discard viewports
66683
66684        for (let trackView of this.trackViews) {
66685          const retain = trackView.viewports[referenceFrameIndex];
66686          trackView.viewports.filter((viewport, i) => i !== referenceFrameIndex).forEach(viewport => viewport.dispose());
66687          trackView.viewports = [retain];
66688        }
66689
66690        const viewportWidth = this.calculateViewportWidth(1);
66691        referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / viewportWidth;
66692        this.referenceFrameList = [referenceFrame];
66693        this.trackViews.forEach(_ref2 => {
66694          let {
66695            viewports
66696          } = _ref2;
66697          return viewports.forEach(viewport => viewport.setWidth(viewportWidth));
66698        });
66699        this.centerLineList = this.createCenterLineList(this.columnContainer);
66700        this.updateUIWithReferenceFrameList();
66701        await this.updateViews(true);
66702      }
66703
66704      async selectMultiLocusPanel(referenceFrame) {
66705        const referenceFrameIndex = this.referenceFrameList.indexOf(referenceFrame); // Remove columns for unselected panels
66706
66707        this.columnContainer.querySelectorAll('.igv-column').forEach((column, c) => {
66708          if (c === referenceFrameIndex) ; else {
66709            column.remove();
66710          }
66711        }); // Remove all column shims
66712
66713        this.columnContainer.querySelectorAll('.igv-column-shim').forEach(shim => shim.remove()); // Discard viewports
66714
66715        for (let trackView of this.trackViews) {
66716          const retain = trackView.viewports[referenceFrameIndex];
66717          trackView.viewports.filter((viewport, i) => i !== referenceFrameIndex).forEach(viewport => viewport.dispose());
66718          trackView.viewports = [retain];
66719        }
66720
66721        const viewportWidth = this.calculateViewportWidth(1);
66722        referenceFrame.bpPerPixel = (referenceFrame.end - referenceFrame.start) / viewportWidth;
66723        this.referenceFrameList = [referenceFrame];
66724        this.trackViews.forEach(_ref3 => {
66725          let {
66726            viewports
66727          } = _ref3;
66728          return viewports.forEach(viewport => viewport.setWidth(viewportWidth));
66729        });
66730        this.centerLineList = this.createCenterLineList(this.columnContainer);
66731        this.updateUIWithReferenceFrameList();
66732        await this.updateViews(true);
66733      }
66734
66735      async rescaleForMultiLocus(scaleFactor) {
66736        const viewportWidth = this.calculateViewportWidth(this.referenceFrameList.length);
66737
66738        for (let referenceFrame of this.referenceFrameList) {
66739          referenceFrame.bpPerPixel *= scaleFactor;
66740        }
66741
66742        for (let {
66743          viewports
66744        } of this.trackViews) {
66745          for (let viewport of viewports) {
66746            viewport.setWidth(viewportWidth);
66747          }
66748        }
66749
66750        this.centerLineList = this.createCenterLineList(this.columnContainer);
66751        this.updateUIWithReferenceFrameList();
66752        await this.updateViews(true);
66753      }
66754      /**
66755       * @deprecated  This is a deprecated method with no known usages.  To be removed in a future release.
66756       */
66757
66758
66759      async goto(chr, start, end) {
66760        await this.search(chr + ":" + start + "-" + end);
66761      }
66762      /**
66763        * Search for the locus string -- this function is called from various igv.js GUI elements, and is not part of the
66764       * API.  Wraps ```search``` and presents an error dialog if false.
66765       *
66766       * @param string
66767       * @param init
66768       * @returns {Promise<void>}
66769       */
66770
66771
66772      async doSearch(string, init) {
66773        const success = await this.search(string, init);
66774
66775        if (!success) {
66776          Alert.presentAlert(new Error(`Unrecognized locus: <b> ${string} </b>`));
66777        }
66778
66779        return success;
66780      }
66781      /**
66782       * Search for the locus string
66783       * NOTE: This is part of the API
66784       * @param string
66785       * @param init  true if called during browser initialization
66786       * @returns {Promise<boolean>}  true if found, false if not
66787       */
66788
66789
66790      async search(string, init) {
66791        const loci = await search(this, string);
66792
66793        if (loci && loci.length > 0) {
66794          // create reference frame list based on search loci
66795          this.referenceFrameList = createReferenceFrameList(loci, this.genome, this.flanking, this.minimumBases(), this.calculateViewportWidth(loci.length)); // discard viewport DOM elements
66796
66797          for (let trackView of this.trackViews) {
66798            // empty axis column, viewport columns, sampleName column, scroll column, drag column, gear column
66799            trackView.removeDOMFromColumnContainer();
66800          } // discard ONLY viewport columns
66801
66802
66803          this.columnContainer.querySelectorAll('.igv-column-shim, .igv-column').forEach(el => el.remove()); // Insert viewport columns preceding the sample-name column
66804
66805          viewportColumnManager.insertBefore(this.columnContainer.querySelector('.igv-sample-name-column'), this.referenceFrameList.length);
66806          this.centerLineList = this.createCenterLineList(this.columnContainer); // Populate the columns
66807
66808          for (let trackView of this.trackViews) {
66809            trackView.addDOMToColumnContainer(this, this.columnContainer, this.referenceFrameList);
66810          }
66811
66812          this.updateUIWithReferenceFrameList();
66813
66814          if (!init) {
66815            await this.updateViews();
66816          }
66817
66818          return true;
66819        } else {
66820          return false;
66821        }
66822      }
66823
66824      async loadSampleInformation(url) {
66825        var name = url;
66826
66827        if (isFile(url)) {
66828          name = url.name;
66829        }
66830
66831        var ext = name.substr(name.lastIndexOf('.') + 1);
66832
66833        if (ext === 'fam') {
66834          this.sampleInformation = await loadPlinkFile(url);
66835        }
66836      }
66837
66838      // EVENTS
66839      on(eventName, fn) {
66840        if (!this.eventHandlers[eventName]) {
66841          this.eventHandlers[eventName] = [];
66842        }
66843
66844        this.eventHandlers[eventName].push(fn);
66845      }
66846
66847      /**
66848       * @deprecated use off()
66849       * @param eventName
66850       * @param fn
66851       */
66852      un(eventName, fn) {
66853        this.off(eventName, fn);
66854      }
66855
66856      off(eventName, fn) {
66857        if (!eventName) {
66858          this.eventHandlers = {}; // Remove all event handlers
66859        } else if (!fn) {
66860          this.eventHandlers[eventName] = []; // Remove all eventhandlers matching name
66861        } else {
66862          // Remove specific event handler
66863          const handlers = this.eventHandlers[eventName];
66864
66865          if (!handlers || handlers.length === 0) {
66866            console.warn("No handlers to remove for event: " + eventName);
66867          } else {
66868            const callbackIndex = handlers.indexOf(fn);
66869
66870            if (callbackIndex !== -1) {
66871              this.eventHandlers[eventName].splice(callbackIndex, 1);
66872            }
66873          }
66874        }
66875      }
66876
66877      fireEvent(eventName, args, thisObj) {
66878        const handlers = this.eventHandlers[eventName];
66879
66880        if (undefined === handlers || handlers.length === 0) {
66881          return undefined;
66882        }
66883
66884        const scope = thisObj || window;
66885        const results = handlers.map(function (event) {
66886          return event.apply(scope, args);
66887        });
66888        return results[0];
66889      }
66890
66891      dispose() {
66892        this.removeMouseHandlers();
66893
66894        for (let trackView of this.trackViews) {
66895          trackView.dispose();
66896        }
66897      }
66898
66899      toJSON() {
66900        const json = {
66901          "version": version$1()
66902        };
66903
66904        if (this.showSampleNames !== undefined) {
66905          json['showSampleNames'] = this.showSampleNames;
66906        }
66907
66908        if (this.sampleNameViewportWidth !== defaultSampleNameViewportWidth) {
66909          json['sampleNameViewportWidth'] = this.sampleNameViewportWidth;
66910        }
66911
66912        json["reference"] = this.genome.toJSON();
66913
66914        if (isFilePath(json.reference.fastaURL)) {
66915          throw new Error(`Error. Sessions cannot include local file references ${json.reference.fastaURL.name}.`);
66916        } else if (isFilePath(json.reference.indexURL)) {
66917          throw new Error(`Error. Sessions cannot include local file references ${json.reference.indexURL.name}.`);
66918        } // Build locus array (multi-locus view).  Use the first track to extract the loci, any track could be used.
66919
66920
66921        const locus = [];
66922        const gtexSelections = {};
66923        let anyTrackView = this.trackViews[0];
66924
66925        for (let {
66926          referenceFrame
66927        } of anyTrackView.viewports) {
66928          const locusString = referenceFrame.getLocusString();
66929          locus.push(locusString);
66930
66931          if (referenceFrame.selection) {
66932            const selection = {
66933              gene: referenceFrame.selection.gene,
66934              snp: referenceFrame.selection.snp
66935            };
66936            gtexSelections[locusString] = selection;
66937          }
66938        }
66939
66940        json["locus"] = locus.length === 1 ? locus[0] : locus;
66941        const gtexKeys = Object.getOwnPropertyNames(gtexSelections);
66942
66943        if (gtexKeys.length > 0) {
66944          json["gtexSelections"] = gtexSelections;
66945        }
66946
66947        const trackJson = [];
66948        const errors = [];
66949
66950        for (let {
66951          track
66952        } of this.trackViews) {
66953          try {
66954            let config;
66955
66956            if (typeof track.getState === "function") {
66957              config = track.getState();
66958            } else {
66959              config = track.config;
66960            }
66961
66962            if (config) {
66963              // null backpointer to browser
66964              if (config.browser) {
66965                delete config.browser;
66966              }
66967
66968              config.order = track.order; //order++;
66969
66970              trackJson.push(config);
66971            }
66972          } catch (e) {
66973            errors.push(e);
66974          }
66975        }
66976
66977        if (errors.length > 0) {
66978          let n = 1;
66979          let message = 'Errors encountered saving session:';
66980
66981          for (let e of errors) {
66982            message += ` (${n++}) ${e.toString()}.`;
66983          }
66984
66985          throw Error(message);
66986        }
66987
66988        const locaTrackFiles = trackJson.filter(track => {
66989          track.url && isFile(track.url);
66990        });
66991
66992        if (locaTrackFiles.length > 0) {
66993          throw new Error(`Error. Sessions cannot include local file references.`);
66994        }
66995
66996        json["tracks"] = trackJson;
66997        return json; // This is an object, not a json string
66998      }
66999
67000      compressedSession() {
67001        const json = JSON.stringify(this.toJSON());
67002        return compressString(json);
67003      }
67004
67005      sessionURL() {
67006        const path = window.location.href.slice();
67007        const idx = path.indexOf("?");
67008        const surl = (idx > 0 ? path.substring(0, idx) : path) + "?sessionURL=blob:" + this.compressedSession();
67009        return surl;
67010      }
67011
67012      currentLoci() {
67013        const loci = [];
67014        const anyTrackView = this.trackViews[0];
67015
67016        for (let {
67017          referenceFrame
67018        } of anyTrackView.viewports) {
67019          const locusString = referenceFrame.getLocusString();
67020          loci.push(locusString);
67021        }
67022
67023        return loci;
67024      }
67025      /**
67026       * Record a mouse click on a specific viewport.   This might be the start of a drag operation.   Dragging
67027       * (panning) is handled here so that the mouse can move out of a specific viewport (e.g. stray into another
67028       * track) without halting the drag.
67029       *
67030       * @param e
67031       * @param viewport
67032       */
67033
67034
67035      mouseDownOnViewport(e, viewport) {
67036        var coords;
67037        coords = pageCoordinates$1(e);
67038        this.vpMouseDown = {
67039          viewport,
67040          lastMouseX: coords.x,
67041          mouseDownX: coords.x,
67042          lastMouseY: coords.y,
67043          mouseDownY: coords.y,
67044          referenceFrame: viewport.referenceFrame
67045        };
67046      }
67047
67048      cancelTrackPan() {
67049        const dragObject = this.dragObject;
67050        this.dragObject = undefined;
67051        this.isScrolling = false;
67052        this.vpMouseDown = undefined;
67053
67054        if (dragObject && dragObject.viewport.referenceFrame.start !== dragObject.start) {
67055          this.updateViews();
67056          this.fireEvent('trackdragend');
67057        }
67058      }
67059
67060      startTrackDrag(trackView) {
67061        this.dragTrack = trackView;
67062      }
67063
67064      updateTrackDrag(dragDestination) {
67065        if (dragDestination && this.dragTrack) {
67066          const dragged = this.dragTrack;
67067          const indexDestination = this.trackViews.indexOf(dragDestination);
67068          const indexDragged = this.trackViews.indexOf(dragged);
67069          const trackViews = this.trackViews;
67070          trackViews[indexDestination] = dragged;
67071          trackViews[indexDragged] = dragDestination;
67072          const newOrder = this.trackViews[indexDestination].track.order;
67073          this.trackViews[indexDragged].track.order = newOrder;
67074          const nTracks = trackViews.length;
67075          let lastOrder = newOrder;
67076
67077          if (indexDestination < indexDragged) {
67078            // Displace tracks below
67079            for (let i = indexDestination + 1; i < nTracks; i++) {
67080              const track = trackViews[i].track;
67081
67082              if (track.order <= lastOrder) {
67083                track.order = Math.min(Number.MAX_SAFE_INTEGER, lastOrder + 1);
67084                lastOrder = track.order;
67085              } else {
67086                break;
67087              }
67088            }
67089          } else {
67090            // Displace tracks above.  First track (index 0) is "ruler"
67091            for (let i = indexDestination - 1; i > 0; i--) {
67092              const track = trackViews[i].track;
67093
67094              if (track.order >= lastOrder) {
67095                track.order = Math.max(-Number.MAX_SAFE_INTEGER, lastOrder - 1);
67096                lastOrder = track.order;
67097              } else {
67098                break;
67099              }
67100            }
67101          }
67102
67103          this.reorderTracks();
67104        }
67105      }
67106
67107      endTrackDrag() {
67108        if (this.dragTrack) {
67109          // this.dragTrack.$trackDragScrim.hide();
67110          this.dragTrack = undefined;
67111          this.fireEvent('trackorderchanged', [this.getTrackOrder()]);
67112        } else {
67113          this.dragTrack = undefined;
67114        }
67115      }
67116      /**
67117       * Mouse handlers to support drag (pan)
67118       */
67119
67120
67121      addMouseHandlers() {
67122        this.addWindowResizeHandler();
67123        this.addRootMouseUpHandler();
67124        this.addRootMouseLeaveHandler();
67125        this.addColumnContainerEventHandlers();
67126      }
67127
67128      removeMouseHandlers() {
67129        this.removeWindowResizeHandler();
67130        this.removeRootMouseUpHandler();
67131        this.removeRootMouseLeaveHandler();
67132        this.removeColumnContainerEventHandlers();
67133      }
67134
67135      addWindowResizeHandler() {
67136        this.boundWindowResizeHandler = windowResizeHandler.bind(this);
67137        window.addEventListener('resize', this.boundWindowResizeHandler);
67138
67139        function windowResizeHandler() {
67140          this.resize();
67141        }
67142      }
67143
67144      removeWindowResizeHandler() {
67145        window.removeEventListener('resize', this.boundWindowResizeHandler);
67146      }
67147
67148      addRootMouseUpHandler() {
67149        this.boundRootMouseUpHandler = mouseUpOrLeave.bind(this);
67150        this.root.addEventListener('mouseup', this.boundRootMouseUpHandler);
67151      }
67152
67153      removeRootMouseUpHandler() {
67154        this.root.removeEventListener('mouseup', this.boundRootMouseUpHandler);
67155      }
67156
67157      addRootMouseLeaveHandler() {
67158        this.boundRootMouseLeaveHandler = mouseUpOrLeave.bind(this);
67159        this.root.addEventListener('mouseleave', this.boundRootMouseLeaveHandler);
67160      }
67161
67162      removeRootMouseLeaveHandler() {
67163        this.root.removeEventListener('mouseleave', this.boundRootMouseLeaveHandler);
67164      }
67165
67166      addColumnContainerEventHandlers() {
67167        this.boundColumnContainerMouseMoveHandler = handleMouseMove.bind(this);
67168        this.boundColumnContainerTouchMoveHandler = handleMouseMove.bind(this);
67169        this.boundColumnContainerMouseLeaveHandler = mouseUpOrLeave.bind(this);
67170        this.boundColumnContainerMouseUpHandler = mouseUpOrLeave.bind(this);
67171        this.boundColumnContainerTouchEndHandler = mouseUpOrLeave.bind(this);
67172        this.columnContainer.addEventListener('mousemove', this.boundColumnContainerMouseMoveHandler);
67173        this.columnContainer.addEventListener('touchmove', this.boundColumnContainerTouchMoveHandler);
67174        this.columnContainer.addEventListener('mouseleave', this.boundColumnContainerMouseLeaveHandler);
67175        this.columnContainer.addEventListener('mouseup', this.boundColumnContainerMouseUpHandler);
67176        this.columnContainer.addEventListener('touchend', this.boundColumnContainerTouchEndHandler);
67177      }
67178
67179      removeColumnContainerEventHandlers() {
67180        this.columnContainer.removeEventListener('mousemove', this.boundColumnContainerMouseMoveHandler);
67181        this.columnContainer.removeEventListener('touchmove', this.boundColumnContainerTouchMoveHandler);
67182        this.columnContainer.removeEventListener('mouseleave', this.boundColumnContainerMouseLeaveHandler);
67183        this.columnContainer.removeEventListener('mouseup', this.boundColumnContainerMouseUpHandler);
67184        this.columnContainer.removeEventListener('touchend', this.boundColumnContainerTouchEndHandler);
67185      }
67186
67187      async getDriveFileInfo(googleDriveURL) {
67188        const id = getGoogleDriveFileID(googleDriveURL);
67189        const endPoint = "https://www.googleapis.com/drive/v3/files/" + id + "?supportsTeamDrives=true";
67190        return igvxhr.loadJson(endPoint, buildOptions({}));
67191      }
67192
67193      static uncompressSession(url) {
67194        let bytes;
67195
67196        if (url.indexOf('/gzip;base64') > 0) {
67197          //Proper dataURI
67198          bytes = decodeDataURI$1(url);
67199          let json = '';
67200
67201          for (let b of bytes) {
67202            json += String.fromCharCode(b);
67203          }
67204
67205          return json;
67206        } else {
67207          let enc = url.substring(5);
67208          return uncompressString(enc);
67209        }
67210      }
67211
67212      createCircularView(container, show) {
67213        this.circularView = createCircularView(container, this);
67214        this.circularViewControl = new CircularViewControl(this.$toggle_button_container.get(0), this);
67215        this.circularView.setAssembly({
67216          name: this.genome.id,
67217          id: this.genome.id,
67218          chromosomes: makeCircViewChromosomes(this.genome)
67219        });
67220        this.circularViewVisible = show === true;
67221      }
67222
67223      get circularViewVisible() {
67224        return this.circularView !== undefined && this.circularView.visible;
67225      }
67226
67227      set circularViewVisible(isVisible) {
67228        if (this.circularView) {
67229          this.circularView.visible = isVisible;
67230          this.circularViewControl.setState(isVisible);
67231        }
67232      }
67233
67234    }
67235
67236    function handleMouseMove(e) {
67237      e.preventDefault();
67238      const {
67239        x,
67240        y
67241      } = pageCoordinates$1(e);
67242
67243      if (this.vpMouseDown) {
67244        const {
67245          viewport,
67246          referenceFrame
67247        } = this.vpMouseDown; // Determine direction,  true == horizontal
67248
67249        const horizontal = Math.abs(x - this.vpMouseDown.mouseDownX) > Math.abs(y - this.vpMouseDown.mouseDownY);
67250
67251        if (!this.dragObject && !this.isScrolling) {
67252          if (horizontal) {
67253            if (this.vpMouseDown.mouseDownX && Math.abs(x - this.vpMouseDown.mouseDownX) > this.constants.dragThreshold) {
67254              this.dragObject = {
67255                viewport,
67256                start: referenceFrame.start
67257              };
67258            }
67259          } else {
67260            if (this.vpMouseDown.mouseDownY && Math.abs(y - this.vpMouseDown.mouseDownY) > this.constants.scrollThreshold) {
67261              this.isScrolling = true;
67262              const viewportHeight = viewport.$viewport.height();
67263              const contentHeight = maxViewportContentHeight(viewport.trackView.viewports);
67264              this.vpMouseDown.r = viewportHeight / contentHeight;
67265            }
67266          }
67267        }
67268
67269        if (this.dragObject) {
67270          const viewChanged = referenceFrame.shiftPixels(this.vpMouseDown.lastMouseX - x, viewport.$viewport.width());
67271
67272          if (viewChanged) {
67273            this.updateViews();
67274          }
67275
67276          this.fireEvent('trackdrag');
67277        }
67278
67279        if (this.isScrolling) {
67280          const delta = this.vpMouseDown.r * (this.vpMouseDown.lastMouseY - y);
67281          viewport.trackView.moveScroller(delta);
67282        }
67283
67284        this.vpMouseDown.lastMouseX = x;
67285        this.vpMouseDown.lastMouseY = y;
67286      }
67287    }
67288
67289    function mouseUpOrLeave(e) {
67290      this.cancelTrackPan();
67291      this.endTrackDrag();
67292    }
67293
67294    function getInitialLocus(locus, genome) {
67295      if (locus) {
67296        return Array.isArray(locus) ? locus.join(' ') : locus;
67297      } else {
67298        return genome.getHomeChromosomeName();
67299      }
67300    }
67301
67302    function logo() {
67303      return $$1('<svg width="690px" height="324px" viewBox="0 0 690 324" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' + '<title>IGV</title>' + '<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">' + '<g id="IGV" fill="#666666">' + '<polygon id="Path" points="379.54574 8.00169252 455.581247 8.00169252 515.564813 188.87244 532.884012 253.529506 537.108207 253.529506 554.849825 188.87244 614.833392 8.00169252 689.60164 8.00169252 582.729511 320.722144 486.840288 320.722144"></polygon>' + '<path d="M261.482414,323.793286 C207.975678,323.793286 168.339046,310.552102 142.571329,284.069337 C116.803612,257.586572 103.919946,217.158702 103.919946,162.784513 C103.919946,108.410325 117.437235,67.8415913 144.472217,41.0770945 C171.507199,14.3125977 212.903894,0.930550071 268.663545,0.930550071 C283.025879,0.930550071 298.232828,1.84616386 3
6730314.284849,3.6774189 C330.33687,5.50867394 344.839793,7.97378798 357.794056,11.072835 L357.794056,68.968378 C339.48912,65.869331 323.578145,63.5450806 310.060654,61.9955571 C296.543163,60.4460336 284.574731,59.6712835 274.154998,59.6712835 C255.850062,59.6712835 240.502308,61.4320792 228.111274,64.9537236 C215.720241,68.4753679 205.793482,74.2507779 198.330701,82.2801269 C190.867919,90.309476 185.587729,100.87425 182.48997,113.974767 C179.392212,127.075284 177.843356,143.345037 177.843356,162.784513 C177.843356,181.942258 179.251407,198.000716 182.067551,210.960367 C184.883695,223.920018 189.671068,234.41436 196.429813,242.443709 C203.188559,250.473058 212.059279,256.178037 223.042241,259.558815 C234.025202,262.939594 247.683295,264.629958 264.01693,264.629958 C268.241146,264.629958 273.098922,264.489094 278.590403,264.207362 C284.081883,263.925631 289.643684,263.50304 295.275972,262.939577 L295.275972,159.826347 L361.595831,159.826347 L361.595831,308.579859 C344.698967,313.087564 327.239137,316.750019 309.215815,319.567334 C291.192494,322.38465 275.281519,323.793286 261.482414,323.793286 L261.482414,323.793286 L261.482414,323.793286 Z" id="Path"></path>;' + '<polygon id="Path" points="0.81355666 5.00169252 73.0472883 5.00169252 73.0472883 317.722144 0.81355666 317.722144"></polygon>' + '</g> </g> </svg>');
67304    }
67305
67306    function toggleTrackLabels(trackViews, isVisible) {
67307      for (let {
67308        viewports
67309      } of trackViews) {
67310        for (let viewport of viewports) {
67311          if (viewport.$trackLabel) {
67312            if (0 === viewports.indexOf(viewport) && true === isVisible) {
67313              viewport.$trackLabel.show();
67314            } else {
67315              viewport.$trackLabel.hide();
67316            }
67317          }
67318        }
67319      }
67320    }
67321
67322    /*
67323     * The MIT License (MIT)
67324     *
67325     * Copyright (c) 2014 Broad Institute
67326     *
67327     * Permission is hereby granted, free of charge, to any person obtaining a copy
67328     * of this software and associated documentation files (the "Software"), to deal
67329     * in the Software without restriction, including without limitation the rights
67330     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
67331     * copies of the Software, and to permit persons to whom the Software is
67332     * furnished to do so, subject to the following conditions:
67333     *
67334     * The above copyright notice and this permission notice shall be included in
67335     * all copies or substantial portions of the Software.
67336     *
67337     *
67338     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
67339     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
67340     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
67341     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
67342     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
67343     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
67344     * THE SOFTWARE.
67345     */
67346    let allBrowsers = [];
67347    /**
67348     * Create an igv.browser instance.  This object defines the public API for interacting with the genome browser.
67349     *
67350     * @param parentDiv - DOM tree root
67351     * @param config - configuration options.
67352     *
67353     */
67354
67355    async function createBrowser(parentDiv, config) {
67356      if (undefined === config) config = {}; // Initialize pre-defined genomes.  The genome list is shared among all browser instances
67357
67358      if (!GenomeUtils.KNOWN_GENOMES) {
67359        await GenomeUtils.initializeGenomes(config);
67360      }
67361
67362      setDefaults(config);
67363
67364      if (config.queryParametersSupported !== false) {
67365        extractQuery(config);
67366      }
67367
67368      if (config.apiKey) {
67369        igvxhr.setApiKey(config.apiKey);
67370      }
67371
67372      if (config.oauthToken) {
67373        oauth.setToken(config.oauthToken);
67374      }
67375
67376      if (config.clientId && !isInitialized()) {
67377        await init$1({
67378          clientId: config.clientId,
67379          apiKey: config.apiKey,
67380          scope: 'https://www.googleapis.com/auth/userinfo.profile'
67381        });
67382      } // Create browser
67383
67384
67385      const browser = new Browser(config, parentDiv);
67386      allBrowsers.push(browser); // Load initial session
67387
67388      if (config.sessionURL) {
67389        await browser.loadSession({
67390          url: config.sessionURL
67391        });
67392      } else {
67393        await browser.loadSessionObject(config);
67394      }
67395
67396      const isWGV = browser.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(browser.referenceFrameList[0].chr);
67397      browser.navbarManager.navbarDidResize(browser.$navigation.width(), isWGV);
67398      return browser;
67399    }
67400
67401    function removeBrowser(browser) {
67402      browser.dispose();
67403      browser.root.remove();
67404      allBrowsers = allBrowsers.filter(item => item !== browser);
67405    }
67406
67407    function removeAllBrowsers() {
67408      for (let browser of allBrowsers) {
67409        browser.dispose();
67410        browser.root.remove();
67411      }
67412
67413      allBrowsers = [];
67414    }
67415    /**
67416     * This function provided so clients can inform igv of a visibility change, typically when an igv instance is
67417     * made visible from a tab, accordion, or similar widget.
67418     */
67419
67420
67421    async function visibilityChange() {
67422      for (let browser of allBrowsers) {
67423        await browser.visibilityChange();
67424      }
67425    }
67426
67427    function setDefaults(config) {
67428      if (undefined === config.promisified) {
67429        config.promisified = false;
67430      }
67431
67432      if (undefined === config.minimumBases) {
67433        config.minimumBases = 40;
67434      }
67435
67436      if (undefined === config.showIdeogram) {
67437        config.showIdeogram = true;
67438      }
67439
67440      if (undefined === config.showCircularView) {
67441        config.showCircularView = false;
67442      }
67443
67444      if (undefined === config.showCircularViewButton) {
67445        config.showCircularViewButton = false;
67446      }
67447
67448      if (undefined === config.showTrackLabelButton) {
67449        config.showTrackLabelButton = true;
67450      }
67451
67452      if (undefined === config.showTrackLabels) {
67453        config.showTrackLabels = true;
67454      }
67455
67456      if (undefined === config.showCursorTrackingGuideButton) {
67457        config.showCursorTrackingGuideButton = true;
67458      }
67459
67460      if (undefined === config.showCursorTrackingGuide) {
67461        config.showCursorTrackingGuide = false;
67462      }
67463
67464      if (undefined === config.showCenterGuideButton) {
67465        config.showCenterGuideButton = true;
67466      }
67467
67468      if (undefined === config.showCenterGuide) {
67469        config.showCenterGuide = false;
67470      }
67471
67472      if (undefined === config.showSampleNames) {
67473        config.showSampleNames = false;
67474      }
67475
67476      if (undefined === config.showSVGButton) {
67477        config.showSVGButton = true;
67478      }
67479
67480      if (config.showControls === undefined) {
67481        config.showControls = true;
67482      }
67483
67484      if (config.showNavigation === undefined) {
67485        config.showNavigation = true;
67486      }
67487
67488      if (config.showRuler === undefined) {
67489        config.showRuler = true;
67490      }
67491
67492      if (config.flanking === undefined) {
67493        config.flanking = 1000;
67494      }
67495
67496      if (config.pairsSupported === undefined) {
67497        config.pairsSupported = true;
67498      }
67499
67500      if (!config.tracks) {
67501        config.tracks = [];
67502      }
67503    }
67504
67505    function extractQuery(config) {
67506      var i1, i2, i, j, s, query, tokens, uri, key, value;
67507      uri = window.location.href;
67508      query = {};
67509      i1 = uri.indexOf("?");
67510      i2 = uri.lastIndexOf("#");
67511      let files;
67512      let indexURLs;
67513      let names;
67514
67515      if (i1 >= 0) {
67516        if (i2 < 0) i2 = uri.length;
67517
67518        for (i = i1 + 1; i < i2;) {
67519          j = uri.indexOf("&", i);
67520          if (j < 0) j = i2;
67521          s = uri.substring(i, j);
67522          tokens = s.split("=", 2);
67523
67524          if (tokens.length === 2) {
67525            key = tokens[0];
67526            value = decodeURIComponent(tokens[1]);
67527
67528            if ('file' === key) {
67529              // IGV desktop style file parameter
67530              files = value.split(',');
67531            } else if ('index' === key) {
67532              // IGV desktop style index parameter
67533              indexURLs = value.split(',');
67534            } else if ('name' === key) {
67535              // IGV desktop style index parameter
67536              names = value.split(',');
67537            } else if ('genome' === key && (value.startsWith("https://") || value.startsWith("http://")) && !value.endsWith(".json")) {
67538              // IGV desktop compatibility -- assuming url to fasta
67539              config['reference'] = {
67540                fastaURL: value,
67541                indexURL: value + ".fai"
67542              };
67543            } else {
67544              config[key] = value;
67545            }
67546
67547            i = j + 1;
67548          }
67549        }
67550      }
67551
67552      if (files) {
67553        if (!config.tracks) config.tracks = [];
67554
67555        for (let i = 0; i < files.length; i++) {
67556          if (files[i].endsWith(".xml") || files[i].endsWith(".json")) {
67557            config.sessionURL = files[i];
67558            break;
67559          }
67560
67561          const trackConfig = {
67562            url: files[i]
67563          };
67564
67565          if (indexURLs && indexURLs.length > i) {
67566            trackConfig.indexURL = indexURLs[i];
67567          }
67568
67569          if (names && names.length > i) {
67570            trackConfig.name = names[i];
67571          }
67572
67573          config.tracks.push(trackConfig);
67574        }
67575      }
67576
67577      return query;
67578    }
67579
67580    async function createTrack(config, browser) {
67581      return await Browser.prototype.createTrack.call(browser, config);
67582    }
67583
67584    function embedCSS() {
67585      var css = '.igv-navbar {\n  display: flex;\n  flex-flow: row;\n  flex-wrap: nowrap;\n  justify-content: space-between;\n  align-items: center;\n  box-sizing: border-box;\n  width: 100%;\n  color: #444;\n  font-size: 12px;\n  font-family: \"Open Sans\", sans-serif;\n  font-weight: 400;\n  line-height: 32px;\n  padding-left: 8px;\n  padding-right: 8px;\n  margin-top: 2px;\n  margin-bottom: 6px;\n  height: 32px;\n  border-style: solid;\n  border-radius: 3px;\n  border-width: thin;\n  border-color: #bfbfbf;\n  background-color: #f3f3f3; }\n  .igv-navbar .igv-navbar-left-container {\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: space-between;
67585\n    align-items: center;\n    height: 32px;\n    line-height: 32px; }\n    .igv-navbar .igv-navbar-left-container .igv-logo {\n      width: 34px;\n      height: 32px;\n      margin-right: 8px; }\n    .igv-navbar .igv-navbar-left-container .igv-current-genome {\n      height: 32px;\n      margin-left: 4px;\n      margin-right: 4px;\n      user-select: none;\n      line-height: 32px;\n      vertical-align: middle;\n      text-align: center; }\n    .igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location {\n      display: flex;\n      flex-flow: row;\n      flex-wrap: nowrap;\n      justify-content: space-between;\n      align-items: center;\n      height: 100%; }\n      .igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container {\n        display: flex;\n        flex-flow: column;\n        flex-wrap: nowrap;\n        justify-content: space-around;\n        align-items: center;\n        height: 100%;\n        width: 125px;\n        margin-right: 4px; }\n        .igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container select {\n          display: block;\n          cursor: pointer;\n          width: 100px;\n          height: 75%;\n          outline: none;\n          font-size: 12px;\n          font-family: \"Open Sans\", sans-serif;\n          font-weight: 400; }\n      .igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group {\n        display: flex;\n        flex-flow: row;\n        flex-wrap: nowrap;\n        justify-content: space-between;\n        align-items: center;\n        margin-left: 8px;\n        height: 22px; }\n        .igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container {\n          display: flex;\n          flex-flow: row;\n          flex-wrap: nowrap;\n          justify-content: flex-start;\n          align-items: center;\n          width: 210px;\n          height: 22px;\n          line-height: 22px; }\n          .igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container input.igv-search-input {\n            cursor: text;\n            width: 85%;\n            height: 22px;\n            line-height: 22px;\n            font-size: 12px;\n            font-family: \"Open Sans\", sans-serif;\n            font-weight: 400;\n            text-align: left;\n            padding-left: 8px;\n            margin-right: 8px;\n            outline: none;\n            border-style: solid;\n            border-radius: 3px;\n            border-width: thin;\n            border-color: #bfbfbf;\n            background-color: white; }\n          .igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container .igv-search-icon-container {\n            cursor: pointer;\n            height: 16px;\n            width: 16px; }\n        .igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-windowsize-panel-container {\n          margin-left: 4px;\n          user-select: none; }\n  .igv-navbar .igv-navbar-right-container {\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: space-between;\n    align-items: center;\n    height: 32px;\n    line-height: 32px; }\n    .igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {\n      display: flex;\n      flex-flow: row;\n      flex-wrap: nowrap;\n      justify-content: space-between;\n      align-items: center;\n      height: 100%; }\n      .igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div {\n        margin-left: 0;\n        margin-right: 4px; }\n      .igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div:last-child {\n        margin-left: 0;\n        margin-right: 0; }\n    .igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-750 {\n      display: none; }\n    .igv-navbar .igv-navbar-right-container .igv-zoom-widget {\n      color: #737373;\n      font-size: 18px;\n      height: 32px;\n      line-height: 32px;\n      margin-left: 8px;\n      user-select: none;\n      display: flex;\n      flex-flow: row;\n      flex-wrap: nowrap;\n      justify-content: flex-end;\n      align-items: center; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget div {\n        cursor: pointer;\n        margin-left: unset;\n        margin-right: unset; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {\n        height: 24px;\n        width: 24px;\n        margin-left: unset;\n        margin-right: 8px; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {\n        height: 24px;\n        width: 24px;\n        margin-left: 8px;\n        margin-right: unset; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {\n        display: block;\n        height: fit-content; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget input {\n        display: block;\n        width: 125px; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget svg {\n        display: block; }\n    .igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 {\n      color: #737373;\n      font-size: 18px;\n      height: 32px;\n      line-height: 32px;\n      margin-left: 8px;\n      user-select: none;\n      display: flex;\n      flex-flow: row;\n      flex-wrap: nowrap;\n      justify-content: flex-end;\n      align-items: center; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div {\n        cursor: pointer;\n        margin-left: unset;\n        margin-right: unset; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {\n        height: 24px;\n        width: 24px;\n        margin-left: unset;\n        margin-right: 8px; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {\n        height: 24px;\n        width: 24px;\n        margin-left: 8px;\n        margin-right: unset; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {\n        width: 0;\n        height: 0;\n        display: none; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 input {\n        width: 0;\n        height: 0;\n        display: none; }\n      .igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 svg {\n        display: block; }\n    .igv-navbar .igv-navbar-right-container .igv-zoom-widget-hidden {\n      display: none; }\n\n.igv-navbar-button {\n  display: block;\n  box-sizing: unset;\n  padding-left: 6px;\n  padding-right: 6px;\n  height: 18px;\n  text-transform: capitalize;\n  user-select: none;\n  line-height: 18px;\n  text-align: center;\n  vertical-align: middle;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: 11px;\n  font-weight: 200;\n  color: #737373;\n  background-color: #f3f3f3;\n  border-color: #737373;\n  border-style: solid;\n  border-width: thin;\n  border-radius: 6px; }\n\n.igv-navbar-button-clicked {\n  color: white;\n  background-color: #737373; }
67585\n\n.igv-navbar-button:hover {\n  cursor: pointer; }\n\n.igv-zoom-in-notice-container {\n  z-index: 1024;\n  position: absolute;\n  top: 8px;\n  left: 50%;\n  transform: translate(-50%, 0%);\n  display: flex;\n  flex-direction: row;\n  flex-wrap: nowrap;\n  justify-content: center;\n  align-items: center;\n  background-color: white; }\n  .igv-zoom-in-notice-container > div {\n    padding-left: 4px;\n    padding-right: 4px;\n    padding-top: 2px;\n    padding-bottom: 2px;\n    width: 100%;\n    height: 100%;\n    font-family: \"Open Sans\", sans-serif;\n    font-size: 14px;\n    font-weight: 400;\n    color: #3f3f3f; }\n\n.igv-zoom-in-notice {\n  position: absolute;\n  top: 10px;\n  left: 50%; }\n  .igv-zoom-in-notice div {\n    position: relative;\n    left: -50%;\n    font-family: \"Open Sans\", sans-serif;\n    font-size: medium;\n    font-weight: 400;\n    color: #3f3f3f;\n    background-color: rgba(255, 255, 255, 0.51);\n    z-index: 64; }\n\n.igv-container-spinner {\n  position: absolute;\n  top: 90%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  z-index: 1024;\n  width: 24px;\n  height: 24px;\n  pointer-events: none;\n  color: #737373; }\n\n.igv-multi-locus-close-button {\n  position: absolute;\n  top: 2px;\n  right: 0;\n  padding-left: 2px;\n  padding-right: 2px;\n  width: 14px;\n  height: 14px;\n  color: #666666;\n  background-color: white;\n  z-index: 1000; }\n  .igv-multi-locus-close-button > svg {\n    vertical-align: top; }\n\n.igv-multi-locus-close-button:hover {\n  cursor: pointer;\n  color: #434343; }\n\n.igv-multi-locus-ruler-label {\n  z-index: 64;\n  position: absolute;\n  top: 2px;\n  left: 0;\n  width: 100%;\n  height: 14px;\n  display: flex;\n  flex-flow: row;\n  flex-wrap: nowrap;\n  justify-content: center;\n  align-items: center; }\n  .igv-multi-locus-ruler-label div {\n    font-family: \"Open Sans\", sans-serif;\n    font-size: 14px;\n    font-weight: 400;\n    color: #101010;\n    background-color: white; }\n\n.igv-multi-locus-ruler-label-square-dot {\n  z-index: 64;\n  position: absolute;\n  left: 50%;\n  top: 5%;\n  transform: translate(-50%, 0%);\n  background-color: white;\n  display: flex;\n  flex-flow: row;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: center; }\n  .igv-multi-locus-ruler-label-square-dot > div:first-child {\n    width: 14px;\n    height: 14px; }\n  .igv-multi-locus-ruler-label-square-dot > div:last-child {\n    margin-left: 16px;\n    font-family: \"Open Sans\", sans-serif;\n    font-size: 14px;\n    font-weight: 400;\n    color: #101010; }\n\n.igv-multi-locus-ruler-label:hover {\n  cursor: pointer; }\n\n.igv-ruler-sweeper {\n  display: none;\n  pointer-events: none;\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 0;\n  height: 100%;\n  z-index: 99999;\n  background-color: rgba(68, 134, 247, 0.25); }\n\n.igv-ruler-tooltip {\n  pointer-events: none;\n  z-index: 128;\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 1px;\n  height: 32px;\n  background-color: transparent;\n  display: flex;\n  flex-flow: row;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: center; }\n  .igv-ruler-tooltip > div {\n    pointer-events: none;\n    width: 128px;\n    height: auto;\n    padding: 1px;\n    color: #373737;\n    font-size: 10px;\n    font-family: \"Open Sans\", sans-serif;\n    font-weight: 400;\n    background-color: white;\n    border-style: solid;\n    border-width: thin;\n    border-color: #373737; }\n\n.igv-track-label {\n  position: absolute;\n  left: 8px;\n  top: 8px;\n  width: auto;\n  height: auto;\n  max-width: 200px;\n  padding-left: 4px;\n  padding-right: 4px;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: small;\n  font-weight: 400;\n  text-align: center;\n  user-select: none;\n  -moz-user-select: none;\n  -webkit-user-select: none;\n  border-color: #444;\n  border-radius: 2px;\n  border-style: solid;\n  border-width: thin;\n  background-color: white;\n  z-index: 128;\n  cursor: pointer; }\n\n.igv-track-label:hover,\n.igv-track-label:focus,\n.igv-track-label:active {\n  background-color: #e8e8e8; }\n\n.igv-center-line {\n  display: none;\n  pointer-events: none;\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  transform: translateX(-50%);\n  z-index: 8;\n  user-select: none;\n  -moz-user-select: none;\n  -webkit-user-select: none;\n  border-left-style: dashed;\n  border-left-width: thin;\n  border-right-style: dashed;\n  border-right-width: thin; }\n\n.igv-center-line-wide {\n  background-color: rgba(0, 0, 0, 0);\n  border-left-color: rgba(127, 127, 127, 0.51);\n  border-right-color: rgba(127, 127, 127, 0.51); }\n\n.igv-center-line-thin {\n  background-color: rgba(0, 0, 0, 0);\n  border-left-color: rgba(127, 127, 127, 0.51);\n  border-right-color: rgba(0, 0, 0, 0); }\n\n.igv-cursor-guide-horizontal {\n  display: none;\n  pointer-events: none;\n  user-select: none;\n  -moz-user-select: none;\n  -webkit-user-select: none;\n  position: absolute;\n  left: 0;\n  right: 0;\n  top: 50%;\n  height: 1px;\n  z-index: 1;\n  margin-left: 50px;\n  margin-right: 54px;\n  border-top-style: dotted;\n  border-top-width: thin;\n  border-top-color: rgba(127, 127, 127, 0.76); }\n\n.igv-cursor-guide-vertical {\n  pointer-events: none;\n  user-select: none;\n  -moz-user-select: none;\n  -webkit-user-select: none;\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 50%;\n  width: 1px;\n  z-index: 1;\n  border-left-style: dotted;\n  border-left-width: thin;\n  border-left-color: rgba(127, 127, 127, 0.76);\n  display: none; }\n\n.igv-user-feedback {\n  position: fixed;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: 512px;\n  height: 360px;\n  z-index: 2048;\n  background-color: white;\n  border-color: #a2a2a2;\n  border-style: solid;\n  border-width: thin;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: medium;\n  font-weight: 400;\n  color: #444;\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: center; }\n  .igv-user-feedback div:first-child {\n    position: relative;\n    height: 24px;\n    width: 100%;\n    background-color: white;\n    border-bottom-color: #a2a2a2;\n    border-bottom-style: solid;\n    border-bottom-width: thin; }\n    .igv-user-feedback div:first-child div {\n      position: absolute;\n      top: 2px;\n      width: 16px;\n      height: 16px;\n      background-color: transparent; }\n    .igv-user-feedback div:first-child div:first-child {\n      left: 8px; }\n    .igv-user-feedback div:first-child div:last-child {\n      cursor: pointer;\n      right: 8px; }\n  .igv-user-feedback div:last-child {\n    width: 100%;\n    height: calc(100% - 24px);\n    border-width: 0; }\n    .igv-user-feedback div:last-child div {\n      width: auto;\n      height: auto;\n      margin: 8px; }\n\n.igv-generic-dialog-container {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 300px;\n  height: 200px;\n  border-color: #7F7F7F;\n  border-radius: 4px;\n  border-style: solid;\n  border-width: thin;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: medium;\n  font-weight: 400;\n  z-index: 2048;\n  background-color: white;\n  display: flex;\n  flex-flow: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: center; }\n  .igv-generic-dialog-container .igv-generic-dialog-header {\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: flex-end;
67585\n    align-items: center;\n    width: 100%;\n    height: 24px;\n    cursor: move;\n    border-top-left-radius: 4px;\n    border-top-right-radius: 4px;\n    border-bottom-color: #7F7F7F;\n    border-bottom-style: solid;\n    border-bottom-width: thin;\n    background-color: #eee; }\n    .igv-generic-dialog-container .igv-generic-dialog-header div {\n      margin-right: 4px;\n      margin-bottom: 2px;\n      height: 12px;\n      width: 12px;\n      color: #7F7F7F; }\n    .igv-generic-dialog-container .igv-generic-dialog-header div:hover {\n      cursor: pointer;\n      color: #444; }\n  .igv-generic-dialog-container .igv-generic-dialog-one-liner {\n    color: #373737;\n    width: 95%;\n    height: 24px;\n    line-height: 24px;\n    text-align: left;\n    margin-top: 8px;\n    padding-left: 8px;\n    overflow-wrap: break-word;\n    background-color: white; }\n  .igv-generic-dialog-container .igv-generic-dialog-label-input {\n    margin-top: 8px;\n    width: 95%;\n    height: 24px;\n    color: #373737;\n    line-height: 24px;\n    padding-left: 8px;\n    background-color: white;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: flex-start;\n    align-items: center; }\n    .igv-generic-dialog-container .igv-generic-dialog-label-input div {\n      width: 30%;\n      height: 100%;\n      font-size: 16px;\n      text-align: right;\n      padding-right: 8px;\n      background-color: white; }\n    .igv-generic-dialog-container .igv-generic-dialog-label-input input {\n      display: block;\n      height: 100%;\n      width: 100%;\n      padding-left: 4px;\n      font-family: \"Open Sans\", sans-serif;\n      font-weight: 400;\n      color: #373737;\n      text-align: left;\n      outline: none;\n      border-style: solid;\n      border-width: thin;\n      border-color: #7F7F7F;\n      background-color: white; }\n    .igv-generic-dialog-container .igv-generic-dialog-label-input input {\n      width: 50%;\n      font-size: 16px; }\n  .igv-generic-dialog-container .igv-generic-dialog-input {\n    margin-top: 8px;\n    width: calc(100% - 16px);\n    height: 24px;\n    color: #373737;\n    line-height: 24px;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: space-around;\n    align-items: center; }\n    .igv-generic-dialog-container .igv-generic-dialog-input input {\n      display: block;\n      height: 100%;\n      width: 100%;\n      padding-left: 4px;\n      font-family: \"Open Sans\", sans-serif;\n      font-weight: 400;\n      color: #373737;\n      text-align: left;\n      outline: none;\n      border-style: solid;\n      border-width: thin;\n      border-color: #7F7F7F;\n      background-color: white; }\n    .igv-generic-dialog-container .igv-generic-dialog-input input {\n      font-size: 16px; }\n  .igv-generic-dialog-container .igv-generic-dialog-ok-cancel {\n    width: 100%;\n    height: 28px;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: space-around;\n    align-items: center; }\n    .igv-generic-dialog-container .igv-generic-dialog-ok-cancel div {\n      margin-top: 32px;\n      color: white;\n      font-family: \"Open Sans\", sans-serif;\n      font-size: 14px;\n      font-weight: 400;\n      width: 75px;\n      height: 28px;\n      line-height: 28px;\n      text-align: center;\n      border-color: transparent;\n      border-style: solid;\n      border-width: thin;\n      border-radius: 2px; }\n    .igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child {\n      margin-left: 32px;\n      margin-right: 0;\n      background-color: #5ea4e0; }\n    .igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child {\n      margin-left: 0;\n      margin-right: 32px;\n      background-color: #c4c4c4; }\n    .igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child:hover {\n      cursor: pointer;\n      background-color: #3b5c7f; }\n    .igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child:hover {\n      cursor: pointer;\n      background-color: #7f7f7f; }\n  .igv-generic-dialog-container .igv-generic-dialog-ok {\n    width: 100%;\n    height: 36px;\n    margin-top: 32px;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: space-around;
67585\n    align-items: center; }\n    .igv-generic-dialog-container .igv-generic-dialog-ok div {\n      width: 98px;\n      height: 36px;\n      line-height: 36px;\n      text-align: center;\n      color: white;\n      font-family: \"Open Sans\", sans-serif;\n      font-size: medium;\n      font-weight: 400;\n      border-color: white;\n      border-style: solid;\n      border-width: thin;\n      border-radius: 4px;\n      background-color: #2B81AF; }\n    .igv-generic-dialog-container .igv-generic-dialog-ok div:hover {\n      cursor: pointer;\n      background-color: #25597f; }\n\n.igv-generic-container {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 2048;\n  background-color: white;\n  cursor: pointer;\n  display: flex;\n  flex-direction: row;\n  flex-wrap: wrap;\n  justify-content: flex-start;\n  align-items: center; }\n  .igv-generic-container div:first-child {\n    cursor: move;\n    display: flex;\n    flex-flow: row;\n    flex-wrap: nowrap;\n    justify-content: flex-end;\n    align-items: center;\n    height: 24px;\n    width: 100%;\n    background-color: #dddddd; }\n    .igv-generic-container div:first-child i {\n      display: block;\n      color: #5f5f5f;\n      cursor: pointer;\n      width: 14px;\n      height: 14px;\n      margin-right: 8px;\n      margin-bottom: 4px; }\n\n.igv-menu-popup {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: max-content;\n  z-index: 4096;\n  cursor: pointer;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: small;\n  font-weight: 400;\n  color: #4b4b4b;\n  background: white;\n  border-radius: 4px;\n  border-color: #7F7F7F;\n  border-style: solid;\n  border-width: thin;\n  display: flex;\n  flex-flow: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: flex-end;\n  text-align: left; }\n  .igv-menu-popup > div:not(:first-child) {\n    width: 100%; }\n    .igv-menu-popup > div:not(:first-child) > div {\n      background: white; }\n    .igv-menu-popup > div:not(:first-child) > div.context-menu {\n      padding-left: 4px;\n      padding-right: 4px; }\n    .igv-menu-popup > div:not(:first-child) > div:last-child {\n      border-bottom-left-radius: 4px;\n      border-bottom-right-radius: 4px;\n      border-bottom-color: transparent;\n      border-bottom-style: solid;\n      border-bottom-width: thin; }\n    .igv-menu-popup > div:not(:first-child) > div:hover {\n      background: #efefef; }\n\n.igv-menu-popup-shim {\n  padding-left: 8px;\n  padding-right: 8px; }\n\n.igv-menu-popup-header {\n  position: relative;\n  width: 100%;\n  height: 24px;\n  cursor: move;\n  border-top-color: transparent;\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n  border-bottom-color: #7F7F7F;\n  border-bottom-style: solid;\n  border-bottom-width: thin;\n  background-color: #eee;\n  display: flex;\n  flex-flow: row;\n  flex-wrap: nowrap;\n  justify-content: flex-end;\n  align-items: center; }\n  .igv-menu-popup-header div {\n    margin-right: 4px;\n    height: 12px;\n    width: 12px;\n    color: #7F7F7F; }\n  .igv-menu-popup-header div:hover {\n    cursor: pointer;\n    color: #444; }\n\n.igv-menu-popup-check-container {\n  display: flex;\n  flex-flow: row;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: center;\n  width: 100%;\n  height: 20px;\n  background-color: transparent; }\n  .igv-menu-popup-check-container div {\n    padding-top: 2px;\n    padding-left: 8px; }\n  .igv-menu-popup-check-container div:first-child {\n    position: relative;\n    width: 12px;\n    height: 12px; }\n    .igv-menu-popup-check-container div:first-child svg {\n      position: absolute;\n      width: 12px;\n      height: 12px; }\n\n.igv-user-feedback {\n  position: fixed;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: 512px;\n  height: 360px;\n  z-index: 2048;\n  background-color: white;\n  border-color: #a2a2a2;\n  border-style: solid;\n  border-width: thin;\n  font-family: \"Open Sans\", sans-serif;\n  font-size: medium;\n  font-weight: 400;\n  color: #444;\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: center; }\n  .igv-user-feedback div:first-child {\n    position: relative;\n    height: 24px;\n    width: 100%;\n    background-color: white;\n    border-bottom-color: #a2a2a2;\n    border-bottom-style: solid;\n    border-bottom-width: thin; }\n    .igv-user-feedback div:first-child div {\n      position: absolute;\n      top: 2px;\n      width: 16px;\n      height: 16px;\n      background-color: transparent; }\n    .igv-user-feedback div:first-child div:first-child {\n      left: 8px; }\n    .igv-user-feedback div:first-child div:last-child {\n      cursor: pointer;\n      right: 8px; }\n  .igv-user-feedback div:last-child {\n    width: 100%;\n    height: calc(100% - 24px);\n    border-width: 0; }\n    .igv-user-feedback div:last-child div {\n      width: auto;\n      height: auto;\n      margin: 8px; }\n\n.igv-loading-spinner-container {\n  z-index: 1024;\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  width: 32px;\n  height: 32px;\n  display: flex;\n  flex-direction: row;\n  flex-wrap: nowrap;\n  justify-content: center;\n  align-items: center; }\n  .igv-loading-spinner-container > div {\n    box-sizing: border-box;\n    width: 100%;\n    height: 100%;\n    border-radius: 50%;\n    border: 4px solid rgba(128, 128, 128, 0.5);\n    border-top-color: white;\n    animation: spin 1s ease-in-out infinite;\n    -webkit-animation: spin 1s ease-in-out infinite; }\n\n@keyframes spin {\n  to {\n    -webkit-transform: rotate(360deg);\n    transform: rotate(360deg); } }\n@-webkit-keyframes spin {\n  to {\n    -webkit-transform: rotate(360deg);\n    transform: rotate(360deg); } }\n.igv-container {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: flex-start;\n  padding-top: 4px;\n  user-select: none;\n  -webkit-user-select: none;\n  -ms-user-select: none; }\n\n.igv-viewport {\n  position: relative;\n  margin-top: 5px;\n  overflow-x: hidden;\n  overflow-y: hidden; }\n\n.igv-viewport-content {\n  position: relative;\n  width: 100%; }\n  .igv-viewport-content > canvas {\n    position: relative;\n    display: block; }\n\n.igv-column-container {\n  position: relative;\n  display: flex;\n  flex-direction: row;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: stretch;\n  width: 100%; }\n\n.igv-column-shim {\n  width: 1px;\n  margin-left: 2px;\n  margin-right: 2px;\n  background-color: #545453; }\n\n.igv-column {\n  position: relative;\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: flex-start;\n  box-sizing: border-box;\n  height: 100%; }\n\n.igv-axis-column {\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: flex-start;\n  box-sizing: border-box;\n  height: 100%;\n  width: 50px; }\n  .igv-axis-column > div {\n    margin-top: 5px;\n    width: 100%; }\n\n.igv-sample-name-column {\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: flex-start;\n  box-sizing: border-box;\n  height: 100%; }\n\n.igv-scrollbar-column {\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: flex-start;\n  box-sizing: border-box;\n  height: 100%;\n  width: 14px; }\n  .igv-scrollbar-column > div {\n    position: relative;\n    margin-top: 5px;\n    width: 14px; }\n    .igv-scrollbar-column > div > div {\n      cursor: pointer;\n      position: absolute;\n      top: 0;\n      left: 2px;\n      width: 8px;\n      border-width: 1px;\n      border-style: solid;\n      border-color: #c4c4c4;\n      border-top-left-radius: 4px;\n      border-top-right-radius: 4px;\n      border-bottom-left-radius: 4px;\n      border-bottom-right-radius: 4px; }\n    .igv-scrollbar-column > div > div:hover {\n      background-color: #c4c4c4; }\n\n.igv-track-drag-column {\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: flex-start;\n  box-sizing: border-box;\n  height: 100%;\n  width: 12px;\n  background-color: white; }\n  .igv-track-drag-column > .igv-track-drag-handle {\n    z-index: 512;\n    position: relative;\n    cursor: pointer;\n    margin-top: 5px;\n    width: 100%;\n    border-style: solid;\n    border-width: 0;\n    border-top-right-radius: 6px;\n    border-bottom-right-radius: 6px;\n    background-color: #c4c4c4; }\n  .igv-track-drag-column .igv-track-drag-handle-hover {\n    background-color: #787878; }\n  .igv-track-drag-column > .igv-track-drag-shim {\n    position: relative;\n    margin-top: 5px;\n    width: 100%;\n    border-style: solid;\n    border-width: 0; }\n\n.igv-gear-menu-column {\n  display: flex;\n  flex-direction: column;\n  flex-wrap: nowrap;\n  justify-content: flex-start;\n  align-items: flex-start;\n  box-sizing: border-box;\n  height: 100%;\n  width: 28px; }\n  .igv-gear-menu-column > div {\n    display: flex;\n    flex-direction: column;\n    flex-wrap: nowrap;\n    justify-content: flex-start;
67585\n    align-items: center;\n    margin-top: 5px;\n    width: 100%;\n    background: white; }\n    .igv-gear-menu-column > div > div {\n      position: relative;\n      margin-top: 4px;\n      width: 16px;\n      height: 16px;\n      color: #7F7F7F; }\n    .igv-gear-menu-column > div > div:hover {\n      cursor: pointer;\n      color: #444; }\n\n/*# sourceMappingURL=dom.css.map */\n';
67586      var style = document.createElement('style');
67587      style.setAttribute('type', 'text/css');
67588      style.innerHTML = css;
67589      document.head.insertBefore(style, document.head.childNodes[document.head.childNodes.length - 1]);
67590    }
67591
67592    // Defines the top-level API for the igv module
67593    const setApiKey = igvxhr.setApiKey;
67594    embedCSS();
67595
67596    function setGoogleOauthToken(accessToken) {
67597      return oauth.setToken(accessToken);
67598    }
67599
67600    function setOauthToken(accessToken, host) {
67601      return oauth.setToken(accessToken, host);
67602    }
67603
67604    var index = {
67605      IGVGraphics,
67606      MenuUtils,
67607      DataRangeDialog,
67608      createTrack,
67609      createBrowser,
67610      removeBrowser,
67611      removeAllBrowsers,
67612      visibilityChange,
67613      setGoogleOauthToken,
67614      setOauthToken,
67615      oauth,
67616      version: version$1,
67617      setApiKey,
67618      doAutoscale,
67619      TrackView
67620    };
67621
67622    return index;
67623
67624}));</script>
67624
67625            <div id="myDiv" style="padding-top: 50px;padding-bottom: 20px; height: auto">
67626</div>
67627
67628<script type="module">
67629
67630    document.addEventListener("DOMContentLoaded", function () {
67631        var div = document.getElementById("myDiv");
67632        var options = {
67633            reference: {
67634                      id: "ce11",
67635                      fastaURL: "//storage.googleapis.com/elegansvariation.org/browser_tracks/c_elegans.PRJNA13758.WS245.genomic.fa"
67636                    },
67637            locus: "II:6710150-6712932",
67638            showNavigation: true,
67639            showKaryo: false,
67640            tracks: [
67641                {
67642                    name: "Genes",
67643                    displayMode: "EXPANDED",
67644                    order: 2,
67645                    url: "https://s3.eu-central-1.amazonaws.com/wormbuilder.dev/tracks/wormTracks/Genes_WS282.bed",
67646                    indexed: false,
67647                    searchable: true,
67648                    visibilityWindow: 250000,
67649                    color: "#2471A3",
67650		    altColor: "#C0392B"
67651                },
67652                {
67653                    name: "Alphafold confidence score",
67654		    order: 1,
67655                    type: "wig",
67656                    format: "bigWig",                  
67657                    url: "https://s3.eu-central-1.amazonaws.com/wormbuilder.dev/tracks/wormTracks/AF_confidence.bigwig",
67658                    visibilityWindow: 5000,
67659                    min: 0,
67660                    max: 100
67661                },
67662                {
67663                    name: "Transcripts",
67664                    displayMode: "EXPANDED",
67665                    order: 3,
67666                    url: "//s3.eu-central-1.amazonaws.com/wormbuilder.dev/tracks/wormTracks/c_elegans.WS282.WormBase.gff3",
67667                    indexURL: "https://s3.eu-central-1.amazonaws.com/wormbuilder.dev/tracks/wormTracks/c_elegans.WS282.WormBase.gff3.idx",
67668                    searchable: true,
67669                    visibilityWindow: 250000,
67670					height: 200,
67671                    color: "#2471A3",
67672		    altColor: "#C0392B"
67673                },
67674                {
67675                  name: "Library",
67676		  order: 4,
67677                  url: "https://s3.eu-central-1.amazonaws.com/wormbuilder.dev/tracks/wormTracks/crRNAlib.v4.bed",
67678		  indexURL: "https://s3.eu-central-1.amazonaws.com/wormbuilder.dev/tracks/wormTracks/crRNAlib.v4.bed.idx",
67679                  displayMode: "SQUISHED",
67680		  visibilityWindow: 100000,
67681                  autoHeight: true,
67682                  searchable: false 
67683                }
67684            ]
67685        };
67686
67687        igv.createBrowser(div, options)
67688
67689                        .then(function (browser) {
67690
67691
67692                    browser.on('trackclick', function (track, popoverData) {
67693                        var symbol = null;
67694                        popoverData.forEach(function (nameValue) {
67695                            if (nameValue.name && nameValue.name.toLowerCase() === 'name') {
67696                                symbol = nameValue.value;
67697                                Shiny.onInputChange("jsValue", symbol);
67698                            }
67699                        });
67700
67701                        // Prevent default pop-over behavior
67702                         return false;
67703
67704
67705                    });
67706
67707                    // Function to keep track of where the user is
67708                    //browser.on('locuschange', function (referenceFrame) {
67709                     //   Shiny.onInputChange("locationIGV", referenceFrame.label);
67710                        //Shiny.onInputChange("locationIGV", 'Hola');
67711                    //});
67712
67713                    browser.on('locuschange', function (referenceFrameList) {
67714                        let loc = referenceFrameList.map(rf => rf.getLocusString()).join('%20');
67715                        Shiny.onInputChange("locationIGV", loc);
67716                    });
67717
67718                });
67719
67720    });
67721</script>
67721
67722            <hr/>
67723            
67723<script>
67724                     Shiny.addCustomMessageHandler('gene-coordinates', function(coordinates) {
67725                     igv.browser.search(coordinates);
67726                     });
67727                                 </script>
67727
67728            <div id="genebrowsearch" class="shiny-html-output"></div>
67729            <pre id="igv_id" class="shiny-text-output noplaceholder"></pre>
67730            <pre id="ErrorMessageBrowser" class="shiny-text-output noplaceholder"></pre>
67731            <pre id="SimpleFragmentBrowser" class="shiny-text-output noplaceholder"></pre>
67732            <button id="userigvlocation" type="button" class="btn btn-default action-button">Display guide sequences seen in browser</button>
67733            <button id="userigvbasket" type="button" class="btn btn-default action-button">Send guide sequences seen in browser to basket</button>
67734            <hr/>
67735            <div id="SelPiTabBrowser" style="width:100%; height:auto; " class="datatables html-widget html-widget-output"></div>
67736          </div>
67737        </div>
67738        <div class="tab-pane" data-value="Basket" id="tab-3862-3">
67739          <div class="row">
67740            <h3>Download oligos in bulk</h3>
67741            <div id="BigBasket" style="width:100%; height:auto; " class="datatables html-widget html-widget-output"></div>
67742            <div id="DownloadBasket" class="shiny-html-output"></div>
67743          </div>
67744        </div>
67745        <div class="tab-pane" data-value="Downloads" id="tab-3862-4">
67746          <div class="row">
67747            <h3>Tracks</h3>
67748            <br>Bed track with protospacers (ce11/WS282)
67749                              <p align="justify">
67750                         <a href="https://s3.eu-central-1.amazonaws.com/wormbuilder.dev/tracks/wormTracks/crRNAlib.v4.bed">Download (45.5 MB)</a><br></p>
67751            <br>BigWig track with AlphaFold confidence scores (ce11/WS282)
67752                              <p align="justify">
67753                         <a href="https://s3.eu-central-1.amazonaws.com/wormbuilder.dev/tracks/wormTracks/AF_confidence.bigwig">Download (145 MB)</a><br></p>
67754          </div>
67755        </div>
67756        <div class="tab-pane" data-value="About" id="tab-3862-5">
67757          <div class="row">
67758            <h3><i>C. elegans</i> CRISPR-Cas9 library DB</h3>
67759            <p align="justify">
67760                      This website is generated via custom modified css/html code running in R via the shiny library.
67761                 <br>All the templates, libraries, and programs used to produce this site are under the MIT and GNU licenses.
67762                    <br>The R scripts and files to render this site can be found <a href="https://github.com/AmhedVargas/CRISPR_library_track">here</a></p>
67763                 This website was designed by <a href="https://scholar.google.com/citations?user=WokAqF8AAAAJ&hl=en&authuser=1">Mohammed Al-Johani</a> (<a href="https://www.linkedin.com/in/mohammedaljohani/">LinkedIn</a>), <a href="https://www.researchgate.net/profile/Amhed_Vargas_Velazquez">Amhed Missael Vargas Velazquez</a> (<a href="https://github.com/AmhedVargas">Github</a>), and 
67764                          <a href="https://www.kaust.edu.sa/en/study/faculty/christian-jensen">Christian Froekjaer-Jensen</a> from the Laboratory of Synthetic Genome Biology<br>
67765            <h3>The Laboratory of Synthetic Genome Biology</h3>
67766            <p align="justify">
67767                 The Laboratory of Synthetic Genome Biology is located in building 2 - level 3 (Ibn Al-Haytham – Above Spine) at King Abdullah University of Science and Technology (KAUST).
67768                 <br><i>Contact info</i>:<br>Christian-Froekjaer Jensen, Ph.D. 
67769                 <br>Associate Professor of Bioscience
67770                 <br><a href="https://wormbuilder.org/laboratory-of-synthetic-genome-biology/">Laboratory of Synthetic Genome Biology</a>
67771                 <br>Email: <a href="mailto:[email protected]">[email protected]</a>
67772                      </p>
67773          </div>
67774        </div>
67775      </div>
67776    </div>
67777    <hr/>
67778    <a href="https://www.kaust.edu.sa/en/study/faculty/christian-jensen">Froekjaer-Jensen Lab @KAUST</a><br>
67779    <a href="http://www.wormbuilder.org/">Wormbuilder</a><br>
67780    <a href="mailto:[email protected]">Contact us!</a>
67781  </div>
67782</body>
67783</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.