@gmod/bbi 1.0.30 → 1.0.33

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/blockView.js CHANGED
@@ -1,82 +1,148 @@
1
1
  "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (_) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
8
53
  exports.BlockView = void 0;
9
-
10
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
-
12
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
-
14
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
-
16
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
17
-
18
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
19
-
20
- var _binaryParser = require("@gmod/binary-parser");
21
-
22
- var _abortablePromiseCache = _interopRequireDefault(require("abortable-promise-cache"));
23
-
24
- var _zlib = _interopRequireDefault(require("zlib"));
25
-
26
- var _quickLru = _interopRequireDefault(require("quick-lru"));
27
-
28
- var _range = _interopRequireDefault(require("./range"));
29
-
30
- var _util = require("./util");
31
-
32
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
33
-
34
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
35
-
54
+ var binary_parser_1 = require("@gmod/binary-parser");
55
+ var abortable_promise_cache_1 = __importDefault(require("abortable-promise-cache"));
56
+ var unzip_1 = require("./unzip");
57
+ var quick_lru_1 = __importDefault(require("quick-lru"));
58
+ var range_1 = __importDefault(require("./range"));
59
+ var util_1 = require("./util");
36
60
  var BIG_WIG_TYPE_GRAPH = 1;
37
61
  var BIG_WIG_TYPE_VSTEP = 2;
38
62
  var BIG_WIG_TYPE_FSTEP = 3;
39
-
40
63
  function getParsers(isBigEndian) {
41
- var _choices;
42
-
43
- var le = isBigEndian ? 'big' : 'little';
44
- var summaryParser = new _binaryParser.Parser().endianess(le).uint32('chromId').uint32('start').uint32('end').uint32('validCnt').float('minScore').float('maxScore').float('sumData').float('sumSqData');
45
- var leafParser = new _binaryParser.Parser().endianess(le).uint8('isLeaf').skip(1).uint16('cnt').choice({
46
- tag: 'isLeaf',
47
- choices: {
48
- 1: new _binaryParser.Parser().array('blocksToFetch', {
49
- length: 'cnt',
50
- type: new _binaryParser.Parser().uint32('startChrom').uint32('startBase').uint32('endChrom').uint32('endBase').uint64('blockOffset').uint64('blockSize')
51
- }),
52
- 0: new _binaryParser.Parser().array('recurOffsets', {
53
- length: 'cnt',
54
- type: new _binaryParser.Parser().uint32('startChrom').uint32('startBase').uint32('endChrom').uint32('endBase').uint64('blockOffset')
55
- })
56
- }
57
- });
58
- var bigBedParser = new _binaryParser.Parser().endianess(le).uint32('chromId').int32('start').int32('end').string('rest', {
59
- zeroTerminated: true
60
- });
61
- var bigWigParser = new _binaryParser.Parser().endianess(le).skip(4).int32('blockStart').skip(4).uint32('itemStep').uint32('itemSpan').uint8('blockType').skip(1).uint16('itemCount').choice({
62
- tag: 'blockType',
63
- choices: (_choices = {}, (0, _defineProperty2.default)(_choices, BIG_WIG_TYPE_FSTEP, new _binaryParser.Parser().array('items', {
64
- length: 'itemCount',
65
- type: new _binaryParser.Parser().float('score')
66
- })), (0, _defineProperty2.default)(_choices, BIG_WIG_TYPE_VSTEP, new _binaryParser.Parser().array('items', {
67
- length: 'itemCount',
68
- type: new _binaryParser.Parser().int32('start').float('score')
69
- })), (0, _defineProperty2.default)(_choices, BIG_WIG_TYPE_GRAPH, new _binaryParser.Parser().array('items', {
70
- length: 'itemCount',
71
- type: new _binaryParser.Parser().int32('start').int32('end').float('score')
72
- })), _choices)
73
- });
74
- return {
75
- bigWigParser: bigWigParser,
76
- bigBedParser: bigBedParser,
77
- summaryParser: summaryParser,
78
- leafParser: leafParser
79
- };
64
+ var _a;
65
+ var le = isBigEndian ? 'big' : 'little';
66
+ var summaryParser = new binary_parser_1.Parser()
67
+ .endianess(le)
68
+ .uint32('chromId')
69
+ .uint32('start')
70
+ .uint32('end')
71
+ .uint32('validCnt')
72
+ .float('minScore')
73
+ .float('maxScore')
74
+ .float('sumData')
75
+ .float('sumSqData');
76
+ var leafParser = new binary_parser_1.Parser()
77
+ .endianess(le)
78
+ .uint8('isLeaf')
79
+ .skip(1)
80
+ .uint16('cnt')
81
+ .choice({
82
+ tag: 'isLeaf',
83
+ choices: {
84
+ 1: new binary_parser_1.Parser().array('blocksToFetch', {
85
+ length: 'cnt',
86
+ type: new binary_parser_1.Parser()
87
+ .uint32('startChrom')
88
+ .uint32('startBase')
89
+ .uint32('endChrom')
90
+ .uint32('endBase')
91
+ .uint64('blockOffset')
92
+ .uint64('blockSize'),
93
+ }),
94
+ 0: new binary_parser_1.Parser().array('recurOffsets', {
95
+ length: 'cnt',
96
+ type: new binary_parser_1.Parser()
97
+ .uint32('startChrom')
98
+ .uint32('startBase')
99
+ .uint32('endChrom')
100
+ .uint32('endBase')
101
+ .uint64('blockOffset'),
102
+ }),
103
+ },
104
+ });
105
+ var bigBedParser = new binary_parser_1.Parser()
106
+ .endianess(le)
107
+ .uint32('chromId')
108
+ .int32('start')
109
+ .int32('end')
110
+ .string('rest', {
111
+ zeroTerminated: true,
112
+ });
113
+ var bigWigParser = new binary_parser_1.Parser()
114
+ .endianess(le)
115
+ .skip(4)
116
+ .int32('blockStart')
117
+ .skip(4)
118
+ .uint32('itemStep')
119
+ .uint32('itemSpan')
120
+ .uint8('blockType')
121
+ .skip(1)
122
+ .uint16('itemCount')
123
+ .choice({
124
+ tag: 'blockType',
125
+ choices: (_a = {},
126
+ _a[BIG_WIG_TYPE_FSTEP] = new binary_parser_1.Parser().array('items', {
127
+ length: 'itemCount',
128
+ type: new binary_parser_1.Parser().float('score'),
129
+ }),
130
+ _a[BIG_WIG_TYPE_VSTEP] = new binary_parser_1.Parser().array('items', {
131
+ length: 'itemCount',
132
+ type: new binary_parser_1.Parser().int32('start').float('score'),
133
+ }),
134
+ _a[BIG_WIG_TYPE_GRAPH] = new binary_parser_1.Parser().array('items', {
135
+ length: 'itemCount',
136
+ type: new binary_parser_1.Parser().int32('start').int32('end').float('score'),
137
+ }),
138
+ _a),
139
+ });
140
+ return {
141
+ bigWigParser: bigWigParser,
142
+ bigBedParser: bigBedParser,
143
+ summaryParser: summaryParser,
144
+ leafParser: leafParser,
145
+ };
80
146
  }
81
147
  /**
82
148
  * View into a subset of the data in a BigWig file.
@@ -85,432 +151,275 @@ function getParsers(isBigEndian) {
85
151
  * Explorer by Thomas Down.
86
152
  * @constructs
87
153
  */
