@macrostrat/cesium-martini 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3,12 +3,109 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var cesium = require('cesium');
6
- var ndarray = require('ndarray');
7
-
8
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
-
10
- var ndarray__default = /*#__PURE__*/_interopDefaultLegacy(ndarray);
11
6
 
7
+ function _arrayLikeToArray(r, a) {
8
+ (null == a || a > r.length) && (a = r.length);
9
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
10
+ return n;
11
+ }
12
+ function _arrayWithoutHoles(r) {
13
+ if (Array.isArray(r)) return _arrayLikeToArray(r);
14
+ }
15
+ function _assertThisInitialized(e) {
16
+ if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
17
+ return e;
18
+ }
19
+ function asyncGeneratorStep(n, t, e, r, o, a, c) {
20
+ try {
21
+ var i = n[a](c),
22
+ u = i.value;
23
+ } catch (n) {
24
+ return void e(n);
25
+ }
26
+ i.done ? t(u) : Promise.resolve(u).then(r, o);
27
+ }
28
+ function _asyncToGenerator(n) {
29
+ return function () {
30
+ var t = this,
31
+ e = arguments;
32
+ return new Promise(function (r, o) {
33
+ var a = n.apply(t, e);
34
+ function _next(n) {
35
+ asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
36
+ }
37
+ function _throw(n) {
38
+ asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
39
+ }
40
+ _next(void 0);
41
+ });
42
+ };
43
+ }
44
+ function _callSuper(t, o, e) {
45
+ return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
46
+ }
47
+ function _classCallCheck(a, n) {
48
+ if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
49
+ }
50
+ function _defineProperties(e, r) {
51
+ for (var t = 0; t < r.length; t++) {
52
+ var o = r[t];
53
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
54
+ }
55
+ }
56
+ function _createClass(e, r, t) {
57
+ return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
58
+ writable: !1
59
+ }), e;
60
+ }
61
+ function _defineProperty(e, r, t) {
62
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
63
+ value: t,
64
+ enumerable: !0,
65
+ configurable: !0,
66
+ writable: !0
67
+ }) : e[r] = t, e;
68
+ }
69
+ function _get() {
70
+ return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) {
71
+ var p = _superPropBase(e, t);
72
+ if (p) {
73
+ var n = Object.getOwnPropertyDescriptor(p, t);
74
+ return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value;
75
+ }
76
+ }, _get.apply(null, arguments);
77
+ }
78
+ function _getPrototypeOf(t) {
79
+ return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
80
+ return t.__proto__ || Object.getPrototypeOf(t);
81
+ }, _getPrototypeOf(t);
82
+ }
83
+ function _inherits(t, e) {
84
+ if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
85
+ t.prototype = Object.create(e && e.prototype, {
86
+ constructor: {
87
+ value: t,
88
+ writable: !0,
89
+ configurable: !0
90
+ }
91
+ }), Object.defineProperty(t, "prototype", {
92
+ writable: !1
93
+ }), e && _setPrototypeOf(t, e);
94
+ }
95
+ function _isNativeReflectConstruct() {
96
+ try {
97
+ var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
98
+ } catch (t) {}
99
+ return (_isNativeReflectConstruct = function () {
100
+ return !!t;
101
+ })();
102
+ }
103
+ function _iterableToArray(r) {
104
+ if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
105
+ }
106
+ function _nonIterableSpread() {
107
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
108
+ }
12
109
  function ownKeys(e, r) {
13
110
  var t = Object.keys(e);
14
111
  if (Object.getOwnPropertySymbols) {
@@ -30,6 +127,31 @@ function _objectSpread2(e) {
30
127
  }
31
128
  return e;
32
129
  }
130
+ function _objectWithoutProperties(e, t) {
131
+ if (null == e) return {};
132
+ var o,
133
+ r,
134
+ i = _objectWithoutPropertiesLoose(e, t);
135
+ if (Object.getOwnPropertySymbols) {
136
+ var n = Object.getOwnPropertySymbols(e);
137
+ for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
138
+ }
139
+ return i;
140
+ }
141
+ function _objectWithoutPropertiesLoose(r, e) {
142
+ if (null == r) return {};
143
+ var t = {};
144
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
145
+ if (-1 !== e.indexOf(n)) continue;
146
+ t[n] = r[n];
147
+ }
148
+ return t;
149
+ }
150
+ function _possibleConstructorReturn(t, e) {
151
+ if (e && ("object" == typeof e || "function" == typeof e)) return e;
152
+ if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
153
+ return _assertThisInitialized(t);
154
+ }
33
155
  function _regeneratorRuntime() {
34
156
  _regeneratorRuntime = function () {
35
157
  return e;
@@ -138,7 +260,7 @@ function _regeneratorRuntime() {
138
260
  function makeInvokeMethod(e, r, n) {
139
261
  var o = h;
140
262
  return function (i, a) {
141
- if (o === f) throw new Error("Generator is already running");
263
+ if (o === f) throw Error("Generator is already running");
142
264
  if (o === s) {
143
265
  if ("throw" === i) throw a;
144
266
  return {
@@ -280,7 +402,7 @@ function _regeneratorRuntime() {
280
402
  } else if (c) {
281
403
  if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
282
404
  } else {
283
- if (!u) throw new Error("try statement without catch or finally");
405
+ if (!u) throw Error("try statement without catch or finally");
284
406
  if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
285
407
  }
286
408
  }
@@ -320,7 +442,7 @@ function _regeneratorRuntime() {
320
442
  return o;
321
443
  }
322
444
  }
323
- throw new Error("illegal catch attempt");
445
+ throw Error("illegal catch attempt");
324
446
  },
325
447
  delegateYield: function (e, r, n) {
326
448
  return this.delegate = {
@@ -331,258 +453,80 @@ function _regeneratorRuntime() {
331
453
  }
332
454
  }, e;
333
455
  }
334
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
335
- try {
336
- var info = gen[key](arg);
337
- var value = info.value;
338
- } catch (error) {
339
- reject(error);
340
- return;
341
- }
342
- if (info.done) {
343
- resolve(value);
344
- } else {
345
- Promise.resolve(value).then(_next, _throw);
346
- }
347
- }
348
- function _asyncToGenerator(fn) {
349
- return function () {
350
- var self = this,
351
- args = arguments;
352
- return new Promise(function (resolve, reject) {
353
- var gen = fn.apply(self, args);
354
- function _next(value) {
355
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
356
- }
357
- function _throw(err) {
358
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
359
- }
360
- _next(undefined);
361
- });
362
- };
363
- }
364
- function _classCallCheck(instance, Constructor) {
365
- if (!(instance instanceof Constructor)) {
366
- throw new TypeError("Cannot call a class as a function");
367
- }
368
- }
369
- function _defineProperties(target, props) {
370
- for (var i = 0; i < props.length; i++) {
371
- var descriptor = props[i];
372
- descriptor.enumerable = descriptor.enumerable || false;
373
- descriptor.configurable = true;
374
- if ("value" in descriptor) descriptor.writable = true;
375
- Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
376
- }
377
- }
378
- function _createClass(Constructor, protoProps, staticProps) {
379
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
380
- if (staticProps) _defineProperties(Constructor, staticProps);
381
- Object.defineProperty(Constructor, "prototype", {
382
- writable: false
383
- });
384
- return Constructor;
385
- }
386
- function _defineProperty(obj, key, value) {
387
- key = _toPropertyKey(key);
388
- if (key in obj) {
389
- Object.defineProperty(obj, key, {
390
- value: value,
391
- enumerable: true,
392
- configurable: true,
393
- writable: true
394
- });
395
- } else {
396
- obj[key] = value;
397
- }
398
- return obj;
456
+ function _setPrototypeOf(t, e) {
457
+ return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
458
+ return t.__proto__ = e, t;
459
+ }, _setPrototypeOf(t, e);
399
460
  }
400
- function _inherits(subClass, superClass) {
401
- if (typeof superClass !== "function" && superClass !== null) {
402
- throw new TypeError("Super expression must either be null or a function");
403
- }
404
- subClass.prototype = Object.create(superClass && superClass.prototype, {
405
- constructor: {
406
- value: subClass,
407
- writable: true,
408
- configurable: true
409
- }
410
- });
411
- Object.defineProperty(subClass, "prototype", {
412
- writable: false
413
- });
414
- if (superClass) _setPrototypeOf(subClass, superClass);
415
- }
416
- function _getPrototypeOf(o) {
417
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
418
- return o.__proto__ || Object.getPrototypeOf(o);
419
- };
420
- return _getPrototypeOf(o);
421
- }
422
- function _setPrototypeOf(o, p) {
423
- _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
424
- o.__proto__ = p;
425
- return o;
426
- };
427
- return _setPrototypeOf(o, p);
461
+ function _superPropBase(t, o) {
462
+ for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t)););
463
+ return t;
428
464
  }
429
- function _isNativeReflectConstruct() {
430
- if (typeof Reflect === "undefined" || !Reflect.construct) return false;
431
- if (Reflect.construct.sham) return false;
432
- if (typeof Proxy === "function") return true;
433
- try {
434
- Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
435
- return true;
436
- } catch (e) {
437
- return false;
438
- }
465
+ function _superPropGet(t, o, e, r) {
466
+ var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e);
467
+ return 2 & r && "function" == typeof p ? function (t) {
468
+ return p.apply(e, t);
469
+ } : p;
439
470
  }