88
-
89
-
90
- var BlockView = /*#__PURE__*/function () {
91
- function BlockView(bbi, refsByName, cirTreeOffset, cirTreeLength, isBigEndian, isCompressed, blockType) {
92
- var _this = this;
93
-
94
- (0, _classCallCheck2.default)(this, BlockView);
95
- (0, _defineProperty2.default)(this, "cirTreeOffset", void 0);
96
- (0, _defineProperty2.default)(this, "cirTreeLength", void 0);
97
- (0, _defineProperty2.default)(this, "bbi", void 0);
98
- (0, _defineProperty2.default)(this, "isCompressed", void 0);
99
- (0, _defineProperty2.default)(this, "isBigEndian", void 0);
100
- (0, _defineProperty2.default)(this, "refsByName", void 0);
101
- (0, _defineProperty2.default)(this, "blockType", void 0);
102
- (0, _defineProperty2.default)(this, "cirTreePromise", void 0);
103
- (0, _defineProperty2.default)(this, "featureCache", new _abortablePromiseCache.default({
104
- cache: new _quickLru.default({
105
- maxSize: 1000
106
- }),
107
- fill: function () {
108
- var _fill = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(requestData, signal) {
109
- var length, offset, _yield$_this$bbi$read, buffer;
110
-
111
- return _regenerator.default.wrap(function _callee$(_context) {
112
- while (1) {
113
- switch (_context.prev = _context.next) {
114
- case 0:
115
- length = requestData.length, offset = requestData.offset;
116
- _context.next = 3;
117
- return _this.bbi.read(Buffer.alloc(length), 0, length, offset, {
118
- signal: signal
119
- });
120
-
121
- case 3:
122
- _yield$_this$bbi$read = _context.sent;
123
- buffer = _yield$_this$bbi$read.buffer;
124
- return _context.abrupt("return", buffer);
125
-
126
- case 6:
127
- case "end":
128
- return _context.stop();
129
- }
130
- }
131
- }, _callee);
132
- }));
133
-
134
- function fill(_x, _x2) {
135
- return _fill.apply(this, arguments);
136
- }
137
-
138
- return fill;
139
- }()
140
- }));
141
- (0, _defineProperty2.default)(this, "leafParser", void 0);
142
- (0, _defineProperty2.default)(this, "bigWigParser", void 0);
143
- (0, _defineProperty2.default)(this, "bigBedParser", void 0);
144
- (0, _defineProperty2.default)(this, "summaryParser", void 0);
145
- if (!(cirTreeOffset >= 0)) throw new Error('invalid cirTreeOffset!');
146
- if (!(cirTreeLength > 0)) throw new Error('invalid cirTreeLength!');
147
- this.cirTreeOffset = cirTreeOffset;
148
- this.cirTreeLength = cirTreeLength;
149
- this.isCompressed = isCompressed;
150
- this.refsByName = refsByName;
151
- this.isBigEndian = isBigEndian;
152
- this.bbi = bbi;
153
- this.blockType = blockType;
154
- Object.assign(this, getParsers(isBigEndian));
155
- }
156
-
157
- (0, _createClass2.default)(BlockView, [{
158
- key: "readWigData",
159
- value: function () {
160
- var _readWigData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(chrName, start, end, observer, opts) {
161
- var _this2 = this;
162
-
163
- var refsByName, bbi, cirTreeOffset, isBigEndian, signal, chrId, request, _yield$this$cirTreePr, buffer, cirBlockSize, blocksToFetch, outstanding, cirFobRecur2, filterFeats, cirFobStartFetch, cirFobRecur;
164
-
165
- return _regenerator.default.wrap(function _callee3$(_context3) {
166
- while (1) {
167
- switch (_context3.prev = _context3.next) {
168
- case 0:
169
- _context3.prev = 0;
170
- refsByName = this.refsByName, bbi = this.bbi, cirTreeOffset = this.cirTreeOffset, isBigEndian = this.isBigEndian;
171
- signal = opts.signal;
172
- chrId = refsByName[chrName];
173
-
174
- if (chrId === undefined) {
175
- observer.complete();
176
- }
177
-
178
- request = {
179
- chrId: chrId,
180
- start: start,
181
- end: end
182
- };
183
-
184
- if (!this.cirTreePromise) {
185
- this.cirTreePromise = bbi.read(Buffer.alloc(48), 0, 48, cirTreeOffset, {
186
- signal: signal
187
- });
188
- }
189
-
190
- _context3.next = 9;
191
- return this.cirTreePromise;
192
-
193
- case 9:
194
- _yield$this$cirTreePr = _context3.sent;
195
- buffer = _yield$this$cirTreePr.buffer;
196
- cirBlockSize = isBigEndian ? buffer.readUInt32BE(4) : buffer.readUInt32LE(4);
197
- blocksToFetch = [];
198
- outstanding = 0; //eslint-disable-next-line prefer-const
199
-
200
- filterFeats = function filterFeats(b) {
201
- return (b.startChrom < chrId || b.startChrom === chrId && b.startBase <= end) && (b.endChrom > chrId || b.endChrom === chrId && b.endBase >= start);
202
- };
203
-
204
- cirFobStartFetch = /*#__PURE__*/function () {
205
- var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(off, fr, level) {
206
- var length, offset, resultBuffer, i;
207
- return _regenerator.default.wrap(function _callee2$(_context2) {
208
- while (1) {
209
- switch (_context2.prev = _context2.next) {
210
- case 0:
211
- _context2.prev = 0;
212
- length = fr.max() - fr.min();
213
- offset = fr.min();
214
- _context2.next = 5;
215
- return _this2.featureCache.get("".concat(length, "_").concat(offset), {
216
- length: length,
217
- offset: offset
218
- }, signal);
219
-
220
- case 5:
221
- resultBuffer = _context2.sent;
222
-
223
- for (i = 0; i < off.length; i += 1) {
224
- if (fr.contains(off[i])) {
225
- cirFobRecur2(resultBuffer, off[i] - offset, level, observer, opts);
226
- outstanding -= 1;
227
-
228
- if (outstanding === 0) {
229
- _this2.readFeatures(observer, blocksToFetch, _objectSpread(_objectSpread({}, opts), {}, {
230
- request: request
231
- }));
232
- }
233
- }
234
- }
235
-
236
- _context2.next = 12;
237
- break;
238
-
239
- case 9:
240
- _context2.prev = 9;
241
- _context2.t0 = _context2["catch"](0);
242
- observer.error(_context2.t0);
243
-
244
- case 12:
245
- case "end":
246
- return _context2.stop();
247
- }
248
- }
249
- }, _callee2, null, [[0, 9]]);
250
- }));
251
-
252
- return function cirFobStartFetch(_x8, _x9, _x10) {
253
- return _ref.apply(this, arguments);
254
- };
255
- }();
256
-
257
- cirFobRecur = function cirFobRecur(offset, level) {
258
- try {
259
- outstanding += offset.length;
260
- var maxCirBlockSpan = 4 + cirBlockSize * 32; // Upper bound on size, based on a completely full leaf node.
261
-
262
- var spans = new _range.default(offset[0], offset[0] + maxCirBlockSpan);
263
-
264
- for (var i = 1; i < offset.length; i += 1) {
265
- var blockSpan = new _range.default(offset[i], offset[i] + maxCirBlockSpan);
266
- spans = spans.union(blockSpan);
267
- }
268
-
269
- spans.getRanges().map(function (fr) {
270
- return cirFobStartFetch(offset, fr, level);
271
- });
272
- } catch (e) {
273
- observer.error(e);
274
- }
275
- };
276
-
277
- cirFobRecur2 = function cirFobRecur2(cirBlockData, offset, level) {
278
- try {
279
- var data = cirBlockData.slice(offset);
280
-
281
- var p = _this2.leafParser.parse(data).result;
282
-
283
- if (p.blocksToFetch) {
284
- blocksToFetch = blocksToFetch.concat(p.blocksToFetch.filter(filterFeats).map(function (l) {
285
- return {
286
- offset: l.blockOffset,
287
- length: l.blockSize
288
- };
289
- }));
154
+ var BlockView = /** @class */ (function () {
155
+ function BlockView(bbi, refsByName, cirTreeOffset, cirTreeLength, isBigEndian, isCompressed, blockType) {
156
+ var _this = this;
157
+ this.featureCache = new abortable_promise_cache_1.default({
158
+ cache: new quick_lru_1.default({ maxSize: 1000 }),
159
+ fill: function (requestData, signal) { return __awaiter(_this, void 0, void 0, function () {
160
+ var length, offset, buffer;
161
+ return __generator(this, function (_a) {
162
+ switch (_a.label) {
163
+ case 0:
164
+ length = requestData.length, offset = requestData.offset;
165
+ return [4 /*yield*/, this.bbi.read(Buffer.alloc(length), 0, length, offset, { signal: signal })];
166
+ case 1:
167
+ buffer = (_a.sent()).buffer;
168
+ return [2 /*return*/, buffer];
290
169
  }
291
-
292
- if (p.recurOffsets) {
293
- var recurOffsets = p.recurOffsets.filter(filterFeats).map(function (l) {
294
- return l.blockOffset;
295
- });
296
-
297
- if (recurOffsets.length > 0) {
298
- cirFobRecur(recurOffsets, level + 1);
299
- }
300
- }
301
- } catch (e) {
302
- observer.error(e);
303
- }
304
- };
305
-
306
- return _context3.abrupt("return", cirFobRecur([cirTreeOffset + 48], 1));
307
-
308
- case 21:
309
- _context3.prev = 21;
310
- _context3.t0 = _context3["catch"](0);
311
- observer.error(_context3.t0);
312
-
313
- case 24:
314
- case "end":
315
- return _context3.stop();
316
- }
317
- }
318
- }, _callee3, this, [[0, 21]]);
319
- }));
320
-
321
- function readWigData(_x3, _x4, _x5, _x6, _x7) {
322
- return _readWigData.apply(this, arguments);
323
- }
324
-
325
- return readWigData;
326
- }()
327
- }, {
328
- key: "parseSummaryBlock",
329
- value: function parseSummaryBlock(data, startOffset, request) {
330
- var features = [];
331
- var currOffset = startOffset;
332
-
333
- while (currOffset < data.byteLength) {
334
- var res = this.summaryParser.parse(data.slice(currOffset));
335
- features.push(res.result);
336
- currOffset += res.offset;
337
- }
338
-
339
- var items = features;
340
- if (request) items = items.filter(function (elt) {
341
- return elt.chromId === request.chrId;
342
- });
343
- items = items.map(function (elt) {
344
- return {
345
- start: elt.start,
346
- end: elt.end,
347
- maxScore: elt.maxScore,
348
- minScore: elt.minScore,
349
- score: elt.sumData / (elt.validCnt || 1),
350
- summary: true
351
- };
352
- });
353
- return request ? items.filter(function (f) {
354
- return BlockView.coordFilter(f, request);
355
- }) : items;
356
- }
357
- }, {
358
- key: "parseBigBedBlock",
359
- value: function parseBigBedBlock(data, startOffset, offset, request) {
360
- var items = [];
361
- var currOffset = startOffset;
362
-
363
- while (currOffset < data.byteLength) {
364
- var res = this.bigBedParser.parse(data.slice(currOffset));
365
- res.result.uniqueId = "bb-".concat(offset + currOffset);
366
- items.push(res.result);
367
- currOffset += res.offset;
368
- }
369
-
370
- return request ? items.filter(function (f) {
371
- return BlockView.coordFilter(f, request);
372
- }) : items;
373
- }
374
- }, {
375
- key: "parseBigWigBlock",
376
- value: function parseBigWigBlock(bytes, startOffset, request) {
377
- var data = bytes.slice(startOffset);
378
- var results = this.bigWigParser.parse(data).result;
379
- var items = results.items,
380
- itemSpan = results.itemSpan,
381
- itemStep = results.itemStep,
382
- blockStart = results.blockStart,
383
- blockType = results.blockType;
384
-
385
- if (blockType === BIG_WIG_TYPE_FSTEP) {
386
- for (var i = 0; i < items.length; i++) {
387
- items[i].start = blockStart + i * itemStep;
388
- items[i].end = blockStart + i * itemStep + itemSpan;
170
+ });
171
+ }); },
172
+ });
173
+ if (!(cirTreeOffset >= 0)) {
174
+ throw new Error('invalid cirTreeOffset!');
389
175
  }
390
- } else if (blockType === BIG_WIG_TYPE_VSTEP) {
391
- for (var _i = 0; _i < items.length; _i++) {
392
- items[_i].end = items[_i].start + itemSpan;
176
+ if (!(cirTreeLength > 0)) {
177
+ throw new Error('invalid cirTreeLength!');
393
178
  }
394
- }
395
-
396
- return request ? items.filter(function (f) {
397
- return BlockView.coordFilter(f, request);
398
- }) : items;
179
+ this.cirTreeOffset = cirTreeOffset;
180
+ this.cirTreeLength = cirTreeLength;
181
+ this.isCompressed = isCompressed;
182
+ this.refsByName = refsByName;
183
+ this.isBigEndian = isBigEndian;
184
+ this.bbi = bbi;
185
+ this.blockType = blockType;
186
+ Object.assign(this, getParsers(isBigEndian));
399
187
  }
400
- }, {
401
- key: "readFeatures",
402
- value: function () {
403
- var _readFeatures = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5(observer, blocks) {
404
- var _this3 = this;
405
-
406
- var opts,
407
- blockType,
408
- isCompressed,
409
- signal,
410
- request,
411
- blockGroupsToFetch,
412
- _args5 = arguments;
413
- return _regenerator.default.wrap(function _callee5$(_context5) {
414
- while (1) {
415
- switch (_context5.prev = _context5.next) {
416
- case 0:
417
- opts = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : {};
418
- _context5.prev = 1;
419
- blockType = this.blockType, isCompressed = this.isCompressed;
420
- signal = opts.signal, request = opts.request;
421
- blockGroupsToFetch = (0, _util.groupBlocks)(blocks);
422
- (0, _util.checkAbortSignal)(signal);
423
- _context5.next = 8;
424
- return Promise.all(blockGroupsToFetch.map( /*#__PURE__*/function () {
425
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4(blockGroup) {
426
- var length, offset, data;
427
- return _regenerator.default.wrap(function _callee4$(_context4) {
428
- while (1) {
429
- switch (_context4.prev = _context4.next) {
430
- case 0:
431
- (0, _util.checkAbortSignal)(signal);
432
- length = blockGroup.length, offset = blockGroup.offset;
433
- _context4.next = 4;
434
- return _this3.featureCache.get("".concat(length, "_").concat(offset), blockGroup, signal);
435
-
436
- case 4:
437
- data = _context4.sent;
438
- blockGroup.blocks.forEach(function (block) {
439
- (0, _util.checkAbortSignal)(signal);
440
- var blockOffset = block.offset - blockGroup.offset;
441
- var resultData = data;
442
-
443
- if (isCompressed) {
444
- resultData = _zlib.default.inflateSync(data.slice(blockOffset));
445
- blockOffset = 0;
446
- }
447
-
448
- (0, _util.checkAbortSignal)(signal);
449
-
450
- switch (blockType) {
451
- case 'summary':
452
- observer.next(_this3.parseSummaryBlock(resultData, blockOffset, request));
453
- break;
454
-
455
- case 'bigwig':
456
- observer.next(_this3.parseBigWigBlock(resultData, blockOffset, request));
457
- break;
458
-
459
- case 'bigbed':
460
- observer.next( // eslint-disable-next-line no-bitwise
461
- _this3.parseBigBedBlock(resultData, blockOffset, block.offset * (1 << 8), request));
462
- break;
463
-
464
- default:
465
- console.warn("Don't know what to do with ".concat(blockType));
466
- }
188
+ BlockView.prototype.readWigData = function (chrName, start, end, observer, opts) {
189
+ return __awaiter(this, void 0, void 0, function () {
190
+ var _a, refsByName, bbi, cirTreeOffset, isBigEndian, signal_1, chrId_1, request_1, buffer, cirBlockSize_1, blocksToFetch_1, outstanding_1, cirFobRecur2_1, filterFeats_1, cirFobStartFetch_1, cirFobRecur_1, e_1;
191
+ var _this = this;
192
+ return __generator(this, function (_b) {
193
+ switch (_b.label) {
194
+ case 0:
195
+ _b.trys.push([0, 2, , 3]);
196
+ _a = this, refsByName = _a.refsByName, bbi = _a.bbi, cirTreeOffset = _a.cirTreeOffset, isBigEndian = _a.isBigEndian;
197
+ signal_1 = opts.signal;
198
+ chrId_1 = refsByName[chrName];
199
+ if (chrId_1 === undefined) {
200
+ observer.complete();
201
+ }
202
+ request_1 = { chrId: chrId_1, start: start, end: end };
203
+ if (!this.cirTreePromise) {
204
+ this.cirTreePromise = bbi.read(Buffer.alloc(48), 0, 48, cirTreeOffset, {
205
+ signal: signal_1,
467
206
  });
468
-
469
- case 6:
470
- case "end":
471
- return _context4.stop();
472
207
  }
473
- }
474
- }, _callee4);
475
- }));
476
-
477
- return function (_x13) {
478
- return _ref2.apply(this, arguments);
479
- };
480
- }()));
481
-
482
- case 8:
483
- observer.complete();
484
- _context5.next = 14;
485
- break;
486
-
487
- case 11:
488
- _context5.prev = 11;
489
- _context5.t0 = _context5["catch"](1);
490
- observer.error(_context5.t0);
491
-
492
- case 14:
493
- case "end":
494
- return _context5.stop();
208
+ return [4 /*yield*/, this.cirTreePromise];
209
+ case 1:
210
+ buffer = (_b.sent()).buffer;
211
+ cirBlockSize_1 = isBigEndian
212
+ ? buffer.readUInt32BE(4)
213
+ : buffer.readUInt32LE(4);
214
+ blocksToFetch_1 = [];
215
+ outstanding_1 = 0;
216
+ cirFobRecur2_1 = function (cirBlockData, offset, level) {
217
+ try {
218
+ var data = cirBlockData.subarray(offset);
219
+ var p = _this.leafParser.parse(data).result;
220
+ if (p.blocksToFetch) {
221
+ blocksToFetch_1 = blocksToFetch_1.concat(p.blocksToFetch.filter(filterFeats_1).map(function (l) { return ({
222
+ offset: l.blockOffset,
223
+ length: l.blockSize,
224
+ }); }));
225
+ }
226
+ if (p.recurOffsets) {
227
+ var recurOffsets = p.recurOffsets
228
+ .filter(filterFeats_1)
229
+ .map(function (l) { return l.blockOffset; });
230
+ if (recurOffsets.length > 0) {
231
+ cirFobRecur_1(recurOffsets, level + 1);
232
+ }
233
+ }
234
+ }
235
+ catch (e) {
236
+ observer.error(e);
237
+ }
238
+ };
239
+ filterFeats_1 = function (b) {
240
+ var startChrom = b.startChrom, startBase = b.startBase, endChrom = b.endChrom, endBase = b.endBase;
241
+ return ((startChrom < chrId_1 || (startChrom === chrId_1 && startBase <= end)) &&
242
+ (endChrom > chrId_1 || (endChrom === chrId_1 && endBase >= start)));
243
+ };
244
+ cirFobStartFetch_1 = function (off, fr, level) { return __awaiter(_this, void 0, void 0, function () {
245
+ var length_1, offset, resultBuffer, i, e_2;
246
+ return __generator(this, function (_a) {
247
+ switch (_a.label) {
248
+ case 0:
249
+ _a.trys.push([0, 2, , 3]);
250
+ length_1 = fr.max() - fr.min();
251
+ offset = fr.min();
252
+ return [4 /*yield*/, this.featureCache.get("".concat(length_1, "_").concat(offset), { length: length_1, offset: offset }, signal_1)];
253
+ case 1:
254
+ resultBuffer = _a.sent();
255
+ for (i = 0; i < off.length; i += 1) {
256
+ if (fr.contains(off[i])) {
257
+ cirFobRecur2_1(resultBuffer, off[i] - offset, level);
258
+ outstanding_1 -= 1;
259
+ if (outstanding_1 === 0) {
260
+ this.readFeatures(observer, blocksToFetch_1, __assign(__assign({}, opts), { request: request_1 }));
261
+ }
262
+ }
263
+ }
264
+ return [3 /*break*/, 3];
265
+ case 2:
266
+ e_2 = _a.sent();
267
+ observer.error(e_2);
268
+ return [3 /*break*/, 3];
269
+ case 3: return [2 /*return*/];
270
+ }
271
+ });
272
+ }); };
273
+ cirFobRecur_1 = function (offset, level) {
274
+ try {
275
+ outstanding_1 += offset.length;
276
+ var maxCirBlockSpan = 4 + cirBlockSize_1 * 32; // Upper bound on size, based on a completely full leaf node.
277
+ var spans = new range_1.default(offset[0], offset[0] + maxCirBlockSpan);
278
+ for (var i = 1; i < offset.length; i += 1) {
279
+ var blockSpan = new range_1.default(offset[i], offset[i] + maxCirBlockSpan);
280
+ spans = spans.union(blockSpan);
281
+ }
282
+ spans.getRanges().map(function (fr) { return cirFobStartFetch_1(offset, fr, level); });
283
+ }
284
+ catch (e) {
285
+ observer.error(e);
286
+ }
287
+ };
288
+ return [2 /*return*/, cirFobRecur_1([cirTreeOffset + 48], 1)];
289
+ case 2:
290
+ e_1 = _b.sent();
291
+ observer.error(e_1);
292
+ return [3 /*break*/, 3];
293
+ case 3: return [2 /*return*/];
294
+ }
295
+ });
296
+ });
297
+ };
298
+ BlockView.prototype.parseSummaryBlock = function (data, startOffset, request) {
299
+ var features = [];
300
+ var currOffset = startOffset;
301
+ while (currOffset < data.byteLength) {
302
+ var res = this.summaryParser.parse(data.subarray(currOffset));
303
+ features.push(res.result);
304
+ currOffset += res.offset;
305
+ }
306
+ var items = features;
307
+ if (request) {
308
+ items = items.filter(function (elt) { return elt.chromId === request.chrId; });
309
+ }
310
+ var feats = items.map(function (elt) { return ({
311
+ start: elt.start,
312
+ end: elt.end,
313
+ maxScore: elt.maxScore,
314
+ minScore: elt.minScore,
315
+ score: elt.sumData / (elt.validCnt || 1),
316
+ summary: true,
317
+ }); });
318
+ return request
319
+ ? feats.filter(function (f) { return BlockView.coordFilter(f, request); })
320
+ : feats;
321
+ };
322
+ BlockView.prototype.parseBigBedBlock = function (data, startOffset, offset, request) {
323
+ var items = [];
324
+ var currOffset = startOffset;
325
+ while (currOffset < data.byteLength) {
326
+ var res = this.bigBedParser.parse(data.subarray(currOffset));
327
+ res.result.uniqueId = "bb-".concat(offset + currOffset);
328
+ items.push(res.result);
329
+ currOffset += res.offset;
330
+ }
331
+ return request
332
+ ? items.filter(function (f) { return BlockView.coordFilter(f, request); })
333
+ : items;
334
+ };
335
+ BlockView.prototype.parseBigWigBlock = function (bytes, startOffset, request) {
336
+ var data = bytes.subarray(startOffset);
337
+ var results = this.bigWigParser.parse(data).result;
338
+ var items = results.items, itemSpan = results.itemSpan, itemStep = results.itemStep, blockStart = results.blockStart, blockType = results.blockType;
339
+ if (blockType === BIG_WIG_TYPE_FSTEP) {
340
+ for (var i = 0; i < items.length; i++) {
341
+ items[i].start = blockStart + i * itemStep;
342
+ items[i].end = blockStart + i * itemStep + itemSpan;
495
343
  }
496
- }
497
- }, _callee5, this, [[1, 11]]);
498
- }));
499
-
500
- function readFeatures(_x11, _x12) {
501
- return _readFeatures.apply(this, arguments);
502
- }
503
-
504
- return readFeatures;
505
- }()
506
- }], [{
507
- key: "coordFilter",
508
- value: function coordFilter(f, range) {
509
- return f.start < range.end && f.end >= range.start;
510
- }
511
- }]);
512
- return BlockView;
513
- }();
514
-
344
+ }
345
+ else if (blockType === BIG_WIG_TYPE_VSTEP) {
346
+ for (var i = 0; i < items.length; i++) {
347
+ items[i].end = items[i].start + itemSpan;
348
+ }
349
+ }
350
+ return request
351
+ ? items.filter(function (f) { return BlockView.coordFilter(f, request); })
352
+ : items;
353
+ };
354
+ BlockView.coordFilter = function (f, range) {
355
+ return f.start < range.end && f.end >= range.start;
356
+ };
357
+ BlockView.prototype.readFeatures = function (observer, blocks, opts) {
358
+ if (opts === void 0) { opts = {}; }
359
+ return __awaiter(this, void 0, void 0, function () {
360
+ var _a, blockType_1, isCompressed_1, signal_2, request_2, blockGroupsToFetch, e_3;
361
+ var _this = this;
362
+ return __generator(this, function (_b) {
363
+ switch (_b.label) {
364
+ case 0:
365
+ _b.trys.push([0, 2, , 3]);
366
+ _a = this, blockType_1 = _a.blockType, isCompressed_1 = _a.isCompressed;
367
+ signal_2 = opts.signal, request_2 = opts.request;
368
+ blockGroupsToFetch = (0, util_1.groupBlocks)(blocks);
369
+ (0, util_1.checkAbortSignal)(signal_2);
370
+ return [4 /*yield*/, Promise.all(blockGroupsToFetch.map(function (blockGroup) { return __awaiter(_this, void 0, void 0, function () {
371
+ var length, offset, data;
372
+ var _this = this;
373
+ return __generator(this, function (_a) {
374
+ switch (_a.label) {
375
+ case 0:
376
+ (0, util_1.checkAbortSignal)(signal_2);
377
+ length = blockGroup.length, offset = blockGroup.offset;
378
+ return [4 /*yield*/, this.featureCache.get("".concat(length, "_").concat(offset), blockGroup, signal_2)];
379
+ case 1:
380
+ data = _a.sent();
381
+ blockGroup.blocks.forEach(function (block) {
382
+ (0, util_1.checkAbortSignal)(signal_2);
383
+ var blockOffset = block.offset - blockGroup.offset;
384
+ var resultData = data;
385
+ if (isCompressed_1) {
386
+ resultData = (0, unzip_1.unzip)(data.subarray(blockOffset));
387
+ blockOffset = 0;
388
+ }
389
+ (0, util_1.checkAbortSignal)(signal_2);
390
+ switch (blockType_1) {
391
+ case 'summary':
392
+ observer.next(_this.parseSummaryBlock(resultData, blockOffset, request_2));
393
+ break;
394
+ case 'bigwig':
395
+ observer.next(_this.parseBigWigBlock(resultData, blockOffset, request_2));
396
+ break;
397
+ case 'bigbed':
398
+ observer.next(_this.parseBigBedBlock(resultData, blockOffset,
399
+ // eslint-disable-next-line no-bitwise
400
+ block.offset * (1 << 8), request_2));
401
+ break;
402
+ default:
403
+ console.warn("Don't know what to do with ".concat(blockType_1));
404
+ }
405
+ });
406
+ return [2 /*return*/];
407
+ }
408
+ });
409
+ }); }))];
410
+ case 1:
411
+ _b.sent();
412
+ observer.complete();
413
+ return [3 /*break*/, 3];
414
+ case 2:
415
+ e_3 = _b.sent();
416
+ observer.error(e_3);
417
+ return [3 /*break*/, 3];
418
+ case 3: return [2 /*return*/];
419
+ }
420
+ });
421
+ });
422
+ };
423
+ return BlockView;
424
+ }());
515
425
  exports.BlockView = BlockView;
516
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9ibG9ja1ZpZXcudHMiXSwibmFtZXMiOlsiQklHX1dJR19UWVBFX0dSQVBIIiwiQklHX1dJR19UWVBFX1ZTVEVQIiwiQklHX1dJR19UWVBFX0ZTVEVQIiwiZ2V0UGFyc2VycyIsImlzQmlnRW5kaWFuIiwibGUiLCJzdW1tYXJ5UGFyc2VyIiwiUGFyc2VyIiwiZW5kaWFuZXNzIiwidWludDMyIiwiZmxvYXQiLCJsZWFmUGFyc2VyIiwidWludDgiLCJza2lwIiwidWludDE2IiwiY2hvaWNlIiwidGFnIiwiY2hvaWNlcyIsImFycmF5IiwibGVuZ3RoIiwidHlwZSIsInVpbnQ2NCIsImJpZ0JlZFBhcnNlciIsImludDMyIiwic3RyaW5nIiwiemVyb1Rlcm1pbmF0ZWQiLCJiaWdXaWdQYXJzZXIiLCJCbG9ja1ZpZXciLCJiYmkiLCJyZWZzQnlOYW1lIiwiY2lyVHJlZU9mZnNldCIsImNpclRyZWVMZW5ndGgiLCJpc0NvbXByZXNzZWQiLCJibG9ja1R5cGUiLCJBYm9ydGFibGVQcm9taXNlQ2FjaGUiLCJjYWNoZSIsIlF1aWNrTFJVIiwibWF4U2l6ZSIsImZpbGwiLCJyZXF1ZXN0RGF0YSIsInNpZ25hbCIsIm9mZnNldCIsInJlYWQiLCJCdWZmZXIiLCJhbGxvYyIsImJ1ZmZlciIsIkVycm9yIiwiT2JqZWN0IiwiYXNzaWduIiwiY2hyTmFtZSIsInN0YXJ0IiwiZW5kIiwib2JzZXJ2ZXIiLCJvcHRzIiwiY2hySWQiLCJ1bmRlZmluZWQiLCJjb21wbGV0ZSIsInJlcXVlc3QiLCJjaXJUcmVlUHJvbWlzZSIsImNpckJsb2NrU2l6ZSIsInJlYWRVSW50MzJCRSIsInJlYWRVSW50MzJMRSIsImJsb2Nrc1RvRmV0Y2giLCJvdXRzdGFuZGluZyIsImZpbHRlckZlYXRzIiwiYiIsInN0YXJ0Q2hyb20iLCJzdGFydEJhc2UiLCJlbmRDaHJvbSIsImVuZEJhc2UiLCJjaXJGb2JTdGFydEZldGNoIiwib2ZmIiwiZnIiLCJsZXZlbCIsIm1heCIsIm1pbiIsImZlYXR1cmVDYWNoZSIsImdldCIsInJlc3VsdEJ1ZmZlciIsImkiLCJjb250YWlucyIsImNpckZvYlJlY3VyMiIsInJlYWRGZWF0dXJlcyIsImVycm9yIiwiY2lyRm9iUmVjdXIiLCJtYXhDaXJCbG9ja1NwYW4iLCJzcGFucyIsIlJhbmdlIiwiYmxvY2tTcGFuIiwidW5pb24iLCJnZXRSYW5nZXMiLCJtYXAiLCJlIiwiY2lyQmxvY2tEYXRhIiwiZGF0YSIsInNsaWNlIiwicCIsInBhcnNlIiwicmVzdWx0IiwiY29uY2F0IiwiZmlsdGVyIiwibCIsImJsb2NrT2Zmc2V0IiwiYmxvY2tTaXplIiwicmVjdXJPZmZzZXRzIiwic3RhcnRPZmZzZXQiLCJmZWF0dXJlcyIsImN1cnJPZmZzZXQiLCJieXRlTGVuZ3RoIiwicmVzIiwicHVzaCIsIml0ZW1zIiwiZWx0IiwiY2hyb21JZCIsIm1heFNjb3JlIiwibWluU2NvcmUiLCJzY29yZSIsInN1bURhdGEiLCJ2YWxpZENudCIsInN1bW1hcnkiLCJmIiwiY29vcmRGaWx0ZXIiLCJ1bmlxdWVJZCIsImJ5dGVzIiwicmVzdWx0cyIsIml0ZW1TcGFuIiwiaXRlbVN0ZXAiLCJibG9ja1N0YXJ0IiwiYmxvY2tzIiwiYmxvY2tHcm91cHNUb0ZldGNoIiwiUHJvbWlzZSIsImFsbCIsImJsb2NrR3JvdXAiLCJmb3JFYWNoIiwiYmxvY2siLCJyZXN1bHREYXRhIiwiemxpYiIsImluZmxhdGVTeW5jIiwibmV4dCIsInBhcnNlU3VtbWFyeUJsb2NrIiwicGFyc2VCaWdXaWdCbG9jayIsInBhcnNlQmlnQmVkQmxvY2siLCJjb25zb2xlIiwid2FybiIsInJhbmdlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUE7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBRUE7O0FBQ0E7Ozs7OztBQXNDQSxJQUFNQSxrQkFBa0IsR0FBRyxDQUEzQjtBQUNBLElBQU1DLGtCQUFrQixHQUFHLENBQTNCO0FBQ0EsSUFBTUMsa0JBQWtCLEdBQUcsQ0FBM0I7O0FBRUEsU0FBU0MsVUFBVCxDQUFv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InNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludCBuby1iaXR3aXNlOiBbXCJlcnJvclwiLCB7IFwiYWxsb3dcIjogW1wifFwiXSB9XSAqL1xuaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tICdyeGpzJ1xuaW1wb3J0IHsgUGFyc2VyIH0gZnJvbSAnQGdtb2QvYmluYXJ5LXBhcnNlcidcbmltcG9ydCBBYm9ydGFibGVQcm9taXNlQ2FjaGUgZnJvbSAnYWJvcnRhYmxlLXByb21pc2UtY2FjaGUnXG5pbXBvcnQgeyBHZW5lcmljRmlsZWhhbmRsZSB9IGZyb20gJ2dlbmVyaWMtZmlsZWhhbmRsZSdcbmltcG9ydCB6bGliIGZyb20gJ3psaWInXG5pbXBvcnQgUXVpY2tMUlUgZnJvbSAncXVpY2stbHJ1J1xuaW1wb3J0IHsgRmVhdHVyZSB9IGZyb20gJy4vYmJpJ1xuaW1wb3J0IFJhbmdlIGZyb20gJy4vcmFuZ2UnXG5pbXBvcnQgeyBncm91cEJsb2NrcywgY2hlY2tBYm9ydFNpZ25hbCB9IGZyb20gJy4vdXRpbCdcblxuaW50ZXJmYWNlIENvb3JkUmVxdWVzdCB7XG4gIGNocklkOiBudW1iZXJcbiAgc3RhcnQ6IG51bWJlclxuICBlbmQ6IG51bWJlclxufVxuaW50ZXJmYWNlIERhdGFCbG9jayB7XG4gIHN0YXJ0Q2hyb206IG51bWJlclxuICBlbmRDaHJvbTogbnVtYmVyXG4gIHN0YXJ0QmFzZTogbnVtYmVyXG4gIGVuZEJhc2U6IG51bWJlclxuICB2YWxpZENudDogbnVtYmVyXG4gIG1pblZhbDogbnVtYmVyXG4gIG1heFZhbDogbnVtYmVyXG4gIHN1bURhdGE6IG51bWJlclxuICBzdW1TcURhdGE6IG51bWJlclxufVxuaW50ZXJmYWNlIFJlYWREYXRhIHtcbiAgb2Zmc2V0OiBudW1iZXJcbiAgbGVuZ3RoOiBudW1iZXJcbn1cblxuaW50ZXJmYWNlIFN1bW1hcnlCbG9jayB7XG4gIGNocm9tSWQ6IG51bWJlclxuICBzdGFydDogbnVtYmVyXG4gIGVuZDogbnVtYmVyXG4gIHZhbGlkQ250OiBudW1iZXJcbiAgbWluU2NvcmU6IG51bWJlclxuICBtYXhTY29yZTogbnVtYmVyXG4gIHN1bURhdGE6IG51bWJlclxuICBzdW1TcURhdGE6IG51bWJlclxufVxuaW50ZXJmYWNlIE9wdGlvbnMge1xuICBzaWduYWw/OiBBYm9ydFNpZ25hbFxuICByZXF1ZXN0PzogQ29vcmRSZXF1ZXN0XG59XG5cbmNvbnN0IEJJR19XSUdfVFlQRV9HUkFQSCA9IDFcbmNvbnN0IEJJR19XSUdfVFlQRV9WU1RFUCA9IDJcbmNvbnN0IEJJR19XSUdfVFlQRV9GU1RFUCA9IDNcblxuZnVuY3Rpb24gZ2V0UGFyc2Vycyhpc0JpZ0VuZGlhbjogYm9vbGVhbik6IGFueSB7XG4gIGNvbnN0IGxlID0gaXNCaWdFbmRpYW4gPyAnYmlnJyA6ICdsaXR0bGUnXG4gIGNvbnN0IHN1bW1hcnlQYXJzZXIgPSBuZXcgUGFyc2VyKClcbiAgICAuZW5kaWFuZXNzKGxlKVxuICAgIC51aW50MzIoJ2Nocm9tSWQnKVxuICAgIC51aW50MzIoJ3N0YXJ0JylcbiAgICAudWludDMyKCdlbmQnKVxuICAgIC51aW50MzIoJ3ZhbGlkQ250JylcbiAgICAuZmxvYXQoJ21pblNjb3JlJylcbiAgICAuZmxvYXQoJ21heFNjb3JlJylcbiAgICAuZmxvYXQoJ3N1bURhdGEnKVxuICAgIC5mbG9hdCgnc3VtU3FEYXRhJylcblxuICBjb25zdCBsZWFmUGFyc2VyID0gbmV3IFBhcnNlcigpXG4gICAgLmVuZGlhbmVzcyhsZSlcbiAgICAudWludDgoJ2lzTGVhZicpXG4gICAgLnNraXAoMSlcbiAgICAudWludDE2KCdjbnQnKVxuICAgIC5jaG9pY2Uoe1xuICAgICAgdGFnOiAnaXNMZWFmJyxcbiAgICAgIGNob2ljZXM6IHtcbiAgICAgICAgMTogbmV3IFBhcnNlcigpLmFycmF5KCdibG9ja3NUb0ZldGNoJywge1xuICAgICAgICAgIGxlbmd0aDogJ2NudCcsXG4gICAgICAgICAgdHlwZTogbmV3IFBhcnNlcigpXG4gICAgICAgICAgICAudWludDMyKCdzdGFydENocm9tJylcbiAgICAgICAgICAgIC51aW50MzIoJ3N0YXJ0QmFzZScpXG4gICAgICAgICAgICAudWludDMyKCdlbmRDaHJvbScpXG4gICAgICAgICAgICAudWludDMyKCdlbmRCYXNlJylcbiAgICAgICAgICAgIC51aW50NjQoJ2Jsb2NrT2Zmc2V0JylcbiAgICAgICAgICAgIC51aW50NjQoJ2Jsb2NrU2l6ZScpLFxuICAgICAgICB9KSxcbiAgICAgICAgMDogbmV3IFBhcnNlcigpLmFycmF5KCdyZWN1ck9mZnNldHMnLCB7XG4gICAgICAgICAgbGVuZ3RoOiAnY250JyxcbiAgICAgICAgICB0eXBlOiBuZXcgUGFyc2VyKClcbiAgICAgICAgICAgIC51aW50MzIoJ3N0YXJ0Q2hyb20nKVxuICAgICAgICAgICAgLnVpbnQzMignc3RhcnRCYXNlJylcbiAgICAgICAgICAgIC51aW50MzIoJ2VuZENocm9tJylcbiAgICAgICAgICAgIC51aW50MzIoJ2VuZEJhc2UnKVxuICAgICAgICAgICAgLnVpbnQ2NCgnYmxvY2tPZmZzZXQnKSxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH0pXG4gIGNvbnN0IGJpZ0JlZFBhcnNlciA9IG5ldyBQYXJzZXIoKVxuICAgIC5lbmRpYW5lc3MobGUpXG4gICAgLnVpbnQzMignY2hyb21JZCcpXG4gICAgLmludDMyKCdzdGFydCcpXG4gICAgLmludDMyKCdlbmQnKVxuICAgIC5zdHJpbmcoJ3Jlc3QnLCB7XG4gICAgICB6ZXJvVGVybWluYXRlZDogdHJ1ZSxcbiAgICB9KVxuXG4gIGNvbnN0IGJpZ1dpZ1BhcnNlciA9IG5ldyBQYXJzZXIoKVxuICAgIC5lbmRpYW5lc3MobGUpXG4gICAgLnNraXAoNClcbiAgICAuaW50MzIoJ2Jsb2NrU3RhcnQnKVxuICAgIC5za2lwKDQpXG4gICAgLnVpbnQzMignaXRlbVN0ZXAnKVxuICAgIC51aW50MzIoJ2l0ZW1TcGFuJylcbiAgICAudWludDgoJ2Jsb2NrVHlwZScpXG4gICAgLnNraXAoMSlcbiAgICAudWludDE2KCdpdGVtQ291bnQnKVxuICAgIC5jaG9pY2Uoe1xuICAgICAgdGFnOiAnYmxvY2tUeXBlJyxcbiAgICAgIGNob2ljZXM6IHtcbiAgICAgICAgW0JJR19XSUdfVFlQRV9GU1RFUF06IG5ldyBQYXJzZXIoKS5hcnJheSgnaXRlbXMnLCB7XG4gICAgICAgICAgbGVuZ3RoOiAnaXRlbUNvdW50JyxcbiAgICAgICAgICB0eXBlOiBuZXcgUGFyc2VyKCkuZmxvYXQoJ3Njb3JlJyksXG4gICAgICAgIH0pLFxuICAgICAgICBbQklHX1dJR19UWVBFX1ZTVEVQXTogbmV3IFBhcnNlcigpLmFycmF5KCdpdGVtcycsIHtcbiAgICAgICAgICBsZW5ndGg6ICdpdGVtQ291bnQnLFxuICAgICAgICAgIHR5cGU6IG5ldyBQYXJzZXIoKS5pbnQzMignc3RhcnQnKS5mbG9hdCgnc2NvcmUnKSxcbiAgICAgICAgfSksXG4gICAgICAgIFtCSUdfV0lHX1RZUEVfR1JBUEhdOiBuZXcgUGFyc2VyKCkuYXJyYXkoJ2l0ZW1zJywge1xuICAgICAgICAgIGxlbmd0aDogJ2l0ZW1Db3VudCcsXG4gICAgICAgICAgdHlwZTogbmV3IFBhcnNlcigpXG4gICAgICAgICAgICAuaW50MzIoJ3N0YXJ0JylcbiAgICAgICAgICAgIC5pbnQzMignZW5kJylcbiAgICAgICAgICAgIC5mbG9hdCgnc2NvcmUnKSxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH0pXG4gIHJldHVybiB7XG4gICAgYmlnV2lnUGFyc2VyLFxuICAgIGJpZ0JlZFBhcnNlcixcbiAgICBzdW1tYXJ5UGFyc2VyLFxuICAgIGxlYWZQYXJzZXIsXG4gIH1cbn1cblxuLyoqXG4gKiBWaWV3IGludG8gYSBzdWJzZXQgb2YgdGhlIGRhdGEgaW4gYSBCaWdXaWcgZmlsZS5cbiAqXG4gKiBBZGFwdGVkIGJ5IFJvYmVydCBCdWVscyBhbmQgQ29saW4gRGllc2ggZnJvbSBiaWd3aWcuanMgaW4gdGhlIERhbGxpYW5jZSBHZW5vbWVcbiAqIEV4cGxvcmVyIGJ5IFRob21hcyBEb3duLlxuICogQGNvbnN0cnVjdHNcbiAqL1xuXG5leHBvcnQgY2xhc3MgQmxvY2tWaWV3IHtcbiAgcHJpdmF0ZSBjaXJUcmVlT2Zmc2V0OiBudW1iZXJcblxuICBwcml2YXRlIGNpclRyZWVMZW5ndGg6IG51bWJlclxuXG4gIHByaXZhdGUgYmJpOiBHZW5lcmljRmlsZWhhbmRsZVxuXG4gIHByaXZhdGUgaXNDb21wcmVzc2VkOiBib29sZWFuXG5cbiAgcHJpdmF0ZSBpc0JpZ0VuZGlhbjogYm9vbGVhblxuXG4gIHByaXZhdGUgcmVmc0J5TmFtZTogYW55XG5cbiAgcHJpdmF0ZSBibG9ja1R5cGU6IHN0cmluZ1xuXG4gIHByaXZhdGUgY2lyVHJlZVByb21pc2U/OiBQcm9taXNlPHsgYnl0ZXNSZWFkOiBudW1iZXI7IGJ1ZmZlcjogQnVmZmVyIH0+XG5cbiAgcHJpdmF0ZSBmZWF0dXJlQ2FjaGUgPSBuZXcgQWJvcnRhYmxlUHJvbWlzZUNhY2hlKHtcbiAgICBjYWNoZTogbmV3IFF1aWNrTFJVKHsgbWF4U2l6ZTogMTAwMCB9KSxcblxuICAgIGZpbGw6IGFzeW5jIChyZXF1ZXN0RGF0YTogUmVhZERhdGEsIHNpZ25hbDogQWJvcnRTaWduYWwpID0+IHtcbiAgICAgIGNvbnN0IHsgbGVuZ3RoLCBvZmZzZXQgfSA9IHJlcXVlc3REYXRhXG4gICAgICBjb25zdCB7IGJ1ZmZlciB9ID0gYXdhaXQgdGhpcy5iYmkucmVhZChCdWZmZXIuYWxsb2MobGVuZ3RoKSwgMCwgbGVuZ3RoLCBvZmZzZXQsIHsgc2lnbmFsIH0pXG4gICAgICByZXR1cm4gYnVmZmVyXG4gICAgfSxcbiAgfSlcblxuICBwcml2YXRlIGxlYWZQYXJzZXI6IGFueVxuXG4gIHByaXZhdGUgYmlnV2lnUGFyc2VyOiBhbnlcblxuICBwcml2YXRlIGJpZ0JlZFBhcnNlcjogYW55XG5cbiAgcHJpdmF0ZSBzdW1tYXJ5UGFyc2VyOiBhbnlcblxuICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgYmJpOiBHZW5lcmljRmlsZWhhbmRsZSxcbiAgICByZWZzQnlOYW1lOiBhbnksXG4gICAgY2lyVHJlZU9mZnNldDogbnVtYmVyLFxuICAgIGNpclRyZWVMZW5ndGg6IG51bWJlcixcbiAgICBpc0JpZ0VuZGlhbjogYm9vbGVhbixcbiAgICBpc0NvbXByZXNzZWQ6IGJvb2xlYW4sXG4gICAgYmxvY2tUeXBlOiBzdHJpbmcsXG4gICkge1xuICAgIGlmICghKGNpclRyZWVPZmZzZXQgPj0gMCkpIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBjaXJUcmVlT2Zmc2V0IScpXG4gICAgaWYgKCEoY2lyVHJlZUxlbmd0aCA+IDApKSB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgY2lyVHJlZUxlbmd0aCEnKVxuXG4gICAgdGhpcy5jaXJUcmVlT2Zmc2V0ID0gY2lyVHJlZU9mZnNldFxuICAgIHRoaXMuY2lyVHJlZUxlbmd0aCA9IGNpclRyZWVMZW5ndGhcbiAgICB0aGlzLmlzQ29tcHJlc3NlZCA9IGlzQ29tcHJlc3NlZFxuICAgIHRoaXMucmVmc0J5TmFtZSA9IHJlZnNCeU5hbWVcbiAgICB0aGlzLmlzQmlnRW5kaWFuID0gaXNCaWdFbmRpYW5cbiAgICB0aGlzLmJiaSA9IGJiaVxuICAgIHRoaXMuYmxvY2tUeXBlID0gYmxvY2tUeXBlXG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBnZXRQYXJzZXJzKGlzQmlnRW5kaWFuKSlcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyByZWFkV2lnRGF0YShcbiAgICBjaHJOYW1lOiBzdHJpbmcsXG4gICAgc3RhcnQ6IG51bWJlcixcbiAgICBlbmQ6IG51bWJlcixcbiAgICBvYnNlcnZlcjogT2JzZXJ2ZXI8RmVhdHVyZVtdPixcbiAgICBvcHRzOiBPcHRpb25zLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyByZWZzQnlOYW1lLCBiYmksIGNpclRyZWVPZmZzZXQsIGlzQmlnRW5kaWFuIH0gPSB0aGlzXG4gICAgICBjb25zdCB7IHNpZ25hbCB9ID0gb3B0c1xuICAgICAgY29uc3QgY2hySWQgPSByZWZzQnlOYW1lW2Nock5hbWVdXG4gICAgICBpZiAoY2hySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpXG4gICAgICB9XG4gICAgICBjb25zdCByZXF1ZXN0ID0geyBjaHJJZCwgc3RhcnQsIGVuZCB9XG4gICAgICBpZiAoIXRoaXMuY2lyVHJlZVByb21pc2UpIHtcbiAgICAgICAgdGhpcy5jaXJUcmVlUHJvbWlzZSA9IGJiaS5yZWFkKEJ1ZmZlci5hbGxvYyg0OCksIDAsIDQ4LCBjaXJUcmVlT2Zmc2V0LCB7IHNpZ25hbCB9KVxuICAgICAgfVxuICAgICAgY29uc3QgeyBidWZmZXIgfSA9IGF3YWl0IHRoaXMuY2lyVHJlZVByb21pc2VcbiAgICAgIGNvbnN0IGNpckJsb2NrU2l6ZSA9IGlzQmlnRW5kaWFuID8gYnVmZmVyLnJlYWRVSW50MzJCRSg0KSA6IGJ1ZmZlci5yZWFkVUludDMyTEUoNClcbiAgICAgIGxldCBibG9ja3NUb0ZldGNoOiBhbnlbXSA9IFtdXG4gICAgICBsZXQgb3V0c3RhbmRpbmcgPSAwXG5cbiAgICAgIC8vZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdFxuICAgICAgbGV0IGNpckZvYlJlY3VyMjogRnVuY3Rpb25cblxuICAgICAgY29uc3QgZmlsdGVyRmVhdHMgPSAoYjogRGF0YUJsb2NrKTogYm9vbGVhbiA9PlxuICAgICAgICAoYi5zdGFydENocm9tIDwgY2hySWQgfHwgKGIuc3RhcnRDaHJvbSA9PT0gY2hySWQgJiYgYi5zdGFydEJhc2UgPD0gZW5kKSkgJiZcbiAgICAgICAgKGIuZW5kQ2hyb20gPiBjaHJJZCB8fCAoYi5lbmRDaHJvbSA9PT0gY2hySWQgJiYgYi5lbmRCYXNlID49IHN0YXJ0KSlcblxuICAgICAgY29uc3QgY2lyRm9iU3RhcnRGZXRjaCA9IGFzeW5jIChvZmY6IGFueSwgZnI6IGFueSwgbGV2ZWw6IG51bWJlcik6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IGZyLm1heCgpIC0gZnIubWluKClcbiAgICAgICAgICBjb25zdCBvZmZzZXQgPSBmci5taW4oKVxuICAgICAgICAgIGNvbnN0IHJlc3VsdEJ1ZmZlciA9IGF3YWl0IHRoaXMuZmVhdHVyZUNhY2hlLmdldChcbiAgICAgICAgICAgIGAke2xlbmd0aH1fJHtvZmZzZXR9YCxcbiAgICAgICAgICAgIHsgbGVuZ3RoLCBvZmZzZXQgfSxcbiAgICAgICAgICAgIHNpZ25hbCxcbiAgICAgICAgICApXG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvZmYubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGlmIChmci5jb250YWlucyhvZmZbaV0pKSB7XG4gICAgICAgICAgICAgIGNpckZvYlJlY3VyMihyZXN1bHRCdWZmZXIsIG9mZltpXSAtIG9mZnNldCwgbGV2ZWwsIG9ic2VydmVyLCBvcHRzKVxuICAgICAgICAgICAgICBvdXRzdGFuZGluZyAtPSAxXG4gICAgICAgICAgICAgIGlmIChvdXRzdGFuZGluZyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVhZEZlYXR1cmVzKG9ic2VydmVyLCBibG9ja3NUb0ZldGNoLCB7IC4uLm9wdHMsIHJlcXVlc3QgfSlcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIG9ic2VydmVyLmVycm9yKGUpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IGNpckZvYlJlY3VyID0gKG9mZnNldDogYW55LCBsZXZlbDogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgb3V0c3RhbmRpbmcgKz0gb2Zmc2V0Lmxlbmd0aFxuXG4gICAgICAgICAgY29uc3QgbWF4Q2lyQmxvY2tTcGFuID0gNCArIGNpckJsb2NrU2l6ZSAqIDMyIC8vIFVwcGVyIGJvdW5kIG9uIHNpemUsIGJhc2VkIG9uIGEgY29tcGxldGVseSBmdWxsIGxlYWYgbm9kZS5cbiAgICAgICAgICBsZXQgc3BhbnMgPSBuZXcgUmFuZ2Uob2Zmc2V0WzBdLCBvZmZzZXRbMF0gKyBtYXhDaXJCbG9ja1NwYW4pXG4gICAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBvZmZzZXQubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IGJsb2NrU3BhbiA9IG5ldyBSYW5nZShvZmZzZXRbaV0sIG9mZnNldFtpXSArIG1heENpckJsb2NrU3BhbilcbiAgICAgICAgICAgIHNwYW5zID0gc3BhbnMudW5pb24oYmxvY2tTcGFuKVxuICAgICAgICAgIH1cbiAgICAgICAgICBzcGFucy5nZXRSYW5nZXMoKS5tYXAoKGZyOiBSYW5nZSkgPT4gY2lyRm9iU3RhcnRGZXRjaChvZmZzZXQsIGZyLCBsZXZlbCkpXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBvYnNlcnZlci5lcnJvcihlKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNpckZvYlJlY3VyMiA9IChjaXJCbG9ja0RhdGE6IEJ1ZmZlciwgb2Zmc2V0OiBudW1iZXIsIGxldmVsOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gY2lyQmxvY2tEYXRhLnNsaWNlKG9mZnNldClcblxuICAgICAgICAgIGNvbnN0IHAgPSB0aGlzLmxlYWZQYXJzZXIucGFyc2UoZGF0YSkucmVzdWx0XG4gICAgICAgICAgaWYgKHAuYmxvY2tzVG9GZXRjaCkge1xuICAgICAgICAgICAgYmxvY2tzVG9GZXRjaCA9IGJsb2Nrc1RvRmV0Y2guY29uY2F0KFxuICAgICAgICAgICAgICBwLmJsb2Nrc1RvRmV0Y2hcbiAgICAgICAgICAgICAgICAuZmlsdGVyKGZpbHRlckZlYXRzKVxuICAgICAgICAgICAgICAgIC5tYXAoKGw6IGFueSk6IGFueSA9PiAoeyBvZmZzZXQ6IGwuYmxvY2tPZmZzZXQsIGxlbmd0aDogbC5ibG9ja1NpemUgfSkpLFxuICAgICAgICAgICAgKVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocC5yZWN1ck9mZnNldHMpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlY3VyT2Zmc2V0cyA9IHAucmVjdXJPZmZzZXRzXG4gICAgICAgICAgICAgIC5maWx0ZXIoZmlsdGVyRmVhdHMpXG4gICAgICAgICAgICAgIC5tYXAoKGw6IGFueSk6IGFueSA9PiBsLmJsb2NrT2Zmc2V0KVxuICAgICAgICAgICAgaWYgKHJlY3VyT2Zmc2V0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIGNpckZvYlJlY3VyKHJlY3VyT2Zmc2V0cywgbGV2ZWwgKyAxKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIG9ic2VydmVyLmVycm9yKGUpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNpckZvYlJlY3VyKFtjaXJUcmVlT2Zmc2V0ICsgNDhdLCAxKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIG9ic2VydmVyLmVycm9yKGUpXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVN1bW1hcnlCbG9jayhkYXRhOiBCdWZmZXIsIHN0YXJ0T2Zmc2V0OiBudW1iZXIsIHJlcXVlc3Q/OiBDb29yZFJlcXVlc3QpOiBGZWF0dXJlW10ge1xuICAgIGNvbnN0IGZlYXR1cmVzID0gW11cbiAgICBsZXQgY3Vyck9mZnNldCA9IHN0YXJ0T2Zmc2V0XG4gICAgd2hpbGUgKGN1cnJPZmZzZXQgPCBkYXRhLmJ5dGVMZW5ndGgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IHRoaXMuc3VtbWFyeVBhcnNlci5wYXJzZShkYXRhLnNsaWNlKGN1cnJPZmZzZXQpKVxuICAgICAgZmVhdHVyZXMucHVzaChyZXMucmVzdWx0KVxuICAgICAgY3Vyck9mZnNldCArPSByZXMub2Zmc2V0XG4gICAgfVxuICAgIGxldCBpdGVtcyA9IGZlYXR1cmVzXG4gICAgaWYgKHJlcXVlc3QpIGl0ZW1zID0gaXRlbXMuZmlsdGVyKChlbHQ6IFN1bW1hcnlCbG9jayk6IGJvb2xlYW4gPT4gZWx0LmNocm9tSWQgPT09IHJlcXVlc3QuY2hySWQpXG4gICAgaXRlbXMgPSBpdGVtcy5tYXAoXG4gICAgICAoZWx0OiBTdW1tYXJ5QmxvY2spOiBGZWF0dXJlID0+ICh7XG4gICAgICAgIHN0YXJ0OiBlbHQuc3RhcnQsXG4gICAgICAgIGVuZDogZWx0LmVuZCxcbiAgICAgICAgbWF4U2NvcmU6IGVsdC5tYXhTY29yZSxcbiAgICAgICAgbWluU2NvcmU6IGVsdC5taW5TY29yZSxcbiAgICAgICAgc2NvcmU6IGVsdC5zdW1EYXRhIC8gKGVsdC52YWxpZENudCB8fCAxKSxcbiAgICAgICAgc3VtbWFyeTogdHJ1ZSxcbiAgICAgIH0pLFxuICAgIClcbiAgICByZXR1cm4gcmVxdWVzdCA/IGl0ZW1zLmZpbHRlcihmID0+IEJsb2NrVmlldy5jb29yZEZpbHRlcihmLCByZXF1ZXN0KSkgOiBpdGVtc1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUJpZ0JlZEJsb2NrKFxuICAgIGRhdGE6IEJ1ZmZlcixcbiAgICBzdGFydE9mZnNldDogbnVtYmVyLFxuICAgIG9mZnNldDogbnVtYmVyLFxuICAgIHJlcXVlc3Q/OiBDb29yZFJlcXVlc3QsXG4gICk6IEZlYXR1cmVbXSB7XG4gICAgY29uc3QgaXRlbXMgPSBbXVxuICAgIGxldCBjdXJyT2Zmc2V0ID0gc3RhcnRPZmZzZXRcbiAgICB3aGlsZSAoY3Vyck9mZnNldCA8IGRhdGEuYnl0ZUxlbmd0aCkge1xuICAgICAgY29uc3QgcmVzID0gdGhpcy5iaWdCZWRQYXJzZXIucGFyc2UoZGF0YS5zbGljZShjdXJyT2Zmc2V0KSlcbiAgICAgIHJlcy5yZXN1bHQudW5pcXVlSWQgPSBgYmItJHtvZmZzZXQgKyBjdXJyT2Zmc2V0fWBcbiAgICAgIGl0ZW1zLnB1c2gocmVzLnJlc3VsdClcbiAgICAgIGN1cnJPZmZzZXQgKz0gcmVzLm9mZnNldFxuICAgIH1cblxuICAgIHJldHVybiByZXF1ZXN0ID8gaXRlbXMuZmlsdGVyKChmOiBhbnkpID0+IEJsb2NrVmlldy5jb29yZEZpbHRlcihmLCByZXF1ZXN0KSkgOiBpdGVtc1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUJpZ1dpZ0Jsb2NrKGJ5dGVzOiBCdWZmZXIsIHN0YXJ0T2Zmc2V0OiBudW1iZXIsIHJlcXVlc3Q/OiBDb29yZFJlcXVlc3QpOiBGZWF0dXJlW10ge1xuICAgIGNvbnN0IGRhdGEgPSBieXRlcy5zbGljZShzdGFydE9mZnNldClcbiAgICBjb25zdCByZXN1bHRzID0gdGhpcy5iaWdXaWdQYXJzZXIucGFyc2UoZGF0YSkucmVzdWx0XG4gICAgY29uc3QgeyBpdGVtcywgaXRlbVNwYW4sIGl0ZW1TdGVwLCBibG9ja1N0YXJ0LCBibG9ja1R5cGUgfSA9IHJlc3VsdHNcbiAgICBpZiAoYmxvY2tUeXBlID09PSBCSUdfV0lHX1RZUEVfRlNURVApIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaXRlbXNbaV0uc3RhcnQgPSBibG9ja1N0YXJ0ICsgaSAqIGl0ZW1TdGVwXG4gICAgICAgIGl0ZW1zW2ldLmVuZCA9IGJsb2NrU3RhcnQgKyBpICogaXRlbVN0ZXAgKyBpdGVtU3BhblxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYmxvY2tUeXBlID09PSBCSUdfV0lHX1RZUEVfVlNURVApIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaXRlbXNbaV0uZW5kID0gaXRlbXNbaV0uc3RhcnQgKyBpdGVtU3BhblxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVxdWVzdCA/IGl0ZW1zLmZpbHRlcigoZjogYW55KSA9PiBCbG9ja1ZpZXcuY29vcmRGaWx0ZXIoZiwgcmVxdWVzdCkpIDogaXRlbXNcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGNvb3JkRmlsdGVyKGY6IEZlYXR1cmUsIHJhbmdlOiBDb29yZFJlcXVlc3QpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZi5zdGFydCA8IHJhbmdlLmVuZCAmJiBmLmVuZCA+PSByYW5nZS5zdGFydFxuICB9XG5cbiAgcHVibGljIGFzeW5jIHJlYWRGZWF0dXJlcyhcbiAgICBvYnNlcnZlcjogT2JzZXJ2ZXI8RmVhdHVyZVtdPixcbiAgICBibG9ja3M6IGFueSxcbiAgICBvcHRzOiBPcHRpb25zID0ge30sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGJsb2NrVHlwZSwgaXNDb21wcmVzc2VkIH0gPSB0aGlzXG4gICAgICBjb25zdCB7IHNpZ25hbCwgcmVxdWVzdCB9ID0gb3B0c1xuICAgICAgY29uc3QgYmxvY2tHcm91cHNUb0ZldGNoID0gZ3JvdXBCbG9ja3MoYmxvY2tzKVxuICAgICAgY2hlY2tBYm9ydFNpZ25hbChzaWduYWwpXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgYmxvY2tHcm91cHNUb0ZldGNoLm1hcChhc3luYyAoYmxvY2tHcm91cDogYW55KSA9PiB7XG4gICAgICAgICAgY2hlY2tBYm9ydFNpZ25hbChzaWduYWwpXG4gICAgICAgICAgY29uc3QgeyBsZW5ndGgsIG9mZnNldCB9ID0gYmxvY2tHcm91cFxuICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmZlYXR1cmVDYWNoZS5nZXQoYCR7bGVuZ3RofV8ke29mZnNldH1gLCBibG9ja0dyb3VwLCBzaWduYWwpXG4gICAgICAgICAgYmxvY2tHcm91cC5ibG9ja3MuZm9yRWFjaCgoYmxvY2s6IGFueSkgPT4ge1xuICAgICAgICAgICAgY2hlY2tBYm9ydFNpZ25hbChzaWduYWwpXG4gICAgICAgICAgICBsZXQgYmxvY2tPZmZzZXQgPSBibG9jay5vZmZzZXQgLSBibG9ja0dyb3VwLm9mZnNldFxuICAgICAgICAgICAgbGV0IHJlc3VsdERhdGEgPSBkYXRhXG4gICAgICAgICAgICBpZiAoaXNDb21wcmVzc2VkKSB7XG4gICAgICAgICAgICAgIHJlc3VsdERhdGEgPSB6bGliLmluZmxhdGVTeW5jKGRhdGEuc2xpY2UoYmxvY2tPZmZzZXQpKVxuICAgICAgICAgICAgICBibG9ja09mZnNldCA9IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNoZWNrQWJvcnRTaWduYWwoc2lnbmFsKVxuXG4gICAgICAgICAgICBzd2l0Y2ggKGJsb2NrVHlwZSkge1xuICAgICAgICAgICAgICBjYXNlICdzdW1tYXJ5JzpcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KHRoaXMucGFyc2VTdW1tYXJ5QmxvY2socmVzdWx0RGF0YSwgYmxvY2tPZmZzZXQsIHJlcXVlc3QpKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIGNhc2UgJ2JpZ3dpZyc6XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dCh0aGlzLnBhcnNlQmlnV2lnQmxvY2socmVzdWx0RGF0YSwgYmxvY2tPZmZzZXQsIHJlcXVlc3QpKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIGNhc2UgJ2JpZ2JlZCc6XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChcbiAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgICAgICAgICAgICAgICB0aGlzLnBhcnNlQmlnQmVkQmxvY2socmVzdWx0RGF0YSwgYmxvY2tPZmZzZXQsIGJsb2NrLm9mZnNldCAqICgxIDw8IDgpLCByZXF1ZXN0KSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYERvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoICR7YmxvY2tUeXBlfWApXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgfSksXG4gICAgICApXG4gICAgICBvYnNlcnZlci5jb21wbGV0ZSgpXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgb2JzZXJ2ZXIuZXJyb3IoZSlcbiAgICB9XG4gIH1cbn1cbiJdfQ==