440
- function _assertThisInitialized(self) {
441
- if (self === void 0) {
442
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
443
- }
444
- return self;
471
+ function _toConsumableArray(r) {
472
+ return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
445
473
  }
446
- function _possibleConstructorReturn(self, call) {
447
- if (call && (typeof call === "object" || typeof call === "function")) {
448
- return call;
449
- } else if (call !== void 0) {
450
- throw new TypeError("Derived constructors may only return object or undefined");
474
+ function _toPrimitive(t, r) {
475
+ if ("object" != typeof t || !t) return t;
476
+ var e = t[Symbol.toPrimitive];
477
+ if (void 0 !== e) {
478
+ var i = e.call(t, r || "default");
479
+ if ("object" != typeof i) return i;
480
+ throw new TypeError("@@toPrimitive must return a primitive value.");
451
481
  }
452
- return _assertThisInitialized(self);
482
+ return ("string" === r ? String : Number)(t);
453
483
  }
454
- function _createSuper(Derived) {
455
- var hasNativeReflectConstruct = _isNativeReflectConstruct();
456
- return function _createSuperInternal() {
457
- var Super = _getPrototypeOf(Derived),
458
- result;
459
- if (hasNativeReflectConstruct) {
460
- var NewTarget = _getPrototypeOf(this).constructor;
461
- result = Reflect.construct(Super, arguments, NewTarget);
462
- } else {
463
- result = Super.apply(this, arguments);
464
- }
465
- return _possibleConstructorReturn(this, result);
466
- };
484
+ function _toPropertyKey(t) {
485
+ var i = _toPrimitive(t, "string");
486
+ return "symbol" == typeof i ? i : i + "";
467
487
  }
468
- function _superPropBase(object, property) {
469
- while (!Object.prototype.hasOwnProperty.call(object, property)) {
470
- object = _getPrototypeOf(object);
471
- if (object === null) break;
488
+ function _unsupportedIterableToArray(r, a) {
489
+ if (r) {
490
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
491
+ var t = {}.toString.call(r).slice(8, -1);
492
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
472
493
  }
473
- return object;
474
- }
475
- function _get() {
476
- if (typeof Reflect !== "undefined" && Reflect.get) {
477
- _get = Reflect.get.bind();
478
- } else {
479
- _get = function _get(target, property, receiver) {
480
- var base = _superPropBase(target, property);
481
- if (!base) return;
482
- var desc = Object.getOwnPropertyDescriptor(base, property);
483
- if (desc.get) {
484
- return desc.get.call(arguments.length < 3 ? target : receiver);
485
- }
486
- return desc.value;
487
- };
488
- }
489
- return _get.apply(this, arguments);
490
- }
491
- function _toConsumableArray(arr) {
492
- return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
493
- }
494
- function _arrayWithoutHoles(arr) {
495
- if (Array.isArray(arr)) return _arrayLikeToArray(arr);
496
- }
497
- function _iterableToArray(iter) {
498
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
499
- }
500
- function _unsupportedIterableToArray(o, minLen) {
501
- if (!o) return;
502
- if (typeof o === "string") return _arrayLikeToArray(o, minLen);
503
- var n = Object.prototype.toString.call(o).slice(8, -1);
504
- if (n === "Object" && o.constructor) n = o.constructor.name;
505
- if (n === "Map" || n === "Set") return Array.from(o);
506
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
507
- }
508
- function _arrayLikeToArray(arr, len) {
509
- if (len == null || len > arr.length) len = arr.length;
510
- for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
511
- return arr2;
512
- }
513
- function _nonIterableSpread() {
514
- throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
515
- }
516
- function _toPrimitive(input, hint) {
517
- if (typeof input !== "object" || input === null) return input;
518
- var prim = input[Symbol.toPrimitive];
519
- if (prim !== undefined) {
520
- var res = prim.call(input, hint || "default");
521
- if (typeof res !== "object") return res;
522
- throw new TypeError("@@toPrimitive must return a primitive value.");
523
- }
524
- return (hint === "string" ? String : Number)(input);
525
- }
526
- function _toPropertyKey(arg) {
527
- var key = _toPrimitive(arg, "string");
528
- return typeof key === "symbol" ? key : String(key);
529
494
  }
530
495
 
531
- var loadImage = function loadImage(url) {
532
- return new Promise(function (resolve, reject) {
533
- var img = new Image();
534
- img.addEventListener("load", function () {
535
- return resolve(img);
536
- });
537
- img.addEventListener("error", function (err) {
538
- return reject(err);
539
- });
540
- img.crossOrigin = "anonymous";
541
- img.src = url;
542
- });
543
- };
544
496
  var DefaultHeightmapResource = /*#__PURE__*/function () {
545
497
  function DefaultHeightmapResource() {
546
- var _this = this,
547
- _opts$skipOddLevels,
548
- _opts$tileSize,
549
- _opts$maxZoom;
498
+ var _opts$tileSize, _opts$maxZoom;
550
499
  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
551
500
  _classCallCheck(this, DefaultHeightmapResource);
552
501
  _defineProperty(this, "resource", null);
553
502
  _defineProperty(this, "tileSize", 256);
554
- _defineProperty(this, "skipOddLevels", false);
555
- _defineProperty(this, "getTilePixels", /*#__PURE__*/function () {
556
- var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(coords) {
557
- var url, img;
558
- return _regeneratorRuntime().wrap(function _callee$(_context) {
559
- while (1) switch (_context.prev = _context.next) {
560
- case 0:
561
- url = _this.buildTileURL(coords);
562
- _context.next = 3;
563
- return loadImage(url);
564
- case 3:
565
- img = _context.sent;
566
- return _context.abrupt("return", _this.getPixels(img));
567
- case 5:
568
- case "end":
569
- return _context.stop();
570
- }
571
- }, _callee);
572
- }));
573
- return function (_x) {
574
- return _ref.apply(this, arguments);
575
- };
576
- }());
577
503
  if (opts.url) {
578
- this.resource = cesium.Resource.createIfNeeded(opts.url);
504
+ this.resource = new cesium.Resource({
505
+ url: opts.url
506
+ });
507
+ }
508
+ this.skipZoomLevel = function () {
509
+ return false;
510
+ };
511
+ if (opts.skipZoomLevels) {
512
+ if (Array.isArray(opts.skipZoomLevels)) {
513
+ var _skipZoomLevels = opts.skipZoomLevels;
514
+ this.skipZoomLevel = function (z) {
515
+ return _skipZoomLevels.includes(z);
516
+ };
517
+ } else {
518
+ this.skipZoomLevel = opts.skipZoomLevels;
519
+ }
520
+ } else if (opts.skipOddLevels) {
521
+ this.skipZoomLevel = function (z) {
522
+ return z % 2 == 1;
523
+ };
579
524
  }
580
- this.skipOddLevels = (_opts$skipOddLevels = opts.skipOddLevels) !== null && _opts$skipOddLevels !== void 0 ? _opts$skipOddLevels : false;
581
525
  this.tileSize = (_opts$tileSize = opts.tileSize) !== null && _opts$tileSize !== void 0 ? _opts$tileSize : 256;
582
526
  this.maxZoom = (_opts$maxZoom = opts.maxZoom) !== null && _opts$maxZoom !== void 0 ? _opts$maxZoom : 15;
583
527
  this.contextQueue = [];
584
528
  }
585
- _createClass(DefaultHeightmapResource, [{
529
+ return _createClass(DefaultHeightmapResource, [{
586
530
  key: "getCanvas",
587
531
  value: function getCanvas() {
588
532
  var ctx = this.contextQueue.pop();
@@ -613,31 +557,52 @@ var DefaultHeightmapResource = /*#__PURE__*/function () {
613
557
  return pixels;
614
558
  }
615
559
  }, {
616
- key: "buildTileURL",
617
- value: function buildTileURL(tileCoords) {
618
- var _this$resource;
560
+ key: "getTileResource",
561
+ value: function getTileResource(tileCoords) {
619
562
  // reverseY for TMS tiling (https://gist.github.com/tmcw/4954720)
620
563
  // See tiling schemes here: https://www.maptiler.com/google-maps-coordinates-tile-bounds-projection/
621
564
  var z = tileCoords.z,
622
565
  y = tileCoords.y;
623
- return (_this$resource = this.resource) === null || _this$resource === void 0 ? void 0 : _this$resource.getDerivedResource({
566
+ return this.resource.getDerivedResource({
624
567
  templateValues: _objectSpread2(_objectSpread2({}, tileCoords), {}, {
625
568
  reverseY: Math.pow(2, z) - y - 1
626
569
  }),
627
570
  preserveQueryParameters: true
628
- }).getUrlComponent(true);
571
+ });
572
+ }
573
+ }, {
574
+ key: "getTilePixels",
575
+ value: function getTilePixels(coords) {
576
+ var _this = this;
577
+ var resource = this.getTileResource(coords);
578
+ var request = resource.fetchImage({
579
+ preferImageBitmap: false,
580
+ // @ts-ignore
581
+ retryAttempts: 3
582
+ });
583
+ if (request == null) return undefined;
584
+ return request.then(function (img) {
585
+ return (
586
+ // @ts-ignore
587
+ _this.getPixels(img)
588
+ );
589
+ });
629
590
  }
630
591
  }, {
631
592
  key: "getTileDataAvailable",
632
- value: function getTileDataAvailable(_ref2) {
633
- var z = _ref2.z;
593
+ value: function getTileDataAvailable(_ref) {
594
+ var z = _ref.z;
634
595
  if (z == this.maxZoom) return true;
635
- if (z % 2 == 1 && this.skipOddLevels) return false;
596
+ /* Weird hack:
597
+ For some reason, request render mode breaks if zoom 1 tiles are disabled.
598
+ So we have to make sure that we always report zoom 1 tiles as available.
599
+ */
600
+ if (z < 2) return true;
601
+ if (this.skipZoomLevel(z)) return false;
636
602
  if (z > this.maxZoom) return false;
637
603
  return true;
638
604
  }
639
605
  }]);
640
- return DefaultHeightmapResource;
641
606
  }();
642
607
 
643
608
  var ImageFormat = /*#__PURE__*/function (ImageFormat) {
@@ -647,17 +612,17 @@ var ImageFormat = /*#__PURE__*/function (ImageFormat) {
647
612
  return ImageFormat;
648
613
  }({});
649
614
  var MapboxTerrainResource = /*#__PURE__*/function (_DefaultHeightmapReso) {
650
- _inherits(MapboxTerrainResource, _DefaultHeightmapReso);
651
- var _super = _createSuper(MapboxTerrainResource);
652
615
  function MapboxTerrainResource() {
653
616
  var _opts$highResolution, _opts$imageFormat;
654
617
  var _this;
655
618
  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
656
619
  _classCallCheck(this, MapboxTerrainResource);
657
- _this = _super.call(this, opts);
658
- _defineProperty(_assertThisInitialized(_this), "resource", null);
620
+ _this = _callSuper(this, MapboxTerrainResource, [opts]);
621
+ _defineProperty(_this, "resource", null);
622
+ _defineProperty(_this, "credit", new cesium.Credit("Mapbox"));
659
623
  var highResolution = (_opts$highResolution = opts.highResolution) !== null && _opts$highResolution !== void 0 ? _opts$highResolution : false;
660
624
  var format = (_opts$imageFormat = opts.imageFormat) !== null && _opts$imageFormat !== void 0 ? _opts$imageFormat : ImageFormat.WEBP;
625
+ var urlTemplate = opts.urlTemplate;
661
626
 
662
627
  // overrides based on highResolution flag
663
628
  if (highResolution) {
@@ -668,7 +633,10 @@ var MapboxTerrainResource = /*#__PURE__*/function (_DefaultHeightmapReso) {
668
633
  _this.tileSize = 512;
669
634
  }
670
635
  }
671
- _this.resource = cesium.Resource.createIfNeeded("https://api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}".concat(highResolution ? "@2x" : "", ".").concat(format));
636
+ var defaultURL = "https://api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}".concat(highResolution ? "@2x" : "", ".").concat(format);
637
+ _this.resource = new cesium.Resource({
638
+ url: urlTemplate !== null && urlTemplate !== void 0 ? urlTemplate : defaultURL
639
+ });
672
640
  if (opts.accessToken) {
673
641
  _this.resource.setQueryParameters({
674
642
  access_token: opts.accessToken
@@ -676,153 +644,33 @@ var MapboxTerrainResource = /*#__PURE__*/function (_DefaultHeightmapReso) {
676
644
  }
677
645
  return _this;
678
646
  }
647
+ _inherits(MapboxTerrainResource, _DefaultHeightmapReso);
679
648
  return _createClass(MapboxTerrainResource);
680
649
  }(DefaultHeightmapResource);
681
650
 
682
- function decodeBase64(base64, enableUnicode) {
683
- var binaryString = atob(base64);
684
- if (enableUnicode) {
685
- var binaryView = new Uint8Array(binaryString.length);
686
- for (var i = 0, n = binaryString.length; i < n; ++i) {
687
- binaryView[i] = binaryString.charCodeAt(i);
688
- }
689
- return String.fromCharCode.apply(null, new Uint16Array(binaryView.buffer));
690
- }
691
- return binaryString;
692
- }
693
-
694
- function createURL(base64, sourcemapArg, enableUnicodeArg) {
695
- var sourcemap = sourcemapArg === undefined ? null : sourcemapArg;
696
- var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg;
697
- var source = decodeBase64(base64, enableUnicode);
698
- var start = source.indexOf('\n', 10) + 1;
699
- var body = source.substring(start) + (sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : '');
700
- var blob = new Blob([body], { type: 'application/javascript' });
701
- return URL.createObjectURL(blob);
702
- }
703
-
704
- function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) {
705
- var url;
706
- return function WorkerFactory(options) {
707
- url = url || createURL(base64, sourcemapArg, enableUnicodeArg);
708
- return new Worker(url, options);
709
- };
710
- }
711
-
712
- var WorkerFactory = createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwp2YXIgd29ya2VyX2NvZGUgPSAoZnVuY3Rpb24gKGV4cG9ydHMpIHsKICAndXNlIHN0cmljdCc7CgogIGZ1bmN0aW9uIF90b0NvbnN1bWFibGVBcnJheShhcnIpIHsKICAgIHJldHVybiBfYXJyYXlXaXRob3V0SG9sZXMoYXJyKSB8fCBfaXRlcmFibGVUb0FycmF5KGFycikgfHwgX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KGFycikgfHwgX25vbkl0ZXJhYmxlU3ByZWFkKCk7CiAgfQogIGZ1bmN0aW9uIF9hcnJheVdpdGhvdXRIb2xlcyhhcnIpIHsKICAgIGlmIChBcnJheS5pc0FycmF5KGFycikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShhcnIpOwogIH0KICBmdW5jdGlvbiBfaXRlcmFibGVUb0FycmF5KGl0ZXIpIHsKICAgIGlmICh0eXBlb2YgU3ltYm9sICE9PSAidW5kZWZpbmVkIiAmJiBpdGVyW1N5bWJvbC5pdGVyYXRvcl0gIT0gbnVsbCB8fCBpdGVyWyJAQGl0ZXJhdG9yIl0gIT0gbnVsbCkgcmV0dXJuIEFycmF5LmZyb20oaXRlcik7CiAgfQogIGZ1bmN0aW9uIF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShvLCBtaW5MZW4pIHsKICAgIGlmICghbykgcmV0dXJuOwogICAgaWYgKHR5cGVvZiBvID09PSAic3RyaW5nIikgcmV0dXJuIF9hcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7CiAgICB2YXIgbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKS5zbGljZSg4LCAtMSk7CiAgICBpZiAobiA9PT0gIk9iamVjdCIgJiYgby5jb25zdHJ1Y3RvcikgbiA9IG8uY29uc3RydWN0b3IubmFtZTsKICAgIGlmIChuID09PSAiTWFwIiB8fCBuID09PSAiU2V0IikgcmV0dXJuIEFycmF5LmZyb20obyk7CiAgICBpZiAobiA9PT0gIkFyZ3VtZW50cyIgfHwgL14oPzpVaXxJKW50KD86OHwxNnwzMikoPzpDbGFtcGVkKT9BcnJheSQvLnRlc3QobikpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pOwogIH0KICBmdW5jdGlvbiBfYXJyYXlMaWtlVG9BcnJheShhcnIsIGxlbikgewogICAgaWYgKGxlbiA9PSBudWxsIHx8IGxlbiA+IGFyci5sZW5ndGgpIGxlbiA9IGFyci5sZW5ndGg7CiAgICBmb3IgKHZhciBpID0gMCwgYXJyMiA9IG5ldyBBcnJheShsZW4pOyBpIDwgbGVuOyBpKyspIGFycjJbaV0gPSBhcnJbaV07CiAgICByZXR1cm4gYXJyMjsKICB9CiAgZnVuY3Rpb24gX25vbkl0ZXJhYmxlU3ByZWFkKCkgewogICAgdGhyb3cgbmV3IFR5cGVFcnJvcigiSW52YWxpZCBhdHRlbXB0IHRvIHNwcmVhZCBub24taXRlcmFibGUgaW5zdGFuY2UuXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuIik7CiAgfQoKICAvLyBXZSBzaG91bGQgc2F2ZSB0aGVzZQogIC8vY29uc3QgY2FudmFzID0gbmV3IE9mZnNjcmVlbkNhbnZhcygyNTYsIDI1Nik7CiAgLy9jb25zdCBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgiMmQiKTsKCiAgZnVuY3Rpb24gbWFwYm94VGVycmFpblRvR3JpZChwbmcsIGludGVydmFsLCBvZmZzZXQpIHsKICAgIHZhciBfaW50ZXJ2YWwsIF9vZmZzZXQ7CiAgICAvLyBtYXliZSB3ZSBzaG91bGQgZG8gdGhpcyBvbiB0aGUgR1BVIHVzaW5nIFJFR0w/CiAgICAvLyBidXQgdGhhdCB3b3VsZCByZXF1aXJlIEdQVSAtPiBDUFUgLT4gR1BVCiAgICB2YXIgZ3JpZFNpemUgPSBwbmcuc2hhcGVbMF0gKyAxOwogICAgdmFyIHRlcnJhaW4gPSBuZXcgRmxvYXQzMkFycmF5KGdyaWRTaXplICogZ3JpZFNpemUpOwogICAgdmFyIHRpbGVTaXplID0gcG5nLnNoYXBlWzBdOwogICAgaW50ZXJ2YWwgPSAoX2ludGVydmFsID0gaW50ZXJ2YWwpICE9PSBudWxsICYmIF9pbnRlcnZhbCAhPT0gdm9pZCAwID8gX2ludGVydmFsIDogMC4xOwogICAgb2Zmc2V0ID0gKF9vZmZzZXQgPSBvZmZzZXQpICE9PSBudWxsICYmIF9vZmZzZXQgIT09IHZvaWQgMCA/IF9vZmZzZXQgOiAtMTAwMDA7CgogICAgLy8gZGVjb2RlIHRlcnJhaW4gdmFsdWVzCiAgICBmb3IgKHZhciB5ID0gMDsgeSA8IHRpbGVTaXplOyB5KyspIHsKICAgICAgZm9yICh2YXIgeCA9IDA7IHggPCB0aWxlU2l6ZTsgeCsrKSB7CiAgICAgICAgdmFyIHljID0geTsKICAgICAgICB2YXIgciA9IHBuZy5nZXQoeCwgeWMsIDApOwogICAgICAgIHZhciBnID0gcG5nLmdldCh4LCB5YywgMSk7CiAgICAgICAgdmFyIGIgPSBwbmcuZ2V0KHgsIHljLCAyKTsKICAgICAgICB0ZXJyYWluW3kgKiBncmlkU2l6ZSArIHhdID0gciAqIDI1NiAqIDI1NiAqIGludGVydmFsICsgZyAqIDI1Ni4wICogaW50ZXJ2YWwgKyBiICogaW50ZXJ2YWwgKyBvZmZzZXQ7CiAgICAgIH0KICAgIH0KICAgIC8vIGJhY2tmaWxsIHJpZ2h0IGFuZCBib3R0b20gYm9yZGVycwogICAgZm9yICh2YXIgX3ggPSAwOyBfeCA8IGdyaWRTaXplIC0gMTsgX3grKykgewogICAgICB0ZXJyYWluW2dyaWRTaXplICogKGdyaWRTaXplIC0gMSkgKyBfeF0gPSB0ZXJyYWluW2dyaWRTaXplICogKGdyaWRTaXplIC0gMikgKyBfeF07CiAgICB9CiAgICBmb3IgKHZhciBfeSA9IDA7IF95IDwgZ3JpZFNpemU7IF95KyspIHsKICAgICAgdGVycmFpbltncmlkU2l6ZSAqIF95ICsgZ3JpZFNpemUgLSAxXSA9IHRlcnJhaW5bZ3JpZFNpemUgKiBfeSArIGdyaWRTaXplIC0gMl07CiAgICB9CiAgICByZXR1cm4gdGVycmFpbjsKICB9CiAgZnVuY3Rpb24gY3JlYXRlUXVhbnRpemVkTWVzaERhdGEodGlsZSwgbWVzaCwgdGlsZVNpemUpIHsKICAgIHZhciB4dmFscyA9IFtdOwogICAgdmFyIHl2YWxzID0gW107CiAgICB2YXIgaGVpZ2h0TWV0ZXJzID0gW107CiAgICB2YXIgbm9ydGhJbmRpY2VzID0gW107CiAgICB2YXIgc291dGhJbmRpY2VzID0gW107CiAgICB2YXIgZWFzdEluZGljZXMgPSBbXTsKICAgIHZhciB3ZXN0SW5kaWNlcyA9IFtdOwogICAgdmFyIG1pbmltdW1IZWlnaHQgPSBJbmZpbml0eTsKICAgIHZhciBtYXhpbXVtSGVpZ2h0ID0gLUluZmluaXR5OwogICAgdmFyIHNjYWxhciA9IDMyNzY4LjAgLyB0aWxlU2l6ZTsKICAgIGZvciAodmFyIGl4ID0gMDsgaXggPCBtZXNoLnZlcnRpY2VzLmxlbmd0aCAvIDI7IGl4KyspIHsKICAgICAgdmFyIHZlcnRleEl4ID0gaXg7CiAgICAgIHZhciBweCA9IG1lc2gudmVydGljZXNbaXggKiAyXTsKICAgICAgdmFyIHB5ID0gbWVzaC52ZXJ0aWNlc1tpeCAqIDIgKyAxXTsKICAgICAgdmFyIGhlaWdodCA9IHRpbGUudGVycmFpbltweSAqICh0aWxlU2l6ZSArIDEpICsgcHhdOwogICAgICBpZiAoaGVpZ2h0ID4gbWF4aW11bUhlaWdodCkgbWF4aW11bUhlaWdodCA9IGhlaWdodDsKICAgICAgaWYgKGhlaWdodCA8IG1pbmltdW1IZWlnaHQpIG1pbmltdW1IZWlnaHQgPSBoZWlnaHQ7CiAgICAgIGhlaWdodE1ldGVycy5wdXNoKGhlaWdodCk7CiAgICAgIGlmIChweSA9PSAwKSBub3J0aEluZGljZXMucHVzaCh2ZXJ0ZXhJeCk7CiAgICAgIGlmIChweSA9PSB0aWxlU2l6ZSkgc291dGhJbmRpY2VzLnB1c2godmVydGV4SXgpOwogICAgICBpZiAocHggPT0gMCkgd2VzdEluZGljZXMucHVzaCh2ZXJ0ZXhJeCk7CiAgICAgIGlmIChweCA9PSB0aWxlU2l6ZSkgZWFzdEluZGljZXMucHVzaCh2ZXJ0ZXhJeCk7CiAgICAgIHZhciB4diA9IHB4ICogc2NhbGFyOwogICAgICB2YXIgeXYgPSAodGlsZVNpemUgLSBweSkgKiBzY2FsYXI7CiAgICAgIHh2YWxzLnB1c2goeHYpOwogICAgICB5dmFscy5wdXNoKHl2KTsKICAgIH0KICAgIHZhciBoZWlnaHRSYW5nZSA9IG1heGltdW1IZWlnaHQgLSBtaW5pbXVtSGVpZ2h0OwogICAgdmFyIGhlaWdodHMgPSBoZWlnaHRNZXRlcnMubWFwKGZ1bmN0aW9uIChkKSB7CiAgICAgIGlmIChoZWlnaHRSYW5nZSA8IDEpIHJldHVybiAwOwogICAgICByZXR1cm4gKGQgLSBtaW5pbXVtSGVpZ2h0KSAqICgzMjc2Ny4wIC8gaGVpZ2h0UmFuZ2UpOwogICAgfSk7CiAgICB2YXIgdHJpYW5nbGVzID0gbmV3IFVpbnQxNkFycmF5KG1lc2gudHJpYW5nbGVzKTsKICAgIHZhciBxdWFudGl6ZWRWZXJ0aWNlcyA9IG5ldyBVaW50MTZBcnJheSggLy92ZXJ0cwogICAgW10uY29uY2F0KHh2YWxzLCB5dmFscywgX3RvQ29uc3VtYWJsZUFycmF5KGhlaWdodHMpKSk7CgogICAgLy8gU0UgTlcgTkUKICAgIC8vIE5FIE5XIFNFCgogICAgcmV0dXJuIHsKICAgICAgbWluaW11bUhlaWdodDogbWluaW11bUhlaWdodCwKICAgICAgbWF4aW11bUhlaWdodDogbWF4aW11bUhlaWdodCwKICAgICAgcXVhbnRpemVkVmVydGljZXM6IHF1YW50aXplZFZlcnRpY2VzLAogICAgICBpbmRpY2VzOiB0cmlhbmdsZXMsCiAgICAgIHdlc3RJbmRpY2VzOiB3ZXN0SW5kaWNlcywKICAgICAgc291dGhJbmRpY2VzOiBzb3V0aEluZGljZXMsCiAgICAgIGVhc3RJbmRpY2VzOiBlYXN0SW5kaWNlcywKICAgICAgbm9ydGhJbmRpY2VzOiBub3J0aEluZGljZXMKICAgIH07CiAgfQoKICBmdW5jdGlvbiBpb3RhKG4pIHsKICAgIHZhciByZXN1bHQgPSBuZXcgQXJyYXkobik7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSkgewogICAgICByZXN1bHRbaV0gPSBpOwogICAgfQogICAgcmV0dXJuIHJlc3VsdDsKICB9CiAgdmFyIGlvdGFfMSA9IGlvdGE7CgogIC8qIQogICAqIERldGVybWluZSBpZiBhbiBvYmplY3QgaXMgYSBCdWZmZXIKICAgKgogICAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxodHRwczovL2Zlcm9zcy5vcmc+CiAgICogQGxpY2Vuc2UgIE1JVAogICAqLwogIC8vIFRoZSBfaXNCdWZmZXIgY2hlY2sgaXMgZm9yIFNhZmFyaSA1LTcgc3VwcG9ydCwgYmVjYXVzZSBpdCdzIG1pc3NpbmcKICAvLyBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yLiBSZW1vdmUgdGhpcyBldmVudHVhbGx5CiAgdmFyIGlzQnVmZmVyXzEgPSBmdW5jdGlvbiAob2JqKSB7CiAgICByZXR1cm4gb2JqICE9IG51bGwgJiYgKGlzQnVmZmVyKG9iaikgfHwgaXNTbG93QnVmZmVyKG9iaikgfHwgISFvYmouX2lzQnVmZmVyKTsKICB9OwogIGZ1bmN0aW9uIGlzQnVmZmVyKG9iaikgewogICAgcmV0dXJuICEhb2JqLmNvbnN0cnVjdG9yICYmIHR5cGVvZiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIgPT09ICdmdW5jdGlvbicgJiYgb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyKG9iaik7CiAgfQoKICAvLyBGb3IgTm9kZSB2MC4xMCBzdXBwb3J0LiBSZW1vdmUgdGhpcyBldmVudHVhbGx5LgogIGZ1bmN0aW9uIGlzU2xvd0J1ZmZlcihvYmopIHsKICAgIHJldHVybiB0eXBlb2Ygb2JqLnJlYWRGbG9hdExFID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBvYmouc2xpY2UgPT09ICdmdW5jdGlvbicgJiYgaXNCdWZmZXIob2JqLnNsaWNlKDAsIDApKTsKICB9CgogIHZhciBoYXNUeXBlZEFycmF5cyA9IHR5cGVvZiBGbG9hdDY0QXJyYXkgIT09ICJ1bmRlZmluZWQiOwogIGZ1bmN0aW9uIGNvbXBhcmUxc3QoYSwgYikgewogICAgcmV0dXJuIGFbMF0gLSBiWzBdOwogIH0KICBmdW5jdGlvbiBvcmRlcigpIHsKICAgIHZhciBzdHJpZGUgPSB0aGlzLnN0cmlkZTsKICAgIHZhciB0ZXJtcyA9IG5ldyBBcnJheShzdHJpZGUubGVuZ3RoKTsKICAgIHZhciBpOwogICAgZm9yIChpID0gMDsgaSA8IHRlcm1zLmxlbmd0aDsgKytpKSB7CiAgICAgIHRlcm1zW2ldID0gW01hdGguYWJzKHN0cmlkZVtpXSksIGldOwogICAgfQogICAgdGVybXMuc29ydChjb21wYXJlMXN0KTsKICAgIHZhciByZXN1bHQgPSBuZXcgQXJyYXkodGVybXMubGVuZ3RoKTsKICAgIGZvciAoaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyArK2kpIHsKICAgICAgcmVzdWx0W2ldID0gdGVybXNbaV1bMV07CiAgICB9CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICBmdW5jdGlvbiBjb21waWxlQ29uc3RydWN0b3IoZHR5cGUsIGRpbWVuc2lvbikgewogICAgdmFyIGNsYXNzTmFtZSA9IFsiVmlldyIsIGRpbWVuc2lvbiwgImQiLCBkdHlwZV0uam9pbigiIik7CiAgICBpZiAoZGltZW5zaW9uIDwgMCkgewogICAgICBjbGFzc05hbWUgPSAiVmlld19OaWwiICsgZHR5cGU7CiAgICB9CiAgICB2YXIgdXNlR2V0dGVycyA9IGR0eXBlID09PSAiZ2VuZXJpYyI7CiAgICBpZiAoZGltZW5zaW9uID09PSAtMSkgewogICAgICAvL1NwZWNpYWwgY2FzZSBmb3IgdHJpdmlhbCBhcnJheXMKICAgICAgdmFyIGNvZGUgPSAiZnVuY3Rpb24gIiArIGNsYXNzTmFtZSArICIoYSl7dGhpcy5kYXRhPWE7fTtcCnZhciBwcm90bz0iICsgY2xhc3NOYW1lICsgIi5wcm90b3R5cGU7XApwcm90by5kdHlwZT0nIiArIGR0eXBlICsgIic7XApwcm90by5pbmRleD1mdW5jdGlvbigpe3JldHVybiAtMX07XApwcm90by5zaXplPTA7XApwcm90by5kaW1lbnNpb249LTE7XApwcm90by5zaGFwZT1wcm90by5zdHJpZGU9cHJvdG8ub3JkZXI9W107XApwcm90by5sbz1wcm90by5oaT1wcm90by50cmFuc3Bvc2U9cHJvdG8uc3RlcD1cCmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyAiICsgY2xhc3NOYW1lICsgIih0aGlzLmRhdGEpO307XApwcm90by5nZXQ9cHJvdG8uc2V0PWZ1bmN0aW9uKCl7fTtcCnByb3RvLnBpY2s9ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH07XApyZXR1cm4gZnVuY3Rpb24gY29uc3RydWN0XyIgKyBjbGFzc05hbWUgKyAiKGEpe3JldHVybiBuZXcgIiArIGNsYXNzTmFtZSArICIoYSk7fSI7CiAgICAgIHZhciBwcm9jZWR1cmUgPSBuZXcgRnVuY3Rpb24oY29kZSk7CiAgICAgIHJldHVybiBwcm9jZWR1cmUoKTsKICAgIH0gZWxzZSBpZiAoZGltZW5zaW9uID09PSAwKSB7CiAgICAgIC8vU3BlY2lhbCBjYXNlIGZvciAwZCBhcnJheXMKICAgICAgdmFyIGNvZGUgPSAiZnVuY3Rpb24gIiArIGNsYXNzTmFtZSArICIoYSxkKSB7XAp0aGlzLmRhdGEgPSBhO1wKdGhpcy5vZmZzZXQgPSBkXAp9O1wKdmFyIHByb3RvPSIgKyBjbGFzc05hbWUgKyAiLnByb3RvdHlwZTtcCnByb3RvLmR0eXBlPSciICsgZHR5cGUgKyAiJztcCnByb3RvLmluZGV4PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMub2Zmc2V0fTtcCnByb3RvLmRpbWVuc2lvbj0wO1wKcHJvdG8uc2l6ZT0xO1wKcHJvdG8uc2hhcGU9XApwcm90by5zdHJpZGU9XApwcm90by5vcmRlcj1bXTtcCnByb3RvLmxvPVwKcHJvdG8uaGk9XApwcm90by50cmFuc3Bvc2U9XApwcm90by5zdGVwPWZ1bmN0aW9uICIgKyBjbGFzc05hbWUgKyAiX2NvcHkoKSB7XApyZXR1cm4gbmV3ICIgKyBjbGFzc05hbWUgKyAiKHRoaXMuZGF0YSx0aGlzLm9mZnNldClcCn07XApwcm90by5waWNrPWZ1bmN0aW9uICIgKyBjbGFzc05hbWUgKyAiX3BpY2soKXtcCnJldHVybiBUcml2aWFsQXJyYXkodGhpcy5kYXRhKTtcCn07XApwcm90by52YWx1ZU9mPXByb3RvLmdldD1mdW5jdGlvbiAiICsgY2xhc3NOYW1lICsgIl9nZXQoKXtcCnJldHVybiAiICsgKHVzZUdldHRlcnMgPyAidGhpcy5kYXRhLmdldCh0aGlzLm9mZnNldCkiIDogInRoaXMuZGF0YVt0aGlzLm9mZnNldF0iKSArICJ9O1wKcHJvdG8uc2V0PWZ1bmN0aW9uICIgKyBjbGFzc05hbWUgKyAiX3NldCh2KXtcCnJldHVybiAiICsgKHVzZUdldHRlcnMgPyAidGhpcy5kYXRhLnNldCh0aGlzLm9mZnNldCx2KSIgOiAidGhpcy5kYXRhW3RoaXMub2Zmc2V0XT12IikgKyAiXAp9O1wKcmV0dXJuIGZ1bmN0aW9uIGNvbnN0cnVjdF8iICsgY2xhc3NOYW1lICsgIihhLGIsYyxkKXtyZXR1cm4gbmV3ICIgKyBjbGFzc05hbWUgKyAiKGEsZCl9IjsKICAgICAgdmFyIHByb2NlZHVyZSA9IG5ldyBGdW5jdGlvbigiVHJpdmlhbEFycmF5IiwgY29kZSk7CiAgICAgIHJldHVybiBwcm9jZWR1cmUoQ0FDSEVEX0NPTlNUUlVDVE9SU1tkdHlwZV1bMF0pOwogICAgfQogICAgdmFyIGNvZGUgPSBbIid1c2Ugc3RyaWN0JyJdOwoKICAgIC8vQ3JlYXRlIGNvbnN0cnVjdG9yIGZvciB2aWV3CiAgICB2YXIgaW5kaWNlcyA9IGlvdGFfMShkaW1lbnNpb24pOwogICAgdmFyIGFyZ3MgPSBpbmRpY2VzLm1hcChmdW5jdGlvbiAoaSkgewogICAgICByZXR1cm4gImkiICsgaTsKICAgIH0pOwogICAgdmFyIGluZGV4X3N0ciA9ICJ0aGlzLm9mZnNldCsiICsgaW5kaWNlcy5tYXAoZnVuY3Rpb24gKGkpIHsKICAgICAgcmV0dXJuICJ0aGlzLnN0cmlkZVsiICsgaSArICJdKmkiICsgaTsKICAgIH0pLmpvaW4oIisiKTsKICAgIHZhciBzaGFwZUFyZyA9IGluZGljZXMubWFwKGZ1bmN0aW9uIChpKSB7CiAgICAgIHJldHVybiAiYiIgKyBpOwogICAgfSkuam9pbigiLCIpOwogICAgdmFyIHN0cmlkZUFyZyA9IGluZGljZXMubWFwKGZ1bmN0aW9uIChpKSB7CiAgICAgIHJldHVybiAiYyIgKyBpOwogICAgfSkuam9pbigiLCIpOwogICAgY29kZS5wdXNoKCJmdW5jdGlvbiAiICsgY2xhc3NOYW1lICsgIihhLCIgKyBzaGFwZUFyZyArICIsIiArIHN0cmlkZUFyZyArICIsZCl7dGhpcy5kYXRhPWEiLCAidGhpcy5zaGFwZT1bIiArIHNoYXBlQXJnICsgIl0iLCAidGhpcy5zdHJpZGU9WyIgKyBzdHJpZGVBcmcgKyAiXSIsICJ0aGlzLm9mZnNldD1kfDB9IiwgInZhciBwcm90bz0iICsgY2xhc3NOYW1lICsgIi5wcm90b3R5cGUiLCAicHJvdG8uZHR5cGU9JyIgKyBkdHlwZSArICInIiwgInByb3RvLmRpbWVuc2lvbj0iICsgZGltZW5zaW9uKTsKCiAgICAvL3ZpZXcuc2l6ZToKICAgIGNvZGUucHVzaCgiT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3RvLCdzaXplJyx7Z2V0OmZ1bmN0aW9uICIgKyBjbGFzc05hbWUgKyAiX3NpemUoKXtcCnJldHVybiAiICsgaW5kaWNlcy5tYXAoZnVuY3Rpb24gKGkpIHsKICAgICAgcmV0dXJuICJ0aGlzLnNoYXBlWyIgKyBpICsgIl0iOwogICAgfSkuam9pbigiKiIpLCAifX0pIik7CgogICAgLy92aWV3Lm9yZGVyOgogICAgaWYgKGRpbWVuc2lvbiA9PT0gMSkgewogICAgICBjb2RlLnB1c2goInByb3RvLm9yZGVyPVswXSIpOwogICAgfSBlbHNlIHsKICAgICAgY29kZS5wdXNoKCJPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvdG8sJ29yZGVyJyx7Z2V0OiIpOwogICAgICBpZiAoZGltZW5zaW9uIDwgNCkgewogICAgICAgIGNvZGUucHVzaCgiZnVuY3Rpb24gIiArIGNsYXNzTmFtZSArICJfb3JkZXIoKXsiKTsKICAgICAgICBpZiAoZGltZW5zaW9uID09PSAyKSB7CiAgICAgICAgICBjb2RlLnB1c2goInJldHVybiAoTWF0aC5hYnModGhpcy5zdHJpZGVbMF0pPk1hdGguYWJzKHRoaXMuc3RyaWRlWzFdKSk/WzEsMF06WzAsMV19fSkiKTsKICAgICAgICB9IGVsc2UgaWYgKGRpbWVuc2lvbiA9PT0gMykgewogICAgICAgICAgY29kZS5wdXNoKCJ2YXIgczA9TWF0aC5hYnModGhpcy5zdHJpZGVbMF0pLHMxPU1hdGguYWJzKHRoaXMuc3RyaWRlWzFdKSxzMj1NYXRoLmFicyh0aGlzLnN0cmlkZVsyXSk7XAppZihzMD5zMSl7XAppZihzMT5zMil7XApyZXR1cm4gWzIsMSwwXTtcCn1lbHNlIGlmKHMwPnMyKXtcCnJldHVybiBbMSwyLDBdO1wKfWVsc2V7XApyZXR1cm4gWzEsMCwyXTtcCn1cCn1lbHNlIGlmKHMwPnMyKXtcCnJldHVybiBbMiwwLDFdO1wKfWVsc2UgaWYoczI+czEpe1wKcmV0dXJuIFswLDEsMl07XAp9ZWxzZXtcCnJldHVybiBbMCwyLDFdO1wKfX19KSIpOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBjb2RlLnB1c2goIk9SREVSfSkiKTsKICAgICAgfQogICAgfQoKICAgIC8vdmlldy5zZXQoaTAsIC4uLiwgdik6CiAgICBjb2RlLnB1c2goInByb3RvLnNldD1mdW5jdGlvbiAiICsgY2xhc3NOYW1lICsgIl9zZXQoIiArIGFyZ3Muam9pbigiLCIpICsgIix2KXsiKTsKICAgIGlmICh1c2VHZXR0ZXJzKSB7CiAgICAgIGNvZGUucHVzaCgicmV0dXJuIHRoaXMuZGF0YS5zZXQoIiArIGluZGV4X3N0ciArICIsdil9Iik7CiAgICB9IGVsc2UgewogICAgICBjb2RlLnB1c2goInJldHVybiB0aGlzLmRhdGFbIiArIGluZGV4X3N0ciArICJdPXZ9Iik7CiAgICB9CgogICAgLy92aWV3LmdldChpMCwgLi4uKToKICAgIGNvZGUucHVzaCgicHJvdG8uZ2V0PWZ1bmN0aW9uICIgKyBjbGFzc05hbWUgKyAiX2dldCgiICsgYXJncy5qb2luKCIsIikgKyAiKXsiKTsKICAgIGlmICh1c2VHZXR0ZXJzKSB7CiAgICAgIGNvZGUucHVzaCgicmV0dXJuIHRoaXMuZGF0YS5nZXQoIiArIGluZGV4X3N0ciArICIpfSIpOwogICAgfSBlbHNlIHsKICAgICAgY29kZS5wdXNoKCJyZXR1cm4gdGhpcy5kYXRhWyIgKyBpbmRleF9zdHIgKyAiXX0iKTsKICAgIH0KCiAgICAvL3ZpZXcuaW5kZXg6CiAgICBjb2RlLnB1c2goInByb3RvLmluZGV4PWZ1bmN0aW9uICIgKyBjbGFzc05hbWUgKyAiX2luZGV4KCIsIGFyZ3Muam9pbigpLCAiKXtyZXR1cm4gIiArIGluZGV4X3N0ciArICJ9Iik7CgogICAgLy92aWV3LmhpKCk6CiAgICBjb2RlLnB1c2goInByb3RvLmhpPWZ1bmN0aW9uICIgKyBjbGFzc05hbWUgKyAiX2hpKCIgKyBhcmdzLmpvaW4oIiwiKSArICIpe3JldHVybiBuZXcgIiArIGNsYXNzTmFtZSArICIodGhpcy5kYXRhLCIgKyBpbmRpY2VzLm1hcChmdW5jdGlvbiAoaSkgewogICAgICByZXR1cm4gWyIodHlwZW9mIGkiLCBpLCAiIT09J251bWJlcid8fGkiLCBpLCAiPDApP3RoaXMuc2hhcGVbIiwgaSwgIl06aSIsIGksICJ8MCJdLmpvaW4oIiIpOwogICAgfSkuam9pbigiLCIpICsgIiwiICsgaW5kaWNlcy5tYXAoZnVuY3Rpb24gKGkpIHsKICAgICAgcmV0dXJuICJ0aGlzLnN0cmlkZVsiICsgaSArICJdIjsKICAgIH0pLmpvaW4oIiwiKSArICIsdGhpcy5vZmZzZXQpfSIpOwoKICAgIC8vdmlldy5sbygpOgogICAgdmFyIGFfdmFycyA9IGluZGljZXMubWFwKGZ1bmN0aW9uIChpKSB7CiAgICAgIHJldHVybiAiYSIgKyBpICsgIj10aGlzLnNoYXBlWyIgKyBpICsgIl0iOwogICAgfSk7CiAgICB2YXIgY192YXJzID0gaW5kaWNlcy5tYXAoZnVuY3Rpb24gKGkpIHsKICAgICAgcmV0dXJuICJjIiArIGkgKyAiPXRoaXMuc3RyaWRlWyIgKyBpICsgIl0iOwogICAgfSk7CiAgICBjb2RlLnB1c2goInByb3RvLmxvPWZ1bmN0aW9uICIgKyBjbGFzc05hbWUgKyAiX2xvKCIgKyBhcmdzLmpvaW4oIiwiKSArICIpe3ZhciBiPXRoaXMub2Zmc2V0LGQ9MCwiICsgYV92YXJzLmpvaW4oIiwiKSArICIsIiArIGNfdmFycy5qb2luKCIsIikpOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkaW1lbnNpb247ICsraSkgewogICAgICBjb2RlLnB1c2goImlmKHR5cGVvZiBpIiArIGkgKyAiPT09J251bWJlcicmJmkiICsgaSArICI+PTApe1wKZD1pIiArIGkgKyAifDA7XApiKz1jIiArIGkgKyAiKmQ7XAphIiArIGkgKyAiLT1kfSIpOwogICAgfQogICAgY29kZS5wdXNoKCJyZXR1cm4gbmV3ICIgKyBjbGFzc05hbWUgKyAiKHRoaXMuZGF0YSwiICsgaW5kaWNlcy5tYXAoZnVuY3Rpb24gKGkpIHsKICAgICAgcmV0dXJuICJhIiArIGk7CiAgICB9KS5qb2luKCIsIikgKyAiLCIgKyBpbmRpY2VzLm1hcChmdW5jdGlvbiAoaSkgewogICAgICByZXR1cm4gImMiICsgaTsKICAgIH0pLmpvaW4oIiwiKSArICIsYil9Iik7CgogICAgLy92aWV3LnN0ZXAoKToKICAgIGNvZGUucHVzaCgicHJvdG8uc3RlcD1mdW5jdGlvbiAiICsgY2xhc3NOYW1lICsgIl9zdGVwKCIgKyBhcmdzLmpvaW4oIiwiKSArICIpe3ZhciAiICsgaW5kaWNlcy5tYXAoZnVuY3Rpb24gKGkpIHsKICAgICAgcmV0dXJuICJhIiArIGkgKyAiPXRoaXMuc2hhcGVbIiArIGkgKyAiXSI7CiAgICB9KS5qb2luKCIsIikgKyAiLCIgKyBpbmRpY2VzLm1hcChmdW5jdGlvbiAoaSkgewogICAgICByZXR1cm4gImIiICsgaSArICI9dGhpcy5zdHJpZGVbIiArIGkgKyAiXSI7CiAgICB9KS5qb2luKCIsIikgKyAiLGM9dGhpcy5vZmZzZXQsZD0wLGNlaWw9TWF0aC5jZWlsIik7CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRpbWVuc2lvbjsgKytpKSB7CiAgICAgIGNvZGUucHVzaCgiaWYodHlwZW9mIGkiICsgaSArICI9PT0nbnVtYmVyJyl7XApkPWkiICsgaSArICJ8MDtcCmlmKGQ8MCl7XApjKz1iIiArIGkgKyAiKihhIiArIGkgKyAiLTEpO1wKYSIgKyBpICsgIj1jZWlsKC1hIiArIGkgKyAiL2QpXAp9ZWxzZXtcCmEiICsgaSArICI9Y2VpbChhIiArIGkgKyAiL2QpXAp9XApiIiArIGkgKyAiKj1kXAp9Iik7CiAgICB9CiAgICBjb2RlLnB1c2goInJldHVybiBuZXcgIiArIGNsYXNzTmFtZSArICIodGhpcy5kYXRhLCIgKyBpbmRpY2VzLm1hcChmdW5jdGlvbiAoaSkgewogICAgICByZXR1cm4gImEiICsgaTsKICAgIH0pLmpvaW4oIiwiKSArICIsIiArIGluZGljZXMubWFwKGZ1bmN0aW9uIChpKSB7CiAgICAgIHJldHVybiAiYiIgKyBpOwogICAgfSkuam9pbigiLCIpICsgIixjKX0iKTsKCiAgICAvL3ZpZXcudHJhbnNwb3NlKCk6CiAgICB2YXIgdFNoYXBlID0gbmV3IEFycmF5KGRpbWVuc2lvbik7CiAgICB2YXIgdFN0cmlkZSA9IG5ldyBBcnJheShkaW1lbnNpb24pOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkaW1lbnNpb247ICsraSkgewogICAgICB0U2hhcGVbaV0gPSAiYVtpIiArIGkgKyAiXSI7CiAgICAgIHRTdHJpZGVbaV0gPSAiYltpIiArIGkgKyAiXSI7CiAgICB9CiAgICBjb2RlLnB1c2goInByb3RvLnRyYW5zcG9zZT1mdW5jdGlvbiAiICsgY2xhc3NOYW1lICsgIl90cmFuc3Bvc2UoIiArIGFyZ3MgKyAiKXsiICsgYXJncy5tYXAoZnVuY3Rpb24gKG4sIGlkeCkgewogICAgICByZXR1cm4gbiArICI9KCIgKyBuICsgIj09PXVuZGVmaW5lZD8iICsgaWR4ICsgIjoiICsgbiArICJ8MCkiOwogICAgfSkuam9pbigiOyIpLCAidmFyIGE9dGhpcy5zaGFwZSxiPXRoaXMuc3RyaWRlO3JldHVybiBuZXcgIiArIGNsYXNzTmFtZSArICIodGhpcy5kYXRhLCIgKyB0U2hhcGUuam9pbigiLCIpICsgIiwiICsgdFN0cmlkZS5qb2luKCIsIikgKyAiLHRoaXMub2Zmc2V0KX0iKTsKCiAgICAvL3ZpZXcucGljaygpOgogICAgY29kZS5wdXNoKCJwcm90by5waWNrPWZ1bmN0aW9uICIgKyBjbGFzc05hbWUgKyAiX3BpY2soIiArIGFyZ3MgKyAiKXt2YXIgYT1bXSxiPVtdLGM9dGhpcy5vZmZzZXQiKTsKICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGltZW5zaW9uOyArK2kpIHsKICAgICAgY29kZS5wdXNoKCJpZih0eXBlb2YgaSIgKyBpICsgIj09PSdudW1iZXInJiZpIiArIGkgKyAiPj0wKXtjPShjK3RoaXMuc3RyaWRlWyIgKyBpICsgIl0qaSIgKyBpICsgIil8MH1lbHNle2EucHVzaCh0aGlzLnNoYXBlWyIgKyBpICsgIl0pO2IucHVzaCh0aGlzLnN0cmlkZVsiICsgaSArICJdKX0iKTsKICAgIH0KICAgIGNvZGUucHVzaCgidmFyIGN0b3I9Q1RPUl9MSVNUW2EubGVuZ3RoKzFdO3JldHVybiBjdG9yKHRoaXMuZGF0YSxhLGIsYyl9Iik7CgogICAgLy9BZGQgcmV0dXJuIHN0YXRlbWVudAogICAgY29kZS5wdXNoKCJyZXR1cm4gZnVuY3Rpb24gY29uc3RydWN0XyIgKyBjbGFzc05hbWUgKyAiKGRhdGEsc2hhcGUsc3RyaWRlLG9mZnNldCl7cmV0dXJuIG5ldyAiICsgY2xhc3NOYW1lICsgIihkYXRhLCIgKyBpbmRpY2VzLm1hcChmdW5jdGlvbiAoaSkgewogICAgICByZXR1cm4gInNoYXBlWyIgKyBpICsgIl0iOwogICAgfSkuam9pbigiLCIpICsgIiwiICsgaW5kaWNlcy5tYXAoZnVuY3Rpb24gKGkpIHsKICAgICAgcmV0dXJuICJzdHJpZGVbIiArIGkgKyAiXSI7CiAgICB9KS5qb2luKCIsIikgKyAiLG9mZnNldCl9Iik7CgogICAgLy9Db21waWxlIHByb2NlZHVyZQogICAgdmFyIHByb2NlZHVyZSA9IG5ldyBGdW5jdGlvbigiQ1RPUl9MSVNUIiwgIk9SREVSIiwgY29kZS5qb2luKCJcbiIpKTsKICAgIHJldHVybiBwcm9jZWR1cmUoQ0FDSEVEX0NPTlNUUlVDVE9SU1tkdHlwZV0sIG9yZGVyKTsKICB9CiAgZnVuY3Rpb24gYXJyYXlEVHlwZShkYXRhKSB7CiAgICBpZiAoaXNCdWZmZXJfMShkYXRhKSkgewogICAgICByZXR1cm4gImJ1ZmZlciI7CiAgICB9CiAgICBpZiAoaGFzVHlwZWRBcnJheXMpIHsKICAgICAgc3dpdGNoIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZGF0YSkpIHsKICAgICAgICBjYXNlICJbb2JqZWN0IEZsb2F0NjRBcnJheV0iOgogICAgICAgICAgcmV0dXJuICJmbG9hdDY0IjsKICAgICAgICBjYXNlICJbb2JqZWN0IEZsb2F0MzJBcnJheV0iOgogICAgICAgICAgcmV0dXJuICJmbG9hdDMyIjsKICAgICAgICBjYXNlICJbb2JqZWN0IEludDhBcnJheV0iOgogICAgICAgICAgcmV0dXJuICJpbnQ4IjsKICAgICAgICBjYXNlICJbb2JqZWN0IEludDE2QXJyYXldIjoKICAgICAgICAgIHJldHVybiAiaW50MTYiOwogICAgICAgIGNhc2UgIltvYmplY3QgSW50MzJBcnJheV0iOgogICAgICAgICAgcmV0dXJuICJpbnQzMiI7CiAgICAgICAgY2FzZSAiW29iamVjdCBVaW50OEFycmF5XSI6CiAgICAgICAgICByZXR1cm4gInVpbnQ4IjsKICAgICAgICBjYXNlICJbb2JqZWN0IFVpbnQxNkFycmF5XSI6CiAgICAgICAgICByZXR1cm4gInVpbnQxNiI7CiAgICAgICAgY2FzZSAiW29iamVjdCBVaW50MzJBcnJheV0iOgogICAgICAgICAgcmV0dXJuICJ1aW50MzIiOwogICAgICAgIGNhc2UgIltvYmplY3QgVWludDhDbGFtcGVkQXJyYXldIjoKICAgICAgICAgIHJldHVybiAidWludDhfY2xhbXBlZCI7CiAgICAgICAgY2FzZSAiW29iamVjdCBCaWdJbnQ2NEFycmF5XSI6CiAgICAgICAgICByZXR1cm4gImJpZ2ludDY0IjsKICAgICAgICBjYXNlICJbb2JqZWN0IEJpZ1VpbnQ2NEFycmF5XSI6CiAgICAgICAgICByZXR1cm4gImJpZ3VpbnQ2NCI7CiAgICAgIH0KICAgIH0KICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7CiAgICAgIHJldHVybiAiYXJyYXkiOwogICAgfQogICAgcmV0dXJuICJnZW5lcmljIjsKICB9CiAgdmFyIENBQ0hFRF9DT05TVFJVQ1RPUlMgPSB7CiAgICAiZmxvYXQzMiI6IFtdLAogICAgImZsb2F0NjQiOiBbXSwKICAgICJpbnQ4IjogW10sCiAgICAiaW50MTYiOiBbXSwKICAgICJpbnQzMiI6IFtdLAogICAgInVpbnQ4IjogW10sCiAgICAidWludDE2IjogW10sCiAgICAidWludDMyIjogW10sCiAgICAiYXJyYXkiOiBbXSwKICAgICJ1aW50OF9jbGFtcGVkIjogW10sCiAgICAiYmlnaW50NjQiOiBbXSwKICAgICJiaWd1aW50NjQiOiBbXSwKICAgICJidWZmZXIiOiBbXSwKICAgICJnZW5lcmljIjogW10KICB9OwogIGZ1bmN0aW9uIHdyYXBwZWROREFycmF5Q3RvcihkYXRhLCBzaGFwZSwgc3RyaWRlLCBvZmZzZXQpIHsKICAgIGlmIChkYXRhID09PSB1bmRlZmluZWQpIHsKICAgICAgdmFyIGN0b3IgPSBDQUNIRURfQ09OU1RSVUNUT1JTLmFycmF5WzBdOwogICAgICByZXR1cm4gY3RvcihbXSk7CiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhID09PSAibnVtYmVyIikgewogICAgICBkYXRhID0gW2RhdGFdOwogICAgfQogICAgaWYgKHNoYXBlID09PSB1bmRlZmluZWQpIHsKICAgICAgc2hhcGUgPSBbZGF0YS5sZW5ndGhdOwogICAgfQogICAgdmFyIGQgPSBzaGFwZS5sZW5ndGg7CiAgICBpZiAoc3RyaWRlID09PSB1bmRlZmluZWQpIHsKICAgICAgc3RyaWRlID0gbmV3IEFycmF5KGQpOwogICAgICBmb3IgKHZhciBpID0gZCAtIDEsIHN6ID0gMTsgaSA+PSAwOyAtLWkpIHsKICAgICAgICBzdHJpZGVbaV0gPSBzejsKICAgICAgICBzeiAqPSBzaGFwZVtpXTsKICAgICAgfQogICAgfQogICAgaWYgKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIG9mZnNldCA9IDA7CiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZDsgKytpKSB7CiAgICAgICAgaWYgKHN0cmlkZVtpXSA8IDApIHsKICAgICAgICAgIG9mZnNldCAtPSAoc2hhcGVbaV0gLSAxKSAqIHN0cmlkZVtpXTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIHZhciBkdHlwZSA9IGFycmF5RFR5cGUoZGF0YSk7CiAgICB2YXIgY3Rvcl9saXN0ID0gQ0FDSEVEX0NPTlNUUlVDVE9SU1tkdHlwZV07CiAgICB3aGlsZSAoY3Rvcl9saXN0Lmxlbmd0aCA8PSBkICsgMSkgewogICAgICBjdG9yX2xpc3QucHVzaChjb21waWxlQ29uc3RydWN0b3IoZHR5cGUsIGN0b3JfbGlzdC5sZW5ndGggLSAxKSk7CiAgICB9CiAgICB2YXIgY3RvciA9IGN0b3JfbGlzdFtkICsgMV07CiAgICByZXR1cm4gY3RvcihkYXRhLCBzaGFwZSwgc3RyaWRlLCBvZmZzZXQpOwogIH0KICB2YXIgbmRhcnJheSA9IHdyYXBwZWROREFycmF5Q3RvcjsKCiAgY2xhc3MgTWFydGluaSB7CiAgICBjb25zdHJ1Y3RvcihncmlkU2l6ZSA9IDI1NykgewogICAgICB0aGlzLmdyaWRTaXplID0gZ3JpZFNpemU7CiAgICAgIGNvbnN0IHRpbGVTaXplID0gZ3JpZFNpemUgLSAxOwogICAgICBpZiAodGlsZVNpemUgJiB0aWxlU2l6ZSAtIDEpIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgZ3JpZCBzaXplIHRvIGJlIDJebisxLCBnb3QgJHtncmlkU2l6ZX0uYCk7CiAgICAgIHRoaXMubnVtVHJpYW5nbGVzID0gdGlsZVNpemUgKiB0aWxlU2l6ZSAqIDIgLSAyOwogICAgICB0aGlzLm51bVBhcmVudFRyaWFuZ2xlcyA9IHRoaXMubnVtVHJpYW5nbGVzIC0gdGlsZVNpemUgKiB0aWxlU2l6ZTsKICAgICAgdGhpcy5pbmRpY2VzID0gbmV3IFVpbnQzMkFycmF5KHRoaXMuZ3JpZFNpemUgKiB0aGlzLmdyaWRTaXplKTsKCiAgICAgIC8vIGNvb3JkaW5hdGVzIGZvciBhbGwgcG9zc2libGUgdHJpYW5nbGVzIGluIGFuIFJUSU4gdGlsZQogICAgICB0aGlzLmNvb3JkcyA9IG5ldyBVaW50MTZBcnJheSh0aGlzLm51bVRyaWFuZ2xlcyAqIDQpOwoKICAgICAgLy8gZ2V0IHRyaWFuZ2xlIGNvb3JkaW5hdGVzIGZyb20gaXRzIGluZGV4IGluIGFuIGltcGxpY2l0IGJpbmFyeSB0cmVlCiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5udW1UcmlhbmdsZXM7IGkrKykgewogICAgICAgIGxldCBpZCA9IGkgKyAyOwogICAgICAgIGxldCBheCA9IDAsCiAgICAgICAgICBheSA9IDAsCiAgICAgICAgICBieCA9IDAsCiAgICAgICAgICBieSA9IDAsCiAgICAgICAgICBjeCA9IDAsCiAgICAgICAgICBjeSA9IDA7CiAgICAgICAgaWYgKGlkICYgMSkgewogICAgICAgICAgYnggPSBieSA9IGN4ID0gdGlsZVNpemU7IC8vIGJvdHRvbS1sZWZ0IHRyaWFuZ2xlCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGF4ID0gYXkgPSBjeSA9IHRpbGVTaXplOyAvLyB0b3AtcmlnaHQgdHJpYW5nbGUKICAgICAgICB9CgogICAgICAgIHdoaWxlICgoaWQgPj49IDEpID4gMSkgewogICAgICAgICAgY29uc3QgbXggPSBheCArIGJ4ID4+IDE7CiAgICAgICAgICBjb25zdCBteSA9IGF5ICsgYnkgPj4gMTsKICAgICAgICAgIGlmIChpZCAmIDEpIHsKICAgICAgICAgICAgLy8gbGVmdCBoYWxmCiAgICAgICAgICAgIGJ4ID0gYXg7CiAgICAgICAgICAgIGJ5ID0gYXk7CiAgICAgICAgICAgIGF4ID0gY3g7CiAgICAgICAgICAgIGF5ID0gY3k7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyByaWdodCBoYWxmCiAgICAgICAgICAgIGF4ID0gYng7CiAgICAgICAgICAgIGF5ID0gYnk7CiAgICAgICAgICAgIGJ4ID0gY3g7CiAgICAgICAgICAgIGJ5ID0gY3k7CiAgICAgICAgICB9CiAgICAgICAgICBjeCA9IG14OwogICAgICAgICAgY3kgPSBteTsKICAgICAgICB9CiAgICAgICAgY29uc3QgayA9IGkgKiA0OwogICAgICAgIHRoaXMuY29vcmRzW2sgKyAwXSA9IGF4OwogICAgICAgIHRoaXMuY29vcmRzW2sgKyAxXSA9IGF5OwogICAgICAgIHRoaXMuY29vcmRzW2sgKyAyXSA9IGJ4OwogICAgICAgIHRoaXMuY29vcmRzW2sgKyAzXSA9IGJ5OwogICAgICB9CiAgICB9CiAgICBjcmVhdGVUaWxlKHRlcnJhaW4pIHsKICAgICAgcmV0dXJuIG5ldyBUaWxlKHRlcnJhaW4sIHRoaXMpOwogICAgfQogIH0KICBjbGFzcyBUaWxlIHsKICAgIGNvbnN0cnVjdG9yKHRlcnJhaW4sIG1hcnRpbmkpIHsKICAgICAgY29uc3Qgc2l6ZSA9IG1hcnRpbmkuZ3JpZFNpemU7CiAgICAgIGlmICh0ZXJyYWluLmxlbmd0aCAhPT0gc2l6ZSAqIHNpemUpIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgdGVycmFpbiBkYXRhIG9mIGxlbmd0aCAke3NpemUgKiBzaXplfSAoJHtzaXplfSB4ICR7c2l6ZX0pLCBnb3QgJHt0ZXJyYWluLmxlbmd0aH0uYCk7CiAgICAgIHRoaXMudGVycmFpbiA9IHRlcnJhaW47CiAgICAgIHRoaXMubWFydGluaSA9IG1hcnRpbmk7CiAgICAgIHRoaXMuZXJyb3JzID0gbmV3IEZsb2F0MzJBcnJheSh0ZXJyYWluLmxlbmd0aCk7CiAgICAgIHRoaXMudXBkYXRlKCk7CiAgICB9CiAgICB1cGRhdGUoKSB7CiAgICAgIGNvbnN0IHsKICAgICAgICBudW1UcmlhbmdsZXMsCiAgICAgICAgbnVtUGFyZW50VHJpYW5nbGVzLAogICAgICAgIGNvb3JkcywKICAgICAgICBncmlkU2l6ZTogc2l6ZQogICAgICB9ID0gdGhpcy5tYXJ0aW5pOwogICAgICBjb25zdCB7CiAgICAgICAgdGVycmFpbiwKICAgICAgICBlcnJvcnMKICAgICAgfSA9IHRoaXM7CgogICAgICAvLyBpdGVyYXRlIG92ZXIgYWxsIHBvc3NpYmxlIHRyaWFuZ2xlcywgc3RhcnRpbmcgZnJvbSB0aGUgc21hbGxlc3QgbGV2ZWwKICAgICAgZm9yIChsZXQgaSA9IG51bVRyaWFuZ2xlcyAtIDE7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgY29uc3QgayA9IGkgKiA0OwogICAgICAgIGNvbnN0IGF4ID0gY29vcmRzW2sgKyAwXTsKICAgICAgICBjb25zdCBheSA9IGNvb3Jkc1trICsgMV07CiAgICAgICAgY29uc3QgYnggPSBjb29yZHNbayArIDJdOwogICAgICAgIGNvbnN0IGJ5ID0gY29vcmRzW2sgKyAzXTsKICAgICAgICBjb25zdCBteCA9IGF4ICsgYnggPj4gMTsKICAgICAgICBjb25zdCBteSA9IGF5ICsgYnkgPj4gMTsKICAgICAgICBjb25zdCBjeCA9IG14ICsgbXkgLSBheTsKICAgICAgICBjb25zdCBjeSA9IG15ICsgYXggLSBteDsKCiAgICAgICAgLy8gY2FsY3VsYXRlIGVycm9yIGluIHRoZSBtaWRkbGUgb2YgdGhlIGxvbmcgZWRnZSBvZiB0aGUgdHJpYW5nbGUKICAgICAgICBjb25zdCBpbnRlcnBvbGF0ZWRIZWlnaHQgPSAodGVycmFpbltheSAqIHNpemUgKyBheF0gKyB0ZXJyYWluW2J5ICogc2l6ZSArIGJ4XSkgLyAyOwogICAgICAgIGNvbnN0IG1pZGRsZUluZGV4ID0gbXkgKiBzaXplICsgbXg7CiAgICAgICAgY29uc3QgbWlkZGxlRXJyb3IgPSBNYXRoLmFicyhpbnRlcnBvbGF0ZWRIZWlnaHQgLSB0ZXJyYWluW21pZGRsZUluZGV4XSk7CiAgICAgICAgZXJyb3JzW21pZGRsZUluZGV4XSA9IE1hdGgubWF4KGVycm9yc1ttaWRkbGVJbmRleF0sIG1pZGRsZUVycm9yKTsKICAgICAgICBpZiAoaSA8IG51bVBhcmVudFRyaWFuZ2xlcykgewogICAgICAgICAgLy8gYmlnZ2VyIHRyaWFuZ2xlczsgYWNjdW11bGF0ZSBlcnJvciB3aXRoIGNoaWxkcmVuCiAgICAgICAgICBjb25zdCBsZWZ0Q2hpbGRJbmRleCA9IChheSArIGN5ID4+IDEpICogc2l6ZSArIChheCArIGN4ID4+IDEpOwogICAgICAgICAgY29uc3QgcmlnaHRDaGlsZEluZGV4ID0gKGJ5ICsgY3kgPj4gMSkgKiBzaXplICsgKGJ4ICsgY3ggPj4gMSk7CiAgICAgICAgICBlcnJvcnNbbWlkZGxlSW5kZXhdID0gTWF0aC5tYXgoZXJyb3JzW21pZGRsZUluZGV4XSwgZXJyb3JzW2xlZnRDaGlsZEluZGV4XSwgZXJyb3JzW3JpZ2h0Q2hpbGRJbmRleF0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgZ2V0TWVzaChtYXhFcnJvciA9IDAsIG1heExlbmd0aCA9IG51bGwpIHsKICAgICAgY29uc3QgewogICAgICAgIGdyaWRTaXplOiBzaXplLAogICAgICAgIGluZGljZXMKICAgICAgfSA9IHRoaXMubWFydGluaTsKICAgICAgY29uc3QgewogICAgICAgIGVycm9ycwogICAgICB9ID0gdGhpczsKICAgICAgbGV0IG51bVZlcnRpY2VzID0gMDsKICAgICAgbGV0IG51bVRyaWFuZ2xlcyA9IDA7CiAgICAgIGNvbnN0IG1heCA9IHNpemUgLSAxOwoKICAgICAgLy8gVGhlIG1heExlbmd0aCBwYXJhbWV0ZXIgd2lsbCBjYXVzZSB0cmlhbmdsZXMgdG8gYmUgZ2VuZXJhdGVkIHVudGlsIHRoZSBsZWdzIGFyZSBiZWxvdyB0aGlzIGxlbmd0aAogICAgICAvLyBJdCBpcyBtZWFudCB0byBzdXBwb3J0IGNhc2VzIHdoZXJlIGEgY2VydGFpbiBtZXNoIGRlbnNpdHkgaXMgcmVxdWlyZWQgdG8gZG8gc3BoZXJpY2FsIG1hdGggb24gZGlnaXRhbCBnbG9iZXMKICAgICAgY29uc3QgbWF4U2NhbGUgPSBtYXhMZW5ndGggfHwgc2l6ZTsKCiAgICAgIC8vIHVzZSBhbiBpbmRleCBncmlkIHRvIGtlZXAgdHJhY2sgb2YgdmVydGljZXMgdGhhdCB3ZXJlIGFscmVhZHkgdXNlZCB0byBhdm9pZCBkdXBsaWNhdGlvbgogICAgICBpbmRpY2VzLmZpbGwoMCk7CgogICAgICAvLyByZXRyaWV2ZSBtZXNoIGluIHR3byBzdGFnZXMgdGhhdCBib3RoIHRyYXZlcnNlIHRoZSBlcnJvciBtYXA6CiAgICAgIC8vIC0gY291bnRFbGVtZW50czogZmluZCB1c2VkIHZlcnRpY2VzIChhbmQgYXNzaWduIGVhY2ggYW4gaW5kZXgpLCBhbmQgY291bnQgdHJpYW5nbGVzIChmb3IgbWluaW11bSBhbGxvY2F0aW9uKQogICAgICAvLyAtIHByb2Nlc3NUcmlhbmdsZTogZmlsbCB0aGUgYWxsb2NhdGVkIHZlcnRpY2VzICYgdHJpYW5nbGVzIHR5cGVkIGFycmF5cwoKICAgICAgZnVuY3Rpb24gY291bnRFbGVtZW50cyhheCwgYXksIGJ4LCBieSwgY3gsIGN5KSB7CiAgICAgICAgY29uc3QgbXggPSBheCArIGJ4ID4+IDE7CiAgICAgICAgY29uc3QgbXkgPSBheSArIGJ5ID4+IDE7CiAgICAgICAgY29uc3QgbGVnTGVuZ3RoID0gTWF0aC5hYnMoYXggLSBjeCkgKyBNYXRoLmFicyhheSAtIGN5KTsKICAgICAgICBpZiAobGVnTGVuZ3RoID4gMSAmJiBlcnJvcnNbbXkgKiBzaXplICsgbXhdID4gbWF4RXJyb3IgfHwgbGVnTGVuZ3RoID4gbWF4U2NhbGUpIHsKICAgICAgICAgIGNvdW50RWxlbWVudHMoY3gsIGN5LCBheCwgYXksIG14LCBteSk7CiAgICAgICAgICBjb3VudEVsZW1lbnRzKGJ4LCBieSwgY3gsIGN5LCBteCwgbXkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpbmRpY2VzW2F5ICogc2l6ZSArIGF4XSA9IGluZGljZXNbYXkgKiBzaXplICsgYXhdIHx8ICsrbnVtVmVydGljZXM7CiAgICAgICAgICBpbmRpY2VzW2J5ICogc2l6ZSArIGJ4XSA9IGluZGljZXNbYnkgKiBzaXplICsgYnhdIHx8ICsrbnVtVmVydGljZXM7CiAgICAgICAgICBpbmRpY2VzW2N5ICogc2l6ZSArIGN4XSA9IGluZGljZXNbY3kgKiBzaXplICsgY3hdIHx8ICsrbnVtVmVydGljZXM7CiAgICAgICAgICBudW1UcmlhbmdsZXMrKzsKICAgICAgICB9CiAgICAgIH0KICAgICAgY291bnRFbGVtZW50cygwLCAwLCBtYXgsIG1heCwgbWF4LCAwKTsKICAgICAgY291bnRFbGVtZW50cyhtYXgsIG1heCwgMCwgMCwgMCwgbWF4KTsKICAgICAgY29uc3QgdmVydGljZXMgPSBuZXcgVWludDE2QXJyYXkobnVtVmVydGljZXMgKiAyKTsKICAgICAgY29uc3QgdHJpYW5nbGVzID0gbmV3IFVpbnQzMkFycmF5KG51bVRyaWFuZ2xlcyAqIDMpOwogICAgICBsZXQgdHJpSW5kZXggPSAwOwogICAgICBmdW5jdGlvbiBwcm9jZXNzVHJpYW5nbGUoYXgsIGF5LCBieCwgYnksIGN4LCBjeSkgewogICAgICAgIGNvbnN0IG14ID0gYXggKyBieCA+PiAxOwogICAgICAgIGNvbnN0IG15ID0gYXkgKyBieSA+PiAxOwogICAgICAgIGNvbnN0IGxlZ0xlbmd0aCA9IE1hdGguYWJzKGF4IC0gY3gpICsgTWF0aC5hYnMoYXkgLSBjeSk7CiAgICAgICAgaWYgKGxlZ0xlbmd0aCA+IDEgJiYgZXJyb3JzW215ICogc2l6ZSArIG14XSA+IG1heEVycm9yIHx8IGxlZ0xlbmd0aCA+IG1heFNjYWxlKSB7CiAgICAgICAgICAvLyB0cmlhbmdsZSBkb2Vzbid0IGFwcHJveGltYXRlIHRoZSBzdXJmYWNlIHdlbGwgZW5vdWdoOyBkcmlsbCBkb3duIGZ1cnRoZXIKICAgICAgICAgIHByb2Nlc3NUcmlhbmdsZShjeCwgY3ksIGF4LCBheSwgbXgsIG15KTsKICAgICAgICAgIHByb2Nlc3NUcmlhbmdsZShieCwgYnksIGN4LCBjeSwgbXgsIG15KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLy8gYWRkIGEgdHJpYW5nbGUKICAgICAgICAgIGNvbnN0IGEgPSBpbmRpY2VzW2F5ICogc2l6ZSArIGF4XSAtIDE7CiAgICAgICAgICBjb25zdCBiID0gaW5kaWNlc1tieSAqIHNpemUgKyBieF0gLSAxOwogICAgICAgICAgY29uc3QgYyA9IGluZGljZXNbY3kgKiBzaXplICsgY3hdIC0gMTsKICAgICAgICAgIHZlcnRpY2VzWzIgKiBhXSA9IGF4OwogICAgICAgICAgdmVydGljZXNbMiAqIGEgKyAxXSA9IGF5OwogICAgICAgICAgdmVydGljZXNbMiAqIGJdID0gYng7CiAgICAgICAgICB2ZXJ0aWNlc1syICogYiArIDFdID0gYnk7CiAgICAgICAgICB2ZXJ0aWNlc1syICogY10gPSBjeDsKICAgICAgICAgIHZlcnRpY2VzWzIgKiBjICsgMV0gPSBjeTsKICAgICAgICAgIHRyaWFuZ2xlc1t0cmlJbmRleCsrXSA9IGE7CiAgICAgICAgICB0cmlhbmdsZXNbdHJpSW5kZXgrK10gPSBiOwogICAgICAgICAgdHJpYW5nbGVzW3RyaUluZGV4KytdID0gYzsKICAgICAgICB9CiAgICAgIH0KICAgICAgcHJvY2Vzc1RyaWFuZ2xlKDAsIDAsIG1heCwgbWF4LCBtYXgsIDApOwogICAgICBwcm9jZXNzVHJpYW5nbGUobWF4LCBtYXgsIDAsIDAsIDAsIG1heCk7CiAgICAgIHJldHVybiB7CiAgICAgICAgdmVydGljZXMsCiAgICAgICAgdHJpYW5nbGVzCiAgICAgIH07CiAgICB9CiAgfQoKICAvLyBodHRwczovL2dpdGh1Yi5jb20vQ2VzaXVtR1MvY2VzaXVtL2Jsb2IvMS43Ni9Tb3VyY2UvV29ya2Vyc0VTNi9jcmVhdGVWZXJ0aWNlc0Zyb21RdWFudGl6ZWRUZXJyYWluTWVzaC5qcwoKICB2YXIgbWFydGluaSA9IG51bGw7CiAgZnVuY3Rpb24gZGVjb2RlVGVycmFpbihwYXJhbWV0ZXJzLCB0cmFuc2ZlcmFibGVPYmplY3RzKSB7CiAgICB2YXIgX21hcnRpbmk7CiAgICB2YXIgaW1hZ2VEYXRhID0gcGFyYW1ldGVycy5pbWFnZURhdGEsCiAgICAgIF9wYXJhbWV0ZXJzJHRpbGVTaXplID0gcGFyYW1ldGVycy50aWxlU2l6ZSwKICAgICAgdGlsZVNpemUgPSBfcGFyYW1ldGVycyR0aWxlU2l6ZSA9PT0gdm9pZCAwID8gMjU2IDogX3BhcmFtZXRlcnMkdGlsZVNpemUsCiAgICAgIGVycm9yTGV2ZWwgPSBwYXJhbWV0ZXJzLmVycm9yTGV2ZWwsCiAgICAgIGludGVydmFsID0gcGFyYW1ldGVycy5pbnRlcnZhbCwKICAgICAgb2Zmc2V0ID0gcGFyYW1ldGVycy5vZmZzZXQ7CiAgICB2YXIgcGl4ZWxzID0gbmRhcnJheShuZXcgVWludDhBcnJheShpbWFnZURhdGEpLCBbdGlsZVNpemUsIHRpbGVTaXplLCA0XSwgWzQsIDQgKiB0aWxlU2l6ZSwgMV0sIDApOwoKICAgIC8vIFRpbGUgc2l6ZSBtdXN0IGJlIG1haW50YWluZWQgdGhyb3VnaCB0aGUgbGlmZSBvZiB0aGUgd29ya2VyCiAgICAoX21hcnRpbmkgPSBtYXJ0aW5pKSAhPT0gbnVsbCAmJiBfbWFydGluaSAhPT0gdm9pZCAwID8gX21hcnRpbmkgOiBtYXJ0aW5pID0gbmV3IE1hcnRpbmkodGlsZVNpemUgKyAxKTsKICAgIHZhciB0ZXJyYWluID0gbWFwYm94VGVycmFpblRvR3JpZChwaXhlbHMsIGludGVydmFsLCBvZmZzZXQpOwogICAgdmFyIHRpbGUgPSBtYXJ0aW5pLmNyZWF0ZVRpbGUodGVycmFpbik7CgogICAgLy8gZ2V0IGEgbWVzaCAodmVydGljZXMgYW5kIHRyaWFuZ2xlcyBpbmRpY2VzKSBmb3IgYSAxMG0gZXJyb3IKICAgIHZhciBtZXNoID0gdGlsZS5nZXRNZXNoKGVycm9yTGV2ZWwsIHBhcmFtZXRlcnMubWF4TGVuZ3RoKTsKICAgIHJldHVybiBjcmVhdGVRdWFudGl6ZWRNZXNoRGF0YSh0aWxlLCBtZXNoLCB0aWxlU2l6ZSk7CiAgfQogIHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24gKG1zZykgewogICAgdmFyIF9tc2ckZGF0YSA9IG1zZy5kYXRhLAogICAgICBpZCA9IF9tc2ckZGF0YS5pZCwKICAgICAgcGF5bG9hZCA9IF9tc2ckZGF0YS5wYXlsb2FkOwogICAgaWYgKGlkID09IG51bGwpIHJldHVybjsKICAgIHZhciBvYmplY3RzID0gW107CiAgICB2YXIgcmVzID0gbnVsbDsKICAgIHRyeSB7CiAgICAgIHJlcyA9IGRlY29kZVRlcnJhaW4ocGF5bG9hZCk7CiAgICAgIG9iamVjdHMucHVzaChyZXMuaW5kaWNlcy5idWZmZXIpOwogICAgICBvYmplY3RzLnB1c2gocmVzLnF1YW50aXplZFZlcnRpY2VzLmJ1ZmZlcik7CiAgICAgIHNlbGYucG9zdE1lc3NhZ2UoewogICAgICAgIGlkOiBpZCwKICAgICAgICBwYXlsb2FkOiByZXMKICAgICAgfSwgb2JqZWN0cyk7CiAgICB9IGNhdGNoIChlcnIpIHsKICAgICAgc2VsZi5wb3N0TWVzc2FnZSh7CiAgICAgICAgaWQ6IGlkLAogICAgICAgIGVycjogZXJyLnRvU3RyaW5nKCkKICAgICAgfSk7CiAgICB9IGZpbmFsbHkgewogICAgICByZXMgPSBudWxsOwogICAgICBvYmplY3RzID0gbnVsbDsKICAgIH0KICB9OwoKICBleHBvcnRzLmRlY29kZVRlcnJhaW4gPSBkZWNvZGVUZXJyYWluOwoKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pOwoKICByZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsKCg==', null, false);
713
- /* eslint-enable */
714
-
715
- var resolves = {};
716
- var rejects = {};
717
- var globalMsgId = 0; // Activate calculation in the worker, returning a promise
718
- function sendMessage(_x, _x2, _x3) {
719
- return _sendMessage.apply(this, arguments);
720
- } // Handle incoming calculation result
721
- function _sendMessage() {
722
- _sendMessage = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(worker, payload, transferableObjects) {
723
- var msgId, msg;
724
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
725
- while (1) switch (_context2.prev = _context2.next) {
726
- case 0:
727
- msgId = globalMsgId++;
728
- msg = {
729
- id: msgId,
730
- payload: payload
731
- };
732
- return _context2.abrupt("return", new Promise(function (resolve, reject) {
733
- // save callbacks for later
734
- resolves[msgId] = resolve;
735
- rejects[msgId] = reject;
736
- worker.postMessage(msg, transferableObjects);
737
- }));
738
- case 3:
739
- case "end":
740
- return _context2.stop();
741
- }
742
- }, _callee2);
743
- }));
744
- return _sendMessage.apply(this, arguments);
745
- }
746
- function handleMessage(msg) {
747
- var _msg$data = msg.data,
748
- id = _msg$data.id,
749
- err = _msg$data.err,
750
- payload = _msg$data.payload;
751
- if (payload) {
752
- var resolve = resolves[id];
753
- if (resolve) {
754
- resolve(payload);
755
- }
756
- } else {
757
- // error condition
758
- var reject = rejects[id];
759
- if (reject) {
760
- if (err) {
761
- reject(err);
762
- } else {
763
- reject("Got nothing");
764
- }
765
- }
766
- }
767
-
768
- // purge used callbacks
769
- delete resolves[id];
770
- delete rejects[id];
771
- }
772
- var WorkerFarm = /*#__PURE__*/function () {
773
- function WorkerFarm() {
774
- _classCallCheck(this, WorkerFarm);
775
- this.worker = new WorkerFactory();
776
- this.worker.onmessage = handleMessage;
777
- }
778
- _createClass(WorkerFarm, [{
779
- key: "scheduleTask",
780
- value: function () {
781
- var _scheduleTask = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(params, transferableObjects) {
782
- return _regeneratorRuntime().wrap(function _callee$(_context) {
783
- while (1) switch (_context.prev = _context.next) {
784
- case 0:
785
- _context.next = 2;
786
- return sendMessage(this.worker, params, transferableObjects);
787
- case 2:
788
- return _context.abrupt("return", _context.sent);
789
- case 3:
790
- case "end":
791
- return _context.stop();
792
- }
793
- }, _callee, this);
794
- }));
795
- function scheduleTask(_x4, _x5) {
796
- return _scheduleTask.apply(this, arguments);
797
- }
798
- return scheduleTask;
799
- }()
800
- }]);
801
- return WorkerFarm;
802
- }();
803
-
804
- // We should save these
805
- //const canvas = new OffscreenCanvas(256, 256);
806
- //const ctx = canvas.getContext("2d");
807
-
808
- function mapboxTerrainToGrid(png, interval, offset) {
809
- var _interval, _offset;
651
+ /** Mapbox Terrain-RGB default decode function
652
+ * (r * 256 * 256) / 10 + (g * 256) / 10 + b / 10 - 10000
653
+ */
654
+ var defaultMapboxDecodeRgb = function defaultMapboxDecodeRgb(r, g, b, a) {
655
+ return r * 6553.6 + g * 25.6 + b * 0.1 - 10000;
656
+ };
657
+ function rgbTerrainToGrid(png, decodeRgb) {
810
658
  // maybe we should do this on the GPU using REGL?
811
659
  // but that would require GPU -> CPU -> GPU
812
660
  var gridSize = png.shape[0] + 1;
813
661
  var terrain = new Float32Array(gridSize * gridSize);
814
662
  var tileSize = png.shape[0];
815
- interval = (_interval = interval) !== null && _interval !== void 0 ? _interval : 0.1;
816
- offset = (_offset = offset) !== null && _offset !== void 0 ? _offset : -10000;
663
+ var decode = decodeRgb !== null && decodeRgb !== void 0 ? decodeRgb : defaultMapboxDecodeRgb;
817
664
 
818
665
  // decode terrain values
819
666
  for (var y = 0; y < tileSize; y++) {
820
667
  for (var x = 0; x < tileSize; x++) {
821
668
  var yc = y;
822
- var r = png.get(x, yc, 0);
823
- var g = png.get(x, yc, 1);
824
- var b = png.get(x, yc, 2);
825
- terrain[y * gridSize + x] = r * 256 * 256 * interval + g * 256.0 * interval + b * interval + offset;
669
+ var _r = png.get(x, yc, 0);
670
+ var _g = png.get(x, yc, 1);
671
+ var _b = png.get(x, yc, 2);
672
+ var _a = png.get(x, yc, 3);
673
+ terrain[y * gridSize + x] = decode(_r, _g, _b, _a);
826
674
  }
827
675
  }
828
676
  // backfill right and bottom borders
@@ -834,6 +682,42 @@ function mapboxTerrainToGrid(png, interval, offset) {
834
682
  }
835
683
  return terrain;
836
684
  }
685
+ function subsetByWindow(array, window, augmented) {
686
+ var sz = Math.sqrt(array.length);
687
+ var x0 = window.x0;
688
+ var x1 = window.x1;
689
+ var y0 = window.y0;
690
+ var y1 = window.y1;
691
+ var aug = augmented ? 1 : 0;
692
+ var n = Math.floor(x1 - x0) + aug;
693
+ var m = Math.floor(y1 - y0) + aug;
694
+ var result = new Float32Array(n * m);
695
+ for (var i = 0; i < m; i++) {
696
+ for (var j = 0; j < n; j++) {
697
+ result[i * n + j] = array[(i + y0) * sz + j + x0];
698
+ }
699
+ }
700
+ return result;
701
+ }
702
+ function testMeshData() {
703
+ return {
704
+ minimumHeight: -100,
705
+ maximumHeight: 2101,
706
+ quantizedVertices: new Uint16Array([
707
+ // order is SW NW SE NE
708
+ // longitude
709
+ 0, 0, 32767, 32767,
710
+ // latitude
711
+ 0, 32767, 0, 32767,
712
+ // heights
713
+ 16384, 0, 32767, 16384]),
714
+ indices: new Uint16Array([0, 3, 1, 0, 2, 3]),
715
+ westIndices: [0, 1],
716
+ southIndices: [0, 1],
717
+ eastIndices: [2, 3],
718
+ northIndices: [1, 3]
719
+ };
720
+ }
837
721
  function _emptyMesh(n) {
838
722
  n = Math.max(n, 2);
839
723
  var nTriangles = Math.pow(n - 1, 2) * 2;
@@ -894,7 +778,14 @@ function emptyMesh(n) {
894
778
  return result;
895
779
  }
896
780
  }
897
- function createQuantizedMeshData(tile, mesh, tileSize) {
781
+
782
+ /** Terrain workers should return a quantized mesh */
783
+
784
+ function createQuantizedMeshData(tile, mesh, tileSize, terrain) {
785
+ /** Terrain is passed through so we can keep track of it
786
+ * for overscaled tiles
787
+ */
788
+
898
789
  var xvals = [];
899
790
  var yvals = [];
900
791
  var heightMeters = [];
@@ -905,6 +796,9 @@ function createQuantizedMeshData(tile, mesh, tileSize) {
905
796
  var minimumHeight = Infinity;
906
797
  var maximumHeight = -Infinity;
907
798
  var scalar = 32768.0 / tileSize;
799
+
800
+ // There appears to be a problem with the x/y indexing when using 512x512 tiles
801
+ // This may be solved by increasing the minumumErrorLevel in the terrain provider
908
802
  for (var ix = 0; ix < mesh.vertices.length / 2; ix++) {
909
803
  var vertexIx = ix;
910
804
  var px = mesh.vertices[ix * 2];
@@ -925,10 +819,10 @@ function createQuantizedMeshData(tile, mesh, tileSize) {
925
819
  var heightRange = maximumHeight - minimumHeight;
926
820
  var heights = heightMeters.map(function (d) {
927
821
  if (heightRange < 1) return 0;
928
- return (d - minimumHeight) * (32767.0 / heightRange);
822
+ return (d - minimumHeight) * (32768.0 / heightRange);
929
823
  });
930
824
  var triangles = new Uint16Array(mesh.triangles);
931
- var quantizedVertices = new Uint16Array( //verts
825
+ var quantizedVertices = new Uint16Array(//verts
932
826
  [].concat(xvals, yvals, _toConsumableArray(heights)));
933
827
 
934
828
  // SE NW NE
@@ -942,250 +836,469 @@ function createQuantizedMeshData(tile, mesh, tileSize) {
942
836
  westIndices: westIndices,
943
837
  southIndices: southIndices,
944
838
  eastIndices: eastIndices,
945
- northIndices: northIndices
839
+ northIndices: northIndices,
840
+ quantizedHeights: terrain
946
841
  };
947
842
  }
948
843
 
949
- class Martini {
950
- constructor(gridSize = 257) {
951
- this.gridSize = gridSize;
952
- const tileSize = gridSize - 1;
953
- if (tileSize & tileSize - 1) throw new Error(`Expected grid size to be 2^n+1, got ${gridSize}.`);
954
- this.numTriangles = tileSize * tileSize * 2 - 2;
955
- this.numParentTriangles = this.numTriangles - tileSize * tileSize;
956
- this.indices = new Uint32Array(this.gridSize * this.gridSize);
957
-
958
- // coordinates for all possible triangles in an RTIN tile
959
- this.coords = new Uint16Array(this.numTriangles * 4);
960
-
961
- // get triangle coordinates from its index in an implicit binary tree
962
- for (let i = 0; i < this.numTriangles; i++) {
963
- let id = i + 2;
964
- let ax = 0,
965
- ay = 0,
966
- bx = 0,
967
- by = 0,
968
- cx = 0,
969
- cy = 0;
970
- if (id & 1) {
971
- bx = by = cx = tileSize; // bottom-left triangle
844
+ var resolves = {};
845
+ var rejects = {};
846
+ var globalMsgId = 0; // Activate calculation in the worker, returning a promise
847
+ function sendMessage(_x, _x2, _x3) {
848
+ return _sendMessage.apply(this, arguments);
849
+ } // Handle incoming calculation result
850
+ function _sendMessage() {
851
+ _sendMessage = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(worker, payload, transferableObjects) {
852
+ var msgId, msg;
853
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
854
+ while (1) switch (_context3.prev = _context3.next) {
855
+ case 0:
856
+ msgId = globalMsgId++;
857
+ msg = {
858
+ id: msgId,
859
+ payload: payload
860
+ };
861
+ return _context3.abrupt("return", new Promise(function (resolve, reject) {
862
+ // save callbacks for later
863
+ resolves[msgId] = resolve;
864
+ rejects[msgId] = reject;
865
+ worker.postMessage(msg, transferableObjects);
866
+ }));
867
+ case 3:
868
+ case "end":
869
+ return _context3.stop();
870
+ }
871
+ }, _callee3);
872
+ }));
873
+ return _sendMessage.apply(this, arguments);
874
+ }
875
+ function handleMessage(msg) {
876
+ var _msg$data = msg.data,
877
+ id = _msg$data.id,
878
+ err = _msg$data.err,
879
+ payload = _msg$data.payload;
880
+ if (payload) {
881
+ var resolve = resolves[id];
882
+ if (resolve) {
883
+ resolve(payload);
884
+ }
885
+ } else {
886
+ // error condition
887
+ var reject = rejects[id];
888
+ if (reject) {
889
+ if (err) {
890
+ reject(err);
972
891
  } else {
973
- ax = ay = cy = tileSize; // top-right triangle
892
+ reject("Got nothing");
974
893
  }
894
+ }
895
+ }
975
896
 
976
- while ((id >>= 1) > 1) {
977
- const mx = ax + bx >> 1;
978
- const my = ay + by >> 1;
979
- if (id & 1) {
980
- // left half
981
- bx = ax;
982
- by = ay;
983
- ax = cx;
984
- ay = cy;
985
- } else {
986
- // right half
987
- ax = bx;
988
- ay = by;
989
- bx = cx;
990
- by = cy;
991
- }
992
- cx = mx;
993
- cy = my;
897
+ // purge used callbacks
898
+ delete resolves[id];
899
+ delete rejects[id];
900
+ }
901
+ var WorkerFarm = /*#__PURE__*/function () {
902
+ function WorkerFarm(opts) {
903
+ _classCallCheck(this, WorkerFarm);
904
+ _defineProperty(this, "inProgressWorkers", 0);
905
+ _defineProperty(this, "maxWorkers", 5);
906
+ _defineProperty(this, "processingQueue", []);
907
+ this.worker = opts.worker;
908
+ this.worker.onmessage = handleMessage;
909
+ }
910
+ return _createClass(WorkerFarm, [{
911
+ key: "scheduleTask",
912
+ value: function () {
913
+ var _scheduleTask = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(params, transferableObjects) {
914
+ var res;
915
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
916
+ while (1) switch (_context.prev = _context.next) {
917
+ case 0:
918
+ _context.next = 2;
919
+ return sendMessage(this.worker, params, transferableObjects);
920
+ case 2:
921
+ res = _context.sent;
922
+ this.releaseWorker();
923
+ return _context.abrupt("return", res);
924
+ case 5:
925
+ case "end":
926
+ return _context.stop();
927
+ }
928
+ }, _callee, this);
929
+ }));
930
+ function scheduleTask(_x4, _x5) {
931
+ return _scheduleTask.apply(this, arguments);
932
+ }
933
+ return scheduleTask;
934
+ }()
935
+ }, {
936
+ key: "holdForAvailableWorker",
937
+ value: function () {
938
+ var _holdForAvailableWorker = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
939
+ var _this = this;
940
+ var resultPromise;
941
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
942
+ while (1) switch (_context2.prev = _context2.next) {
943
+ case 0:
944
+ if (this.inProgressWorkers > this.maxWorkers) {
945
+ resultPromise = new Promise(function (resolve, reject) {
946
+ _this.processingQueue.push(resolve);
947
+ });
948
+ } else {
949
+ resultPromise = Promise.resolve(null);
950
+ }
951
+ _context2.next = 3;
952
+ return resultPromise;
953
+ case 3:
954
+ this.inProgressWorkers += 1;
955
+ case 4:
956
+ case "end":
957
+ return _context2.stop();
958
+ }
959
+ }, _callee2, this);
960
+ }));
961
+ function holdForAvailableWorker() {
962
+ return _holdForAvailableWorker.apply(this, arguments);
963
+ }
964
+ return holdForAvailableWorker;
965
+ }()
966
+ }, {
967
+ key: "releaseWorker",
968
+ value: function releaseWorker() {
969
+ this.inProgressWorkers -= 1;
970
+ if (this.processingQueue.length > 0) {
971
+ this.processingQueue.shift()();
994
972
  }
995
- const k = i * 4;
996
- this.coords[k + 0] = ax;
997
- this.coords[k + 1] = ay;
998
- this.coords[k + 2] = bx;
999
- this.coords[k + 3] = by;
1000
973
  }
974
+ }]);
975
+ }();
976
+
977
+ var DefaultTerrainDecoder = /*#__PURE__*/function () {
978
+ function DefaultTerrainDecoder() {
979
+ _classCallCheck(this, DefaultTerrainDecoder);
980
+ _defineProperty(this, "inProgress", 0);
981
+ _defineProperty(this, "maxRequests", 2);
1001
982
  }
1002
- createTile(terrain) {
1003
- return new Tile(terrain, this);
983
+ return _createClass(DefaultTerrainDecoder, [{
984
+ key: "requestTileGeometry",
985
+ value: function requestTileGeometry(coords, processFunction) {
986
+ var _this = this;
987
+ if (this.inProgress > this.maxRequests) return undefined;
988
+ this.inProgress += 1;
989
+ return processFunction(coords)["finally"](function () {
990
+ _this.inProgress -= 1;
991
+ });
992
+ }
993
+ }, {
994
+ key: "decodeTerrain",
995
+ value: function decodeTerrain(params, data) {
996
+ return Promise.resolve(null);
997
+ }
998
+ }]);
999
+ }();
1000
+ var WorkerFarmTerrainDecoder = /*#__PURE__*/function (_DefaultTerrainDecode) {
1001
+ function WorkerFarmTerrainDecoder(opts) {
1002
+ var _opts$maxWorkers;
1003
+ var _this2;
1004
+ _classCallCheck(this, WorkerFarmTerrainDecoder);
1005
+ _this2 = _callSuper(this, WorkerFarmTerrainDecoder);
1006
+ _this2.farm = new WorkerFarm({
1007
+ worker: opts.worker
1008
+ });
1009
+ _this2.maxRequests = (_opts$maxWorkers = opts.maxWorkers) !== null && _opts$maxWorkers !== void 0 ? _opts$maxWorkers : 5;
1010
+ return _this2;
1004
1011
  }
1012
+ _inherits(WorkerFarmTerrainDecoder, _DefaultTerrainDecode);
1013
+ return _createClass(WorkerFarmTerrainDecoder, [{
1014
+ key: "decodeTerrain",
1015
+ value: function decodeTerrain(params, data) {
1016
+ return this.farm.scheduleTask(params, [data]);
1017
+ }
1018
+ }]);
1019
+ }(DefaultTerrainDecoder);
1020
+
1021
+ function decodeBase64(base64, enableUnicode) {
1022
+ var binaryString = atob(base64);
1023
+ if (enableUnicode) {
1024
+ var binaryView = new Uint8Array(binaryString.length);
1025
+ for (var i = 0, n = binaryString.length; i < n; ++i) {
1026
+ binaryView[i] = binaryString.charCodeAt(i);
1027
+ }
1028
+ const decoder = new TextDecoder("utf-16le");
1029
+ return decoder.decode(new Uint16Array(binaryView.buffer));
1030
+ }
1031
+ return binaryString;
1032
+ }
1033
+
1034
+ function createURL(base64, sourcemapArg, enableUnicodeArg) {
1035
+ var sourcemap = sourcemapArg === undefined ? null : sourcemapArg;
1036
+ var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg;
1037
+ var source = decodeBase64(base64, enableUnicode);
1038
+ var start = source.indexOf('\n', 10) + 1;
1039
+ var body = source.substring(start) + (sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : '');
1040
+ var blob = new Blob([body], { type: 'application/javascript' });
1041
+ return URL.createObjectURL(blob);
1005
1042
  }
1006
- class Tile {
1007
- constructor(terrain, martini) {
1008
- const size = martini.gridSize;
1009
- if (terrain.length !== size * size) throw new Error(`Expected terrain data of length ${size * size} (${size} x ${size}), got ${terrain.length}.`);
1010
- this.terrain = terrain;
1011
- this.martini = martini;
1012
- this.errors = new Float32Array(terrain.length);
1013
- this.update();
1043
+
1044
+ function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) {
1045
+ var url;
1046
+ return function WorkerFactory(options) {
1047
+ url = url || createURL(base64, sourcemapArg, enableUnicodeArg);
1048
+ return new Worker(url, options);
1049
+ };
1050
+ }
1051
+
1052
+ var WorkerFactory$1 = /*#__PURE__*/createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkociwgYSkgewogICAgKG51bGwgPT0gYSB8fCBhID4gci5sZW5ndGgpICYmIChhID0gci5sZW5ndGgpOwogICAgZm9yICh2YXIgZSA9IDAsIG4gPSBBcnJheShhKTsgZSA8IGE7IGUrKykgbltlXSA9IHJbZV07CiAgICByZXR1cm4gbjsKICB9CiAgZnVuY3Rpb24gX2FycmF5V2l0aG91dEhvbGVzKHIpIHsKICAgIGlmIChBcnJheS5pc0FycmF5KHIpKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkocik7CiAgfQogIGZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXkocikgewogICAgaWYgKCJ1bmRlZmluZWQiICE9IHR5cGVvZiBTeW1ib2wgJiYgbnVsbCAhPSByW1N5bWJvbC5pdGVyYXRvcl0gfHwgbnVsbCAhPSByWyJAQGl0ZXJhdG9yIl0pIHJldHVybiBBcnJheS5mcm9tKHIpOwogIH0KICBmdW5jdGlvbiBfbm9uSXRlcmFibGVTcHJlYWQoKSB7CiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJJbnZhbGlkIGF0dGVtcHQgdG8gc3ByZWFkIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC4iKTsKICB9CiAgZnVuY3Rpb24gX3RvQ29uc3VtYWJsZUFycmF5KHIpIHsKICAgIHJldHVybiBfYXJyYXlXaXRob3V0SG9sZXMocikgfHwgX2l0ZXJhYmxlVG9BcnJheShyKSB8fCBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkocikgfHwgX25vbkl0ZXJhYmxlU3ByZWFkKCk7CiAgfQogIGZ1bmN0aW9uIF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShyLCBhKSB7CiAgICBpZiAocikgewogICAgICBpZiAoInN0cmluZyIgPT0gdHlwZW9mIHIpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShyLCBhKTsKICAgICAgdmFyIHQgPSB7fS50b1N0cmluZy5jYWxsKHIpLnNsaWNlKDgsIC0xKTsKICAgICAgcmV0dXJuICJPYmplY3QiID09PSB0ICYmIHIuY29uc3RydWN0b3IgJiYgKHQgPSByLmNvbnN0cnVjdG9yLm5hbWUpLCAiTWFwIiA9PT0gdCB8fCAiU2V0IiA9PT0gdCA/IEFycmF5LmZyb20ocikgOiAiQXJndW1lbnRzIiA9PT0gdCB8fCAvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdCh0KSA/IF9hcnJheUxpa2VUb0FycmF5KHIsIGEpIDogdm9pZCAwOwogICAgfQogIH0KCiAgLyoqIFRlcnJhaW4gd29ya2VycyBzaG91bGQgcmV0dXJuIGEgcXVhbnRpemVkIG1lc2ggKi8KCiAgZnVuY3Rpb24gY3JlYXRlUXVhbnRpemVkTWVzaERhdGEodGlsZSwgbWVzaCwgdGlsZVNpemUsIHRlcnJhaW4pIHsKICAgIC8qKiBUZXJyYWluIGlzIHBhc3NlZCB0aHJvdWdoIHNvIHdlIGNhbiBrZWVwIHRyYWNrIG9mIGl0CiAgICAgKiBmb3Igb3ZlcnNjYWxlZCB0aWxlcwogICAgICovCgogICAgdmFyIHh2YWxzID0gW107CiAgICB2YXIgeXZhbHMgPSBbXTsKICAgIHZhciBoZWlnaHRNZXRlcnMgPSBbXTsKICAgIHZhciBub3J0aEluZGljZXMgPSBbXTsKICAgIHZhciBzb3V0aEluZGljZXMgPSBbXTsKICAgIHZhciBlYXN0SW5kaWNlcyA9IFtdOwogICAgdmFyIHdlc3RJbmRpY2VzID0gW107CiAgICB2YXIgbWluaW11bUhlaWdodCA9IEluZmluaXR5OwogICAgdmFyIG1heGltdW1IZWlnaHQgPSAtSW5maW5pdHk7CiAgICB2YXIgc2NhbGFyID0gMzI3NjguMCAvIHRpbGVTaXplOwoKICAgIC8vIFRoZXJlIGFwcGVhcnMgdG8gYmUgYSBwcm9ibGVtIHdpdGggdGhlIHgveSBpbmRleGluZyB3aGVuIHVzaW5nIDUxMng1MTIgdGlsZXMKICAgIC8vIFRoaXMgbWF5IGJlIHNvbHZlZCBieSBpbmNyZWFzaW5nIHRoZSBtaW51bXVtRXJyb3JMZXZlbCBpbiB0aGUgdGVycmFpbiBwcm92aWRlcgogICAgZm9yICh2YXIgaXggPSAwOyBpeCA8IG1lc2gudmVydGljZXMubGVuZ3RoIC8gMjsgaXgrKykgewogICAgICB2YXIgdmVydGV4SXggPSBpeDsKICAgICAgdmFyIHB4ID0gbWVzaC52ZXJ0aWNlc1tpeCAqIDJdOwogICAgICB2YXIgcHkgPSBtZXNoLnZlcnRpY2VzW2l4ICogMiArIDFdOwogICAgICB2YXIgaGVpZ2h0ID0gdGlsZS50ZXJyYWluW3B5ICogKHRpbGVTaXplICsgMSkgKyBweF07CiAgICAgIGlmIChoZWlnaHQgPiBtYXhpbXVtSGVpZ2h0KSBtYXhpbXVtSGVpZ2h0ID0gaGVpZ2h0OwogICAgICBpZiAoaGVpZ2h0IDwgbWluaW11bUhlaWdodCkgbWluaW11bUhlaWdodCA9IGhlaWdodDsKICAgICAgaGVpZ2h0TWV0ZXJzLnB1c2goaGVpZ2h0KTsKICAgICAgaWYgKHB5ID09IDApIG5vcnRoSW5kaWNlcy5wdXNoKHZlcnRleEl4KTsKICAgICAgaWYgKHB5ID09IHRpbGVTaXplKSBzb3V0aEluZGljZXMucHVzaCh2ZXJ0ZXhJeCk7CiAgICAgIGlmIChweCA9PSAwKSB3ZXN0SW5kaWNlcy5wdXNoKHZlcnRleEl4KTsKICAgICAgaWYgKHB4ID09IHRpbGVTaXplKSBlYXN0SW5kaWNlcy5wdXNoKHZlcnRleEl4KTsKICAgICAgdmFyIHh2ID0gcHggKiBzY2FsYXI7CiAgICAgIHZhciB5diA9ICh0aWxlU2l6ZSAtIHB5KSAqIHNjYWxhcjsKICAgICAgeHZhbHMucHVzaCh4dik7CiAgICAgIHl2YWxzLnB1c2goeXYpOwogICAgfQogICAgdmFyIGhlaWdodFJhbmdlID0gbWF4aW11bUhlaWdodCAtIG1pbmltdW1IZWlnaHQ7CiAgICB2YXIgaGVpZ2h0cyA9IGhlaWdodE1ldGVycy5tYXAoZnVuY3Rpb24gKGQpIHsKICAgICAgaWYgKGhlaWdodFJhbmdlIDwgMSkgcmV0dXJuIDA7CiAgICAgIHJldHVybiAoZCAtIG1pbmltdW1IZWlnaHQpICogKDMyNzY4LjAgLyBoZWlnaHRSYW5nZSk7CiAgICB9KTsKICAgIHZhciB0cmlhbmdsZXMgPSBuZXcgVWludDE2QXJyYXkobWVzaC50cmlhbmdsZXMpOwogICAgdmFyIHF1YW50aXplZFZlcnRpY2VzID0gbmV3IFVpbnQxNkFycmF5KC8vdmVydHMKICAgIFtdLmNvbmNhdCh4dmFscywgeXZhbHMsIF90b0NvbnN1bWFibGVBcnJheShoZWlnaHRzKSkpOwoKICAgIC8vIFNFIE5XIE5FCiAgICAvLyBORSBOVyBTRQoKICAgIHJldHVybiB7CiAgICAgIG1pbmltdW1IZWlnaHQ6IG1pbmltdW1IZWlnaHQsCiAgICAgIG1heGltdW1IZWlnaHQ6IG1heGltdW1IZWlnaHQsCiAgICAgIHF1YW50aXplZFZlcnRpY2VzOiBxdWFudGl6ZWRWZXJ0aWNlcywKICAgICAgaW5kaWNlczogdHJpYW5nbGVzLAogICAgICB3ZXN0SW5kaWNlczogd2VzdEluZGljZXMsCiAgICAgIHNvdXRoSW5kaWNlczogc291dGhJbmRpY2VzLAogICAgICBlYXN0SW5kaWNlczogZWFzdEluZGljZXMsCiAgICAgIG5vcnRoSW5kaWNlczogbm9ydGhJbmRpY2VzLAogICAgICBxdWFudGl6ZWRIZWlnaHRzOiB0ZXJyYWluCiAgICB9OwogIH0KCiAgY2xhc3MgTWFydGluaSB7CiAgICAgIGNvbnN0cnVjdG9yKGdyaWRTaXplID0gMjU3KSB7CiAgICAgICAgICB0aGlzLmdyaWRTaXplID0gZ3JpZFNpemU7CiAgICAgICAgICBjb25zdCB0aWxlU2l6ZSA9IGdyaWRTaXplIC0gMTsKICAgICAgICAgIGlmICh0aWxlU2l6ZSAmICh0aWxlU2l6ZSAtIDEpKSB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAgICAgYEV4cGVjdGVkIGdyaWQgc2l6ZSB0byBiZSAyXm4rMSwgZ290ICR7Z3JpZFNpemV9LmApOwoKICAgICAgICAgIHRoaXMubnVtVHJpYW5nbGVzID0gdGlsZVNpemUgKiB0aWxlU2l6ZSAqIDIgLSAyOwogICAgICAgICAgdGhpcy5udW1QYXJlbnRUcmlhbmdsZXMgPSB0aGlzLm51bVRyaWFuZ2xlcyAtIHRpbGVTaXplICogdGlsZVNpemU7CgogICAgICAgICAgdGhpcy5pbmRpY2VzID0gbmV3IFVpbnQzMkFycmF5KHRoaXMuZ3JpZFNpemUgKiB0aGlzLmdyaWRTaXplKTsKCiAgICAgICAgICAvLyBjb29yZGluYXRlcyBmb3IgYWxsIHBvc3NpYmxlIHRyaWFuZ2xlcyBpbiBhbiBSVElOIHRpbGUKICAgICAgICAgIHRoaXMuY29vcmRzID0gbmV3IFVpbnQxNkFycmF5KHRoaXMubnVtVHJpYW5nbGVzICogNCk7CgogICAgICAgICAgLy8gZ2V0IHRyaWFuZ2xlIGNvb3JkaW5hdGVzIGZyb20gaXRzIGluZGV4IGluIGFuIGltcGxpY2l0IGJpbmFyeSB0cmVlCiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubnVtVHJpYW5nbGVzOyBpKyspIHsKICAgICAgICAgICAgICBsZXQgaWQgPSBpICsgMjsKICAgICAgICAgICAgICBsZXQgYXggPSAwLCBheSA9IDAsIGJ4ID0gMCwgYnkgPSAwLCBjeCA9IDAsIGN5ID0gMDsKICAgICAgICAgICAgICBpZiAoaWQgJiAxKSB7CiAgICAgICAgICAgICAgICAgIGJ4ID0gYnkgPSBjeCA9IHRpbGVTaXplOyAvLyBib3R0b20tbGVmdCB0cmlhbmdsZQogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGF4ID0gYXkgPSBjeSA9IHRpbGVTaXplOyAvLyB0b3AtcmlnaHQgdHJpYW5nbGUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgd2hpbGUgKChpZCA+Pj0gMSkgPiAxKSB7CiAgICAgICAgICAgICAgICAgIGNvbnN0IG14ID0gKGF4ICsgYngpID4+IDE7CiAgICAgICAgICAgICAgICAgIGNvbnN0IG15ID0gKGF5ICsgYnkpID4+IDE7CgogICAgICAgICAgICAgICAgICBpZiAoaWQgJiAxKSB7IC8vIGxlZnQgaGFsZgogICAgICAgICAgICAgICAgICAgICAgYnggPSBheDsgYnkgPSBheTsKICAgICAgICAgICAgICAgICAgICAgIGF4ID0gY3g7IGF5ID0gY3k7CiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7IC8vIHJpZ2h0IGhhbGYKICAgICAgICAgICAgICAgICAgICAgIGF4ID0gYng7IGF5ID0gYnk7CiAgICAgICAgICAgICAgICAgICAgICBieCA9IGN4OyBieSA9IGN5OwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGN4ID0gbXg7IGN5ID0gbXk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGNvbnN0IGsgPSBpICogNDsKICAgICAgICAgICAgICB0aGlzLmNvb3Jkc1trICsgMF0gPSBheDsKICAgICAgICAgICAgICB0aGlzLmNvb3Jkc1trICsgMV0gPSBheTsKICAgICAgICAgICAgICB0aGlzLmNvb3Jkc1trICsgMl0gPSBieDsKICAgICAgICAgICAgICB0aGlzLmNvb3Jkc1trICsgM10gPSBieTsKICAgICAgICAgIH0KICAgICAgfQoKICAgICAgY3JlYXRlVGlsZSh0ZXJyYWluKSB7CiAgICAgICAgICByZXR1cm4gbmV3IFRpbGUodGVycmFpbiwgdGhpcyk7CiAgICAgIH0KICB9CgogIGNsYXNzIFRpbGUgewogICAgICBjb25zdHJ1Y3Rvcih0ZXJyYWluLCBtYXJ0aW5pKSB7CiAgICAgICAgICBjb25zdCBzaXplID0gbWFydGluaS5ncmlkU2l6ZTsKICAgICAgICAgIGlmICh0ZXJyYWluLmxlbmd0aCAhPT0gc2l6ZSAqIHNpemUpIHRocm93IG5ldyBFcnJvcigKICAgICAgICAgICAgICBgRXhwZWN0ZWQgdGVycmFpbiBkYXRhIG9mIGxlbmd0aCAke3NpemUgKiBzaXplfSAoJHtzaXplfSB4ICR7c2l6ZX0pLCBnb3QgJHt0ZXJyYWluLmxlbmd0aH0uYCk7CgogICAgICAgICAgdGhpcy50ZXJyYWluID0gdGVycmFpbjsKICAgICAgICAgIHRoaXMubWFydGluaSA9IG1hcnRpbmk7CiAgICAgICAgICB0aGlzLmVycm9ycyA9IG5ldyBGbG9hdDMyQXJyYXkodGVycmFpbi5sZW5ndGgpOwogICAgICAgICAgdGhpcy51cGRhdGUoKTsKICAgICAgfQoKICAgICAgdXBkYXRlKCkgewogICAgICAgICAgY29uc3Qge251bVRyaWFuZ2xlcywgbnVtUGFyZW50VHJpYW5nbGVzLCBjb29yZHMsIGdyaWRTaXplOiBzaXplfSA9IHRoaXMubWFydGluaTsKICAgICAgICAgIGNvbnN0IHt0ZXJyYWluLCBlcnJvcnN9ID0gdGhpczsKCiAgICAgICAgICAvLyBpdGVyYXRlIG92ZXIgYWxsIHBvc3NpYmxlIHRyaWFuZ2xlcywgc3RhcnRpbmcgZnJvbSB0aGUgc21hbGxlc3QgbGV2ZWwKICAgICAgICAgIGZvciAobGV0IGkgPSBudW1UcmlhbmdsZXMgLSAxOyBpID49IDA7IGktLSkgewogICAgICAgICAgICAgIGNvbnN0IGsgPSBpICogNDsKICAgICAgICAgICAgICBjb25zdCBheCA9IGNvb3Jkc1trICsgMF07CiAgICAgICAgICAgICAgY29uc3QgYXkgPSBjb29yZHNbayArIDFdOwogICAgICAgICAgICAgIGNvbnN0IGJ4ID0gY29vcmRzW2sgKyAyXTsKICAgICAgICAgICAgICBjb25zdCBieSA9IGNvb3Jkc1trICsgM107CiAgICAgICAgICAgICAgY29uc3QgbXggPSAoYXggKyBieCkgPj4gMTsKICAgICAgICAgICAgICBjb25zdCBteSA9IChheSArIGJ5KSA+PiAxOwogICAgICAgICAgICAgIGNvbnN0IGN4ID0gbXggKyBteSAtIGF5OwogICAgICAgICAgICAgIGNvbnN0IGN5ID0gbXkgKyBheCAtIG14OwoKICAgICAgICAgICAgICAvLyBjYWxjdWxhdGUgZXJyb3IgaW4gdGhlIG1pZGRsZSBvZiB0aGUgbG9uZyBlZGdlIG9mIHRoZSB0cmlhbmdsZQogICAgICAgICAgICAgIGNvbnN0IGludGVycG9sYXRlZEhlaWdodCA9ICh0ZXJyYWluW2F5ICogc2l6ZSArIGF4XSArIHRlcnJhaW5bYnkgKiBzaXplICsgYnhdKSAvIDI7CiAgICAgICAgICAgICAgY29uc3QgbWlkZGxlSW5kZXggPSBteSAqIHNpemUgKyBteDsKICAgICAgICAgICAgICBjb25zdCBtaWRkbGVFcnJvciA9IE1hdGguYWJzKGludGVycG9sYXRlZEhlaWdodCAtIHRlcnJhaW5bbWlkZGxlSW5kZXhdKTsKCiAgICAgICAgICAgICAgZXJyb3JzW21pZGRsZUluZGV4XSA9IE1hdGgubWF4KGVycm9yc1ttaWRkbGVJbmRleF0sIG1pZGRsZUVycm9yKTsKCiAgICAgICAgICAgICAgaWYgKGkgPCBudW1QYXJlbnRUcmlhbmdsZXMpIHsgLy8gYmlnZ2VyIHRyaWFuZ2xlczsgYWNjdW11bGF0ZSBlcnJvciB3aXRoIGNoaWxkcmVuCiAgICAgICAgICAgICAgICAgIGNvbnN0IGxlZnRDaGlsZEluZGV4ID0gKChheSArIGN5KSA+PiAxKSAqIHNpemUgKyAoKGF4ICsgY3gpID4+IDEpOwogICAgICAgICAgICAgICAgICBjb25zdCByaWdodENoaWxkSW5kZXggPSAoKGJ5ICsgY3kpID4+IDEpICogc2l6ZSArICgoYnggKyBjeCkgPj4gMSk7CiAgICAgICAgICAgICAgICAgIGVycm9yc1ttaWRkbGVJbmRleF0gPSBNYXRoLm1heChlcnJvcnNbbWlkZGxlSW5kZXhdLCBlcnJvcnNbbGVmdENoaWxkSW5kZXhdLCBlcnJvcnNbcmlnaHRDaGlsZEluZGV4XSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICB9CgogICAgICBnZXRNZXNoKG1heEVycm9yID0gMCwgbWF4TGVuZ3RoID0gbnVsbCkgewogICAgICAgICAgY29uc3Qge2dyaWRTaXplOiBzaXplLCBpbmRpY2VzfSA9IHRoaXMubWFydGluaTsKICAgICAgICAgIGNvbnN0IHtlcnJvcnN9ID0gdGhpczsKICAgICAgICAgIGxldCBudW1WZXJ0aWNlcyA9IDA7CiAgICAgICAgICBsZXQgbnVtVHJpYW5nbGVzID0gMDsKICAgICAgICAgIGNvbnN0IG1heCA9IHNpemUgLSAxOwoKICAgICAgICAgIC8vIFRoZSBtYXhMZW5ndGggcGFyYW1ldGVyIHdpbGwgY2F1c2UgdHJpYW5nbGVzIHRvIGJlIGdlbmVyYXRlZCB1bnRpbCB0aGUgbGVncyBhcmUgYmVsb3cgdGhpcyBsZW5ndGgKICAgICAgICAgIC8vIEl0IGlzIG1lYW50IHRvIHN1cHBvcnQgY2FzZXMgd2hlcmUgYSBjZXJ0YWluIG1lc2ggZGVuc2l0eSBpcyByZXF1aXJlZCB0byBkbyBzcGhlcmljYWwgbWF0aCBvbiBkaWdpdGFsIGdsb2JlcwogICAgICAgICAgY29uc3QgbWF4U2NhbGUgPSBtYXhMZW5ndGggfHwgc2l6ZTsKCiAgICAgICAgICAvLyB1c2UgYW4gaW5kZXggZ3JpZCB0byBrZWVwIHRyYWNrIG9mIHZlcnRpY2VzIHRoYXQgd2VyZSBhbHJlYWR5IHVzZWQgdG8gYXZvaWQgZHVwbGljYXRpb24KICAgICAgICAgIGluZGljZXMuZmlsbCgwKTsKCiAgICAgICAgICAvLyByZXRyaWV2ZSBtZXNoIGluIHR3byBzdGFnZXMgdGhhdCBib3RoIHRyYXZlcnNlIHRoZSBlcnJvciBtYXA6CiAgICAgICAgICAvLyAtIGNvdW50RWxlbWVudHM6IGZpbmQgdXNlZCB2ZXJ0aWNlcyAoYW5kIGFzc2lnbiBlYWNoIGFuIGluZGV4KSwgYW5kIGNvdW50IHRyaWFuZ2xlcyAoZm9yIG1pbmltdW0gYWxsb2NhdGlvbikKICAgICAgICAgIC8vIC0gcHJvY2Vzc1RyaWFuZ2xlOiBmaWxsIHRoZSBhbGxvY2F0ZWQgdmVydGljZXMgJiB0cmlhbmdsZXMgdHlwZWQgYXJyYXlzCgogICAgICAgICAgZnVuY3Rpb24gY291bnRFbGVtZW50cyhheCwgYXksIGJ4LCBieSwgY3gsIGN5KSB7CiAgICAgICAgICAgICAgY29uc3QgbXggPSAoYXggKyBieCkgPj4gMTsKICAgICAgICAgICAgICBjb25zdCBteSA9IChheSArIGJ5KSA+PiAxOwoKICAgICAgICAgICAgICBjb25zdCBsZWdMZW5ndGggPSBNYXRoLmFicyhheCAtIGN4KSArIE1hdGguYWJzKGF5IC0gY3kpOwogICAgICAgICAgICAgIGlmICgobGVnTGVuZ3RoID4gMSAmJiBlcnJvcnNbbXkgKiBzaXplICsgbXhdID4gbWF4RXJyb3IpIHx8IGxlZ0xlbmd0aCA+IG1heFNjYWxlKSB7CiAgICAgICAgICAgICAgICAgIGNvdW50RWxlbWVudHMoY3gsIGN5LCBheCwgYXksIG14LCBteSk7CiAgICAgICAgICAgICAgICAgIGNvdW50RWxlbWVudHMoYngsIGJ5LCBjeCwgY3ksIG14LCBteSk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW5kaWNlc1theSAqIHNpemUgKyBheF0gPSBpbmRpY2VzW2F5ICogc2l6ZSArIGF4XSB8fCArK251bVZlcnRpY2VzOwogICAgICAgICAgICAgICAgICBpbmRpY2VzW2J5ICogc2l6ZSArIGJ4XSA9IGluZGljZXNbYnkgKiBzaXplICsgYnhdIHx8ICsrbnVtVmVydGljZXM7CiAgICAgICAgICAgICAgICAgIGluZGljZXNbY3kgKiBzaXplICsgY3hdID0gaW5kaWNlc1tjeSAqIHNpemUgKyBjeF0gfHwgKytudW1WZXJ0aWNlczsKICAgICAgICAgICAgICAgICAgbnVtVHJpYW5nbGVzKys7CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgY291bnRFbGVtZW50cygwLCAwLCBtYXgsIG1heCwgbWF4LCAwKTsKICAgICAgICAgIGNvdW50RWxlbWVudHMobWF4LCBtYXgsIDAsIDAsIDAsIG1heCk7CgogICAgICAgICAgY29uc3QgdmVydGljZXMgPSBuZXcgVWludDE2QXJyYXkobnVtVmVydGljZXMgKiAyKTsKICAgICAgICAgIGNvbnN0IHRyaWFuZ2xlcyA9IG5ldyBVaW50MzJBcnJheShudW1UcmlhbmdsZXMgKiAzKTsKICAgICAgICAgIGxldCB0cmlJbmRleCA9IDA7CgogICAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1RyaWFuZ2xlKGF4LCBheSwgYngsIGJ5LCBjeCwgY3kpIHsKICAgICAgICAgICAgICBjb25zdCBteCA9IChheCArIGJ4KSA+PiAxOwogICAgICAgICAgICAgIGNvbnN0IG15ID0gKGF5ICsgYnkpID4+IDE7CgogICAgICAgICAgICAgIGNvbnN0IGxlZ0xlbmd0aCA9IE1hdGguYWJzKGF4IC0gY3gpICsgTWF0aC5hYnMoYXkgLSBjeSk7CiAgICAgICAgICAgICAgaWYgKChsZWdMZW5ndGggPiAxICYmIGVycm9yc1tteSAqIHNpemUgKyBteF0gPiBtYXhFcnJvcikgfHwgbGVnTGVuZ3RoID4gbWF4U2NhbGUpIHsKICAgICAgICAgICAgICAgICAgLy8gdHJpYW5nbGUgZG9lc24ndCBhcHByb3hpbWF0ZSB0aGUgc3VyZmFjZSB3ZWxsIGVub3VnaDsgZHJpbGwgZG93biBmdXJ0aGVyCiAgICAgICAgICAgICAgICAgIHByb2Nlc3NUcmlhbmdsZShjeCwgY3ksIGF4LCBheSwgbXgsIG15KTsKICAgICAgICAgICAgICAgICAgcHJvY2Vzc1RyaWFuZ2xlKGJ4LCBieSwgY3gsIGN5LCBteCwgbXkpOwoKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAvLyBhZGQgYSB0cmlhbmdsZQogICAgICAgICAgICAgICAgICBjb25zdCBhID0gaW5kaWNlc1theSAqIHNpemUgKyBheF0gLSAxOwogICAgICAgICAgICAgICAgICBjb25zdCBiID0gaW5kaWNlc1tieSAqIHNpemUgKyBieF0gLSAxOwogICAgICAgICAgICAgICAgICBjb25zdCBjID0gaW5kaWNlc1tjeSAqIHNpemUgKyBjeF0gLSAxOwoKICAgICAgICAgICAgICAgICAgdmVydGljZXNbMiAqIGFdID0gYXg7CiAgICAgICAgICAgICAgICAgIHZlcnRpY2VzWzIgKiBhICsgMV0gPSBheTsKCiAgICAgICAgICAgICAgICAgIHZlcnRpY2VzWzIgKiBiXSA9IGJ4OwogICAgICAgICAgICAgICAgICB2ZXJ0aWNlc1syICogYiArIDFdID0gYnk7CgogICAgICAgICAgICAgICAgICB2ZXJ0aWNlc1syICogY10gPSBjeDsKICAgICAgICAgICAgICAgICAgdmVydGljZXNbMiAqIGMgKyAxXSA9IGN5OwoKICAgICAgICAgICAgICAgICAgdHJpYW5nbGVzW3RyaUluZGV4KytdID0gYTsKICAgICAgICAgICAgICAgICAgdHJpYW5nbGVzW3RyaUluZGV4KytdID0gYjsKICAgICAgICAgICAgICAgICAgdHJpYW5nbGVzW3RyaUluZGV4KytdID0gYzsKICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBwcm9jZXNzVHJpYW5nbGUoMCwgMCwgbWF4LCBtYXgsIG1heCwgMCk7CiAgICAgICAgICBwcm9jZXNzVHJpYW5nbGUobWF4LCBtYXgsIDAsIDAsIDAsIG1heCk7CgogICAgICAgICAgcmV0dXJuIHt2ZXJ0aWNlcywgdHJpYW5nbGVzfTsKICAgICAgfQogIH0KCiAgLyoqIFdvcmtlciB0byB1cHNhbXBsZSB0ZXJyYWluIG1lc2hlcyAqLwogIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9DZXNpdW1HUy9jZXNpdW0vYmxvYi8xLjc2L1NvdXJjZS9Xb3JrZXJzRVM2L2NyZWF0ZVZlcnRpY2VzRnJvbVF1YW50aXplZFRlcnJhaW5NZXNoLmpzCgogIHZhciBtYXJ0aW5pQ2FjaGUgPSB7fTsKICBmdW5jdGlvbiBkZWNvZGVUZXJyYWluKHBhcmFtZXRlcnMsIHRyYW5zZmVyYWJsZU9iamVjdHMpIHsKICAgIHZhciBfbWFydGluaUNhY2hlJHRpbGVTaXo7CiAgICB2YXIgaGVpZ2h0RGF0YSA9IHBhcmFtZXRlcnMuaGVpZ2h0RGF0YSwKICAgICAgX3BhcmFtZXRlcnMkdGlsZVNpemUgPSBwYXJhbWV0ZXJzLnRpbGVTaXplLAogICAgICB0aWxlU2l6ZSA9IF9wYXJhbWV0ZXJzJHRpbGVTaXplID09PSB2b2lkIDAgPyAyNTYgOiBfcGFyYW1ldGVycyR0aWxlU2l6ZSwKICAgICAgZXJyb3JMZXZlbCA9IHBhcmFtZXRlcnMuZXJyb3JMZXZlbCwKICAgICAgbWF4VmVydGV4RGlzdGFuY2UgPSBwYXJhbWV0ZXJzLm1heFZlcnRleERpc3RhbmNlOwoKICAgIC8vIEhlaWdodCBkYXRhIGNhbiBiZSBlaXRoZXIgYW4gYXJyYXkgb2YgbnVtYmVycyAoZm9yIHByZS1leGlzdGluZyB0ZXJyYWluIGRhdGEpCiAgICAvLyBvciBhbiBpbWFnZSBkYXRhIGFycmF5IChmb3IgZGVjb2RpbmcgZnJvbSBhbiBpbWFnZSkKCiAgICB2YXIgdGVycmFpbiA9IGhlaWdodERhdGE7CgogICAgLy8gVGlsZSBzaXplIG11c3QgYmUgbWFpbnRhaW5lZCB0aHJvdWdoIHRoZSBsaWZlIG9mIHRoZSB3b3JrZXIKICAgIChfbWFydGluaUNhY2hlJHRpbGVTaXogPSBtYXJ0aW5pQ2FjaGVbdGlsZVNpemVdKSAhPT0gbnVsbCAmJiBfbWFydGluaUNhY2hlJHRpbGVTaXogIT09IHZvaWQgMCA/IF9tYXJ0aW5pQ2FjaGUkdGlsZVNpeiA6IG1hcnRpbmlDYWNoZVt0aWxlU2l6ZV0gPSBuZXcgTWFydGluaSh0aWxlU2l6ZSArIDEpOwogICAgdmFyIHRpbGUgPSBtYXJ0aW5pQ2FjaGVbdGlsZVNpemVdLmNyZWF0ZVRpbGUodGVycmFpbik7CgogICAgLy8gZ2V0IGEgbWVzaCAodmVydGljZXMgYW5kIHRyaWFuZ2xlcyBpbmRpY2VzKSBmb3IgYSAxMG0gZXJyb3IKICAgIHZhciBtZXNoID0gdGlsZS5nZXRNZXNoKGVycm9yTGV2ZWwsIE1hdGgubWluKG1heFZlcnRleERpc3RhbmNlLCB0aWxlU2l6ZSkpOwogICAgdmFyIHJlcyA9IGNyZWF0ZVF1YW50aXplZE1lc2hEYXRhKHRpbGUsIG1lc2gsIHRpbGVTaXplLAogICAgLy8gT25seSBpbmNsdWRlIHZlcnRleCBkYXRhIGlmIGFudGljaXBhdGUgdXBzY2FsaW5nIHRpbGUKICAgIHRlcnJhaW4gKTsKICAgIHRyYW5zZmVyYWJsZU9iamVjdHMucHVzaChyZXMuaW5kaWNlcy5idWZmZXIpOwogICAgdHJhbnNmZXJhYmxlT2JqZWN0cy5wdXNoKHJlcy5xdWFudGl6ZWRWZXJ0aWNlcy5idWZmZXIpOwogICAgaWYgKHJlcy5xdWFudGl6ZWRIZWlnaHRzKSB7CiAgICAgIHRyYW5zZmVyYWJsZU9iamVjdHMucHVzaChyZXMucXVhbnRpemVkSGVpZ2h0cy5idWZmZXIpOwogICAgfQogICAgcmV0dXJuIHJlczsKICB9CiAgc2VsZi5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAobXNnKSB7CiAgICB2YXIgX21zZyRkYXRhID0gbXNnLmRhdGEsCiAgICAgIGlkID0gX21zZyRkYXRhLmlkLAogICAgICBwYXlsb2FkID0gX21zZyRkYXRhLnBheWxvYWQ7CiAgICBpZiAoaWQgPT0gbnVsbCkgcmV0dXJuOwogICAgdmFyIG9iamVjdHMgPSBbXTsKICAgIHZhciByZXMgPSBudWxsOwogICAgdHJ5IHsKICAgICAgcmVzID0gZGVjb2RlVGVycmFpbihwYXlsb2FkLCBvYmplY3RzKTsKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICBzZWxmLnBvc3RNZXNzYWdlKHsKICAgICAgICBpZDogaWQsCiAgICAgICAgcGF5bG9hZDogcmVzCiAgICAgIH0sIG9iamVjdHMpOwogICAgfSBjYXRjaCAoZXJyKSB7CiAgICAgIHZhciBfZXJyJG1lc3NhZ2U7CiAgICAgIHZhciBfbXNnID0gKF9lcnIkbWVzc2FnZSA9IGVyci5tZXNzYWdlKSAhPT0gbnVsbCAmJiBfZXJyJG1lc3NhZ2UgIT09IHZvaWQgMCA/IF9lcnIkbWVzc2FnZSA6IGVycjsKICAgICAgc2VsZi5wb3N0TWVzc2FnZSh7CiAgICAgICAgaWQ6IGlkLAogICAgICAgIGVycjogX21zZy50b1N0cmluZygpCiAgICAgIH0pOwogICAgfSBmaW5hbGx5IHsKICAgICAgcmVzID0gbnVsbDsKICAgICAgb2JqZWN0cyA9IG51bGw7CiAgICB9CiAgfTsKCn0pKCk7Cgo=', null, false);
1053
+ /* eslint-enable */
1054
+
1055
+ var _excluded = ["tilingScheme", "overscaleFactor"];
1056
+ function createTerrainMesh(data, meta) {
1057
+ var minimumHeight = data.minimumHeight,
1058
+ maximumHeight = data.maximumHeight,
1059
+ quantizedVertices = data.quantizedVertices,
1060
+ indices = data.indices,
1061
+ westIndices = data.westIndices,
1062
+ southIndices = data.southIndices,
1063
+ eastIndices = data.eastIndices,
1064
+ northIndices = data.northIndices,
1065
+ quantizedHeights = data.quantizedHeights;
1066
+ var errorLevel = meta.errorLevel,
1067
+ tileSize = meta.tileSize,
1068
+ maxVertexDistance = meta.maxVertexDistance,
1069
+ tileRect = meta.tileRect,
1070
+ ellipsoid = meta.ellipsoid,
1071
+ overscaleFactor = meta.overscaleFactor;
1072
+ var err = errorLevel;
1073
+ var skirtHeight = err * 20;
1074
+
1075
+ // Check if tileRect is not NaNs
1076
+ if (isNaN(tileRect.east) || isNaN(tileRect.north)) {
1077
+ throw new Error("Invalid tile rect");
1014
1078
  }
1015
- update() {
1016
- const {
1017
- numTriangles,
1018
- numParentTriangles,
1019
- coords,
1020
- gridSize: size
1021
- } = this.martini;
1022
- const {
1023
- terrain,
1024
- errors
1025
- } = this;
1079
+ var center = cesium.Rectangle.center(tileRect);
1026
1080
 
1027
- // iterate over all possible triangles, starting from the smallest level
1028
- for (let i = numTriangles - 1; i >= 0; i--) {
1029
- const k = i * 4;
1030
- const ax = coords[k + 0];
1031
- const ay = coords[k + 1];
1032
- const bx = coords[k + 2];
1033
- const by = coords[k + 3];
1034
- const mx = ax + bx >> 1;
1035
- const my = ay + by >> 1;
1036
- const cx = mx + my - ay;
1037
- const cy = my + ax - mx;
1081
+ // Calculating occlusion height is kind of messy currently, but it definitely works
1082
+ var halfAngle = tileRect.width / 2;
1083
+ var dr = Math.cos(halfAngle); // half tile width since our ref point is at the center
1038
1084
 
1039
- // calculate error in the middle of the long edge of the triangle
1040
- const interpolatedHeight = (terrain[ay * size + ax] + terrain[by * size + bx]) / 2;
1041
- const middleIndex = my * size + mx;
1042
- const middleError = Math.abs(interpolatedHeight - terrain[middleIndex]);
1043
- errors[middleIndex] = Math.max(errors[middleIndex], middleError);
1044
- if (i < numParentTriangles) {
1045
- // bigger triangles; accumulate error with children
1046
- const leftChildIndex = (ay + cy >> 1) * size + (ax + cx >> 1);
1047
- const rightChildIndex = (by + cy >> 1) * size + (bx + cx >> 1);
1048
- errors[middleIndex] = Math.max(errors[middleIndex], errors[leftChildIndex], errors[rightChildIndex]);
1049
- }
1085
+ var occlusionHeight = dr * ellipsoid.maximumRadius + maximumHeight;
1086
+ if (halfAngle > Math.PI / 4) {
1087
+ occlusionHeight = (1 + halfAngle) * ellipsoid.maximumRadius;
1088
+ }
1089
+ var occlusionPoint = new cesium.Cartographic(center.longitude, center.latitude, occlusionHeight) // Scaling factor of two just to be sure.
1090
+ ;
1091
+ var horizonOcclusionPoint = ellipsoid.transformPositionToScaledSpace(cesium.Cartographic.toCartesian(occlusionPoint));
1092
+ var orientedBoundingBox = cesium.OrientedBoundingBox.fromRectangle(tileRect, minimumHeight, maximumHeight, ellipsoid);
1093
+ var boundingSphere = cesium.BoundingSphere.fromOrientedBoundingBox(orientedBoundingBox);
1094
+ return new RasterTerrainData({
1095
+ minimumHeight: minimumHeight,
1096
+ maximumHeight: maximumHeight,
1097
+ quantizedVertices: quantizedVertices,
1098
+ indices: indices,
1099
+ boundingSphere: boundingSphere,
1100
+ orientedBoundingBox: orientedBoundingBox,
1101
+ horizonOcclusionPoint: horizonOcclusionPoint,
1102
+ westIndices: westIndices,
1103
+ southIndices: southIndices,
1104
+ eastIndices: eastIndices,
1105
+ northIndices: northIndices,
1106
+ westSkirtHeight: skirtHeight,
1107
+ southSkirtHeight: skirtHeight,
1108
+ eastSkirtHeight: skirtHeight,
1109
+ northSkirtHeight: skirtHeight,
1110
+ childTileMask: 15,
1111
+ createdByUpsampling: overscaleFactor > 0,
1112
+ errorLevel: err,
1113
+ maxVertexDistance: maxVertexDistance,
1114
+ tileSize: tileSize,
1115
+ quantizedHeights: quantizedHeights
1116
+ });
1117
+ }
1118
+ function createEmptyMesh(opts) {
1119
+ var tileRect = opts.tileRect,
1120
+ tileCoord = opts.tileCoord,
1121
+ errorLevel = opts.errorLevel,
1122
+ ellipsoid = opts.ellipsoid,
1123
+ maxVertexDistance = opts.maxVertexDistance;
1124
+ var center = cesium.Rectangle.center(tileRect);
1125
+ var z = tileCoord.z;
1126
+ var latScalar = Math.min(Math.abs(Math.sin(center.latitude)), 0.995);
1127
+ var v = Math.max(Math.ceil(200 / (z + 1) * Math.pow(1 - latScalar, 0.25)), 4);
1128
+ var output = emptyMesh(v);
1129
+ // We use zero for some undefined values
1130
+ return createTerrainMesh(output, {
1131
+ tileRect: tileRect,
1132
+ ellipsoid: ellipsoid,
1133
+ errorLevel: errorLevel,
1134
+ overscaleFactor: 0,
1135
+ maxVertexDistance: maxVertexDistance,
1136
+ tileSize: output.tileSize
1137
+ });
1138
+ }
1139
+ var UpsampleTracker = /*#__PURE__*/function () {
1140
+ function UpsampleTracker() {
1141
+ _classCallCheck(this, UpsampleTracker);
1142
+ this.ne = false;
1143
+ this.nw = false;
1144
+ this.se = false;
1145
+ this.sw = false;
1146
+ }
1147
+ return _createClass(UpsampleTracker, [{
1148
+ key: "finished",
1149
+ value: function finished() {
1150
+ return this.ne && this.nw && this.se && this.sw;
1050
1151
  }
1152
+ }]);
1153
+ }();
1154
+ var RasterTerrainData = /*#__PURE__*/function (_QuantizedMeshTerrain) {
1155
+ function RasterTerrainData(opts) {
1156
+ var _opts$maxVertexDistan;
1157
+ var _this;
1158
+ _classCallCheck(this, RasterTerrainData);
1159
+ _this = _callSuper(this, RasterTerrainData, [opts]);
1160
+ _this.quantizedHeights = opts.quantizedHeights;
1161
+ _this.errorLevel = opts.errorLevel;
1162
+ _this.maxVertexDistance = (_opts$maxVertexDistan = opts.maxVertexDistance) !== null && _opts$maxVertexDistan !== void 0 ? _opts$maxVertexDistan : opts.tileSize;
1163
+ _this.tileSize = opts.tileSize;
1164
+ _this.upsampleTracker = new UpsampleTracker();
1165
+ return _this;
1051
1166
  }
1052
- getMesh(maxError = 0, maxLength = null) {
1053
- const {
1054
- gridSize: size,
1055
- indices
1056
- } = this.martini;
1057
- const {
1058
- errors
1059
- } = this;
1060
- let numVertices = 0;
1061
- let numTriangles = 0;
1062
- const max = size - 1;
1167
+ _inherits(RasterTerrainData, _QuantizedMeshTerrain);
1168
+ return _createClass(RasterTerrainData, [{
1169
+ key: "upsample",
1170
+ value: function upsample(tilingScheme, thisX, thisY, thisLevel, descendantX, descendantY, descendantLevel) {
1171
+ if (this.quantizedHeights == null) {
1172
+ return _superPropGet(RasterTerrainData, "upsample", this, 3)([tilingScheme, thisX, thisY, thisLevel, descendantX, descendantY, descendantLevel]);
1173
+ } // Something wonky about our tiling scheme, perhaps
1174
+ // 12/2215/2293 @2x
1175
+ //const url = `https://a.tiles.mapbox.com/v4/mapbox.terrain-rgb/${z}/${x}/${y}${hires}.${this.format}?access_token=${this.accessToken}`;
1063
1176
 
1064
- // The maxLength parameter will cause triangles to be generated until the legs are below this length
1065
- // It is meant to support cases where a certain mesh density is required to do spherical math on digital globes
1066
- const maxScale = maxLength || size;
1177
+ var x = descendantX;
1178
+ var y = descendantY;
1179
+ var z = descendantLevel;
1067
1180
 
1068
- // use an index grid to keep track of vertices that were already used to avoid duplication
1069
- indices.fill(0);
1181
+ //console.log(`Upsampling terrain data from zoom ${thisLevel} to ` + tile);
1070
1182
 
1071
- // retrieve mesh in two stages that both traverse the error map:
1072
- // - countElements: find used vertices (and assign each an index), and count triangles (for minimum allocation)
1073
- // - processTriangle: fill the allocated vertices & triangles typed arrays
1074
-
1075
- function countElements(ax, ay, bx, by, cx, cy) {
1076
- const mx = ax + bx >> 1;
1077
- const my = ay + by >> 1;
1078
- const legLength = Math.abs(ax - cx) + Math.abs(ay - cy);
1079
- if (legLength > 1 && errors[my * size + mx] > maxError || legLength > maxScale) {
1080
- countElements(cx, cy, ax, ay, mx, my);
1081
- countElements(bx, by, cx, cy, mx, my);
1082
- } else {
1083
- indices[ay * size + ax] = indices[ay * size + ax] || ++numVertices;
1084
- indices[by * size + bx] = indices[by * size + bx] || ++numVertices;
1085
- indices[cy * size + cx] = indices[cy * size + cx] || ++numVertices;
1086
- numTriangles++;
1183
+ var dz = z - thisLevel;
1184
+ var scalar = Math.pow(2, dz);
1185
+ var ellipsoid = tilingScheme.ellipsoid;
1186
+ var err = this.errorLevel / scalar;
1187
+ var maxVertexDistance = Math.min(this.maxVertexDistance * scalar, this.tileSize);
1188
+ var upscaledX = thisX * scalar;
1189
+ var upscaledY = thisY * scalar;
1190
+ var dx = x - upscaledX;
1191
+ var dy = y - upscaledY;
1192
+ var x0 = dx * this.tileSize / scalar;
1193
+ var x1 = (dx + 1) * this.tileSize / scalar;
1194
+ var y0 = dy * this.tileSize / scalar;
1195
+ var y1 = (dy + 1) * this.tileSize / scalar;
1196
+ var window = {
1197
+ x0: x0,
1198
+ x1: x1,
1199
+ y0: y0,
1200
+ y1: y1
1201
+ };
1202
+ var res = buildOverscaledTerrainTile({
1203
+ tilingScheme: tilingScheme,
1204
+ heightData: subsetByWindow(this.quantizedHeights, window, true),
1205
+ maxVertexDistance: maxVertexDistance,
1206
+ x: x,
1207
+ y: y,
1208
+ z: z,
1209
+ errorLevel: err,
1210
+ ellipsoidRadius: ellipsoid.maximumRadius,
1211
+ tileSize: x1 - x0,
1212
+ overscaleFactor: dz
1213
+ });
1214
+ if (dz == 1) {
1215
+ // If we've got a single child tile, we can track that we've upsampled the parent.
1216
+ var quadrant = getQuadrant(dx, dy);
1217
+ this.upsampleTracker[quadrant] = true;
1087
1218
  }
1088
- }
1089
- countElements(0, 0, max, max, max, 0);
1090
- countElements(max, max, 0, 0, 0, max);
1091
- const vertices = new Uint16Array(numVertices * 2);
1092
- const triangles = new Uint32Array(numTriangles * 3);
1093
- let triIndex = 0;
1094
- function processTriangle(ax, ay, bx, by, cx, cy) {
1095
- const mx = ax + bx >> 1;
1096
- const my = ay + by >> 1;
1097
- const legLength = Math.abs(ax - cx) + Math.abs(ay - cy);
1098
- if (legLength > 1 && errors[my * size + mx] > maxError || legLength > maxScale) {
1099
- // triangle doesn't approximate the surface well enough; drill down further
1100
- processTriangle(cx, cy, ax, ay, mx, my);
1101
- processTriangle(bx, by, cx, cy, mx, my);
1102
- } else {
1103
- // add a triangle
1104
- const a = indices[ay * size + ax] - 1;
1105
- const b = indices[by * size + bx] - 1;
1106
- const c = indices[cy * size + cx] - 1;
1107
- vertices[2 * a] = ax;
1108
- vertices[2 * a + 1] = ay;
1109
- vertices[2 * b] = bx;
1110
- vertices[2 * b + 1] = by;
1111
- vertices[2 * c] = cx;
1112
- vertices[2 * c + 1] = cy;
1113
- triangles[triIndex++] = a;
1114
- triangles[triIndex++] = b;
1115
- triangles[triIndex++] = c;
1219
+ if (this.upsampleTracker.finished()) {
1220
+ // We've upsampled all child tiles and don't need to keep terrain data around anymore.
1221
+ this.quantizedHeights = undefined;
1116
1222
  }
1223
+ return res;
1117
1224
  }
1118
- processTriangle(0, 0, max, max, max, 0);
1119
- processTriangle(max, max, 0, 0, 0, max);
1120
- return {
1121
- vertices,
1122
- triangles
1123
- };
1124
- }
1225
+ }]);
1226
+ }(cesium.QuantizedMeshTerrainData);
1227
+ function getQuadrant(dx, dy) {
1228
+ if (dx == 0 && dy == 0) return "sw";
1229
+ if (dx == 0 && dy == 1) return "nw";
1230
+ if (dx == 1 && dy == 0) return "se";
1231
+ if (dx == 1 && dy == 1) return "ne";
1232
+ throw new Error("Invalid quadrant");
1125
1233
  }
1126
-
1127
- // https://github.com/CesiumGS/cesium/blob/1.76/Source/WorkersES6/createVerticesFromQuantizedTerrainMesh.js
1128
-
1129
- var martini = null;
1130
- function decodeTerrain(parameters, transferableObjects) {
1131
- var _martini;
1132
- var imageData = parameters.imageData,
1133
- _parameters$tileSize = parameters.tileSize,
1134
- tileSize = _parameters$tileSize === void 0 ? 256 : _parameters$tileSize,
1135
- errorLevel = parameters.errorLevel,
1136
- interval = parameters.interval,
1137
- offset = parameters.offset;
1138
- var pixels = ndarray__default["default"](new Uint8Array(imageData), [tileSize, tileSize, 4], [4, 4 * tileSize, 1], 0);
1139
-
1140
- // Tile size must be maintained through the life of the worker
1141
- (_martini = martini) !== null && _martini !== void 0 ? _martini : martini = new Martini(tileSize + 1);
1142
- var terrain = mapboxTerrainToGrid(pixels, interval, offset);
1143
- var tile = martini.createTile(terrain);
1144
-
1145
- // get a mesh (vertices and triangles indices) for a 10m error
1146
- var mesh = tile.getMesh(errorLevel, parameters.maxLength);
1147
- return createQuantizedMeshData(tile, mesh, tileSize);
1234
+ function buildOverscaledTerrainTile(_x) {
1235
+ return _buildOverscaledTerrainTile.apply(this, arguments);
1148
1236
  }
1149
- self.onmessage = function (msg) {
1150
- var _msg$data = msg.data,
1151
- id = _msg$data.id,
1152
- payload = _msg$data.payload;
1153
- if (id == null) return;
1154
- var objects = [];
1155
- var res = null;
1156
- try {
1157
- res = decodeTerrain(payload);
1158
- objects.push(res.indices.buffer);
1159
- objects.push(res.quantizedVertices.buffer);
1160
- self.postMessage({
1161
- id: id,
1162
- payload: res
1163
- }, objects);
1164
- } catch (err) {
1165
- self.postMessage({
1166
- id: id,
1167
- err: err.toString()
1168
- });
1169
- } finally {
1170
- res = null;
1171
- objects = null;
1172
- }
1173
- };
1237
+ function _buildOverscaledTerrainTile() {
1238
+ _buildOverscaledTerrainTile = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(opts) {
1239
+ var tilingScheme, overscaleFactor, workerOpts, x, y, z, tileRect, ellipsoid, errorLevel, maxVertexDistance, tileSize, res;
1240
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
1241
+ while (1) switch (_context.prev = _context.next) {
1242
+ case 0:
1243
+ tilingScheme = opts.tilingScheme, overscaleFactor = opts.overscaleFactor, workerOpts = _objectWithoutProperties(opts, _excluded);
1244
+ x = workerOpts.x, y = workerOpts.y, z = workerOpts.z;
1245
+ tileRect = tilingScheme.tileXYToRectangle(x, y, z);
1246
+ ellipsoid = tilingScheme.ellipsoid;
1247
+ errorLevel = workerOpts.errorLevel, maxVertexDistance = workerOpts.maxVertexDistance, tileSize = workerOpts.tileSize;
1248
+ _context.prev = 5;
1249
+ _context.next = 8;
1250
+ return upsamplerFarm.scheduleTask(workerOpts, [workerOpts.heightData.buffer]);
1251
+ case 8:
1252
+ res = _context.sent;
1253
+ return _context.abrupt("return", createTerrainMesh(res, {
1254
+ tileRect: tileRect,
1255
+ ellipsoid: ellipsoid,
1256
+ errorLevel: errorLevel,
1257
+ overscaleFactor: overscaleFactor,
1258
+ tileSize: tileSize,
1259
+ // Maximum vertex distance
1260
+ maxVertexDistance: maxVertexDistance
1261
+ }));
1262
+ case 12:
1263
+ _context.prev = 12;
1264
+ _context.t0 = _context["catch"](5);
1265
+ return _context.abrupt("return", createEmptyMesh({
1266
+ tileRect: tileRect,
1267
+ errorLevel: errorLevel,
1268
+ ellipsoid: ellipsoid,
1269
+ tileCoord: {
1270
+ x: x,
1271
+ y: y,
1272
+ z: z
1273
+ },
1274
+ tileSize: 0
1275
+ }));
1276
+ case 15:
1277
+ case "end":
1278
+ return _context.stop();
1279
+ }
1280
+ }, _callee, null, [[5, 12]]);
1281
+ }));
1282
+ return _buildOverscaledTerrainTile.apply(this, arguments);
1283
+ }
1284
+ var upsamplerFarm = new WorkerFarm({
1285
+ worker: new WorkerFactory$1(),
1286
+ maxWorkers: 5
1287
+ });
1174
1288
 
1175
1289
  // https://github.com/CesiumGS/cesium/blob/1.68/Source/Scene/MapboxImageryProvider.js#L42
1290
+
1176
1291
  var StretchedTilingScheme = /*#__PURE__*/function (_WebMercatorTilingSch) {
1177
- _inherits(StretchedTilingScheme, _WebMercatorTilingSch);
1178
- var _super = _createSuper(StretchedTilingScheme);
1179
1292
  function StretchedTilingScheme() {
1180
1293
  _classCallCheck(this, StretchedTilingScheme);
1181
- return _super.apply(this, arguments);
1294
+ return _callSuper(this, StretchedTilingScheme, arguments);
1182
1295
  }
1183
- _createClass(StretchedTilingScheme, [{
1296
+ _inherits(StretchedTilingScheme, _WebMercatorTilingSch);
1297
+ return _createClass(StretchedTilingScheme, [{
1184
1298
  key: "tileXYToRectangle",
1185
1299
  value: function tileXYToRectangle(x, y, level, res) {
1186
- var result = _get(_getPrototypeOf(StretchedTilingScheme.prototype), "tileXYToRectangle", this).call(this, x, y, level);
1300
+ var result = _superPropGet(StretchedTilingScheme, "tileXYToRectangle", this, 3)([x, y, level]);
1187
1301
  if (y == 0) {
1188
- //console.log("Top row", res, y, level);
1189
1302
  result.north = Math.PI / 2;
1190
1303
  }
1191
1304
  if (y + 1 == Math.pow(2, level)) {
@@ -1194,12 +1307,11 @@ var StretchedTilingScheme = /*#__PURE__*/function (_WebMercatorTilingSch) {
1194
1307
  return result;
1195
1308
  }
1196
1309
  }]);
1197
- return StretchedTilingScheme;
1198
1310
  }(cesium.WebMercatorTilingScheme);
1199
1311
  var MartiniTerrainProvider = /*#__PURE__*/function () {
1200
1312
  // @ts-ignore
1201
1313
  function MartiniTerrainProvider() {
1202
- var _opts$interval, _opts$offset, _opts$maxWorkers, _opts$minZoomLevel, _opts$fillPoles, _opts$detailScalar, _opts$minimumErrorLev, _opts$ellipsoid;
1314
+ var _this$resource$credit, _opts$maxWorkers, _opts$minZoomLevel, _opts$fillPoles, _opts$minimumErrorLev, _opts$ellipsoid, _opts$detailScalar, _ref, _opts$tilingScheme$el, _opts$tilingScheme;
1203
1315
  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1204
1316
  _classCallCheck(this, MartiniTerrainProvider);
1205
1317
  _defineProperty(this, "hasWaterMask", false);
@@ -1207,125 +1319,159 @@ var MartiniTerrainProvider = /*#__PURE__*/function () {
1207
1319
  _defineProperty(this, "credit", new cesium.Credit("Mapbox"));
1208
1320
  _defineProperty(this, "availability", null);
1209
1321
  _defineProperty(this, "errorEvent", new cesium.Event());
1210
- _defineProperty(this, "workerFarm", null);
1211
- _defineProperty(this, "inProgressWorkers", 0);
1212
1322
  _defineProperty(this, "levelOfDetailScalar", null);
1213
1323
  _defineProperty(this, "maxWorkers", 5);
1214
1324
  _defineProperty(this, "minError", 0.1);
1215
1325
  _defineProperty(this, "fillPoles", true);
1216
1326
  _defineProperty(this, "_errorAtMinZoom", 1000);
1217
1327
  _defineProperty(this, "resource", null);
1328
+ _defineProperty(this, "decoder", null);
1218
1329
  _defineProperty(this, "RADIUS_SCALAR", 1.0);
1219
1330
  //this.martini = new Martini(257);
1220
1331
  this.resource = opts.resource;
1221
- this.interval = (_opts$interval = opts.interval) !== null && _opts$interval !== void 0 ? _opts$interval : 0.1;
1222
- this.offset = (_opts$offset = opts.offset) !== null && _opts$offset !== void 0 ? _opts$offset : -10000;
1332
+ this.credit = (_this$resource$credit = this.resource.credit) !== null && _this$resource$credit !== void 0 ? _this$resource$credit : new cesium.Credit("Mapbox");
1333
+ this.decoder = opts.decoder;
1223
1334
  this.maxWorkers = (_opts$maxWorkers = opts.maxWorkers) !== null && _opts$maxWorkers !== void 0 ? _opts$maxWorkers : 5;
1335
+ if (!this.decoder) {
1336
+ var maxWorkers = this.maxWorkers;
1337
+ if (maxWorkers > 0) {
1338
+ this.decoder = new WorkerFarmTerrainDecoder({
1339
+ maxWorkers: maxWorkers
1340
+ });
1341
+ } else {
1342
+ this.decoder = new DefaultTerrainDecoder();
1343
+ }
1344
+ }
1224
1345
  this.minZoomLevel = (_opts$minZoomLevel = opts.minZoomLevel) !== null && _opts$minZoomLevel !== void 0 ? _opts$minZoomLevel : 3;
1225
1346
  this.fillPoles = (_opts$fillPoles = opts.fillPoles) !== null && _opts$fillPoles !== void 0 ? _opts$fillPoles : true;
1226
- console.log("fillPoles", this.fillPoles);
1227
- this.levelOfDetailScalar = ((_opts$detailScalar = opts.detailScalar) !== null && _opts$detailScalar !== void 0 ? _opts$detailScalar : 4.0) + cesium.Math.EPSILON5;
1228
1347
  this.ready = true;
1229
1348
  this.readyPromise = Promise.resolve(true);
1230
1349
  this.minError = (_opts$minimumErrorLev = opts.minimumErrorLevel) !== null && _opts$minimumErrorLev !== void 0 ? _opts$minimumErrorLev : 0.1;
1231
1350
  this.errorEvent.addEventListener(console.log, this);
1232
1351
  this.ellipsoid = (_opts$ellipsoid = opts.ellipsoid) !== null && _opts$ellipsoid !== void 0 ? _opts$ellipsoid : cesium.Ellipsoid.WGS84;
1233
- if (this.maxWorkers > 0) {
1234
- this.workerFarm = new WorkerFarm();
1235
- }
1236
- var scheme = cesium.WebMercatorTilingScheme;
1237
- if (this.fillPoles) {
1238
- scheme = StretchedTilingScheme;
1352
+ if (opts.tilingScheme == null) {
1353
+ var scheme = cesium.WebMercatorTilingScheme;
1354
+ if (this.fillPoles) {
1355
+ scheme = StretchedTilingScheme;
1356
+ }
1357
+ this.tilingScheme = new scheme({
1358
+ numberOfLevelZeroTilesX: 1,
1359
+ numberOfLevelZeroTilesY: 1,
1360
+ ellipsoid: this.ellipsoid
1361
+ });
1362
+ } else {
1363
+ this.tilingScheme = opts.tilingScheme;
1239
1364
  }
1240
- this.tilingScheme = new scheme({
1241
- numberOfLevelZeroTilesX: 1,
1242
- numberOfLevelZeroTilesY: 1,
1243
- ellipsoid: this.ellipsoid
1244
- });
1365
+ this.levelOfDetailScalar = ((_opts$detailScalar = opts.detailScalar) !== null && _opts$detailScalar !== void 0 ? _opts$detailScalar : 2.0) + cesium.Math.EPSILON5;
1366
+
1367
+ //this.errorEvent.addEventListener(console.log, this);
1368
+ this.ellipsoid = (_ref = (_opts$tilingScheme$el = (_opts$tilingScheme = opts.tilingScheme) === null || _opts$tilingScheme === void 0 ? void 0 : _opts$tilingScheme.ellipsoid) !== null && _opts$tilingScheme$el !== void 0 ? _opts$tilingScheme$el : opts.ellipsoid) !== null && _ref !== void 0 ? _ref : cesium.Ellipsoid.WGS84;
1245
1369
  this._errorAtMinZoom = this.errorAtZoom(this.minZoomLevel);
1246
1370
  }
1247
- _createClass(MartiniTerrainProvider, [{
1371
+ return _createClass(MartiniTerrainProvider, [{
1248
1372
  key: "requestTileGeometry",
1249
1373
  value: function requestTileGeometry(x, y, z, request) {
1250
- var _this = this;
1251
1374
  // Look for tiles both below the zoom level and below the error threshold for the zoom level at the equator...
1252
-
1253
- if (z < this.minZoomLevel || this.scaledErrorForTile(x, y, z) > this._errorAtMinZoom) {
1375
+ if (this.minZoomLevel != 0 && (z < this.minZoomLevel || this.scaledErrorForTile(x, y, z) > this._errorAtMinZoom)) {
1254
1376
  // If we are below the minimum zoom level, we return empty heightmaps
1255
1377
  // to avoid unnecessary requests for low-resolution data.
1256
1378
  return Promise.resolve(this.emptyMesh(x, y, z));
1257
1379
  }
1258
1380
 
1259
1381
  // Note: we still load a TON of tiles near the poles. We might need to do some overzooming here...
1260
-
1261
- if (this.inProgressWorkers > this.maxWorkers) return undefined;
1262
- this.inProgressWorkers += 1;
1263
- return this.processTile(x, y, z)["finally"](function () {
1264
- _this.inProgressWorkers -= 1;
1265
- });
1382
+ return this.decoder.requestTileGeometry({
1383
+ x: x,
1384
+ y: y,
1385
+ z: z
1386
+ }, this.processTile.bind(this));
1266
1387
  }
1267
1388
  }, {
1268
1389
  key: "processTile",
1269
1390
  value: function () {
1270
- var _processTile = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(x, y, z) {
1271
- var _this$resource, tileSize, getTilePixels, px, pixelData, tileRect, err, maxLength, params, res;
1391
+ var _processTile = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref2) {
1392
+ var x, y, z, tileRect, errorLevel, maxVertexDistance, _this$resource, tileSize, getTilePixels, r1, px, pixelData, params, res, meta;
1272
1393
  return _regeneratorRuntime().wrap(function _callee$(_context) {
1273
1394
  while (1) switch (_context.prev = _context.next) {
1274
1395
  case 0:
1275
- _context.prev = 0;
1396
+ x = _ref2.x, y = _ref2.y, z = _ref2.z;
1397
+ // Something wonky about our tiling scheme, perhaps
1398
+ // 12/2215/2293 @2x
1399
+ //const url = `https://a.tiles.mapbox.com/v4/mapbox.terrain-rgb/${z}/${x}/${y}${hires}.${this.format}?access_token=${this.accessToken}`;
1400
+ tileRect = this.tilingScheme.tileXYToRectangle(x, y, z);
1401
+ errorLevel = this.errorAtZoom(z);
1402
+ maxVertexDistance = this.maxVertexDistance(tileRect);
1403
+ _context.prev = 4;
1276
1404
  _this$resource = this.resource, tileSize = _this$resource.tileSize, getTilePixels = _this$resource.getTilePixels;
1277
- _context.next = 4;
1278
- return getTilePixels({
1405
+ r1 = getTilePixels.bind(this.resource, {
1279
1406
  x: x,
1280
1407
  y: y,
1281
1408
  z: z
1282
1409
  });
1283
- case 4:
1410
+ if (!(r1 == null)) {
1411
+ _context.next = 9;
1412
+ break;
1413
+ }
1414
+ return _context.abrupt("return");
1415
+ case 9:
1416
+ _context.next = 11;
1417
+ return r1();
1418
+ case 11:
1284
1419
  px = _context.sent;
1285
1420
  pixelData = px.data;
1286
- tileRect = this.tilingScheme.tileXYToRectangle(x, y, z); ///const center = Rectangle.center(tileRect);
1287
- err = this.errorAtZoom(z);
1288
- maxLength = this.maxVertexDistance(tileRect);
1421
+ if (!(pixelData == null)) {
1422
+ _context.next = 15;
1423
+ break;
1424
+ }
1425
+ return _context.abrupt("return");
1426
+ case 15:
1427
+ ///const center = Rectangle.center(tileRect);
1289
1428
  params = {
1290
1429
  imageData: pixelData,
1291
- maxLength: maxLength,
1430
+ maxVertexDistance: maxVertexDistance,
1292
1431
  x: x,
1293
1432
  y: y,
1294
1433
  z: z,
1295
- errorLevel: err,
1296
- ellipsoidRadius: this.ellipsoid.maximumRadius,
1297
- tileSize: tileSize,
1298
- interval: this.interval,
1299
- offset: this.offset
1434
+ errorLevel: errorLevel,
1435
+ ellipsoidRadius: this.tilingScheme.ellipsoid.maximumRadius,
1436
+ tileSize: tileSize
1300
1437
  };
1301
- if (!(this.workerFarm != null)) {
1302
- _context.next = 16;
1303
- break;
1304
- }
1305
- _context.next = 13;
1306
- return this.workerFarm.scheduleTask(params, [pixelData.buffer]);
1307
- case 13:
1438
+ _context.next = 18;
1439
+ return this.decoder.decodeTerrain(params, pixelData.buffer);
1440
+ case 18:
1308
1441
  res = _context.sent;
1309
- _context.next = 17;
1310
- break;
1311
- case 16:
1312
- res = decodeTerrain(params);
1313
- case 17:
1314
- pixelData = undefined;
1315
- px = undefined;
1316
- return _context.abrupt("return", this.createQuantizedMeshData(tileRect, err, res));
1317
- case 22:
1318
- _context.prev = 22;
1319
- _context.t0 = _context["catch"](0);
1320
- console.log(_context.t0);
1321
- return _context.abrupt("return", this.emptyMesh(x, y, z));
1442
+ meta = {
1443
+ ellipsoid: this.tilingScheme.ellipsoid,
1444
+ errorLevel: errorLevel,
1445
+ overscaleFactor: 0,
1446
+ maxVertexDistance: maxVertexDistance,
1447
+ tileRect: tileRect,
1448
+ tileSize: tileSize
1449
+ };
1450
+ /** This builds a final terrain mesh object that can optionally
1451
+ * be upscaled to a higher resolution.
1452
+ */
1453
+ return _context.abrupt("return", createTerrainMesh(res, meta));
1454
+ case 23:
1455
+ _context.prev = 23;
1456
+ _context.t0 = _context["catch"](4);
1457
+ return _context.abrupt("return", createEmptyMesh({
1458
+ tileRect: tileRect,
1459
+ errorLevel: errorLevel,
1460
+ ellipsoid: this.tilingScheme.ellipsoid,
1461
+ tileCoord: {
1462
+ x: x,
1463
+ y: y,
1464
+ z: z
1465
+ },
1466
+ tileSize: 0
1467
+ }));
1322
1468
  case 26:
1323
1469
  case "end":
1324
1470
  return _context.stop();
1325
1471
  }
1326
- }, _callee, this, [[0, 22]]);
1472
+ }, _callee, this, [[4, 23]]);
1327
1473
  }));
1328
- function processTile(_x, _x2, _x3) {
1474
+ function processTile(_x) {
1329
1475
  return _processTile.apply(this, arguments);
1330
1476
  }
1331
1477
  return processTile;
@@ -1381,10 +1527,8 @@ var MartiniTerrainProvider = /*#__PURE__*/function () {
1381
1527
  if (halfAngle > Math.PI / 4) {
1382
1528
  occlusionHeight = (1 + halfAngle) * this.ellipsoid.maximumRadius;
1383
1529
  }
1384
- var occlusionPoint = new cesium.Cartographic(center.longitude, center.latitude, occlusionHeight
1385
- // Scaling factor of two just to be sure.
1386
- );
1387
-
1530
+ var occlusionPoint = new cesium.Cartographic(center.longitude, center.latitude, occlusionHeight) // Scaling factor of two just to be sure.
1531
+ ;
1388
1532
  var horizonOcclusionPoint = this.ellipsoid.transformPositionToScaledSpace(cesium.Cartographic.toCartesian(occlusionPoint));
1389
1533
  var orientedBoundingBox = cesium.OrientedBoundingBox.fromRectangle(tileRect, minimumHeight, maximumHeight, this.tilingScheme.ellipsoid);
1390
1534
  var boundingSphere = cesium.BoundingSphere.fromOrientedBoundingBox(orientedBoundingBox);
@@ -1392,7 +1536,8 @@ var MartiniTerrainProvider = /*#__PURE__*/function () {
1392
1536
  // SE NW NE
1393
1537
  // NE NW SE
1394
1538
 
1395
- var result = new cesium.QuantizedMeshTerrainData({
1539
+ /** TODO: we need to create raster terrain data. */
1540
+ return new cesium.QuantizedMeshTerrainData({
1396
1541
  minimumHeight: minimumHeight,
1397
1542
  maximumHeight: maximumHeight,
1398
1543
  quantizedVertices: quantizedVertices,
@@ -1410,16 +1555,21 @@ var MartiniTerrainProvider = /*#__PURE__*/function () {
1410
1555
  northSkirtHeight: skirtHeight,
1411
1556
  childTileMask: 15
1412
1557
  });
1413
- return result;
1414
1558
  }
1415
1559
  }, {
1416
1560
  key: "getLevelMaximumGeometricError",
1417
1561
  value: function getLevelMaximumGeometricError(level) {
1418
1562
  var levelZeroMaximumGeometricError = cesium.TerrainProvider.getEstimatedLevelZeroGeometricErrorForAHeightmap(this.tilingScheme.ellipsoid, 65, this.tilingScheme.getNumberOfXTilesAtLevel(0));
1419
1563
 
1420
- // Scalar to control overzooming
1421
- // also seems to control zooming for imagery layers
1422
- var scalar = this.resource.tileSize / 256;
1564
+ /*
1565
+ Scalar to control overzooming
1566
+ - also seems to control zooming for imagery layers
1567
+ - This scalar was causing trouble for non-256 tile sizes,
1568
+ and we've removed it for now. It could be reintroduced
1569
+ if it seems necessary
1570
+ */
1571
+ var scalar = 1; //this.resource.tileSize / 256 ;
1572
+
1423
1573
  return levelZeroMaximumGeometricError / scalar / (1 << level);
1424
1574
  }
1425
1575
  }, {
@@ -1432,24 +1582,38 @@ var MartiniTerrainProvider = /*#__PURE__*/function () {
1432
1582
  });
1433
1583
  }
1434
1584
  }]);
1435
- return MartiniTerrainProvider;
1436
1585
  }();
1586
+
1587
+ var WorkerFactory = /*#__PURE__*/createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkociwgYSkgewogICAgKG51bGwgPT0gYSB8fCBhID4gci5sZW5ndGgpICYmIChhID0gci5sZW5ndGgpOwogICAgZm9yICh2YXIgZSA9IDAsIG4gPSBBcnJheShhKTsgZSA8IGE7IGUrKykgbltlXSA9IHJbZV07CiAgICByZXR1cm4gbjsKICB9CiAgZnVuY3Rpb24gX2FycmF5V2l0aG91dEhvbGVzKHIpIHsKICAgIGlmIChBcnJheS5pc0FycmF5KHIpKSByZXR1cm4gX2FycmF5TGlrZVRvQXJyYXkocik7CiAgfQogIGZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXkocikgewogICAgaWYgKCJ1bmRlZmluZWQiICE9IHR5cGVvZiBTeW1ib2wgJiYgbnVsbCAhPSByW1N5bWJvbC5pdGVyYXRvcl0gfHwgbnVsbCAhPSByWyJAQGl0ZXJhdG9yIl0pIHJldHVybiBBcnJheS5mcm9tKHIpOwogIH0KICBmdW5jdGlvbiBfbm9uSXRlcmFibGVTcHJlYWQoKSB7CiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCJJbnZhbGlkIGF0dGVtcHQgdG8gc3ByZWFkIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC4iKTsKICB9CiAgZnVuY3Rpb24gX3RvQ29uc3VtYWJsZUFycmF5KHIpIHsKICAgIHJldHVybiBfYXJyYXlXaXRob3V0SG9sZXMocikgfHwgX2l0ZXJhYmxlVG9BcnJheShyKSB8fCBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkocikgfHwgX25vbkl0ZXJhYmxlU3ByZWFkKCk7CiAgfQogIGZ1bmN0aW9uIF91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShyLCBhKSB7CiAgICBpZiAocikgewogICAgICBpZiAoInN0cmluZyIgPT0gdHlwZW9mIHIpIHJldHVybiBfYXJyYXlMaWtlVG9BcnJheShyLCBhKTsKICAgICAgdmFyIHQgPSB7fS50b1N0cmluZy5jYWxsKHIpLnNsaWNlKDgsIC0xKTsKICAgICAgcmV0dXJuICJPYmplY3QiID09PSB0ICYmIHIuY29uc3RydWN0b3IgJiYgKHQgPSByLmNvbnN0cnVjdG9yLm5hbWUpLCAiTWFwIiA9PT0gdCB8fCAiU2V0IiA9PT0gdCA/IEFycmF5LmZyb20ocikgOiAiQXJndW1lbnRzIiA9PT0gdCB8fCAvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdCh0KSA/IF9hcnJheUxpa2VUb0FycmF5KHIsIGEpIDogdm9pZCAwOwogICAgfQogIH0KCiAgLyoqIE1hcGJveCBUZXJyYWluLVJHQiBkZWZhdWx0IGRlY29kZSBmdW5jdGlvbgogICAqICAociAqIDI1NiAqIDI1NikgLyAxMCArIChnICogMjU2KSAvIDEwICsgYiAvIDEwIC0gMTAwMDAKICAgKi8KICB2YXIgZGVmYXVsdE1hcGJveERlY29kZVJnYiA9IGZ1bmN0aW9uIGRlZmF1bHRNYXBib3hEZWNvZGVSZ2IociwgZywgYiwgYSkgewogICAgcmV0dXJuIHIgKiA2NTUzLjYgKyBnICogMjUuNiArIGIgKiAwLjEgLSAxMDAwMDsKICB9OwogIGZ1bmN0aW9uIHJnYlRlcnJhaW5Ub0dyaWQocG5nLCBkZWNvZGVSZ2IpIHsKICAgIC8vIG1heWJlIHdlIHNob3VsZCBkbyB0aGlzIG9uIHRoZSBHUFUgdXNpbmcgUkVHTD8KICAgIC8vIGJ1dCB0aGF0IHdvdWxkIHJlcXVpcmUgR1BVIC0+IENQVSAtPiBHUFUKICAgIHZhciBncmlkU2l6ZSA9IHBuZy5zaGFwZVswXSArIDE7CiAgICB2YXIgdGVycmFpbiA9IG5ldyBGbG9hdDMyQXJyYXkoZ3JpZFNpemUgKiBncmlkU2l6ZSk7CiAgICB2YXIgdGlsZVNpemUgPSBwbmcuc2hhcGVbMF07CiAgICB2YXIgZGVjb2RlID0gZGVjb2RlUmdiICE9PSBudWxsICYmIGRlY29kZVJnYiAhPT0gdm9pZCAwID8gZGVjb2RlUmdiIDogZGVmYXVsdE1hcGJveERlY29kZVJnYjsKCiAgICAvLyBkZWNvZGUgdGVycmFpbiB2YWx1ZXMKICAgIGZvciAodmFyIHkgPSAwOyB5IDwgdGlsZVNpemU7IHkrKykgewogICAgICBmb3IgKHZhciB4ID0gMDsgeCA8IHRpbGVTaXplOyB4KyspIHsKICAgICAgICB2YXIgeWMgPSB5OwogICAgICAgIHZhciBfciA9IHBuZy5nZXQoeCwgeWMsIDApOwogICAgICAgIHZhciBfZyA9IHBuZy5nZXQoeCwgeWMsIDEpOwogICAgICAgIHZhciBfYiA9IHBuZy5nZXQoeCwgeWMsIDIpOwogICAgICAgIHZhciBfYSA9IHBuZy5nZXQoeCwgeWMsIDMpOwogICAgICAgIHRlcnJhaW5beSAqIGdyaWRTaXplICsgeF0gPSBkZWNvZGUoX3IsIF9nLCBfYiwgX2EpOwogICAgICB9CiAgICB9CiAgICAvLyBiYWNrZmlsbCByaWdodCBhbmQgYm90dG9tIGJvcmRlcnMKICAgIGZvciAodmFyIF94ID0gMDsgX3ggPCBncmlkU2l6ZSAtIDE7IF94KyspIHsKICAgICAgdGVycmFpbltncmlkU2l6ZSAqIChncmlkU2l6ZSAtIDEpICsgX3hdID0gdGVycmFpbltncmlkU2l6ZSAqIChncmlkU2l6ZSAtIDIpICsgX3hdOwogICAgfQogICAgZm9yICh2YXIgX3kgPSAwOyBfeSA8IGdyaWRTaXplOyBfeSsrKSB7CiAgICAgIHRlcnJhaW5bZ3JpZFNpemUgKiBfeSArIGdyaWRTaXplIC0gMV0gPSB0ZXJyYWluW2dyaWRTaXplICogX3kgKyBncmlkU2l6ZSAtIDJdOwogICAgfQogICAgcmV0dXJuIHRlcnJhaW47CiAgfQoKICAvKiogVGVycmFpbiB3b3JrZXJzIHNob3VsZCByZXR1cm4gYSBxdWFudGl6ZWQgbWVzaCAqLwoKICBmdW5jdGlvbiBjcmVhdGVRdWFudGl6ZWRNZXNoRGF0YSh0aWxlLCBtZXNoLCB0aWxlU2l6ZSwgdGVycmFpbikgewogICAgLyoqIFRlcnJhaW4gaXMgcGFzc2VkIHRocm91Z2ggc28gd2UgY2FuIGtlZXAgdHJhY2sgb2YgaXQKICAgICAqIGZvciBvdmVyc2NhbGVkIHRpbGVzCiAgICAgKi8KCiAgICB2YXIgeHZhbHMgPSBbXTsKICAgIHZhciB5dmFscyA9IFtdOwogICAgdmFyIGhlaWdodE1ldGVycyA9IFtdOwogICAgdmFyIG5vcnRoSW5kaWNlcyA9IFtdOwogICAgdmFyIHNvdXRoSW5kaWNlcyA9IFtdOwogICAgdmFyIGVhc3RJbmRpY2VzID0gW107CiAgICB2YXIgd2VzdEluZGljZXMgPSBbXTsKICAgIHZhciBtaW5pbXVtSGVpZ2h0ID0gSW5maW5pdHk7CiAgICB2YXIgbWF4aW11bUhlaWdodCA9IC1JbmZpbml0eTsKICAgIHZhciBzY2FsYXIgPSAzMjc2OC4wIC8gdGlsZVNpemU7CgogICAgLy8gVGhlcmUgYXBwZWFycyB0byBiZSBhIHByb2JsZW0gd2l0aCB0aGUgeC95IGluZGV4aW5nIHdoZW4gdXNpbmcgNTEyeDUxMiB0aWxlcwogICAgLy8gVGhpcyBtYXkgYmUgc29sdmVkIGJ5IGluY3JlYXNpbmcgdGhlIG1pbnVtdW1FcnJvckxldmVsIGluIHRoZSB0ZXJyYWluIHByb3ZpZGVyCiAgICBmb3IgKHZhciBpeCA9IDA7IGl4IDwgbWVzaC52ZXJ0aWNlcy5sZW5ndGggLyAyOyBpeCsrKSB7CiAgICAgIHZhciB2ZXJ0ZXhJeCA9IGl4OwogICAgICB2YXIgcHggPSBtZXNoLnZlcnRpY2VzW2l4ICogMl07CiAgICAgIHZhciBweSA9IG1lc2gudmVydGljZXNbaXggKiAyICsgMV07CiAgICAgIHZhciBoZWlnaHQgPSB0aWxlLnRlcnJhaW5bcHkgKiAodGlsZVNpemUgKyAxKSArIHB4XTsKICAgICAgaWYgKGhlaWdodCA+IG1heGltdW1IZWlnaHQpIG1heGltdW1IZWlnaHQgPSBoZWlnaHQ7CiAgICAgIGlmIChoZWlnaHQgPCBtaW5pbXVtSGVpZ2h0KSBtaW5pbXVtSGVpZ2h0ID0gaGVpZ2h0OwogICAgICBoZWlnaHRNZXRlcnMucHVzaChoZWlnaHQpOwogICAgICBpZiAocHkgPT0gMCkgbm9ydGhJbmRpY2VzLnB1c2godmVydGV4SXgpOwogICAgICBpZiAocHkgPT0gdGlsZVNpemUpIHNvdXRoSW5kaWNlcy5wdXNoKHZlcnRleEl4KTsKICAgICAgaWYgKHB4ID09IDApIHdlc3RJbmRpY2VzLnB1c2godmVydGV4SXgpOwogICAgICBpZiAocHggPT0gdGlsZVNpemUpIGVhc3RJbmRpY2VzLnB1c2godmVydGV4SXgpOwogICAgICB2YXIgeHYgPSBweCAqIHNjYWxhcjsKICAgICAgdmFyIHl2ID0gKHRpbGVTaXplIC0gcHkpICogc2NhbGFyOwogICAgICB4dmFscy5wdXNoKHh2KTsKICAgICAgeXZhbHMucHVzaCh5dik7CiAgICB9CiAgICB2YXIgaGVpZ2h0UmFuZ2UgPSBtYXhpbXVtSGVpZ2h0IC0gbWluaW11bUhlaWdodDsKICAgIHZhciBoZWlnaHRzID0gaGVpZ2h0TWV0ZXJzLm1hcChmdW5jdGlvbiAoZCkgewogICAgICBpZiAoaGVpZ2h0UmFuZ2UgPCAxKSByZXR1cm4gMDsKICAgICAgcmV0dXJuIChkIC0gbWluaW11bUhlaWdodCkgKiAoMzI3NjguMCAvIGhlaWdodFJhbmdlKTsKICAgIH0pOwogICAgdmFyIHRyaWFuZ2xlcyA9IG5ldyBVaW50MTZBcnJheShtZXNoLnRyaWFuZ2xlcyk7CiAgICB2YXIgcXVhbnRpemVkVmVydGljZXMgPSBuZXcgVWludDE2QXJyYXkoLy92ZXJ0cwogICAgW10uY29uY2F0KHh2YWxzLCB5dmFscywgX3RvQ29uc3VtYWJsZUFycmF5KGhlaWdodHMpKSk7CgogICAgLy8gU0UgTlcgTkUKICAgIC8vIE5FIE5XIFNFCgogICAgcmV0dXJuIHsKICAgICAgbWluaW11bUhlaWdodDogbWluaW11bUhlaWdodCwKICAgICAgbWF4aW11bUhlaWdodDogbWF4aW11bUhlaWdodCwKICAgICAgcXVhbnRpemVkVmVydGljZXM6IHF1YW50aXplZFZlcnRpY2VzLAogICAgICBpbmRpY2VzOiB0cmlhbmdsZXMsCiAgICAgIHdlc3RJbmRpY2VzOiB3ZXN0SW5kaWNlcywKICAgICAgc291dGhJbmRpY2VzOiBzb3V0aEluZGljZXMsCiAgICAgIGVhc3RJbmRpY2VzOiBlYXN0SW5kaWNlcywKICAgICAgbm9ydGhJbmRpY2VzOiBub3J0aEluZGljZXMsCiAgICAgIHF1YW50aXplZEhlaWdodHM6IHRlcnJhaW4KICAgIH07CiAgfQoKICBmdW5jdGlvbiBpb3RhKG4pIHsKICAgIHZhciByZXN1bHQgPSBuZXcgQXJyYXkobik7CiAgICBmb3IodmFyIGk9MDsgaTxuOyArK2kpIHsKICAgICAgcmVzdWx0W2ldID0gaTsKICAgIH0KICAgIHJldHVybiByZXN1bHQKICB9CgogIHZhciBpb3RhXzEgPSBpb3RhOwoKICAvKiEKICAgKiBEZXRlcm1pbmUgaWYgYW4gb2JqZWN0IGlzIGEgQnVmZmVyCiAgICoKICAgKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8aHR0cHM6Ly9mZXJvc3Mub3JnPgogICAqIEBsaWNlbnNlICBNSVQKICAgKi8KICAvLyBUaGUgX2lzQnVmZmVyIGNoZWNrIGlzIGZvciBTYWZhcmkgNS03IHN1cHBvcnQsIGJlY2F1c2UgaXQncyBtaXNzaW5nCiAgLy8gT2JqZWN0LnByb3RvdHlwZS5jb25zdHJ1Y3Rvci4gUmVtb3ZlIHRoaXMgZXZlbnR1YWxseQogIHZhciBpc0J1ZmZlcl8xID0gZnVuY3Rpb24gKG9iaikgewogICAgcmV0dXJuIG9iaiAhPSBudWxsICYmIChpc0J1ZmZlcihvYmopIHx8IGlzU2xvd0J1ZmZlcihvYmopIHx8ICEhb2JqLl9pc0J1ZmZlcikKICB9OwoKICBmdW5jdGlvbiBpc0J1ZmZlciAob2JqKSB7CiAgICByZXR1cm4gISFvYmouY29uc3RydWN0b3IgJiYgdHlwZW9mIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIob2JqKQogIH0KCiAgLy8gRm9yIE5vZGUgdjAuMTAgc3VwcG9ydC4gUmVtb3ZlIHRoaXMgZXZlbnR1YWxseS4KICBmdW5jdGlvbiBpc1Nsb3dCdWZmZXIgKG9iaikgewogICAgcmV0dXJuIHR5cGVvZiBvYmoucmVhZEZsb2F0TEUgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIG9iai5zbGljZSA9PT0gJ2Z1bmN0aW9uJyAmJiBpc0J1ZmZlcihvYmouc2xpY2UoMCwgMCkpCiAgfQoKICB2YXIgaGFzVHlwZWRBcnJheXMgID0gKCh0eXBlb2YgRmxvYXQ2NEFycmF5KSAhPT0gInVuZGVmaW5lZCIpOwoKICBmdW5jdGlvbiBjb21wYXJlMXN0KGEsIGIpIHsKICAgIHJldHVybiBhWzBdIC0gYlswXQogIH0KCiAgZnVuY3Rpb24gb3JkZXIoKSB7CiAgICB2YXIgc3RyaWRlID0gdGhpcy5zdHJpZGU7CiAgICB2YXIgdGVybXMgPSBuZXcgQXJyYXkoc3RyaWRlLmxlbmd0aCk7CiAgICB2YXIgaTsKICAgIGZvcihpPTA7IGk8dGVybXMubGVuZ3RoOyArK2kpIHsKICAgICAgdGVybXNbaV0gPSBbTWF0aC5hYnMoc3RyaWRlW2ldKSwgaV07CiAgICB9CiAgICB0ZXJtcy5zb3J0KGNvbXBhcmUxc3QpOwogICAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheSh0ZXJtcy5sZW5ndGgpOwogICAgZm9yKGk9MDsgaTxyZXN1bHQubGVuZ3RoOyArK2kpIHsKICAgICAgcmVzdWx0W2ldID0gdGVybXNbaV1bMV07CiAgICB9CiAgICByZXR1cm4gcmVzdWx0CiAgfQoKICBmdW5jdGlvbiBjb21waWxlQ29uc3RydWN0b3IoZHR5cGUsIGRpbWVuc2lvbikgewogICAgdmFyIGNsYXNzTmFtZSA9IFsiVmlldyIsIGRpbWVuc2lvbiwgImQiLCBkdHlwZV0uam9pbigiIik7CiAgICBpZihkaW1lbnNpb24gPCAwKSB7CiAgICAgIGNsYXNzTmFtZSA9ICJWaWV3X05pbCIgKyBkdHlwZTsKICAgIH0KICAgIHZhciB1c2VHZXR0ZXJzID0gKGR0eXBlID09PSAiZ2VuZXJpYyIpOwoKICAgIGlmKGRpbWVuc2lvbiA9PT0gLTEpIHsKICAgICAgLy9TcGVjaWFsIGNhc2UgZm9yIHRyaXZpYWwgYXJyYXlzCiAgICAgIHZhciBjb2RlID0KICAgICAgICAiZnVuY3Rpb24gIitjbGFzc05hbWUrIihhKXt0aGlzLmRhdGE9YTt9O1wKdmFyIHByb3RvPSIrY2xhc3NOYW1lKyIucHJvdG90eXBlO1wKcHJvdG8uZHR5cGU9JyIrZHR5cGUrIic7XApwcm90by5pbmRleD1mdW5jdGlvbigpe3JldHVybiAtMX07XApwcm90by5zaXplPTA7XApwcm90by5kaW1lbnNpb249LTE7XApwcm90by5zaGFwZT1wcm90by5zdHJpZGU9cHJvdG8ub3JkZXI9W107XApwcm90by5sbz1wcm90by5oaT1wcm90by50cmFuc3Bvc2U9cHJvdG8uc3RlcD1cCmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyAiK2NsYXNzTmFtZSsiKHRoaXMuZGF0YSk7fTtcCnByb3RvLmdldD1wcm90by5zZXQ9ZnVuY3Rpb24oKXt9O1wKcHJvdG8ucGljaz1mdW5jdGlvbigpe3JldHVybiBudWxsfTtcCnJldHVybiBmdW5jdGlvbiBjb25zdHJ1Y3RfIitjbGFzc05hbWUrIihhKXtyZXR1cm4gbmV3ICIrY2xhc3NOYW1lKyIoYSk7fSI7CiAgICAgIHZhciBwcm9jZWR1cmUgPSBuZXcgRnVuY3Rpb24oY29kZSk7CiAgICAgIHJldHVybiBwcm9jZWR1cmUoKQogICAgfSBlbHNlIGlmKGRpbWVuc2lvbiA9PT0gMCkgewogICAgICAvL1NwZWNpYWwgY2FzZSBmb3IgMGQgYXJyYXlzCiAgICAgIHZhciBjb2RlID0KICAgICAgICAiZnVuY3Rpb24gIitjbGFzc05hbWUrIihhLGQpIHtcCnRoaXMuZGF0YSA9IGE7XAp0aGlzLm9mZnNldCA9IGRcCn07XAp2YXIgcHJvdG89IitjbGFzc05hbWUrIi5wcm90b3R5cGU7XApwcm90by5kdHlwZT0nIitkdHlwZSsiJztcCnByb3RvLmluZGV4PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMub2Zmc2V0fTtcCnByb3RvLmRpbWVuc2lvbj0wO1wKcHJvdG8uc2l6ZT0xO1wKcHJvdG8uc2hhcGU9XApwcm90by5zdHJpZGU9XApwcm90by5vcmRlcj1bXTtcCnByb3RvLmxvPVwKcHJvdG8uaGk9XApwcm90by50cmFuc3Bvc2U9XApwcm90by5zdGVwPWZ1bmN0aW9uICIrY2xhc3NOYW1lKyJfY29weSgpIHtcCnJldHVybiBuZXcgIitjbGFzc05hbWUrIih0aGlzLmRhdGEsdGhpcy5vZmZzZXQpXAp9O1wKcHJvdG8ucGljaz1mdW5jdGlvbiAiK2NsYXNzTmFtZSsiX3BpY2soKXtcCnJldHVybiBUcml2aWFsQXJyYXkodGhpcy5kYXRhKTtcCn07XApwcm90by52YWx1ZU9mPXByb3RvLmdldD1mdW5jdGlvbiAiK2NsYXNzTmFtZSsiX2dldCgpe1wKcmV0dXJuICIrKHVzZUdldHRlcnMgPyAidGhpcy5kYXRhLmdldCh0aGlzLm9mZnNldCkiIDogInRoaXMuZGF0YVt0aGlzLm9mZnNldF0iKSsKICAifTtcCnByb3RvLnNldD1mdW5jdGlvbiAiK2NsYXNzTmFtZSsiX3NldCh2KXtcCnJldHVybiAiKyh1c2VHZXR0ZXJzID8gInRoaXMuZGF0YS5zZXQodGhpcy5vZmZzZXQsdikiIDogInRoaXMuZGF0YVt0aGlzLm9mZnNldF09diIpKyJcCn07XApyZXR1cm4gZnVuY3Rpb24gY29uc3RydWN0XyIrY2xhc3NOYW1lKyIoYSxiLGMsZCl7cmV0dXJuIG5ldyAiK2NsYXNzTmFtZSsiKGEsZCl9IjsKICAgICAgdmFyIHByb2NlZHVyZSA9IG5ldyBGdW5jdGlvbigiVHJpdmlhbEFycmF5IiwgY29kZSk7CiAgICAgIHJldHVybiBwcm9jZWR1cmUoQ0FDSEVEX0NPTlNUUlVDVE9SU1tkdHlwZV1bMF0pCiAgICB9CgogICAgdmFyIGNvZGUgPSBbIid1c2Ugc3RyaWN0JyJdOwoKICAgIC8vQ3JlYXRlIGNvbnN0cnVjdG9yIGZvciB2aWV3CiAgICB2YXIgaW5kaWNlcyA9IGlvdGFfMShkaW1lbnNpb24pOwogICAgdmFyIGFyZ3MgPSBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7IHJldHVybiAiaSIraSB9KTsKICAgIHZhciBpbmRleF9zdHIgPSAidGhpcy5vZmZzZXQrIiArIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsKICAgICAgICAgIHJldHVybiAidGhpcy5zdHJpZGVbIiArIGkgKyAiXSppIiArIGkKICAgICAgICB9KS5qb2luKCIrIik7CiAgICB2YXIgc2hhcGVBcmcgPSBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7CiAgICAgICAgcmV0dXJuICJiIitpCiAgICAgIH0pLmpvaW4oIiwiKTsKICAgIHZhciBzdHJpZGVBcmcgPSBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7CiAgICAgICAgcmV0dXJuICJjIitpCiAgICAgIH0pLmpvaW4oIiwiKTsKICAgIGNvZGUucHVzaCgKICAgICAgImZ1bmN0aW9uICIrY2xhc3NOYW1lKyIoYSwiICsgc2hhcGVBcmcgKyAiLCIgKyBzdHJpZGVBcmcgKyAiLGQpe3RoaXMuZGF0YT1hIiwKICAgICAgICAidGhpcy5zaGFwZT1bIiArIHNoYXBlQXJnICsgIl0iLAogICAgICAgICJ0aGlzLnN0cmlkZT1bIiArIHN0cmlkZUFyZyArICJdIiwKICAgICAgICAidGhpcy5vZmZzZXQ9ZHwwfSIsCiAgICAgICJ2YXIgcHJvdG89IitjbGFzc05hbWUrIi5wcm90b3R5cGUiLAogICAgICAicHJvdG8uZHR5cGU9JyIrZHR5cGUrIiciLAogICAgICAicHJvdG8uZGltZW5zaW9uPSIrZGltZW5zaW9uKTsKCiAgICAvL3ZpZXcuc2l6ZToKICAgIGNvZGUucHVzaCgiT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3RvLCdzaXplJyx7Z2V0OmZ1bmN0aW9uICIrY2xhc3NOYW1lKyJfc2l6ZSgpe1wKcmV0dXJuICIraW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkgeyByZXR1cm4gInRoaXMuc2hhcGVbIitpKyJdIiB9KS5qb2luKCIqIiksCiAgIn19KSIpOwoKICAgIC8vdmlldy5vcmRlcjoKICAgIGlmKGRpbWVuc2lvbiA9PT0gMSkgewogICAgICBjb2RlLnB1c2goInByb3RvLm9yZGVyPVswXSIpOwogICAgfSBlbHNlIHsKICAgICAgY29kZS5wdXNoKCJPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvdG8sJ29yZGVyJyx7Z2V0OiIpOwogICAgICBpZihkaW1lbnNpb24gPCA0KSB7CiAgICAgICAgY29kZS5wdXNoKCJmdW5jdGlvbiAiK2NsYXNzTmFtZSsiX29yZGVyKCl7Iik7CiAgICAgICAgaWYoZGltZW5zaW9uID09PSAyKSB7CiAgICAgICAgICBjb2RlLnB1c2goInJldHVybiAoTWF0aC5hYnModGhpcy5zdHJpZGVbMF0pPk1hdGguYWJzKHRoaXMuc3RyaWRlWzFdKSk/WzEsMF06WzAsMV19fSkiKTsKICAgICAgICB9IGVsc2UgaWYoZGltZW5zaW9uID09PSAzKSB7CiAgICAgICAgICBjb2RlLnB1c2goCiAgInZhciBzMD1NYXRoLmFicyh0aGlzLnN0cmlkZVswXSksczE9TWF0aC5hYnModGhpcy5zdHJpZGVbMV0pLHMyPU1hdGguYWJzKHRoaXMuc3RyaWRlWzJdKTtcCmlmKHMwPnMxKXtcCmlmKHMxPnMyKXtcCnJldHVybiBbMiwxLDBdO1wKfWVsc2UgaWYoczA+czIpe1wKcmV0dXJuIFsxLDIsMF07XAp9ZWxzZXtcCnJldHVybiBbMSwwLDJdO1wKfVwKfWVsc2UgaWYoczA+czIpe1wKcmV0dXJuIFsyLDAsMV07XAp9ZWxzZSBpZihzMj5zMSl7XApyZXR1cm4gWzAsMSwyXTtcCn1lbHNle1wKcmV0dXJuIFswLDIsMV07XAp9fX0pIik7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGNvZGUucHVzaCgiT1JERVJ9KSIpOwogICAgICB9CiAgICB9CgogICAgLy92aWV3LnNldChpMCwgLi4uLCB2KToKICAgIGNvZGUucHVzaCgKICAicHJvdG8uc2V0PWZ1bmN0aW9uICIrY2xhc3NOYW1lKyJfc2V0KCIrYXJncy5qb2luKCIsIikrIix2KXsiKTsKICAgIGlmKHVzZUdldHRlcnMpIHsKICAgICAgY29kZS5wdXNoKCJyZXR1cm4gdGhpcy5kYXRhLnNldCgiK2luZGV4X3N0cisiLHYpfSIpOwogICAgfSBlbHNlIHsKICAgICAgY29kZS5wdXNoKCJyZXR1cm4gdGhpcy5kYXRhWyIraW5kZXhfc3RyKyJdPXZ9Iik7CiAgICB9CgogICAgLy92aWV3LmdldChpMCwgLi4uKToKICAgIGNvZGUucHVzaCgicHJvdG8uZ2V0PWZ1bmN0aW9uICIrY2xhc3NOYW1lKyJfZ2V0KCIrYXJncy5qb2luKCIsIikrIil7Iik7CiAgICBpZih1c2VHZXR0ZXJzKSB7CiAgICAgIGNvZGUucHVzaCgicmV0dXJuIHRoaXMuZGF0YS5nZXQoIitpbmRleF9zdHIrIil9Iik7CiAgICB9IGVsc2UgewogICAgICBjb2RlLnB1c2goInJldHVybiB0aGlzLmRhdGFbIitpbmRleF9zdHIrIl19Iik7CiAgICB9CgogICAgLy92aWV3LmluZGV4OgogICAgY29kZS5wdXNoKAogICAgICAicHJvdG8uaW5kZXg9ZnVuY3Rpb24gIitjbGFzc05hbWUrIl9pbmRleCgiLCBhcmdzLmpvaW4oKSwgIil7cmV0dXJuICIraW5kZXhfc3RyKyJ9Iik7CgogICAgLy92aWV3LmhpKCk6CiAgICBjb2RlLnB1c2goInByb3RvLmhpPWZ1bmN0aW9uICIrY2xhc3NOYW1lKyJfaGkoIithcmdzLmpvaW4oIiwiKSsiKXtyZXR1cm4gbmV3ICIrY2xhc3NOYW1lKyIodGhpcy5kYXRhLCIrCiAgICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsKICAgICAgICByZXR1cm4gWyIodHlwZW9mIGkiLGksIiE9PSdudW1iZXInfHxpIixpLCI8MCk/dGhpcy5zaGFwZVsiLCBpLCAiXTppIiwgaSwifDAiXS5qb2luKCIiKQogICAgICB9KS5qb2luKCIsIikrIiwiKwogICAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7CiAgICAgICAgcmV0dXJuICJ0aGlzLnN0cmlkZVsiK2kgKyAiXSIKICAgICAgfSkuam9pbigiLCIpKyIsdGhpcy5vZmZzZXQpfSIpOwoKICAgIC8vdmlldy5sbygpOgogICAgdmFyIGFfdmFycyA9IGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuICJhIitpKyI9dGhpcy5zaGFwZVsiK2krIl0iIH0pOwogICAgdmFyIGNfdmFycyA9IGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuICJjIitpKyI9dGhpcy5zdHJpZGVbIitpKyJdIiB9KTsKICAgIGNvZGUucHVzaCgicHJvdG8ubG89ZnVuY3Rpb24gIitjbGFzc05hbWUrIl9sbygiK2FyZ3Muam9pbigiLCIpKyIpe3ZhciBiPXRoaXMub2Zmc2V0LGQ9MCwiK2FfdmFycy5qb2luKCIsIikrIiwiK2NfdmFycy5qb2luKCIsIikpOwogICAgZm9yKHZhciBpPTA7IGk8ZGltZW5zaW9uOyArK2kpIHsKICAgICAgY29kZS5wdXNoKAogICJpZih0eXBlb2YgaSIraSsiPT09J251bWJlcicmJmkiK2krIj49MCl7XApkPWkiK2krInwwO1wKYis9YyIraSsiKmQ7XAphIitpKyItPWR9Iik7CiAgICB9CiAgICBjb2RlLnB1c2goInJldHVybiBuZXcgIitjbGFzc05hbWUrIih0aGlzLmRhdGEsIisKICAgICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkgewogICAgICAgIHJldHVybiAiYSIraQogICAgICB9KS5qb2luKCIsIikrIiwiKwogICAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7CiAgICAgICAgcmV0dXJuICJjIitpCiAgICAgIH0pLmpvaW4oIiwiKSsiLGIpfSIpOwoKICAgIC8vdmlldy5zdGVwKCk6CiAgICBjb2RlLnB1c2goInByb3RvLnN0ZXA9ZnVuY3Rpb24gIitjbGFzc05hbWUrIl9zdGVwKCIrYXJncy5qb2luKCIsIikrIil7dmFyICIrCiAgICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsKICAgICAgICByZXR1cm4gImEiK2krIj10aGlzLnNoYXBlWyIraSsiXSIKICAgICAgfSkuam9pbigiLCIpKyIsIisKICAgICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkgewogICAgICAgIHJldHVybiAiYiIraSsiPXRoaXMuc3RyaWRlWyIraSsiXSIKICAgICAgfSkuam9pbigiLCIpKyIsYz10aGlzLm9mZnNldCxkPTAsY2VpbD1NYXRoLmNlaWwiKTsKICAgIGZvcih2YXIgaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7CiAgICAgIGNvZGUucHVzaCgKICAiaWYodHlwZW9mIGkiK2krIj09PSdudW1iZXInKXtcCmQ9aSIraSsifDA7XAppZihkPDApe1wKYys9YiIraSsiKihhIitpKyItMSk7XAphIitpKyI9Y2VpbCgtYSIraSsiL2QpXAp9ZWxzZXtcCmEiK2krIj1jZWlsKGEiK2krIi9kKVwKfVwKYiIraSsiKj1kXAp9Iik7CiAgICB9CiAgICBjb2RlLnB1c2goInJldHVybiBuZXcgIitjbGFzc05hbWUrIih0aGlzLmRhdGEsIisKICAgICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkgewogICAgICAgIHJldHVybiAiYSIgKyBpCiAgICAgIH0pLmpvaW4oIiwiKSsiLCIrCiAgICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsKICAgICAgICByZXR1cm4gImIiICsgaQogICAgICB9KS5qb2luKCIsIikrIixjKX0iKTsKCiAgICAvL3ZpZXcudHJhbnNwb3NlKCk6CiAgICB2YXIgdFNoYXBlID0gbmV3IEFycmF5KGRpbWVuc2lvbik7CiAgICB2YXIgdFN0cmlkZSA9IG5ldyBBcnJheShkaW1lbnNpb24pOwogICAgZm9yKHZhciBpPTA7IGk8ZGltZW5zaW9uOyArK2kpIHsKICAgICAgdFNoYXBlW2ldID0gImFbaSIraSsiXSI7CiAgICAgIHRTdHJpZGVbaV0gPSAiYltpIitpKyJdIjsKICAgIH0KICAgIGNvZGUucHVzaCgicHJvdG8udHJhbnNwb3NlPWZ1bmN0aW9uICIrY2xhc3NOYW1lKyJfdHJhbnNwb3NlKCIrYXJncysiKXsiKwogICAgICBhcmdzLm1hcChmdW5jdGlvbihuLGlkeCkgeyByZXR1cm4gbiArICI9KCIgKyBuICsgIj09PXVuZGVmaW5lZD8iICsgaWR4ICsgIjoiICsgbiArICJ8MCkifSkuam9pbigiOyIpLAogICAgICAidmFyIGE9dGhpcy5zaGFwZSxiPXRoaXMuc3RyaWRlO3JldHVybiBuZXcgIitjbGFzc05hbWUrIih0aGlzLmRhdGEsIit0U2hhcGUuam9pbigiLCIpKyIsIit0U3RyaWRlLmpvaW4oIiwiKSsiLHRoaXMub2Zmc2V0KX0iKTsKCiAgICAvL3ZpZXcucGljaygpOgogICAgY29kZS5wdXNoKCJwcm90by5waWNrPWZ1bmN0aW9uICIrY2xhc3NOYW1lKyJfcGljaygiK2FyZ3MrIil7dmFyIGE9W10sYj1bXSxjPXRoaXMub2Zmc2V0Iik7CiAgICBmb3IodmFyIGk9MDsgaTxkaW1lbnNpb247ICsraSkgewogICAgICBjb2RlLnB1c2goImlmKHR5cGVvZiBpIitpKyI9PT0nbnVtYmVyJyYmaSIraSsiPj0wKXtjPShjK3RoaXMuc3RyaWRlWyIraSsiXSppIitpKyIpfDB9ZWxzZXthLnB1c2godGhpcy5zaGFwZVsiK2krIl0pO2IucHVzaCh0aGlzLnN0cmlkZVsiK2krIl0pfSIpOwogICAgfQogICAgY29kZS5wdXNoKCJ2YXIgY3Rvcj1DVE9SX0xJU1RbYS5sZW5ndGgrMV07cmV0dXJuIGN0b3IodGhpcy5kYXRhLGEsYixjKX0iKTsKCiAgICAvL0FkZCByZXR1cm4gc3RhdGVtZW50CiAgICBjb2RlLnB1c2goInJldHVybiBmdW5jdGlvbiBjb25zdHJ1Y3RfIitjbGFzc05hbWUrIihkYXRhLHNoYXBlLHN0cmlkZSxvZmZzZXQpe3JldHVybiBuZXcgIitjbGFzc05hbWUrIihkYXRhLCIrCiAgICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsKICAgICAgICByZXR1cm4gInNoYXBlWyIraSsiXSIKICAgICAgfSkuam9pbigiLCIpKyIsIisKICAgICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkgewogICAgICAgIHJldHVybiAic3RyaWRlWyIraSsiXSIKICAgICAgfSkuam9pbigiLCIpKyIsb2Zmc2V0KX0iKTsKCiAgICAvL0NvbXBpbGUgcHJvY2VkdXJlCiAgICB2YXIgcHJvY2VkdXJlID0gbmV3IEZ1bmN0aW9uKCJDVE9SX0xJU1QiLCAiT1JERVIiLCBjb2RlLmpvaW4oIlxuIikpOwogICAgcmV0dXJuIHByb2NlZHVyZShDQUNIRURfQ09OU1RSVUNUT1JTW2R0eXBlXSwgb3JkZXIpCiAgfQoKICBmdW5jdGlvbiBhcnJheURUeXBlKGRhdGEpIHsKICAgIGlmKGlzQnVmZmVyXzEoZGF0YSkpIHsKICAgICAgcmV0dXJuICJidWZmZXIiCiAgICB9CiAgICBpZihoYXNUeXBlZEFycmF5cykgewogICAgICBzd2l0Y2goT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRhdGEpKSB7CiAgICAgICAgY2FzZSAiW29iamVjdCBGbG9hdDY0QXJyYXldIjoKICAgICAgICAgIHJldHVybiAiZmxvYXQ2NCIKICAgICAgICBjYXNlICJbb2JqZWN0IEZsb2F0MzJBcnJheV0iOgogICAgICAgICAgcmV0dXJuICJmbG9hdDMyIgogICAgICAgIGNhc2UgIltvYmplY3QgSW50OEFycmF5XSI6CiAgICAgICAgICByZXR1cm4gImludDgiCiAgICAgICAgY2FzZSAiW29iamVjdCBJbnQxNkFycmF5XSI6CiAgICAgICAgICByZXR1cm4gImludDE2IgogICAgICAgIGNhc2UgIltvYmplY3QgSW50MzJBcnJheV0iOgogICAgICAgICAgcmV0dXJuICJpbnQzMiIKICAgICAgICBjYXNlICJbb2JqZWN0IFVpbnQ4QXJyYXldIjoKICAgICAgICAgIHJldHVybiAidWludDgiCiAgICAgICAgY2FzZSAiW29iamVjdCBVaW50MTZBcnJheV0iOgogICAgICAgICAgcmV0dXJuICJ1aW50MTYiCiAgICAgICAgY2FzZSAiW29iamVjdCBVaW50MzJBcnJheV0iOgogICAgICAgICAgcmV0dXJuICJ1aW50MzIiCiAgICAgICAgY2FzZSAiW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0iOgogICAgICAgICAgcmV0dXJuICJ1aW50OF9jbGFtcGVkIgogICAgICAgIGNhc2UgIltvYmplY3QgQmlnSW50NjRBcnJheV0iOgogICAgICAgICAgcmV0dXJuICJiaWdpbnQ2NCIKICAgICAgICBjYXNlICJbb2JqZWN0IEJpZ1VpbnQ2NEFycmF5XSI6CiAgICAgICAgICByZXR1cm4gImJpZ3VpbnQ2NCIKICAgICAgfQogICAgfQogICAgaWYoQXJyYXkuaXNBcnJheShkYXRhKSkgewogICAgICByZXR1cm4gImFycmF5IgogICAgfQogICAgcmV0dXJuICJnZW5lcmljIgogIH0KCiAgdmFyIENBQ0hFRF9DT05TVFJVQ1RPUlMgPSB7CiAgICAiZmxvYXQzMiI6W10sCiAgICAiZmxvYXQ2NCI6W10sCiAgICAiaW50OCI6W10sCiAgICAiaW50MTYiOltdLAogICAgImludDMyIjpbXSwKICAgICJ1aW50OCI6W10sCiAgICAidWludDE2IjpbXSwKICAgICJ1aW50MzIiOltdLAogICAgImFycmF5IjpbXSwKICAgICJ1aW50OF9jbGFtcGVkIjpbXSwKICAgICJiaWdpbnQ2NCI6IFtdLAogICAgImJpZ3VpbnQ2NCI6IFtdLAogICAgImJ1ZmZlciI6W10sCiAgICAiZ2VuZXJpYyI6W10KICB9CgogIDsKICBmdW5jdGlvbiB3cmFwcGVkTkRBcnJheUN0b3IoZGF0YSwgc2hhcGUsIHN0cmlkZSwgb2Zmc2V0KSB7CiAgICBpZihkYXRhID09PSB1bmRlZmluZWQpIHsKICAgICAgdmFyIGN0b3IgPSBDQUNIRURfQ09OU1RSVUNUT1JTLmFycmF5WzBdOwogICAgICByZXR1cm4gY3RvcihbXSkKICAgIH0gZWxzZSBpZih0eXBlb2YgZGF0YSA9PT0gIm51bWJlciIpIHsKICAgICAgZGF0YSA9IFtkYXRhXTsKICAgIH0KICAgIGlmKHNoYXBlID09PSB1bmRlZmluZWQpIHsKICAgICAgc2hhcGUgPSBbIGRhdGEubGVuZ3RoIF07CiAgICB9CiAgICB2YXIgZCA9IHNoYXBlLmxlbmd0aDsKICAgIGlmKHN0cmlkZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIHN0cmlkZSA9IG5ldyBBcnJheShkKTsKICAgICAgZm9yKHZhciBpPWQtMSwgc3o9MTsgaT49MDsgLS1pKSB7CiAgICAgICAgc3RyaWRlW2ldID0gc3o7CiAgICAgICAgc3ogKj0gc2hhcGVbaV07CiAgICAgIH0KICAgIH0KICAgIGlmKG9mZnNldCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIG9mZnNldCA9IDA7CiAgICAgIGZvcih2YXIgaT0wOyBpPGQ7ICsraSkgewogICAgICAgIGlmKHN0cmlkZVtpXSA8IDApIHsKICAgICAgICAgIG9mZnNldCAtPSAoc2hhcGVbaV0tMSkqc3RyaWRlW2ldOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgdmFyIGR0eXBlID0gYXJyYXlEVHlwZShkYXRhKTsKICAgIHZhciBjdG9yX2xpc3QgPSBDQUNIRURfQ09OU1RSVUNUT1JTW2R0eXBlXTsKICAgIHdoaWxlKGN0b3JfbGlzdC5sZW5ndGggPD0gZCsxKSB7CiAgICAgIGN0b3JfbGlzdC5wdXNoKGNvbXBpbGVDb25zdHJ1Y3RvcihkdHlwZSwgY3Rvcl9saXN0Lmxlbmd0aC0xKSk7CiAgICB9CiAgICB2YXIgY3RvciA9IGN0b3JfbGlzdFtkKzFdOwogICAgcmV0dXJuIGN0b3IoZGF0YSwgc2hhcGUsIHN0cmlkZSwgb2Zmc2V0KQogIH0KCiAgdmFyIG5kYXJyYXkgPSB3cmFwcGVkTkRBcnJheUN0b3I7CgogIGNsYXNzIE1hcnRpbmkgewogICAgICBjb25zdHJ1Y3RvcihncmlkU2l6ZSA9IDI1NykgewogICAgICAgICAgdGhpcy5ncmlkU2l6ZSA9IGdyaWRTaXplOwogICAgICAgICAgY29uc3QgdGlsZVNpemUgPSBncmlkU2l6ZSAtIDE7CiAgICAgICAgICBpZiAodGlsZVNpemUgJiAodGlsZVNpemUgLSAxKSkgdGhyb3cgbmV3IEVycm9yKAogICAgICAgICAgICAgIGBFeHBlY3RlZCBncmlkIHNpemUgdG8gYmUgMl5uKzEsIGdvdCAke2dyaWRTaXplfS5gKTsKCiAgICAgICAgICB0aGlzLm51bVRyaWFuZ2xlcyA9IHRpbGVTaXplICogdGlsZVNpemUgKiAyIC0gMjsKICAgICAgICAgIHRoaXMubnVtUGFyZW50VHJpYW5nbGVzID0gdGhpcy5udW1UcmlhbmdsZXMgLSB0aWxlU2l6ZSAqIHRpbGVTaXplOwoKICAgICAgICAgIHRoaXMuaW5kaWNlcyA9IG5ldyBVaW50MzJBcnJheSh0aGlzLmdyaWRTaXplICogdGhpcy5ncmlkU2l6ZSk7CgogICAgICAgICAgLy8gY29vcmRpbmF0ZXMgZm9yIGFsbCBwb3NzaWJsZSB0cmlhbmdsZXMgaW4gYW4gUlRJTiB0aWxlCiAgICAgICAgICB0aGlzLmNvb3JkcyA9IG5ldyBVaW50MTZBcnJheSh0aGlzLm51bVRyaWFuZ2xlcyAqIDQpOwoKICAgICAgICAgIC8vIGdldCB0cmlhbmdsZSBjb29yZGluYXRlcyBmcm9tIGl0cyBpbmRleCBpbiBhbiBpbXBsaWNpdCBiaW5hcnkgdHJlZQogICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm51bVRyaWFuZ2xlczsgaSsrKSB7CiAgICAgICAgICAgICAgbGV0IGlkID0gaSArIDI7CiAgICAgICAgICAgICAgbGV0IGF4ID0gMCwgYXkgPSAwLCBieCA9IDAsIGJ5ID0gMCwgY3ggPSAwLCBjeSA9IDA7CiAgICAgICAgICAgICAgaWYgKGlkICYgMSkgewogICAgICAgICAgICAgICAgICBieCA9IGJ5ID0gY3ggPSB0aWxlU2l6ZTsgLy8gYm90dG9tLWxlZnQgdHJpYW5nbGUKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBheCA9IGF5ID0gY3kgPSB0aWxlU2l6ZTsgLy8gdG9wLXJpZ2h0IHRyaWFuZ2xlCiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHdoaWxlICgoaWQgPj49IDEpID4gMSkgewogICAgICAgICAgICAgICAgICBjb25zdCBteCA9IChheCArIGJ4KSA+PiAxOwogICAgICAgICAgICAgICAgICBjb25zdCBteSA9IChheSArIGJ5KSA+PiAxOwoKICAgICAgICAgICAgICAgICAgaWYgKGlkICYgMSkgeyAvLyBsZWZ0IGhhbGYKICAgICAgICAgICAgICAgICAgICAgIGJ4ID0gYXg7IGJ5ID0gYXk7CiAgICAgICAgICAgICAgICAgICAgICBheCA9IGN4OyBheSA9IGN5OwogICAgICAgICAgICAgICAgICB9IGVsc2UgeyAvLyByaWdodCBoYWxmCiAgICAgICAgICAgICAgICAgICAgICBheCA9IGJ4OyBheSA9IGJ5OwogICAgICAgICAgICAgICAgICAgICAgYnggPSBjeDsgYnkgPSBjeTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBjeCA9IG14OyBjeSA9IG15OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBjb25zdCBrID0gaSAqIDQ7CiAgICAgICAgICAgICAgdGhpcy5jb29yZHNbayArIDBdID0gYXg7CiAgICAgICAgICAgICAgdGhpcy5jb29yZHNbayArIDFdID0gYXk7CiAgICAgICAgICAgICAgdGhpcy5jb29yZHNbayArIDJdID0gYng7CiAgICAgICAgICAgICAgdGhpcy5jb29yZHNbayArIDNdID0gYnk7CiAgICAgICAgICB9CiAgICAgIH0KCiAgICAgIGNyZWF0ZVRpbGUodGVycmFpbikgewogICAgICAgICAgcmV0dXJuIG5ldyBUaWxlKHRlcnJhaW4sIHRoaXMpOwogICAgICB9CiAgfQoKICBjbGFzcyBUaWxlIHsKICAgICAgY29uc3RydWN0b3IodGVycmFpbiwgbWFydGluaSkgewogICAgICAgICAgY29uc3Qgc2l6ZSA9IG1hcnRpbmkuZ3JpZFNpemU7CiAgICAgICAgICBpZiAodGVycmFpbi5sZW5ndGggIT09IHNpemUgKiBzaXplKSB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAgICAgYEV4cGVjdGVkIHRlcnJhaW4gZGF0YSBvZiBsZW5ndGggJHtzaXplICogc2l6ZX0gKCR7c2l6ZX0geCAke3NpemV9KSwgZ290ICR7dGVycmFpbi5sZW5ndGh9LmApOwoKICAgICAgICAgIHRoaXMudGVycmFpbiA9IHRlcnJhaW47CiAgICAgICAgICB0aGlzLm1hcnRpbmkgPSBtYXJ0aW5pOwogICAgICAgICAgdGhpcy5lcnJvcnMgPSBuZXcgRmxvYXQzMkFycmF5KHRlcnJhaW4ubGVuZ3RoKTsKICAgICAgICAgIHRoaXMudXBkYXRlKCk7CiAgICAgIH0KCiAgICAgIHVwZGF0ZSgpIHsKICAgICAgICAgIGNvbnN0IHtudW1UcmlhbmdsZXMsIG51bVBhcmVudFRyaWFuZ2xlcywgY29vcmRzLCBncmlkU2l6ZTogc2l6ZX0gPSB0aGlzLm1hcnRpbmk7CiAgICAgICAgICBjb25zdCB7dGVycmFpbiwgZXJyb3JzfSA9IHRoaXM7CgogICAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIGFsbCBwb3NzaWJsZSB0cmlhbmdsZXMsIHN0YXJ0aW5nIGZyb20gdGhlIHNtYWxsZXN0IGxldmVsCiAgICAgICAgICBmb3IgKGxldCBpID0gbnVtVHJpYW5nbGVzIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgICBjb25zdCBrID0gaSAqIDQ7CiAgICAgICAgICAgICAgY29uc3QgYXggPSBjb29yZHNbayArIDBdOwogICAgICAgICAgICAgIGNvbnN0IGF5ID0gY29vcmRzW2sgKyAxXTsKICAgICAgICAgICAgICBjb25zdCBieCA9IGNvb3Jkc1trICsgMl07CiAgICAgICAgICAgICAgY29uc3QgYnkgPSBjb29yZHNbayArIDNdOwogICAgICAgICAgICAgIGNvbnN0IG14ID0gKGF4ICsgYngpID4+IDE7CiAgICAgICAgICAgICAgY29uc3QgbXkgPSAoYXkgKyBieSkgPj4gMTsKICAgICAgICAgICAgICBjb25zdCBjeCA9IG14ICsgbXkgLSBheTsKICAgICAgICAgICAgICBjb25zdCBjeSA9IG15ICsgYXggLSBteDsKCiAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIGVycm9yIGluIHRoZSBtaWRkbGUgb2YgdGhlIGxvbmcgZWRnZSBvZiB0aGUgdHJpYW5nbGUKICAgICAgICAgICAgICBjb25zdCBpbnRlcnBvbGF0ZWRIZWlnaHQgPSAodGVycmFpbltheSAqIHNpemUgKyBheF0gKyB0ZXJyYWluW2J5ICogc2l6ZSArIGJ4XSkgLyAyOwogICAgICAgICAgICAgIGNvbnN0IG1pZGRsZUluZGV4ID0gbXkgKiBzaXplICsgbXg7CiAgICAgICAgICAgICAgY29uc3QgbWlkZGxlRXJyb3IgPSBNYXRoLmFicyhpbnRlcnBvbGF0ZWRIZWlnaHQgLSB0ZXJyYWluW21pZGRsZUluZGV4XSk7CgogICAgICAgICAgICAgIGVycm9yc1ttaWRkbGVJbmRleF0gPSBNYXRoLm1heChlcnJvcnNbbWlkZGxlSW5kZXhdLCBtaWRkbGVFcnJvcik7CgogICAgICAgICAgICAgIGlmIChpIDwgbnVtUGFyZW50VHJpYW5nbGVzKSB7IC8vIGJpZ2dlciB0cmlhbmdsZXM7IGFjY3VtdWxhdGUgZXJyb3Igd2l0aCBjaGlsZHJlbgogICAgICAgICAgICAgICAgICBjb25zdCBsZWZ0Q2hpbGRJbmRleCA9ICgoYXkgKyBjeSkgPj4gMSkgKiBzaXplICsgKChheCArIGN4KSA+PiAxKTsKICAgICAgICAgICAgICAgICAgY29uc3QgcmlnaHRDaGlsZEluZGV4ID0gKChieSArIGN5KSA+PiAxKSAqIHNpemUgKyAoKGJ4ICsgY3gpID4+IDEpOwogICAgICAgICAgICAgICAgICBlcnJvcnNbbWlkZGxlSW5kZXhdID0gTWF0aC5tYXgoZXJyb3JzW21pZGRsZUluZGV4XSwgZXJyb3JzW2xlZnRDaGlsZEluZGV4XSwgZXJyb3JzW3JpZ2h0Q2hpbGRJbmRleF0pOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgfQoKICAgICAgZ2V0TWVzaChtYXhFcnJvciA9IDAsIG1heExlbmd0aCA9IG51bGwpIHsKICAgICAgICAgIGNvbnN0IHtncmlkU2l6ZTogc2l6ZSwgaW5kaWNlc30gPSB0aGlzLm1hcnRpbmk7CiAgICAgICAgICBjb25zdCB7ZXJyb3JzfSA9IHRoaXM7CiAgICAgICAgICBsZXQgbnVtVmVydGljZXMgPSAwOwogICAgICAgICAgbGV0IG51bVRyaWFuZ2xlcyA9IDA7CiAgICAgICAgICBjb25zdCBtYXggPSBzaXplIC0gMTsKCiAgICAgICAgICAvLyBUaGUgbWF4TGVuZ3RoIHBhcmFtZXRlciB3aWxsIGNhdXNlIHRyaWFuZ2xlcyB0byBiZSBnZW5lcmF0ZWQgdW50aWwgdGhlIGxlZ3MgYXJlIGJlbG93IHRoaXMgbGVuZ3RoCiAgICAgICAgICAvLyBJdCBpcyBtZWFudCB0byBzdXBwb3J0IGNhc2VzIHdoZXJlIGEgY2VydGFpbiBtZXNoIGRlbnNpdHkgaXMgcmVxdWlyZWQgdG8gZG8gc3BoZXJpY2FsIG1hdGggb24gZGlnaXRhbCBnbG9iZXMKICAgICAgICAgIGNvbnN0IG1heFNjYWxlID0gbWF4TGVuZ3RoIHx8IHNpemU7CgogICAgICAgICAgLy8gdXNlIGFuIGluZGV4IGdyaWQgdG8ga2VlcCB0cmFjayBvZiB2ZXJ0aWNlcyB0aGF0IHdlcmUgYWxyZWFkeSB1c2VkIHRvIGF2b2lkIGR1cGxpY2F0aW9uCiAgICAgICAgICBpbmRpY2VzLmZpbGwoMCk7CgogICAgICAgICAgLy8gcmV0cmlldmUgbWVzaCBpbiB0d28gc3RhZ2VzIHRoYXQgYm90aCB0cmF2ZXJzZSB0aGUgZXJyb3IgbWFwOgogICAgICAgICAgLy8gLSBjb3VudEVsZW1lbnRzOiBmaW5kIHVzZWQgdmVydGljZXMgKGFuZCBhc3NpZ24gZWFjaCBhbiBpbmRleCksIGFuZCBjb3VudCB0cmlhbmdsZXMgKGZvciBtaW5pbXVtIGFsbG9jYXRpb24pCiAgICAgICAgICAvLyAtIHByb2Nlc3NUcmlhbmdsZTogZmlsbCB0aGUgYWxsb2NhdGVkIHZlcnRpY2VzICYgdHJpYW5nbGVzIHR5cGVkIGFycmF5cwoKICAgICAgICAgIGZ1bmN0aW9uIGNvdW50RWxlbWVudHMoYXgsIGF5LCBieCwgYnksIGN4LCBjeSkgewogICAgICAgICAgICAgIGNvbnN0IG14ID0gKGF4ICsgYngpID4+IDE7CiAgICAgICAgICAgICAgY29uc3QgbXkgPSAoYXkgKyBieSkgPj4gMTsKCiAgICAgICAgICAgICAgY29uc3QgbGVnTGVuZ3RoID0gTWF0aC5hYnMoYXggLSBjeCkgKyBNYXRoLmFicyhheSAtIGN5KTsKICAgICAgICAgICAgICBpZiAoKGxlZ0xlbmd0aCA+IDEgJiYgZXJyb3JzW215ICogc2l6ZSArIG14XSA+IG1heEVycm9yKSB8fCBsZWdMZW5ndGggPiBtYXhTY2FsZSkgewogICAgICAgICAgICAgICAgICBjb3VudEVsZW1lbnRzKGN4LCBjeSwgYXgsIGF5LCBteCwgbXkpOwogICAgICAgICAgICAgICAgICBjb3VudEVsZW1lbnRzKGJ4LCBieSwgY3gsIGN5LCBteCwgbXkpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIGluZGljZXNbYXkgKiBzaXplICsgYXhdID0gaW5kaWNlc1theSAqIHNpemUgKyBheF0gfHwgKytudW1WZXJ0aWNlczsKICAgICAgICAgICAgICAgICAgaW5kaWNlc1tieSAqIHNpemUgKyBieF0gPSBpbmRpY2VzW2J5ICogc2l6ZSArIGJ4XSB8fCArK251bVZlcnRpY2VzOwogICAgICAgICAgICAgICAgICBpbmRpY2VzW2N5ICogc2l6ZSArIGN4XSA9IGluZGljZXNbY3kgKiBzaXplICsgY3hdIHx8ICsrbnVtVmVydGljZXM7CiAgICAgICAgICAgICAgICAgIG51bVRyaWFuZ2xlcysrOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGNvdW50RWxlbWVudHMoMCwgMCwgbWF4LCBtYXgsIG1heCwgMCk7CiAgICAgICAgICBjb3VudEVsZW1lbnRzKG1heCwgbWF4LCAwLCAwLCAwLCBtYXgpOwoKICAgICAgICAgIGNvbnN0IHZlcnRpY2VzID0gbmV3IFVpbnQxNkFycmF5KG51bVZlcnRpY2VzICogMik7CiAgICAgICAgICBjb25zdCB0cmlhbmdsZXMgPSBuZXcgVWludDMyQXJyYXkobnVtVHJpYW5nbGVzICogMyk7CiAgICAgICAgICBsZXQgdHJpSW5kZXggPSAwOwoKICAgICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NUcmlhbmdsZShheCwgYXksIGJ4LCBieSwgY3gsIGN5KSB7CiAgICAgICAgICAgICAgY29uc3QgbXggPSAoYXggKyBieCkgPj4gMTsKICAgICAgICAgICAgICBjb25zdCBteSA9IChheSArIGJ5KSA+PiAxOwoKICAgICAgICAgICAgICBjb25zdCBsZWdMZW5ndGggPSBNYXRoLmFicyhheCAtIGN4KSArIE1hdGguYWJzKGF5IC0gY3kpOwogICAgICAgICAgICAgIGlmICgobGVnTGVuZ3RoID4gMSAmJiBlcnJvcnNbbXkgKiBzaXplICsgbXhdID4gbWF4RXJyb3IpIHx8IGxlZ0xlbmd0aCA+IG1heFNjYWxlKSB7CiAgICAgICAgICAgICAgICAgIC8vIHRyaWFuZ2xlIGRvZXNuJ3QgYXBwcm94aW1hdGUgdGhlIHN1cmZhY2Ugd2VsbCBlbm91Z2g7IGRyaWxsIGRvd24gZnVydGhlcgogICAgICAgICAgICAgICAgICBwcm9jZXNzVHJpYW5nbGUoY3gsIGN5LCBheCwgYXksIG14LCBteSk7CiAgICAgICAgICAgICAgICAgIHByb2Nlc3NUcmlhbmdsZShieCwgYnksIGN4LCBjeSwgbXgsIG15KTsKCiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgLy8gYWRkIGEgdHJpYW5nbGUKICAgICAgICAgICAgICAgICAgY29uc3QgYSA9IGluZGljZXNbYXkgKiBzaXplICsgYXhdIC0gMTsKICAgICAgICAgICAgICAgICAgY29uc3QgYiA9IGluZGljZXNbYnkgKiBzaXplICsgYnhdIC0gMTsKICAgICAgICAgICAgICAgICAgY29uc3QgYyA9IGluZGljZXNbY3kgKiBzaXplICsgY3hdIC0gMTsKCiAgICAgICAgICAgICAgICAgIHZlcnRpY2VzWzIgKiBhXSA9IGF4OwogICAgICAgICAgICAgICAgICB2ZXJ0aWNlc1syICogYSArIDFdID0gYXk7CgogICAgICAgICAgICAgICAgICB2ZXJ0aWNlc1syICogYl0gPSBieDsKICAgICAgICAgICAgICAgICAgdmVydGljZXNbMiAqIGIgKyAxXSA9IGJ5OwoKICAgICAgICAgICAgICAgICAgdmVydGljZXNbMiAqIGNdID0gY3g7CiAgICAgICAgICAgICAgICAgIHZlcnRpY2VzWzIgKiBjICsgMV0gPSBjeTsKCiAgICAgICAgICAgICAgICAgIHRyaWFuZ2xlc1t0cmlJbmRleCsrXSA9IGE7CiAgICAgICAgICAgICAgICAgIHRyaWFuZ2xlc1t0cmlJbmRleCsrXSA9IGI7CiAgICAgICAgICAgICAgICAgIHRyaWFuZ2xlc1t0cmlJbmRleCsrXSA9IGM7CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcHJvY2Vzc1RyaWFuZ2xlKDAsIDAsIG1heCwgbWF4LCBtYXgsIDApOwogICAgICAgICAgcHJvY2Vzc1RyaWFuZ2xlKG1heCwgbWF4LCAwLCAwLCAwLCBtYXgpOwoKICAgICAgICAgIHJldHVybiB7dmVydGljZXMsIHRyaWFuZ2xlc307CiAgICAgIH0KICB9CgogIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9DZXNpdW1HUy9jZXNpdW0vYmxvYi8xLjc2L1NvdXJjZS9Xb3JrZXJzRVM2L2NyZWF0ZVZlcnRpY2VzRnJvbVF1YW50aXplZFRlcnJhaW5NZXNoLmpzCgogIHZhciBtYXJ0aW5pQ2FjaGUgPSB7fTsKICBmdW5jdGlvbiBkZWNvZGVUZXJyYWluKHBhcmFtZXRlcnMsIHRyYW5zZmVyYWJsZU9iamVjdHMpIHsKICAgIHZhciBfbWFydGluaUNhY2hlJHRpbGVTaXo7CiAgICB2YXIgaW1hZ2VEYXRhID0gcGFyYW1ldGVycy5pbWFnZURhdGEsCiAgICAgIF9wYXJhbWV0ZXJzJHRpbGVTaXplID0gcGFyYW1ldGVycy50aWxlU2l6ZSwKICAgICAgdGlsZVNpemUgPSBfcGFyYW1ldGVycyR0aWxlU2l6ZSA9PT0gdm9pZCAwID8gMjU2IDogX3BhcmFtZXRlcnMkdGlsZVNpemUsCiAgICAgIGVycm9yTGV2ZWwgPSBwYXJhbWV0ZXJzLmVycm9yTGV2ZWwsCiAgICAgIG1heFZlcnRleERpc3RhbmNlID0gcGFyYW1ldGVycy5tYXhWZXJ0ZXhEaXN0YW5jZTsKCiAgICAvLyBIZWlnaHQgZGF0YSBjYW4gYmUgZWl0aGVyIGFuIGFycmF5IG9mIG51bWJlcnMgKGZvciBwcmUtZXhpc3RpbmcgdGVycmFpbiBkYXRhKQogICAgLy8gb3IgYW4gaW1hZ2UgZGF0YSBhcnJheSAoZm9yIGRlY29kaW5nIGZyb20gYW4gaW1hZ2UpCgogICAgdmFyIGhlaWdodERhdGEgPSB7CiAgICAgIHR5cGU6ICJpbWFnZSIsCiAgICAgIGFycmF5OiBpbWFnZURhdGEKICAgIH07CiAgICB2YXIgdGVycmFpbjsKICAgIHsKICAgICAgdmFyIGFycmF5ID0gaGVpZ2h0RGF0YS5hcnJheTsKICAgICAgdmFyIHBpeGVscyA9IG5kYXJyYXkobmV3IFVpbnQ4QXJyYXkoYXJyYXkpLCBbdGlsZVNpemUsIHRpbGVTaXplLCA0XSwgWzQsIDQgKiB0aWxlU2l6ZSwgMV0sIDApOwogICAgICB0ZXJyYWluID0gcmdiVGVycmFpblRvR3JpZChwaXhlbHMpOwogICAgfQoKICAgIC8vIFRpbGUgc2l6ZSBtdXN0IGJlIG1haW50YWluZWQgdGhyb3VnaCB0aGUgbGlmZSBvZiB0aGUgd29ya2VyCiAgICAoX21hcnRpbmlDYWNoZSR0aWxlU2l6ID0gbWFydGluaUNhY2hlW3RpbGVTaXplXSkgIT09IG51bGwgJiYgX21hcnRpbmlDYWNoZSR0aWxlU2l6ICE9PSB2b2lkIDAgPyBfbWFydGluaUNhY2hlJHRpbGVTaXogOiBtYXJ0aW5pQ2FjaGVbdGlsZVNpemVdID0gbmV3IE1hcnRpbmkodGlsZVNpemUgKyAxKTsKICAgIHZhciB0aWxlID0gbWFydGluaUNhY2hlW3RpbGVTaXplXS5jcmVhdGVUaWxlKHRlcnJhaW4pOwoKICAgIC8vIGdldCBhIG1lc2ggKHZlcnRpY2VzIGFuZCB0cmlhbmdsZXMgaW5kaWNlcykgZm9yIGEgMTBtIGVycm9yCiAgICB2YXIgbWVzaCA9IHRpbGUuZ2V0TWVzaChlcnJvckxldmVsLCBNYXRoLm1pbihtYXhWZXJ0ZXhEaXN0YW5jZSwgdGlsZVNpemUpKTsKICAgIHZhciByZXMgPSBjcmVhdGVRdWFudGl6ZWRNZXNoRGF0YSh0aWxlLCBtZXNoLCB0aWxlU2l6ZSwKICAgIC8vIE9ubHkgaW5jbHVkZSB2ZXJ0ZXggZGF0YSBpZiBhbnRpY2lwYXRlIHVwc2NhbGluZyB0aWxlCiAgICB0ZXJyYWluICk7CiAgICB0cmFuc2ZlcmFibGVPYmplY3RzLnB1c2gocmVzLmluZGljZXMuYnVmZmVyKTsKICAgIHRyYW5zZmVyYWJsZU9iamVjdHMucHVzaChyZXMucXVhbnRpemVkVmVydGljZXMuYnVmZmVyKTsKICAgIGlmIChyZXMucXVhbnRpemVkSGVpZ2h0cykgewogICAgICB0cmFuc2ZlcmFibGVPYmplY3RzLnB1c2gocmVzLnF1YW50aXplZEhlaWdodHMuYnVmZmVyKTsKICAgIH0KICAgIHJldHVybiByZXM7CiAgfQogIHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24gKG1zZykgewogICAgdmFyIF9tc2ckZGF0YSA9IG1zZy5kYXRhLAogICAgICBpZCA9IF9tc2ckZGF0YS5pZCwKICAgICAgcGF5bG9hZCA9IF9tc2ckZGF0YS5wYXlsb2FkOwogICAgaWYgKGlkID09IG51bGwpIHJldHVybjsKICAgIHZhciBvYmplY3RzID0gW107CiAgICB2YXIgcmVzID0gbnVsbDsKICAgIHRyeSB7CiAgICAgIHJlcyA9IGRlY29kZVRlcnJhaW4ocGF5bG9hZCwgb2JqZWN0cyk7CiAgICAgIC8vIEB0cy1pZ25vcmUKICAgICAgc2VsZi5wb3N0TWVzc2FnZSh7CiAgICAgICAgaWQ6IGlkLAogICAgICAgIHBheWxvYWQ6IHJlcwogICAgICB9LCBvYmplY3RzKTsKICAgIH0gY2F0Y2ggKGVycikgewogICAgICB2YXIgX2VyciRtZXNzYWdlOwogICAgICB2YXIgX21zZyA9IChfZXJyJG1lc3NhZ2UgPSBlcnIubWVzc2FnZSkgIT09IG51bGwgJiYgX2VyciRtZXNzYWdlICE9PSB2b2lkIDAgPyBfZXJyJG1lc3NhZ2UgOiBlcnI7CiAgICAgIHNlbGYucG9zdE1lc3NhZ2UoewogICAgICAgIGlkOiBpZCwKICAgICAgICBlcnI6IF9tc2cudG9TdHJpbmcoKQogICAgICB9KTsKICAgIH0gZmluYWxseSB7CiAgICAgIHJlcyA9IG51bGw7CiAgICAgIG9iamVjdHMgPSBudWxsOwogICAgfQogIH07Cgp9KSgpOwoK', null, false);
1588
+ /* eslint-enable */
1589
+
1437
1590
  var MapboxTerrainProvider = /*#__PURE__*/function (_MartiniTerrainProvid) {
1438
- _inherits(MapboxTerrainProvider, _MartiniTerrainProvid);
1439
- var _super2 = _createSuper(MapboxTerrainProvider);
1440
1591
  function MapboxTerrainProvider() {
1441
1592
  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1442
1593
  _classCallCheck(this, MapboxTerrainProvider);
1443
1594
  var resource = new MapboxTerrainResource(opts);
1444
- return _super2.call(this, _objectSpread2(_objectSpread2({}, opts), {}, {
1445
- resource: resource
1446
- }));
1595
+ var decoder = new WorkerFarmTerrainDecoder({
1596
+ worker: new WorkerFactory()
1597
+ });
1598
+ return _callSuper(this, MapboxTerrainProvider, [_objectSpread2(_objectSpread2({}, opts), {}, {
1599
+ resource: resource,
1600
+ decoder: decoder
1601
+ })]);
1447
1602
  }
1603
+ _inherits(MapboxTerrainProvider, _MartiniTerrainProvid);
1448
1604
  return _createClass(MapboxTerrainProvider);
1449
1605
  }(MartiniTerrainProvider);
1450
1606
 
1451
1607
  exports.DefaultHeightmapResource = DefaultHeightmapResource;
1608
+ exports.DefaultTerrainDecoder = DefaultTerrainDecoder;
1452
1609
  exports.MapboxTerrainResource = MapboxTerrainResource;
1453
1610
  exports.MartiniTerrainProvider = MartiniTerrainProvider;
1611
+ exports.StretchedTilingScheme = StretchedTilingScheme;
1612
+ exports.WorkerFarmTerrainDecoder = WorkerFarmTerrainDecoder;
1613
+ exports.createQuantizedMeshData = createQuantizedMeshData;
1454
1614
  exports["default"] = MapboxTerrainProvider;
1615
+ exports.emptyMesh = emptyMesh;
1616
+ exports.rgbTerrainToGrid = rgbTerrainToGrid;
1617
+ exports.subsetByWindow = subsetByWindow;
1618
+ exports.testMeshData = testMeshData;
1455
1619
  //# sourceMappingURL=index.cjs.map