1(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.GlslEditor = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ 2module.exports = { "default": _dereq_("core-js/library/fn/get-iterator"), __esModule: true }; 3},{"core-js/library/fn/get-iterator":32}],2:[function(_dereq_,module,exports){ 4module.exports = { "default": _dereq_("core-js/library/fn/object/assign"), __esModule: true }; 5},{"core-js/library/fn/object/assign":33}],3:[function(_dereq_,module,exports){ 6module.exports = { "default": _dereq_("core-js/library/fn/object/create"), __esModule: true }; 7},{"core-js/library/fn/object/create":34}],4:[function(_dereq_,module,exports){ 8module.exports = { "default": _dereq_("core-js/library/fn/object/define-property"), __esModule: true }; 9},{"core-js/library/fn/object/define-property":35}],5:[function(_dereq_,module,exports){ 10module.exports = { "default": _dereq_("core-js/library/fn/object/get-own-property-descriptor"), __esModule: true }; 11},{"core-js/library/fn/object/get-own-property-descriptor":36}],6:[function(_dereq_,module,exports){ 12module.exports = { "default": _dereq_("core-js/library/fn/object/keys"), __esModule: true }; 13},{"core-js/library/fn/object/keys":37}],7:[function(_dereq_,module,exports){ 14module.exports = { "default": _dereq_("core-js/library/fn/object/set-prototype-of"), __esModule: true }; 15},{"core-js/library/fn/object/set-prototype-of":38}],8:[function(_dereq_,module,exports){ 16module.exports = { "default": _dereq_("core-js/library/fn/promise"), __esModule: true }; 17},{"core-js/library/fn/promise":39}],9:[function(_dereq_,module,exports){ 18module.exports = { "default": _dereq_("core-js/library/fn/set"), __esModule: true }; 19},{"core-js/library/fn/set":40}],10:[function(_dereq_,module,exports){ 20"use strict"; 21 22exports["default"] = function (instance, Constructor) { 23 if (!(instance instanceof Constructor)) { 24 throw new TypeError("Cannot call a class as a function"); 25 } 26}; 27 28exports.__esModule = true; 29},{}],11:[function(_dereq_,module,exports){ 30"use strict"; 31 32var _Object$defineProperty = _dereq_("babel-runtime/core-js/object/define-property")["default"]; 33 34exports["default"] = (function () { 35 function defineProperties(target, props) { 36 for (var i = 0; i < props.length; i++) { 37 var descriptor = props[i]; 38 descriptor.enumerable = descriptor.enumerable || false; 39 descriptor.configurable = true; 40 if ("value" in descriptor) descriptor.writable = true; 41 42 _Object$defineProperty(target, descriptor.key, descriptor); 43 } 44 } 45 46 return function (Constructor, protoProps, staticProps) { 47 if (protoProps) defineProperties(Constructor.prototype, protoProps); 48 if (staticProps) defineProperties(Constructor, staticProps); 49 return Constructor; 50 }; 51})(); 52 53exports.__esModule = true; 54},{"babel-runtime/core-js/object/define-property":4}],12:[function(_dereq_,module,exports){ 55"use strict"; 56 57var _Object$getOwnPropertyDescriptor = _dereq_("babel-runtime/core-js/object/get-own-property-descriptor")["default"]; 58 59exports["default"] = function get(_x, _x2, _x3) { 60 var _again = true; 61 62 _function: while (_again) { 63 var object = _x, 64 property = _x2, 65 receiver = _x3; 66 _again = false; 67 if (object === null) object = Function.prototype; 68 69 var desc = _Object$getOwnPropertyDescriptor(object, property); 70 71 if (desc === undefined) { 72 var parent = Object.getPrototypeOf(object); 73 74 if (parent === null) { 75 return undefined; 76 } else { 77 _x = parent; 78 _x2 = property; 79 _x3 = receiver; 80 _again = true; 81 desc = parent = undefined; 82 continue _function; 83 } 84 } else if ("value" in desc) { 85 return desc.value; 86 } else { 87 var getter = desc.get; 88 89 if (getter === undefined) { 90 return undefined; 91 } 92 93 return getter.call(receiver); 94 } 95 } 96}; 97 98exports.__esModule = true; 99},{"babel-runtime/core-js/object/get-own-property-descriptor":5}],13:[function(_dereq_,module,exports){ 100"use strict"; 101
102var _Object$create = _dereq_("babel-runtime/core-js/object/create")["default"]; 103 104var _Object$setPrototypeOf = _dereq_("babel-runtime/core-js/object/set-prototype-of")["default"]; 105 106exports["default"] = function (subClass, superClass) { 107 if (typeof superClass !== "function" && superClass !== null) { 108 throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); 109 } 110 111 subClass.prototype = _Object$create(superClass && superClass.prototype, { 112 constructor: { 113 value: subClass, 114 enumerable: false, 115 writable: true, 116 configurable: true 117 } 118 }); 119 if (superClass) _Object$setPrototypeOf ? _Object$setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; 120}; 121 122exports.__esModule = true; 123},{"babel-runtime/core-js/object/create":3,"babel-runtime/core-js/object/set-prototype-of":7}],14:[function(_dereq_,module,exports){ 124"use strict"; 125 126exports["default"] = function (obj) { 127 return obj && obj.__esModule ? obj : { 128 "default": obj 129 }; 130}; 131 132exports.__esModule = true; 133},{}],15:[function(_dereq_,module,exports){ 134// CodeMirror, copyright (c) by Marijn Haverbeke and others 135// Distributed under an MIT license: http://codemirror.net/LICENSE 136 137(function(mod) { 138 if (typeof exports == "object" && typeof module == "object") // CommonJS 139 mod(_dereq_("../../lib/codemirror")); 140 else if (typeof define == "function" && define.amd) // AMD 141 define(["../../lib/codemirror"], mod); 142 else // Plain browser env 143 mod(CodeMirror); 144})(function(CodeMirror) { 145 "use strict"; 146 147 var noOptions = {}; 148 var nonWS = /[^\s\u00a0]/; 149 var Pos = CodeMirror.Pos; 150 151 function firstNonWS(str) { 152 var found = str.search(nonWS); 153 return found == -1 ? 0 : found; 154 } 155 156 CodeMirror.commands.toggleComment = function(cm) { 157 cm.toggleComment(); 158 }; 159 160 CodeMirror.defineExtension("toggleComment", function(options) { 161 if (!options) options = noOptions; 162 var cm = this; 163 var minLine = Infinity, ranges = this.listSelections(), mode = null; 164 for (var i = ranges.length - 1; i >= 0; i--) { 165 var from = ranges[i].from(), to = ranges[i].to(); 166 if (from.line >= minLine) continue; 167 if (to.line >= minLine) to = Pos(minLine, 0); 168 minLine = from.line; 169 if (mode == null) { 170 if (cm.uncomment(from, to, options)) mode = "un"; 171 else { cm.lineComment(from, to, options); mode = "line"; } 172 } else if (mode == "un") { 173 cm.uncomment(from, to, options); 174 } else { 175 cm.lineComment(from, to, options); 176 } 177 } 178 }); 179 180 CodeMirror.defineExtension("lineComment", function(from, to, options) { 181 if (!options) options = noOptions; 182 var self = this, mode = self.getModeAt(from); 183 var commentString = options.lineComment || mode.lineComment; 184 if (!commentString) { 185 if (options.blockCommentStart || mode.blockCommentStart) { 186 options.fullLines = true; 187 self.blockComment(from, to, options); 188 } 189 return; 190 } 191 var firstLine = self.getLine(from.line); 192 if (firstLine == null) return; 193 var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1); 194 var pad = options.padding == null ? " " : options.padding; 195 var blankLines = options.commentBlankLines || from.line == to.line; 196 197 self.operation(function() { 198 if (options.indent) { 199 var baseString = null; 200 for (var i = from.line; i < end; ++i) { 201 var line = self.getLine(i); 202 var whitespace = line.slice(0, firstNonWS(line)); 203 if (baseString == null || baseString.length > whitespace.length) { 204 baseString = whitespace; 205 } 206 } 207 for (var i = from.line; i < end; ++i) { 208 var line = self.getLine(i), cut = baseString.length; 209 if (!blankLines && !nonWS.test(line)) continue; 210 if (line.slice(0, cut) != baseString) cut = firstNonWS(line); 211 self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut)); 212 } 213 } else { 214 for (var i = from.line; i < end; ++i) {
215 if (blankLines || nonWS.test(self.getLine(i))) 216 self.replaceRange(commentString + pad, Pos(i, 0)); 217 } 218 } 219 }); 220 }); 221 222 CodeMirror.defineExtension("blockComment", function(from, to, options) { 223 if (!options) options = noOptions; 224 var self = this, mode = self.getModeAt(from); 225 var startString = options.blockCommentStart || mode.blockCommentStart; 226 var endString = options.blockCommentEnd || mode.blockCommentEnd; 227 if (!startString || !endString) { 228 if ((options.lineComment || mode.lineComment) && options.fullLines != false) 229 self.lineComment(from, to, options); 230 return; 231 } 232 233 var end = Math.min(to.line, self.lastLine()); 234 if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end; 235 236 var pad = options.padding == null ? " " : options.padding; 237 if (from.line > end) return; 238 239 self.operation(function() { 240 if (options.fullLines != false) { 241 var lastLineHasText = nonWS.test(self.getLine(end)); 242 self.replaceRange(pad + endString, Pos(end)); 243 self.replaceRange(startString + pad, Pos(from.line, 0)); 244 var lead = options.blockCommentLead || mode.blockCommentLead; 245 if (lead != null) for (var i = from.line + 1; i <= end; ++i) 246 if (i != end || lastLineHasText) 247 self.replaceRange(lead + pad, Pos(i, 0)); 248 } else { 249 self.replaceRange(endString, to); 250 self.replaceRange(startString, from); 251 } 252 }); 253 }); 254 255 CodeMirror.defineExtension("uncomment", function(from, to, options) { 256 if (!options) options = noOptions; 257 var self = this, mode = self.getModeAt(from); 258 var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end); 259 260 // Try finding line comments 261 var lineString = options.lineComment || mode.lineComment, lines = []; 262 var pad = options.padding == null ? " " : options.padding, didSomething; 263 lineComment: { 264 if (!lineString) break lineComment; 265 for (var i = start; i <= end; ++i) { 266 var line = self.getLine(i); 267 var found = line.indexOf(lineString); 268 if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1; 269 if (found == -1 && (i != end || i == start) && nonWS.test(line)) break lineComment; 270 if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment; 271 lines.push(line); 272 } 273 self.operation(function() { 274 for (var i = start; i <= end; ++i) { 275 var line = lines[i - start]; 276 var pos = line.indexOf(lineString), endPos = pos + lineString.length; 277 if (pos < 0) continue; 278 if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length; 279 didSomething = true; 280 self.replaceRange("", Pos(i, pos), Pos(i, endPos)); 281 } 282 }); 283 if (didSomething) return true; 284 } 285 286 // Try block comments 287 var startString = options.blockCommentStart || mode.blockCommentStart; 288 var endString = options.blockCommentEnd || mode.blockCommentEnd; 289 if (!startString || !endString) return false; 290 var lead = options.blockCommentLead || mode.blockCommentLead; 291 var startLine = self.getLine(start), endLine = end == start ? startLine : self.getLine(end); 292 var open = startLine.indexOf(startString), close = endLine.lastIndexOf(endString); 293 if (close == -1 && start != end) { 294 endLine = self.getLine(--end); 295 close = endLine.lastIndexOf(endString); 296 } 297 if (open == -1 || close == -1 || 298 !/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) || 299 !/comment/.test(self.getTokenTypeAt(Pos(end, close + 1)))) 300 return false; 301 302 // Avoid killing block comments completely outside the selection. 303 // Positions of the last startString before the start of the selection, and the first endString after it. 304 var lastStart = startLine.lastIndexOf(startString, from.ch); 305 var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length); 306 if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false;
307 // Positions of the first endString after the end of the selection, and the last startString before it. 308 firstEnd = endLine.indexOf(endString, to.ch); 309 var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch); 310 lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart; 311 if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false; 312 313 self.operation(function() { 314 self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)), 315 Pos(end, close + endString.length)); 316 var openEnd = open + startString.length; 317 if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length; 318 self.replaceRange("", Pos(start, open), Pos(start, openEnd)); 319 if (lead) for (var i = start + 1; i <= end; ++i) { 320 var line = self.getLine(i), found = line.indexOf(lead); 321 if (found == -1 || nonWS.test(line.slice(0, found))) continue; 322 var foundEnd = found + lead.length; 323 if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length; 324 self.replaceRange("", Pos(i, found), Pos(i, foundEnd)); 325 } 326 }); 327 return true; 328 }); 329}); 330 331},{"../../lib/codemirror":30}],16:[function(_dereq_,module,exports){ 332// CodeMirror, copyright (c) by Marijn Haverbeke and others 333// Distributed under an MIT license: http://codemirror.net/LICENSE 334 335// Open simple dialogs on top of an editor. Relies on dialog.css. 336 337(function(mod) { 338 if (typeof exports == "object" && typeof module == "object") // CommonJS 339 mod(_dereq_("../../lib/codemirror")); 340 else if (typeof define == "function" && define.amd) // AMD 341 define(["../../lib/codemirror"], mod); 342 else // Plain browser env 343 mod(CodeMirror); 344})(function(CodeMirror) { 345 function dialogDiv(cm, template, bottom) { 346 var wrap = cm.getWrapperElement(); 347 var dialog; 348 dialog = wrap.appendChild(document.createElement("div")); 349 if (bottom) 350 dialog.className = "CodeMirror-dialog CodeMirror-dialog-bottom"; 351 else 352 dialog.className = "CodeMirror-dialog CodeMirror-dialog-top"; 353 354 if (typeof template == "string") { 355 dialog.innerHTML = template; 356 } else { // Assuming it's a detached DOM element. 357 dialog.appendChild(template); 358 } 359 return dialog; 360 } 361 362 function closeNotification(cm, newVal) { 363 if (cm.state.currentNotificationClose) 364 cm.state.currentNotificationClose(); 365 cm.state.currentNotificationClose = newVal; 366 } 367 368 CodeMirror.defineExtension("openDialog", function(template, callback, options) { 369 if (!options) options = {}; 370 371 closeNotification(this, null); 372 373 var dialog = dialogDiv(this, template, options.bottom); 374 var closed = false, me = this; 375 function close(newVal) { 376 if (typeof newVal == 'string') { 377 inp.value = newVal; 378 } else { 379 if (closed) return; 380 closed = true; 381 dialog.parentNode.removeChild(dialog); 382 me.focus(); 383 384 if (options.onClose) options.onClose(dialog); 385 } 386 } 387 388 var inp = dialog.getElementsByTagName("input")[0], button; 389 if (inp) { 390 if (options.value) { 391 inp.value = options.value; 392 if (options.selectValueOnOpen !== false) { 393 inp.select(); 394 } 395 } 396 397 if (options.onInput) 398 CodeMirror.on(inp, "input", function(e) { options.onInput(e, inp.value, close);}); 399 if (options.onKeyUp) 400 CodeMirror.on(inp, "keyup", function(e) {options.onKeyUp(e, inp.value, close);}); 401 402 CodeMirror.on(inp, "keydown", function(e) { 403 if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } 404 if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) { 405 inp.blur(); 406 CodeMirror.e_stop(e); 407 close(); 408 } 409 if (e.keyCode == 13) callback(inp.value, e); 410 }); 411 412 if (options.closeOnBlur !== false) CodeMirror.on(inp, "blur", close); 413 414 inp.focus(); 415 } else if (button = dialog.getElementsByTagName("button")[0]) { 416 CodeMirror.on(button, "click", function() { 417 close(); 418 me.focus(); 419 }); 420 421 if (options.closeOnBlur !== false) CodeMirror.on(button, "blur", close); 422 423 button.focus(); 424 } 425 return close; 426 }); 427 428 CodeMirror.defineExtension("openConfirm", function(template, callbacks, options) { 429 closeNotification(this, null); 430 var dialog = dialogDiv(this, template, options && options.bottom); 431 var buttons = dialog.getElementsByTagName("button"); 432 var closed = false, me = this, blurring = 1; 433 function close() { 434 if (closed) return; 435 closed = true; 436 dialog.parentNode.removeChild(dialog); 437 me.focus(); 438 } 439 buttons[0].focus(); 440 for (var i = 0; i < buttons.length; ++i) { 441 var b = buttons[i]; 442 (function(callback) { 443 CodeMirror.on(b, "click", function(e) { 444 CodeMirror.e_preventDefault(e); 445 close(); 446 if (callback) callback(me); 447 }); 448 })(callbacks[i]); 449 CodeMirror.on(b, "blur", function() { 450 --blurring; 451 setTimeout(function() { if (blurring <= 0) close(); }, 200); 452 }); 453 CodeMirror.on(b, "focus", function() { ++blurring; }); 454 } 455 }); 456 457 /* 458 * openNotification 459 * Opens a notification, that can be closed with an optional timer 460 * (default 5000ms timer) and always closes on click. 461 * 462 * If a notification is opened while another is opened, it will close the 463 * currently opened one and open the new one immediately. 464 */ 465 CodeMirror.defineExtension("openNotification", function(template, options) { 466 closeNotification(this, close); 467 var dialog = dialogDiv(this, template, options && options.bottom); 468 var closed = false, doneTimer; 469 var duration = options && typeof options.duration !== "undefined" ? options.duration : 5000; 470 471 function close() { 472 if (closed) return; 473 closed = true; 474 clearTimeout(doneTimer); 475 dialog.parentNode.removeChild(dialog); 476 } 477 478 CodeMirror.on(dialog, 'click', function(e) { 479 CodeMirror.e_preventDefault(e); 480 close(); 481 }); 482 483 if (duration) 484 doneTimer = setTimeout(close, duration); 485 486 return close; 487 }); 488}); 489 490},{"../../lib/codemirror":30}],17:[function(_dereq_,module,exports){ 491// CodeMirror, copyright (c) by Marijn Haverbeke and others 492// Distributed under an MIT license: http://codemirror.net/LICENSE 493 494(function(mod) { 495 if (typeof exports == "object" && typeof module == "object") // CommonJS 496 mod(_dereq_("../../lib/codemirror")); 497 else if (typeof define == "function" && define.amd) // AMD 498 define(["../../lib/codemirror"], mod); 499 else // Plain browser env 500 mod(CodeMirror); 501})(function(CodeMirror) { 502 CodeMirror.defineExtension("addPanel", function(node, options) { 503 options = options || {}; 504 505 if (!this.state.panels) initPanels(this); 506 507 var info = this.state.panels; 508 var wrapper = info.wrapper; 509 var cmWrapper = this.getWrapperElement(); 510 511 if (options.after instanceof Panel && !options.after.cleared) { 512 wrapper.insertBefore(node, options.before.node.nextSibling); 513 } else if (options.before instanceof Panel && !options.before.cleared) { 514 wrapper.insertBefore(node, options.before.node); 515 } else if (options.replace instanceof Panel && !options.replace.cleared) { 516 wrapper.insertBefore(node, options.replace.node); 517 options.replace.clear(); 518 } else if (options.position == "bottom") { 519 wrapper.appendChild(node); 520 } else if (options.position == "before-bottom") { 521 wrapper.insertBefore(node, cmWrapper.nextSibling); 522 } else if (options.position == "after-top") { 523 wrapper.insertBefore(node, cmWrapper); 524 } else { 525 wrapper.insertBefore(node, wrapper.firstChild); 526 } 527 528 var height = (options && options.height) || node.offsetHeight; 529 this._setSize(null, info.heightLeft -= height); 530 info.panels++; 531 return new Panel(this, node, options, height); 532 }); 533 534 function Panel(cm, node, options, height) { 535 this.cm = cm; 536 this.node = node; 537 this.options = options; 538 this.height = height; 539 this.cleared = false;
540 } 541 542 Panel.prototype.clear = function() { 543 if (this.cleared) return; 544 this.cleared = true; 545 var info = this.cm.state.panels; 546 this.cm._setSize(null, info.heightLeft += this.height); 547 info.wrapper.removeChild(this.node); 548 if (--info.panels == 0) removePanels(this.cm); 549 }; 550 551 Panel.prototype.changed = function(height) { 552 var newHeight = height == null ? this.node.offsetHeight : height; 553 var info = this.cm.state.panels; 554 this.cm._setSize(null, info.height += (newHeight - this.height)); 555 this.height = newHeight; 556 }; 557 558 function initPanels(cm) { 559 var wrap = cm.getWrapperElement(); 560 var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle; 561 var height = parseInt(style.height); 562 var info = cm.state.panels = { 563 setHeight: wrap.style.height, 564 heightLeft: height, 565 panels: 0, 566 wrapper: document.createElement("div") 567 }; 568 wrap.parentNode.insertBefore(info.wrapper, wrap); 569 var hasFocus = cm.hasFocus(); 570 info.wrapper.appendChild(wrap); 571 if (hasFocus) cm.focus(); 572 573 cm._setSize = cm.setSize; 574 if (height != null) cm.setSize = function(width, newHeight) { 575 if (newHeight == null) return this._setSize(width, newHeight); 576 info.setHeight = newHeight; 577 if (typeof newHeight != "number") { 578 var px = /^(\d+\.?\d*)px$/.exec(newHeight); 579 if (px) { 580 newHeight = Number(px[1]); 581 } else { 582 info.wrapper.style.height = newHeight; 583 newHeight = info.wrapper.offsetHeight; 584 info.wrapper.style.height = ""; 585 } 586 } 587 cm._setSize(width, info.heightLeft += (newHeight - height)); 588 height = newHeight; 589 }; 590 } 591 592 function removePanels(cm) { 593 var info = cm.state.panels; 594 cm.state.panels = null; 595 596 var wrap = cm.getWrapperElement(); 597 info.wrapper.parentNode.replaceChild(wrap, info.wrapper); 598 wrap.style.height = info.setHeight; 599 cm.setSize = cm._setSize; 600 cm.setSize(); 601 } 602}); 603 604},{"../../lib/codemirror":30}],18:[function(_dereq_,module,exports){ 605// CodeMirror, copyright (c) by Marijn Haverbeke and others 606// Distributed under an MIT license: http://codemirror.net/LICENSE 607 608(function(mod) { 609 if (typeof exports == "object" && typeof module == "object") // CommonJS 610 mod(_dereq_("../../lib/codemirror")); 611 else if (typeof define == "function" && define.amd) // AMD 612 define(["../../lib/codemirror"], mod); 613 else // Plain browser env 614 mod(CodeMirror); 615})(function(CodeMirror) { 616 "use strict"; 617 618 CodeMirror.defineOption("rulers", false, function(cm, val, old) { 619 if (old && old != CodeMirror.Init) { 620 clearRulers(cm); 621 cm.off("refresh", refreshRulers); 622 } 623 if (val && val.length) { 624 setRulers(cm); 625 cm.on("refresh", refreshRulers); 626 } 627 }); 628 629 function clearRulers(cm) { 630 for (var i = cm.display.lineSpace.childNodes.length - 1; i >= 0; i--) { 631 var node = cm.display.lineSpace.childNodes[i]; 632 if (/(^|\s)CodeMirror-ruler($|\s)/.test(node.className)) 633 node.parentNode.removeChild(node); 634 } 635 } 636 637 function setRulers(cm) { 638 var val = cm.getOption("rulers"); 639 var cw = cm.defaultCharWidth(); 640 var left = cm.charCoords(CodeMirror.Pos(cm.firstLine(), 0), "div").left; 641 var minH = cm.display.scroller.offsetHeight + 30; 642 for (var i = 0; i < val.length; i++) { 643 var elt = document.createElement("div"); 644 elt.className = "CodeMirror-ruler"; 645 var col, conf = val[i]; 646 if (typeof conf == "number") { 647 col = conf; 648 } else { 649 col = conf.column; 650 if (conf.className) elt.className += " " + conf.className; 651 if (conf.color) elt.style.borderColor = conf.color; 652 if (conf.lineStyle) elt.style.borderLeftStyle = conf.lineStyle; 653 if (conf.width) elt.style.borderLeftWidth = conf.width; 654 } 655 elt.style.left = (left + col * cw) + "px"; 656 elt.style.top = "-50px"; 657 elt.style.bottom = "-20px"; 658 elt.style.minHeight = minH + "px"; 659 cm.display.lineSpace.insertBefore(elt, cm.display.cursorDiv); 660 } 661 } 662 663 function refreshRulers(cm) { 664 clearRulers(cm); 665 setRulers(cm); 666 } 667}); 668 669},{"../../lib/codemirror":30}],19:[function(_dereq_,module,exports){ 670// CodeMirror, copyright (c) by Marijn Haverbeke and others 671// Distributed under an MIT license: http://codemirror.net/LICENSE 672 673(function(mod) { 674 if (typeof exports == "object" && typeof module == "object") // CommonJS 675 mod(_dereq_("../../lib/codemirror")); 676 else if (typeof define == "function" && define.amd) // AMD 677 define(["../../lib/codemirror"], mod); 678 else // Plain browser env 679 mod(CodeMirror); 680})(function(CodeMirror) { 681 var defaults = { 682 pairs: "()[]{}''\"\"", 683 triples: "", 684 explode: "[]{}" 685 }; 686
687 var Pos = CodeMirror.Pos; 688 689 CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { 690 if (old && old != CodeMirror.Init) { 691 cm.removeKeyMap(keyMap); 692 cm.state.closeBrackets = null; 693 } 694 if (val) { 695 cm.state.closeBrackets = val; 696 cm.addKeyMap(keyMap); 697 } 698 }); 699 700 function getOption(conf, name) { 701 if (name == "pairs" && typeof conf == "string") return conf; 702 if (typeof conf == "object" && conf[name] != null) return conf[name]; 703 return defaults[name]; 704 } 705 706 var bind = defaults.pairs + "`"; 707 var keyMap = {Backspace: handleBackspace, Enter: handleEnter}; 708 for (var i = 0; i < bind.length; i++) 709 keyMap["'" + bind.charAt(i) + "'"] = handler(bind.charAt(i)); 710 711 function handler(ch) { 712 return function(cm) { return handleChar(cm, ch); }; 713 } 714 715 function getConfig(cm) { 716 var deflt = cm.state.closeBrackets; 717 if (!deflt) return null; 718 var mode = cm.getModeAt(cm.getCursor()); 719 return mode.closeBrackets || deflt; 720 } 721 722 function handleBackspace(cm) { 723 var conf = getConfig(cm); 724 if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; 725 726 var pairs = getOption(conf, "pairs"); 727 var ranges = cm.listSelections(); 728 for (var i = 0; i < ranges.length; i++) { 729 if (!ranges[i].empty()) return CodeMirror.Pass; 730 var around = charsAround(cm, ranges[i].head); 731 if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass; 732 } 733 for (var i = ranges.length - 1; i >= 0; i--) { 734 var cur = ranges[i].head; 735 cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1)); 736 } 737 } 738 739 function handleEnter(cm) { 740 var conf = getConfig(cm); 741 var explode = conf && getOption(conf, "explode"); 742 if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass; 743 744 var ranges = cm.listSelections(); 745 for (var i = 0; i < ranges.length; i++) { 746 if (!ranges[i].empty()) return CodeMirror.Pass; 747 var around = charsAround(cm, ranges[i].head); 748 if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass; 749 } 750 cm.operation(function() { 751 cm.replaceSelection("\n\n", null); 752 cm.execCommand("goCharLeft"); 753 ranges = cm.listSelections(); 754 for (var i = 0; i < ranges.length; i++) { 755 var line = ranges[i].head.line; 756 cm.indentLine(line, null, true); 757 cm.indentLine(line + 1, null, true); 758 } 759 }); 760 } 761 762 function contractSelection(sel) { 763 var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0; 764 return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)), 765 head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))}; 766 } 767 768 function handleChar(cm, ch) { 769 var conf = getConfig(cm); 770 if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass; 771 772 var pairs = getOption(conf, "pairs"); 773 var pos = pairs.indexOf(ch); 774 if (pos == -1) return CodeMirror.Pass; 775 var triples = getOption(conf, "triples"); 776 777 var identical = pairs.charAt(pos + 1) == ch; 778 var ranges = cm.listSelections(); 779 var opening = pos % 2 == 0; 780 781 var type, next; 782 for (var i = 0; i < ranges.length; i++) { 783 var range = ranges[i], cur = range.head, curType; 784 var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1)); 785 if (opening && !range.empty()) { 786 curType = "surround"; 787 } else if ((identical || !opening) && next == ch) { 788 if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch) 789 curType = "skipThree"; 790 else 791 curType = "skip"; 792 } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 && 793 cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch && 794 (cur.ch <= 2 || cm.getRange(Pos(cur.line, cur.ch - 3), Pos(cur.line, cur.ch - 2)) != ch)) { 795 curType = "addFour"; 796 } else if (identical) { 797 if (!CodeMirror.isWordChar(next) && enteringString(cm, cur, ch)) curType = "both"; 798 else return CodeMirror.Pass; 799 } else if (opening && (cm.getLine(cur.line).length == cur.ch || 800 isClosingBracket(next, pairs) || 801 /\s/.test(next))) { 802 curType = "both"; 803 } else { 804 return CodeMirror.Pass; 805 } 806 if (!type) type = curType; 807 else if (type != curType) return CodeMirror.Pass; 808 } 809 810 var left = pos % 2 ? pairs.charAt(pos - 1) : ch; 811 var right = pos % 2 ? ch : pairs.charAt(pos + 1); 812 cm.operation(function() { 813 if (type == "skip") { 814 cm.execCommand("goCharRight"); 815 } else if (type == "skipThree") { 816 for (var i = 0; i < 3; i++) 817 cm.execCommand("goCharRight"); 818 } else if (type == "surround") { 819 var sels = cm.getSelections(); 820 for (var i = 0; i < sels.length; i++) 821 sels[i] = left + sels[i] + right; 822 cm.replaceSelections(sels, "around"); 823 sels = cm.listSelections().slice(); 824 for (var i = 0; i < sels.length; i++) 825 sels[i] = contractSelection(sels[i]); 826 cm.setSelections(sels); 827 } else if (type == "both") { 828 cm.replaceSelection(left + right, null); 829 cm.triggerElectric(left + right); 830 cm.execCommand("goCharLeft"); 831 } else if (type == "addFour") { 832 cm.replaceSelection(left + left + left + left, "before"); 833 cm.execCommand("goCharRight"); 834 } 835 }); 836 } 837 838 function isClosingBracket(ch, pairs) { 839 var pos = pairs.lastIndexOf(ch); 840 return pos > -1 && pos % 2 == 1; 841 } 842 843 function charsAround(cm, pos) { 844 var str = cm.getRange(Pos(pos.line, pos.ch - 1),
vendor: 12,203 bytes, lines 845-1175
845 Pos(pos.line, pos.ch + 1)); 846 return str.length == 2 ? str : null; 847 } 848 849 // Project the token type that will exists after the given char is 850 // typed, and use it to determine whether it would cause the start 851 // of a string token. 852 function enteringString(cm, pos, ch) { 853 var line = cm.getLine(pos.line); 854 var token = cm.getTokenAt(pos); 855 if (/\bstring2?\b/.test(token.type)) return false; 856 var stream = new CodeMirror.StringStream(line.slice(0, pos.ch) + ch + line.slice(pos.ch), 4); 857 stream.pos = stream.start = token.start; 858 for (;;) { 859 var type1 = cm.getMode().token(stream, token.state); 860 if (stream.pos >= pos.ch + 1) return /\bstring2?\b/.test(type1); 861 stream.start = stream.pos; 862 } 863 } 864}); 865 866},{"../../lib/codemirror":30}],20:[function(_dereq_,module,exports){ 867// CodeMirror, copyright (c) by Marijn Haverbeke and others 868// Distributed under an MIT license: http://codemirror.net/LICENSE 869 870(function(mod) { 871 if (typeof exports == "object" && typeof module == "object") // CommonJS 872 mod(_dereq_("../../lib/codemirror")); 873 else if (typeof define == "function" && define.amd) // AMD 874 define(["../../lib/codemirror"], mod); 875 else // Plain browser env 876 mod(CodeMirror); 877})(function(CodeMirror) { 878 var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && 879 (document.documentMode == null || document.documentMode < 8); 880 881 var Pos = CodeMirror.Pos; 882 883 var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; 884 885 function findMatchingBracket(cm, where, strict, config) { 886 var line = cm.getLineHandle(where.line), pos = where.ch - 1; 887 var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; 888 if (!match) return null; 889 var dir = match.charAt(1) == ">" ? 1 : -1; 890 if (strict && (dir > 0) != (pos == where.ch)) return null; 891 var style = cm.getTokenTypeAt(Pos(where.line, pos + 1)); 892 893 var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config); 894 if (found == null) return null; 895 return {from: Pos(where.line, pos), to: found && found.pos, 896 match: found && found.ch == match.charAt(0), forward: dir > 0}; 897 } 898 899 // bracketRegex is used to specify which type of bracket to scan 900 // should be a regexp, e.g. /[[\]]/ 901 // 902 // Note: If "where" is on an open bracket, then this bracket is ignored. 903 // 904 // Returns false when no bracket was found, null when it reached 905 // maxScanLines and gave up 906 function scanForBracket(cm, where, dir, style, config) { 907 var maxScanLen = (config && config.maxScanLineLength) || 10000; 908 var maxScanLines = (config && config.maxScanLines) || 1000; 909 910 var stack = []; 911 var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/; 912 var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1) 913 : Math.max(cm.firstLine() - 1, where.line - maxScanLines); 914 for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) { 915 var line = cm.getLine(lineNo); 916 if (!line) continue; 917 var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1; 918 if (line.length > maxScanLen) continue; 919 if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0); 920 for (; pos != end; pos += dir) { 921 var ch = line.charAt(pos); 922 if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) { 923 var match = matching[ch]; 924 if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch); 925 else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch}; 926 else stack.pop(); 927 } 928 } 929 } 930 return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null; 931 } 932 933 function matchBrackets(cm, autoclear, config) { 934 // Disable brace matching in long lines, since it'll cause hugely slow updates 935 var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; 936 var marks = [], ranges = cm.listSelections(); 937 for (var i = 0; i < ranges.length; i++) { 938 var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config); 939 if (match && cm.getLine(match.from.line).length <= maxHighlightLen) { 940 var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; 941 marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style})); 942 if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen) 943 marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style})); 944 } 945 } 946 947 if (marks.length) { 948 // Kludge to work around the IE bug from issue #1193, where text 949 // input stops going to the textare whever this fires. 950 if (ie_lt8 && cm.state.focused) cm.focus(); 951 952 var clear = function() { 953 cm.operation(function() { 954 for (var i = 0; i < marks.length; i++) marks[i].clear(); 955 }); 956 }; 957 if (autoclear) setTimeout(clear, 800); 958 else return clear; 959 } 960 } 961 962 var currentlyHighlighted = null; 963 function doMatchBrackets(cm) { 964 cm.operation(function() { 965 if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} 966 currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); 967 }); 968 } 969 970 CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { 971 if (old && old != CodeMirror.Init) 972 cm.off("cursorActivity", doMatchBrackets); 973 if (val) { 974 cm.state.matchBrackets = typeof val == "object" ? val : {}; 975 cm.on("cursorActivity", doMatchBrackets); 976 } 977 }); 978 979 CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); 980 CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){ 981 return findMatchingBracket(this, pos, strict, config); 982 }); 983 CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){ 984 return scanForBracket(this, pos, dir, style, config); 985 }); 986}); 987 988},{"../../lib/codemirror":30}],21:[function(_dereq_,module,exports){ 989// CodeMirror, copyright (c) by Marijn Haverbeke and others 990// Distributed under an MIT license: http://codemirror.net/LICENSE 991 992(function(mod) { 993 if (typeof exports == "object" && typeof module == "object") // CommonJS 994 mod(_dereq_("../../lib/codemirror")); 995 else if (typeof define == "function" && define.amd) // AMD 996 define(["../../lib/codemirror"], mod); 997 else // Plain browser env 998 mod(CodeMirror); 999})(function(CodeMirror) { 1000 "use strict"; 1001 1002 function doFold(cm, pos, options, force) { 1003 if (options && options.call) { 1004 var finder = options; 1005 options = null; 1006 } else { 1007 var finder = getOption(cm, options, "rangeFinder"); 1008 } 1009 if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0); 1010 var minSize = getOption(cm, options, "minFoldSize"); 1011 1012 function getRange(allowFolded) { 1013 var range = finder(cm, pos); 1014 if (!range || range.to.line - range.from.line < minSize) return null; 1015 var marks = cm.findMarksAt(range.from); 1016 for (var i = 0; i < marks.length; ++i) { 1017 if (marks[i].__isFold && force !== "fold") { 1018 if (!allowFolded) return null; 1019 range.cleared = true; 1020 marks[i].clear(); 1021 } 1022 } 1023 return range; 1024 } 1025 1026 var range = getRange(true); 1027 if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) { 1028 pos = CodeMirror.Pos(pos.line - 1, 0); 1029 range = getRange(false); 1030 } 1031 if (!range || range.cleared || force === "unfold") return; 1032 1033 var myWidget = makeWidget(cm, options); 1034 CodeMirror.on(myWidget, "mousedown", function(e) { 1035 myRange.clear(); 1036 CodeMirror.e_preventDefault(e); 1037 }); 1038 var myRange = cm.markText(range.from, range.to, { 1039 replacedWith: myWidget, 1040 clearOnEnter: true, 1041 __isFold: true 1042 }); 1043 myRange.on("clear", function(from, to) { 1044 CodeMirror.signal(cm, "unfold", cm, from, to); 1045 }); 1046 CodeMirror.signal(cm, "fold", cm, range.from, range.to); 1047 } 1048 1049 function makeWidget(cm, options) { 1050 var widget = getOption(cm, options, "widget"); 1051 if (typeof widget == "string") { 1052 var text = document.createTextNode(widget); 1053 widget = document.createElement("span"); 1054 widget.appendChild(text); 1055 widget.className = "CodeMirror-foldmarker"; 1056 } 1057 return widget; 1058 } 1059 1060 // Clumsy backwards-compatible interface 1061 CodeMirror.newFoldFunction = function(rangeFinder, widget) { 1062 return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); }; 1063 }; 1064 1065 // New-style interface 1066 CodeMirror.defineExtension("foldCode", function(pos, options, force) { 1067 doFold(this, pos, options, force); 1068 }); 1069 1070 CodeMirror.defineExtension("isFolded", function(pos) { 1071 var marks = this.findMarksAt(pos); 1072 for (var i = 0; i < marks.length; ++i) 1073 if (marks[i].__isFold) return true; 1074 }); 1075 1076 CodeMirror.commands.toggleFold = function(cm) { 1077 cm.foldCode(cm.getCursor()); 1078 }; 1079 CodeMirror.commands.fold = function(cm) { 1080 cm.foldCode(cm.getCursor(), null, "fold"); 1081 }; 1082 CodeMirror.commands.unfold = function(cm) { 1083 cm.foldCode(cm.getCursor(), null, "unfold"); 1084 }; 1085 CodeMirror.commands.foldAll = function(cm) { 1086 cm.operation(function() { 1087 for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) 1088 cm.foldCode(CodeMirror.Pos(i, 0), null, "fold"); 1089 }); 1090 }; 1091 CodeMirror.commands.unfoldAll = function(cm) { 1092 cm.operation(function() { 1093 for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) 1094 cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold"); 1095 }); 1096 }; 1097 1098 CodeMirror.registerHelper("fold", "combine", function() { 1099 var funcs = Array.prototype.slice.call(arguments, 0); 1100 return function(cm, start) { 1101 for (var i = 0; i < funcs.length; ++i) { 1102 var found = funcs[i](cm, start); 1103 if (found) return found; 1104 } 1105 }; 1106 }); 1107 1108 CodeMirror.registerHelper("fold", "auto", function(cm, start) { 1109 var helpers = cm.getHelpers(start, "fold"); 1110 for (var i = 0; i < helpers.length; i++) { 1111 var cur = helpers[i](cm, start); 1112 if (cur) return cur; 1113 } 1114 }); 1115 1116 var defaultOptions = { 1117 rangeFinder: CodeMirror.fold.auto, 1118 widget: "\u2194", 1119 minFoldSize: 0, 1120 scanUp: false 1121 }; 1122 1123 CodeMirror.defineOption("foldOptions", null); 1124 1125 function getOption(cm, options, name) { 1126 if (options && options[name] !== undefined) 1127 return options[name]; 1128 var editorOptions = cm.options.foldOptions; 1129 if (editorOptions && editorOptions[name] !== undefined) 1130 return editorOptions[name]; 1131 return defaultOptions[name]; 1132 } 1133 1134 CodeMirror.defineExtension("foldOption", function(options, name) { 1135 return getOption(this, options, name); 1136 }); 1137}); 1138 1139},{"../../lib/codemirror":30}],22:[function(_dereq_,module,exports){ 1140// CodeMirror, copyright (c) by Marijn Haverbeke and others 1141// Distributed under an MIT license: http://codemirror.net/LICENSE 1142 1143(function(mod) { 1144 if (typeof exports == "object" && typeof module == "object") // CommonJS 1145 mod(_dereq_("../../lib/codemirror"), _dereq_("./foldcode")); 1146 else if (typeof define == "function" && define.amd) // AMD 1147 define(["../../lib/codemirror", "./foldcode"], mod); 1148 else // Plain browser env 1149 mod(CodeMirror); 1150})(function(CodeMirror) { 1151 "use strict"; 1152 1153 CodeMirror.defineOption("foldGutter", false, function(cm, val, old) { 1154 if (old && old != CodeMirror.Init) { 1155 cm.clearGutter(cm.state.foldGutter.options.gutter); 1156 cm.state.foldGutter = null; 1157 cm.off("gutterClick", onGutterClick); 1158 cm.off("change", onChange); 1159 cm.off("viewportChange", onViewportChange); 1160 cm.off("fold", onFold); 1161 cm.off("unfold", onFold); 1162 cm.off("swapDoc", updateInViewport); 1163 } 1164 if (val) { 1165 cm.state.foldGutter = new State(parseOptions(val)); 1166 updateInViewport(cm); 1167 cm.on("gutterClick", onGutterClick); 1168 cm.on("change", onChange); 1169 cm.on("viewportChange", onViewportChange); 1170 cm.on("fold", onFold); 1171 cm.on("unfold", onFold); 1172 cm.on("swapDoc", updateInViewport); 1173 } 1174 }); 1175
1176 var Pos = CodeMirror.Pos; 1177 1178 function State(options) { 1179 this.options = options; 1180 this.from = this.to = 0; 1181 } 1182 1183 function parseOptions(opts) { 1184 if (opts === true) opts = {}; 1185 if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter"; 1186 if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open"; 1187 if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded"; 1188 return opts; 1189 } 1190 1191 function isFolded(cm, line) { 1192 var marks = cm.findMarksAt(Pos(line)); 1193 for (var i = 0; i < marks.length; ++i) 1194 if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i]; 1195 } 1196 1197 function marker(spec) { 1198 if (typeof spec == "string") { 1199 var elt = document.createElement("div"); 1200 elt.className = spec + " CodeMirror-guttermarker-subtle"; 1201 return elt; 1202 } else { 1203 return spec.cloneNode(true); 1204 } 1205 } 1206 1207 function updateFoldInfo(cm, from, to) { 1208 var opts = cm.state.foldGutter.options, cur = from; 1209 var minSize = cm.foldOption(opts, "minFoldSize"); 1210 var func = cm.foldOption(opts, "rangeFinder"); 1211 cm.eachLine(from, to, function(line) { 1212 var mark = null; 1213 if (isFolded(cm, cur)) { 1214 mark = marker(opts.indicatorFolded); 1215 } else { 1216 var pos = Pos(cur, 0); 1217 var range = func && func(cm, pos); 1218 if (range && range.to.line - range.from.line >= minSize) 1219 mark = marker(opts.indicatorOpen); 1220 } 1221 cm.setGutterMarker(line, opts.gutter, mark); 1222 ++cur; 1223 }); 1224 } 1225 1226 function updateInViewport(cm) { 1227 var vp = cm.getViewport(), state = cm.state.foldGutter; 1228 if (!state) return; 1229 cm.operation(function() { 1230 updateFoldInfo(cm, vp.from, vp.to); 1231 }); 1232 state.from = vp.from; state.to = vp.to; 1233 } 1234 1235 function onGutterClick(cm, line, gutter) { 1236 var state = cm.state.foldGutter; 1237 if (!state) return; 1238 var opts = state.options; 1239 if (gutter != opts.gutter) return; 1240 var folded = isFolded(cm, line); 1241 if (folded) folded.clear(); 1242 else cm.foldCode(Pos(line, 0), opts.rangeFinder); 1243 } 1244 1245 function onChange(cm) { 1246 var state = cm.state.foldGutter; 1247 if (!state) return; 1248 var opts = state.options; 1249 state.from = state.to = 0; 1250 clearTimeout(state.changeUpdate); 1251 state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600); 1252 } 1253 1254 function onViewportChange(cm) { 1255 var state = cm.state.foldGutter; 1256 if (!state) return; 1257 var opts = state.options; 1258 clearTimeout(state.changeUpdate); 1259 state.changeUpdate = setTimeout(function() { 1260 var vp = cm.getViewport(); 1261 if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { 1262 updateInViewport(cm); 1263 } else { 1264 cm.operation(function() { 1265 if (vp.from < state.from) { 1266 updateFoldInfo(cm, vp.from, state.from); 1267 state.from = vp.from; 1268 } 1269 if (vp.to > state.to) { 1270 updateFoldInfo(cm, state.to, vp.to); 1271 state.to = vp.to; 1272 } 1273 }); 1274 } 1275 }, opts.updateViewportTimeSpan || 400); 1276 } 1277 1278 function onFold(cm, from) { 1279 var state = cm.state.foldGutter; 1280 if (!state) return; 1281 var line = from.line; 1282 if (line >= state.from && line < state.to) 1283 updateFoldInfo(cm, line, line + 1); 1284 } 1285}); 1286 1287},{"../../lib/codemirror":30,"./foldcode":21}],23:[function(_dereq_,module,exports){ 1288// CodeMirror, copyright (c) by Marijn Haverbeke and others 1289// Distributed under an MIT license: http://codemirror.net/LICENSE 1290 1291(function(mod) { 1292 if (typeof exports == "object" && typeof module == "object") // CommonJS 1293 mod(_dereq_("../../lib/codemirror")); 1294 else if (typeof define == "function" && define.amd) // AMD 1295 define(["../../lib/codemirror"], mod); 1296 else // Plain browser env 1297 mod(CodeMirror); 1298})(function(CodeMirror) { 1299"use strict"; 1300 1301CodeMirror.registerHelper("fold", "indent", function(cm, start) { 1302 var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line); 1303 if (!/\S/.test(firstLine)) return; 1304 var getIndent = function(line) { 1305 return CodeMirror.countColumn(line, null, tabSize); 1306 }; 1307 var myIndent = getIndent(firstLine); 1308 var lastLineInFold = null; 1309 // Go through lines until we find a line that definitely doesn't belong in 1310 // the block we're folding, or to the end. 1311 for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) { 1312 var curLine = cm.getLine(i); 1313 var curIndent = getIndent(curLine); 1314 if (curIndent > myIndent) { 1315 // Lines with a greater indent are considered part of the block. 1316 lastLineInFold = i; 1317 } else if (!/\S/.test(curLine)) { 1318 // Empty lines might be breaks within the block we're trying to fold. 1319 } else { 1320 // A non-empty line at an indent equal to or less than ours marks the 1321 // start of another block. 1322 break; 1323 } 1324 } 1325 if (lastLineInFold) return { 1326 from: CodeMirror.Pos(start.line, firstLine.length), 1327 to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length) 1328 }; 1329}); 1330 1331}); 1332 1333},{"../../lib/codemirror":30}],24:[function(_dereq_,module,exports){ 1334// CodeMirror, copyright (c) by Marijn Haverbeke and others 1335// Distributed under an MIT license: http://codemirror.net/LICENSE 1336 1337(function(mod) { 1338 if (typeof exports == "object" && typeof module == "object") // CommonJS 1339 mod(_dereq_("../../lib/codemirror")); 1340 else if (typeof define == "function" && define.amd) // AMD 1341 define(["../../lib/codemirror"], mod); 1342 else // Plain browser env 1343 mod(CodeMirror); 1344})(function(CodeMirror) {
1345 var Pos = CodeMirror.Pos; 1346 1347 function forEach(arr, f) { 1348 for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]); 1349 } 1350 1351 function arrayContains(arr, item) { 1352 if (!Array.prototype.indexOf) { 1353 var i = arr.length; 1354 while (i--) { 1355 if (arr[i] === item) { 1356 return true; 1357 } 1358 } 1359 return false; 1360 } 1361 return arr.indexOf(item) != -1; 1362 } 1363 1364 function scriptHint(editor, keywords, getToken, options) { 1365 // Find the token at the cursor 1366 var cur = editor.getCursor(), token = getToken(editor, cur); 1367 if (/\b(?:string|comment)\b/.test(token.type)) return; 1368 token.state = CodeMirror.innerMode(editor.getMode(), token.state).state; 1369 1370 // If it's not a 'word-style' token, ignore the token. 1371 if (!/^[\w$_]*$/.test(token.string)) { 1372 token = {start: cur.ch, end: cur.ch, string: "", state: token.state, 1373 type: token.string == "." ? "property" : null}; 1374 } else if (token.end > cur.ch) { 1375 token.end = cur.ch; 1376 token.string = token.string.slice(0, cur.ch - token.start); 1377 } 1378 1379 var tprop = token; 1380 // If it is a property, find out what it is a property of. 1381 while (tprop.type == "property") { 1382 tprop = getToken(editor, Pos(cur.line, tprop.start)); 1383 if (tprop.string != ".") return; 1384 tprop = getToken(editor, Pos(cur.line, tprop.start)); 1385 if (!context) var context = []; 1386 context.push(tprop); 1387 } 1388 return {list: getCompletions(token, context, keywords, options), 1389 from: Pos(cur.line, token.start), 1390 to: Pos(cur.line, token.end)}; 1391 } 1392 1393 function javascriptHint(editor, options) { 1394 return scriptHint(editor, javascriptKeywords, 1395 function (e, cur) {return e.getTokenAt(cur);}, 1396 options); 1397 }; 1398 CodeMirror.registerHelper("hint", "javascript", javascriptHint); 1399 1400 function getCoffeeScriptToken(editor, cur) { 1401 // This getToken, it is for coffeescript, imitates the behavior of 1402 // getTokenAt method in javascript.js, that is, returning "property" 1403 // type and treat "." as indepenent token. 1404 var token = editor.getTokenAt(cur); 1405 if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') { 1406 token.end = token.start; 1407 token.string = '.'; 1408 token.type = "property"; 1409 } 1410 else if (/^\.[\w$_]*$/.test(token.string)) { 1411 token.type = "property"; 1412 token.start++; 1413 token.string = token.string.replace(/\./, ''); 1414 } 1415 return token; 1416 } 1417 1418 function coffeescriptHint(editor, options) { 1419 return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options); 1420 } 1421 CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint); 1422 1423 var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " + 1424 "toUpperCase toLowerCase split concat match replace search").split(" "); 1425 var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " + 1426 "lastIndexOf every some filter forEach map reduce reduceRight ").split(" "); 1427 var funcProps = "prototype apply call bind".split(" "); 1428 var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " + 1429 "if in instanceof new null return switch throw true try typeof var void while with").split(" "); 1430 var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " + 1431 "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" "); 1432 1433 function getCompletions(token, context, keywords, options) { 1434 var found = [], start = token.string, global = options && options.globalScope || window; 1435 function maybeAdd(str) { 1436 if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str); 1437 } 1438 function gatherCompletions(obj) { 1439 if (typeof obj == "string") forEach(stringProps, maybeAdd); 1440 else if (obj instanceof Array) forEach(arrayProps, maybeAdd); 1441 else if (obj instanceof Function) forEach(funcProps, maybeAdd); 1442 for (var name in obj) maybeAdd(name); 1443 } 1444 1445 if (context && context.length) { 1446 // If this is a property, see if it belongs to some object we can 1447 // find in the current environment. 1448 var obj = context.pop(), base; 1449 if (obj.type && obj.type.indexOf("variable") === 0) { 1450 if (options && options.additionalContext) 1451 base = options.additionalContext[obj.string]; 1452 if (!options || options.useGlobalScope !== false) 1453 base = base || global[obj.string]; 1454 } else if (obj.type == "string") { 1455 base = ""; 1456 } else if (obj.type == "atom") { 1457 base = 1; 1458 } else if (obj.type == "function") { 1459 if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') && 1460 (typeof global.jQuery == 'function')) 1461 base = global.jQuery(); 1462 else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function')) 1463 base = global._(); 1464 } 1465 while (base != null && context.length) 1466 base = base[context.pop().string]; 1467 if (base != null) gatherCompletions(base); 1468 } else { 1469 // If not, just look in the global object and any local scope 1470 // (reading into JS mode internals to get at the local and global variables) 1471 for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name); 1472 for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name); 1473 if (!options || options.useGlobalScope !== false) 1474 gatherCompletions(global);
vendor: 4,113 bytes, lines 1475-1586
1475 forEach(keywords, maybeAdd); 1476 } 1477 return found; 1478 } 1479}); 1480 1481},{"../../lib/codemirror":30}],25:[function(_dereq_,module,exports){ 1482// CodeMirror, copyright (c) by Marijn Haverbeke and others 1483// Distributed under an MIT license: http://codemirror.net/LICENSE 1484 1485(function(mod) { 1486 if (typeof exports == "object" && typeof module == "object") // CommonJS 1487 mod(_dereq_("../../lib/codemirror")); 1488 else if (typeof define == "function" && define.amd) // AMD 1489 define(["../../lib/codemirror"], mod); 1490 else // Plain browser env 1491 mod(CodeMirror); 1492})(function(CodeMirror) { 1493 "use strict"; 1494 1495 var HINT_ELEMENT_CLASS = "CodeMirror-hint"; 1496 var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active"; 1497 1498 // This is the old interface, kept around for now to stay 1499 // backwards-compatible. 1500 CodeMirror.showHint = function(cm, getHints, options) { 1501 if (!getHints) return cm.showHint(options); 1502 if (options && options.async) getHints.async = true; 1503 var newOpts = {hint: getHints}; 1504 if (options) for (var prop in options) newOpts[prop] = options[prop]; 1505 return cm.showHint(newOpts); 1506 }; 1507 1508 CodeMirror.defineExtension("showHint", function(options) { 1509 options = parseOptions(this, this.getCursor("start"), options); 1510 var selections = this.listSelections() 1511 if (selections.length > 1) return; 1512 // By default, don't allow completion when something is selected. 1513 // A hint function can have a `supportsSelection` property to 1514 // indicate that it can handle selections. 1515 if (this.somethingSelected()) { 1516 if (!options.hint.supportsSelection) return; 1517 // Don't try with cross-line selections 1518 for (var i = 0; i < selections.length; i++) 1519 if (selections[i].head.line != selections[i].anchor.line) return; 1520 } 1521 1522 if (this.state.completionActive) this.state.completionActive.close(); 1523 var completion = this.state.completionActive = new Completion(this, options); 1524 if (!completion.options.hint) return; 1525 1526 CodeMirror.signal(this, "startCompletion", this); 1527 completion.update(true); 1528 }); 1529 1530 function Completion(cm, options) { 1531 this.cm = cm; 1532 this.options = options; 1533 this.widget = null; 1534 this.debounce = 0; 1535 this.tick = 0; 1536 this.startPos = this.cm.getCursor("start"); 1537 this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length; 1538 1539 var self = this; 1540 cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); }); 1541 } 1542 1543 var requestAnimationFrame = window.requestAnimationFrame || function(fn) { 1544 return setTimeout(fn, 1000/60); 1545 }; 1546 var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout; 1547 1548 Completion.prototype = { 1549 close: function() { 1550 if (!this.active()) return; 1551 this.cm.state.completionActive = null; 1552 this.tick = null; 1553 this.cm.off("cursorActivity", this.activityFunc); 1554 1555 if (this.widget && this.data) CodeMirror.signal(this.data, "close"); 1556 if (this.widget) this.widget.close(); 1557 CodeMirror.signal(this.cm, "endCompletion", this.cm); 1558 }, 1559 1560 active: function() { 1561 return this.cm.state.completionActive == this; 1562 }, 1563 1564 pick: function(data, i) { 1565 var completion = data.list[i]; 1566 if (completion.hint) completion.hint(this.cm, data, completion); 1567 else this.cm.replaceRange(getText(completion), completion.from || data.from, 1568 completion.to || data.to, "complete"); 1569 CodeMirror.signal(data, "pick", completion); 1570 this.close(); 1571 }, 1572 1573 cursorActivity: function() { 1574 if (this.debounce) { 1575 cancelAnimationFrame(this.debounce); 1576 this.debounce = 0; 1577 } 1578 1579 var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line); 1580 if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch || 1581 pos.ch < this.startPos.ch || this.cm.somethingSelected() || 1582 (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) { 1583 this.close(); 1584 } else { 1585 var self = this; 1586 this.debounce = requestAnimationFrame(function() {self.update(
1586);}); 1587 if (this.widget) this.widget.disable(); 1588 } 1589 }, 1590 1591 update: function(first) { 1592 if (this.tick == null) return; 1593 if (!this.options.hint.async) { 1594 this.finishUpdate(this.options.hint(this.cm, this.options), first); 1595 } else { 1596 var myTick = ++this.tick, self = this; 1597 this.options.hint(this.cm, function(data) { 1598 if (self.tick == myTick) self.finishUpdate(data, first); 1599 }, this.options); 1600 } 1601 }, 1602 1603 finishUpdate: function(data, first) { 1604 if (this.data) CodeMirror.signal(this.data, "update"); 1605 if (data && this.data && CodeMirror.cmpPos(data.from, this.data.from)) data = null; 1606 this.data = data; 1607 1608 var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle); 1609 if (this.widget) this.widget.close(); 1610 if (data && data.list.length) { 1611 if (picked && data.list.length == 1) { 1612 this.pick(data, 0); 1613 } else { 1614 this.widget = new Widget(this, data); 1615 CodeMirror.signal(data, "shown"); 1616 } 1617 } 1618 } 1619 }; 1620 1621 function parseOptions(cm, pos, options) { 1622 var editor = cm.options.hintOptions; 1623 var out = {}; 1624 for (var prop in defaultOptions) out[prop] = defaultOptions[prop]; 1625 if (editor) for (var prop in editor) 1626 if (editor[prop] !== undefined) out[prop] = editor[prop]; 1627 if (options) for (var prop in options) 1628 if (options[prop] !== undefined) out[prop] = options[prop]; 1629 if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos) 1630 return out; 1631 } 1632 1633 function getText(completion) { 1634 if (typeof completion == "string") return completion; 1635 else return completion.text; 1636 } 1637 1638 function buildKeyMap(completion, handle) { 1639 var baseMap = { 1640 Up: function() {handle.moveFocus(-1);}, 1641 Down: function() {handle.moveFocus(1);}, 1642 PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);}, 1643 PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);}, 1644 Home: function() {handle.setFocus(0);}, 1645 End: function() {handle.setFocus(handle.length - 1);}, 1646 Enter: handle.pick, 1647 Tab: handle.pick, 1648 Esc: handle.close 1649 }; 1650 var custom = completion.options.customKeys; 1651 var ourMap = custom ? {} : baseMap; 1652 function addBinding(key, val) { 1653 var bound; 1654 if (typeof val != "string") 1655 bound = function(cm) { return val(cm, handle); }; 1656 // This mechanism is deprecated 1657 else if (baseMap.hasOwnProperty(val)) 1658 bound = baseMap[val]; 1659 else 1660 bound = val; 1661 ourMap[key] = bound; 1662 } 1663 if (custom) 1664 for (var key in custom) if (custom.hasOwnProperty(key)) 1665 addBinding(key, custom[key]); 1666 var extra = completion.options.extraKeys; 1667 if (extra) 1668 for (var key in extra) if (extra.hasOwnProperty(key)) 1669 addBinding(key, extra[key]); 1670 return ourMap; 1671 } 1672 1673 function getHintElement(hintsElement, el) { 1674 while (el && el != hintsElement) { 1675 if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el; 1676 el = el.parentNode; 1677 } 1678 } 1679 1680 function Widget(completion, data) { 1681 this.completion = completion; 1682 this.data = data; 1683 this.picked = false; 1684 var widget = this, cm = completion.cm; 1685 1686 var hints = this.hints = document.createElement("ul"); 1687 hints.className = "CodeMirror-hints"; 1688 this.selectedHint = data.selectedHint || 0; 1689 1690 var completions = data.list; 1691 for (var i = 0; i < completions.length; ++i) { 1692 var elt = hints.appendChild(document.createElement("li")), cur = completions[i]; 1693 var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); 1694 if (cur.className != null) className = cur.className + " " + className; 1695 elt.className = className; 1696 if (cur.render) cur.render(elt, data, cur); 1697 else elt.appendChild(document.createTextNode(cur.displayText || getText(cur))); 1698 elt.hintId = i; 1699 } 1700 1701 var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null); 1702 var left = pos.left, top = pos.bottom, below = true; 1703 hints.style.left = left + "px"; 1704 hints.style.top = top + "px"; 1705 // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. 1706 var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth); 1707 var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight); 1708 (completion.options.container || document.body).appendChild(hints); 1709 var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH; 1710 if (overlapY > 0) { 1711 var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top); 1712 if (curTop - height > 0) { // Fits above cursor 1713 hints.style.top = (top = pos.top - height) + "px"; 1714 below = false;
1715 } else if (height > winH) { 1716 hints.style.height = (winH - 5) + "px"; 1717 hints.style.top = (top = pos.bottom - box.top) + "px"; 1718 var cursor = cm.getCursor(); 1719 if (data.from.ch != cursor.ch) { 1720 pos = cm.cursorCoords(cursor); 1721 hints.style.left = (left = pos.left) + "px"; 1722 box = hints.getBoundingClientRect(); 1723 } 1724 } 1725 } 1726 var overlapX = box.right - winW; 1727 if (overlapX > 0) { 1728 if (box.right - box.left > winW) { 1729 hints.style.width = (winW - 5) + "px"; 1730 overlapX -= (box.right - box.left) - winW; 1731 } 1732 hints.style.left = (left = pos.left - overlapX) + "px"; 1733 } 1734 1735 cm.addKeyMap(this.keyMap = buildKeyMap(completion, { 1736 moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); }, 1737 setFocus: function(n) { widget.changeActive(n); }, 1738 menuSize: function() { return widget.screenAmount(); }, 1739 length: completions.length, 1740 close: function() { completion.close(); }, 1741 pick: function() { widget.pick(); }, 1742 data: data 1743 })); 1744 1745 if (completion.options.closeOnUnfocus) { 1746 var closingOnBlur; 1747 cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); }); 1748 cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); }); 1749 } 1750 1751 var startScroll = cm.getScrollInfo(); 1752 cm.on("scroll", this.onScroll = function() { 1753 var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); 1754 var newTop = top + startScroll.top - curScroll.top; 1755 var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop); 1756 if (!below) point += hints.offsetHeight; 1757 if (point <= editor.top || point >= editor.bottom) return completion.close(); 1758 hints.style.top = newTop + "px"; 1759 hints.style.left = (left + startScroll.left - curScroll.left) + "px"; 1760 }); 1761 1762 CodeMirror.on(hints, "dblclick", function(e) { 1763 var t = getHintElement(hints, e.target || e.srcElement); 1764 if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();} 1765 }); 1766 1767 CodeMirror.on(hints, "click", function(e) { 1768 var t = getHintElement(hints, e.target || e.srcElement); 1769 if (t && t.hintId != null) { 1770 widget.changeActive(t.hintId); 1771 if (completion.options.completeOnSingleClick) widget.pick(); 1772 } 1773 }); 1774 1775 CodeMirror.on(hints, "mousedown", function() { 1776 setTimeout(function(){cm.focus();}, 20); 1777 }); 1778 1779 CodeMirror.signal(data, "select", completions[0], hints.firstChild); 1780 return true; 1781 } 1782 1783 Widget.prototype = { 1784 close: function() { 1785 if (this.completion.widget != this) return; 1786 this.completion.widget = null; 1787 this.hints.parentNode.removeChild(this.hints); 1788 this.completion.cm.removeKeyMap(this.keyMap); 1789 1790 var cm = this.completion.cm; 1791 if (this.completion.options.closeOnUnfocus) { 1792 cm.off("blur", this.onBlur); 1793 cm.off("focus", this.onFocus); 1794 } 1795 cm.off("scroll", this.onScroll); 1796 }, 1797 1798 disable: function() { 1799 this.completion.cm.removeKeyMap(this.keyMap); 1800 var widget = this; 1801 this.keyMap = {Enter: function() { widget.picked = true; }}; 1802 this.completion.cm.addKeyMap(this.keyMap); 1803 }, 1804 1805 pick: function() { 1806 this.completion.pick(this.data, this.selectedHint); 1807 }, 1808 1809 changeActive: function(i, avoidWrap) { 1810 if (i >= this.data.list.length) 1811 i = avoidWrap ? this.data.list.length - 1 : 0; 1812 else if (i < 0) 1813 i = avoidWrap ? 0 : this.data.list.length - 1; 1814 if (this.selectedHint == i) return; 1815 var node = this.hints.childNodes[this.selectedHint]; 1816 node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, ""); 1817 node = this.hints.childNodes[this.selectedHint = i]; 1818 node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; 1819 if (node.offsetTop < this.hints.scrollTop) 1820 this.hints.scrollTop = node.offsetTop - 3; 1821 else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight) 1822 this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3; 1823 CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); 1824 }, 1825 1826 screenAmount: function() { 1827 return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1; 1828 } 1829 }; 1830 1831 function applicableHelpers(cm, helpers) { 1832 if (!cm.somethingSelected()) return helpers 1833 var result = [] 1834 for (var i = 0; i < helpers.length; i++) 1835 if (helpers[i].supportsSelection) result.push(helpers[i]) 1836 return result 1837 } 1838 1839 function resolveAutoHints(cm, pos) { 1840 var helpers = cm.getHelpers(pos, "hint"), words 1841 if (helpers.length) { 1842 var async = false, resolved 1843 for (var i = 0; i < helpers.length; i++) if (helpers[i].async) async = true 1844 if (async) { 1845 resolved = function(cm, callback, options) { 1846 var app = applicableHelpers(cm, helpers) 1847 function run(i, result) { 1848 if (i == app.length) return callback(null) 1849 var helper = app[i] 1850 if (helper.async) { 1851 helper(cm, function(result) { 1852 if (result) callback(result) 1853 else run(i + 1) 1854 }, options) 1855 } else { 1856 var result = helper(cm, options) 1857 if (result) callback(result) 1858 else run(i + 1) 1859 } 1860 } 1861 run(0) 1862 } 1863 resolved.async = true 1864 } else { 1865 resolved = function(cm, options) { 1866 var app = applicableHelpers(cm, helpers) 1867 for (var i = 0; i < app.length; i++) { 1868 var cur = app[i](cm, options) 1869 if (cur && cur.list.length) return cur 1870 } 1871 } 1872 } 1873 resolved.supportsSelection = true 1874 return resolved 1875 } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) { 1876 return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) } 1877 } else if (CodeMirror.hint.anyword) { 1878 return function(cm, options) { return CodeMirror.hint.anyword(cm, options) } 1879 } else { 1880 return function() {} 1881 } 1882 } 1883 1884 CodeMirror.registerHelper("hint", "auto", { 1885 resolve: resolveAutoHints 1886 }); 1887 1888 CodeMirror.registerHelper("hint", "fromList", function(cm, options) { 1889 var cur = cm.getCursor(), token = cm.getTokenAt(cur); 1890 var to = CodeMirror.Pos(cur.line, token.end); 1891 if (token.string && /\w/.test(token.string[token.string.length - 1])) { 1892 var term = token.string, from = CodeMirror.Pos(cur.line, token.start); 1893 } else { 1894 var term = "", from = to; 1895 } 1896 var found = []; 1897 for (var i = 0; i < options.words.length; i++) { 1898 var word = options.words[i]; 1899 if (word.slice(0, term.length) == term) 1900 found.push(word); 1901 } 1902 1903 if (found.length) return {list: found, from: from, to: to}; 1904 }); 1905 1906 CodeMirror.commands.autocomplete = CodeMirror.showHint; 1907 1908 var defaultOptions = { 1909 hint: CodeMirror.hint.auto, 1910 completeSingle: true, 1911 alignWithWord: true, 1912 closeCharacters: /[\s()\[\]{};:>,]/, 1913 closeOnUnfocus: true, 1914 completeOnSingleClick: false, 1915 container: null, 1916 customKeys: null, 1917 extraKeys: null 1918 }; 1919 1920 CodeMirror.defineOption("hintOptions", null); 1921}); 1922 1923},{"../../lib/codemirror":30}],26:[function(_dereq_,module,exports){ 1924// CodeMirror, copyright (c) by Marijn Haverbeke and others 1925// Distributed under an MIT license: http://codemirror.net/LICENSE 1926 1927// Define search commands. Depends on dialog.js or another 1928// implementation of the openDialog method. 1929 1930// Replace works a little oddly -- it will do the replace on the next 1931// Ctrl-G (or whatever is bound to findNext) press. You prevent a 1932// replace by making sure the match is no longer selected when hitting 1933// Ctrl-G. 1934 1935(function(mod) { 1936 if (typeof exports == "object" && typeof module == "object") // CommonJS 1937 mod(_dereq_("../../lib/codemirror"), _dereq_("./searchcursor"), _dereq_("../dialog/dialog")); 1938 else if (typeof define == "function" && define.amd) // AMD 1939 define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod); 1940 else // Plain browser env 1941 mod(CodeMirror); 1942})(function(CodeMirror) { 1943 "use strict"; 1944 1945 function searchOverlay(query, caseInsensitive) { 1946 if (typeof query == "string") 1947 query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g"); 1948 else if (!query.global) 1949 query = new RegExp(query.source, query.ignoreCase ? "gi" : "g"); 1950 1951 return {token: function(stream) { 1952 query.lastIndex = stream.pos; 1953 var match = query.exec(stream.string); 1954 if (match && match.index == stream.pos) { 1955 stream.pos += match[0].length; 1956 return "searching"; 1957 } else if (match) { 1958 stream.pos = match.index; 1959 } else { 1960 stream.skipToEnd(); 1961 } 1962 }}; 1963 } 1964 1965 function SearchState() { 1966 this.posFrom = this.posTo = this.lastQuery = this.query = null;
1967 this.overlay = null; 1968 } 1969 1970 function getSearchState(cm) { 1971 return cm.state.search || (cm.state.search = new SearchState()); 1972 } 1973 1974 function queryCaseInsensitive(query) { 1975 return typeof query == "string" && query == query.toLowerCase(); 1976 } 1977 1978 function getSearchCursor(cm, query, pos) { 1979 // Heuristic: if the query string is all lowercase, do a case insensitive search. 1980 return cm.getSearchCursor(query, pos, queryCaseInsensitive(query)); 1981 } 1982 1983 function persistentDialog(cm, text, deflt, f) { 1984 cm.openDialog(text, f, { 1985 value: deflt, 1986 selectValueOnOpen: true, 1987 closeOnEnter: false, 1988 onClose: function() { clearSearch(cm); } 1989 }); 1990 } 1991 1992 function dialog(cm, text, shortText, deflt, f) { 1993 if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true}); 1994 else f(prompt(shortText, deflt)); 1995 } 1996 1997 function confirmDialog(cm, text, shortText, fs) { 1998 if (cm.openConfirm) cm.openConfirm(text, fs); 1999 else if (confirm(shortText)) fs[0](); 2000 } 2001 2002 function parseString(string) { 2003 return string.replace(/\\(.)/g, function(_, ch) { 2004 if (ch == "n") return "\n" 2005 if (ch == "r") return "\r" 2006 return ch 2007 }) 2008 } 2009 2010 function parseQuery(query) { 2011 var isRE = query.match(/^\/(.*)\/([a-z]*)$/); 2012 if (isRE) { 2013 try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); } 2014 catch(e) {} // Not a regular expression after all, do a string search 2015 } else { 2016 query = parseString(query) 2017 } 2018 if (typeof query == "string" ? query == "" : query.test("")) 2019 query = /x^/; 2020 return query; 2021 } 2022 2023 var queryDialog = 2024 'Search: <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>'; 2025 2026 function startSearch(cm, state, query) { 2027 state.queryText = query; 2028 state.query = parseQuery(query); 2029 cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query)); 2030 state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query)); 2031 cm.addOverlay(state.overlay); 2032 if (cm.showMatchesOnScrollbar) { 2033 if (state.annotate) { state.annotate.clear(); state.annotate = null; } 2034 state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query)); 2035 } 2036 } 2037 2038 function doSearch(cm, rev, persistent) { 2039 var state = getSearchState(cm); 2040 if (state.query) return findNext(cm, rev); 2041 var q = cm.getSelection() || state.lastQuery; 2042 if (persistent && cm.openDialog) { 2043 var hiding = null 2044 persistentDialog(cm, queryDialog, q, function(query, event) { 2045 CodeMirror.e_stop(event); 2046 if (!query) return; 2047 if (query != state.queryText) startSearch(cm, state, query); 2048 if (hiding) hiding.style.opacity = 1 2049 findNext(cm, event.shiftKey, function(_, to) { 2050 var dialog 2051 if (to.line < 3 && document.querySelector && 2052 (dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) && 2053 dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top) 2054 (hiding = dialog).style.opacity = .4 2055 }) 2056 }); 2057 } else { 2058 dialog(cm, queryDialog, "Search for:", q, function(query) { 2059 if (query && !state.query) cm.operation(function() { 2060 startSearch(cm, state, query); 2061 state.posFrom = state.posTo = cm.getCursor(); 2062 findNext(cm, rev); 2063 }); 2064 }); 2065 } 2066 } 2067 2068 function findNext(cm, rev, callback) {cm.operation(function() { 2069 var state = getSearchState(cm); 2070 var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo); 2071 if (!cursor.find(rev)) { 2072 cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0)); 2073 if (!cursor.find(rev)) return; 2074 } 2075 cm.setSelection(cursor.from(), cursor.to()); 2076 cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20); 2077 state.posFrom = cursor.from(); state.posTo = cursor.to(); 2078 if (callback) callback(cursor.from(), cursor.to()) 2079 });} 2080 2081 function clearSearch(cm) {cm.operation(function() { 2082 var state = getSearchState(cm); 2083 state.lastQuery = state.query; 2084 if (!state.query) return; 2085 state.query = state.queryText = null; 2086 cm.removeOverlay(state.overlay); 2087 if (state.annotate) { state.annotate.clear(); state.annotate = null; } 2088 });} 2089 2090 var replaceQueryDialog = 2091 ' <input type="text" style="width: 10em" class="CodeMirror-search-field"/> <span style="color: #888" class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>'; 2092 var replacementQueryDialog = 'With: <input type="text" style="width: 10em" class="CodeMirror-search-field"/>'; 2093 var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>All</button> <button>Stop</button>"; 2094 2095 function replaceAll(cm, query, text) { 2096 cm.operation(function() { 2097 for (var cursor = getSearchCursor(cm, query);
2097 cursor.findNext();) { 2098 if (typeof query != "string") { 2099 var match = cm.getRange(cursor.from(), cursor.to()).match(query); 2100 cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];})); 2101 } else cursor.replace(text); 2102 } 2103 }); 2104 } 2105 2106 function replace(cm, all) { 2107 if (cm.getOption("readOnly")) return; 2108 var query = cm.getSelection() || getSearchState(cm).lastQuery; 2109 var dialogText = all ? "Replace all:" : "Replace:" 2110 dialog(cm, dialogText + replaceQueryDialog, dialogText, query, function(query) { 2111 if (!query) return; 2112 query = parseQuery(query); 2113 dialog(cm, replacementQueryDialog, "Replace with:", "", function(text) { 2114 text = parseString(text) 2115 if (all) { 2116 replaceAll(cm, query, text) 2117 } else { 2118 clearSearch(cm); 2119 var cursor = getSearchCursor(cm, query, cm.getCursor()); 2120 var advance = function() { 2121 var start = cursor.from(), match; 2122 if (!(match = cursor.findNext())) { 2123 cursor = getSearchCursor(cm, query); 2124 if (!(match = cursor.findNext()) || 2125 (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return; 2126 } 2127 cm.setSelection(cursor.from(), cursor.to()); 2128 cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); 2129 confirmDialog(cm, doReplaceConfirm, "Replace?", 2130 [function() {doReplace(match);}, advance, 2131 function() {replaceAll(cm, query, text)}]); 2132 }; 2133 var doReplace = function(match) { 2134 cursor.replace(typeof query == "string" ? text : 2135 text.replace(/\$(\d)/g, function(_, i) {return match[i];})); 2136 advance(); 2137 }; 2138 advance(); 2139 } 2140 }); 2141 }); 2142 } 2143 2144 CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);}; 2145 CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);}; 2146 CodeMirror.commands.findNext = doSearch; 2147 CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);}; 2148 CodeMirror.commands.clearSearch = clearSearch; 2149 CodeMirror.commands.replace = replace; 2150 CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);}; 2151}); 2152 2153},{"../../lib/codemirror":30,"../dialog/dialog":16,"./searchcursor":27}],27:[function(_dereq_,module,exports){ 2154// CodeMirror, copyright (c) by Marijn Haverbeke and others 2155// Distributed under an MIT license: http://codemirror.net/LICENSE 2156 2157(function(mod) { 2158 if (typeof exports == "object" && typeof module == "object") // CommonJS 2159 mod(_dereq_("../../lib/codemirror")); 2160 else if (typeof define == "function" && define.amd) // AMD 2161 define(["../../lib/codemirror"], mod); 2162 else // Plain browser env 2163 mod(CodeMirror); 2164})(function(CodeMirror) { 2165 "use strict"; 2166 var Pos = CodeMirror.Pos; 2167 2168 function SearchCursor(doc, query, pos, caseFold) { 2169 this.atOccurrence = false; this.doc = doc; 2170 if (caseFold == null && typeof query == "string") caseFold = false; 2171 2172 pos = pos ? doc.clipPos(pos) : Pos(0, 0); 2173 this.pos = {from: pos, to: pos}; 2174 2175 // The matches method is filled in based on the type of query. 2176 // It takes a position and a direction, and returns an object 2177 // describing the next occurrence of the query, or null if no 2178 // more matches were found. 2179 if (typeof query != "string") { // Regexp match 2180 if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g"); 2181 this.matches = function(reverse, pos) { 2182 if (reverse) { 2183 query.lastIndex = 0; 2184 var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start; 2185 for (;;) { 2186 query.lastIndex = cutOff; 2187 var newMatch = query.exec(line); 2188 if (!newMatch) break; 2189 match = newMatch; 2190 start = match.index; 2191 cutOff = match.index + (match[0].length || 1); 2192 if (cutOff == line.length) break; 2193 } 2194 var matchLen = (match && match[0].length) || 0; 2195 if (!matchLen) { 2196 if (start == 0 && line.length == 0) {match = undefined;} 2197 else if (start != doc.getLine(pos.line).length) { 2198 matchLen++; 2199 } 2200 } 2201 } else { 2202 query.lastIndex = pos.ch; 2203 var line = doc.getLine(pos.line), match = query.exec(line); 2204 var matchLen = (match && match[0].length) || 0; 2205 var start = match && match.index; 2206 if (start + matchLen != line.length && !matchLen) matchLen = 1; 2207 } 2208 if (match && matchLen) 2209 return {from: Pos(pos.line, start), 2210 to: Pos(pos.line, start + matchLen), 2211 match: match}; 2212 }; 2213 } else { // String query 2214 var origQuery = query; 2215 if (caseFold) query = query.toLowerCase(); 2216 var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; 2217 var target = query.split("\n"); 2218 // Different methods for single-line and multi-line queries 2219 if (target.length == 1) { 2220 if (!query.length) { 2221 // Empty string would match anything and never progress, so 2222 // we define it to match nothing instead. 2223 this.matches = function() {}; 2224 } else { 2225 this.matches = function(reverse, pos) { 2226 if (reverse) { 2227 var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig); 2228 var match = line.lastIndexOf(query); 2229 if (match > -1) { 2230 match = adjustPos(orig, line, match); 2231 return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; 2232 } 2233 } else { 2234 var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig); 2235 var match = line.indexOf(query); 2236 if (match > -1) { 2237 match = adjustPos(orig, line, match) + pos.ch; 2238 return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; 2239 } 2240 } 2241 }; 2242 } 2243 } else { 2244 var origTarget = origQuery.split("\n"); 2245 this.matches = function(reverse, pos) { 2246 var last = target.length - 1; 2247 if (reverse) { 2248 if (pos.line - (target.length - 1) < doc.firstLine()) return; 2249 if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return; 2250 var to = Pos(pos.line, origTarget[last].length); 2251 for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln) 2252 if (target[i] != fold(doc.getLine(ln))) return; 2253 var line = doc.getLine(ln), cut = line.length - origTarget[0].length; 2254 if (fold(line.slice(cut)) != target[0]) return; 2255 return {from: Pos(ln, cut), to: to}; 2256 } else { 2257 if (pos.line + (target.length - 1) >
2257 doc.lastLine()) return; 2258 var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length; 2259 if (fold(line.slice(cut)) != target[0]) return; 2260 var from = Pos(pos.line, cut); 2261 for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln) 2262 if (target[i] != fold(doc.getLine(ln))) return; 2263 if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return; 2264 return {from: from, to: Pos(ln, origTarget[last].length)}; 2265 } 2266 }; 2267 } 2268 } 2269 } 2270 2271 SearchCursor.prototype = { 2272 findNext: function() {return this.find(false);}, 2273 findPrevious: function() {return this.find(true);}, 2274 2275 find: function(reverse) { 2276 var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to); 2277 function savePosAndFail(line) { 2278 var pos = Pos(line, 0); 2279 self.pos = {from: pos, to: pos}; 2280 self.atOccurrence = false; 2281 return false; 2282 } 2283 2284 for (;;) { 2285 if (this.pos = this.matches(reverse, pos)) { 2286 this.atOccurrence = true; 2287 return this.pos.match || true; 2288 } 2289 if (reverse) { 2290 if (!pos.line) return savePosAndFail(0); 2291 pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length); 2292 } 2293 else { 2294 var maxLine = this.doc.lineCount(); 2295 if (pos.line == maxLine - 1) return savePosAndFail(maxLine); 2296 pos = Pos(pos.line + 1, 0); 2297 } 2298 } 2299 }, 2300 2301 from: function() {if (this.atOccurrence) return this.pos.from;}, 2302 to: function() {if (this.atOccurrence) return this.pos.to;}, 2303 2304 replace: function(newText, origin) { 2305 if (!this.atOccurrence) return; 2306 var lines = CodeMirror.splitLines(newText); 2307 this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin); 2308 this.pos.to = Pos(this.pos.from.line + lines.length - 1, 2309 lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0)); 2310 } 2311 }; 2312 2313 // Maps a position in a case-folded line back to a position in the original line 2314 // (compensating for codepoints increasing in number during folding) 2315 function adjustPos(orig, folded, pos) { 2316 if (orig.length == folded.length) return pos; 2317 for (var pos1 = Math.min(pos, orig.length);;) { 2318 var len1 = orig.slice(0, pos1).toLowerCase().length; 2319 if (len1 < pos) ++pos1; 2320 else if (len1 > pos) --pos1; 2321 else return pos1; 2322 } 2323 } 2324 2325 CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { 2326 return new SearchCursor(this.doc, query, pos, caseFold); 2327 }); 2328 CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { 2329 return new SearchCursor(this, query, pos, caseFold); 2330 }); 2331 2332 CodeMirror.defineExtension("selectMatches", function(query, caseFold) { 2333 var ranges = []; 2334 var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold); 2335 while (cur.findNext()) { 2336 if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break; 2337 ranges.push({anchor: cur.from(), head: cur.to()}); 2338 } 2339 if (ranges.length) 2340 this.setSelections(ranges, 0); 2341 }); 2342}); 2343 2344},{"../../lib/codemirror":30}],28:[function(_dereq_,module,exports){ 2345// CodeMirror, copyright (c) by Marijn Haverbeke and others 2346// Distributed under an MIT license: http://codemirror.net/LICENSE 2347 2348(function(mod) { 2349 if (typeof exports == "object" && typeof module == "object") // CommonJS 2350 mod(_dereq_("../../lib/codemirror")); 2351 else if (typeof define == "function" && define.amd) // AMD 2352 define(["../../lib/codemirror"], mod); 2353 else // Plain browser env 2354 mod(CodeMirror); 2355})(function(CodeMirror) { 2356 "use strict"; 2357 2358 var Pos = CodeMirror.Pos; 2359 2360 function findParagraph(cm, pos, options) { 2361 var startRE = options.paragraphStart || cm.getHelper(pos, "paragraphStart"); 2362 for (var start = pos.line, first = cm.firstLine(); start > first; --start) { 2363 var line = cm.getLine(start); 2364 if (startRE && startRE.test(line)) break; 2365 if (!/\S/.test(line)) { ++start; break; } 2366 } 2367 var endRE = options.paragraphEnd || cm.getHelper(pos, "paragraphEnd"); 2368 for (var end = pos.line + 1, last = cm.lastLine(); end <= last; ++end) { 2369 var line = cm.getLine(end); 2370 if (endRE && endRE.test(line)) { ++end; break; } 2371 if (!/\S/.test(line)) break; 2372 } 2373 return {from: start, to: end}; 2374 } 2375 2376 function findBreakPoint(text, column, wrapOn, killTrailingSpace) { 2377 for (var at = column; at > 0; --at) 2378 if (wrapOn.test(text.slice(at - 1, at + 1))) break; 2379 for (var first = true;; first = false) { 2380 var endOfText = at; 2381 if (killTrailingSpace) 2382 while (text.charAt(endOfText - 1) == " ") --endOfText; 2383 if (endOfText == 0 && first) at = column; 2384 else return {from: endOfText, to: at}; 2385 } 2386 } 2387 2388 function wrapRange(cm, from, to, options) { 2389 from = cm.clipPos(from); to = cm.clipPos(to); 2390 var column = options.column || 80; 2391 var wrapOn = options.wrapOn || /\s\S|-[^\.\d]/; 2392 var killTrailing = options.killTrailingSpace !== false; 2393 var changes = [], curLine = "", curNo = from.line; 2394 var lines = cm.getRange(from, to, false); 2395 if (!lines.length) return null; 2396 var leadingSpace = lines[0].match(/^[ \t]*/)[0]; 2397 2398 for (var i = 0; i < lines.length; ++i) { 2399 var text = lines[i], oldLen = curLine.length, spaceInserted = 0; 2400 if (curLine && text && !wrapOn.test(curLine.charAt(curLine.length - 1) + text.charAt(0))) { 2401 curLine += " ";
2402 spaceInserted = 1; 2403 } 2404 var spaceTrimmed = ""; 2405 if (i) { 2406 spaceTrimmed = text.match(/^\s*/)[0]; 2407 text = text.slice(spaceTrimmed.length); 2408 } 2409 curLine += text; 2410 if (i) { 2411 var firstBreak = curLine.length > column && leadingSpace == spaceTrimmed && 2412 findBreakPoint(curLine, column, wrapOn, killTrailing); 2413 // If this isn't broken, or is broken at a different point, remove old break 2414 if (!firstBreak || firstBreak.from != oldLen || firstBreak.to != oldLen + spaceInserted) { 2415 changes.push({text: [spaceInserted ? " " : ""], 2416 from: Pos(curNo, oldLen), 2417 to: Pos(curNo + 1, spaceTrimmed.length)}); 2418 } else { 2419 curLine = leadingSpace + text; 2420 ++curNo; 2421 } 2422 } 2423 while (curLine.length > column) { 2424 var bp = findBreakPoint(curLine, column, wrapOn, killTrailing); 2425 changes.push({text: ["", leadingSpace], 2426 from: Pos(curNo, bp.from), 2427 to: Pos(curNo, bp.to)}); 2428 curLine = leadingSpace + curLine.slice(bp.to); 2429 ++curNo; 2430 } 2431 } 2432 if (changes.length) cm.operation(function() { 2433 for (var i = 0; i < changes.length; ++i) { 2434 var change = changes[i]; 2435 if (change.text || CodeMirror.cmpPos(change.from, change.to)) 2436 cm.replaceRange(change.text, change.from, change.to); 2437 } 2438 }); 2439 return changes.length ? {from: changes[0].from, to: CodeMirror.changeEnd(changes[changes.length - 1])} : null; 2440 } 2441 2442 CodeMirror.defineExtension("wrapParagraph", function(pos, options) { 2443 options = options || {}; 2444 if (!pos) pos = this.getCursor(); 2445 var para = findParagraph(this, pos, options); 2446 return wrapRange(this, Pos(para.from, 0), Pos(para.to - 1), options); 2447 }); 2448 2449 CodeMirror.commands.wrapLines = function(cm) { 2450 cm.operation(function() { 2451 var ranges = cm.listSelections(), at = cm.lastLine() + 1; 2452 for (var i = ranges.length - 1; i >= 0; i--) { 2453 var range = ranges[i], span; 2454 if (range.empty()) { 2455 var para = findParagraph(cm, range.head, {}); 2456 span = {from: Pos(para.from, 0), to: Pos(para.to - 1)}; 2457 } else { 2458 span = {from: range.from(), to: range.to()}; 2459 } 2460 if (span.to.line >= at) continue; 2461 at = span.from.line; 2462 wrapRange(cm, span.from, span.to, {}); 2463 } 2464 }); 2465 }; 2466 2467 CodeMirror.defineExtension("wrapRange", function(from, to, options) { 2468 return wrapRange(this, from, to, options || {}); 2469 }); 2470 2471 CodeMirror.defineExtension("wrapParagraphsInRange", function(from, to, options) { 2472 options = options || {}; 2473 var cm = this, paras = []; 2474 for (var line = from.line; line <= to.line;) { 2475 var para = findParagraph(cm, Pos(line, 0), options); 2476 paras.push(para); 2477 line = para.to; 2478 } 2479 var madeChange = false; 2480 if (paras.length) cm.operation(function() { 2481 for (var i = paras.length - 1; i >= 0; --i) 2482 madeChange = madeChange || wrapRange(cm, Pos(paras[i].from, 0), Pos(paras[i].to - 1), options); 2483 }); 2484 return madeChange; 2485 }); 2486}); 2487 2488},{"../../lib/codemirror":30}],29:[function(_dereq_,module,exports){ 2489// CodeMirror, copyright (c) by Marijn Haverbeke and others 2490// Distributed under an MIT license: http://codemirror.net/LICENSE 2491 2492// A rough approximation of Sublime Text's keybindings 2493// Depends on addon/search/searchcursor.js and optionally addon/dialog/dialogs.js 2494 2495(function(mod) { 2496 if (typeof exports == "object" && typeof module == "object") // CommonJS 2497 mod(_dereq_("../lib/codemirror"), _dereq_("../addon/search/searchcursor"), _dereq_("../addon/edit/matchbrackets")); 2498 else if (typeof define == "function" && define.amd) // AMD 2499 define(["../lib/codemirror", "../addon/search/searchcursor", "../addon/edit/matchbrackets"], mod); 2500 else // Plain browser env 2501 mod(CodeMirror); 2502})(function(CodeMirror) { 2503 "use strict"; 2504 2505 var map = CodeMirror.keyMap.sublime = {fallthrough: "default"}; 2506 var cmds = CodeMirror.commands; 2507 var Pos = CodeMirror.Pos; 2508 var mac = CodeMirror.keyMap["default"] == CodeMirror.keyMap.macDefault; 2509 var ctrl = mac ? "Cmd-" : "Ctrl-"; 2510 2511 // This is not exactly Sublime's algorithm. I couldn't make heads or tails of that. 2512 function findPosSubword(doc, start, dir) { 2513 if (dir < 0 && start.ch == 0) return doc.clipPos(Pos(start.line - 1)); 2514 var line = doc.getLine(start.line); 2515 if (dir > 0 && start.ch >= line.length) return doc.clipPos(Pos(start.line + 1, 0)); 2516 var state = "start", type; 2517 for (var pos = start.ch, e = dir < 0 ? 0 : line.length, i = 0; pos != e; pos += dir, i++) { 2518 var next = line.charAt(dir < 0 ? pos - 1 : pos); 2519 var cat = next != "_" && CodeMirror.isWordChar(next) ? "w" : "o"; 2520 if (cat == "w" && next.toUpperCase() == next) cat = "W"; 2521 if (state == "start") { 2522 if (cat != "o") { state = "in"; type = cat; } 2523 } else if (state == "in") { 2524 if (type != cat) { 2525 if (type == "w" && cat == "W" && dir < 0) pos--; 2526 if (type == "W" && cat == "w" && dir > 0) { type = "w"; continue; } 2527 break; 2528 } 2529 } 2530 } 2531 return Pos(start.line, pos); 2532 } 2533 2534 function moveSubword(cm, dir) { 2535 cm.extendSelectionsBy(function(range) { 2536 if (cm.display.shift || cm.doc.extend || range.empty()) 2537 return findPosSubword(cm.doc, range.head, dir); 2538 else 2539 return dir < 0 ? range.from() : range.to(); 2540 }); 2541 } 2542 2543 cmds[map["Alt-Left"] = "goSubwordLeft"] = function(cm) { moveSubword(cm, -1); }; 2544 cmds[map["Alt-Right"] = "goSubwordRight"] = function(cm) { moveSubword(cm, 1); }; 2545 2546 var scrollLineCombo = mac ? "Ctrl-Alt-" : "Ctrl-"; 2547 2548 cmds[map[scrollLineCombo + "Up"] = "scrollLineUp"] = function(cm) { 2549 var info = cm.getScrollInfo(); 2550 if (!cm.somethingSelected()) { 2551 var visibleBottomLine = cm.lineAtHeight(info.top + info.clientHeight, "local"); 2552 if (cm.getCursor().line >= visibleBottomLine) 2553 cm.execCommand("goLineUp"); 2554 } 2555 cm.scrollTo(null, info.top - cm.defaultTextHeight()); 2556 }; 2557 cmds[map[scrollLineCombo + "Down"] = "scrollLineDown"] = function(cm) { 2558 var info = cm.getScrollInfo(); 2559 if (!cm.somethingSelected()) { 2560 var visibleTopLine = cm.lineAtHeight(info.top, "local")+1; 2561 if (cm.getCursor().line <= visibleTopLine) 2562 cm.execCommand("goLineDown"); 2563 } 2564 cm.scrollTo(null, info.top + cm.defaultTextHeight()); 2565 }; 2566 2567 cmds[map["Shift-" + ctrl + "L"] = "splitSelectionByLine"] = function(cm) { 2568 var ranges = cm.listSelections(), lineRanges = []; 2569 for (var i = 0; i < ranges.length; i++) { 2570 var from = ranges[i].from(), to = ranges[i].to(); 2571 for (var line = from.line; line <= to.line; ++line) 2572 if (!(to.line > from.line && line == to.line && to.ch == 0)) 2573 lineRanges.push({anchor: line == from.line ? from : Pos(line, 0), 2574 head: line == to.line ? to : Pos(line)}); 2575 } 2576 cm.setSelections(lineRanges, 0); 2577 }; 2578 2579 map["Shift-Tab"] = "indentLess"; 2580 2581 cmds[map["Esc"] = "singleSelectionTop"] = function(cm) { 2582 var range = cm.listSelections()[0]; 2583 cm.setSelection(range.anchor, range.head, {scroll: false}); 2584 }; 2585 2586 cmds[map[ctrl + "L"] = "selectLine"] = function(cm) { 2587 var ranges = cm.listSelections(), extended = []; 2588 for (var i = 0; i < ranges.length; i++) { 2589 var range = ranges[i]; 2590 extended.push({anchor: Pos(range.from().line, 0), 2591 head: Pos(range.to().line + 1, 0)}); 2592 } 2593 cm.setSelections(extended); 2594 }; 2595 2596 map["Shift-" + ctrl + "K"] = "deleteLine"; 2597 2598 function insertLine(cm, above) { 2599 cm.operation(function() { 2600 var len = cm.listSelections().length, newSelection = [], last = -1; 2601 for (var i = 0; i < len; i++) { 2602 var head = cm.listSelections()[i].head; 2603 if (head.line <= last) continue; 2604 var at = Pos(head.line + (above ? 0 : 1), 0); 2605 cm.replaceRange("\n", at, null, "+insertLine"); 2606 cm.indentLine(at.line, null, true); 2607 newSelection.push({head: at, anchor: at}); 2608 last = head.line + 1; 2609 } 2610 cm.setSelections(newSelection); 2611 }); 2612 } 2613 2614 cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { insertLine(cm, false); }; 2615 2616 cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { insertLine(cm, true); }; 2617 2618 function wordAt(cm, pos) { 2619 var start = pos.ch, end = start, line = cm.getLine(pos.line); 2620 while (start && CodeMirror.isWordChar(line.charAt(start - 1))) --start; 2621 while (end < line.length && CodeMirror.isWordChar(line.charAt(end))) ++end; 2622 return {from: Pos(pos.line, start), to: Pos(pos.line, end), word: line.slice(start, end)}; 2623 } 2624
2625 cmds[map[ctrl + "D"] = "selectNextOccurrence"] = function(cm) { 2626 var from = cm.getCursor("from"), to = cm.getCursor("to"); 2627 var fullWord = cm.state.sublimeFindFullWord == cm.doc.sel; 2628 if (CodeMirror.cmpPos(from, to) == 0) { 2629 var word = wordAt(cm, from); 2630 if (!word.word) return; 2631 cm.setSelection(word.from, word.to); 2632 fullWord = true; 2633 } else { 2634 var text = cm.getRange(from, to); 2635 var query = fullWord ? new RegExp("\\b" + text + "\\b") : text; 2636 var cur = cm.getSearchCursor(query, to); 2637 if (cur.findNext()) { 2638 cm.addSelection(cur.from(), cur.to()); 2639 } else { 2640 cur = cm.getSearchCursor(query, Pos(cm.firstLine(), 0)); 2641 if (cur.findNext()) 2642 cm.addSelection(cur.from(), cur.to()); 2643 } 2644 } 2645 if (fullWord) 2646 cm.state.sublimeFindFullWord = cm.doc.sel; 2647 }; 2648 2649 var mirror = "(){}[]"; 2650 function selectBetweenBrackets(cm) { 2651 var pos = cm.getCursor(), opening = cm.scanForBracket(pos, -1); 2652 if (!opening) return; 2653 for (;;) { 2654 var closing = cm.scanForBracket(pos, 1); 2655 if (!closing) return; 2656 if (closing.ch == mirror.charAt(mirror.indexOf(opening.ch) + 1)) { 2657 cm.setSelection(Pos(opening.pos.line, opening.pos.ch + 1), closing.pos, false); 2658 return true; 2659 } 2660 pos = Pos(closing.pos.line, closing.pos.ch + 1); 2661 } 2662 } 2663 2664 cmds[map["Shift-" + ctrl + "Space"] = "selectScope"] = function(cm) { 2665 selectBetweenBrackets(cm) || cm.execCommand("selectAll"); 2666 }; 2667 cmds[map["Shift-" + ctrl + "M"] = "selectBetweenBrackets"] = function(cm) { 2668 if (!selectBetweenBrackets(cm)) return CodeMirror.Pass; 2669 }; 2670 2671 cmds[map[ctrl + "M"] = "goToBracket"] = function(cm) { 2672 cm.extendSelectionsBy(function(range) { 2673 var next = cm.scanForBracket(range.head, 1); 2674 if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos; 2675 var prev = cm.scanForBracket(range.head, -1); 2676 return prev && Pos(prev.pos.line, prev.pos.ch + 1) || range.head; 2677 }); 2678 }; 2679 2680 var swapLineCombo = mac ? "Cmd-Ctrl-" : "Shift-Ctrl-"; 2681 2682 cmds[map[swapLineCombo + "Up"] = "swapLineUp"] = function(cm) { 2683 var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1, newSels = []; 2684 for (var i = 0; i < ranges.length; i++) { 2685 var range = ranges[i], from = range.from().line - 1, to = range.to().line; 2686 newSels.push({anchor: Pos(range.anchor.line - 1, range.anchor.ch), 2687 head: Pos(range.head.line - 1, range.head.ch)}); 2688 if (range.to().ch == 0 && !range.empty()) --to; 2689 if (from > at) linesToMove.push(from, to); 2690 else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to; 2691 at = to; 2692 } 2693 cm.operation(function() { 2694 for (var i = 0; i < linesToMove.length; i += 2) { 2695 var from = linesToMove[i], to = linesToMove[i + 1]; 2696 var line = cm.getLine(from); 2697 cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine"); 2698 if (to > cm.lastLine()) 2699 cm.replaceRange("\n" + line, Pos(cm.lastLine()), null, "+swapLine"); 2700 else 2701 cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine"); 2702 } 2703 cm.setSelections(newSels); 2704 cm.scrollIntoView(); 2705 }); 2706 }; 2707 2708 cmds[map[swapLineCombo + "Down"] = "swapLineDown"] = function(cm) { 2709 var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1; 2710 for (var i = ranges.length - 1; i >= 0; i--) { 2711 var range = ranges[i], from = range.to().line + 1, to = range.from().line; 2712 if (range.to().ch == 0 && !range.empty()) from--; 2713 if (from < at) linesToMove.push(from, to); 2714 else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to; 2715 at = to; 2716 } 2717 cm.operation(function() { 2718 for (var i = linesToMove.length - 2; i >= 0; i -= 2) { 2719 var from = linesToMove[i], to = linesToMove[i + 1]; 2720 var line = cm.getLine(from); 2721 if (from == cm.lastLine()) 2722 cm.replaceRange("", Pos(from - 1), Pos(from), "+swapLine"); 2723 else 2724 cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine"); 2725 cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine"); 2726 } 2727 cm.scrollIntoView(); 2728 }); 2729 }; 2730 2731 map[ctrl + "/"] = function(cm) { 2732 cm.toggleComment({ indent: true }); 2733 } 2734 2735 cmds[map[ctrl + "J"] = "joinLines"] = function(cm) { 2736 var ranges = cm.listSelections(), joined = []; 2737 for (var i = 0; i < ranges.length; i++) { 2738 var range = ranges[i], from = range.from(); 2739 var start = from.line, end = range.to().line; 2740 while (i < ranges.length - 1 && ranges[i + 1].from().line == end) 2741 end = ranges[++i].to().line; 2742 joined.push({start: start, end: end, anchor: !range.empty() && from}); 2743 } 2744 cm.operation(function() { 2745 var offset = 0, ranges = []; 2746 for (var i = 0; i < joined.length; i++) { 2747 var obj = joined[i]; 2748 var anchor = obj.anchor && Pos(obj.anchor.line - offset, obj.anchor.ch), head; 2749 for (var line = obj.start; line <= obj.end; line++) { 2750 var actual = line - offset; 2751 if (line == obj.end) head = Pos(actual, cm.getLine(actual).length + 1);
2752 if (actual < cm.lastLine()) { 2753 cm.replaceRange(" ", Pos(actual), Pos(actual + 1, /^\s*/.exec(cm.getLine(actual + 1))[0].length)); 2754 ++offset; 2755 } 2756 } 2757 ranges.push({anchor: anchor || head, head: head}); 2758 } 2759 cm.setSelections(ranges, 0); 2760 }); 2761 }; 2762 2763 cmds[map["Shift-" + ctrl + "D"] = "duplicateLine"] = function(cm) { 2764 cm.operation(function() { 2765 var rangeCount = cm.listSelections().length; 2766 for (var i = 0; i < rangeCount; i++) { 2767 var range = cm.listSelections()[i]; 2768 if (range.empty()) 2769 cm.replaceRange(cm.getLine(range.head.line) + "\n", Pos(range.head.line, 0)); 2770 else 2771 cm.replaceRange(cm.getRange(range.from(), range.to()), range.from()); 2772 } 2773 cm.scrollIntoView(); 2774 }); 2775 }; 2776 2777 map[ctrl + "T"] = "transposeChars"; 2778 2779 function sortLines(cm, caseSensitive) { 2780 var ranges = cm.listSelections(), toSort = [], selected; 2781 for (var i = 0; i < ranges.length; i++) { 2782 var range = ranges[i]; 2783 if (range.empty()) continue; 2784 var from = range.from().line, to = range.to().line; 2785 while (i < ranges.length - 1 && ranges[i + 1].from().line == to) 2786 to = range[++i].to().line; 2787 toSort.push(from, to); 2788 } 2789 if (toSort.length) selected = true; 2790 else toSort.push(cm.firstLine(), cm.lastLine()); 2791 2792 cm.operation(function() { 2793 var ranges = []; 2794 for (var i = 0; i < toSort.length; i += 2) { 2795 var from = toSort[i], to = toSort[i + 1]; 2796 var start = Pos(from, 0), end = Pos(to); 2797 var lines = cm.getRange(start, end, false); 2798 if (caseSensitive) 2799 lines.sort(); 2800 else 2801 lines.sort(function(a, b) { 2802 var au = a.toUpperCase(), bu = b.toUpperCase(); 2803 if (au != bu) { a = au; b = bu; } 2804 return a < b ? -1 : a == b ? 0 : 1; 2805 }); 2806 cm.replaceRange(lines, start, end); 2807 if (selected) ranges.push({anchor: start, head: end}); 2808 } 2809 if (selected) cm.setSelections(ranges, 0); 2810 }); 2811 } 2812 2813 cmds[map["F9"] = "sortLines"] = function(cm) { sortLines(cm, true); }; 2814 cmds[map[ctrl + "F9"] = "sortLinesInsensitive"] = function(cm) { sortLines(cm, false); }; 2815 2816 cmds[map["F2"] = "nextBookmark"] = function(cm) { 2817 var marks = cm.state.sublimeBookmarks; 2818 if (marks) while (marks.length) { 2819 var current = marks.shift(); 2820 var found = current.find(); 2821 if (found) { 2822 marks.push(current); 2823 return cm.setSelection(found.from, found.to); 2824 } 2825 } 2826 }; 2827 2828 cmds[map["Shift-F2"] = "prevBookmark"] = function(cm) { 2829 var marks = cm.state.sublimeBookmarks; 2830 if (marks) while (marks.length) { 2831 marks.unshift(marks.pop()); 2832 var found = marks[marks.length - 1].find(); 2833 if (!found) 2834 marks.pop(); 2835 else 2836 return cm.setSelection(found.from, found.to); 2837 } 2838 }; 2839 2840 cmds[map[ctrl + "F2"] = "toggleBookmark"] = function(cm) { 2841 var ranges = cm.listSelections(); 2842 var marks = cm.state.sublimeBookmarks || (cm.state.sublimeBookmarks = []); 2843 for (var i = 0; i < ranges.length; i++) { 2844 var from = ranges[i].from(), to = ranges[i].to(); 2845 var found = cm.findMarks(from, to); 2846 for (var j = 0; j < found.length; j++) { 2847 if (found[j].sublimeBookmark) { 2848 found[j].clear(); 2849 for (var k = 0; k < marks.length; k++) 2850 if (marks[k] == found[j]) 2851 marks.splice(k--, 1); 2852 break; 2853 } 2854 } 2855 if (j == found.length) 2856 marks.push(cm.markText(from, to, {sublimeBookmark: true, clearWhenEmpty: false})); 2857 } 2858 }; 2859 2860 cmds[map["Shift-" + ctrl + "F2"] = "clearBookmarks"] = function(cm) { 2861 var marks = cm.state.sublimeBookmarks; 2862 if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear(); 2863 marks.length = 0; 2864 }; 2865 2866 cmds[map["Alt-F2"] = "selectBookmarks"] = function(cm) { 2867 var marks = cm.state.sublimeBookmarks, ranges = []; 2868 if (marks) for (var i = 0; i < marks.length; i++) { 2869 var found = marks[i].find(); 2870 if (!found) 2871 marks.splice(i--, 0); 2872 else 2873 ranges.push({anchor: found.from, head: found.to}); 2874 } 2875 if (ranges.length) 2876 cm.setSelections(ranges, 0); 2877 }; 2878 2879 map["Alt-Q"] = "wrapLines"; 2880 2881 var cK = ctrl + "K "; 2882 2883 function modifyWordOrSelection(cm, mod) { 2884 cm.operation(function() { 2885 var ranges = cm.listSelections(), indices = [], replacements = []; 2886 for (var i = 0; i < ranges.length; i++) { 2887 var range = ranges[i]; 2888 if (range.empty()) { indices.push(i); replacements.push(""); } 2889 else replacements.push(mod(cm.getRange(range.from(), range.to()))); 2890 } 2891 cm.replaceSelections(replacements, "around", "case"); 2892 for (var i = indices.length - 1, at; i >= 0; i--) { 2893 var range = ranges[indices[i]]; 2894 if (at && CodeMirror.cmpPos(range.head, at) > 0) continue; 2895 var word = wordAt(cm, range.head); 2896 at = word.from; 2897 cm.replaceRange(mod(word.word), word.from, word.to); 2898 } 2899 }); 2900 } 2901 2902 map[cK + ctrl + "Backspace"] = "delLineLeft"; 2903 2904 cmds[map["Backspace"] = "smartBackspace"] = function(cm) { 2905 if (cm.somethingSelected()) return CodeMirror.Pass; 2906 2907 var cursor = cm.getCursor(); 2908 var toStartOfLine = cm.getRange({line: cursor.line, ch: 0}, cursor); 2909 var column = CodeMirror.countColumn(toStartOfLine, null, cm.getOption("tabSize")); 2910 var indentUnit = cm.getOption("indentUnit"); 2911 2912 if (toStartOfLine && !/\S/.test(toStartOfLine) && column % indentUnit == 0) { 2913 var prevIndent = new Pos(cursor.line, 2914 CodeMirror.findColumn(toStartOfLine, column - indentUnit, indentUnit)); 2915 2916 // If no smart delete is happening (due to tab sizing) just do a regular delete 2917 if (prevIndent.ch == cursor.ch) return CodeMirror.Pass; 2918 2919 return cm.replaceRange("", prevIndent, cursor, "+delete"); 2920 } else { 2921 return CodeMirror.Pass; 2922 } 2923 }; 2924 2925 cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) { 2926 cm.operation(function() { 2927 var ranges = cm.listSelections(); 2928 for (var i = ranges.length - 1; i >= 0; i--) 2929 cm.replaceRange("", ranges[i].anchor, Pos(ranges[i].to().line), "+delete"); 2930 cm.scrollIntoView(); 2931 }); 2932 }; 2933 2934 cmds[map[cK + ctrl + "U"] = "upcaseAtCursor"] = function(cm) { 2935 modifyWordOrSelection(cm, function(str) { return str.toUpperCase(); }); 2936 }; 2937 cmds[map[cK + ctrl + "L"] = "downcaseAtCursor"] = function(cm) { 2938 modifyWordOrSelection(cm, function(str) { return str.toLowerCase(); }); 2939 }; 2940 2941 cmds[map[cK + ctrl + "Space"] = "setSublimeMark"] = function(cm) { 2942 if (cm.state.sublimeMark) cm.state.sublimeMark.clear(); 2943 cm.state.sublimeMark = cm.setBookmark(cm.getCursor()); 2944 }; 2945 cmds[map[cK + ctrl + "A"] = "selectToSublimeMark"] = function(cm) { 2946 var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); 2947 if (found) cm.setSelection(cm.getCursor(), found); 2948 }; 2949 cmds[map[cK + ctrl + "W"] = "deleteToSublimeMark"] = function(cm) { 2950 var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); 2951 if (found) { 2952 var from = cm.getCursor(), to = found; 2953 if (CodeMirror.cmpPos(from, to) > 0) { var tmp = to; to = from; from = tmp; } 2954 cm.state.sublimeKilled = cm.getRange(from, to); 2955 cm.replaceRange("", from, to); 2956 } 2957 }; 2958 cmds[map[cK + ctrl + "X"] = "swapWithSublimeMark"] = function(cm) { 2959 var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); 2960 if (found) { 2961 cm.state.sublimeMark.clear(); 2962 cm.state.sublimeMark = cm.setBookmark(cm.getCursor()); 2963 cm.setCursor(found); 2964 } 2965 }; 2966 cmds[map[cK + ctrl + "Y"] = "sublimeYank"] = function(cm) { 2967 if (cm.state.sublimeKilled != null) 2968 cm.replaceSelection(cm.state.sublimeKilled, null, "paste"); 2969 }; 2970 2971 map[cK + ctrl + "G"] = "clearBookmarks"; 2972 cmds[map[cK + ctrl + "C"] = "showInCenter"] = function(cm) { 2973 var pos = cm.cursorCoords(null, "local"); 2974 cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2); 2975 }; 2976 2977 cmds[map["Shift-Alt-Up"] = "selectLinesUpward"] = function(cm) { 2978 cm.operation(function() { 2979 var ranges = cm.listSelections(); 2980 for (var i = 0; i < ranges.length; i++) { 2981 var range = ranges[i]; 2982 if (range.head.line > cm.firstLine()) 2983 cm.addSelection(Pos(range.head.line - 1, range.head.ch)); 2984 } 2985 }); 2986 };
2987 cmds[map["Shift-Alt-Down"] = "selectLinesDownward"] = function(cm) { 2988 cm.operation(function() { 2989 var ranges = cm.listSelections(); 2990 for (var i = 0; i < ranges.length; i++) { 2991 var range = ranges[i]; 2992 if (range.head.line < cm.lastLine()) 2993 cm.addSelection(Pos(range.head.line + 1, range.head.ch)); 2994 } 2995 }); 2996 }; 2997 2998 function getTarget(cm) { 2999 var from = cm.getCursor("from"), to = cm.getCursor("to"); 3000 if (CodeMirror.cmpPos(from, to) == 0) { 3001 var word = wordAt(cm, from); 3002 if (!word.word) return; 3003 from = word.from; 3004 to = word.to; 3005 } 3006 return {from: from, to: to, query: cm.getRange(from, to), word: word}; 3007 } 3008 3009 function findAndGoTo(cm, forward) { 3010 var target = getTarget(cm); 3011 if (!target) return; 3012 var query = target.query; 3013 var cur = cm.getSearchCursor(query, forward ? target.to : target.from); 3014 3015 if (forward ? cur.findNext() : cur.findPrevious()) { 3016 cm.setSelection(cur.from(), cur.to()); 3017 } else { 3018 cur = cm.getSearchCursor(query, forward ? Pos(cm.firstLine(), 0) 3019 : cm.clipPos(Pos(cm.lastLine()))); 3020 if (forward ? cur.findNext() : cur.findPrevious()) 3021 cm.setSelection(cur.from(), cur.to()); 3022 else if (target.word) 3023 cm.setSelection(target.from, target.to); 3024 } 3025 }; 3026 cmds[map[ctrl + "F3"] = "findUnder"] = function(cm) { findAndGoTo(cm, true); }; 3027 cmds[map["Shift-" + ctrl + "F3"] = "findUnderPrevious"] = function(cm) { findAndGoTo(cm,false); }; 3028 cmds[map["Alt-F3"] = "findAllUnder"] = function(cm) { 3029 var target = getTarget(cm); 3030 if (!target) return; 3031 var cur = cm.getSearchCursor(target.query); 3032 var matches = []; 3033 var primaryIndex = -1; 3034 while (cur.findNext()) { 3035 matches.push({anchor: cur.from(), head: cur.to()}); 3036 if (cur.from().line <= target.from.line && cur.from().ch <= target.from.ch) 3037 primaryIndex++; 3038 } 3039 cm.setSelections(matches, primaryIndex); 3040 }; 3041 3042 map["Shift-" + ctrl + "["] = "fold"; 3043 map["Shift-" + ctrl + "]"] = "unfold"; 3044 map[cK + ctrl + "0"] = map[cK + ctrl + "j"] = "unfoldAll"; 3045 3046 map[ctrl + "I"] = "findIncremental"; 3047 map["Shift-" + ctrl + "I"] = "findIncrementalReverse"; 3048 map[ctrl + "H"] = "replace"; 3049 map["F3"] = "findNext"; 3050 map["Shift-F3"] = "findPrev"; 3051 3052 CodeMirror.normalizeKeyMap(map); 3053}); 3054 3055},{"../addon/edit/matchbrackets":20,"../addon/search/searchcursor":27,"../lib/codemirror":30}],30:[function(_dereq_,module,exports){ 3056// CodeMirror, copyright (c) by Marijn Haverbeke and others 3057// Distributed under an MIT license: http://codemirror.net/LICENSE 3058 3059// This is CodeMirror (http://codemirror.net), a code editor 3060// implemented in JavaScript on top of the browser's DOM. 3061// 3062// You can find some technical background for some of the code below 3063// at http://marijnhaverbeke.nl/blog/#cm-internals . 3064 3065(function(mod) { 3066 if (typeof exports == "object" && typeof module == "object") // CommonJS 3067 module.exports = mod(); 3068 else if (typeof define == "function" && define.amd) // AMD 3069 return define([], mod); 3070 else // Plain browser env 3071 this.CodeMirror = mod(); 3072})(function() { 3073 "use strict"; 3074 3075 // BROWSER SNIFFING 3076 3077 // Kludges for bugs and behavior differences that can't be feature 3078 // detected are enabled based on userAgent etc sniffing. 3079 var userAgent = navigator.userAgent; 3080 var platform = navigator.platform; 3081 3082 var gecko = /gecko\/\d/i.test(userAgent); 3083 var ie_upto10 = /MSIE \d/.test(userAgent); 3084 var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent); 3085 var ie = ie_upto10 || ie_11up; 3086 var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]); 3087 var webkit = /WebKit\//.test(userAgent); 3088 var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent); 3089 var chrome = /Chrome\//.test(userAgent); 3090 var presto = /Opera\//.test(userAgent); 3091 var safari = /Apple Computer/.test(navigator.vendor); 3092 var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent); 3093 var phantom = /PhantomJS/.test(userAgent); 3094 3095 var ios = /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent); 3096 // This is woefully incomplete. Suggestions for alternative methods welcome. 3097 var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent); 3098 var mac = ios || /Mac/.test(platform
vendor: 14,033 bytes, lines 3098-3468
3098); 3099 var windows = /win/i.test(platform); 3100 3101 var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/); 3102 if (presto_version) presto_version = Number(presto_version[1]); 3103 if (presto_version && presto_version >= 15) { presto = false; webkit = true; } 3104 // Some browsers use the wrong event properties to signal cmd/ctrl on OS X 3105 var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); 3106 var captureRightClick = gecko || (ie && ie_version >= 9); 3107 3108 // Optimize some code when these features are not used. 3109 var sawReadOnlySpans = false, sawCollapsedSpans = false; 3110 3111 // EDITOR CONSTRUCTOR 3112 3113 // A CodeMirror instance represents an editor. This is the object 3114 // that user code is usually dealing with. 3115 3116 function CodeMirror(place, options) { 3117 if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); 3118 3119 this.options = options = options ? copyObj(options) : {}; 3120 // Determine effective options based on given values and defaults. 3121 copyObj(defaults, options, false); 3122 setGuttersForLineNumbers(options); 3123 3124 var doc = options.value; 3125 if (typeof doc == "string") doc = new Doc(doc, options.mode, null, options.lineSeparator); 3126 this.doc = doc; 3127 3128 var input = new CodeMirror.inputStyles[options.inputStyle](this); 3129 var display = this.display = new Display(place, doc, input); 3130 display.wrapper.CodeMirror = this; 3131 updateGutters(this); 3132 themeChanged(this); 3133 if (options.lineWrapping) 3134 this.display.wrapper.className += " CodeMirror-wrap"; 3135 if (options.autofocus && !mobile) display.input.focus(); 3136 initScrollbars(this); 3137 3138 this.state = { 3139 keyMaps: [], // stores maps added by addKeyMap 3140 overlays: [], // highlighting overlays, as added by addOverlay 3141 modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info 3142 overwrite: false, 3143 delayingBlurEvent: false, 3144 focused: false, 3145 suppressEdits: false, // used to disable editing during key handlers when in readOnly mode 3146 pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll 3147 selectingText: false, 3148 draggingText: false, 3149 highlight: new Delayed(), // stores highlight worker timeout 3150 keySeq: null, // Unfinished key sequence 3151 specialChars: null 3152 }; 3153 3154 var cm = this; 3155 3156 // Override magic textarea content restore that IE sometimes does 3157 // on our hidden textarea on reload 3158 if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20); 3159 3160 registerEventHandlers(this); 3161 ensureGlobalHandlers(); 3162 3163 startOperation(this); 3164 this.curOp.forceUpdate = true; 3165 attachDoc(this, doc); 3166 3167 if ((options.autofocus && !mobile) || cm.hasFocus()) 3168 setTimeout(bind(onFocus, this), 20); 3169 else 3170 onBlur(this); 3171 3172 for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) 3173 optionHandlers[opt](this, options[opt], Init); 3174 maybeUpdateLineNumberWidth(this); 3175 if (options.finishInit) options.finishInit(this); 3176 for (var i = 0; i < initHooks.length; ++i) initHooks[i](this); 3177 endOperation(this); 3178 // Suppress optimizelegibility in Webkit, since it breaks text 3179 // measuring on line wrapping boundaries. 3180 if (webkit && options.lineWrapping && 3181 getComputedStyle(display.lineDiv).textRendering == "optimizelegibility") 3182 display.lineDiv.style.textRendering = "auto"; 3183 } 3184 3185 // DISPLAY CONSTRUCTOR 3186 3187 // The display handles the DOM integration, both for input reading 3188 // and content drawing. It holds references to DOM nodes and 3189 // display-related state. 3190 3191 function Display(place, doc, input) { 3192 var d = this; 3193 this.input = input; 3194 3195 // Covers bottom-right square when both scrollbars are present. 3196 d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); 3197 d.scrollbarFiller.setAttribute("cm-not-content", "true"); 3198 // Covers bottom of gutter when coverGutterNextToScrollbar is on 3199 // and h scrollbar is present. 3200 d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); 3201 d.gutterFiller.setAttribute("cm-not-content", "true"); 3202 // Will contain the actual code, positioned to cover the viewport. 3203 d.lineDiv = elt("div", null, "CodeMirror-code"); 3204 // Elements are added to these to represent selection and cursors. 3205 d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); 3206 d.cursorDiv = elt("div", null, "CodeMirror-cursors"); 3207 // A visibility: hidden element used to find the size of things. 3208 d.measure = elt("div", null, "CodeMirror-measure"); 3209 // When lines outside of the viewport are measured, they are drawn in this. 3210 d.lineMeasure = elt("div", null, "CodeMirror-measure"); 3211 // Wraps everything that needs to exist inside the vertically-padded coordinate system 3212 d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], 3213 null, "position: relative; outline: none"); 3214 // Moved around its parent to cover visible view. 3215 d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); 3216 // Set to the height of the document, allowing scrolling. 3217 d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); 3218 d.sizerWidth = null; 3219 // Behavior of elts with overflow: auto and padding is 3220 // inconsistent across browsers. This is used to ensure the 3221 // scrollable area is big enough. 3222 d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;"); 3223 // Will contain the gutters, if any. 3224 d.gutters = elt("div", null, "CodeMirror-gutters"); 3225 d.lineGutter = null; 3226 // Actual scrollable element. 3227 d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); 3228 d.scroller.setAttribute("tabIndex", "-1"); 3229 // The element in which the editor lives. 3230 d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); 3231 3232 // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) 3233 if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } 3234 if (!webkit && !(gecko && mobile)) d.scroller.draggable = true; 3235 3236 if (place) { 3237 if (place.appendChild) place.appendChild(d.wrapper); 3238 else place(d.wrapper); 3239 } 3240 3241 // Current rendered range (may be bigger than the view window). 3242 d.viewFrom = d.viewTo = doc.first; 3243 d.reportedViewFrom = d.reportedViewTo = doc.first; 3244 // Information about the rendered lines. 3245 d.view = []; 3246 d.renderedView = null; 3247 // Holds info about a single rendered line when it was rendered 3248 // for measurement, while not in view. 3249 d.externalMeasured = null; 3250 // Empty space (in pixels) above the view 3251 d.viewOffset = 0; 3252 d.lastWrapHeight = d.lastWrapWidth = 0; 3253 d.updateLineNumbers = null; 3254 3255 d.nativeBarWidth = d.barHeight = d.barWidth = 0; 3256 d.scrollbarsClipped = false; 3257 3258 // Used to only resize the line number gutter when necessary (when 3259 // the amount of lines crosses a boundary that makes its width change) 3260 d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; 3261 // Set to true when a non-horizontal-scrolling line widget is 3262 // added. As an optimization, line widget aligning is skipped when 3263 // this is false. 3264 d.alignWidgets = false; 3265 3266 d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; 3267 3268 // Tracks the maximum line length so that the horizontal scrollbar 3269 // can be kept static when scrolling. 3270 d.maxLine = null; 3271 d.maxLineLength = 0; 3272 d.maxLineChanged = false; 3273 3274 // Used for measuring wheel scrolling granularity 3275 d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; 3276 3277 // True when shift is held down. 3278 d.shift = false; 3279 3280 // Used to track whether anything happened since the context menu 3281 // was opened. 3282 d.selForContextMenu = null; 3283 3284 d.activeTouch = null; 3285 3286 input.init(d); 3287 } 3288 3289 // STATE UPDATES 3290 3291 // Used to get the editor into a consistent state again when options change. 3292 3293 function loadMode(cm) { 3294 cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); 3295 resetModeState(cm); 3296 } 3297 3298 function resetModeState(cm) { 3299 cm.doc.iter(function(line) { 3300 if (line.stateAfter) line.stateAfter = null; 3301 if (line.styles) line.styles = null; 3302 }); 3303 cm.doc.frontier = cm.doc.first; 3304 startWorker(cm, 100); 3305 cm.state.modeGen++; 3306 if (cm.curOp) regChange(cm); 3307 } 3308 3309 function wrappingChanged(cm) { 3310 if (cm.options.lineWrapping) { 3311 addClass(cm.display.wrapper, "CodeMirror-wrap"); 3312 cm.display.sizer.style.minWidth = ""; 3313 cm.display.sizerWidth = null; 3314 } else { 3315 rmClass(cm.display.wrapper, "CodeMirror-wrap"); 3316 findMaxLine(cm); 3317 } 3318 estimateLineHeights(cm); 3319 regChange(cm); 3320 clearCaches(cm); 3321 setTimeout(function(){updateScrollbars(cm);}, 100); 3322 } 3323 3324 // Returns a function that estimates the height of a line, to use as 3325 // first approximation until the line becomes visible (and is thus 3326 // properly measurable). 3327 function estimateHeight(cm) { 3328 var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; 3329 var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); 3330 return function(line) { 3331 if (lineIsHidden(cm.doc, line)) return 0; 3332 3333 var widgetsHeight = 0; 3334 if (line.widgets) for (var i = 0; i < line.widgets.length; i++) { 3335 if (line.widgets[i].height) widgetsHeight += line.widgets[i].height; 3336 } 3337 3338 if (wrapping) 3339 return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th; 3340 else 3341 return widgetsHeight + th; 3342 }; 3343 } 3344 3345 function estimateLineHeights(cm) { 3346 var doc = cm.doc, est = estimateHeight(cm); 3347 doc.iter(function(line) { 3348 var estHeight = est(line); 3349 if (estHeight != line.height) updateLineHeight(line, estHeight); 3350 }); 3351 } 3352 3353 function themeChanged(cm) { 3354 cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + 3355 cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); 3356 clearCaches(cm); 3357 } 3358 3359 function guttersChanged(cm) { 3360 updateGutters(cm); 3361 regChange(cm); 3362 setTimeout(function(){alignHorizontally(cm);}, 20); 3363 } 3364 3365 // Rebuild the gutter elements, ensure the margin to the left of the 3366 // code matches their width. 3367 function updateGutters(cm) { 3368 var gutters = cm.display.gutters, specs = cm.options.gutters; 3369 removeChildren(gutters); 3370 for (var i = 0; i < specs.length; ++i) { 3371 var gutterClass = specs[i]; 3372 var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); 3373 if (gutterClass == "CodeMirror-linenumbers") { 3374 cm.display.lineGutter = gElt; 3375 gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; 3376 } 3377 } 3378 gutters.style.display = i ? "" : "none"; 3379 updateGutterSpace(cm); 3380 } 3381 3382 function updateGutterSpace(cm) { 3383 var width = cm.display.gutters.offsetWidth; 3384 cm.display.sizer.style.marginLeft = width + "px"; 3385 } 3386 3387 // Compute the character length of a line, taking into account 3388 // collapsed ranges (see markText) that might hide parts, and join 3389 // other lines onto it. 3390 function lineLength(line) { 3391 if (line.height == 0) return 0; 3392 var len = line.text.length, merged, cur = line; 3393 while (merged = collapsedSpanAtStart(cur)) { 3394 var found = merged.find(0, true); 3395 cur = found.from.line; 3396 len += found.from.ch - found.to.ch; 3397 } 3398 cur = line; 3399 while (merged = collapsedSpanAtEnd(cur)) { 3400 var found = merged.find(0, true); 3401 len -= cur.text.length - found.from.ch; 3402 cur = found.to.line; 3403 len += cur.text.length - found.to.ch; 3404 } 3405 return len; 3406 } 3407 3408 // Find the longest line in the document. 3409 function findMaxLine(cm) { 3410 var d = cm.display, doc = cm.doc; 3411 d.maxLine = getLine(doc, doc.first); 3412 d.maxLineLength = lineLength(d.maxLine); 3413 d.maxLineChanged = true; 3414 doc.iter(function(line) { 3415 var len = lineLength(line); 3416 if (len > d.maxLineLength) { 3417 d.maxLineLength = len; 3418 d.maxLine = line; 3419 } 3420 }); 3421 } 3422 3423 // Make sure the gutters options contains the element 3424 // "CodeMirror-linenumbers" when the lineNumbers option is true. 3425 function setGuttersForLineNumbers(options) { 3426 var found = indexOf(options.gutters, "CodeMirror-linenumbers"); 3427 if (found == -1 && options.lineNumbers) { 3428 options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); 3429 } else if (found > -1 && !options.lineNumbers) { 3430 options.gutters = options.gutters.slice(0); 3431 options.gutters.splice(found, 1); 3432 } 3433 } 3434 3435 // SCROLLBARS 3436 3437 // Prepare DOM reads needed to update the scrollbars. Done in one 3438 // shot to minimize update/measure roundtrips. 3439 function measureForScrollbars(cm) { 3440 var d = cm.display, gutterW = d.gutters.offsetWidth; 3441 var docH = Math.round(cm.doc.height + paddingVert(cm.display)); 3442 return { 3443 clientHeight: d.scroller.clientHeight, 3444 viewHeight: d.wrapper.clientHeight, 3445 scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth, 3446 viewWidth: d.wrapper.clientWidth, 3447 barLeft: cm.options.fixedGutter ? gutterW : 0, 3448 docHeight: docH, 3449 scrollHeight: docH + scrollGap(cm) + d.barHeight, 3450 nativeBarWidth: d.nativeBarWidth, 3451 gutterWidth: gutterW 3452 }; 3453 } 3454 3455 function NativeScrollbars(place, scroll, cm) { 3456 this.cm = cm; 3457 var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); 3458 var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); 3459 place(vert); place(horiz); 3460 3461 on(vert, "scroll", function() { 3462 if (vert.clientHeight) scroll(vert.scrollTop, "vertical"); 3463 }); 3464 on(horiz, "scroll", function() { 3465 if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal"); 3466 }); 3467 3468 this.checked
3468Overlay = false;
3469 // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). 3470 if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; 3471 } 3472 3473 NativeScrollbars.prototype = copyObj({ 3474 update: function(measure) { 3475 var needsH = measure.scrollWidth > measure.clientWidth + 1; 3476 var needsV = measure.scrollHeight > measure.clientHeight + 1; 3477 var sWidth = measure.nativeBarWidth; 3478 3479 if (needsV) { 3480 this.vert.style.display = "block"; 3481 this.vert.style.bottom = needsH ? sWidth + "px" : "0"; 3482 var totalHeight = measure.viewHeight - (needsH ? sWidth : 0); 3483 // A bug in IE8 can cause this value to be negative, so guard it. 3484 this.vert.firstChild.style.height = 3485 Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px"; 3486 } else { 3487 this.vert.style.display = ""; 3488 this.vert.firstChild.style.height = "0"; 3489 } 3490 3491 if (needsH) { 3492 this.horiz.style.display = "block"; 3493 this.horiz.style.right = needsV ? sWidth + "px" : "0"; 3494 this.horiz.style.left = measure.barLeft + "px"; 3495 var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0); 3496 this.horiz.firstChild.style.width = 3497 (measure.scrollWidth - measure.clientWidth + totalWidth) + "px"; 3498 } else { 3499 this.horiz.style.display = ""; 3500 this.horiz.firstChild.style.width = "0"; 3501 } 3502 3503 if (!this.checkedOverlay && measure.clientHeight > 0) { 3504 if (sWidth == 0) this.overlayHack(); 3505 this.checkedOverlay = true; 3506 } 3507 3508 return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}; 3509 }, 3510 setScrollLeft: function(pos) { 3511 if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos; 3512 }, 3513 setScrollTop: function(pos) { 3514 if (this.vert.scrollTop != pos) this.vert.scrollTop = pos; 3515 }, 3516 overlayHack: function() { 3517 var w = mac && !mac_geMountainLion ? "12px" : "18px"; 3518 this.horiz.style.minHeight = this.vert.style.minWidth = w; 3519 var self = this; 3520 var barMouseDown = function(e) { 3521 if (e_target(e) != self.vert && e_target(e) != self.horiz) 3522 operation(self.cm, onMouseDown)(e); 3523 }; 3524 on(this.vert, "mousedown", barMouseDown); 3525 on(this.horiz, "mousedown", barMouseDown); 3526 }, 3527 clear: function() { 3528 var parent = this.horiz.parentNode; 3529 parent.removeChild(this.horiz); 3530 parent.removeChild(this.vert); 3531 } 3532 }, NativeScrollbars.prototype); 3533 3534 function NullScrollbars() {} 3535 3536 NullScrollbars.prototype = copyObj({ 3537 update: function() { return {bottom: 0, right: 0}; }, 3538 setScrollLeft: function() {}, 3539 setScrollTop: function() {}, 3540 clear: function() {} 3541 }, NullScrollbars.prototype); 3542 3543 CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars}; 3544 3545 function initScrollbars(cm) { 3546 if (cm.display.scrollbars) { 3547 cm.display.scrollbars.clear(); 3548 if (cm.display.scrollbars.addClass) 3549 rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); 3550 } 3551 3552 cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) { 3553 cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller); 3554 // Prevent clicks in the scrollbars from killing focus 3555 on(node, "mousedown", function() { 3556 if (cm.state.focused) setTimeout(function() { cm.display.input.focus(); }, 0); 3557 }); 3558 node.setAttribute("cm-not-content", "true"); 3559 }, function(pos, axis) { 3560 if (axis == "horizontal") setScrollLeft(cm, pos); 3561 else setScrollTop(cm, pos); 3562 }, cm); 3563 if (cm.display.scrollbars.addClass) 3564 addClass(cm.display.wrapper, cm.display.scrollbars.addClass); 3565 } 3566 3567 function updateScrollbars(cm, measure) { 3568 if (!measure) measure = measureForScrollbars(cm); 3569 var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight; 3570 updateScrollbarsInner(cm, measure); 3571 for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
3572 if (startWidth != cm.display.barWidth && cm.options.lineWrapping) 3573 updateHeightsInViewport(cm); 3574 updateScrollbarsInner(cm, measureForScrollbars(cm)); 3575 startWidth = cm.display.barWidth; startHeight = cm.display.barHeight; 3576 } 3577 } 3578 3579 // Re-synchronize the fake scrollbars with the actual size of the 3580 // content. 3581 function updateScrollbarsInner(cm, measure) { 3582 var d = cm.display; 3583 var sizes = d.scrollbars.update(measure); 3584 3585 d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px"; 3586 d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
vendor: 8,669 bytes, lines 3586-3789
3586 3587 3588 if (sizes.right && sizes.bottom) { 3589 d.scrollbarFiller.style.display = "block"; 3590 d.scrollbarFiller.style.height = sizes.bottom + "px"; 3591 d.scrollbarFiller.style.width = sizes.right + "px"; 3592 } else d.scrollbarFiller.style.display = ""; 3593 if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { 3594 d.gutterFiller.style.display = "block"; 3595 d.gutterFiller.style.height = sizes.bottom + "px"; 3596 d.gutterFiller.style.width = measure.gutterWidth + "px"; 3597 } else d.gutterFiller.style.display = ""; 3598 } 3599 3600 // Compute the lines that are visible in a given viewport (defaults 3601 // the the current scroll position). viewport may contain top, 3602 // height, and ensure (see op.scrollToPos) properties. 3603 function visibleLines(display, doc, viewport) { 3604 var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop; 3605 top = Math.floor(top - paddingTop(display)); 3606 var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight; 3607 3608 var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); 3609 // Ensure is a {from: {line, ch}, to: {line, ch}} object, and 3610 // forces those lines into the viewport (if possible). 3611 if (viewport && viewport.ensure) { 3612 var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; 3613 if (ensureFrom < from) { 3614 from = ensureFrom; 3615 to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); 3616 } else if (Math.min(ensureTo, doc.lastLine()) >= to) { 3617 from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); 3618 to = ensureTo; 3619 } 3620 } 3621 return {from: from, to: Math.max(to, from + 1)}; 3622 } 3623 3624 // LINE NUMBERS 3625 3626 // Re-align line numbers and gutter marks to compensate for 3627 // horizontal scrolling. 3628 function alignHorizontally(cm) { 3629 var display = cm.display, view = display.view; 3630 if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; 3631 var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; 3632 var gutterW = display.gutters.offsetWidth, left = comp + "px"; 3633 for (var i = 0; i < view.length; i++) if (!view[i].hidden) { 3634 if (cm.options.fixedGutter && view[i].gutter) 3635 view[i].gutter.style.left = left; 3636 var align = view[i].alignable; 3637 if (align) for (var j = 0; j < align.length; j++) 3638 align[j].style.left = left; 3639 } 3640 if (cm.options.fixedGutter) 3641 display.gutters.style.left = (comp + gutterW) + "px"; 3642 } 3643 3644 // Used to ensure that the line number gutter is still the right 3645 // size for the current document size. Returns true when an update 3646 // is needed. 3647 function maybeUpdateLineNumberWidth(cm) { 3648 if (!cm.options.lineNumbers) return false; 3649 var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; 3650 if (last.length != display.lineNumChars) { 3651 var test = display.measure.appendChild(elt("div", [elt("div", last)], 3652 "CodeMirror-linenumber CodeMirror-gutter-elt")); 3653 var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; 3654 display.lineGutter.style.width = ""; 3655 display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1; 3656 display.lineNumWidth = display.lineNumInnerWidth + padding; 3657 display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; 3658 display.lineGutter.style.width = display.lineNumWidth + "px"; 3659 updateGutterSpace(cm); 3660 return true; 3661 } 3662 return false; 3663 } 3664 3665 function lineNumberFor(options, i) { 3666 return String(options.lineNumberFormatter(i + options.firstLineNumber)); 3667 } 3668 3669 // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, 3670 // but using getBoundingClientRect to get a sub-pixel-accurate 3671 // result. 3672 function compensateForHScroll(display) { 3673 return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left; 3674 } 3675 3676 // DISPLAY DRAWING 3677 3678 function DisplayUpdate(cm, viewport, force) { 3679 var display = cm.display; 3680 3681 this.viewport = viewport; 3682 // Store some values that we'll need later (but don't want to force a relayout for) 3683 this.visible = visibleLines(display, cm.doc, viewport); 3684 this.editorIsHidden = !display.wrapper.offsetWidth; 3685 this.wrapperHeight = display.wrapper.clientHeight; 3686 this.wrapperWidth = display.wrapper.clientWidth; 3687 this.oldDisplayWidth = displayWidth(cm); 3688 this.force = force; 3689 this.dims = getDimensions(cm); 3690 this.events = []; 3691 } 3692 3693 DisplayUpdate.prototype.signal = function(emitter, type) { 3694 if (hasHandler(emitter, type)) 3695 this.events.push(arguments); 3696 }; 3697 DisplayUpdate.prototype.finish = function() { 3698 for (var i = 0; i < this.events.length; i++) 3699 signal.apply(null, this.events[i]); 3700 }; 3701 3702 function maybeClipScrollbars(cm) { 3703 var display = cm.display; 3704 if (!display.scrollbarsClipped && display.scroller.offsetWidth) { 3705 display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth; 3706 display.heightForcer.style.height = scrollGap(cm) + "px"; 3707 display.sizer.style.marginBottom = -display.nativeBarWidth + "px"; 3708 display.sizer.style.borderRightWidth = scrollGap(cm) + "px"; 3709 display.scrollbarsClipped = true; 3710 } 3711 } 3712 3713 // Does the actual updating of the line display. Bails out 3714 // (returning false) when there is nothing to be done and forced is 3715 // false. 3716 function updateDisplayIfNeeded(cm, update) { 3717 var display = cm.display, doc = cm.doc; 3718 3719 if (update.editorIsHidden) { 3720 resetView(cm); 3721 return false; 3722 } 3723 3724 // Bail out if the visible area is already rendered and nothing changed. 3725 if (!update.force && 3726 update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo && 3727 (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && 3728 display.renderedView == display.view && countDirtyView(cm) == 0) 3729 return false; 3730 3731 if (maybeUpdateLineNumberWidth(cm)) { 3732 resetView(cm); 3733 update.dims = getDimensions(cm); 3734 } 3735 3736 // Compute a suitable new viewport (from & to) 3737 var end = doc.first + doc.size; 3738 var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first); 3739 var to = Math.min(end, update.visible.to + cm.options.viewportMargin); 3740 if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom); 3741 if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo); 3742 if (sawCollapsedSpans) { 3743 from = visualLineNo(cm.doc, from); 3744 to = visualLineEndNo(cm.doc, to); 3745 } 3746 3747 var different = from != display.viewFrom || to != display.viewTo || 3748 display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth; 3749 adjustView(cm, from, to); 3750 3751 display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); 3752 // Position the mover div to align with the current scroll position 3753 cm.display.mover.style.top = display.viewOffset + "px"; 3754 3755 var toUpdate = countDirtyView(cm); 3756 if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view && 3757 (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo)) 3758 return false; 3759 3760 // For big changes, we hide the enclosing element during the 3761 // update, since that speeds up the operations on most browsers. 3762 var focused = activeElt(); 3763 if (toUpdate > 4) display.lineDiv.style.display = "none"; 3764 patchDisplay(cm, display.updateLineNumbers, update.dims); 3765 if (toUpdate > 4) display.lineDiv.style.display = ""; 3766 display.renderedView = display.view; 3767 // There might have been a widget with a focused element that got 3768 // hidden or updated, if so re-focus it. 3769 if (focused && activeElt() != focused && focused.offsetHeight) focused.focus(); 3770 3771 // Prevent selection and cursors from interfering with the scroll 3772 // width and height. 3773 removeChildren(display.cursorDiv); 3774 removeChildren(display.selectionDiv); 3775 display.gutters.style.height = display.sizer.style.minHeight = 0; 3776 3777 if (different) { 3778 display.lastWrapHeight = update.wrapperHeight; 3779 display.lastWrapWidth = update.wrapperWidth; 3780 startWorker(cm, 400); 3781 } 3782 3783 display.updateLineNumbers = null; 3784 3785 return true; 3786 } 3787 3788 function postUpdateDisplay(cm, update) { 3789 var viewport = update.viewport;
3790 for (var first = true;; first = false) { 3791 if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) { 3792 // Clip forced viewport to actual scrollable area. 3793 if (viewport && viewport.top != null) 3794 viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)}; 3795 // Updated line heights might result in the drawn area not 3796 // actually covering the viewport. Keep looping until it does. 3797 update.visible = visibleLines(cm.display, cm.doc, viewport); 3798 if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo) 3799 break; 3800 } 3801 if (!updateDisplayIfNeeded(cm, update)) break; 3802 updateHeightsInViewport(cm); 3803 var barMeasure = measureForScrollbars(cm); 3804 updateSelection(cm); 3805 setDocumentHeight(cm, barMeasure); 3806 updateScrollbars(cm, barMeasure); 3807 } 3808 3809 update.signal(cm, "update", cm); 3810 if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) { 3811 update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); 3812 cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo; 3813 } 3814 } 3815 3816 function updateDisplaySimple(cm, viewport) { 3817 var update = new DisplayUpdate(cm, viewport); 3818 if (updateDisplayIfNeeded(cm, update)) { 3819 updateHeightsInViewport(cm); 3820 postUpdateDisplay(cm, update); 3821 var barMeasure = measureForScrollbars(cm); 3822 updateSelection(cm); 3823 setDocumentHeight(cm, barMeasure); 3824 updateScrollbars(cm, barMeasure); 3825 update.finish(); 3826 } 3827 } 3828 3829 function setDocumentHeight(cm, measure) { 3830 cm.display.sizer.style.minHeight = measure.docHeight + "px"; 3831 var total = measure.docHeight + cm.display.barHeight; 3832 cm.display.heightForcer.style.top = total + "px"; 3833 cm.display.gutters.style.height = Math.max(total + scrollGap(cm), measure.clientHeight) + "px"; 3834 } 3835 3836 // Read the actual heights of the rendered lines, and update their 3837 // stored heights to match. 3838 function updateHeightsInViewport(cm) { 3839 var display = cm.display; 3840 var prevBottom = display.lineDiv.offsetTop; 3841 for (var i = 0; i < display.view.length; i++) { 3842 var cur = display.view[i], height; 3843 if (cur.hidden) continue; 3844 if (ie && ie_version < 8) { 3845 var bot = cur.node.offsetTop + cur.node.offsetHeight; 3846 height = bot - prevBottom; 3847 prevBottom = bot; 3848 } else { 3849 var box = cur.node.getBoundingClientRect(); 3850 height = box.bottom - box.top; 3851 }
3852 var diff = cur.line.height - height; 3853 if (height < 2) height = textHeight(display); 3854 if (diff > .001 || diff < -.001) { 3855 updateLineHeight(cur.line, height); 3856 updateWidgetHeight(cur.line); 3857 if (cur.rest) for (var j = 0; j < cur.rest.length; j++) 3858 updateWidgetHeight(cur.rest[j]); 3859 } 3860 } 3861 } 3862 3863 // Read and store the height of line widgets associated with the 3864 // given line. 3865 function updateWidgetHeight(line) { 3866 if (line.widgets) for (var i = 0; i < line.widgets.length; ++i) 3867 line.widgets[i].height = line.widgets[i].n
vendor: 11,316 bytes, lines 3867-4138
3867ode.offsetHeight; 3868 } 3869 3870 // Do a bulk-read of the DOM positions and sizes needed to draw the 3871 // view, so that we don't interleave reading and writing to the DOM. 3872 function getDimensions(cm) { 3873 var d = cm.display, left = {}, width = {}; 3874 var gutterLeft = d.gutters.clientLeft; 3875 for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { 3876 left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft; 3877 width[cm.options.gutters[i]] = n.clientWidth; 3878 } 3879 return {fixedPos: compensateForHScroll(d), 3880 gutterTotalWidth: d.gutters.offsetWidth, 3881 gutterLeft: left, 3882 gutterWidth: width, 3883 wrapperWidth: d.wrapper.clientWidth}; 3884 } 3885 3886 // Sync the actual display DOM structure with display.view, removing 3887 // nodes for lines that are no longer in view, and creating the ones 3888 // that are not there yet, and updating the ones that are out of 3889 // date. 3890 function patchDisplay(cm, updateNumbersFrom, dims) { 3891 var display = cm.display, lineNumbers = cm.options.lineNumbers; 3892 var container = display.lineDiv, cur = container.firstChild; 3893 3894 function rm(node) { 3895 var next = node.nextSibling; 3896 // Works around a throw-scroll bug in OS X Webkit 3897 if (webkit && mac && cm.display.currentWheelTarget == node) 3898 node.style.display = "none"; 3899 else 3900 node.parentNode.removeChild(node); 3901 return next; 3902 } 3903 3904 var view = display.view, lineN = display.viewFrom; 3905 // Loop over the elements in the view, syncing cur (the DOM nodes 3906 // in display.lineDiv) with the view as we go. 3907 for (var i = 0; i < view.length; i++) { 3908 var lineView = view[i]; 3909 if (lineView.hidden) { 3910 } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet 3911 var node = buildLineElement(cm, lineView, lineN, dims); 3912 container.insertBefore(node, cur); 3913 } else { // Already drawn 3914 while (cur != lineView.node) cur = rm(cur); 3915 var updateNumber = lineNumbers && updateNumbersFrom != null && 3916 updateNumbersFrom <= lineN && lineView.lineNumber; 3917 if (lineView.changes) { 3918 if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false; 3919 updateLineForChanges(cm, lineView, lineN, dims); 3920 } 3921 if (updateNumber) { 3922 removeChildren(lineView.lineNumber); 3923 lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); 3924 } 3925 cur = lineView.node.nextSibling; 3926 } 3927 lineN += lineView.size; 3928 } 3929 while (cur) cur = rm(cur); 3930 } 3931 3932 // When an aspect of a line changes, a string is added to 3933 // lineView.changes. This updates the relevant part of the line's 3934 // DOM structure. 3935 function updateLineForChanges(cm, lineView, lineN, dims) { 3936 for (var j = 0; j < lineView.changes.length; j++) { 3937 var type = lineView.changes[j]; 3938 if (type == "text") updateLineText(cm, lineView); 3939 else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims); 3940 else if (type == "class") updateLineClasses(lineView); 3941 else if (type == "widget") updateLineWidgets(cm, lineView, dims); 3942 } 3943 lineView.changes = null; 3944 } 3945 3946 // Lines with gutter elements, widgets or a background class need to 3947 // be wrapped, and have the extra elements added to the wrapper div 3948 function ensureLineWrapped(lineView) { 3949 if (lineView.node == lineView.text) { 3950 lineView.node = elt("div", null, null, "position: relative"); 3951 if (lineView.text.parentNode) 3952 lineView.text.parentNode.replaceChild(lineView.node, lineView.text); 3953 lineView.node.appendChild(lineView.text); 3954 if (ie && ie_version < 8) lineView.node.style.zIndex = 2; 3955 } 3956 return lineView.node; 3957 } 3958 3959 function updateLineBackground(lineView) { 3960 var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; 3961 if (cls) cls += " CodeMirror-linebackground"; 3962 if (lineView.background) { 3963 if (cls) lineView.background.className = cls; 3964 else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } 3965 } else if (cls) { 3966 var wrap = ensureLineWrapped(lineView); 3967 lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); 3968 } 3969 } 3970 3971 // Wrapper around buildLineContent which will reuse the structure 3972 // in display.externalMeasured when possible. 3973 function getLineContent(cm, lineView) { 3974 var ext = cm.display.externalMeasured; 3975 if (ext && ext.line == lineView.line) { 3976 cm.display.externalMeasured = null; 3977 lineView.measure = ext.measure; 3978 return ext.built; 3979 } 3980 return buildLineContent(cm, lineView); 3981 } 3982 3983 // Redraw the line's text. Interacts with the background and text 3984 // classes because the mode may output tokens that influence these 3985 // classes. 3986 function updateLineText(cm, lineView) { 3987 var cls = lineView.text.className; 3988 var built = getLineContent(cm, lineView); 3989 if (lineView.text == lineView.node) lineView.node = built.pre; 3990 lineView.text.parentNode.replaceChild(built.pre, lineView.text); 3991 lineView.text = built.pre; 3992 if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { 3993 lineView.bgClass = built.bgClass; 3994 lineView.textClass = built.textClass; 3995 updateLineClasses(lineView); 3996 } else if (cls) { 3997 lineView.text.className = cls; 3998 } 3999 } 4000 4001 function updateLineClasses(lineView) { 4002 updateLineBackground(lineView); 4003 if (lineView.line.wrapClass) 4004 ensureLineWrapped(lineView).className = lineView.line.wrapClass; 4005 else if (lineView.node != lineView.text) 4006 lineView.node.className = ""; 4007 var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; 4008 lineView.text.className = textClass || ""; 4009 } 4010 4011 function updateLineGutter(cm, lineView, lineN, dims) { 4012 if (lineView.gutter) { 4013 lineView.node.removeChild(lineView.gutter); 4014 lineView.gutter = null; 4015 } 4016 if (lineView.gutterBackground) { 4017 lineView.node.removeChild(lineView.gutterBackground); 4018 lineView.gutterBackground = null; 4019 } 4020 if (lineView.line.gutterClass) { 4021 var wrap = ensureLineWrapped(lineView); 4022 lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass, 4023 "left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + 4024 "px; width: " + dims.gutterTotalWidth + "px"); 4025 wrap.insertBefore(lineView.gutterBackground, lineView.text); 4026 } 4027 var markers = lineView.line.gutterMarkers; 4028 if (cm.options.lineNumbers || markers) { 4029 var wrap = ensureLineWrapped(lineView); 4030 var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " + 4031 (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"); 4032 cm.display.input.setUneditable(gutterWrap); 4033 wrap.insertBefore(gutterWrap, lineView.text); 4034 if (lineView.line.gutterClass) 4035 gutterWrap.className += " " + lineView.line.gutterClass; 4036 if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) 4037 lineView.lineNumber = gutterWrap.appendChild( 4038 elt("div", lineNumberFor(cm.options, lineN), 4039 "CodeMirror-linenumber CodeMirror-gutter-elt", 4040 "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " 4041 + cm.display.lineNumInnerWidth + "px")); 4042 if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) { 4043 var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; 4044 if (found) 4045 gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + 4046 dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px")); 4047 } 4048 } 4049 } 4050 4051 function updateLineWidgets(cm, lineView, dims) { 4052 if (lineView.alignable) lineView.alignable = null; 4053 for (var node = lineView.node.firstChild, next; node; node = next) { 4054 var next = node.nextSibling; 4055 if (node.className == "CodeMirror-linewidget") 4056 lineView.node.removeChild(node); 4057 } 4058 insertLineWidgets(cm, lineView, dims); 4059 } 4060 4061 // Build a line's DOM representation from scratch 4062 function buildLineElement(cm, lineView, lineN, dims) { 4063 var built = getLineContent(cm, lineView); 4064 lineView.text = lineView.node = built.pre; 4065 if (built.bgClass) lineView.bgClass = built.bgClass; 4066 if (built.textClass) lineView.textClass = built.textClass; 4067 4068 updateLineClasses(lineView); 4069 updateLineGutter(cm, lineView, lineN, dims); 4070 insertLineWidgets(cm, lineView, dims); 4071 return lineView.node; 4072 } 4073 4074 // A lineView may contain multiple logical lines (when merged by 4075 // collapsed spans). The widgets for all of them need to be drawn. 4076 function insertLineWidgets(cm, lineView, dims) { 4077 insertLineWidgetsFor(cm, lineView.line, lineView, dims, true); 4078 if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) 4079 insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); 4080 } 4081 4082 function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) { 4083 if (!line.widgets) return; 4084 var wrap = ensureLineWrapped(lineView); 4085 for (var i = 0, ws = line.widgets; i < ws.length; ++i) { 4086 var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); 4087 if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true"); 4088 positionLineWidget(widget, node, lineView, dims); 4089 cm.display.input.setUneditable(node); 4090 if (allowAbove && widget.above) 4091 wrap.insertBefore(node, lineView.gutter || lineView.text); 4092 else 4093 wrap.appendChild(node); 4094 signalLater(widget, "redraw"); 4095 } 4096 } 4097 4098 function positionLineWidget(widget, node, lineView, dims) { 4099 if (widget.noHScroll) { 4100 (lineView.alignable || (lineView.alignable = [])).push(node); 4101 var width = dims.wrapperWidth; 4102 node.style.left = dims.fixedPos + "px"; 4103 if (!widget.coverGutter) { 4104 width -= dims.gutterTotalWidth; 4105 node.style.paddingLeft = dims.gutterTotalWidth + "px"; 4106 } 4107 node.style.width = width + "px"; 4108 } 4109 if (widget.coverGutter) { 4110 node.style.zIndex = 5; 4111 node.style.position = "relative"; 4112 if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px"; 4113 } 4114 } 4115 4116 // POSITION OBJECT 4117 4118 // A Pos instance represents a position within the text. 4119 var Pos = CodeMirror.Pos = function(line, ch) { 4120 if (!(this instanceof Pos)) return new Pos(line, ch); 4121 this.line = line; this.ch = ch; 4122 }; 4123 4124 // Compare two positions, return 0 if they are the same, a negative 4125 // number when a is less, and a positive number otherwise. 4126 var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; }; 4127 4128 function copyPos(x) {return Pos(x.line, x.ch);} 4129 function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; } 4130 function minPos(a, b) { return cmp(a, b) < 0 ? a : b; } 4131 4132 // INPUT HANDLING 4133 4134 function ensureFocus(cm) { 4135 if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); } 4136 } 4137 4138
4138function isReadOnly(cm) { 4139 return cm.options.readOnly || cm.doc.cantEdit; 4140 } 4141 4142 // This will be set to an array of strings when copying, so that, 4143 // when pasting, we know what kind of selections the copied text 4144 // was made out of. 4145 var lastCopied = null; 4146 4147 function applyTextInput(cm, inserted, deleted, sel, origin) { 4148 var doc = cm.doc; 4149 cm.display.shift = false; 4150 if (!sel) sel = doc.sel; 4151 4152 var paste = cm.state.pasteIncoming || origin == "paste"; 4153 var textLines = doc.splitLines(inserted), multiPaste = null; 4154 // When pasing N lines into N selections, insert one line per selection 4155 if (paste && sel.ranges.length > 1) { 4156 if (lastCopied && lastCopied.join("\n") == inserted) { 4157 if (sel.ranges.length % lastCopied.length == 0) { 4158 multiPaste = []; 4159 for (var i = 0; i < lastCopied.length; i++) 4160 multiPaste.push(doc.splitLines(lastCopied[i])); 4161 } 4162 } else if (textLines.length == sel.ranges.length) { 4163 multiPaste = map(textLines, function(l) { return [l]; }); 4164 } 4165 } 4166 4167 // Normal behavior is to insert the new text into every selection 4168 for (var i = sel.ranges.length - 1; i >= 0; i--) { 4169 var range = sel.ranges[i]; 4170 var from = range.from(), to = range.to(); 4171 if (range.empty()) { 4172 if (deleted && deleted > 0) // Handle deletion 4173 from = Pos(from.line, from.ch - deleted); 4174 else if (cm.state.overwrite && !paste) // Handle overwrite 4175 to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); 4176 } 4177 var updateInput = cm.curOp.updateInput; 4178 var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines, 4179 origin: origin || (paste ? "paste" : cm.state.cutIncoming ? "cut" : "+input")}; 4180 makeChange(cm.doc, changeEvent); 4181 signalLater(cm, "inputRead", cm, changeEvent); 4182 } 4183 if (inserted && !paste) 4184 triggerElectric(cm, inserted); 4185 4186 ensureCursorVisible(cm); 4187 cm.curOp.updateInput = updateInput; 4188 cm.curOp.typing = true; 4189 cm.state.pasteIncoming = cm.state.cutIncoming = false;
vendor: 21,341 bytes, lines 4190-4737
4190 } 4191 4192 function handlePaste(e, cm) { 4193 var pasted = e.clipboardData && e.clipboardData.getData("text/plain"); 4194 if (pasted) { 4195 e.preventDefault(); 4196 if (!isReadOnly(cm) && !cm.options.disableInput) 4197 runInOp(cm, function() { applyTextInput(cm, pasted, 0, null, "paste"); }); 4198 return true; 4199 } 4200 } 4201 4202 function triggerElectric(cm, inserted) { 4203 // When an 'electric' character is inserted, immediately trigger a reindent 4204 if (!cm.options.electricChars || !cm.options.smartIndent) return; 4205 var sel = cm.doc.sel; 4206 4207 for (var i = sel.ranges.length - 1; i >= 0; i--) { 4208 var range = sel.ranges[i]; 4209 if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue; 4210 var mode = cm.getModeAt(range.head); 4211 var indented = false; 4212 if (mode.electricChars) { 4213 for (var j = 0; j < mode.electricChars.length; j++) 4214 if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { 4215 indented = indentLine(cm, range.head.line, "smart"); 4216 break; 4217 } 4218 } else if (mode.electricInput) { 4219 if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch))) 4220 indented = indentLine(cm, range.head.line, "smart"); 4221 } 4222 if (indented) signalLater(cm, "electricInput", cm, range.head.line); 4223 } 4224 } 4225 4226 function copyableRanges(cm) { 4227 var text = [], ranges = []; 4228 for (var i = 0; i < cm.doc.sel.ranges.length; i++) { 4229 var line = cm.doc.sel.ranges[i].head.line; 4230 var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)}; 4231 ranges.push(lineRange); 4232 text.push(cm.getRange(lineRange.anchor, lineRange.head)); 4233 } 4234 return {text: text, ranges: ranges}; 4235 } 4236 4237 function disableBrowserMagic(field) { 4238 field.setAttribute("autocorrect", "off"); 4239 field.setAttribute("autocapitalize", "off"); 4240 field.setAttribute("spellcheck", "false"); 4241 } 4242 4243 // TEXTAREA INPUT STYLE 4244 4245 function TextareaInput(cm) { 4246 this.cm = cm; 4247 // See input.poll and input.reset 4248 this.prevInput = ""; 4249 4250 // Flag that indicates whether we expect input to appear real soon 4251 // now (after some event like 'keypress' or 'input') and are 4252 // polling intensively. 4253 this.pollingFast = false; 4254 // Self-resetting timeout for the poller 4255 this.polling = new Delayed(); 4256 // Tracks when input.reset has punted to just putting a short 4257 // string into the textarea instead of the full selection. 4258 this.inaccurateSelection = false; 4259 // Used to work around IE issue with selection being forgotten when focus moves away from textarea 4260 this.hasSelection = false; 4261 this.composing = null; 4262 }; 4263 4264 function hiddenTextarea() { 4265 var te = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none"); 4266 var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); 4267 // The textarea is kept positioned near the cursor to prevent the 4268 // fact that it'll be scrolled into view on input from scrolling 4269 // our fake cursor out of view. On webkit, when wrap=off, paste is 4270 // very slow. So make the area wide instead. 4271 if (webkit) te.style.width = "1000px"; 4272 else te.setAttribute("wrap", "off"); 4273 // If border: 0; -- iOS fails to open keyboard (issue #1287) 4274 if (ios) te.style.border = "1px solid black"; 4275 disableBrowserMagic(te); 4276 return div; 4277 } 4278 4279 TextareaInput.prototype = copyObj({ 4280 init: function(display) { 4281 var input = this, cm = this.cm; 4282 4283 // Wraps and hides input textarea 4284 var div = this.wrapper = hiddenTextarea(); 4285 // The semihidden textarea that is focused when the editor is 4286 // focused, and receives input. 4287 var te = this.textarea = div.firstChild; 4288 display.wrapper.insertBefore(div, display.wrapper.firstChild); 4289 4290 // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) 4291 if (ios) te.style.width = "0px"; 4292 4293 on(te, "input", function() { 4294 if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null; 4295 input.poll(); 4296 }); 4297 4298 on(te, "paste", function(e) { 4299 if (handlePaste(e, cm)) return true; 4300 4301 cm.state.pasteIncoming = true; 4302 input.fastPoll(); 4303 }); 4304 4305 function prepareCopyCut(e) { 4306 if (cm.somethingSelected()) { 4307 lastCopied = cm.getSelections(); 4308 if (input.inaccurateSelection) { 4309 input.prevInput = ""; 4310 input.inaccurateSelection = false; 4311 te.value = lastCopied.join("\n"); 4312 selectInput(te); 4313 } 4314 } else if (!cm.options.lineWiseCopyCut) { 4315 return; 4316 } else { 4317 var ranges = copyableRanges(cm); 4318 lastCopied = ranges.text; 4319 if (e.type == "cut") { 4320 cm.setSelections(ranges.ranges, null, sel_dontScroll); 4321 } else { 4322 input.prevInput = ""; 4323 te.value = ranges.text.join("\n"); 4324 selectInput(te); 4325 } 4326 } 4327 if (e.type == "cut") cm.state.cutIncoming = true; 4328 } 4329 on(te, "cut", prepareCopyCut); 4330 on(te, "copy", prepareCopyCut); 4331 4332 on(display.scroller, "paste", function(e) { 4333 if (eventInWidget(display, e)) return; 4334 cm.state.pasteIncoming = true; 4335 input.focus(); 4336 }); 4337 4338 // Prevent normal selection in the editor (we handle our own) 4339 on(display.lineSpace, "selectstart", function(e) { 4340 if (!eventInWidget(display, e)) e_preventDefault(e); 4341 }); 4342 4343 on(te, "compositionstart", function() { 4344 var start = cm.getCursor("from"); 4345 if (input.composing) input.composing.range.clear() 4346 input.composing = { 4347 start: start, 4348 range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"}) 4349 }; 4350 }); 4351 on(te, "compositionend", function() { 4352 if (input.composing) { 4353 input.poll(); 4354 input.composing.range.clear(); 4355 input.composing = null; 4356 } 4357 }); 4358 }, 4359 4360 prepareSelection: function() { 4361 // Redraw the selection and/or cursor 4362 var cm = this.cm, display = cm.display, doc = cm.doc; 4363 var result = prepareSelection(cm); 4364 4365 // Move the hidden textarea near the cursor to prevent scrolling artifacts 4366 if (cm.options.moveInputWithCursor) { 4367 var headPos = cursorCoords(cm, doc.sel.primary().head, "div"); 4368 var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect(); 4369 result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10, 4370 headPos.top + lineOff.top - wrapOff.top)); 4371 result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10, 4372 headPos.left + lineOff.left - wrapOff.left)); 4373 } 4374 4375 return result; 4376 }, 4377 4378 showSelection: function(drawn) { 4379 var cm = this.cm, display = cm.display; 4380 removeChildrenAndAdd(display.cursorDiv, drawn.cursors); 4381 removeChildrenAndAdd(display.selectionDiv, drawn.selection); 4382 if (drawn.teTop != null) { 4383 this.wrapper.style.top = drawn.teTop + "px"; 4384 this.wrapper.style.left = drawn.teLeft + "px"; 4385 } 4386 }, 4387 4388 // Reset the input to correspond to the selection (or to be empty, 4389 // when not typing and nothing is selected) 4390 reset: function(typing) { 4391 if (this.contextMenuPending) return; 4392 var minimal, selected, cm = this.cm, doc = cm.doc; 4393 if (cm.somethingSelected()) { 4394 this.prevInput = ""; 4395 var range = doc.sel.primary(); 4396 minimal = hasCopyEvent && 4397 (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000); 4398 var content = minimal ? "-" : selected || cm.getSelection(); 4399 this.textarea.value = content; 4400 if (cm.state.focused) selectInput(this.textarea); 4401 if (ie && ie_version >= 9) this.hasSelection = content; 4402 } else if (!typing) { 4403 this.prevInput = this.textarea.value = ""; 4404 if (ie && ie_version >= 9) this.hasSelection = null; 4405 } 4406 this.inaccurateSelection = minimal; 4407 }, 4408 4409 getField: function() { return this.textarea; }, 4410 4411 supportsTouch: function() { return false; }, 4412 4413 focus: function() { 4414 if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { 4415 try { this.textarea.focus(); } 4416 catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM 4417 } 4418 }, 4419 4420 blur: function() { this.textarea.blur(); }, 4421 4422 resetPosition: function() { 4423 this.wrapper.style.top = this.wrapper.style.left = 0; 4424 }, 4425 4426 receivedFocus: function() { this.slowPoll(); }, 4427 4428 // Poll for input changes, using the normal rate of polling. This 4429 // runs as long as the editor is focused. 4430 slowPoll: function() { 4431 var input = this; 4432 if (input.pollingFast) return; 4433 input.polling.set(this.cm.options.pollInterval, function() { 4434 input.poll(); 4435 if (input.cm.state.focused) input.slowPoll(); 4436 }); 4437 }, 4438 4439 // When an event has just come in that is likely to add or change 4440 // something in the input textarea, we poll faster, to ensure that 4441 // the change appears on the screen quickly. 4442 fastPoll: function() { 4443 var missed = false, input = this; 4444 input.pollingFast = true; 4445 function p() { 4446 var changed = input.poll(); 4447 if (!changed && !missed) {missed = true; input.polling.set(60, p);} 4448 else {input.pollingFast = false; input.slowPoll();} 4449 } 4450 input.polling.set(20, p); 4451 }, 4452 4453 // Read input from the textarea, and update the document to match. 4454 // When something is selected, it is present in the textarea, and 4455 // selected (unless it is huge, in which case a placeholder is 4456 // used). When nothing is selected, the cursor sits after previously 4457 // seen text (can be empty), which is stored in prevInput (we must 4458 // not reset the textarea when typing, because that breaks IME). 4459 poll: function() { 4460 var cm = this.cm, input = this.textarea, prevInput = this.prevInput; 4461 // Since this is called a *lot*, try to bail out as cheaply as 4462 // possible when it is clear that nothing happened. hasSelection 4463 // will be the case when there is a lot of text in the textarea, 4464 // in which case reading its value would be expensive. 4465 if (this.contextMenuPending || !cm.state.focused || 4466 (hasSelection(input) && !prevInput && !this.composing) || 4467 isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq) 4468 return false; 4469 4470 var text = input.value; 4471 // If nothing changed, bail. 4472 if (text == prevInput && !cm.somethingSelected()) return false; 4473 // Work around nonsensical selection resetting in IE9/10, and 4474 // inexplicable appearance of private area unicode characters on 4475 // some key combos in Mac (#2689). 4476 if (ie && ie_version >= 9 && this.hasSelection === text || 4477 mac && /[\uf700-\uf7ff]/.test(text)) { 4478 cm.display.input.reset(); 4479 return false; 4480 } 4481 4482 if (cm.doc.sel == cm.display.selForContextMenu) { 4483 var first = text.charCodeAt(0); 4484 if (first == 0x200b && !prevInput) prevInput = "\u200b"; 4485 if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); } 4486 } 4487 // Find the part of the input that is actually new 4488 var same = 0, l = Math.min(prevInput.length, text.length); 4489 while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; 4490 4491 var self = this; 4492 runInOp(cm, function() { 4493 applyTextInput(cm, text.slice(same), prevInput.length - same, 4494 null, self.composing ? "*compose" : null); 4495 4496 // Don't leave long text in the textarea, since it makes further polling slow 4497 if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = ""; 4498 else self.prevInput = text; 4499 4500 if (self.composing) { 4501 self.composing.range.clear(); 4502 self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"), 4503 {className: "CodeMirror-composing"}); 4504 } 4505 }); 4506 return true; 4507 }, 4508 4509 ensurePolled: function() { 4510 if (this.pollingFast && this.poll()) this.pollingFast = false; 4511 }, 4512 4513 onKeyPress: function() { 4514 if (ie && ie_version >= 9) this.hasSelection = null; 4515 this.fastPoll(); 4516 }, 4517 4518 onContextMenu: function(e) { 4519 var input = this, cm = input.cm, display = cm.display, te = input.textarea; 4520 var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; 4521 if (!pos || presto) return; // Opera is difficult. 4522 4523 // Reset the current text selection only if the click is done outside of the selection 4524 // and 'resetSelectionOnContextMenu' option is true. 4525 var reset = cm.options.resetSelectionOnContextMenu; 4526 if (reset && cm.doc.sel.contains(pos) == -1) 4527 operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); 4528 4529 var oldCSS = te.style.cssText; 4530 input.wrapper.style.position = "absolute"; 4531 te.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) + 4532 "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " + 4533 (ie ? "rgba(255, 255, 255, .05)" : "transparent") + 4534 "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; 4535 if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712) 4536 display.input.focus(); 4537 if (webkit) window.scrollTo(null, oldScrollY); 4538 display.input.reset(); 4539 // Adds "Select all" to context menu in FF 4540 if (!cm.somethingSelected()) te.value = input.prevInput = " "; 4541 input.contextMenuPending = true; 4542 display.selForContextMenu = cm.doc.sel; 4543 clearTimeout(display.detectingSelectAll); 4544 4545 // Select-all will be greyed out if there's nothing to select, so 4546 // this adds a zero-width space so that we can later check whether 4547 // it got selected. 4548 function prepareSelectAllHack() { 4549 if (te.selectionStart != null) { 4550 var selected = cm.somethingSelected(); 4551 var extval = "\u200b" + (selected ? te.value : ""); 4552 te.value = "\u21da"; // Used to catch context-menu undo 4553 te.value = extval; 4554 input.prevInput = selected ? "" : "\u200b"; 4555 te.selectionStart = 1; te.selectionEnd = extval.length; 4556 // Re-set this, in case some other handler touched the 4557 // selection in the meantime. 4558 display.selForContextMenu = cm.doc.sel; 4559 } 4560 } 4561 function rehide() { 4562 input.contextMenuPending = false; 4563 input.wrapper.style.position = "relative"; 4564 te.style.cssText = oldCSS; 4565 if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos); 4566 4567 // Try to detect the user choosing select-all 4568 if (te.selectionStart != null) { 4569 if (!ie || (ie && ie_version < 9)) prepareSelectAllHack(); 4570 var i = 0, poll = function() { 4571 if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 && 4572 te.selectionEnd > 0 && input.prevInput == "\u200b") 4573 operation(cm, commands.selectAll)(cm); 4574 else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500); 4575 else display.input.reset(); 4576 }; 4577 display.detectingSelectAll = setTimeout(poll, 200); 4578 } 4579 } 4580 4581 if (ie && ie_version >= 9) prepareSelectAllHack(); 4582 if (captureRightClick) { 4583 e_stop(e); 4584 var mouseup = function() { 4585 off(window, "mouseup", mouseup); 4586 setTimeout(rehide, 20); 4587 }; 4588 on(window, "mouseup", mouseup); 4589 } else { 4590 setTimeout(rehide, 50); 4591 } 4592 }, 4593 4594 readOnlyChanged: function(val) { 4595 if (!val) this.reset(); 4596 }, 4597 4598 setUneditable: nothing, 4599 4600 needsContentAttribute: false 4601 }, TextareaInput.prototype); 4602 4603 // CONTENTEDITABLE INPUT STYLE 4604 4605 function ContentEditableInput(cm) { 4606 this.cm = cm; 4607 this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null; 4608 this.polling = new Delayed(); 4609 this.gracePeriod = false; 4610 } 4611 4612 ContentEditableInput.prototype = copyObj({ 4613 init: function(display) { 4614 var input = this, cm = input.cm; 4615 var div = input.div = display.lineDiv; 4616 disableBrowserMagic(div); 4617 4618 on(div, "paste", function(e) { handlePaste(e, cm); }) 4619 4620 on(div, "compositionstart", function(e) { 4621 var data = e.data; 4622 input.composing = {sel: cm.doc.sel, data: data, startData: data}; 4623 if (!data) return; 4624 var prim = cm.doc.sel.primary(); 4625 var line = cm.getLine(prim.head.line); 4626 var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length)); 4627 if (found > -1 && found <= prim.head.ch) 4628 input.composing.sel = simpleSelection(Pos(prim.head.line, found), 4629 Pos(prim.head.line, found + data.length)); 4630 }); 4631 on(div, "compositionupdate", function(e) { 4632 input.composing.data = e.data; 4633 }); 4634 on(div, "compositionend", function(e) { 4635 var ours = input.composing; 4636 if (!ours) return; 4637 if (e.data != ours.startData && !/\u200b/.test(e.data)) 4638 ours.data = e.data; 4639 // Need a small delay to prevent other code (input event, 4640 // selection polling) from doing damage when fired right after 4641 // compositionend. 4642 setTimeout(function() { 4643 if (!ours.handled) 4644 input.applyComposition(ours); 4645 if (input.composing == ours) 4646 input.composing = null; 4647 }, 50); 4648 }); 4649 4650 on(div, "touchstart", function() { 4651 input.forceCompositionEnd(); 4652 }); 4653 4654 on(div, "input", function() { 4655 if (input.composing) return; 4656 if (isReadOnly(cm) || !input.pollContent()) 4657 runInOp(input.cm, function() {regChange(cm);}); 4658 }); 4659 4660 function onCopyCut(e) { 4661 if (cm.somethingSelected()) { 4662 lastCopied = cm.getSelections(); 4663 if (e.type == "cut") cm.replaceSelection("", null, "cut"); 4664 } else if (!cm.options.lineWiseCopyCut) { 4665 return; 4666 } else { 4667 var ranges = copyableRanges(cm); 4668 lastCopied = ranges.text; 4669 if (e.type == "cut") { 4670 cm.operation(function() { 4671 cm.setSelections(ranges.ranges, 0, sel_dontScroll); 4672 cm.replaceSelection("", null, "cut"); 4673 }); 4674 } 4675 } 4676 // iOS exposes the clipboard API, but seems to discard content inserted into it 4677 if (e.clipboardData && !ios) { 4678 e.preventDefault(); 4679 e.clipboardData.clearData(); 4680 e.clipboardData.setData("text/plain", lastCopied.join("\n")); 4681 } else { 4682 // Old-fashioned briefly-focus-a-textarea hack 4683 var kludge = hiddenTextarea(), te = kludge.firstChild; 4684 cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild); 4685 te.value = lastCopied.join("\n"); 4686 var hadFocus = document.activeElement; 4687 selectInput(te); 4688 setTimeout(function() { 4689 cm.display.lineSpace.removeChild(kludge); 4690 hadFocus.focus(); 4691 }, 50); 4692 } 4693 } 4694 on(div, "copy", onCopyCut); 4695 on(div, "cut", onCopyCut); 4696 }, 4697 4698 prepareSelection: function() { 4699 var result = prepareSelection(this.cm, false); 4700 result.focus = this.cm.state.focused; 4701 return result; 4702 }, 4703 4704 showSelection: function(info) { 4705 if (!info || !this.cm.display.view.length) return; 4706 if (info.focus) this.showPrimarySelection(); 4707 this.showMultipleSelections(info); 4708 }, 4709 4710 showPrimarySelection: function() { 4711 var sel = window.getSelection(), prim = this.cm.doc.sel.primary(); 4712 var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset); 4713 var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset); 4714 if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad && 4715 cmp(minPos(curAnchor, curFocus), prim.from()) == 0 && 4716 cmp(maxPos(curAnchor, curFocus), prim.to()) == 0) 4717 return; 4718 4719 var start = posToDOM(this.cm, prim.from()); 4720 var end = posToDOM(this.cm, prim.to()); 4721 if (!start && !end) return; 4722 4723 var view = this.cm.display.view; 4724 var old = sel.rangeCount && sel.getRangeAt(0); 4725 if (!start) { 4726 start = {node: view[0].measure.map[2], offset: 0}; 4727 } else if (!end) { // FIXME dangerously hacky 4728 var measure = view[view.length - 1].measure; 4729 var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map; 4730 end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]}; 4731 } 4732 4733 try { var rng = range(start.node, start.offset, end.offset, end.node); } 4734 catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible 4735 if (rng) { 4736 sel.removeAllRanges(); 4737 sel.addRange(rng);
vendor: 5,598 bytes, lines 4737-4881
4737 4738 if (old && sel.anchorNode == null) sel.addRange(old); 4739 else if (gecko) this.startGracePeriod(); 4740 } 4741 this.rememberSelection(); 4742 }, 4743 4744 startGracePeriod: function() { 4745 var input = this; 4746 clearTimeout(this.gracePeriod); 4747 this.gracePeriod = setTimeout(function() { 4748 input.gracePeriod = false; 4749 if (input.selectionChanged()) 4750 input.cm.operation(function() { input.cm.curOp.selectionChanged = true; }); 4751 }, 20); 4752 }, 4753 4754 showMultipleSelections: function(info) { 4755 removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors); 4756 removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection); 4757 }, 4758 4759 rememberSelection: function() { 4760 var sel = window.getSelection(); 4761 this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset; 4762 this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset; 4763 }, 4764 4765 selectionInEditor: function() { 4766 var sel = window.getSelection(); 4767 if (!sel.rangeCount) return false; 4768 var node = sel.getRangeAt(0).commonAncestorContainer; 4769 return contains(this.div, node); 4770 }, 4771 4772 focus: function() { 4773 if (this.cm.options.readOnly != "nocursor") this.div.focus(); 4774 }, 4775 blur: function() { this.div.blur(); }, 4776 getField: function() { return this.div; }, 4777 4778 supportsTouch: function() { return true; }, 4779 4780 receivedFocus: function() { 4781 var input = this; 4782 if (this.selectionInEditor()) 4783 this.pollSelection(); 4784 else 4785 runInOp(this.cm, function() { input.cm.curOp.selectionChanged = true; }); 4786 4787 function poll() { 4788 if (input.cm.state.focused) { 4789 input.pollSelection(); 4790 input.polling.set(input.cm.options.pollInterval, poll); 4791 } 4792 } 4793 this.polling.set(this.cm.options.pollInterval, poll); 4794 }, 4795 4796 selectionChanged: function() { 4797 var sel = window.getSelection(); 4798 return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || 4799 sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset; 4800 }, 4801 4802 pollSelection: function() { 4803 if (!this.composing && !this.gracePeriod && this.selectionChanged()) { 4804 var sel = window.getSelection(), cm = this.cm; 4805 this.rememberSelection(); 4806 var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset); 4807 var head = domToPos(cm, sel.focusNode, sel.focusOffset); 4808 if (anchor && head) runInOp(cm, function() { 4809 setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll); 4810 if (anchor.bad || head.bad) cm.curOp.selectionChanged = true; 4811 }); 4812 } 4813 }, 4814 4815 pollContent: function() { 4816 var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary(); 4817 var from = sel.from(), to = sel.to(); 4818 if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false; 4819 4820 var fromIndex; 4821 if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { 4822 var fromLine = lineNo(display.view[0].line); 4823 var fromNode = display.view[0].node; 4824 } else { 4825 var fromLine = lineNo(display.view[fromIndex].line); 4826 var fromNode = display.view[fromIndex - 1].node.nextSibling; 4827 } 4828 var toIndex = findViewIndex(cm, to.line); 4829 if (toIndex == display.view.length - 1) { 4830 var toLine = display.viewTo - 1; 4831 var toNode = display.lineDiv.lastChild; 4832 } else { 4833 var toLine = lineNo(display.view[toIndex + 1].line) - 1; 4834 var toNode = display.view[toIndex + 1].node.previousSibling; 4835 } 4836 4837 var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine)); 4838 var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length)); 4839 while (newText.length > 1 && oldText.length > 1) { 4840 if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; } 4841 else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; } 4842 else break; 4843 } 4844 4845 var cutFront = 0, cutEnd = 0; 4846 var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length); 4847 while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront)) 4848 ++cutFront; 4849 var newBot = lst(newText), oldBot = lst(oldText); 4850 var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0), 4851 oldBot.length - (oldText.length == 1 ? cutFront : 0)); 4852 while (cutEnd < maxCutEnd && 4853 newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) 4854 ++cutEnd; 4855 4856 newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd); 4857 newText[0] = newText[0].slice(cutFront); 4858 4859 var chFrom = Pos(fromLine, cutFront); 4860 var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0); 4861 if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) { 4862 replaceRange(cm.doc, newText, chFrom, chTo, "+input"); 4863 return true; 4864 } 4865 }, 4866 4867 ensurePolled: function() { 4868 this.forceCompositionEnd(); 4869 }, 4870 reset: function() { 4871 this.forceCompositionEnd(); 4872 }, 4873 forceCompositionEnd: function() { 4874 if (!this.composing || this.composing.handled) return; 4875 this.applyComposition(this.composing); 4876 this.composing.handled = true; 4877 this.div.blur(); 4878 this.div.focus(); 4879 }, 4880 applyComposition: function(composing) { 4881 if (
4881isReadOnly(this.cm)) 4882 operation(this.cm, regChange)(this.cm) 4883 else if (composing.data && composing.data != composing.startData) 4884 operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel); 4885 }, 4886 4887 setUneditable: function(node) { 4888 node.contentEditable = "false" 4889 }, 4890 4891 onKeyPress: function(e) { 4892 e.preventDefault(); 4893 if (!isReadOnly(this.cm
vendor: 11,411 bytes, lines 4893-5198
4893)) 4894 operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); 4895 }, 4896 4897 readOnlyChanged: function(val) { 4898 this.div.contentEditable = String(val != "nocursor") 4899 }, 4900 4901 onContextMenu: nothing, 4902 resetPosition: nothing, 4903 4904 needsContentAttribute: true 4905 }, ContentEditableInput.prototype); 4906 4907 function posToDOM(cm, pos) { 4908 var view = findViewForLine(cm, pos.line); 4909 if (!view || view.hidden) return null; 4910 var line = getLine(cm.doc, pos.line); 4911 var info = mapFromLineView(view, line, pos.line); 4912 4913 var order = getOrder(line), side = "left"; 4914 if (order) { 4915 var partPos = getBidiPartAt(order, pos.ch); 4916 side = partPos % 2 ? "right" : "left"; 4917 } 4918 var result = nodeAndOffsetInLineMap(info.map, pos.ch, side); 4919 result.offset = result.collapse == "right" ? result.end : result.start; 4920 return result; 4921 } 4922 4923 function badPos(pos, bad) { if (bad) pos.bad = true; return pos; } 4924 4925 function domToPos(cm, node, offset) { 4926 var lineNode; 4927 if (node == cm.display.lineDiv) { 4928 lineNode = cm.display.lineDiv.childNodes[offset]; 4929 if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true); 4930 node = null; offset = 0; 4931 } else { 4932 for (lineNode = node;; lineNode = lineNode.parentNode) { 4933 if (!lineNode || lineNode == cm.display.lineDiv) return null; 4934 if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break; 4935 } 4936 } 4937 for (var i = 0; i < cm.display.view.length; i++) { 4938 var lineView = cm.display.view[i]; 4939 if (lineView.node == lineNode) 4940 return locateNodeInLineView(lineView, node, offset); 4941 } 4942 } 4943 4944 function locateNodeInLineView(lineView, node, offset) { 4945 var wrapper = lineView.text.firstChild, bad = false; 4946 if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true); 4947 if (node == wrapper) { 4948 bad = true; 4949 node = wrapper.childNodes[offset]; 4950 offset = 0; 4951 if (!node) { 4952 var line = lineView.rest ? lst(lineView.rest) : lineView.line; 4953 return badPos(Pos(lineNo(line), line.text.length), bad); 4954 } 4955 } 4956 4957 var textNode = node.nodeType == 3 ? node : null, topNode = node; 4958 if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { 4959 textNode = node.firstChild; 4960 if (offset) offset = textNode.nodeValue.length; 4961 } 4962 while (topNode.parentNode != wrapper) topNode = topNode.parentNode; 4963 var measure = lineView.measure, maps = measure.maps; 4964 4965 function find(textNode, topNode, offset) { 4966 for (var i = -1; i < (maps ? maps.length : 0); i++) { 4967 var map = i < 0 ? measure.map : maps[i]; 4968 for (var j = 0; j < map.length; j += 3) { 4969 var curNode = map[j + 2]; 4970 if (curNode == textNode || curNode == topNode) { 4971 var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]); 4972 var ch = map[j] + offset; 4973 if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)]; 4974 return Pos(line, ch); 4975 } 4976 } 4977 } 4978 } 4979 var found = find(textNode, topNode, offset); 4980 if (found) return badPos(found, bad); 4981 4982 // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems 4983 for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { 4984 found = find(after, after.firstChild, 0); 4985 if (found) 4986 return badPos(Pos(found.line, found.ch - dist), bad); 4987 else 4988 dist += after.textContent.length; 4989 } 4990 for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) { 4991 found = find(before, before.firstChild, -1); 4992 if (found) 4993 return badPos(Pos(found.line, found.ch + dist), bad); 4994 else 4995 dist += after.textContent.length; 4996 } 4997 } 4998 4999 function domTextBetween(cm, from, to, fromLine, toLine) { 5000 var text = "", closing = false, lineSep = cm.doc.lineSeparator(); 5001 function recognizeMarker(id) { return function(marker) { return marker.id == id; }; } 5002 function walk(node) { 5003 if (node.nodeType == 1) { 5004 var cmText = node.getAttribute("cm-text"); 5005 if (cmText != null) { 5006 if (cmText == "") cmText = node.textContent.replace(/\u200b/g, ""); 5007 text += cmText; 5008 return; 5009 } 5010 var markerID = node.getAttribute("cm-marker"), range; 5011 if (markerID) { 5012 var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID)); 5013 if (found.length && (range = found[0].find())) 5014 text += getBetween(cm.doc, range.from, range.to).join(lineSep); 5015 return; 5016 } 5017 if (node.getAttribute("contenteditable") == "false") return; 5018 for (var i = 0; i < node.childNodes.length; i++) 5019 walk(node.childNodes[i]); 5020 if (/^(pre|div|p)$/i.test(node.nodeName)) 5021 closing = true; 5022 } else if (node.nodeType == 3) { 5023 var val = node.nodeValue; 5024 if (!val) return; 5025 if (closing) { 5026 text += lineSep; 5027 closing = false; 5028 } 5029 text += val; 5030 } 5031 } 5032 for (;;) { 5033 walk(from); 5034 if (from == to) break; 5035 from = from.nextSibling; 5036 } 5037 return text; 5038 } 5039 5040 CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput}; 5041 5042 // SELECTION / CURSOR 5043 5044 // Selection objects are immutable. A new one is created every time 5045 // the selection changes. A selection is one or more non-overlapping 5046 // (and non-touching) ranges, sorted, and an integer that indicates 5047 // which one is the primary selection (the one that's scrolled into 5048 // view, that getCursor returns, etc). 5049 function Selection(ranges, primIndex) { 5050 this.ranges = ranges; 5051 this.primIndex = primIndex; 5052 } 5053 5054 Selection.prototype = { 5055 primary: function() { return this.ranges[this.primIndex]; }, 5056 equals: function(other) { 5057 if (other == this) return true; 5058 if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false; 5059 for (var i = 0; i < this.ranges.length; i++) { 5060 var here = this.ranges[i], there = other.ranges[i]; 5061 if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false; 5062 } 5063 return true; 5064 }, 5065 deepCopy: function() { 5066 for (var out = [], i = 0; i < this.ranges.length; i++) 5067 out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); 5068 return new Selection(out, this.primIndex); 5069 }, 5070 somethingSelected: function() { 5071 for (var i = 0; i < this.ranges.length; i++) 5072 if (!this.ranges[i].empty()) return true; 5073 return false; 5074 }, 5075 contains: function(pos, end) { 5076 if (!end) end = pos; 5077 for (var i = 0; i < this.ranges.length; i++) { 5078 var range = this.ranges[i]; 5079 if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) 5080 return i; 5081 } 5082 return -1; 5083 } 5084 }; 5085 5086 function Range(anchor, head) { 5087 this.anchor = anchor; this.head = head; 5088 } 5089 5090 Range.prototype = { 5091 from: function() { return minPos(this.anchor, this.head); }, 5092 to: function() { return maxPos(this.anchor, this.head); }, 5093 empty: function() { 5094 return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch; 5095 } 5096 }; 5097 5098 // Take an unsorted, potentially overlapping set of ranges, and 5099 // build a selection out of it. 'Consumes' ranges array (modifying 5100 // it). 5101 function normalizeSelection(ranges, primIndex) { 5102 var prim = ranges[primIndex]; 5103 ranges.sort(function(a, b) { return cmp(a.from(), b.from()); }); 5104 primIndex = indexOf(ranges, prim); 5105 for (var i = 1; i < ranges.length; i++) { 5106 var cur = ranges[i], prev = ranges[i - 1]; 5107 if (cmp(prev.to(), cur.from()) >= 0) { 5108 var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); 5109 var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; 5110 if (i <= primIndex) --primIndex; 5111 ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); 5112 } 5113 } 5114 return new Selection(ranges, primIndex); 5115 } 5116 5117 function simpleSelection(anchor, head) { 5118 return new Selection([new Range(anchor, head || anchor)], 0); 5119 } 5120 5121 // Most of the external API clips given positions to make sure they 5122 // actually exist within the document. 5123 function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));} 5124 function clipPos(doc, pos) { 5125 if (pos.line < doc.first) return Pos(doc.first, 0); 5126 var last = doc.first + doc.size - 1; 5127 if (pos.line > last) return Pos(last, getLine(doc, last).text.length); 5128 return clipToLen(pos, getLine(doc, pos.line).text.length); 5129 } 5130 function clipToLen(pos, linelen) { 5131 var ch = pos.ch; 5132 if (ch == null || ch > linelen) return Pos(pos.line, linelen); 5133 else if (ch < 0) return Pos(pos.line, 0); 5134 else return pos; 5135 } 5136 function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;} 5137 function clipPosArray(doc, array) { 5138 for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]); 5139 return out; 5140 } 5141 5142 // SELECTION UPDATES 5143 5144 // The 'scroll' parameter given to many of these indicated whether 5145 // the new cursor position should be scrolled into view after 5146 // modifying the selection. 5147 5148 // If shift is held or the extend flag is set, extends a range to 5149 // include a given position (and optionally a second position). 5150 // Otherwise, simply returns the range between the given positions. 5151 // Used for cursor motion and such. 5152 function extendRange(doc, range, head, other) { 5153 if (doc.cm && doc.cm.display.shift || doc.extend) { 5154 var anchor = range.anchor; 5155 if (other) { 5156 var posBefore = cmp(head, anchor) < 0; 5157 if (posBefore != (cmp(other, anchor) < 0)) { 5158 anchor = head; 5159 head = other; 5160 } else if (posBefore != (cmp(head, other) < 0)) { 5161 head = other; 5162 } 5163 } 5164 return new Range(anchor, head); 5165 } else { 5166 return new Range(other || head, head); 5167 } 5168 } 5169 5170 // Extend the primary selection range, discard the rest. 5171 function extendSelection(doc, head, other, options) { 5172 setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options); 5173 } 5174 5175 // Extend all selections (pos is an array of selections with length 5176 // equal the number of selections) 5177 function extendSelections(doc, heads, options) { 5178 for (var out = [], i = 0; i < doc.sel.ranges.length; i++) 5179 out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null); 5180 var newSel = normalizeSelection(out, doc.sel.primIndex); 5181 setSelection(doc, newSel, options); 5182 } 5183 5184 // Updates a single range in the selection. 5185 function replaceOneSelection(doc, i, range, options) { 5186 var ranges = doc.sel.ranges.slice(0); 5187 ranges[i] = range; 5188 setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options); 5189 } 5190 5191 // Reset the selection to a single range. 5192 function setSimpleSelection(doc, anchor, head, options) { 5193 setSelection(doc, simpleSelection(anchor, head), options); 5194 } 5195 5196 // Give beforeSelectionChange handlers a change to influence a 5197 // selection update. 5198 function filterSelectionChange(doc, sel
5198) { 5199 var obj = { 5200 ranges: sel.ranges, 5201 update: function(ranges) { 5202 this.ranges = []; 5203 for (var i = 0; i < ranges.length; i++) 5204 this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), 5205 clipPos(doc, ranges[i].head)); 5206 } 5207 }; 5208 signal(doc, "beforeSelectionChange", doc, obj); 5209 if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); 5210 if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1); 5211 else return sel; 5212 } 5213 5214 function setSelectionReplaceHistory(doc, sel, options) { 5215 var done = doc.history.done, last = lst(done); 5216 if (last && last.ranges) { 5217 done[done.length - 1] = sel; 5218 setSelectionNoUndo(doc, sel, options); 5219 } else { 5220 setSelection(doc, sel, options); 5221 } 5222 } 5223 5224 // Set a new selection. 5225 function setSelection(doc, sel, options) { 5226 setSelectionNoUndo(doc, sel, options); 5227 addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); 5228 } 5229 5230 function setSelectionNoUndo(doc, sel, options) { 5231 if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) 5232 sel = filterSelectionChange(doc, sel); 5233 5234 var bias = options && options.bias || 5235 (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1); 5236 setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); 5237 5238 if (!(options && options.scroll === false) && doc.cm) 5239 ensureCursorVisible(doc.cm); 5240 } 5241 5242 function setSelectionInner(doc, sel) { 5243 if (sel.equals(doc.sel)) return; 5244 5245 doc.sel = sel; 5246 5247 if (doc.cm) { 5248 doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true; 5249 signalCursorActivity(doc.cm); 5250 } 5251 signalLater(doc, "cursorActivity", doc); 5252 } 5253 5254 // Verify that the selection does not partially select any atomic 5255 // marked ranges. 5256 function reCheckSelection(doc) { 5257 setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll); 5258 } 5259 5260 // Return a selection that does not partially select any atomic 5261 // ranges. 5262 function skipAtomicInSelection(doc, sel, bias, mayClear) { 5263 var out; 5264 for (var i = 0; i < sel.ranges.length; i++) { 5265 var range = sel.ranges[i]; 5266 var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear); 5267 var newHead = skipAtomic(doc, range.head, bias, mayClear); 5268 if (out || newAnchor != range.anchor || newHead != range.head) { 5269 if (!out) out = sel.ranges.slice(0, i); 5270 out[i] = new Range(newAnchor, newHead); 5271 } 5272 } 5273 return out ? normalizeSelection(out, sel.primIndex) : sel; 5274 } 5275 5276 // Ensure a given position is not inside an atomic range. 5277 function skipAtomic(doc, pos, bias, mayClear) { 5278 var flipped = false, curPos = pos; 5279 var dir = bias || 1; 5280 doc.cantEdit = false;
5281 search: for (;;) { 5282 var line = getLine(doc, curPos.line); 5283 if (line.markedSpans) { 5284 for (var i = 0; i < line.markedSpans.length; ++i) { 5285 var sp = line.markedSpans[i], m = sp.marker; 5286 if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) && 5287 (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) { 5288 if (mayClear) { 5289 signal(m, "beforeCursorEnter"); 5290 if (m.explicitlyCleared) { 5291 if (!line.markedSpans) break; 5292 else {--i; continue;} 5293 } 5294 } 5295 if (!m.atomic) continue; 5296 var newPos = m.find(dir < 0 ? -1 : 1); 5297 if (cmp(newPos, curPos) == 0) { 5298 newPos.ch += dir; 5299 if (newPos.ch < 0) { 5300 if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1)); 5301 else newPos = null; 5302 } else if (newPos.ch > line.text.length) { 5303 if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0); 5304 else newPos = null; 5305 } 5306 if (!newPos) { 5307 if (flipped) { 5308 // Driven in a corner -- no valid cursor position found at all 5309 // -- try again *with* clearing, if we didn't already 5310 if (!mayClear) return skipAtomic(doc, pos, bias, true); 5311 // Otherwise, turn off editing until further notice, and return the start of the doc 5312 doc.cantEdit = true; 5313 return Pos(doc.first, 0); 5314 } 5315 flipped = true; newPos = pos; dir = -dir; 5316 } 5317 } 5318 curPos = newPos; 5319 continue search; 5320 } 5321 } 5322 } 5323 return curPos; 5324 } 5325 } 5326 5327 // SELECTION DRAWING 5328 5329 function updateSelection(cm) { 5330 cm.display.input.showSelection(cm.display.input.prepareSelection()); 5331 } 5332 5333 function prepareSelection(cm, primary) { 5334 var doc = cm.doc, result = {}; 5335 var curFragment = result.cursors = document.createDocumentFragment(); 5336 var selFragment = result.selection = document.createDocumentFragment(); 5337 5338 for (var i = 0; i < doc.sel.ranges.length; i++) { 5339 if (primary === false && i == doc.sel.primIndex) continue; 5340 var range = doc.sel.ranges[i]
vendor: 15,513 bytes, lines 5340-5712
5340; 5341 var collapsed = range.empty(); 5342 if (collapsed || cm.options.showCursorWhenSelecting) 5343 drawSelectionCursor(cm, range.head, curFragment); 5344 if (!collapsed) 5345 drawSelectionRange(cm, range, selFragment); 5346 } 5347 return result; 5348 } 5349 5350 // Draws a cursor for the given range 5351 function drawSelectionCursor(cm, head, output) { 5352 var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine); 5353 5354 var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); 5355 cursor.style.left = pos.left + "px"; 5356 cursor.style.top = pos.top + "px"; 5357 cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; 5358 5359 if (pos.other) { 5360 // Secondary cursor, shown when on a 'jump' in bi-directional text 5361 var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); 5362 otherCursor.style.display = ""; 5363 otherCursor.style.left = pos.other.left + "px"; 5364 otherCursor.style.top = pos.other.top + "px"; 5365 otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; 5366 } 5367 } 5368 5369 // Draws the given range as a highlighted selection 5370 function drawSelectionRange(cm, range, output) { 5371 var display = cm.display, doc = cm.doc; 5372 var fragment = document.createDocumentFragment(); 5373 var padding = paddingH(cm.display), leftSide = padding.left; 5374 var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right; 5375 5376 function add(left, top, width, bottom) { 5377 if (top < 0) top = 0; 5378 top = Math.round(top); 5379 bottom = Math.round(bottom); 5380 fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left + 5381 "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) + 5382 "px; height: " + (bottom - top) + "px")); 5383 } 5384 5385 function drawForLine(line, fromArg, toArg) { 5386 var lineObj = getLine(doc, line); 5387 var lineLen = lineObj.text.length; 5388 var start, end; 5389 function coords(ch, bias) { 5390 return charCoords(cm, Pos(line, ch), "div", lineObj, bias); 5391 } 5392 5393 iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) { 5394 var leftPos = coords(from, "left"), rightPos, left, right; 5395 if (from == to) { 5396 rightPos = leftPos; 5397 left = right = leftPos.left; 5398 } else { 5399 rightPos = coords(to - 1, "right"); 5400 if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } 5401 left = leftPos.left; 5402 right = rightPos.right; 5403 } 5404 if (fromArg == null && from == 0) left = leftSide; 5405 if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part 5406 add(left, leftPos.top, null, leftPos.bottom); 5407 left = leftSide; 5408 if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); 5409 } 5410 if (toArg == null && to == lineLen) right = rightSide; 5411 if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) 5412 start = leftPos; 5413 if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) 5414 end = rightPos; 5415 if (left < leftSide + 1) left = leftSide; 5416 add(left, rightPos.top, right - left, rightPos.bottom); 5417 }); 5418 return {start: start, end: end}; 5419 } 5420 5421 var sFrom = range.from(), sTo = range.to(); 5422 if (sFrom.line == sTo.line) { 5423 drawForLine(sFrom.line, sFrom.ch, sTo.ch); 5424 } else { 5425 var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); 5426 var singleVLine = visualLine(fromLine) == visualLine(toLine); 5427 var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; 5428 var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; 5429 if (singleVLine) { 5430 if (leftEnd.top < rightStart.top - 2) { 5431 add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); 5432 add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); 5433 } else { 5434 add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); 5435 } 5436 } 5437 if (leftEnd.bottom < rightStart.top) 5438 add(leftSide, leftEnd.bottom, null, rightStart.top); 5439 } 5440 5441 output.appendChild(fragment); 5442 } 5443 5444 // Cursor-blinking 5445 function restartBlink(cm) { 5446 if (!cm.state.focused) return; 5447 var display = cm.display; 5448 clearInterval(display.blinker); 5449 var on = true; 5450 display.cursorDiv.style.visibility = ""; 5451 if (cm.options.cursorBlinkRate > 0) 5452 display.blinker = setInterval(function() { 5453 display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; 5454 }, cm.options.cursorBlinkRate); 5455 else if (cm.options.cursorBlinkRate < 0) 5456 display.cursorDiv.style.visibility = "hidden"; 5457 } 5458 5459 // HIGHLIGHT WORKER 5460 5461 function startWorker(cm, time) { 5462 if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo) 5463 cm.state.highlight.set(time, bind(highlightWorker, cm)); 5464 } 5465 5466 function highlightWorker(cm) { 5467 var doc = cm.doc; 5468 if (doc.frontier < doc.first) doc.frontier = doc.first; 5469 if (doc.frontier >= cm.display.viewTo) return; 5470 var end = +new Date + cm.options.workTime; 5471 var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); 5472 var changedLines = []; 5473 5474 doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) { 5475 if (doc.frontier >= cm.display.viewFrom) { // Visible 5476 var oldStyles = line.styles, tooLong = line.text.length > cm.options.maxHighlightLength; 5477 var highlighted = highlightLine(cm, line, tooLong ? copyState(doc.mode, state) : state, true); 5478 line.styles = highlighted.styles; 5479 var oldCls = line.styleClasses, newCls = highlighted.classes; 5480 if (newCls) line.styleClasses = newCls; 5481 else if (oldCls) line.styleClasses = null; 5482 var ischange = !oldStyles || oldStyles.length != line.styles.length || 5483 oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass); 5484 for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; 5485 if (ischange) changedLines.push(doc.frontier); 5486 line.stateAfter = tooLong ? state : copyState(doc.mode, state); 5487 } else { 5488 if (line.text.length <= cm.options.maxHighlightLength) 5489 processLine(cm, line.text, state); 5490 line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; 5491 } 5492 ++doc.frontier; 5493 if (+new Date > end) { 5494 startWorker(cm, cm.options.workDelay); 5495 return true; 5496 } 5497 }); 5498 if (changedLines.length) runInOp(cm, function() { 5499 for (var i = 0; i < changedLines.length; i++) 5500 regLineChange(cm, changedLines[i], "text"); 5501 }); 5502 } 5503 5504 // Finds the line to start with when starting a parse. Tries to 5505 // find a line with a stateAfter, so that it can start with a 5506 // valid state. If that fails, it returns the line with the 5507 // smallest indentation, which tends to need the least context to 5508 // parse correctly. 5509 function findStartLine(cm, n, precise) { 5510 var minindent, minline, doc = cm.doc; 5511 var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); 5512 for (var search = n; search > lim; --search) { 5513 if (search <= doc.first) return doc.first; 5514 var line = getLine(doc, search - 1); 5515 if (line.stateAfter && (!precise || search <= doc.frontier)) return search; 5516 var indented = countColumn(line.text, null, cm.options.tabSize); 5517 if (minline == null || minindent > indented) { 5518 minline = search - 1; 5519 minindent = indented; 5520 } 5521 } 5522 return minline; 5523 } 5524 5525 function getStateBefore(cm, n, precise) { 5526 var doc = cm.doc, display = cm.display; 5527 if (!doc.mode.startState) return true; 5528 var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; 5529 if (!state) state = startState(doc.mode); 5530 else state = copyState(doc.mode, state); 5531 doc.iter(pos, n, function(line) { 5532 processLine(cm, line.text, state); 5533 var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo; 5534 line.stateAfter = save ? copyState(doc.mode, state) : null; 5535 ++pos; 5536 }); 5537 if (precise) doc.frontier = pos; 5538 return state; 5539 } 5540 5541 // POSITION MEASUREMENT 5542 5543 function paddingTop(display) {return display.lineSpace.offsetTop;} 5544 function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;} 5545 function paddingH(display) { 5546 if (display.cachedPaddingH) return display.cachedPaddingH; 5547 var e = removeChildrenAndAdd(display.measure, elt("pre", "x")); 5548 var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; 5549 var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}; 5550 if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data; 5551 return data; 5552 } 5553 5554 function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; } 5555 function displayWidth(cm) { 5556 return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth; 5557 } 5558 function displayHeight(cm) { 5559 return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight; 5560 } 5561 5562 // Ensure the lineView.wrapping.heights array is populated. This is 5563 // an array of bottom offsets for the lines that make up a drawn 5564 // line. When lineWrapping is on, there might be more than one 5565 // height. 5566 function ensureLineHeights(cm, lineView, rect) { 5567 var wrapping = cm.options.lineWrapping; 5568 var curWidth = wrapping && displayWidth(cm); 5569 if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { 5570 var heights = lineView.measure.heights = []; 5571 if (wrapping) { 5572 lineView.measure.width = curWidth; 5573 var rects = lineView.text.firstChild.getClientRects(); 5574 for (var i = 0; i < rects.length - 1; i++) { 5575 var cur = rects[i], next = rects[i + 1]; 5576 if (Math.abs(cur.bottom - next.bottom) > 2) 5577 heights.push((cur.bottom + next.top) / 2 - rect.top); 5578 } 5579 } 5580 heights.push(rect.bottom - rect.top); 5581 } 5582 } 5583 5584 // Find a line map (mapping character offsets to text nodes) and a 5585 // measurement cache for the given line number. (A line view might 5586 // contain multiple lines when collapsed ranges are present.) 5587 function mapFromLineView(lineView, line, lineN) { 5588 if (lineView.line == line) 5589 return {map: lineView.measure.map, cache: lineView.measure.cache}; 5590 for (var i = 0; i < lineView.rest.length; i++) 5591 if (lineView.rest[i] == line) 5592 return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]}; 5593 for (var i = 0; i < lineView.rest.length; i++) 5594 if (lineNo(lineView.rest[i]) > lineN) 5595 return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true}; 5596 } 5597 5598 // Render a line into the hidden node display.externalMeasured. Used 5599 // when measurement is needed for a line that's not in the viewport. 5600 function updateExternalMeasurement(cm, line) { 5601 line = visualLine(line); 5602 var lineN = lineNo(line); 5603 var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); 5604 view.lineN = lineN; 5605 var built = view.built = buildLineContent(cm, view); 5606 view.text = built.pre; 5607 removeChildrenAndAdd(cm.display.lineMeasure, built.pre); 5608 return view; 5609 } 5610 5611 // Get a {top, bottom, left, right} box (in line-local coordinates) 5612 // for a given character. 5613 function measureChar(cm, line, ch, bias) { 5614 return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias); 5615 } 5616 5617 // Find a line view that corresponds to the given line number. 5618 function findViewForLine(cm, lineN) { 5619 if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) 5620 return cm.display.view[findViewIndex(cm, lineN)]; 5621 var ext = cm.display.externalMeasured; 5622 if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) 5623 return ext; 5624 } 5625 5626 // Measurement can be split in two steps, the set-up work that 5627 // applies to the whole line, and the measurement of the actual 5628 // character. Functions like coordsChar, that need to do a lot of 5629 // measurements in a row, can thus ensure that the set-up work is 5630 // only done once. 5631 function prepareMeasureForLine(cm, line) { 5632 var lineN = lineNo(line); 5633 var view = findViewForLine(cm, lineN); 5634 if (view && !view.text) { 5635 view = null; 5636 } else if (view && view.changes) { 5637 updateLineForChanges(cm, view, lineN, getDimensions(cm)); 5638 cm.curOp.forceUpdate = true; 5639 } 5640 if (!view) 5641 view = updateExternalMeasurement(cm, line); 5642 5643 var info = mapFromLineView(view, line, lineN); 5644 return { 5645 line: line, view: view, rect: null, 5646 map: info.map, cache: info.cache, before: info.before, 5647 hasHeights: false 5648 }; 5649 } 5650 5651 // Given a prepared measurement object, measures the position of an 5652 // actual character (or fetches it from the cache). 5653 function measureCharPrepared(cm, prepared, ch, bias, varHeight) { 5654 if (prepared.before) ch = -1; 5655 var key = ch + (bias || ""), found; 5656 if (prepared.cache.hasOwnProperty(key)) { 5657 found = prepared.cache[key]; 5658 } else { 5659 if (!prepared.rect) 5660 prepared.rect = prepared.view.text.getBoundingClientRect(); 5661 if (!prepared.hasHeights) { 5662 ensureLineHeights(cm, prepared.view, prepared.rect); 5663 prepared.hasHeights = true; 5664 } 5665 found = measureCharInner(cm, prepared, ch, bias); 5666 if (!found.bogus) prepared.cache[key] = found; 5667 } 5668 return {left: found.left, right: found.right, 5669 top: varHeight ? found.rtop : found.top, 5670 bottom: varHeight ? found.rbottom : found.bottom}; 5671 } 5672 5673 var nullRect = {left: 0, right: 0, top: 0, bottom: 0}; 5674 5675 function nodeAndOffsetInLineMap(map, ch, bias) { 5676 var node, start, end, collapse; 5677 // First, search the line map for the text node corresponding to, 5678 // or closest to, the target character. 5679 for (var i = 0; i < map.length; i += 3) { 5680 var mStart = map[i], mEnd = map[i + 1]; 5681 if (ch < mStart) { 5682 start = 0; end = 1; 5683 collapse = "left"; 5684 } else if (ch < mEnd) { 5685 start = ch - mStart; 5686 end = start + 1; 5687 } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { 5688 end = mEnd - mStart; 5689 start = end - 1; 5690 if (ch >= mEnd) collapse = "right"; 5691 } 5692 if (start != null) { 5693 node = map[i + 2]; 5694 if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) 5695 collapse = bias; 5696 if (bias == "left" && start == 0) 5697 while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { 5698 node = map[(i -= 3) + 2]; 5699 collapse = "left"; 5700 } 5701 if (bias == "right" && start == mEnd - mStart) 5702 while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { 5703 node = map[(i += 3) + 2]; 5704 collapse = "right"; 5705 } 5706 break; 5707 } 5708 } 5709 return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}; 5710 } 5711 5712 function
5712measureCharInner(cm, prepared, ch, bias) { 5713 var place = nodeAndOffsetInLineMap(prepared.map, ch, bias); 5714 var node = place.node, start = place.start, end = place.end, collapse = place.collapse; 5715 5716 var rect; 5717 if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. 5718 for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned 5719 while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start; 5720 while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end; 5721 if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) { 5722 rect = node.parentNode.getBoundingClientRect(); 5723 } else if (ie && cm.options.lineWrapping) { 5724 var rects = range(node, start, end).getClientRects(); 5725 if (rects.length) 5726 rect = rects[bias == "right" ? rects.length - 1 : 0]; 5727 else 5728 rect = nullRect; 5729 } else { 5730 rect = range(node, start, end).getBoundingClientRect() || nullRect; 5731 }
vendor: 9,620 bytes, lines 5731-5957
5731 5732 if (rect.left || rect.right || start == 0) break; 5733 end = start; 5734 start = start - 1; 5735 collapse = "right"; 5736 } 5737 if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect); 5738 } else { // If it is a widget, simply get the box for the whole widget. 5739 if (start > 0) collapse = bias = "right"; 5740 var rects; 5741 if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) 5742 rect = rects[bias == "right" ? rects.length - 1 : 0]; 5743 else 5744 rect = node.getBoundingClientRect(); 5745 } 5746 if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { 5747 var rSpan = node.parentNode.getClientRects()[0]; 5748 if (rSpan) 5749 rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; 5750 else 5751 rect = nullRect; 5752 } 5753 5754 var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; 5755 var mid = (rtop + rbot) / 2; 5756 var heights = prepared.view.measure.heights; 5757 for (var i = 0; i < heights.length - 1; i++) 5758 if (mid < heights[i]) break; 5759 var top = i ? heights[i - 1] : 0, bot = heights[i]; 5760 var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, 5761 right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, 5762 top: top, bottom: bot}; 5763 if (!rect.left && !rect.right) result.bogus = true; 5764 if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } 5765 5766 return result; 5767 } 5768 5769 // Work around problem with bounding client rects on ranges being 5770 // returned incorrectly when zoomed on IE10 and below. 5771 function maybeUpdateRectForZooming(measure, rect) { 5772 if (!window.screen || screen.logicalXDPI == null || 5773 screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure)) 5774 return rect; 5775 var scaleX = screen.logicalXDPI / screen.deviceXDPI; 5776 var scaleY = screen.logicalYDPI / screen.deviceYDPI; 5777 return {left: rect.left * scaleX, right: rect.right * scaleX, 5778 top: rect.top * scaleY, bottom: rect.bottom * scaleY}; 5779 } 5780 5781 function clearLineMeasurementCacheFor(lineView) { 5782 if (lineView.measure) { 5783 lineView.measure.cache = {}; 5784 lineView.measure.heights = null; 5785 if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) 5786 lineView.measure.caches[i] = {}; 5787 } 5788 } 5789 5790 function clearLineMeasurementCache(cm) { 5791 cm.display.externalMeasure = null; 5792 removeChildren(cm.display.lineMeasure); 5793 for (var i = 0; i < cm.display.view.length; i++) 5794 clearLineMeasurementCacheFor(cm.display.view[i]); 5795 } 5796 5797 function clearCaches(cm) { 5798 clearLineMeasurementCache(cm); 5799 cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; 5800 if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; 5801 cm.display.lineNumChars = null; 5802 } 5803 5804 function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } 5805 function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } 5806 5807 // Converts a {top, bottom, left, right} box from line-local 5808 // coordinates into another coordinate system. Context may be one of 5809 // "line", "div" (display.lineDiv), "local"/null (editor), "window", 5810 // or "page". 5811 function intoCoordSystem(cm, lineObj, rect, context) { 5812 if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { 5813 var size = widgetHeight(lineObj.widgets[i]); 5814 rect.top += size; rect.bottom += size; 5815 } 5816 if (context == "line") return rect; 5817 if (!context) context = "local"; 5818 var yOff = heightAtLine(lineObj); 5819 if (context == "local") yOff += paddingTop(cm.display); 5820 else yOff -= cm.display.viewOffset; 5821 if (context == "page" || context == "window") { 5822 var lOff = cm.display.lineSpace.getBoundingClientRect(); 5823 yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); 5824 var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); 5825 rect.left += xOff; rect.right += xOff; 5826 } 5827 rect.top += yOff; rect.bottom += yOff; 5828 return rect; 5829 } 5830 5831 // Coverts a box from "div" coords to another coordinate system. 5832 // Context may be "window", "page", "div", or "local"/null. 5833 function fromCoordSystem(cm, coords, context) { 5834 if (context == "div") return coords; 5835 var left = coords.left, top = coords.top; 5836 // First move into "page" coordinate system 5837 if (context == "page") { 5838 left -= pageScrollX(); 5839 top -= pageScrollY(); 5840 } else if (context == "local" || !context) { 5841 var localBox = cm.display.sizer.getBoundingClientRect(); 5842 left += localBox.left; 5843 top += localBox.top; 5844 } 5845 5846 var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); 5847 return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}; 5848 } 5849 5850 function charCoords(cm, pos, context, lineObj, bias) { 5851 if (!lineObj) lineObj = getLine(cm.doc, pos.line); 5852 return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context); 5853 } 5854 5855 // Returns a box for a given cursor position, which may have an 5856 // 'other' property containing the position of the secondary cursor 5857 // on a bidi boundary. 5858 function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { 5859 lineObj = lineObj || getLine(cm.doc, pos.line); 5860 if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj); 5861 function get(ch, right) { 5862 var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight); 5863 if (right) m.left = m.right; else m.right = m.left; 5864 return intoCoordSystem(cm, lineObj, m, context); 5865 } 5866 function getBidi(ch, partPos) { 5867 var part = order[partPos], right = part.level % 2; 5868 if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { 5869 part = order[--partPos]; 5870 ch = bidiRight(part) - (part.level % 2 ? 0 : 1); 5871 right = true; 5872 } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { 5873 part = order[++partPos]; 5874 ch = bidiLeft(part) - part.level % 2; 5875 right = false; 5876 } 5877 if (right && ch == part.to && ch > part.from) return get(ch - 1); 5878 return get(ch, right); 5879 } 5880 var order = getOrder(lineObj), ch = pos.ch; 5881 if (!order) return get(ch); 5882 var partPos = getBidiPartAt(order, ch); 5883 var val = getBidi(ch, partPos); 5884 if (bidiOther != null) val.other = getBidi(ch, bidiOther); 5885 return val; 5886 } 5887 5888 // Used to cheaply estimate the coordinates for a position. Used for 5889 // intermediate scroll updates. 5890 function estimateCoords(cm, pos) { 5891 var left = 0, pos = clipPos(cm.doc, pos); 5892 if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch; 5893 var lineObj = getLine(cm.doc, pos.line); 5894 var top = heightAtLine(lineObj) + paddingTop(cm.display); 5895 return {left: left, right: left, top: top, bottom: top + lineObj.height}; 5896 } 5897 5898 // Positions returned by coordsChar contain some extra information. 5899 // xRel is the relative x position of the input coordinates compared 5900 // to the found position (so xRel > 0 means the coordinates are to 5901 // the right of the character position, for example). When outside 5902 // is true, that means the coordinates lie outside the line's 5903 // vertical range. 5904 function PosWithInfo(line, ch, outside, xRel) { 5905 var pos = Pos(line, ch); 5906 pos.xRel = xRel; 5907 if (outside) pos.outside = true; 5908 return pos; 5909 } 5910 5911 // Compute the character position closest to the given coordinates. 5912 // Input must be lineSpace-local ("div" coordinate system). 5913 function coordsChar(cm, x, y) { 5914 var doc = cm.doc; 5915 y += cm.display.viewOffset; 5916 if (y < 0) return PosWithInfo(doc.first, 0, true, -1); 5917 var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; 5918 if (lineN > last) 5919 return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); 5920 if (x < 0) x = 0; 5921 5922 var lineObj = getLine(doc, lineN); 5923 for (;;) { 5924 var found = coordsCharInner(cm, lineObj, lineN, x, y); 5925 var merged = collapsedSpanAtEnd(lineObj); 5926 var mergedPos = merged && merged.find(0, true); 5927 if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) 5928 lineN = lineNo(lineObj = mergedPos.to.line); 5929 else 5930 return found; 5931 } 5932 } 5933 5934 function coordsCharInner(cm, lineObj, lineNo, x, y) { 5935 var innerOff = y - heightAtLine(lineObj); 5936 var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; 5937 var preparedMeasure = prepareMeasureForLine(cm, lineObj); 5938 5939 function getX(ch) { 5940 var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure); 5941 wrongLine = true; 5942 if (innerOff > sp.bottom) return sp.left - adjust; 5943 else if (innerOff < sp.top) return sp.left + adjust; 5944 else wrongLine = false; 5945 return sp.left; 5946 } 5947 5948 var bidi = getOrder(lineObj), dist = lineObj.text.length; 5949 var from = lineLeft(lineObj), to = lineRight(lineObj); 5950 var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; 5951 5952 if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); 5953 // Do a binary search between these bounds. 5954 for (;;) { 5955 if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { 5956 var ch = x < fromX || x - fromX <= toX - x ? from : to; 5957 var
vendor: 45,424 bytes, lines 5957-7114
5957xDiff = x - (ch == from ? fromX : toX); 5958 while (isExtendingChar(lineObj.text.charAt(ch))) ++ch; 5959 var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside, 5960 xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0); 5961 return pos; 5962 } 5963 var step = Math.ceil(dist / 2), middle = from + step; 5964 if (bidi) { 5965 middle = from; 5966 for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); 5967 } 5968 var middleX = getX(middle); 5969 if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;} 5970 else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;} 5971 } 5972 } 5973 5974 var measureText; 5975 // Compute the default text height. 5976 function textHeight(display) { 5977 if (display.cachedTextHeight != null) return display.cachedTextHeight; 5978 if (measureText == null) { 5979 measureText = elt("pre"); 5980 // Measure a bunch of lines, for browsers that compute 5981 // fractional heights. 5982 for (var i = 0; i < 49; ++i) { 5983 measureText.appendChild(document.createTextNode("x")); 5984 measureText.appendChild(elt("br")); 5985 } 5986 measureText.appendChild(document.createTextNode("x")); 5987 } 5988 removeChildrenAndAdd(display.measure, measureText); 5989 var height = measureText.offsetHeight / 50; 5990 if (height > 3) display.cachedTextHeight = height; 5991 removeChildren(display.measure); 5992 return height || 1; 5993 } 5994 5995 // Compute the default character width. 5996 function charWidth(display) { 5997 if (display.cachedCharWidth != null) return display.cachedCharWidth; 5998 var anchor = elt("span", "xxxxxxxxxx"); 5999 var pre = elt("pre", [anchor]); 6000 removeChildrenAndAdd(display.measure, pre); 6001 var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; 6002 if (width > 2) display.cachedCharWidth = width; 6003 return width || 10; 6004 } 6005 6006 // OPERATIONS 6007 6008 // Operations are used to wrap a series of changes to the editor 6009 // state in such a way that each change won't have to update the 6010 // cursor and display (which would be awkward, slow, and 6011 // error-prone). Instead, display updates are batched and then all 6012 // combined and executed at once. 6013 6014 var operationGroup = null; 6015 6016 var nextOpId = 0; 6017 // Start a new operation. 6018 function startOperation(cm) { 6019 cm.curOp = { 6020 cm: cm, 6021 viewChanged: false, // Flag that indicates that lines might need to be redrawn 6022 startHeight: cm.doc.height, // Used to detect need to update scrollbar 6023 forceUpdate: false, // Used to force a redraw 6024 updateInput: null, // Whether to reset the input textarea 6025 typing: false, // Whether this reset should be careful to leave existing text (for compositing) 6026 changeObjs: null, // Accumulated changes, for firing change events 6027 cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on 6028 cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already 6029 selectionChanged: false, // Whether the selection needs to be redrawn 6030 updateMaxLine: false, // Set when the widest line needs to be determined anew 6031 scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet 6032 scrollToPos: null, // Used to scroll to a specific position 6033 focus: false, 6034 id: ++nextOpId // Unique ID 6035 }; 6036 if (operationGroup) { 6037 operationGroup.ops.push(cm.curOp); 6038 } else { 6039 cm.curOp.ownsGroup = operationGroup = { 6040 ops: [cm.curOp], 6041 delayedCallbacks: [] 6042 }; 6043 } 6044 } 6045 6046 function fireCallbacksForOps(group) { 6047 // Calls delayed callbacks and cursorActivity handlers until no 6048 // new ones appear 6049 var callbacks = group.delayedCallbacks, i = 0; 6050 do { 6051 for (; i < callbacks.length; i++) 6052 callbacks[i].call(null); 6053 for (var j = 0; j < group.ops.length; j++) { 6054 var op = group.ops[j]; 6055 if (op.cursorActivityHandlers) 6056 while (op.cursorActivityCalled < op.cursorActivityHandlers.length) 6057 op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); 6058 } 6059 } while (i < callbacks.length); 6060 } 6061 6062 // Finish an operation, updating the display and signalling delayed events 6063 function endOperation(cm) { 6064 var op = cm.curOp, group = op.ownsGroup; 6065 if (!group) return; 6066 6067 try { fireCallbacksForOps(group); } 6068 finally { 6069 operationGroup = null; 6070 for (var i = 0; i < group.ops.length; i++) 6071 group.ops[i].cm.curOp = null; 6072 endOperations(group); 6073 } 6074 } 6075 6076 // The DOM updates done when an operation finishes are batched so 6077 // that the minimum number of relayouts are required. 6078 function endOperations(group) { 6079 var ops = group.ops; 6080 for (var i = 0; i < ops.length; i++) // Read DOM 6081 endOperation_R1(ops[i]); 6082 for (var i = 0; i < ops.length; i++) // Write DOM (maybe) 6083 endOperation_W1(ops[i]); 6084 for (var i = 0; i < ops.length; i++) // Read DOM 6085 endOperation_R2(ops[i]); 6086 for (var i = 0; i < ops.length; i++) // Write DOM (maybe) 6087 endOperation_W2(ops[i]); 6088 for (var i = 0; i < ops.length; i++) // Read DOM 6089 endOperation_finish(ops[i]); 6090 } 6091 6092 function endOperation_R1(op) { 6093 var cm = op.cm, display = cm.display; 6094 maybeClipScrollbars(cm); 6095 if (op.updateMaxLine) findMaxLine(cm); 6096 6097 op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null || 6098 op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || 6099 op.scrollToPos.to.line >= display.viewTo) || 6100 display.maxLineChanged && cm.options.lineWrapping; 6101 op.update = op.mustUpdate && 6102 new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate); 6103 } 6104 6105 function endOperation_W1(op) { 6106 op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update); 6107 } 6108 6109 function endOperation_R2(op) { 6110 var cm = op.cm, display = cm.display; 6111 if (op.updatedDisplay) updateHeightsInViewport(cm); 6112 6113 op.barMeasure = measureForScrollbars(cm); 6114 6115 // If the max line changed since it was last measured, measure it, 6116 // and ensure the document's width matches it. 6117 // updateDisplay_W2 will use these properties to do the actual resizing 6118 if (display.maxLineChanged && !cm.options.lineWrapping) { 6119 op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3; 6120 cm.display.sizerWidth = op.adjustWidthTo; 6121 op.barMeasure.scrollWidth = 6122 Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth); 6123 op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm)); 6124 } 6125 6126 if (op.updatedDisplay || op.selectionChanged) 6127 op.preparedSelection = display.input.prepareSelection(); 6128 } 6129 6130 function endOperation_W2(op) { 6131 var cm = op.cm; 6132 6133 if (op.adjustWidthTo != null) { 6134 cm.display.sizer.style.minWidth = op.adjustWidthTo + "px"; 6135 if (op.maxScrollLeft < cm.doc.scrollLeft) 6136 setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); 6137 cm.display.maxLineChanged = false; 6138 } 6139 6140 if (op.preparedSelection) 6141 cm.display.input.showSelection(op.preparedSelection); 6142 if (op.updatedDisplay) 6143 setDocumentHeight(cm, op.barMeasure); 6144 if (op.updatedDisplay || op.startHeight != cm.doc.height) 6145 updateScrollbars(cm, op.barMeasure); 6146 6147 if (op.selectionChanged) restartBlink(cm); 6148 6149 if (cm.state.focused && op.updateInput) 6150 cm.display.input.reset(op.typing); 6151 if (op.focus && op.focus == activeElt()) ensureFocus(op.cm); 6152 } 6153 6154 function endOperation_finish(op) { 6155 var cm = op.cm, display = cm.display, doc = cm.doc; 6156 6157 if (op.updatedDisplay) postUpdateDisplay(cm, op.update); 6158 6159 // Abort mouse wheel delta measurement, when scrolling explicitly 6160 if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) 6161 display.wheelStartX = display.wheelStartY = null; 6162 6163 // Propagate the scroll position to the actual DOM scroller 6164 if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) { 6165 doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop)); 6166 display.scrollbars.setScrollTop(doc.scrollTop); 6167 display.scroller.scrollTop = doc.scrollTop; 6168 } 6169 if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) { 6170 doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - displayWidth(cm), op.scrollLeft)); 6171 display.scrollbars.setScrollLeft(doc.scrollLeft); 6172 display.scroller.scrollLeft = doc.scrollLeft; 6173 alignHorizontally(cm); 6174 } 6175 // If we need to scroll a specific position into view, do so. 6176 if (op.scrollToPos) { 6177 var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from), 6178 clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin); 6179 if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords); 6180 } 6181 6182 // Fire events for markers that are hidden/unidden by editing or 6183 // undoing 6184 var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; 6185 if (hidden) for (var i = 0; i < hidden.length; ++i) 6186 if (!hidden[i].lines.length) signal(hidden[i], "hide"); 6187 if (unhidden) for (var i = 0; i < unhidden.length; ++i) 6188 if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); 6189 6190 if (display.wrapper.offsetHeight) 6191 doc.scrollTop = cm.display.scroller.scrollTop; 6192 6193 // Fire change events, and delayed event handlers 6194 if (op.changeObjs) 6195 signal(cm, "changes", cm, op.changeObjs); 6196 if (op.update) 6197 op.update.finish(); 6198 } 6199 6200 // Run the given function in an operation 6201 function runInOp(cm, f) { 6202 if (cm.curOp) return f(); 6203 startOperation(cm); 6204 try { return f(); } 6205 finally { endOperation(cm); } 6206 } 6207 // Wraps a function in an operation. Returns the wrapped function. 6208 function operation(cm, f) { 6209 return function() { 6210 if (cm.curOp) return f.apply(cm, arguments); 6211 startOperation(cm); 6212 try { return f.apply(cm, arguments); } 6213 finally { endOperation(cm); } 6214 }; 6215 } 6216 // Used to add methods to editor and doc instances, wrapping them in 6217 // operations. 6218 function methodOp(f) { 6219 return function() { 6220 if (this.curOp) return f.apply(this, arguments); 6221 startOperation(this); 6222 try { return f.apply(this, arguments); } 6223 finally { endOperation(this); } 6224 }; 6225 } 6226 function docMethodOp(f) { 6227 return function() { 6228 var cm = this.cm; 6229 if (!cm || cm.curOp) return f.apply(this, arguments); 6230 startOperation(cm); 6231 try { return f.apply(this, arguments); } 6232 finally { endOperation(cm); } 6233 }; 6234 } 6235 6236 // VIEW TRACKING 6237 6238 // These objects are used to represent the visible (currently drawn) 6239 // part of the document. A LineView may correspond to multiple 6240 // logical lines, if those are connected by collapsed ranges. 6241 function LineView(doc, line, lineN) { 6242 // The starting line 6243 this.line = line; 6244 // Continuing lines, if any 6245 this.rest = visualLineContinued(line); 6246 // Number of logical lines in this visual line 6247 this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; 6248 this.node = this.text = null; 6249 this.hidden = lineIsHidden(doc, line); 6250 } 6251 6252 // Create a range of LineView objects for the given lines. 6253 function buildViewArray(cm, from, to) { 6254 var array = [], nextPos; 6255 for (var pos = from; pos < to; pos = nextPos) { 6256 var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); 6257 nextPos = pos + view.size; 6258 array.push(view); 6259 } 6260 return array; 6261 } 6262 6263 // Updates the display.view data structure for a given change to the 6264 // document. From and to are in pre-change coordinates. Lendiff is 6265 // the amount of lines added or subtracted by the change. This is 6266 // used for changes that span multiple lines, or change the way 6267 // lines are divided into visual lines. regLineChange (below) 6268 // registers single-line changes. 6269 function regChange(cm, from, to, lendiff) { 6270 if (from == null) from = cm.doc.first; 6271 if (to == null) to = cm.doc.first + cm.doc.size; 6272 if (!lendiff) lendiff = 0; 6273 6274 var display = cm.display; 6275 if (lendiff && to < display.viewTo && 6276 (display.updateLineNumbers == null || display.updateLineNumbers > from)) 6277 display.updateLineNumbers = from; 6278 6279 cm.curOp.viewChanged = true; 6280 6281 if (from >= display.viewTo) { // Change after 6282 if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) 6283 resetView(cm); 6284 } else if (to <= display.viewFrom) { // Change before 6285 if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { 6286 resetView(cm); 6287 } else { 6288 display.viewFrom += lendiff; 6289 display.viewTo += lendiff; 6290 } 6291 } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap 6292 resetView(cm); 6293 } else if (from <= display.viewFrom) { // Top overlap 6294 var cut = viewCuttingPoint(cm, to, to + lendiff, 1); 6295 if (cut) { 6296 display.view = display.view.slice(cut.index); 6297 display.viewFrom = cut.lineN; 6298 display.viewTo += lendiff; 6299 } else { 6300 resetView(cm); 6301 } 6302 } else if (to >= display.viewTo) { // Bottom overlap 6303 var cut = viewCuttingPoint(cm, from, from, -1); 6304 if (cut) { 6305 display.view = display.view.slice(0, cut.index); 6306 display.viewTo = cut.lineN; 6307 } else { 6308 resetView(cm); 6309 } 6310 } else { // Gap in the middle 6311 var cutTop = viewCuttingPoint(cm, from, from, -1); 6312 var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); 6313 if (cutTop && cutBot) { 6314 display.view = display.view.slice(0, cutTop.index) 6315 .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) 6316 .concat(display.view.slice(cutBot.index)); 6317 display.viewTo += lendiff; 6318 } else { 6319 resetView(cm); 6320 } 6321 } 6322 6323 var ext = display.externalMeasured; 6324 if (ext) { 6325 if (to < ext.lineN) 6326 ext.lineN += lendiff; 6327 else if (from < ext.lineN + ext.size) 6328 display.externalMeasured = null; 6329 } 6330 } 6331 6332 // Register a change to a single line. Type must be one of "text", 6333 // "gutter", "class", "widget" 6334 function regLineChange(cm, line, type) { 6335 cm.curOp.viewChanged = true; 6336 var display = cm.display, ext = cm.display.externalMeasured; 6337 if (ext && line >= ext.lineN && line < ext.lineN + ext.size) 6338 display.externalMeasured = null; 6339 6340 if (line < display.viewFrom || line >= display.viewTo) return; 6341 var lineView = display.view[findViewIndex(cm, line)]; 6342 if (lineView.node == null) return; 6343 var arr = lineView.changes || (lineView.changes = []); 6344 if (indexOf(arr, type) == -1) arr.push(type); 6345 } 6346 6347 // Clear the view. 6348 function resetView(cm) { 6349 cm.display.viewFrom = cm.display.viewTo = cm.doc.first; 6350 cm.display.view = []; 6351 cm.display.viewOffset = 0; 6352 } 6353 6354 // Find the view element corresponding to a given line. Return null 6355 // when the line isn't visible. 6356 function findViewIndex(cm, n) { 6357 if (n >= cm.display.viewTo) return null; 6358 n -= cm.display.viewFrom; 6359 if (n < 0) return null; 6360 var view = cm.display.view; 6361 for (var i = 0; i < view.length; i++) { 6362 n -= view[i].size; 6363 if (n < 0) return i; 6364 } 6365 } 6366 6367 function viewCuttingPoint(cm, oldN, newN, dir) { 6368 var index = findViewIndex(cm, oldN), diff, view = cm.display.view; 6369 if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) 6370 return {index: index, lineN: newN}; 6371 for (var i = 0, n = cm.display.viewFrom; i < index; i++) 6372 n += view[i].size; 6373 if (n != oldN) { 6374 if (dir > 0) { 6375 if (index == view.length - 1) return null; 6376 diff = (n + view[index].size) - oldN; 6377 index++; 6378 } else { 6379 diff = n - oldN; 6380 } 6381 oldN += diff; newN += diff; 6382 } 6383 while (visualLineNo(cm.doc, newN) != newN) { 6384 if (index == (dir < 0 ? 0 : view.length - 1)) return null; 6385 newN += dir * view[index - (dir < 0 ? 1 : 0)].size; 6386 index += dir; 6387 } 6388 return {index: index, lineN: newN}; 6389 } 6390 6391 // Force the view to cover a given range, adding empty view element 6392 // or clipping off existing ones as needed. 6393 function adjustView(cm, from, to) { 6394 var display = cm.display, view = display.view; 6395 if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { 6396 display.view = buildViewArray(cm, from, to); 6397 display.viewFrom = from; 6398 } else { 6399 if (display.viewFrom > from) 6400 display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); 6401 else if (display.viewFrom < from) 6402 display.view = display.view.slice(findViewIndex(cm, from)); 6403 display.viewFrom = from; 6404 if (display.viewTo < to) 6405 display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); 6406 else if (display.viewTo > to) 6407 display.view = display.view.slice(0, findViewIndex(cm, to)); 6408 } 6409 display.viewTo = to; 6410 } 6411 6412 // Count the number of lines in the view whose DOM representation is 6413 // out of date (or nonexistent). 6414 function countDirtyView(cm) { 6415 var view = cm.display.view, dirty = 0; 6416 for (var i = 0; i < view.length; i++) { 6417 var lineView = view[i]; 6418 if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty; 6419 } 6420 return dirty; 6421 } 6422 6423 // EVENT HANDLERS 6424 6425 // Attach the necessary event handlers when initializing the editor 6426 function registerEventHandlers(cm) { 6427 var d = cm.display; 6428 on(d.scroller, "mousedown", operation(cm, onMouseDown)); 6429 // Older IE's will not fire a second mousedown for a double click 6430 if (ie && ie_version < 11) 6431 on(d.scroller, "dblclick", operation(cm, function(e) { 6432 if (signalDOMEvent(cm, e)) return; 6433 var pos = posFromMouse(cm, e); 6434 if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; 6435 e_preventDefault(e); 6436 var word = cm.findWordAt(pos); 6437 extendSelection(cm.doc, word.anchor, word.head); 6438 })); 6439 else 6440 on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); 6441 // Some browsers fire contextmenu *after* opening the menu, at 6442 // which point we can't mess with it anymore. Context menu is 6443 // handled in onMouseDown for these browsers. 6444 if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);}); 6445 6446 // Used to suppress mouse event handling when a touch happens 6447 var touchFinished, prevTouch = {end: 0}; 6448 function finishTouch() { 6449 if (d.activeTouch) { 6450 touchFinished = setTimeout(function() {d.activeTouch = null;}, 1000); 6451 prevTouch = d.activeTouch; 6452 prevTouch.end = +new Date; 6453 } 6454 }; 6455 function isMouseLikeTouchEvent(e) { 6456 if (e.touches.length != 1) return false; 6457 var touch = e.touches[0]; 6458 return touch.radiusX <= 1 && touch.radiusY <= 1; 6459 } 6460 function farAway(touch, other) { 6461 if (other.left == null) return true; 6462 var dx = other.left - touch.left, dy = other.top - touch.top; 6463 return dx * dx + dy * dy > 20 * 20; 6464 } 6465 on(d.scroller, "touchstart", function(e) { 6466 if (!isMouseLikeTouchEvent(e)) { 6467 clearTimeout(touchFinished); 6468 var now = +new Date; 6469 d.activeTouch = {start: now, moved: false, 6470 prev: now - prevTouch.end <= 300 ? prevTouch : null}; 6471 if (e.touches.length == 1) { 6472 d.activeTouch.left = e.touches[0].pageX; 6473 d.activeTouch.top = e.touches[0].pageY; 6474 } 6475 } 6476 }); 6477 on(d.scroller, "touchmove", function() { 6478 if (d.activeTouch) d.activeTouch.moved = true; 6479 }); 6480 on(d.scroller, "touchend", function(e) { 6481 var touch = d.activeTouch; 6482 if (touch && !eventInWidget(d, e) && touch.left != null && 6483 !touch.moved && new Date - touch.start < 300) { 6484 var pos = cm.coordsChar(d.activeTouch, "page"), range; 6485 if (!touch.prev || farAway(touch, touch.prev)) // Single tap 6486 range = new Range(pos, pos); 6487 else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap 6488 range = cm.findWordAt(pos); 6489 else // Triple tap 6490 range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))); 6491 cm.setSelection(range.anchor, range.head); 6492 cm.focus(); 6493 e_preventDefault(e); 6494 } 6495 finishTouch(); 6496 }); 6497 on(d.scroller, "touchcancel", finishTouch); 6498 6499 // Sync scrolling between fake scrollbars and real scrollable 6500 // area, ensure viewport is updated when scrolling. 6501 on(d.scroller, "scroll", function() { 6502 if (d.scroller.clientHeight) { 6503 setScrollTop(cm, d.scroller.scrollTop); 6504 setScrollLeft(cm, d.scroller.scrollLeft, true); 6505 signal(cm, "scroll", cm); 6506 } 6507 }); 6508 6509 // Listen to wheel events in order to try and update the viewport on time. 6510 on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);}); 6511 on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);}); 6512 6513 // Prevent wrapper from ever scrolling 6514 on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); 6515 6516 d.dragFunctions = { 6517 enter: function(e) {if (!signalDOMEvent(cm, e)) e_stop(e);}, 6518 over: function(e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); }}, 6519 start: function(e){onDragStart(cm, e);}, 6520 drop: operation(cm, onDrop), 6521 leave: function() {clearDragCursor(cm);} 6522 }; 6523 6524 var inp = d.input.getField(); 6525 on(inp, "keyup", function(e) { onKeyUp.call(cm, e); }); 6526 on(inp, "keydown", operation(cm, onKeyDown)); 6527 on(inp, "keypress", operation(cm, onKeyPress)); 6528 on(inp, "focus", bind(onFocus, cm)); 6529 on(inp, "blur", bind(onBlur, cm)); 6530 } 6531 6532 function dragDropChanged(cm, value, old) { 6533 var wasOn = old && old != CodeMirror.Init; 6534 if (!value != !wasOn) { 6535 var funcs = cm.display.dragFunctions; 6536 var toggle = value ? on : off; 6537 toggle(cm.display.scroller, "dragstart", funcs.start); 6538 toggle(cm.display.scroller, "dragenter", funcs.enter); 6539 toggle(cm.display.scroller, "dragover", funcs.over); 6540 toggle(cm.display.scroller, "dragleave", funcs.leave); 6541 toggle(cm.display.scroller, "drop", funcs.drop); 6542 } 6543 } 6544 6545 // Called when the window resizes 6546 function onResize(cm) { 6547 var d = cm.display; 6548 if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) 6549 return; 6550 // Might be a text scaling operation, clear size caches. 6551 d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; 6552 d.scrollbarsClipped = false; 6553 cm.setSize(); 6554 } 6555 6556 // MOUSE EVENTS 6557 6558 // Return true when the given mouse event happened in a widget 6559 function eventInWidget(display, e) { 6560 for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { 6561 if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") || 6562 (n.parentNode == display.sizer && n != display.mover)) 6563 return true; 6564 } 6565 } 6566 6567 // Given a mouse event, find the corresponding position. If liberal 6568 // is false, it checks whether a gutter or scrollbar was clicked, 6569 // and returns null if it was. forRect is used by rectangular 6570 // selections, and tries to estimate a character position even for 6571 // coordinates beyond the right of the text. 6572 function posFromMouse(cm, e, liberal, forRect) { 6573 var display = cm.display; 6574 if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null; 6575 6576 var x, y, space = display.lineSpace.getBoundingClientRect(); 6577 // Fails unpredictably on IE[67] when mouse is dragged around quickly. 6578 try { x = e.clientX - space.left; y = e.clientY - space.top; } 6579 catch (e) { return null; } 6580 var coords = coordsChar(cm, x, y), line; 6581 if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { 6582 var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; 6583 coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); 6584 } 6585 return coords; 6586 } 6587 6588 // A mouse down can be a single click, double click, triple click, 6589 // start of selection drag, start of text drag, new cursor 6590 // (ctrl-click), rectangle drag (alt-drag), or xwin 6591 // middle-click-paste. Or it might be a click on something we should 6592 // not interfere with, such as a scrollbar or widget. 6593 function onMouseDown(e) { 6594 var cm = this, display = cm.display; 6595 if (display.activeTouch && display.input.supportsTouch() || signalDOMEvent(cm, e)) return; 6596 display.shift = e.shiftKey; 6597 6598 if (eventInWidget(display, e)) { 6599 if (!webkit) { 6600 // Briefly turn off draggability, to allow widgets to do 6601 // normal dragging things. 6602 display.scroller.draggable = false; 6603 setTimeout(function(){display.scroller.draggable = true;}, 100); 6604 } 6605 return; 6606 } 6607 if (clickInGutter(cm, e)) return; 6608 var start = posFromMouse(cm, e); 6609 window.focus(); 6610 6611 switch (e_button(e)) { 6612 case 1: 6613 // #3261: make sure, that we're not starting a second selection 6614 if (cm.state.selectingText) 6615 cm.state.selectingText(e); 6616 else if (start) 6617 leftButtonDown(cm, e, start); 6618 else if (e_target(e) == display.scroller) 6619 e_preventDefault(e); 6620 break; 6621 case 2: 6622 if (webkit) cm.state.lastMiddleDown = +new Date; 6623 if (start) extendSelection(cm.doc, start); 6624 setTimeout(function() {display.input.focus();}, 20); 6625 e_preventDefault(e); 6626 break; 6627 case 3: 6628 if (captureRightClick) onContextMenu(cm, e); 6629 else delayBlurEvent(cm); 6630 break; 6631 } 6632 } 6633 6634 var lastClick, lastDoubleClick; 6635 function leftButtonDown(cm, e, start) { 6636 if (ie) setTimeout(bind(ensureFocus, cm), 0); 6637 else cm.curOp.focus = activeElt(); 6638 6639 var now = +new Date, type; 6640 if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) { 6641 type = "triple"; 6642 } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) { 6643 type = "double"; 6644 lastDoubleClick = {time: now, pos: start}; 6645 } else { 6646 type = "single"; 6647 lastClick = {time: now, pos: start}; 6648 } 6649 6650 var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained; 6651 if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && 6652 type == "single" && (contained = sel.contains(start)) > -1 && 6653 (cmp((contained = sel.ranges[contained]).from(), start) < 0 || start.xRel > 0) && 6654 (cmp(contained.to(), start) > 0 || start.xRel < 0)) 6655 leftButtonStartDrag(cm, e, start, modifier); 6656 else 6657 leftButtonSelect(cm, e, start, type, modifier); 6658 } 6659 6660 // Start a text drag. When it ends, see if any dragging actually 6661 // happen, and treat as a click if it didn't. 6662 function leftButtonStartDrag(cm, e, start, modifier) { 6663 var display = cm.display, startTime = +new Date; 6664 var dragEnd = operation(cm, function(e2) { 6665 if (webkit) display.scroller.draggable = false; 6666 cm.state.draggingText = false; 6667 off(document, "mouseup", dragEnd); 6668 off(display.scroller, "drop", dragEnd); 6669 if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { 6670 e_preventDefault(e2); 6671 if (!modifier && +new Date - 200 < startTime) 6672 extendSelection(cm.doc, start); 6673 // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) 6674 if (webkit || ie && ie_version == 9) 6675 setTimeout(function() {document.body.focus(); display.input.focus();}, 20); 6676 else 6677 display.input.focus(); 6678 } 6679 }); 6680 // Let the drag handler handle this. 6681 if (webkit) display.scroller.draggable = true; 6682 cm.state.draggingText = dragEnd; 6683 // IE's approach to draggable 6684 if (display.scroller.dragDrop) display.scroller.dragDrop(); 6685 on(document, "mouseup", dragEnd); 6686 on(display.scroller, "drop", dragEnd); 6687 } 6688 6689 // Normal selection, as opposed to text dragging. 6690 function leftButtonSelect(cm, e, start, type, addNew) { 6691 var display = cm.display, doc = cm.doc; 6692 e_preventDefault(e); 6693 6694 var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges; 6695 if (addNew && !e.shiftKey) { 6696 ourIndex = doc.sel.contains(start); 6697 if (ourIndex > -1) 6698 ourRange = ranges[ourIndex]; 6699 else 6700 ourRange = new Range(start, start); 6701 } else { 6702 ourRange = doc.sel.primary(); 6703 ourIndex = doc.sel.primIndex; 6704 } 6705 6706 if (e.altKey) { 6707 type = "rect"; 6708 if (!addNew) ourRange = new Range(start, start); 6709 start = posFromMouse(cm, e, true, true); 6710 ourIndex = -1; 6711 } else if (type == "double") { 6712 var word = cm.findWordAt(start); 6713 if (cm.display.shift || doc.extend) 6714 ourRange = extendRange(doc, ourRange, word.anchor, word.head); 6715 else 6716 ourRange = word; 6717 } else if (type == "triple") { 6718 var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0))); 6719 if (cm.display.shift || doc.extend) 6720 ourRange = extendRange(doc, ourRange, line.anchor, line.head); 6721 else 6722 ourRange = line; 6723 } else { 6724 ourRange = extendRange(doc, ourRange, start); 6725 } 6726 6727 if (!addNew) { 6728 ourIndex = 0; 6729 setSelection(doc, new Selection([ourRange], 0), sel_mouse); 6730 startSel = doc.sel; 6731 } else if (ourIndex == -1) { 6732 ourIndex = ranges.length; 6733 setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex), 6734 {scroll: false, origin: "*mouse"}); 6735 } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) { 6736 setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), 6737 {scroll: false, origin: "*mouse"}); 6738 startSel = doc.sel; 6739 } else { 6740 replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); 6741 } 6742 6743 var lastPos = start; 6744 function extendTo(pos) { 6745 if (cmp(lastPos, pos) == 0) return; 6746 lastPos = pos; 6747 6748 if (type == "rect") { 6749 var ranges = [], tabSize = cm.options.tabSize; 6750 var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); 6751 var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); 6752 var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); 6753 for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); 6754 line <= end; line++) { 6755 var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); 6756 if (left == right) 6757 ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); 6758 else if (text.length > leftPos) 6759 ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); 6760 } 6761 if (!ranges.length) ranges.push(new Range(start, start)); 6762 setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), 6763 {origin: "*mouse", scroll: false}); 6764 cm.scrollIntoView(pos); 6765 } else { 6766 var oldRange = ourRange; 6767 var anchor = oldRange.anchor, head = pos; 6768 if (type != "single") { 6769 if (type == "double") 6770 var range = cm.findWordAt(pos); 6771 else 6772 var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))); 6773 if (cmp(range.anchor, anchor) > 0) { 6774 head = range.head; 6775 anchor = minPos(oldRange.from(), range.anchor); 6776 } else { 6777 head = range.anchor; 6778 anchor = maxPos(oldRange.to(), range.head); 6779 } 6780 } 6781 var ranges = startSel.ranges.slice(0); 6782 ranges[ourIndex] = new Range(clipPos(doc, anchor), head); 6783 setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse); 6784 } 6785 } 6786 6787 var editorSize = display.wrapper.getBoundingClientRect(); 6788 // Used to ensure timeout re-tries don't fire when another extend 6789 // happened in the meantime (clearTimeout isn't reliable -- at 6790 // least on Chrome, the timeouts still happen even when cleared, 6791 // if the clear happens after their scheduled firing time). 6792 var counter = 0; 6793 6794 function extend(e) { 6795 var curCount = ++counter; 6796 var cur = posFromMouse(cm, e, true, type == "rect"); 6797 if (!cur) return; 6798 if (cmp(cur, lastPos) != 0) { 6799 cm.curOp.focus = activeElt(); 6800 extendTo(cur); 6801 var visible = visibleLines(display, doc); 6802 if (cur.line >= visible.to || cur.line < visible.from) 6803 setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150); 6804 } else { 6805 var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; 6806 if (outside) setTimeout(operation(cm, function() { 6807 if (counter != curCount) return; 6808 display.scroller.scrollTop += outside; 6809 extend(e); 6810 }), 50); 6811 } 6812 } 6813 6814 function done(e) { 6815 cm.state.selectingText = false; 6816 counter = Infinity; 6817 e_preventDefault(e); 6818 display.input.focus(); 6819 off(document, "mousemove", move); 6820 off(document, "mouseup", up); 6821 doc.history.lastSelOrigin = null; 6822 } 6823 6824 var move = operation(cm, function(e) { 6825 if (!e_button(e)) done(e); 6826 else extend(e); 6827 }); 6828 var up = operation(cm, done); 6829 cm.state.selectingText = up; 6830 on(document, "mousemove", move); 6831 on(document, "mouseup", up); 6832 } 6833 6834 // Determines whether an event happened in the gutter, and fires the 6835 // handlers for the corresponding event. 6836 function gutterEvent(cm, e, type, prevent, signalfn) { 6837 try { var mX = e.clientX, mY = e.clientY; } 6838 catch(e) { return false; } 6839 if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false; 6840 if (prevent) e_preventDefault(e); 6841 6842 var display = cm.display; 6843 var lineBox = display.lineDiv.getBoundingClientRect(); 6844 6845 if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); 6846 mY -= lineBox.top - display.viewOffset; 6847 6848 for (var i = 0; i < cm.options.gutters.length; ++i) { 6849 var g = display.gutters.childNodes[i]; 6850 if (g && g.getBoundingClientRect().right >= mX) { 6851 var line = lineAtHeight(cm.doc, mY); 6852 var gutter = cm.options.gutters[i]; 6853 signalfn(cm, type, cm, line, gutter, e); 6854 return e_defaultPrevented(e); 6855 } 6856 } 6857 } 6858 6859 function clickInGutter(cm, e) { 6860 return gutterEvent(cm, e, "gutterClick", true, signalLater); 6861 } 6862 6863 // Kludge to work around strange IE behavior where it'll sometimes 6864 // re-fire a series of drag-related events right after the drop (#1551) 6865 var lastDrop = 0; 6866 6867 function onDrop(e) { 6868 var cm = this; 6869 clearDragCursor(cm); 6870 if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) 6871 return; 6872 e_preventDefault(e); 6873 if (ie) lastDrop = +new Date; 6874 var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; 6875 if (!pos || isReadOnly(cm)) return; 6876 // Might be a file drop, in which case we simply extract the text 6877 // and insert it. 6878 if (files && files.length && window.FileReader && window.File) { 6879 var n = files.length, text = Array(n), read = 0; 6880 var loadFile = function(file, i) { 6881 if (cm.options.allowDropFileTypes && 6882 indexOf(cm.options.allowDropFileTypes, file.type) == -1) 6883 return; 6884 6885 var reader = new FileReader; 6886 reader.onload = operation(cm, function() { 6887 var content = reader.result; 6888 if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) content = ""; 6889 text[i] = content; 6890 if (++read == n) { 6891 pos = clipPos(cm.doc, pos); 6892 var change = {from: pos, to: pos, 6893 text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())), 6894 origin: "paste"}; 6895 makeChange(cm.doc, change); 6896 setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))); 6897 } 6898 }); 6899 reader.readAsText(file); 6900 }; 6901 for (var i = 0; i < n; ++i) loadFile(files[i], i); 6902 } else { // Normal drop 6903 // Don't do a replace if the drop happened inside of the selected text. 6904 if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { 6905 cm.state.draggingText(e); 6906 // Ensure the editor is re-focused 6907 setTimeout(function() {cm.display.input.focus();}, 20); 6908 return; 6909 } 6910 try { 6911 var text = e.dataTransfer.getData("Text"); 6912 if (text) { 6913 if (cm.state.draggingText && !(mac ? e.altKey : e.ctrlKey)) 6914 var selected = cm.listSelections(); 6915 setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); 6916 if (selected) for (var i = 0; i < selected.length; ++i) 6917 replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag"); 6918 cm.replaceSelection(text, "around", "paste"); 6919 cm.display.input.focus(); 6920 } 6921 } 6922 catch(e){} 6923 } 6924 } 6925 6926 function onDragStart(cm, e) { 6927 if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } 6928 if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; 6929 6930 e.dataTransfer.setData("Text", cm.getSelection()); 6931 6932 // Use dummy image instead of default browsers image. 6933 // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. 6934 if (e.dataTransfer.setDragImage && !safari) { 6935 var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); 6936 img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; 6937 if (presto) { 6938 img.width = img.height = 1; 6939 cm.display.wrapper.appendChild(img); 6940 // Force a relayout, or Opera won't use our image for some obscure reason 6941 img._top = img.offsetTop; 6942 } 6943 e.dataTransfer.setDragImage(img, 0, 0); 6944 if (presto) img.parentNode.removeChild(img); 6945 } 6946 } 6947 6948 function onDragOver(cm, e) { 6949 var pos = posFromMouse(cm, e); 6950 if (!pos) return; 6951 var frag = document.createDocumentFragment(); 6952 drawSelectionCursor(cm, pos, frag); 6953 if (!cm.display.dragCursor) { 6954 cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors"); 6955 cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv); 6956 } 6957 removeChildrenAndAdd(cm.display.dragCursor, frag); 6958 } 6959 6960 function clearDragCursor(cm) { 6961 if (cm.display.dragCursor) { 6962 cm.display.lineSpace.removeChild(cm.display.dragCursor); 6963 cm.display.dragCursor = null; 6964 } 6965 } 6966 6967 // SCROLL EVENTS 6968 6969 // Sync the scrollable area and scrollbars, ensure the viewport 6970 // covers the visible area. 6971 function setScrollTop(cm, val) { 6972 if (Math.abs(cm.doc.scrollTop - val) < 2) return; 6973 cm.doc.scrollTop = val; 6974 if (!gecko) updateDisplaySimple(cm, {top: val}); 6975 if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; 6976 cm.display.scrollbars.setScrollTop(val); 6977 if (gecko) updateDisplaySimple(cm); 6978 startWorker(cm, 100); 6979 } 6980 // Sync scroller and scrollbar, ensure the gutter elements are 6981 // aligned. 6982 function setScrollLeft(cm, val, isScroller) { 6983 if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; 6984 val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); 6985 cm.doc.scrollLeft = val; 6986 alignHorizontally(cm); 6987 if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; 6988 cm.display.scrollbars.setScrollLeft(val); 6989 } 6990 6991 // Since the delta values reported on mouse wheel events are 6992 // unstandardized between browsers and even browser versions, and 6993 // generally horribly unpredictable, this code starts by measuring 6994 // the scroll effect that the first few mouse wheel events have, 6995 // and, from that, detects the way it can convert deltas to pixel 6996 // offsets afterwards. 6997 // 6998 // The reason we want to know the amount a wheel event will scroll 6999 // is that it gives us a chance to update the display before the 7000 // actual scrolling happens, reducing flickering. 7001 7002 var wheelSamples = 0, wheelPixelsPerUnit = null; 7003 // Fill in a browser-detected starting value on browsers where we 7004 // know one. These don't have to be accurate -- the result of them 7005 // being wrong would just be a slight flicker on the first wheel 7006 // scroll (if it is large enough). 7007 if (ie) wheelPixelsPerUnit = -.53; 7008 else if (gecko) wheelPixelsPerUnit = 15; 7009 else if (chrome) wheelPixelsPerUnit = -.7; 7010 else if (safari) wheelPixelsPerUnit = -1/3; 7011 7012 var wheelEventDelta = function(e) { 7013 var dx = e.wheelDeltaX, dy = e.wheelDeltaY; 7014 if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; 7015 if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; 7016 else if (dy == null) dy = e.wheelDelta; 7017 return {x: dx, y: dy}; 7018 }; 7019 CodeMirror.wheelEventPixels = function(e) { 7020 var delta = wheelEventDelta(e); 7021 delta.x *= wheelPixelsPerUnit; 7022 delta.y *= wheelPixelsPerUnit; 7023 return delta; 7024 }; 7025 7026 function onScrollWheel(cm, e) { 7027 var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y; 7028 7029 var display = cm.display, scroll = display.scroller; 7030 // Quit if there's nothing to scroll here 7031 var canScrollX = scroll.scrollWidth > scroll.clientWidth; 7032 var canScrollY = scroll.scrollHeight > scroll.clientHeight; 7033 if (!(dx && canScrollX || dy && canScrollY)) return; 7034 7035 // Webkit browsers on OS X abort momentum scrolls when the target 7036 // of the scroll event is removed from the scrollable element. 7037 // This hack (see related code in patchDisplay) makes sure the 7038 // element is kept around. 7039 if (dy && mac && webkit) { 7040 outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { 7041 for (var i = 0; i < view.length; i++) { 7042 if (view[i].node == cur) { 7043 cm.display.currentWheelTarget = cur; 7044 break outer; 7045 } 7046 } 7047 } 7048 } 7049 7050 // On some browsers, horizontal scrolling will cause redraws to 7051 // happen before the gutter has been realigned, causing it to 7052 // wriggle around in a most unseemly way. When we have an 7053 // estimated pixels/delta value, we just handle horizontal 7054 // scrolling entirely here. It'll be slightly off from native, but 7055 // better than glitching out. 7056 if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { 7057 if (dy && canScrollY) 7058 setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); 7059 setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); 7060 // Only prevent default scrolling if vertical scrolling is 7061 // actually possible. Otherwise, it causes vertical scroll 7062 // jitter on OSX trackpads when deltaX is small and deltaY 7063 // is large (issue #3579) 7064 if (!dy || (dy && canScrollY)) 7065 e_preventDefault(e); 7066 display.wheelStartX = null; // Abort measurement, if in progress 7067 return; 7068 } 7069 7070 // 'Project' the visible viewport to cover the area that is being 7071 // scrolled into view (if we know enough to estimate it). 7072 if (dy && wheelPixelsPerUnit != null) { 7073 var pixels = dy * wheelPixelsPerUnit; 7074 var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; 7075 if (pixels < 0) top = Math.max(0, top + pixels - 50); 7076 else bot = Math.min(cm.doc.height, bot + pixels + 50); 7077 updateDisplaySimple(cm, {top: top, bottom: bot}); 7078 } 7079 7080 if (wheelSamples < 20) { 7081 if (display.wheelStartX == null) { 7082 display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; 7083 display.wheelDX = dx; display.wheelDY = dy; 7084 setTimeout(function() { 7085 if (display.wheelStartX == null) return; 7086 var movedX = scroll.scrollLeft - display.wheelStartX; 7087 var movedY = scroll.scrollTop - display.wheelStartY; 7088 var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || 7089 (movedX && display.wheelDX && movedX / display.wheelDX); 7090 display.wheelStartX = display.wheelStartY = null; 7091 if (!sample) return; 7092 wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); 7093 ++wheelSamples; 7094 }, 200); 7095 } else { 7096 display.wheelDX += dx; display.wheelDY += dy; 7097 } 7098 } 7099 } 7100 7101 // KEY EVENTS 7102 7103 // Run a handler that was bound to a key. 7104 function doHandleBinding(cm, bound, dropShift) { 7105 if (typeof bound == "string") { 7106 bound = commands[bound]; 7107 if (!bound) return false; 7108 } 7109 // Ensure previous input has been read, so that the handler sees a 7110 // consistent view of the document 7111 cm.display.input.ensurePolled(); 7112 var prevShift = cm.display.shift, done = false; 7113 try { 7114 if (isReadOnly(cm
vendor: 6,170 bytes, lines 7114-7299
7114)) cm.state.suppressEdits = true; 7115 if (dropShift) cm.display.shift = false; 7116 done = bound(cm) != Pass; 7117 } finally { 7118 cm.display.shift = prevShift; 7119 cm.state.suppressEdits = false; 7120 } 7121 return done; 7122 } 7123 7124 function lookupKeyForEditor(cm, name, handle) { 7125 for (var i = 0; i < cm.state.keyMaps.length; i++) { 7126 var result = lookupKey(name, cm.state.keyMaps[i], handle, cm); 7127 if (result) return result; 7128 } 7129 return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm)) 7130 || lookupKey(name, cm.options.keyMap, handle, cm); 7131 } 7132 7133 var stopSeq = new Delayed; 7134 function dispatchKey(cm, name, e, handle) { 7135 var seq = cm.state.keySeq; 7136 if (seq) { 7137 if (isModifierKey(name)) return "handled"; 7138 stopSeq.set(50, function() { 7139 if (cm.state.keySeq == seq) { 7140 cm.state.keySeq = null; 7141 cm.display.input.reset(); 7142 } 7143 }); 7144 name = seq + " " + name; 7145 } 7146 var result = lookupKeyForEditor(cm, name, handle); 7147 7148 if (result == "multi") 7149 cm.state.keySeq = name; 7150 if (result == "handled") 7151 signalLater(cm, "keyHandled", cm, name, e); 7152 7153 if (result == "handled" || result == "multi") { 7154 e_preventDefault(e); 7155 restartBlink(cm); 7156 } 7157 7158 if (seq && !result && /\'$/.test(name)) { 7159 e_preventDefault(e); 7160 return true; 7161 } 7162 return !!result; 7163 } 7164 7165 // Handle a key from the keydown event. 7166 function handleKeyBinding(cm, e) { 7167 var name = keyName(e, true); 7168 if (!name) return false; 7169 7170 if (e.shiftKey && !cm.state.keySeq) { 7171 // First try to resolve full name (including 'Shift-'). Failing 7172 // that, see if there is a cursor-motion command (starting with 7173 // 'go') bound to the keyname without 'Shift-'. 7174 return dispatchKey(cm, "Shift-" + name, e, function(b) {return doHandleBinding(cm, b, true);}) 7175 || dispatchKey(cm, name, e, function(b) { 7176 if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) 7177 return doHandleBinding(cm, b); 7178 }); 7179 } else { 7180 return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); }); 7181 } 7182 } 7183 7184 // Handle a key from the keypress event 7185 function handleCharBinding(cm, e, ch) { 7186 return dispatchKey(cm, "'" + ch + "'", e, 7187 function(b) { return doHandleBinding(cm, b, true); }); 7188 } 7189 7190 var lastStoppedKey = null; 7191 function onKeyDown(e) { 7192 var cm = this; 7193 cm.curOp.focus = activeElt(); 7194 if (signalDOMEvent(cm, e)) return; 7195 // IE does strange things with escape. 7196 if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false; 7197 var code = e.keyCode; 7198 cm.display.shift = code == 16 || e.shiftKey; 7199 var handled = handleKeyBinding(cm, e); 7200 if (presto) { 7201 lastStoppedKey = handled ? code : null; 7202 // Opera has no cut event... we try to at least catch the key combo 7203 if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) 7204 cm.replaceSelection("", null, "cut"); 7205 } 7206 7207 // Turn mouse into crosshair when Alt is held on Mac. 7208 if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) 7209 showCrossHair(cm); 7210 } 7211 7212 function showCrossHair(cm) { 7213 var lineDiv = cm.display.lineDiv; 7214 addClass(lineDiv, "CodeMirror-crosshair"); 7215 7216 function up(e) { 7217 if (e.keyCode == 18 || !e.altKey) { 7218 rmClass(lineDiv, "CodeMirror-crosshair"); 7219 off(document, "keyup", up); 7220 off(document, "mouseover", up); 7221 } 7222 } 7223 on(document, "keyup", up); 7224 on(document, "mouseover", up); 7225 } 7226 7227 function onKeyUp(e) { 7228 if (e.keyCode == 16) this.doc.sel.shift = false; 7229 signalDOMEvent(this, e); 7230 } 7231 7232 function onKeyPress(e) { 7233 var cm = this; 7234 if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return; 7235 var keyCode = e.keyCode, charCode = e.charCode; 7236 if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;} 7237 if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) return; 7238 var ch = String.fromCharCode(charCode == null ? keyCode : charCode); 7239 if (handleCharBinding(cm, e, ch)) return; 7240 cm.display.input.onKeyPress(e); 7241 } 7242 7243 // FOCUS/BLUR EVENTS 7244 7245 function delayBlurEvent(cm) { 7246 cm.state.delayingBlurEvent = true; 7247 setTimeout(function() { 7248 if (cm.state.delayingBlurEvent) { 7249 cm.state.delayingBlurEvent = false; 7250 onBlur(cm); 7251 } 7252 }, 100); 7253 } 7254 7255 function onFocus(cm) { 7256 if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false; 7257 7258 if (cm.options.readOnly == "nocursor") return; 7259 if (!cm.state.focused) { 7260 signal(cm, "focus", cm); 7261 cm.state.focused = true; 7262 addClass(cm.display.wrapper, "CodeMirror-focused"); 7263 // This test prevents this from firing when a context 7264 // menu is closed (since the input reset would kill the 7265 // select-all detection hack) 7266 if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { 7267 cm.display.input.reset(); 7268 if (webkit) setTimeout(function() { cm.display.input.reset(true); }, 20); // Issue #1730 7269 } 7270 cm.display.input.receivedFocus(); 7271 } 7272 restartBlink(cm); 7273 } 7274 function onBlur(cm) { 7275 if (cm.state.delayingBlurEvent) return; 7276 7277 if (cm.state.focused) { 7278 signal(cm, "blur", cm); 7279 cm.state.focused = false; 7280 rmClass(cm.display.wrapper, "CodeMirror-focused"); 7281 } 7282 clearInterval(cm.display.blinker); 7283 setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150); 7284 } 7285 7286 // CONTEXT MENU HANDLING 7287 7288 // To make the context menu work, we need to briefly unhide the 7289 // textarea (making it as unobtrusive as possible) to let the 7290 // right-click take effect on it. 7291 function onContextMenu(cm, e) { 7292 if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return; 7293 if (signalDOMEvent(cm, e, "contextmenu")) return; 7294 cm.display.input.onContextMenu(e); 7295 } 7296 7297 function contextMenuInGutter(cm, e) { 7298 if (!hasHandler(cm, "gutterContextMenu")) return false; 7299 return gutterEvent(cm, e, "gutterContextMenu", false
vendor: 4,806 bytes, lines 7299-7427
7299, signal); 7300 } 7301 7302 // UPDATING 7303 7304 // Compute the position of the end of a change (its 'to' property 7305 // refers to the pre-change end). 7306 var changeEnd = CodeMirror.changeEnd = function(change) { 7307 if (!change.text) return change.to; 7308 return Pos(change.from.line + change.text.length - 1, 7309 lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); 7310 }; 7311 7312 // Adjust a position to refer to the post-change position of the 7313 // same text, or the end of the change if the change covers it. 7314 function adjustForChange(pos, change) { 7315 if (cmp(pos, change.from) < 0) return pos; 7316 if (cmp(pos, change.to) <= 0) return changeEnd(change); 7317 7318 var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; 7319 if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch; 7320 return Pos(line, ch); 7321 } 7322 7323 function computeSelAfterChange(doc, change) { 7324 var out = []; 7325 for (var i = 0; i < doc.sel.ranges.length; i++) { 7326 var range = doc.sel.ranges[i]; 7327 out.push(new Range(adjustForChange(range.anchor, change), 7328 adjustForChange(range.head, change))); 7329 } 7330 return normalizeSelection(out, doc.sel.primIndex); 7331 } 7332 7333 function offsetPos(pos, old, nw) { 7334 if (pos.line == old.line) 7335 return Pos(nw.line, pos.ch - old.ch + nw.ch); 7336 else 7337 return Pos(nw.line + (pos.line - old.line), pos.ch); 7338 } 7339 7340 // Used by replaceSelections to allow moving the selection to the 7341 // start or around the replaced test. Hint may be "start" or "around". 7342 function computeReplacedSel(doc, changes, hint) { 7343 var out = []; 7344 var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; 7345 for (var i = 0; i < changes.length; i++) { 7346 var change = changes[i]; 7347 var from = offsetPos(change.from, oldPrev, newPrev); 7348 var to = offsetPos(changeEnd(change), oldPrev, newPrev); 7349 oldPrev = change.to; 7350 newPrev = to; 7351 if (hint == "around") { 7352 var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; 7353 out[i] = new Range(inv ? to : from, inv ? from : to); 7354 } else { 7355 out[i] = new Range(from, from); 7356 } 7357 } 7358 return new Selection(out, doc.sel.primIndex); 7359 } 7360 7361 // Allow "beforeChange" event handlers to influence a change 7362 function filterChange(doc, change, update) { 7363 var obj = { 7364 canceled: false, 7365 from: change.from, 7366 to: change.to, 7367 text: change.text, 7368 origin: change.origin, 7369 cancel: function() { this.canceled = true; } 7370 }; 7371 if (update) obj.update = function(from, to, text, origin) { 7372 if (from) this.from = clipPos(doc, from); 7373 if (to) this.to = clipPos(doc, to); 7374 if (text) this.text = text; 7375 if (origin !== undefined) this.origin = origin; 7376 }; 7377 signal(doc, "beforeChange", doc, obj); 7378 if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); 7379 7380 if (obj.canceled) return null; 7381 return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}; 7382 } 7383 7384 // Apply a change to a document, and add it to the document's 7385 // history, and propagating it to all linked documents. 7386 function makeChange(doc, change, ignoreReadOnly) { 7387 if (doc.cm) { 7388 if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly); 7389 if (doc.cm.state.suppressEdits) return; 7390 } 7391 7392 if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { 7393 change = filterChange(doc, change, true); 7394 if (!change) return; 7395 } 7396 7397 // Possibly split or suppress the update based on the presence 7398 // of read-only spans in its range. 7399 var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); 7400 if (split) { 7401 for (var i = split.length - 1; i >= 0; --i) 7402 makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}); 7403 } else { 7404 makeChangeInner(doc, change); 7405 } 7406 } 7407 7408 function makeChangeInner(doc, change) { 7409 if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return; 7410 var selAfter = computeSelAfterChange(doc, change); 7411 addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); 7412 7413 makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); 7414 var rebased = []; 7415 7416 linkedDocs(doc, function(doc, sharedHist) { 7417 if (!sharedHist && indexOf(rebased, doc.history) == -1) { 7418 rebaseHist(doc.history, change); 7419 rebased.push(doc.history); 7420 } 7421 makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); 7422 }); 7423 } 7424 7425 // Revert a change stored in a document's history. 7426 function makeChangeFromHistory(doc, type, allowSelectionOnly) { 7427 if (doc.cm && doc.cm.state.suppressEdits
vendor: 17,279 bytes, lines 7427-7847
7427) return; 7428 7429 var hist = doc.history, event, selAfter = doc.sel; 7430 var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; 7431 7432 // Verify that there is a useable event (so that ctrl-z won't 7433 // needlessly clear selection events) 7434 for (var i = 0; i < source.length; i++) { 7435 event = source[i]; 7436 if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) 7437 break; 7438 } 7439 if (i == source.length) return; 7440 hist.lastOrigin = hist.lastSelOrigin = null; 7441 7442 for (;;) { 7443 event = source.pop(); 7444 if (event.ranges) { 7445 pushSelectionToHistory(event, dest); 7446 if (allowSelectionOnly && !event.equals(doc.sel)) { 7447 setSelection(doc, event, {clearRedo: false}); 7448 return; 7449 } 7450 selAfter = event; 7451 } 7452 else break; 7453 } 7454 7455 // Build up a reverse change object to add to the opposite history 7456 // stack (redo when undoing, and vice versa). 7457 var antiChanges = []; 7458 pushSelectionToHistory(selAfter, dest); 7459 dest.push({changes: antiChanges, generation: hist.generation}); 7460 hist.generation = event.generation || ++hist.maxGeneration; 7461 7462 var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); 7463 7464 for (var i = event.changes.length - 1; i >= 0; --i) { 7465 var change = event.changes[i]; 7466 change.origin = type; 7467 if (filter && !filterChange(doc, change, false)) { 7468 source.length = 0; 7469 return; 7470 } 7471 7472 antiChanges.push(historyChangeFromChange(doc, change)); 7473 7474 var after = i ? computeSelAfterChange(doc, change) : lst(source); 7475 makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); 7476 if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}); 7477 var rebased = []; 7478 7479 // Propagate to the linked documents 7480 linkedDocs(doc, function(doc, sharedHist) { 7481 if (!sharedHist && indexOf(rebased, doc.history) == -1) { 7482 rebaseHist(doc.history, change); 7483 rebased.push(doc.history); 7484 } 7485 makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); 7486 }); 7487 } 7488 } 7489 7490 // Sub-views need their line numbers shifted when text is added 7491 // above or below them in the parent document. 7492 function shiftDoc(doc, distance) { 7493 if (distance == 0) return; 7494 doc.first += distance; 7495 doc.sel = new Selection(map(doc.sel.ranges, function(range) { 7496 return new Range(Pos(range.anchor.line + distance, range.anchor.ch), 7497 Pos(range.head.line + distance, range.head.ch)); 7498 }), doc.sel.primIndex); 7499 if (doc.cm) { 7500 regChange(doc.cm, doc.first, doc.first - distance, distance); 7501 for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) 7502 regLineChange(doc.cm, l, "gutter"); 7503 } 7504 } 7505 7506 // More lower-level change function, handling only a single document 7507 // (not linked ones). 7508 function makeChangeSingleDoc(doc, change, selAfter, spans) { 7509 if (doc.cm && !doc.cm.curOp) 7510 return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); 7511 7512 if (change.to.line < doc.first) { 7513 shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); 7514 return; 7515 } 7516 if (change.from.line > doc.lastLine()) return; 7517 7518 // Clip the change to the size of this doc 7519 if (change.from.line < doc.first) { 7520 var shift = change.text.length - 1 - (doc.first - change.from.line); 7521 shiftDoc(doc, shift); 7522 change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), 7523 text: [lst(change.text)], origin: change.origin}; 7524 } 7525 var last = doc.lastLine(); 7526 if (change.to.line > last) { 7527 change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), 7528 text: [change.text[0]], origin: change.origin}; 7529 } 7530 7531 change.removed = getBetween(doc, change.from, change.to); 7532 7533 if (!selAfter) selAfter = computeSelAfterChange(doc, change); 7534 if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans); 7535 else updateDoc(doc, change, spans); 7536 setSelectionNoUndo(doc, selAfter, sel_dontScroll); 7537 } 7538 7539 // Handle the interaction of a change to a document with the editor 7540 // that this document is part of. 7541 function makeChangeSingleDocInEditor(cm, change, spans) { 7542 var doc = cm.doc, display = cm.display, from = change.from, to = change.to; 7543 7544 var recomputeMaxLength = false, checkWidthStart = from.line; 7545 if (!cm.options.lineWrapping) { 7546 checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); 7547 doc.iter(checkWidthStart, to.line + 1, function(line) { 7548 if (line == display.maxLine) { 7549 recomputeMaxLength = true; 7550 return true; 7551 } 7552 }); 7553 } 7554 7555 if (doc.sel.contains(change.from, change.to) > -1) 7556 signalCursorActivity(cm); 7557 7558 updateDoc(doc, change, spans, estimateHeight(cm)); 7559 7560 if (!cm.options.lineWrapping) { 7561 doc.iter(checkWidthStart, from.line + change.text.length, function(line) { 7562 var len = lineLength(line); 7563 if (len > display.maxLineLength) { 7564 display.maxLine = line; 7565 display.maxLineLength = len; 7566 display.maxLineChanged = true; 7567 recomputeMaxLength = false; 7568 } 7569 }); 7570 if (recomputeMaxLength) cm.curOp.updateMaxLine = true; 7571 } 7572 7573 // Adjust frontier, schedule worker 7574 doc.frontier = Math.min(doc.frontier, from.line); 7575 startWorker(cm, 400); 7576 7577 var lendiff = change.text.length - (to.line - from.line) - 1; 7578 // Remember that these lines changed, for updating the display 7579 if (change.full) 7580 regChange(cm); 7581 else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) 7582 regLineChange(cm, from.line, "text"); 7583 else 7584 regChange(cm, from.line, to.line + 1, lendiff); 7585 7586 var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); 7587 if (changeHandler || changesHandler) { 7588 var obj = { 7589 from: from, to: to, 7590 text: change.text, 7591 removed: change.removed, 7592 origin: change.origin 7593 }; 7594 if (changeHandler) signalLater(cm, "change", cm, obj); 7595 if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); 7596 } 7597 cm.display.selForContextMenu = null; 7598 } 7599 7600 function replaceRange(doc, code, from, to, origin) { 7601 if (!to) to = from; 7602 if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; } 7603 if (typeof code == "string") code = doc.splitLines(code); 7604 makeChange(doc, {from: from, to: to, text: code, origin: origin}); 7605 } 7606 7607 // SCROLLING THINGS INTO VIEW 7608 7609 // If an editor sits on the top or bottom of the window, partially 7610 // scrolled out of view, this ensures that the cursor is visible. 7611 function maybeScrollWindow(cm, coords) { 7612 if (signalDOMEvent(cm, "scrollCursorIntoView")) return; 7613 7614 var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; 7615 if (coords.top + box.top < 0) doScroll = true; 7616 else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; 7617 if (doScroll != null && !phantom) { 7618 var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " + 7619 (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " + 7620 (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " + 7621 coords.left + "px; width: 2px;"); 7622 cm.display.lineSpace.appendChild(scrollNode); 7623 scrollNode.scrollIntoView(doScroll); 7624 cm.display.lineSpace.removeChild(scrollNode); 7625 } 7626 } 7627 7628 // Scroll a given position into view (immediately), verifying that 7629 // it actually became visible (as line heights are accurately 7630 // measured, the position of something may 'drift' during drawing). 7631 function scrollPosIntoView(cm, pos, end, margin) { 7632 if (margin == null) margin = 0; 7633 for (var limit = 0; limit < 5; limit++) { 7634 var changed = false, coords = cursorCoords(cm, pos); 7635 var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); 7636 var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), 7637 Math.min(coords.top, endCoords.top) - margin, 7638 Math.max(coords.left, endCoords.left), 7639 Math.max(coords.bottom, endCoords.bottom) + margin); 7640 var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; 7641 if (scrollPos.scrollTop != null) { 7642 setScrollTop(cm, scrollPos.scrollTop); 7643 if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; 7644 } 7645 if (scrollPos.scrollLeft != null) { 7646 setScrollLeft(cm, scrollPos.scrollLeft); 7647 if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; 7648 } 7649 if (!changed) break; 7650 } 7651 return coords; 7652 } 7653 7654 // Scroll a given set of coordinates into view (immediately). 7655 function scrollIntoView(cm, x1, y1, x2, y2) { 7656 var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); 7657 if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); 7658 if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); 7659 } 7660 7661 // Calculate a new scroll position needed to scroll the given 7662 // rectangle into view. Returns an object with scrollTop and 7663 // scrollLeft properties. When these are undefined, the 7664 // vertical/horizontal position does not need to be adjusted. 7665 function calculateScrollPos(cm, x1, y1, x2, y2) { 7666 var display = cm.display, snapMargin = textHeight(cm.display); 7667 if (y1 < 0) y1 = 0; 7668 var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; 7669 var screen = displayHeight(cm), result = {}; 7670 if (y2 - y1 > screen) y2 = y1 + screen; 7671 var docBottom = cm.doc.height + paddingVert(display); 7672 var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; 7673 if (y1 < screentop) { 7674 result.scrollTop = atTop ? 0 : y1; 7675 } else if (y2 > screentop + screen) { 7676 var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); 7677 if (newTop != screentop) result.scrollTop = newTop; 7678 } 7679 7680 var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft; 7681 var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0); 7682 var tooWide = x2 - x1 > screenw; 7683 if (tooWide) x2 = x1 + screenw; 7684 if (x1 < 10) 7685 result.scrollLeft = 0; 7686 else if (x1 < screenleft) 7687 result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10)); 7688 else if (x2 > screenw + screenleft - 3) 7689 result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw; 7690 return result; 7691 } 7692 7693 // Store a relative adjustment to the scroll position in the current 7694 // operation (to be applied when the operation finishes). 7695 function addToScrollPos(cm, left, top) { 7696 if (left != null || top != null) resolveScrollToPos(cm); 7697 if (left != null) 7698 cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left; 7699 if (top != null) 7700 cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; 7701 } 7702 7703 // Make sure that at the end of the operation the current cursor is 7704 // shown. 7705 function ensureCursorVisible(cm) { 7706 resolveScrollToPos(cm); 7707 var cur = cm.getCursor(), from = cur, to = cur; 7708 if (!cm.options.lineWrapping) { 7709 from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur; 7710 to = Pos(cur.line, cur.ch + 1); 7711 } 7712 cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true}; 7713 } 7714 7715 // When an operation has its scrollToPos property set, and another 7716 // scroll action is applied before the end of the operation, this 7717 // 'simulates' scrolling that position into view in a cheap way, so 7718 // that the effect of intermediate scroll commands is not ignored. 7719 function resolveScrollToPos(cm) { 7720 var range = cm.curOp.scrollToPos; 7721 if (range) { 7722 cm.curOp.scrollToPos = null; 7723 var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); 7724 var sPos = calculateScrollPos(cm, Math.min(from.left, to.left), 7725 Math.min(from.top, to.top) - range.margin, 7726 Math.max(from.right, to.right), 7727 Math.max(from.bottom, to.bottom) + range.margin); 7728 cm.scrollTo(sPos.scrollLeft, sPos.scrollTop); 7729 } 7730 } 7731 7732 // API UTILITIES 7733 7734 // Indent the given line. The how parameter can be "smart", 7735 // "add"/null, "subtract", or "prev". When aggressive is false 7736 // (typically set to true for forced single-line indents), empty 7737 // lines are not indented, and places where the mode returns Pass 7738 // are left alone. 7739 function indentLine(cm, n, how, aggressive) { 7740 var doc = cm.doc, state; 7741 if (how == null) how = "add"; 7742 if (how == "smart") { 7743 // Fall back to "prev" when the mode doesn't have an indentation 7744 // method. 7745 if (!doc.mode.indent) how = "prev"; 7746 else state = getStateBefore(cm, n); 7747 } 7748 7749 var tabSize = cm.options.tabSize; 7750 var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); 7751 if (line.stateAfter) line.stateAfter = null; 7752 var curSpaceString = line.text.match(/^\s*/)[0], indentation; 7753 if (!aggressive && !/\S/.test(line.text)) { 7754 indentation = 0; 7755 how = "not"; 7756 } else if (how == "smart") { 7757 indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); 7758 if (indentation == Pass || indentation > 150) { 7759 if (!aggressive) return; 7760 how = "prev"; 7761 } 7762 } 7763 if (how == "prev") { 7764 if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize); 7765 else indentation = 0; 7766 } else if (how == "add") { 7767 indentation = curSpace + cm.options.indentUnit; 7768 } else if (how == "subtract") { 7769 indentation = curSpace - cm.options.indentUnit; 7770 } else if (typeof how == "number") { 7771 indentation = curSpace + how; 7772 } 7773 indentation = Math.max(0, indentation); 7774 7775 var indentString = "", pos = 0; 7776 if (cm.options.indentWithTabs) 7777 for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} 7778 if (pos < indentation) indentString += spaceStr(indentation - pos); 7779 7780 if (indentString != curSpaceString) { 7781 replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); 7782 line.stateAfter = null; 7783 return true; 7784 } else { 7785 // Ensure that, if the cursor was in the whitespace at the start 7786 // of the line, it is moved to the end of that space. 7787 for (var i = 0; i < doc.sel.ranges.length; i++) { 7788 var range = doc.sel.ranges[i]; 7789 if (range.head.line == n && range.head.ch < curSpaceString.length) { 7790 var pos = Pos(n, curSpaceString.length); 7791 replaceOneSelection(doc, i, new Range(pos, pos)); 7792 break; 7793 } 7794 } 7795 } 7796 } 7797 7798 // Utility for applying a change to a line by handle or number, 7799 // returning the number and optionally registering the line as 7800 // changed. 7801 function changeLine(doc, handle, changeType, op) { 7802 var no = handle, line = handle; 7803 if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); 7804 else no = lineNo(handle); 7805 if (no == null) return null; 7806 if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType); 7807 return line; 7808 } 7809 7810 // Helper for deleting text near the selection(s), used to implement 7811 // backspace, delete, and similar functionality. 7812 function deleteNearSelection(cm, compute) { 7813 var ranges = cm.doc.sel.ranges, kill = []; 7814 // Build up a set of ranges to kill first, merging overlapping 7815 // ranges. 7816 for (var i = 0; i < ranges.length; i++) { 7817 var toKill = compute(ranges[i]); 7818 while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { 7819 var replaced = kill.pop(); 7820 if (cmp(replaced.from, toKill.from) < 0) { 7821 toKill.from = replaced.from; 7822 break; 7823 } 7824 } 7825 kill.push(toKill); 7826 } 7827 // Next, remove those actual ranges. 7828 runInOp(cm, function() { 7829 for (var i = kill.length - 1; i >= 0; i--) 7830 replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); 7831 ensureCursorVisible(cm); 7832 }); 7833 } 7834 7835 // Used for horizontal relative motion. Dir is -1 or 1 (left or 7836 // right), unit can be "char", "column" (like char, but doesn't 7837 // cross line boundaries), "word" (across next word), or "group" (to 7838 // the start of next group of word or non-word-non-whitespace 7839 // chars). The visually param controls whether, in right-to-left 7840 // text, direction 1 means to move towards the next index in the 7841 // string, or towards the character to the right of the current 7842 // position. The resulting position will have a hitSide=true 7843 // property if it reached the end of the document. 7844 function findPosH(doc, pos, dir, unit, visually) { 7845 var line = pos.line, ch = pos.ch, origDir = dir; 7846 var lineObj = getLine(doc, line); 7847
7847var possible = true; 7848 function findNextLine() { 7849 var l = line + dir; 7850 if (l < doc.first || l >= doc.first + doc.size) return (possible = false); 7851 line = l; 7852 return lineObj = getLine(doc, l); 7853 } 7854 function moveOnce(boundToLine) { 7855 var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); 7856 if (next == null) { 7857 if (!boundToLine && findNextLine()) { 7858 if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); 7859 else ch = dir < 0 ? lineObj.text.length : 0; 7860 } else return (possible = false); 7861 } else ch = next; 7862 return true; 7863 } 7864 7865 if (unit == "char") moveOnce(); 7866 else if (unit == "column") moveOnce(true); 7867 else if (unit == "word" || unit == "group") { 7868 var sawType = null, group = unit == "group"; 7869 var helper = doc.cm && doc.cm.getHelper(pos, "wordChars"); 7870 for (var first = true;; first = false) { 7871 if (dir < 0 && !moveOnce(!first)) break; 7872 var cur = lineObj.text.charAt(ch) || "\n"; 7873 var type = isWordChar(cur, helper) ? "w" 7874 : group && cur == "\n" ? "n" 7875 : !group || /\s/.test(cur) ? null 7876 : "p"; 7877 if (group && !first && !type) type = "s"; 7878 if (sawType && sawType != type) { 7879 if (dir < 0) {dir = 1; moveOnce();} 7880 break; 7881 } 7882 7883 if (type) sawType = type; 7884 if (dir > 0 && !moveOnce(!first)) break; 7885 } 7886 } 7887 var result = skipAtomic(doc, Pos(line, ch), origDir, true); 7888 if (!possible
vendor: 14,934 bytes, lines 7888-8274
7888) result.hitSide = true; 7889 return result; 7890 } 7891 7892 // For relative vertical movement. Dir may be -1 or 1. Unit can be 7893 // "page" or "line". The resulting position will have a hitSide=true 7894 // property if it reached the end of the document. 7895 function findPosV(cm, pos, dir, unit) { 7896 var doc = cm.doc, x = pos.left, y; 7897 if (unit == "page") { 7898 var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); 7899 y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); 7900 } else if (unit == "line") { 7901 y = dir > 0 ? pos.bottom + 3 : pos.top - 3; 7902 } 7903 for (;;) { 7904 var target = coordsChar(cm, x, y); 7905 if (!target.outside) break; 7906 if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } 7907 y += dir * 5; 7908 } 7909 return target; 7910 } 7911 7912 // EDITOR METHODS 7913 7914 // The publicly visible API. Note that methodOp(f) means 7915 // 'wrap f in an operation, performed on its `this` parameter'. 7916 7917 // This is not the complete set of editor methods. Most of the 7918 // methods defined on the Doc type are also injected into 7919 // CodeMirror.prototype, for backwards compatibility and 7920 // convenience. 7921 7922 CodeMirror.prototype = { 7923 constructor: CodeMirror, 7924 focus: function(){window.focus(); this.display.input.focus();}, 7925 7926 setOption: function(option, value) { 7927 var options = this.options, old = options[option]; 7928 if (options[option] == value && option != "mode") return; 7929 options[option] = value; 7930 if (optionHandlers.hasOwnProperty(option)) 7931 operation(this, optionHandlers[option])(this, value, old); 7932 }, 7933 7934 getOption: function(option) {return this.options[option];}, 7935 getDoc: function() {return this.doc;}, 7936 7937 addKeyMap: function(map, bottom) { 7938 this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map)); 7939 }, 7940 removeKeyMap: function(map) { 7941 var maps = this.state.keyMaps; 7942 for (var i = 0; i < maps.length; ++i) 7943 if (maps[i] == map || maps[i].name == map) { 7944 maps.splice(i, 1); 7945 return true; 7946 } 7947 }, 7948 7949 addOverlay: methodOp(function(spec, options) { 7950 var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); 7951 if (mode.startState) throw new Error("Overlays may not be stateful."); 7952 this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque}); 7953 this.state.modeGen++; 7954 regChange(this); 7955 }), 7956 removeOverlay: methodOp(function(spec) { 7957 var overlays = this.state.overlays; 7958 for (var i = 0; i < overlays.length; ++i) { 7959 var cur = overlays[i].modeSpec; 7960 if (cur == spec || typeof spec == "string" && cur.name == spec) { 7961 overlays.splice(i, 1); 7962 this.state.modeGen++; 7963 regChange(this); 7964 return; 7965 } 7966 } 7967 }), 7968 7969 indentLine: methodOp(function(n, dir, aggressive) { 7970 if (typeof dir != "string" && typeof dir != "number") { 7971 if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; 7972 else dir = dir ? "add" : "subtract"; 7973 } 7974 if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); 7975 }), 7976 indentSelection: methodOp(function(how) { 7977 var ranges = this.doc.sel.ranges, end = -1; 7978 for (var i = 0; i < ranges.length; i++) { 7979 var range = ranges[i]; 7980 if (!range.empty()) { 7981 var from = range.from(), to = range.to(); 7982 var start = Math.max(end, from.line); 7983 end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1; 7984 for (var j = start; j < end; ++j) 7985 indentLine(this, j, how); 7986 var newRanges = this.doc.sel.ranges; 7987 if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0) 7988 replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); 7989 } else if (range.head.line > end) { 7990 indentLine(this, range.head.line, how, true); 7991 end = range.head.line; 7992 if (i == this.doc.sel.primIndex) ensureCursorVisible(this); 7993 } 7994 } 7995 }), 7996 7997 // Fetch the parser token for a given character. Useful for hacks 7998 // that want to inspect the mode state (say, for completion). 7999 getTokenAt: function(pos, precise) { 8000 return takeToken(this, pos, precise); 8001 }, 8002 8003 getLineTokens: function(line, precise) { 8004 return takeToken(this, Pos(line), precise, true); 8005 }, 8006 8007 getTokenTypeAt: function(pos) { 8008 pos = clipPos(this.doc, pos); 8009 var styles = getLineStyles(this, getLine(this.doc, pos.line)); 8010 var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; 8011 var type; 8012 if (ch == 0) type = styles[2]; 8013 else for (;;) { 8014 var mid = (before + after) >> 1; 8015 if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; 8016 else if (styles[mid * 2 + 1] < ch) before = mid + 1; 8017 else { type = styles[mid * 2 + 2]; break; } 8018 } 8019 var cut = type ? type.indexOf("cm-overlay ") : -1; 8020 return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1); 8021 }, 8022 8023 getModeAt: function(pos) { 8024 var mode = this.doc.mode; 8025 if (!mode.innerMode) return mode; 8026 return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; 8027 }, 8028 8029 getHelper: function(pos, type) { 8030 return this.getHelpers(pos, type)[0]; 8031 }, 8032 8033 getHelpers: function(pos, type) { 8034 var found = []; 8035 if (!helpers.hasOwnProperty(type)) return found; 8036 var help = helpers[type], mode = this.getModeAt(pos); 8037 if (typeof mode[type] == "string") { 8038 if (help[mode[type]]) found.push(help[mode[type]]); 8039 } else if (mode[type]) { 8040 for (var i = 0; i < mode[type].length; i++) { 8041 var val = help[mode[type][i]]; 8042 if (val) found.push(val); 8043 } 8044 } else if (mode.helperType && help[mode.helperType]) { 8045 found.push(help[mode.helperType]); 8046 } else if (help[mode.name]) { 8047 found.push(help[mode.name]); 8048 } 8049 for (var i = 0; i < help._global.length; i++) { 8050 var cur = help._global[i]; 8051 if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) 8052 found.push(cur.val); 8053 } 8054 return found; 8055 }, 8056 8057 getStateAfter: function(line, precise) { 8058 var doc = this.doc; 8059 line = clipLine(doc, line == null ? doc.first + doc.size - 1: line); 8060 return getStateBefore(this, line + 1, precise); 8061 }, 8062 8063 cursorCoords: function(start, mode) { 8064 var pos, range = this.doc.sel.primary(); 8065 if (start == null) pos = range.head; 8066 else if (typeof start == "object") pos = clipPos(this.doc, start); 8067 else pos = start ? range.from() : range.to(); 8068 return cursorCoords(this, pos, mode || "page"); 8069 }, 8070 8071 charCoords: function(pos, mode) { 8072 return charCoords(this, clipPos(this.doc, pos), mode || "page"); 8073 }, 8074 8075 coordsChar: function(coords, mode) { 8076 coords = fromCoordSystem(this, coords, mode || "page"); 8077 return coordsChar(this, coords.left, coords.top); 8078 }, 8079 8080 lineAtHeight: function(height, mode) { 8081 height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top; 8082 return lineAtHeight(this.doc, height + this.display.viewOffset); 8083 }, 8084 heightAtLine: function(line, mode) { 8085 var end = false, lineObj; 8086 if (typeof line == "number") { 8087 var last = this.doc.first + this.doc.size - 1; 8088 if (line < this.doc.first) line = this.doc.first; 8089 else if (line > last) { line = last; end = true; } 8090 lineObj = getLine(this.doc, line); 8091 } else { 8092 lineObj = line; 8093 } 8094 return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top + 8095 (end ? this.doc.height - heightAtLine(lineObj) : 0); 8096 }, 8097 8098 defaultTextHeight: function() { return textHeight(this.display); }, 8099 defaultCharWidth: function() { return charWidth(this.display); }, 8100 8101 setGutterMarker: methodOp(function(line, gutterID, value) { 8102 return changeLine(this.doc, line, "gutter", function(line) { 8103 var markers = line.gutterMarkers || (line.gutterMarkers = {}); 8104 markers[gutterID] = value; 8105 if (!value && isEmpty(markers)) line.gutterMarkers = null; 8106 return true; 8107 }); 8108 }), 8109 8110 clearGutter: methodOp(function(gutterID) { 8111 var cm = this, doc = cm.doc, i = doc.first; 8112 doc.iter(function(line) { 8113 if (line.gutterMarkers && line.gutterMarkers[gutterID]) { 8114 line.gutterMarkers[gutterID] = null; 8115 regLineChange(cm, i, "gutter"); 8116 if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; 8117 } 8118 ++i; 8119 }); 8120 }), 8121 8122 lineInfo: function(line) { 8123 if (typeof line == "number") { 8124 if (!isLine(this.doc, line)) return null; 8125 var n = line; 8126 line = getLine(this.doc, line); 8127 if (!line) return null; 8128 } else { 8129 var n = lineNo(line); 8130 if (n == null) return null; 8131 } 8132 return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, 8133 textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, 8134 widgets: line.widgets}; 8135 }, 8136 8137 getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};}, 8138 8139 addWidget: function(pos, node, scroll, vert, horiz) { 8140 var display = this.display; 8141 pos = cursorCoords(this, clipPos(this.doc, pos)); 8142 var top = pos.bottom, left = pos.left; 8143 node.style.position = "absolute"; 8144 node.setAttribute("cm-ignore-events", "true"); 8145 this.display.input.setUneditable(node); 8146 display.sizer.appendChild(node); 8147 if (vert == "over") { 8148 top = pos.top; 8149 } else if (vert == "above" || vert == "near") { 8150 var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), 8151 hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); 8152 // Default to positioning above (if specified and possible); otherwise default to positioning below 8153 if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) 8154 top = pos.top - node.offsetHeight; 8155 else if (pos.bottom + node.offsetHeight <= vspace) 8156 top = pos.bottom; 8157 if (left + node.offsetWidth > hspace) 8158 left = hspace - node.offsetWidth; 8159 } 8160 node.style.top = top + "px"; 8161 node.style.left = node.style.right = ""; 8162 if (horiz == "right") { 8163 left = display.sizer.clientWidth - node.offsetWidth; 8164 node.style.right = "0px"; 8165 } else { 8166 if (horiz == "left") left = 0; 8167 else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; 8168 node.style.left = left + "px"; 8169 } 8170 if (scroll) 8171 scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); 8172 }, 8173 8174 triggerOnKeyDown: methodOp(onKeyDown), 8175 triggerOnKeyPress: methodOp(onKeyPress), 8176 triggerOnKeyUp: onKeyUp, 8177 8178 execCommand: function(cmd) { 8179 if (commands.hasOwnProperty(cmd)) 8180 return commands[cmd].call(null, this); 8181 }, 8182 8183 triggerElectric: methodOp(function(text) { triggerElectric(this, text); }), 8184 8185 findPosH: function(from, amount, unit, visually) { 8186 var dir = 1; 8187 if (amount < 0) { dir = -1; amount = -amount; } 8188 for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { 8189 cur = findPosH(this.doc, cur, dir, unit, visually); 8190 if (cur.hitSide) break; 8191 } 8192 return cur; 8193 }, 8194 8195 moveH: methodOp(function(dir, unit) { 8196 var cm = this; 8197 cm.extendSelectionsBy(function(range) { 8198 if (cm.display.shift || cm.doc.extend || range.empty()) 8199 return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually); 8200 else 8201 return dir < 0 ? range.from() : range.to(); 8202 }, sel_move); 8203 }), 8204 8205 deleteH: methodOp(function(dir, unit) { 8206 var sel = this.doc.sel, doc = this.doc; 8207 if (sel.somethingSelected()) 8208 doc.replaceSelection("", null, "+delete"); 8209 else 8210 deleteNearSelection(this, function(range) { 8211 var other = findPosH(doc, range.head, dir, unit, false); 8212 return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other}; 8213 }); 8214 }), 8215 8216 findPosV: function(from, amount, unit, goalColumn) { 8217 var dir = 1, x = goalColumn; 8218 if (amount < 0) { dir = -1; amount = -amount; } 8219 for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { 8220 var coords = cursorCoords(this, cur, "div"); 8221 if (x == null) x = coords.left; 8222 else coords.left = x; 8223 cur = findPosV(this, coords, dir, unit); 8224 if (cur.hitSide) break; 8225 } 8226 return cur; 8227 }, 8228 8229 moveV: methodOp(function(dir, unit) { 8230 var cm = this, doc = this.doc, goals = []; 8231 var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected(); 8232 doc.extendSelectionsBy(function(range) { 8233 if (collapse) 8234 return dir < 0 ? range.from() : range.to(); 8235 var headPos = cursorCoords(cm, range.head, "div"); 8236 if (range.goalColumn != null) headPos.left = range.goalColumn; 8237 goals.push(headPos.left); 8238 var pos = findPosV(cm, headPos, dir, unit); 8239 if (unit == "page" && range == doc.sel.primary()) 8240 addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top); 8241 return pos; 8242 }, sel_move); 8243 if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++) 8244 doc.sel.ranges[i].goalColumn = goals[i]; 8245 }), 8246 8247 // Find the word at the given position (as returned by coordsChar). 8248 findWordAt: function(pos) { 8249 var doc = this.doc, line = getLine(doc, pos.line).text; 8250 var start = pos.ch, end = pos.ch; 8251 if (line) { 8252 var helper = this.getHelper(pos, "wordChars"); 8253 if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; 8254 var startChar = line.charAt(start); 8255 var check = isWordChar(startChar, helper) 8256 ? function(ch) { return isWordChar(ch, helper); } 8257 : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} 8258 : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; 8259 while (start > 0 && check(line.charAt(start - 1))) --start; 8260 while (end < line.length && check(line.charAt(end))) ++end; 8261 } 8262 return new Range(Pos(pos.line, start), Pos(pos.line, end)); 8263 }, 8264 8265 toggleOverwrite: function(value) { 8266 if (value != null && value == this.state.overwrite) return; 8267 if (this.state.overwrite = !this.state.overwrite) 8268 addClass(this.display.cursorDiv, "CodeMirror-overwrite"); 8269 else 8270 rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); 8271 8272 signal(this, "overwriteToggle", this, this.state.overwrite); 8273 }, 8274 hasFocus: function() { return this.display.input.getField() == activeElt(); },
vendor: 5,266 bytes, lines 8275-8414
8275 8276 scrollTo: methodOp(function(x, y) { 8277 if (x != null || y != null) resolveScrollToPos(this); 8278 if (x != null) this.curOp.scrollLeft = x; 8279 if (y != null) this.curOp.scrollTop = y; 8280 }), 8281 getScrollInfo: function() { 8282 var scroller = this.display.scroller; 8283 return {left: scroller.scrollLeft, top: scroller.scrollTop, 8284 height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight, 8285 width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth, 8286 clientHeight: displayHeight(this), clientWidth: displayWidth(this)}; 8287 }, 8288 8289 scrollIntoView: methodOp(function(range, margin) { 8290 if (range == null) { 8291 range = {from: this.doc.sel.primary().head, to: null}; 8292 if (margin == null) margin = this.options.cursorScrollMargin; 8293 } else if (typeof range == "number") { 8294 range = {from: Pos(range, 0), to: null}; 8295 } else if (range.from == null) { 8296 range = {from: range, to: null}; 8297 } 8298 if (!range.to) range.to = range.from; 8299 range.margin = margin || 0; 8300 8301 if (range.from.line != null) { 8302 resolveScrollToPos(this); 8303 this.curOp.scrollToPos = range; 8304 } else { 8305 var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left), 8306 Math.min(range.from.top, range.to.top) - range.margin, 8307 Math.max(range.from.right, range.to.right), 8308 Math.max(range.from.bottom, range.to.bottom) + range.margin); 8309 this.scrollTo(sPos.scrollLeft, sPos.scrollTop); 8310 } 8311 }), 8312 8313 setSize: methodOp(function(width, height) { 8314 var cm = this; 8315 function interpret(val) { 8316 return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; 8317 } 8318 if (width != null) cm.display.wrapper.style.width = interpret(width); 8319 if (height != null) cm.display.wrapper.style.height = interpret(height); 8320 if (cm.options.lineWrapping) clearLineMeasurementCache(this); 8321 var lineNo = cm.display.viewFrom; 8322 cm.doc.iter(lineNo, cm.display.viewTo, function(line) { 8323 if (line.widgets) for (var i = 0; i < line.widgets.length; i++) 8324 if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; } 8325 ++lineNo; 8326 }); 8327 cm.curOp.forceUpdate = true; 8328 signal(cm, "refresh", this); 8329 }), 8330 8331 operation: function(f){return runInOp(this, f);}, 8332 8333 refresh: methodOp(function() { 8334 var oldHeight = this.display.cachedTextHeight; 8335 regChange(this); 8336 this.curOp.forceUpdate = true; 8337 clearCaches(this); 8338 this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop); 8339 updateGutterSpace(this); 8340 if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) 8341 estimateLineHeights(this); 8342 signal(this, "refresh", this); 8343 }), 8344 8345 swapDoc: methodOp(function(doc) { 8346 var old = this.doc; 8347 old.cm = null; 8348 attachDoc(this, doc); 8349 clearCaches(this); 8350 this.display.input.reset(); 8351 this.scrollTo(doc.scrollLeft, doc.scrollTop); 8352 this.curOp.forceScroll = true; 8353 signalLater(this, "swapDoc", this, old); 8354 return old; 8355 }), 8356 8357 getInputField: function(){return this.display.input.getField();}, 8358 getWrapperElement: function(){return this.display.wrapper;}, 8359 getScrollerElement: function(){return this.display.scroller;}, 8360 getGutterElement: function(){return this.display.gutters;} 8361 }; 8362 eventMixin(CodeMirror); 8363 8364 // OPTION DEFAULTS 8365 8366 // The default configuration options. 8367 var defaults = CodeMirror.defaults = {}; 8368 // Functions to run when options are changed. 8369 var optionHandlers = CodeMirror.optionHandlers = {}; 8370 8371 function option(name, deflt, handle, notOnInit) { 8372 CodeMirror.defaults[name] = deflt; 8373 if (handle) optionHandlers[name] = 8374 notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle; 8375 } 8376 8377 // Passed to option handlers when there is no old value. 8378 var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}}; 8379 8380 // These two are, on init, called from the constructor because they 8381 // have to be initialized before the editor can start at all. 8382 option("value", "", function(cm, val) { 8383 cm.setValue(val); 8384 }, true); 8385 option("mode", null, function(cm, val) { 8386 cm.doc.modeOption = val; 8387 loadMode(cm); 8388 }, true); 8389 8390 option("indentUnit", 2, loadMode, true); 8391 option("indentWithTabs", false); 8392 option("smartIndent", true); 8393 option("tabSize", 4, function(cm) { 8394 resetModeState(cm); 8395 clearCaches(cm); 8396 regChange(cm); 8397 }, true); 8398 option("lineSeparator", null, function(cm, val) { 8399 cm.doc.lineSep = val; 8400 if (!val) return; 8401 var newBreaks = [], lineNo = cm.doc.first; 8402 cm.doc.iter(function(line) { 8403 for (var pos = 0;;) { 8404 var found = line.text.indexOf(val, pos); 8405 if (found == -1) break; 8406 pos = found + val.length; 8407 newBreaks.push(Pos(lineNo, found)); 8408 } 8409 lineNo++; 8410 }); 8411 for (var i = newBreaks.length - 1; i >= 0; i--) 8412 replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)) 8413 }); 8414 option("specialChars", /[\t\u0000-\u0019
vendor: 13,170 bytes, lines 8414-8743
8414\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) { 8415 cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); 8416 if (old != CodeMirror.Init) cm.refresh(); 8417 }); 8418 option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true); 8419 option("electricChars", true); 8420 option("inputStyle", mobile ? "contenteditable" : "textarea", function() { 8421 throw new Error("inputStyle can not (yet) be changed in a running editor"); // FIXME 8422 }, true); 8423 option("rtlMoveVisually", !windows); 8424 option("wholeLineUpdateBefore", true); 8425 8426 option("theme", "default", function(cm) { 8427 themeChanged(cm); 8428 guttersChanged(cm); 8429 }, true); 8430 option("keyMap", "default", function(cm, val, old) { 8431 var next = getKeyMap(val); 8432 var prev = old != CodeMirror.Init && getKeyMap(old); 8433 if (prev && prev.detach) prev.detach(cm, next); 8434 if (next.attach) next.attach(cm, prev || null); 8435 }); 8436 option("extraKeys", null); 8437 8438 option("lineWrapping", false, wrappingChanged, true); 8439 option("gutters", [], function(cm) { 8440 setGuttersForLineNumbers(cm.options); 8441 guttersChanged(cm); 8442 }, true); 8443 option("fixedGutter", true, function(cm, val) { 8444 cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; 8445 cm.refresh(); 8446 }, true); 8447 option("coverGutterNextToScrollbar", false, function(cm) {updateScrollbars(cm);}, true); 8448 option("scrollbarStyle", "native", function(cm) { 8449 initScrollbars(cm); 8450 updateScrollbars(cm); 8451 cm.display.scrollbars.setScrollTop(cm.doc.scrollTop); 8452 cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft); 8453 }, true); 8454 option("lineNumbers", false, function(cm) { 8455 setGuttersForLineNumbers(cm.options); 8456 guttersChanged(cm); 8457 }, true); 8458 option("firstLineNumber", 1, guttersChanged, true); 8459 option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true); 8460 option("showCursorWhenSelecting", false, updateSelection, true); 8461 8462 option("resetSelectionOnContextMenu", true); 8463 option("lineWiseCopyCut", true); 8464 8465 option("readOnly", false, function(cm, val) { 8466 if (val == "nocursor") { 8467 onBlur(cm); 8468 cm.display.input.blur(); 8469 cm.display.disabled = true; 8470 } else { 8471 cm.display.disabled = false; 8472 } 8473 cm.display.input.readOnlyChanged(val) 8474 }); 8475 option("disableInput", false, function(cm, val) {if (!val) cm.display.input.reset();}, true); 8476 option("dragDrop", true, dragDropChanged); 8477 option("allowDropFileTypes", null); 8478 8479 option("cursorBlinkRate", 530); 8480 option("cursorScrollMargin", 0); 8481 option("cursorHeight", 1, updateSelection, true); 8482 option("singleCursorHeightPerLine", true, updateSelection, true); 8483 option("workTime", 100); 8484 option("workDelay", 100); 8485 option("flattenSpans", true, resetModeState, true); 8486 option("addModeClass", false, resetModeState, true); 8487 option("pollInterval", 100); 8488 option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;}); 8489 option("historyEventDelay", 1250); 8490 option("viewportMargin", 10, function(cm){cm.refresh();}, true); 8491 option("maxHighlightLength", 10000, resetModeState, true); 8492 option("moveInputWithCursor", true, function(cm, val) { 8493 if (!val) cm.display.input.resetPosition(); 8494 }); 8495 8496 option("tabindex", null, function(cm, val) { 8497 cm.display.input.getField().tabIndex = val || ""; 8498 }); 8499 option("autofocus", null); 8500 8501 // MODE DEFINITION AND QUERYING 8502 8503 // Known modes, by name and by MIME 8504 var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; 8505 8506 // Extra arguments are stored as the mode's dependencies, which is 8507 // used by (legacy) mechanisms like loadmode.js to automatically 8508 // load a mode. (Preferred mechanism is the require/define calls.) 8509 CodeMirror.defineMode = function(name, mode) { 8510 if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; 8511 if (arguments.length > 2) 8512 mode.dependencies = Array.prototype.slice.call(arguments, 2); 8513 modes[name] = mode; 8514 }; 8515 8516 CodeMirror.defineMIME = function(mime, spec) { 8517 mimeModes[mime] = spec; 8518 }; 8519 8520 // Given a MIME type, a {name, ...options} config object, or a name 8521 // string, return a mode config object. 8522 CodeMirror.resolveMode = function(spec) { 8523 if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { 8524 spec = mimeModes[spec]; 8525 } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { 8526 var found = mimeModes[spec.name]; 8527 if (typeof found == "string") found = {name: found}; 8528 spec = createObj(found, spec); 8529 spec.name = found.name; 8530 } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { 8531 return CodeMirror.resolveMode("application/xml"); 8532 } 8533 if (typeof spec == "string") return {name: spec}; 8534 else return spec || {name: "null"}; 8535 }; 8536 8537 // Given a mode spec (anything that resolveMode accepts), find and 8538 // initialize an actual mode object. 8539 CodeMirror.getMode = function(options, spec) { 8540 var spec = CodeMirror.resolveMode(spec); 8541 var mfactory = modes[spec.name]; 8542 if (!mfactory) return CodeMirror.getMode(options, "text/plain"); 8543 var modeObj = mfactory(options, spec); 8544 if (modeExtensions.hasOwnProperty(spec.name)) { 8545 var exts = modeExtensions[spec.name]; 8546 for (var prop in exts) { 8547 if (!exts.hasOwnProperty(prop)) continue; 8548 if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; 8549 modeObj[prop] = exts[prop]; 8550 } 8551 } 8552 modeObj.name = spec.name; 8553 if (spec.helperType) modeObj.helperType = spec.helperType; 8554 if (spec.modeProps) for (var prop in spec.modeProps) 8555 modeObj[prop] = spec.modeProps[prop]; 8556 8557 return modeObj; 8558 }; 8559 8560 // Minimal default mode. 8561 CodeMirror.defineMode("null", function() { 8562 return {token: function(stream) {stream.skipToEnd();}}; 8563 }); 8564 CodeMirror.defineMIME("text/plain", "null"); 8565 8566 // This can be used to attach properties to mode objects from 8567 // outside the actual mode definition. 8568 var modeExtensions = CodeMirror.modeExtensions = {}; 8569 CodeMirror.extendMode = function(mode, properties) { 8570 var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); 8571 copyObj(properties, exts); 8572 }; 8573 8574 // EXTENSIONS 8575 8576 CodeMirror.defineExtension = function(name, func) { 8577 CodeMirror.prototype[name] = func; 8578 }; 8579 CodeMirror.defineDocExtension = function(name, func) { 8580 Doc.prototype[name] = func; 8581 }; 8582 CodeMirror.defineOption = option; 8583 8584 var initHooks = []; 8585 CodeMirror.defineInitHook = function(f) {initHooks.push(f);}; 8586 8587 var helpers = CodeMirror.helpers = {}; 8588 CodeMirror.registerHelper = function(type, name, value) { 8589 if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []}; 8590 helpers[type][name] = value; 8591 }; 8592 CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { 8593 CodeMirror.registerHelper(type, name, value); 8594 helpers[type]._global.push({pred: predicate, val: value}); 8595 }; 8596 8597 // MODE STATE HANDLING 8598 8599 // Utility functions for working with state. Exported because nested 8600 // modes need to do this for their inner modes. 8601 8602 var copyState = CodeMirror.copyState = function(mode, state) { 8603 if (state === true) return state; 8604 if (mode.copyState) return mode.copyState(state); 8605 var nstate = {}; 8606 for (var n in state) { 8607 var val = state[n]; 8608 if (val instanceof Array) val = val.concat([]); 8609 nstate[n] = val; 8610 } 8611 return nstate; 8612 }; 8613 8614 var startState = CodeMirror.startState = function(mode, a1, a2) { 8615 return mode.startState ? mode.startState(a1, a2) : true; 8616 }; 8617 8618 // Given a mode and a state (for that mode), find the inner mode and 8619 // state at the position that the state refers to. 8620 CodeMirror.innerMode = function(mode, state) { 8621 while (mode.innerMode) { 8622 var info = mode.innerMode(state); 8623 if (!info || info.mode == mode) break; 8624 state = info.state; 8625 mode = info.mode; 8626 } 8627 return info || {mode: mode, state: state}; 8628 }; 8629 8630 // STANDARD COMMANDS 8631 8632 // Commands are parameter-less actions that can be performed on an 8633 // editor, mostly used for keybindings. 8634 var commands = CodeMirror.commands = { 8635 selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);}, 8636 singleSelection: function(cm) { 8637 cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); 8638 }, 8639 killLine: function(cm) { 8640 deleteNearSelection(cm, function(range) { 8641 if (range.empty()) { 8642 var len = getLine(cm.doc, range.head.line).text.length; 8643 if (range.head.ch == len && range.head.line < cm.lastLine()) 8644 return {from: range.head, to: Pos(range.head.line + 1, 0)}; 8645 else 8646 return {from: range.head, to: Pos(range.head.line, len)}; 8647 } else { 8648 return {from: range.from(), to: range.to()}; 8649 } 8650 }); 8651 }, 8652 deleteLine: function(cm) { 8653 deleteNearSelection(cm, function(range) { 8654 return {from: Pos(range.from().line, 0), 8655 to: clipPos(cm.doc, Pos(range.to().line + 1, 0))}; 8656 }); 8657 }, 8658 delLineLeft: function(cm) { 8659 deleteNearSelection(cm, function(range) { 8660 return {from: Pos(range.from().line, 0), to: range.from()}; 8661 }); 8662 }, 8663 delWrappedLineLeft: function(cm) { 8664 deleteNearSelection(cm, function(range) { 8665 var top = cm.charCoords(range.head, "div").top + 5; 8666 var leftPos = cm.coordsChar({left: 0, top: top}, "div"); 8667 return {from: leftPos, to: range.from()}; 8668 }); 8669 }, 8670 delWrappedLineRight: function(cm) { 8671 deleteNearSelection(cm, function(range) { 8672 var top = cm.charCoords(range.head, "div").top + 5; 8673 var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); 8674 return {from: range.from(), to: rightPos }; 8675 }); 8676 }, 8677 undo: function(cm) {cm.undo();}, 8678 redo: function(cm) {cm.redo();}, 8679 undoSelection: function(cm) {cm.undoSelection();}, 8680 redoSelection: function(cm) {cm.redoSelection();}, 8681 goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));}, 8682 goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));}, 8683 goLineStart: function(cm) { 8684 cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); }, 8685 {origin: "+move", bias: 1}); 8686 }, 8687 goLineStartSmart: function(cm) { 8688 cm.extendSelectionsBy(function(range) { 8689 return lineStartSmart(cm, range.head); 8690 }, {origin: "+move", bias: 1}); 8691 }, 8692 goLineEnd: function(cm) { 8693 cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); }, 8694 {origin: "+move", bias: -1}); 8695 }, 8696 goLineRight: function(cm) { 8697 cm.extendSelectionsBy(function(range) { 8698 var top = cm.charCoords(range.head, "div").top + 5; 8699 return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); 8700 }, sel_move); 8701 }, 8702 goLineLeft: function(cm) { 8703 cm.extendSelectionsBy(function(range) { 8704 var top = cm.charCoords(range.head, "div").top + 5; 8705 return cm.coordsChar({left: 0, top: top}, "div"); 8706 }, sel_move); 8707 }, 8708 goLineLeftSmart: function(cm) { 8709 cm.extendSelectionsBy(function(range) { 8710 var top = cm.charCoords(range.head, "div").top + 5; 8711 var pos = cm.coordsChar({left: 0, top: top}, "div"); 8712 if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head); 8713 return pos; 8714 }, sel_move); 8715 }, 8716 goLineUp: function(cm) {cm.moveV(-1, "line");}, 8717 goLineDown: function(cm) {cm.moveV(1, "line");}, 8718 goPageUp: function(cm) {cm.moveV(-1, "page");}, 8719 goPageDown: function(cm) {cm.moveV(1, "page");}, 8720 goCharLeft: function(cm) {cm.moveH(-1, "char");}, 8721 goCharRight: function(cm) {cm.moveH(1, "char");}, 8722 goColumnLeft: function(cm) {cm.moveH(-1, "column");}, 8723 goColumnRight: function(cm) {cm.moveH(1, "column");}, 8724 goWordLeft: function(cm) {cm.moveH(-1, "word");}, 8725 goGroupRight: function(cm) {cm.moveH(1, "group");}, 8726 goGroupLeft: function(cm) {cm.moveH(-1, "group");}, 8727 goWordRight: function(cm) {cm.moveH(1, "word");}, 8728 delCharBefore: function(cm) {cm.deleteH(-1, "char");}, 8729 delCharAfter: function(cm) {cm.deleteH(1, "char");}, 8730 delWordBefore: function(cm) {cm.deleteH(-1, "word");}, 8731 delWordAfter: function(cm) {cm.deleteH(1, "word");}, 8732 delGroupBefore: function(cm) {cm.deleteH(-1, "group");}, 8733 delGroupAfter: function(cm) {cm.deleteH(1, "group");}, 8734 indentAuto: function(cm) {cm.indentSelection("smart");}, 8735 indentMore: function(cm) {cm.indentSelection("add");}, 8736 indentLess: function(cm) {cm.indentSelection("subtract");}, 8737 insertTab: function(cm) {cm.replaceSelection("\t");}, 8738 insertSoftTab: function(cm) { 8739 var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize; 8740 for (var i = 0; i < ranges.length; i++) { 8741 var pos = ranges[i].from(); 8742 var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize); 8743 spaces.push(
vendor: 3,732 bytes, lines 8743-8820
8743new Array(tabSize - col % tabSize + 1).join(" ")); 8744 } 8745 cm.replaceSelections(spaces); 8746 }, 8747 defaultTab: function(cm) { 8748 if (cm.somethingSelected()) cm.indentSelection("add"); 8749 else cm.execCommand("insertTab"); 8750 }, 8751 transposeChars: function(cm) { 8752 runInOp(cm, function() { 8753 var ranges = cm.listSelections(), newSel = []; 8754 for (var i = 0; i < ranges.length; i++) { 8755 var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; 8756 if (line) { 8757 if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1); 8758 if (cur.ch > 0) { 8759 cur = new Pos(cur.line, cur.ch + 1); 8760 cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), 8761 Pos(cur.line, cur.ch - 2), cur, "+transpose"); 8762 } else if (cur.line > cm.doc.first) { 8763 var prev = getLine(cm.doc, cur.line - 1).text; 8764 if (prev) 8765 cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() + 8766 prev.charAt(prev.length - 1), 8767 Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose"); 8768 } 8769 } 8770 newSel.push(new Range(cur, cur)); 8771 } 8772 cm.setSelections(newSel); 8773 }); 8774 }, 8775 newlineAndIndent: function(cm) { 8776 runInOp(cm, function() { 8777 var len = cm.listSelections().length; 8778 for (var i = 0; i < len; i++) { 8779 var range = cm.listSelections()[i]; 8780 cm.replaceRange(cm.doc.lineSeparator(), range.anchor, range.head, "+input"); 8781 cm.indentLine(range.from().line + 1, null, true); 8782 } 8783 ensureCursorVisible(cm); 8784 }); 8785 }, 8786 toggleOverwrite: function(cm) {cm.toggleOverwrite();} 8787 }; 8788 8789 8790 // STANDARD KEYMAPS 8791 8792 var keyMap = CodeMirror.keyMap = {}; 8793 8794 keyMap.basic = { 8795 "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", 8796 "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", 8797 "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", 8798 "Tab": "defaultTab", "Shift-Tab": "indentAuto", 8799 "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", 8800 "Esc": "singleSelection" 8801 }; 8802 // Note that the save and find-related commands aren't defined by 8803 // default. User code or addons can define them. Unknown commands 8804 // are simply ignored. 8805 keyMap.pcDefault = { 8806 "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", 8807 "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown", 8808 "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", 8809 "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", 8810 "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", 8811 "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", 8812 "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", 8813 fallthrough: "basic" 8814 }; 8815 // Very basic readline/emacs-style bindings, which are standard on Mac. 8816 keyMap.emacsy = { 8817 "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", 8818 "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", 8819 "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", 8820 "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars
vendor: 30,541 bytes, lines 8820-9582
8820" 8821 }; 8822 keyMap.macDefault = { 8823 "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", 8824 "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", 8825 "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore", 8826 "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", 8827 "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", 8828 "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", 8829 "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", 8830 fallthrough: ["basic", "emacsy"] 8831 }; 8832 keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; 8833 8834 // KEYMAP DISPATCH 8835 8836 function normalizeKeyName(name) { 8837 var parts = name.split(/-(?!$)/), name = parts[parts.length - 1]; 8838 var alt, ctrl, shift, cmd; 8839 for (var i = 0; i < parts.length - 1; i++) { 8840 var mod = parts[i]; 8841 if (/^(cmd|meta|m)$/i.test(mod)) cmd = true; 8842 else if (/^a(lt)?$/i.test(mod)) alt = true; 8843 else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true; 8844 else if (/^s(hift)$/i.test(mod)) shift = true; 8845 else throw new Error("Unrecognized modifier name: " + mod); 8846 } 8847 if (alt) name = "Alt-" + name; 8848 if (ctrl) name = "Ctrl-" + name; 8849 if (cmd) name = "Cmd-" + name; 8850 if (shift) name = "Shift-" + name; 8851 return name; 8852 } 8853 8854 // This is a kludge to keep keymaps mostly working as raw objects 8855 // (backwards compatibility) while at the same time support features 8856 // like normalization and multi-stroke key bindings. It compiles a 8857 // new normalized keymap, and then updates the old object to reflect 8858 // this. 8859 CodeMirror.normalizeKeyMap = function(keymap) { 8860 var copy = {}; 8861 for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) { 8862 var value = keymap[keyname]; 8863 if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue; 8864 if (value == "...") { delete keymap[keyname]; continue; } 8865 8866 var keys = map(keyname.split(" "), normalizeKeyName); 8867 for (var i = 0; i < keys.length; i++) { 8868 var val, name; 8869 if (i == keys.length - 1) { 8870 name = keys.join(" "); 8871 val = value; 8872 } else { 8873 name = keys.slice(0, i + 1).join(" "); 8874 val = "..."; 8875 } 8876 var prev = copy[name]; 8877 if (!prev) copy[name] = val; 8878 else if (prev != val) throw new Error("Inconsistent bindings for " + name); 8879 } 8880 delete keymap[keyname]; 8881 } 8882 for (var prop in copy) keymap[prop] = copy[prop]; 8883 return keymap; 8884 }; 8885 8886 var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) { 8887 map = getKeyMap(map); 8888 var found = map.call ? map.call(key, context) : map[key]; 8889 if (found === false) return "nothing"; 8890 if (found === "...") return "multi"; 8891 if (found != null && handle(found)) return "handled"; 8892 8893 if (map.fallthrough) { 8894 if (Object.prototype.toString.call(map.fallthrough) != "[object Array]") 8895 return lookupKey(key, map.fallthrough, handle, context); 8896 for (var i = 0; i < map.fallthrough.length; i++) { 8897 var result = lookupKey(key, map.fallthrough[i], handle, context); 8898 if (result) return result; 8899 } 8900 } 8901 }; 8902 8903 // Modifier key presses don't count as 'real' key presses for the 8904 // purpose of keymap fallthrough. 8905 var isModifierKey = CodeMirror.isModifierKey = function(value) { 8906 var name = typeof value == "string" ? value : keyNames[value.keyCode]; 8907 return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; 8908 }; 8909 8910 // Look up the name of a key as indicated by an event object. 8911 var keyName = CodeMirror.keyName = function(event, noShift) { 8912 if (presto && event.keyCode == 34 && event["char"]) return false; 8913 var base = keyNames[event.keyCode], name = base; 8914 if (name == null || event.altGraphKey) return false; 8915 if (event.altKey && base != "Alt") name = "Alt-" + name; 8916 if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name; 8917 if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name; 8918 if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name; 8919 return name; 8920 }; 8921 8922 function getKeyMap(val) { 8923 return typeof val == "string" ? keyMap[val] : val; 8924 } 8925 8926 // FROMTEXTAREA 8927 8928 CodeMirror.fromTextArea = function(textarea, options) { 8929 options = options ? copyObj(options) : {}; 8930 options.value = textarea.value; 8931 if (!options.tabindex && textarea.tabIndex) 8932 options.tabindex = textarea.tabIndex; 8933 if (!options.placeholder && textarea.placeholder) 8934 options.placeholder = textarea.placeholder; 8935 // Set autofocus to true if this textarea is focused, or if it has 8936 // autofocus and no other element is focused. 8937 if (options.autofocus == null) { 8938 var hasFocus = activeElt(); 8939 options.autofocus = hasFocus == textarea || 8940 textarea.getAttribute("autofocus") != null && hasFocus == document.body; 8941 } 8942 8943 function save() {textarea.value = cm.getValue();} 8944 if (textarea.form) { 8945 on(textarea.form, "submit", save); 8946 // Deplorable hack to make the submit method do the right thing. 8947 if (!options.leaveSubmitMethodAlone) { 8948 var form = textarea.form, realSubmit = form.submit; 8949 try { 8950 var wrappedSubmit = form.submit = function() { 8951 save(); 8952 form.submit = realSubmit; 8953 form.submit(); 8954 form.submit = wrappedSubmit; 8955 }; 8956 } catch(e) {} 8957 } 8958 } 8959 8960 options.finishInit = function(cm) { 8961 cm.save = save; 8962 cm.getTextArea = function() { return textarea; }; 8963 cm.toTextArea = function() { 8964 cm.toTextArea = isNaN; // Prevent this from being ran twice 8965 save(); 8966 textarea.parentNode.removeChild(cm.getWrapperElement()); 8967 textarea.style.display = ""; 8968 if (textarea.form) { 8969 off(textarea.form, "submit", save); 8970 if (typeof textarea.form.submit == "function") 8971 textarea.form.submit = realSubmit; 8972 } 8973 }; 8974 }; 8975 8976 textarea.style.display = "none"; 8977 var cm = CodeMirror(function(node) { 8978 textarea.parentNode.insertBefore(node, textarea.nextSibling); 8979 }, options); 8980 return cm; 8981 }; 8982 8983 // STRING STREAM 8984 8985 // Fed to the mode parsers, provides helper functions to make 8986 // parsers more succinct. 8987 8988 var StringStream = CodeMirror.StringStream = function(string, tabSize) { 8989 this.pos = this.start = 0; 8990 this.string = string; 8991 this.tabSize = tabSize || 8; 8992 this.lastColumnPos = this.lastColumnValue = 0; 8993 this.lineStart = 0; 8994 }; 8995 8996 StringStream.prototype = { 8997 eol: function() {return this.pos >= this.string.length;}, 8998 sol: function() {return this.pos == this.lineStart;}, 8999 peek: function() {return this.string.charAt(this.pos) || undefined;}, 9000 next: function() { 9001 if (this.pos < this.string.length) 9002 return this.string.charAt(this.pos++); 9003 }, 9004 eat: function(match) { 9005 var ch = this.string.charAt(this.pos); 9006 if (typeof match == "string") var ok = ch == match; 9007 else var ok = ch && (match.test ? match.test(ch) : match(ch)); 9008 if (ok) {++this.pos; return ch;} 9009 }, 9010 eatWhile: function(match) { 9011 var start = this.pos; 9012 while (this.eat(match)){} 9013 return this.pos > start; 9014 }, 9015 eatSpace: function() { 9016 var start = this.pos; 9017 while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; 9018 return this.pos > start; 9019 }, 9020 skipToEnd: function() {this.pos = this.string.length;}, 9021 skipTo: function(ch) { 9022 var found = this.string.indexOf(ch, this.pos); 9023 if (found > -1) {this.pos = found; return true;} 9024 }, 9025 backUp: function(n) {this.pos -= n;}, 9026 column: function() { 9027 if (this.lastColumnPos < this.start) { 9028 this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); 9029 this.lastColumnPos = this.start; 9030 } 9031 return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); 9032 }, 9033 indentation: function() { 9034 return countColumn(this.string, null, this.tabSize) - 9035 (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); 9036 }, 9037 match: function(pattern, consume, caseInsensitive) { 9038 if (typeof pattern == "string") { 9039 var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; 9040 var substr = this.string.substr(this.pos, pattern.length); 9041 if (cased(substr) == cased(pattern)) { 9042 if (consume !== false) this.pos += pattern.length; 9043 return true; 9044 } 9045 } else { 9046 var match = this.string.slice(this.pos).match(pattern); 9047 if (match && match.index > 0) return null; 9048 if (match && consume !== false) this.pos += match[0].length; 9049 return match; 9050 } 9051 }, 9052 current: function(){return this.string.slice(this.start, this.pos);}, 9053 hideFirstChars: function(n, inner) { 9054 this.lineStart += n; 9055 try { return inner(); } 9056 finally { this.lineStart -= n; } 9057 } 9058 }; 9059 9060 // TEXTMARKERS 9061 9062 // Created with markText and setBookmark methods. A TextMarker is a 9063 // handle that can be used to clear or find a marked position in the 9064 // document. Line objects hold arrays (markedSpans) containing 9065 // {from, to, marker} object pointing to such marker objects, and 9066 // indicating that such a marker is present on that line. Multiple 9067 // lines may point to the same marker when it spans across lines. 9068 // The spans will have null for their from/to properties when the 9069 // marker continues beyond the start/end of the line. Markers have 9070 // links back to the lines they currently touch. 9071 9072 var nextMarkerId = 0; 9073 9074 var TextMarker = CodeMirror.TextMarker = function(doc, type) { 9075 this.lines = []; 9076 this.type = type; 9077 this.doc = doc; 9078 this.id = ++nextMarkerId; 9079 }; 9080 eventMixin(TextMarker); 9081 9082 // Clear the marker. 9083 TextMarker.prototype.clear = function() { 9084 if (this.explicitlyCleared) return; 9085 var cm = this.doc.cm, withOp = cm && !cm.curOp; 9086 if (withOp) startOperation(cm); 9087 if (hasHandler(this, "clear")) { 9088 var found = this.find(); 9089 if (found) signalLater(this, "clear", found.from, found.to); 9090 } 9091 var min = null, max = null; 9092 for (var i = 0; i < this.lines.length; ++i) { 9093 var line = this.lines[i]; 9094 var span = getMarkedSpanFor(line.markedSpans, this); 9095 if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text"); 9096 else if (cm) { 9097 if (span.to != null) max = lineNo(line); 9098 if (span.from != null) min = lineNo(line); 9099 } 9100 line.markedSpans = removeMarkedSpan(line.markedSpans, span); 9101 if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) 9102 updateLineHeight(line, textHeight(cm.display)); 9103 } 9104 if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { 9105 var visual = visualLine(this.lines[i]), len = lineLength(visual); 9106 if (len > cm.display.maxLineLength) { 9107 cm.display.maxLine = visual; 9108 cm.display.maxLineLength = len; 9109 cm.display.maxLineChanged = true; 9110 } 9111 } 9112 9113 if (min != null && cm && this.collapsed) regChange(cm, min, max + 1); 9114 this.lines.length = 0; 9115 this.explicitlyCleared = true; 9116 if (this.atomic && this.doc.cantEdit) { 9117 this.doc.cantEdit = false; 9118 if (cm) reCheckSelection(cm.doc); 9119 } 9120 if (cm) signalLater(cm, "markerCleared", cm, this); 9121 if (withOp) endOperation(cm); 9122 if (this.parent) this.parent.clear(); 9123 }; 9124 9125 // Find the position of the marker in the document. Returns a {from, 9126 // to} object by default. Side can be passed to get a specific side 9127 // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the 9128 // Pos objects returned contain a line object, rather than a line 9129 // number (used to prevent looking up the same line twice). 9130 TextMarker.prototype.find = function(side, lineObj) { 9131 if (side == null && this.type == "bookmark") side = 1; 9132 var from, to; 9133 for (var i = 0; i < this.lines.length; ++i) { 9134 var line = this.lines[i]; 9135 var span = getMarkedSpanFor(line.markedSpans, this); 9136 if (span.from != null) { 9137 from = Pos(lineObj ? line : lineNo(line), span.from); 9138 if (side == -1) return from; 9139 } 9140 if (span.to != null) { 9141 to = Pos(lineObj ? line : lineNo(line), span.to); 9142 if (side == 1) return to; 9143 } 9144 } 9145 return from && {from: from, to: to}; 9146 }; 9147 9148 // Signals that the marker's widget changed, and surrounding layout 9149 // should be recomputed. 9150 TextMarker.prototype.changed = function() { 9151 var pos = this.find(-1, true), widget = this, cm = this.doc.cm; 9152 if (!pos || !cm) return; 9153 runInOp(cm, function() { 9154 var line = pos.line, lineN = lineNo(pos.line); 9155 var view = findViewForLine(cm, lineN); 9156 if (view) { 9157 clearLineMeasurementCacheFor(view); 9158 cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; 9159 } 9160 cm.curOp.updateMaxLine = true; 9161 if (!lineIsHidden(widget.doc, line) && widget.height != null) { 9162 var oldHeight = widget.height; 9163 widget.height = null; 9164 var dHeight = widgetHeight(widget) - oldHeight; 9165 if (dHeight) 9166 updateLineHeight(line, line.height + dHeight); 9167 } 9168 }); 9169 }; 9170 9171 TextMarker.prototype.attachLine = function(line) { 9172 if (!this.lines.length && this.doc.cm) { 9173 var op = this.doc.cm.curOp; 9174 if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) 9175 (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); 9176 } 9177 this.lines.push(line); 9178 }; 9179 TextMarker.prototype.detachLine = function(line) { 9180 this.lines.splice(indexOf(this.lines, line), 1); 9181 if (!this.lines.length && this.doc.cm) { 9182 var op = this.doc.cm.curOp; 9183 (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); 9184 } 9185 }; 9186 9187 // Collapsed markers have unique ids, in order to be able to order 9188 // them, which is needed for uniquely determining an outer marker 9189 // when they overlap (they may nest, but not partially overlap). 9190 var nextMarkerId = 0; 9191 9192 // Create a marker, wire it up to the right lines, and 9193 function markText(doc, from, to, options, type) { 9194 // Shared markers (across linked documents) are handled separately 9195 // (markTextShared will call out to this again, once per 9196 // document). 9197 if (options && options.shared) return markTextShared(doc, from, to, options, type); 9198 // Ensure we are in an operation. 9199 if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); 9200 9201 var marker = new TextMarker(doc, type), diff = cmp(from, to); 9202 if (options) copyObj(options, marker, false); 9203 // Don't connect empty markers unless clearWhenEmpty is false 9204 if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) 9205 return marker; 9206 if (marker.replacedWith) { 9207 // Showing up as a widget implies collapsed (widget replaces text) 9208 marker.collapsed = true; 9209 marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget"); 9210 if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true"); 9211 if (options.insertLeft) marker.widgetNode.insertLeft = true; 9212 } 9213 if (marker.collapsed) { 9214 if (conflictingCollapsedRange(doc, from.line, from, to, marker) || 9215 from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) 9216 throw new Error("Inserting collapsed marker partially overlapping an existing one"); 9217 sawCollapsedSpans = true; 9218 } 9219 9220 if (marker.addToHistory) 9221 addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); 9222 9223 var curLine = from.line, cm = doc.cm, updateMaxLine; 9224 doc.iter(curLine, to.line + 1, function(line) { 9225 if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) 9226 updateMaxLine = true; 9227 if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0); 9228 addMarkedSpan(line, new MarkedSpan(marker, 9229 curLine == from.line ? from.ch : null, 9230 curLine == to.line ? to.ch : null)); 9231 ++curLine; 9232 }); 9233 // lineIsHidden depends on the presence of the spans, so needs a second pass 9234 if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) { 9235 if (lineIsHidden(doc, line)) updateLineHeight(line, 0); 9236 }); 9237 9238 if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); }); 9239 9240 if (marker.readOnly) { 9241 sawReadOnlySpans = true; 9242 if (doc.history.done.length || doc.history.undone.length) 9243 doc.clearHistory(); 9244 } 9245 if (marker.collapsed) { 9246 marker.id = ++nextMarkerId; 9247 marker.atomic = true; 9248 } 9249 if (cm) { 9250 // Sync editor state 9251 if (updateMaxLine) cm.curOp.updateMaxLine = true; 9252 if (marker.collapsed) 9253 regChange(cm, from.line, to.line + 1); 9254 else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css) 9255 for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text"); 9256 if (marker.atomic) reCheckSelection(cm.doc); 9257 signalLater(cm, "markerAdded", cm, marker); 9258 } 9259 return marker; 9260 } 9261 9262 // SHARED TEXTMARKERS 9263 9264 // A shared marker spans multiple linked documents. It is 9265 // implemented as a meta-marker-object controlling multiple normal 9266 // markers. 9267 var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) { 9268 this.markers = markers; 9269 this.primary = primary; 9270 for (var i = 0; i < markers.length; ++i) 9271 markers[i].parent = this; 9272 }; 9273 eventMixin(SharedTextMarker); 9274 9275 SharedTextMarker.prototype.clear = function() { 9276 if (this.explicitlyCleared) return; 9277 this.explicitlyCleared = true; 9278 for (var i = 0; i < this.markers.length; ++i) 9279 this.markers[i].clear(); 9280 signalLater(this, "clear"); 9281 }; 9282 SharedTextMarker.prototype.find = function(side, lineObj) { 9283 return this.primary.find(side, lineObj); 9284 }; 9285 9286 function markTextShared(doc, from, to, options, type) { 9287 options = copyObj(options); 9288 options.shared = false; 9289 var markers = [markText(doc, from, to, options, type)], primary = markers[0]; 9290 var widget = options.widgetNode; 9291 linkedDocs(doc, function(doc) { 9292 if (widget) options.widgetNode = widget.cloneNode(true); 9293 markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); 9294 for (var i = 0; i < doc.linked.length; ++i) 9295 if (doc.linked[i].isParent) return; 9296 primary = lst(markers); 9297 }); 9298 return new SharedTextMarker(markers, primary); 9299 } 9300 9301 function findSharedMarkers(doc) { 9302 return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), 9303 function(m) { return m.parent; }); 9304 } 9305 9306 function copySharedMarkers(doc, markers) { 9307 for (var i = 0; i < markers.length; i++) { 9308 var marker = markers[i], pos = marker.find(); 9309 var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to); 9310 if (cmp(mFrom, mTo)) { 9311 var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type); 9312 marker.markers.push(subMark); 9313 subMark.parent = marker; 9314 } 9315 } 9316 } 9317 9318 function detachSharedMarkers(markers) { 9319 for (var i = 0; i < markers.length; i++) { 9320 var marker = markers[i], linked = [marker.primary.doc];; 9321 linkedDocs(marker.primary.doc, function(d) { linked.push(d); }); 9322 for (var j = 0; j < marker.markers.length; j++) { 9323 var subMarker = marker.markers[j]; 9324 if (indexOf(linked, subMarker.doc) == -1) { 9325 subMarker.parent = null; 9326 marker.markers.splice(j--, 1); 9327 } 9328 } 9329 } 9330 } 9331 9332 // TEXTMARKER SPANS 9333 9334 function MarkedSpan(marker, from, to) { 9335 this.marker = marker; 9336 this.from = from; this.to = to; 9337 } 9338 9339 // Search an array of spans for a span matching the given marker. 9340 function getMarkedSpanFor(spans, marker) { 9341 if (spans) for (var i = 0; i < spans.length; ++i) { 9342 var span = spans[i]; 9343 if (span.marker == marker) return span; 9344 } 9345 } 9346 // Remove a span from an array, returning undefined if no spans are 9347 // left (we don't store arrays for lines without spans). 9348 function removeMarkedSpan(spans, span) { 9349 for (var r, i = 0; i < spans.length; ++i) 9350 if (spans[i] != span) (r || (r = [])).push(spans[i]); 9351 return r; 9352 } 9353 // Add a span to a line. 9354 function addMarkedSpan(line, span) { 9355 line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; 9356 span.marker.attachLine(line); 9357 } 9358 9359 // Used for the algorithm that adjusts markers for a change in the 9360 // document. These functions cut an array of spans at a given 9361 // character position, returning an array of remaining chunks (or 9362 // undefined if nothing remains). 9363 function markedSpansBefore(old, startCh, isInsert) { 9364 if (old) for (var i = 0, nw; i < old.length; ++i) { 9365 var span = old[i], marker = span.marker; 9366 var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); 9367 if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { 9368 var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); 9369 (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); 9370 } 9371 } 9372 return nw; 9373 } 9374 function markedSpansAfter(old, endCh, isInsert) { 9375 if (old) for (var i = 0, nw; i < old.length; ++i) { 9376 var span = old[i], marker = span.marker; 9377 var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); 9378 if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { 9379 var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); 9380 (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, 9381 span.to == null ? null : span.to - endCh)); 9382 } 9383 } 9384 return nw; 9385 } 9386 9387 // Given a change object, compute the new set of marker spans that 9388 // cover the line in which the change took place. Removes spans 9389 // entirely within the change, reconnects spans belonging to the 9390 // same marker that appear on both sides of the change, and cuts off 9391 // spans partially within the change. Returns an array of span 9392 // arrays with one element for each line in (after) the change. 9393 function stretchSpansOverChange(doc, change) { 9394 if (change.full) return null; 9395 var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; 9396 var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; 9397 if (!oldFirst && !oldLast) return null; 9398 9399 var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; 9400 // Get the spans that 'stick out' on both sides 9401 var first = markedSpansBefore(oldFirst, startCh, isInsert); 9402 var last = markedSpansAfter(oldLast, endCh, isInsert); 9403 9404 // Next, merge those two ends 9405 var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); 9406 if (first) { 9407 // Fix up .to properties of first 9408 for (var i = 0; i < first.length; ++i) { 9409 var span = first[i]; 9410 if (span.to == null) { 9411 var found = getMarkedSpanFor(last, span.marker); 9412 if (!found) span.to = startCh; 9413 else if (sameLine) span.to = found.to == null ? null : found.to + offset; 9414 } 9415 } 9416 } 9417 if (last) { 9418 // Fix up .from in last (or move them into first in case of sameLine) 9419 for (var i = 0; i < last.length; ++i) { 9420 var span = last[i]; 9421 if (span.to != null) span.to += offset; 9422 if (span.from == null) { 9423 var found = getMarkedSpanFor(first, span.marker); 9424 if (!found) { 9425 span.from = offset; 9426 if (sameLine) (first || (first = [])).push(span); 9427 } 9428 } else { 9429 span.from += offset; 9430 if (sameLine) (first || (first = [])).push(span); 9431 } 9432 } 9433 } 9434 // Make sure we didn't create any zero-length spans 9435 if (first) first = clearEmptySpans(first); 9436 if (last && last != first) last = clearEmptySpans(last); 9437 9438 var newMarkers = [first]; 9439 if (!sameLine) { 9440 // Fill gap with whole-line-spans 9441 var gap = change.text.length - 2, gapMarkers; 9442 if (gap > 0 && first) 9443 for (var i = 0; i < first.length; ++i) 9444 if (first[i].to == null) 9445 (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null)); 9446 for (var i = 0; i < gap; ++i) 9447 newMarkers.push(gapMarkers); 9448 newMarkers.push(last); 9449 } 9450 return newMarkers; 9451 } 9452 9453 // Remove spans that are empty and don't have a clearWhenEmpty 9454 // option of false. 9455 function clearEmptySpans(spans) { 9456 for (var i = 0; i < spans.length; ++i) { 9457 var span = spans[i]; 9458 if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) 9459 spans.splice(i--, 1); 9460 } 9461 if (!spans.length) return null; 9462 return spans; 9463 } 9464 9465 // Used for un/re-doing changes from the history. Combines the 9466 // result of computing the existing spans with the set of spans that 9467 // existed in the history (so that deleting around a span and then 9468 // undoing brings back the span). 9469 function mergeOldSpans(doc, change) { 9470 var old = getOldSpans(doc, change); 9471 var stretched = stretchSpansOverChange(doc, change); 9472 if (!old) return stretched; 9473 if (!stretched) return old; 9474 9475 for (var i = 0; i < old.length; ++i) { 9476 var oldCur = old[i], stretchCur = stretched[i]; 9477 if (oldCur && stretchCur) { 9478 spans: for (var j = 0; j < stretchCur.length; ++j) { 9479 var span = stretchCur[j]; 9480 for (var k = 0; k < oldCur.length; ++k) 9481 if (oldCur[k].marker == span.marker) continue spans; 9482 oldCur.push(span); 9483 } 9484 } else if (stretchCur) { 9485 old[i] = stretchCur; 9486 } 9487 } 9488 return old; 9489 } 9490 9491 // Used to 'clip' out readOnly ranges when making a change. 9492 function removeReadOnlyRanges(doc, from, to) { 9493 var markers = null; 9494 doc.iter(from.line, to.line + 1, function(line) { 9495 if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { 9496 var mark = line.markedSpans[i].marker; 9497 if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) 9498 (markers || (markers = [])).push(mark); 9499 } 9500 }); 9501 if (!markers) return null; 9502 var parts = [{from: from, to: to}]; 9503 for (var i = 0; i < markers.length; ++i) { 9504 var mk = markers[i], m = mk.find(0); 9505 for (var j = 0; j < parts.length; ++j) { 9506 var p = parts[j]; 9507 if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue; 9508 var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); 9509 if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) 9510 newParts.push({from: p.from, to: m.from}); 9511 if (dto > 0 || !mk.inclusiveRight && !dto) 9512 newParts.push({from: m.to, to: p.to}); 9513 parts.splice.apply(parts, newParts); 9514 j += newParts.length - 1; 9515 } 9516 } 9517 return parts; 9518 } 9519 9520 // Connect or disconnect spans from a line. 9521 function detachMarkedSpans(line) { 9522 var spans = line.markedSpans; 9523 if (!spans) return; 9524 for (var i = 0; i < spans.length; ++i) 9525 spans[i].marker.detachLine(line); 9526 line.markedSpans = null; 9527 } 9528 function attachMarkedSpans(line, spans) { 9529 if (!spans) return; 9530 for (var i = 0; i < spans.length; ++i) 9531 spans[i].marker.attachLine(line); 9532 line.markedSpans = spans; 9533 } 9534 9535 // Helpers used when computing which overlapping collapsed span 9536 // counts as the larger one. 9537 function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; } 9538 function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; } 9539 9540 // Returns a number indicating which of two overlapping collapsed 9541 // spans is larger (and thus includes the other). Falls back to 9542 // comparing ids when the spans cover exactly the same range. 9543 function compareCollapsedMarkers(a, b) { 9544 var lenDiff = a.lines.length - b.lines.length; 9545 if (lenDiff != 0) return lenDiff; 9546 var aPos = a.find(), bPos = b.find(); 9547 var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); 9548 if (fromCmp) return -fromCmp; 9549 var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); 9550 if (toCmp) return toCmp; 9551 return b.id - a.id; 9552 } 9553 9554 // Find out whether a line ends or starts in a collapsed span. If 9555 // so, return the marker for that span. 9556 function collapsedSpanAtSide(line, start) { 9557 var sps = sawCollapsedSpans && line.markedSpans, found; 9558 if (sps) for (var sp, i = 0; i < sps.length; ++i) { 9559 sp = sps[i]; 9560 if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && 9561 (!found || compareCollapsedMarkers(found, sp.marker) < 0)) 9562 found = sp.marker; 9563 } 9564 return found; 9565 } 9566 function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); } 9567 function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); } 9568 9569 // Test whether there exists a collapsed span that partially 9570 // overlaps (covers the start or end, but not both) of a new span. 9571 // Such overlap is not allowed. 9572 function conflictingCollapsedRange(doc, lineNo, from, to, marker) { 9573 var line = getLine(doc, lineNo); 9574 var sps = sawCollapsedSpans && line.markedSpans; 9575 if (sps) for (var i = 0; i < sps.length; ++i) { 9576 var sp = sps[i]; 9577 if (!sp.marker.collapsed) continue; 9578 var found = sp.marker.find(0); 9579 var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); 9580 var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); 9581 if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue; 9582 if (fromCmp <= 0 && (
vendor: 4,962 bytes, lines 9582-9711
9582cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) || 9583 fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight))) 9584 return true; 9585 } 9586 } 9587 9588 // A visual line is a line as drawn on the screen. Folding, for 9589 // example, can cause multiple logical lines to appear on the same 9590 // visual line. This finds the start of the visual line that the 9591 // given line is part of (usually that is the line itself). 9592 function visualLine(line) { 9593 var merged; 9594 while (merged = collapsedSpanAtStart(line)) 9595 line = merged.find(-1, true).line; 9596 return line; 9597 } 9598 9599 // Returns an array of logical lines that continue the visual line 9600 // started by the argument, or undefined if there are no such lines. 9601 function visualLineContinued(line) { 9602 var merged, lines; 9603 while (merged = collapsedSpanAtEnd(line)) { 9604 line = merged.find(1, true).line; 9605 (lines || (lines = [])).push(line); 9606 } 9607 return lines; 9608 } 9609 9610 // Get the line number of the start of the visual line that the 9611 // given line number is part of. 9612 function visualLineNo(doc, lineN) { 9613 var line = getLine(doc, lineN), vis = visualLine(line); 9614 if (line == vis) return lineN; 9615 return lineNo(vis); 9616 } 9617 // Get the line number of the start of the next visual line after 9618 // the given line. 9619 function visualLineEndNo(doc, lineN) { 9620 if (lineN > doc.lastLine()) return lineN; 9621 var line = getLine(doc, lineN), merged; 9622 if (!lineIsHidden(doc, line)) return lineN; 9623 while (merged = collapsedSpanAtEnd(line)) 9624 line = merged.find(1, true).line; 9625 return lineNo(line) + 1; 9626 } 9627 9628 // Compute whether a line is hidden. Lines count as hidden when they 9629 // are part of a visual line that starts with another line, or when 9630 // they are entirely covered by collapsed, non-widget span. 9631 function lineIsHidden(doc, line) { 9632 var sps = sawCollapsedSpans && line.markedSpans; 9633 if (sps) for (var sp, i = 0; i < sps.length; ++i) { 9634 sp = sps[i]; 9635 if (!sp.marker.collapsed) continue; 9636 if (sp.from == null) return true; 9637 if (sp.marker.widgetNode) continue; 9638 if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) 9639 return true; 9640 } 9641 } 9642 function lineIsHiddenInner(doc, line, span) { 9643 if (span.to == null) { 9644 var end = span.marker.find(1, true); 9645 return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)); 9646 } 9647 if (span.marker.inclusiveRight && span.to == line.text.length) 9648 return true; 9649 for (var sp, i = 0; i < line.markedSpans.length; ++i) { 9650 sp = line.markedSpans[i]; 9651 if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && 9652 (sp.to == null || sp.to != span.from) && 9653 (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && 9654 lineIsHiddenInner(doc, line, sp)) return true; 9655 } 9656 } 9657 9658 // LINE WIDGETS 9659 9660 // Line widgets are block elements displayed above or below a line. 9661 9662 var LineWidget = CodeMirror.LineWidget = function(doc, node, options) { 9663 if (options) for (var opt in options) if (options.hasOwnProperty(opt)) 9664 this[opt] = options[opt]; 9665 this.doc = doc; 9666 this.node = node; 9667 }; 9668 eventMixin(LineWidget); 9669 9670 function adjustScrollWhenAboveVisible(cm, line, diff) { 9671 if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) 9672 addToScrollPos(cm, null, diff); 9673 } 9674 9675 LineWidget.prototype.clear = function() { 9676 var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); 9677 if (no == null || !ws) return; 9678 for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); 9679 if (!ws.length) line.widgets = null; 9680 var height = widgetHeight(this); 9681 updateLineHeight(line, Math.max(0, line.height - height)); 9682 if (cm) runInOp(cm, function() { 9683 adjustScrollWhenAboveVisible(cm, line, -height); 9684 regLineChange(cm, no, "widget"); 9685 }); 9686 }; 9687 LineWidget.prototype.changed = function() { 9688 var oldH = this.height, cm = this.doc.cm, line = this.line; 9689 this.height = null; 9690 var diff = widgetHeight(this) - oldH; 9691 if (!diff) return; 9692 updateLineHeight(line, line.height + diff); 9693 if (cm) runInOp(cm, function() { 9694 cm.curOp.forceUpdate = true; 9695 adjustScrollWhenAboveVisible(cm, line, diff); 9696 }); 9697 }; 9698 9699 function widgetHeight(widget) { 9700 if (widget.height != null) return widget.height; 9701 var cm = widget.doc.cm; 9702 if (!cm) return 0; 9703 if (!contains(document.body, widget.node)) { 9704 var parentStyle = "position: relative;"; 9705 if (widget.coverGutter) 9706 parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; 9707 if (widget.noHScroll) 9708 parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; 9709 removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle)); 9710 } 9711 return widget.height = widget.n
vendor: 9,482 bytes, lines 9711-9948
9711ode.offsetHeight; 9712 } 9713 9714 function addLineWidget(doc, handle, node, options) { 9715 var widget = new LineWidget(doc, node, options); 9716 var cm = doc.cm; 9717 if (cm && widget.noHScroll) cm.display.alignWidgets = true; 9718 changeLine(doc, handle, "widget", function(line) { 9719 var widgets = line.widgets || (line.widgets = []); 9720 if (widget.insertAt == null) widgets.push(widget); 9721 else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); 9722 widget.line = line; 9723 if (cm && !lineIsHidden(doc, line)) { 9724 var aboveVisible = heightAtLine(line) < doc.scrollTop; 9725 updateLineHeight(line, line.height + widgetHeight(widget)); 9726 if (aboveVisible) addToScrollPos(cm, null, widget.height); 9727 cm.curOp.forceUpdate = true; 9728 } 9729 return true; 9730 }); 9731 return widget; 9732 } 9733 9734 // LINE DATA STRUCTURE 9735 9736 // Line objects. These hold state related to a line, including 9737 // highlighting info (the styles array). 9738 var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) { 9739 this.text = text; 9740 attachMarkedSpans(this, markedSpans); 9741 this.height = estimateHeight ? estimateHeight(this) : 1; 9742 }; 9743 eventMixin(Line); 9744 Line.prototype.lineNo = function() { return lineNo(this); }; 9745 9746 // Change the content (text, markers) of a line. Automatically 9747 // invalidates cached information and tries to re-estimate the 9748 // line's height. 9749 function updateLine(line, text, markedSpans, estimateHeight) { 9750 line.text = text; 9751 if (line.stateAfter) line.stateAfter = null; 9752 if (line.styles) line.styles = null; 9753 if (line.order != null) line.order = null; 9754 detachMarkedSpans(line); 9755 attachMarkedSpans(line, markedSpans); 9756 var estHeight = estimateHeight ? estimateHeight(line) : 1; 9757 if (estHeight != line.height) updateLineHeight(line, estHeight); 9758 } 9759 9760 // Detach a line from the document tree and its markers. 9761 function cleanUpLine(line) { 9762 line.parent = null; 9763 detachMarkedSpans(line); 9764 } 9765 9766 function extractLineClasses(type, output) { 9767 if (type) for (;;) { 9768 var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); 9769 if (!lineClass) break; 9770 type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); 9771 var prop = lineClass[1] ? "bgClass" : "textClass"; 9772 if (output[prop] == null) 9773 output[prop] = lineClass[2]; 9774 else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) 9775 output[prop] += " " + lineClass[2]; 9776 } 9777 return type; 9778 } 9779 9780 function callBlankLine(mode, state) { 9781 if (mode.blankLine) return mode.blankLine(state); 9782 if (!mode.innerMode) return; 9783 var inner = CodeMirror.innerMode(mode, state); 9784 if (inner.mode.blankLine) return inner.mode.blankLine(inner.state); 9785 } 9786 9787 function readToken(mode, stream, state, inner) { 9788 for (var i = 0; i < 10; i++) { 9789 if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode; 9790 var style = mode.token(stream, state); 9791 if (stream.pos > stream.start) return style; 9792 } 9793 throw new Error("Mode " + mode.name + " failed to advance stream."); 9794 } 9795 9796 // Utility for getTokenAt and getLineTokens 9797 function takeToken(cm, pos, precise, asArray) { 9798 function getObj(copy) { 9799 return {start: stream.start, end: stream.pos, 9800 string: stream.current(), 9801 type: style || null, 9802 state: copy ? copyState(doc.mode, state) : state}; 9803 } 9804 9805 var doc = cm.doc, mode = doc.mode, style; 9806 pos = clipPos(doc, pos); 9807 var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise); 9808 var stream = new StringStream(line.text, cm.options.tabSize), tokens; 9809 if (asArray) tokens = []; 9810 while ((asArray || stream.pos < pos.ch) && !stream.eol()) { 9811 stream.start = stream.pos; 9812 style = readToken(mode, stream, state); 9813 if (asArray) tokens.push(getObj(true)); 9814 } 9815 return asArray ? tokens : getObj(); 9816 } 9817 9818 // Run the given mode's parser over a line, calling f for each token. 9819 function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) { 9820 var flattenSpans = mode.flattenSpans; 9821 if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; 9822 var curStart = 0, curStyle = null; 9823 var stream = new StringStream(text, cm.options.tabSize), style; 9824 var inner = cm.options.addModeClass && [null]; 9825 if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses); 9826 while (!stream.eol()) { 9827 if (stream.pos > cm.options.maxHighlightLength) { 9828 flattenSpans = false; 9829 if (forceToEnd) processLine(cm, text, state, stream.pos); 9830 stream.pos = text.length; 9831 style = null; 9832 } else { 9833 style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses); 9834 } 9835 if (inner) { 9836 var mName = inner[0].name; 9837 if (mName) style = "m-" + (style ? mName + " " + style : mName); 9838 } 9839 if (!flattenSpans || curStyle != style) { 9840 while (curStart < stream.start) { 9841 curStart = Math.min(stream.start, curStart + 50000); 9842 f(curStart, curStyle); 9843 } 9844 curStyle = style; 9845 } 9846 stream.start = stream.pos; 9847 } 9848 while (curStart < stream.pos) { 9849 // Webkit seems to refuse to render text nodes longer than 57444 characters 9850 var pos = Math.min(stream.pos, curStart + 50000); 9851 f(pos, curStyle); 9852 curStart = pos; 9853 } 9854 } 9855 9856 // Compute a style array (an array starting with a mode generation 9857 // -- for invalidation -- followed by pairs of end positions and 9858 // style strings), which is used to highlight the tokens on the 9859 // line. 9860 function highlightLine(cm, line, state, forceToEnd) { 9861 // A styles array always starts with a number identifying the 9862 // mode/overlays that it is based on (for easy invalidation). 9863 var st = [cm.state.modeGen], lineClasses = {}; 9864 // Compute the base array of styles 9865 runMode(cm, line.text, cm.doc.mode, state, function(end, style) { 9866 st.push(end, style); 9867 }, lineClasses, forceToEnd); 9868 9869 // Run overlays, adjust style array. 9870 for (var o = 0; o < cm.state.overlays.length; ++o) { 9871 var overlay = cm.state.overlays[o], i = 1, at = 0; 9872 runMode(cm, line.text, overlay.mode, true, function(end, style) { 9873 var start = i; 9874 // Ensure there's a token end at the current position, and that i points at it 9875 while (at < end) { 9876 var i_end = st[i]; 9877 if (i_end > end) 9878 st.splice(i, 1, end, st[i+1], i_end); 9879 i += 2; 9880 at = Math.min(end, i_end); 9881 } 9882 if (!style) return; 9883 if (overlay.opaque) { 9884 st.splice(start, i - start, end, "cm-overlay " + style); 9885 i = start + 2; 9886 } else { 9887 for (; start < i; start += 2) { 9888 var cur = st[start+1]; 9889 st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style; 9890 } 9891 } 9892 }, lineClasses); 9893 } 9894 9895 return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}; 9896 } 9897 9898 function getLineStyles(cm, line, updateFrontier) { 9899 if (!line.styles || line.styles[0] != cm.state.modeGen) { 9900 var state = getStateBefore(cm, lineNo(line)); 9901 var result = highlightLine(cm, line, line.text.length > cm.options.maxHighlightLength ? copyState(cm.doc.mode, state) : state); 9902 line.stateAfter = state; 9903 line.styles = result.styles; 9904 if (result.classes) line.styleClasses = result.classes; 9905 else if (line.styleClasses) line.styleClasses = null; 9906 if (updateFrontier === cm.doc.frontier) cm.doc.frontier++; 9907 } 9908 return line.styles; 9909 } 9910 9911 // Lightweight form of highlight -- proceed over this line and 9912 // update state, but don't save a style array. Used for lines that 9913 // aren't currently visible. 9914 function processLine(cm, text, state, startAt) { 9915 var mode = cm.doc.mode; 9916 var stream = new StringStream(text, cm.options.tabSize); 9917 stream.start = stream.pos = startAt || 0; 9918 if (text == "") callBlankLine(mode, state); 9919 while (!stream.eol()) { 9920 readToken(mode, stream, state); 9921 stream.start = stream.pos; 9922 } 9923 } 9924 9925 // Convert a style as returned by a mode (either null, or a string 9926 // containing one or more styles) to a CSS style. This is cached, 9927 // and also looks for line-wide styles. 9928 var styleToClassCache = {}, styleToClassCacheWithMode = {}; 9929 function interpretTokenStyle(style, options) { 9930 if (!style || /^\s*$/.test(style)) return null; 9931 var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; 9932 return cache[style] || 9933 (cache[style] = style.replace(/\S+/g, "cm-$&")); 9934 } 9935 9936 // Render the DOM representation of the text of a line. Also builds 9937 // up a 'line map', which points at the DOM nodes that represent 9938 // specific stretches of text, and is used by the measuring code. 9939 // The returned object contains the DOM node, this map, and 9940 // information about line-wide styles that were set by the mode. 9941 function buildLineContent(cm, lineView) { 9942 // The padding-right forces the element to have a 'border', which 9943 // is needed on Webkit to be able to get line-level bounding 9944 // rectangles for it (in measureChar). 9945 var content = elt("span", null, null, webkit ? "padding-right: .1px" : null); 9946 var builder = {pre: elt("pre", [content], "CodeMirror-line"), content: content, 9947 col: 0, pos: 0, cm: cm, 9948
vendor: 644 bytes, lines 9948-9960
9948splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")}; 9949 lineView.measure = {}; 9950 9951 // Iterate over the logical lines that make up this visual line. 9952 for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { 9953 var line = i ? lineView.rest[i - 1] : lineView.line, order; 9954 builder.pos = 0; 9955 builder.addToken = buildToken; 9956 // Optionally wire in some hacks into the token-rendering 9957 // algorithm, to deal with browser quirks. 9958 if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line))) 9959 builder.addToken = buildTokenBadBidi(builder.addToken, order); 9960 builder.map = [];
9961 var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line); 9962 insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate)); 9963 if (line.styleClasses) { 9964 if (line.styleClasses.bgClass) 9965 builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); 9966 if (line.styleClasses.textClass) 9967 builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); 9968 } 9969 9970 // Ensure at least a single node is present, for measuring. 9971 if (builder.map.length == 0) 9972 builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); 9973 9974 // Store the map and a cache object for the current logical line 9975 if (i == 0) { 9976 lineView.measure.map = builder.map; 9977 lineView.measure.cache = {}; 9978 } else { 9979 (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map); 9980 (lineView.measure.caches || (lineView.measure.caches = [])).push({}); 9981 } 9982 } 9983 9984 // See issue #2901 9985 if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className)) 9986 builder.content.className = "cm-tab-wrap-hack"; 9987 9988 signal(cm, "renderLine", cm, lineView.line, builder.pre); 9989 if (builder.pre.className)
vendor: 28,432 bytes, lines 9990-10679
9990 builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); 9991 9992 return builder; 9993 } 9994 9995 function defaultSpecialCharPlaceholder(ch) { 9996 var token = elt("span", "\u2022", "cm-invalidchar"); 9997 token.title = "\\u" + ch.charCodeAt(0).toString(16); 9998 token.setAttribute("aria-label", token.title); 9999 return token; 10000 } 10001 10002 // Build up the DOM representation for a single token, and add it to 10003 // the line map. Takes care to render special characters separately. 10004 function buildToken(builder, text, style, startStyle, endStyle, title, css) { 10005 if (!text) return; 10006 var displayText = builder.splitSpaces ? text.replace(/ {3,}/g, splitSpaces) : text; 10007 var special = builder.cm.state.specialChars, mustWrap = false; 10008 if (!special.test(text)) { 10009 builder.col += text.length; 10010 var content = document.createTextNode(displayText); 10011 builder.map.push(builder.pos, builder.pos + text.length, content); 10012 if (ie && ie_version < 9) mustWrap = true; 10013 builder.pos += text.length; 10014 } else { 10015 var content = document.createDocumentFragment(), pos = 0; 10016 while (true) { 10017 special.lastIndex = pos; 10018 var m = special.exec(text); 10019 var skipped = m ? m.index - pos : text.length - pos; 10020 if (skipped) { 10021 var txt = document.createTextNode(displayText.slice(pos, pos + skipped)); 10022 if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); 10023 else content.appendChild(txt); 10024 builder.map.push(builder.pos, builder.pos + skipped, txt); 10025 builder.col += skipped; 10026 builder.pos += skipped; 10027 } 10028 if (!m) break; 10029 pos += skipped + 1; 10030 if (m[0] == "\t") { 10031 var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; 10032 var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); 10033 txt.setAttribute("role", "presentation"); 10034 txt.setAttribute("cm-text", "\t"); 10035 builder.col += tabWidth; 10036 } else if (m[0] == "\r" || m[0] == "\n") { 10037 var txt = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar")); 10038 txt.setAttribute("cm-text", m[0]); 10039 builder.col += 1; 10040 } else { 10041 var txt = builder.cm.options.specialCharPlaceholder(m[0]); 10042 txt.setAttribute("cm-text", m[0]); 10043 if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); 10044 else content.appendChild(txt); 10045 builder.col += 1; 10046 } 10047 builder.map.push(builder.pos, builder.pos + 1, txt); 10048 builder.pos++; 10049 } 10050 } 10051 if (style || startStyle || endStyle || mustWrap || css) { 10052 var fullStyle = style || ""; 10053 if (startStyle) fullStyle += startStyle; 10054 if (endStyle) fullStyle += endStyle; 10055 var token = elt("span", [content], fullStyle, css); 10056 if (title) token.title = title; 10057 return builder.content.appendChild(token); 10058 } 10059 builder.content.appendChild(content); 10060 } 10061 10062 function splitSpaces(old) { 10063 var out = " "; 10064 for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0"; 10065 out += " "; 10066 return out; 10067 } 10068 10069 // Work around nonsense dimensions being reported for stretches of 10070 // right-to-left text. 10071 function buildTokenBadBidi(inner, order) { 10072 return function(builder, text, style, startStyle, endStyle, title, css) { 10073 style = style ? style + " cm-force-border" : "cm-force-border"; 10074 var start = builder.pos, end = start + text.length; 10075 for (;;) { 10076 // Find the part that overlaps with the start of this text 10077 for (var i = 0; i < order.length; i++) { 10078 var part = order[i]; 10079 if (part.to > start && part.from <= start) break; 10080 } 10081 if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title, css); 10082 inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css); 10083 startStyle = null; 10084 text = text.slice(part.to - start); 10085 start = part.to; 10086 } 10087 }; 10088 } 10089 10090 function buildCollapsedSpan(builder, size, marker, ignoreWidget) { 10091 var widget = !ignoreWidget && marker.widgetNode; 10092 if (widget) builder.map.push(builder.pos, builder.pos + size, widget); 10093 if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) { 10094 if (!widget) 10095 widget = builder.content.appendChild(document.createElement("span")); 10096 widget.setAttribute("cm-marker", marker.id); 10097 } 10098 if (widget) { 10099 builder.cm.display.input.setUneditable(widget); 10100 builder.content.appendChild(widget); 10101 } 10102 builder.pos += size; 10103 } 10104 10105 // Outputs a number of spans to make up a line, taking highlighting 10106 // and marked text into account. 10107 function insertLineContent(line, builder, styles) { 10108 var spans = line.markedSpans, allText = line.text, at = 0; 10109 if (!spans) { 10110 for (var i = 1; i < styles.length; i+=2) 10111 builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options)); 10112 return; 10113 } 10114 10115 var len = allText.length, pos = 0, i = 1, text = "", style, css; 10116 var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; 10117 for (;;) { 10118 if (nextChange == pos) { // Update current marker set 10119 spanStyle = spanEndStyle = spanStartStyle = title = css = ""; 10120 collapsed = null; nextChange = Infinity; 10121 var foundBookmarks = []; 10122 for (var j = 0; j < spans.length; ++j) { 10123 var sp = spans[j], m = sp.marker; 10124 if (m.type == "bookmark" && sp.from == pos && m.widgetNode) { 10125 foundBookmarks.push(m); 10126 } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) { 10127 if (sp.to != null && sp.to != pos && nextChange > sp.to) { 10128 nextChange = sp.to; 10129 spanEndStyle = ""; 10130 } 10131 if (m.className) spanStyle += " " + m.className; 10132 if (m.css) css = m.css; 10133 if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; 10134 if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle; 10135 if (m.title && !title) title = m.title; 10136 if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) 10137 collapsed = sp; 10138 } else if (sp.from > pos && nextChange > sp.from) { 10139 nextChange = sp.from; 10140 } 10141 } 10142 if (collapsed && (collapsed.from || 0) == pos) { 10143 buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, 10144 collapsed.marker, collapsed.from == null); 10145 if (collapsed.to == null) return; 10146 if (collapsed.to == pos) collapsed = false; 10147 } 10148 if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j) 10149 buildCollapsedSpan(builder, 0, foundBookmarks[j]); 10150 } 10151 if (pos >= len) break; 10152 10153 var upto = Math.min(len, nextChange); 10154 while (true) { 10155 if (text) { 10156 var end = pos + text.length; 10157 if (!collapsed) { 10158 var tokenText = end > upto ? text.slice(0, upto - pos) : text; 10159 builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, 10160 spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css); 10161 } 10162 if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} 10163 pos = end; 10164 spanStartStyle = ""; 10165 } 10166 text = allText.slice(at, at = styles[i++]); 10167 style = interpretTokenStyle(styles[i++], builder.cm.options); 10168 } 10169 } 10170 } 10171 10172 // DOCUMENT DATA STRUCTURE 10173 10174 // By default, updates that start and end at the beginning of a line 10175 // are treated specially, in order to make the association of line 10176 // widgets and marker elements with the text behave more intuitive. 10177 function isWholeLineUpdate(doc, change) { 10178 return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && 10179 (!doc.cm || doc.cm.options.wholeLineUpdateBefore); 10180 } 10181 10182 // Perform a change on the document data structure. 10183 function updateDoc(doc, change, markedSpans, estimateHeight) { 10184 function spansFor(n) {return markedSpans ? markedSpans[n] : null;} 10185 function update(line, text, spans) { 10186 updateLine(line, text, spans, estimateHeight); 10187 signalLater(line, "change", line, change); 10188 } 10189 function linesFor(start, end) { 10190 for (var i = start, result = []; i < end; ++i) 10191 result.push(new Line(text[i], spansFor(i), estimateHeight)); 10192 return result; 10193 } 10194 10195 var from = change.from, to = change.to, text = change.text; 10196 var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); 10197 var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; 10198 10199 // Adjust the line structure 10200 if (change.full) { 10201 doc.insert(0, linesFor(0, text.length)); 10202 doc.remove(text.length, doc.size - text.length); 10203 } else if (isWholeLineUpdate(doc, change)) { 10204 // This is a whole-line replace. Treated specially to make 10205 // sure line objects move the way they are supposed to. 10206 var added = linesFor(0, text.length - 1); 10207 update(lastLine, lastLine.text, lastSpans); 10208 if (nlines) doc.remove(from.line, nlines); 10209 if (added.length) doc.insert(from.line, added); 10210 } else if (firstLine == lastLine) { 10211 if (text.length == 1) { 10212 update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); 10213 } else { 10214 var added = linesFor(1, text.length - 1); 10215 added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); 10216 update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); 10217 doc.insert(from.line + 1, added); 10218 } 10219 } else if (text.length == 1) { 10220 update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); 10221 doc.remove(from.line + 1, nlines); 10222 } else { 10223 update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); 10224 update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); 10225 var added = linesFor(1, text.length - 1); 10226 if (nlines > 1) doc.remove(from.line + 1, nlines - 1); 10227 doc.insert(from.line + 1, added); 10228 } 10229 10230 signalLater(doc, "change", doc, change); 10231 } 10232 10233 // The document is represented as a BTree consisting of leaves, with 10234 // chunk of lines in them, and branches, with up to ten leaves or 10235 // other branch nodes below them. The top node is always a branch 10236 // node, and is the document object itself (meaning it has 10237 // additional methods and properties). 10238 // 10239 // All nodes have parent links. The tree is used both to go from 10240 // line numbers to line objects, and to go from objects to numbers. 10241 // It also indexes by height, and is used to convert between height 10242 // and line object, and to find the total height of the document. 10243 // 10244 // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html 10245 10246 function LeafChunk(lines) { 10247 this.lines = lines; 10248 this.parent = null; 10249 for (var i = 0, height = 0; i < lines.length; ++i) { 10250 lines[i].parent = this; 10251 height += lines[i].height; 10252 } 10253 this.height = height; 10254 } 10255 10256 LeafChunk.prototype = { 10257 chunkSize: function() { return this.lines.length; }, 10258 // Remove the n lines at offset 'at'. 10259 removeInner: function(at, n) { 10260 for (var i = at, e = at + n; i < e; ++i) { 10261 var line = this.lines[i]; 10262 this.height -= line.height; 10263 cleanUpLine(line); 10264 signalLater(line, "delete"); 10265 } 10266 this.lines.splice(at, n); 10267 }, 10268 // Helper used to collapse a small branch into a single leaf. 10269 collapse: function(lines) { 10270 lines.push.apply(lines, this.lines); 10271 }, 10272 // Insert the given array of lines at offset 'at', count them as 10273 // having the given height. 10274 insertInner: function(at, lines, height) { 10275 this.height += height; 10276 this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); 10277 for (var i = 0; i < lines.length; ++i) lines[i].parent = this; 10278 }, 10279 // Used to iterate over a part of the tree. 10280 iterN: function(at, n, op) { 10281 for (var e = at + n; at < e; ++at) 10282 if (op(this.lines[at])) return true; 10283 } 10284 }; 10285 10286 function BranchChunk(children) { 10287 this.children = children; 10288 var size = 0, height = 0; 10289 for (var i = 0; i < children.length; ++i) { 10290 var ch = children[i]; 10291 size += ch.chunkSize(); height += ch.height; 10292 ch.parent = this; 10293 } 10294 this.size = size; 10295 this.height = height; 10296 this.parent = null; 10297 } 10298 10299 BranchChunk.prototype = { 10300 chunkSize: function() { return this.size; }, 10301 removeInner: function(at, n) { 10302 this.size -= n; 10303 for (var i = 0; i < this.children.length; ++i) { 10304 var child = this.children[i], sz = child.chunkSize(); 10305 if (at < sz) { 10306 var rm = Math.min(n, sz - at), oldHeight = child.height; 10307 child.removeInner(at, rm); 10308 this.height -= oldHeight - child.height; 10309 if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } 10310 if ((n -= rm) == 0) break; 10311 at = 0; 10312 } else at -= sz; 10313 } 10314 // If the result is smaller than 25 lines, ensure that it is a 10315 // single leaf node. 10316 if (this.size - n < 25 && 10317 (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { 10318 var lines = []; 10319 this.collapse(lines); 10320 this.children = [new LeafChunk(lines)]; 10321 this.children[0].parent = this; 10322 } 10323 }, 10324 collapse: function(lines) { 10325 for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines); 10326 }, 10327 insertInner: function(at, lines, height) { 10328 this.size += lines.length; 10329 this.height += height; 10330 for (var i = 0; i < this.children.length; ++i) { 10331 var child = this.children[i], sz = child.chunkSize(); 10332 if (at <= sz) { 10333 child.insertInner(at, lines, height); 10334 if (child.lines && child.lines.length > 50) { 10335 while (child.lines.length > 50) { 10336 var spilled = child.lines.splice(child.lines.length - 25, 25); 10337 var newleaf = new LeafChunk(spilled); 10338 child.height -= newleaf.height; 10339 this.children.splice(i + 1, 0, newleaf); 10340 newleaf.parent = this; 10341 } 10342 this.maybeSpill(); 10343 } 10344 break; 10345 } 10346 at -= sz; 10347 } 10348 }, 10349 // When a node has grown, check whether it should be split. 10350 maybeSpill: function() { 10351 if (this.children.length <= 10) return; 10352 var me = this; 10353 do { 10354 var spilled = me.children.splice(me.children.length - 5, 5); 10355 var sibling = new BranchChunk(spilled); 10356 if (!me.parent) { // Become the parent node 10357 var copy = new BranchChunk(me.children); 10358 copy.parent = me; 10359 me.children = [copy, sibling]; 10360 me = copy; 10361 } else { 10362 me.size -= sibling.size; 10363 me.height -= sibling.height; 10364 var myIndex = indexOf(me.parent.children, me); 10365 me.parent.children.splice(myIndex + 1, 0, sibling); 10366 } 10367 sibling.parent = me.parent; 10368 } while (me.children.length > 10); 10369 me.parent.maybeSpill(); 10370 }, 10371 iterN: function(at, n, op) { 10372 for (var i = 0; i < this.children.length; ++i) { 10373 var child = this.children[i], sz = child.chunkSize(); 10374 if (at < sz) { 10375 var used = Math.min(n, sz - at); 10376 if (child.iterN(at, used, op)) return true; 10377 if ((n -= used) == 0) break; 10378 at = 0; 10379 } else at -= sz; 10380 } 10381 } 10382 }; 10383 10384 var nextDocId = 0; 10385 var Doc = CodeMirror.Doc = function(text, mode, firstLine, lineSep) { 10386 if (!(this instanceof Doc)) return new Doc(text, mode, firstLine, lineSep); 10387 if (firstLine == null) firstLine = 0; 10388 10389 BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); 10390 this.first = firstLine; 10391 this.scrollTop = this.scrollLeft = 0; 10392 this.cantEdit = false; 10393 this.cleanGeneration = 1; 10394 this.frontier = firstLine; 10395 var start = Pos(firstLine, 0); 10396 this.sel = simpleSelection(start); 10397 this.history = new History(null); 10398 this.id = ++nextDocId; 10399 this.modeOption = mode; 10400 this.lineSep = lineSep; 10401 10402 if (typeof text == "string") text = this.splitLines(text); 10403 updateDoc(this, {from: start, to: start, text: text}); 10404 setSelection(this, simpleSelection(start), sel_dontScroll); 10405 }; 10406 10407 Doc.prototype = createObj(BranchChunk.prototype, { 10408 constructor: Doc, 10409 // Iterate over the document. Supports two forms -- with only one 10410 // argument, it calls that for each line in the document. With 10411 // three, it iterates over the range given by the first two (with 10412 // the second being non-inclusive). 10413 iter: function(from, to, op) { 10414 if (op) this.iterN(from - this.first, to - from, op); 10415 else this.iterN(this.first, this.first + this.size, from); 10416 }, 10417 10418 // Non-public interface for adding and removing lines. 10419 insert: function(at, lines) { 10420 var height = 0; 10421 for (var i = 0; i < lines.length; ++i) height += lines[i].height; 10422 this.insertInner(at - this.first, lines, height); 10423 }, 10424 remove: function(at, n) { this.removeInner(at - this.first, n); }, 10425 10426 // From here, the methods are part of the public interface. Most 10427 // are also available from CodeMirror (editor) instances. 10428 10429 getValue: function(lineSep) { 10430 var lines = getLines(this, this.first, this.first + this.size); 10431 if (lineSep === false) return lines; 10432 return lines.join(lineSep || this.lineSeparator()); 10433 }, 10434 setValue: docMethodOp(function(code) { 10435 var top = Pos(this.first, 0), last = this.first + this.size - 1; 10436 makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), 10437 text: this.splitLines(code), origin: "setValue", full: true}, true); 10438 setSelection(this, simpleSelection(top)); 10439 }), 10440 replaceRange: function(code, from, to, origin) { 10441 from = clipPos(this, from); 10442 to = to ? clipPos(this, to) : from; 10443 replaceRange(this, code, from, to, origin); 10444 }, 10445 getRange: function(from, to, lineSep) { 10446 var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); 10447 if (lineSep === false) return lines; 10448 return lines.join(lineSep || this.lineSeparator()); 10449 }, 10450 10451 getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;}, 10452 10453 getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);}, 10454 getLineNumber: function(line) {return lineNo(line);}, 10455 10456 getLineHandleVisualStart: function(line) { 10457 if (typeof line == "number") line = getLine(this, line); 10458 return visualLine(line); 10459 }, 10460 10461 lineCount: function() {return this.size;}, 10462 firstLine: function() {return this.first;}, 10463 lastLine: function() {return this.first + this.size - 1;}, 10464 10465 clipPos: function(pos) {return clipPos(this, pos);}, 10466 10467 getCursor: function(start) { 10468 var range = this.sel.primary(), pos; 10469 if (start == null || start == "head") pos = range.head; 10470 else if (start == "anchor") pos = range.anchor; 10471 else if (start == "end" || start == "to" || start === false) pos = range.to(); 10472 else pos = range.from(); 10473 return pos; 10474 }, 10475 listSelections: function() { return this.sel.ranges; }, 10476 somethingSelected: function() {return this.sel.somethingSelected();}, 10477 10478 setCursor: docMethodOp(function(line, ch, options) { 10479 setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); 10480 }), 10481 setSelection: docMethodOp(function(anchor, head, options) { 10482 setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); 10483 }), 10484 extendSelection: docMethodOp(function(head, other, options) { 10485 extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); 10486 }), 10487 extendSelections: docMethodOp(function(heads, options) { 10488 extendSelections(this, clipPosArray(this, heads, options)); 10489 }), 10490 extendSelectionsBy: docMethodOp(function(f, options) { 10491 extendSelections(this, map(this.sel.ranges, f), options); 10492 }), 10493 setSelections: docMethodOp(function(ranges, primary, options) { 10494 if (!ranges.length) return; 10495 for (var i = 0, out = []; i < ranges.length; i++) 10496 out[i] = new Range(clipPos(this, ranges[i].anchor), 10497 clipPos(this, ranges[i].head)); 10498 if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex); 10499 setSelection(this, normalizeSelection(out, primary), options); 10500 }), 10501 addSelection: docMethodOp(function(anchor, head, options) { 10502 var ranges = this.sel.ranges.slice(0); 10503 ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); 10504 setSelection(this, normalizeSelection(ranges, ranges.length - 1), options); 10505 }), 10506 10507 getSelection: function(lineSep) { 10508 var ranges = this.sel.ranges, lines; 10509 for (var i = 0; i < ranges.length; i++) { 10510 var sel = getBetween(this, ranges[i].from(), ranges[i].to()); 10511 lines = lines ? lines.concat(sel) : sel; 10512 } 10513 if (lineSep === false) return lines; 10514 else return lines.join(lineSep || this.lineSeparator()); 10515 }, 10516 getSelections: function(lineSep) { 10517 var parts = [], ranges = this.sel.ranges; 10518 for (var i = 0; i < ranges.length; i++) { 10519 var sel = getBetween(this, ranges[i].from(), ranges[i].to()); 10520 if (lineSep !== false) sel = sel.join(lineSep || this.lineSeparator()); 10521 parts[i] = sel; 10522 } 10523 return parts; 10524 }, 10525 replaceSelection: function(code, collapse, origin) { 10526 var dup = []; 10527 for (var i = 0; i < this.sel.ranges.length; i++) 10528 dup[i] = code; 10529 this.replaceSelections(dup, collapse, origin || "+input"); 10530 }, 10531 replaceSelections: docMethodOp(function(code, collapse, origin) { 10532 var changes = [], sel = this.sel; 10533 for (var i = 0; i < sel.ranges.length; i++) { 10534 var range = sel.ranges[i]; 10535 changes[i] = {from: range.from(), to: range.to(), text: this.splitLines(code[i]), origin: origin}; 10536 } 10537 var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); 10538 for (var i = changes.length - 1; i >= 0; i--) 10539 makeChange(this, changes[i]); 10540 if (newSel) setSelectionReplaceHistory(this, newSel); 10541 else if (this.cm) ensureCursorVisible(this.cm); 10542 }), 10543 undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}), 10544 redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}), 10545 undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}), 10546 redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}), 10547 10548 setExtending: function(val) {this.extend = val;}, 10549 getExtending: function() {return this.extend;}, 10550 10551 historySize: function() { 10552 var hist = this.history, done = 0, undone = 0; 10553 for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done; 10554 for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone; 10555 return {undo: done, redo: undone}; 10556 }, 10557 clearHistory: function() {this.history = new History(this.history.maxGeneration);}, 10558 10559 markClean: function() { 10560 this.cleanGeneration = this.changeGeneration(true); 10561 }, 10562 changeGeneration: function(forceSplit) { 10563 if (forceSplit) 10564 this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; 10565 return this.history.generation; 10566 }, 10567 isClean: function (gen) { 10568 return this.history.generation == (gen || this.cleanGeneration); 10569 }, 10570 10571 getHistory: function() { 10572 return {done: copyHistoryArray(this.history.done), 10573 undone: copyHistoryArray(this.history.undone)}; 10574 }, 10575 setHistory: function(histData) { 10576 var hist = this.history = new History(this.history.maxGeneration); 10577 hist.done = copyHistoryArray(histData.done.slice(0), null, true); 10578 hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); 10579 }, 10580 10581 addLineClass: docMethodOp(function(handle, where, cls) { 10582 return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) { 10583 var prop = where == "text" ? "textClass" 10584 : where == "background" ? "bgClass" 10585 : where == "gutter" ? "gutterClass" : "wrapClass"; 10586 if (!line[prop]) line[prop] = cls; 10587 else if (classTest(cls).test(line[prop])) return false; 10588 else line[prop] += " " + cls; 10589 return true; 10590 }); 10591 }), 10592 removeLineClass: docMethodOp(function(handle, where, cls) { 10593 return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) { 10594 var prop = where == "text" ? "textClass" 10595 : where == "background" ? "bgClass" 10596 : where == "gutter" ? "gutterClass" : "wrapClass"; 10597 var cur = line[prop]; 10598 if (!cur) return false; 10599 else if (cls == null) line[prop] = null; 10600 else { 10601 var found = cur.match(classTest(cls)); 10602 if (!found) return false; 10603 var end = found.index + found[0].length; 10604 line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; 10605 } 10606 return true; 10607 }); 10608 }), 10609 10610 addLineWidget: docMethodOp(function(handle, node, options) { 10611 return addLineWidget(this, handle, node, options); 10612 }), 10613 removeLineWidget: function(widget) { widget.clear(); }, 10614 10615 markText: function(from, to, options) { 10616 return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range"); 10617 }, 10618 setBookmark: function(pos, options) { 10619 var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), 10620 insertLeft: options && options.insertLeft, 10621 clearWhenEmpty: false, shared: options && options.shared, 10622 handleMouseEvents: options && options.handleMouseEvents}; 10623 pos = clipPos(this, pos); 10624 return markText(this, pos, pos, realOpts, "bookmark"); 10625 }, 10626 findMarksAt: function(pos) { 10627 pos = clipPos(this, pos); 10628 var markers = [], spans = getLine(this, pos.line).markedSpans; 10629 if (spans) for (var i = 0; i < spans.length; ++i) { 10630 var span = spans[i]; 10631 if ((span.from == null || span.from <= pos.ch) && 10632 (span.to == null || span.to >= pos.ch)) 10633 markers.push(span.marker.parent || span.marker); 10634 } 10635 return markers; 10636 }, 10637 findMarks: function(from, to, filter) { 10638 from = clipPos(this, from); to = clipPos(this, to); 10639 var found = [], lineNo = from.line; 10640 this.iter(from.line, to.line + 1, function(line) { 10641 var spans = line.markedSpans; 10642 if (spans) for (var i = 0; i < spans.length; i++) { 10643 var span = spans[i]; 10644 if (!(lineNo == from.line && from.ch > span.to || 10645 span.from == null && lineNo != from.line|| 10646 lineNo == to.line && span.from > to.ch) && 10647 (!filter || filter(span.marker))) 10648 found.push(span.marker.parent || span.marker); 10649 } 10650 ++lineNo; 10651 }); 10652 return found; 10653 }, 10654 getAllMarks: function() { 10655 var markers = []; 10656 this.iter(function(line) { 10657 var sps = line.markedSpans; 10658 if (sps) for (var i = 0; i < sps.length; ++i) 10659 if (sps[i].from != null) markers.push(sps[i].marker); 10660 }); 10661 return markers; 10662 }, 10663 10664 posFromIndex: function(off) { 10665 var ch, lineNo = this.first; 10666 this.iter(function(line) { 10667 var sz = line.text.length + 1; 10668 if (sz > off) { ch = off; return true; } 10669 off -= sz; 10670 ++lineNo; 10671 }); 10672 return clipPos(this, Pos(lineNo, ch)); 10673 }, 10674 indexFromPos: function (coords) { 10675 coords = clipPos(this, coords); 10676 var index = coords.ch; 10677 if (coords.line < this.first || coords.ch < 0) return 0; 10678 this.iter(this.first, coords.line, function (line) { 10679 index += line.text.length + 1
vendor: 32,457 bytes, lines 10679-11541
10679; 10680 }); 10681 return index; 10682 }, 10683 10684 copy: function(copyHistory) { 10685 var doc = new Doc(getLines(this, this.first, this.first + this.size), 10686 this.modeOption, this.first, this.lineSep); 10687 doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; 10688 doc.sel = this.sel; 10689 doc.extend = false; 10690 if (copyHistory) { 10691 doc.history.undoDepth = this.history.undoDepth; 10692 doc.setHistory(this.getHistory()); 10693 } 10694 return doc; 10695 }, 10696 10697 linkedDoc: function(options) { 10698 if (!options) options = {}; 10699 var from = this.first, to = this.first + this.size; 10700 if (options.from != null && options.from > from) from = options.from; 10701 if (options.to != null && options.to < to) to = options.to; 10702 var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep); 10703 if (options.sharedHist) copy.history = this.history; 10704 (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}); 10705 copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]; 10706 copySharedMarkers(copy, findSharedMarkers(this)); 10707 return copy; 10708 }, 10709 unlinkDoc: function(other) { 10710 if (other instanceof CodeMirror) other = other.doc; 10711 if (this.linked) for (var i = 0; i < this.linked.length; ++i) { 10712 var link = this.linked[i]; 10713 if (link.doc != other) continue; 10714 this.linked.splice(i, 1); 10715 other.unlinkDoc(this); 10716 detachSharedMarkers(findSharedMarkers(this)); 10717 break; 10718 } 10719 // If the histories were shared, split them again 10720 if (other.history == this.history) { 10721 var splitIds = [other.id]; 10722 linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true); 10723 other.history = new History(null); 10724 other.history.done = copyHistoryArray(this.history.done, splitIds); 10725 other.history.undone = copyHistoryArray(this.history.undone, splitIds); 10726 } 10727 }, 10728 iterLinkedDocs: function(f) {linkedDocs(this, f);}, 10729 10730 getMode: function() {return this.mode;}, 10731 getEditor: function() {return this.cm;}, 10732 10733 splitLines: function(str) { 10734 if (this.lineSep) return str.split(this.lineSep); 10735 return splitLinesAuto(str); 10736 }, 10737 lineSeparator: function() { return this.lineSep || "\n"; } 10738 }); 10739 10740 // Public alias. 10741 Doc.prototype.eachLine = Doc.prototype.iter; 10742 10743 // Set up methods on CodeMirror's prototype to redirect to the editor's document. 10744 var dontDelegate = "iter insert remove copy getEditor constructor".split(" "); 10745 for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) 10746 CodeMirror.prototype[prop] = (function(method) { 10747 return function() {return method.apply(this.doc, arguments);}; 10748 })(Doc.prototype[prop]); 10749 10750 eventMixin(Doc); 10751 10752 // Call f for all linked documents. 10753 function linkedDocs(doc, f, sharedHistOnly) { 10754 function propagate(doc, skip, sharedHist) { 10755 if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { 10756 var rel = doc.linked[i]; 10757 if (rel.doc == skip) continue; 10758 var shared = sharedHist && rel.sharedHist; 10759 if (sharedHistOnly && !shared) continue; 10760 f(rel.doc, shared); 10761 propagate(rel.doc, doc, shared); 10762 } 10763 } 10764 propagate(doc, null, true); 10765 } 10766 10767 // Attach a document to an editor. 10768 function attachDoc(cm, doc) { 10769 if (doc.cm) throw new Error("This document is already in use."); 10770 cm.doc = doc; 10771 doc.cm = cm; 10772 estimateLineHeights(cm); 10773 loadMode(cm); 10774 if (!cm.options.lineWrapping) findMaxLine(cm); 10775 cm.options.mode = doc.modeOption; 10776 regChange(cm); 10777 } 10778 10779 // LINE UTILITIES 10780 10781 // Find the line object corresponding to the given line number. 10782 function getLine(doc, n) { 10783 n -= doc.first; 10784 if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document."); 10785 for (var chunk = doc; !chunk.lines;) { 10786 for (var i = 0;; ++i) { 10787 var child = chunk.children[i], sz = child.chunkSize(); 10788 if (n < sz) { chunk = child; break; } 10789 n -= sz; 10790 } 10791 } 10792 return chunk.lines[n]; 10793 } 10794 10795 // Get the part of a document between two positions, as an array of 10796 // strings. 10797 function getBetween(doc, start, end) { 10798 var out = [], n = start.line; 10799 doc.iter(start.line, end.line + 1, function(line) { 10800 var text = line.text; 10801 if (n == end.line) text = text.slice(0, end.ch); 10802 if (n == start.line) text = text.slice(start.ch); 10803 out.push(text); 10804 ++n; 10805 }); 10806 return out; 10807 } 10808 // Get the lines between from and to, as array of strings. 10809 function getLines(doc, from, to) { 10810 var out = []; 10811 doc.iter(from, to, function(line) { out.push(line.text); }); 10812 return out; 10813 } 10814 10815 // Update the height of a line, propagating the height change 10816 // upwards to parent nodes. 10817 function updateLineHeight(line, height) { 10818 var diff = height - line.height; 10819 if (diff) for (var n = line; n; n = n.parent) n.height += diff; 10820 } 10821 10822 // Given a line object, find its line number by walking up through 10823 // its parent links. 10824 function lineNo(line) { 10825 if (line.parent == null) return null; 10826 var cur = line.parent, no = indexOf(cur.lines, line); 10827 for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { 10828 for (var i = 0;; ++i) { 10829 if (chunk.children[i] == cur) break; 10830 no += chunk.children[i].chunkSize(); 10831 } 10832 } 10833 return no + cur.first; 10834 } 10835 10836 // Find the line at the given vertical position, using the height 10837 // information in the document tree. 10838 function lineAtHeight(chunk, h) { 10839 var n = chunk.first; 10840 outer: do { 10841 for (var i = 0; i < chunk.children.length; ++i) { 10842 var child = chunk.children[i], ch = child.height; 10843 if (h < ch) { chunk = child; continue outer; } 10844 h -= ch; 10845 n += child.chunkSize(); 10846 } 10847 return n; 10848 } while (!chunk.lines); 10849 for (var i = 0; i < chunk.lines.length; ++i) { 10850 var line = chunk.lines[i], lh = line.height; 10851 if (h < lh) break; 10852 h -= lh; 10853 } 10854 return n + i; 10855 } 10856 10857 10858 // Find the height above the given line. 10859 function heightAtLine(lineObj) { 10860 lineObj = visualLine(lineObj); 10861 10862 var h = 0, chunk = lineObj.parent; 10863 for (var i = 0; i < chunk.lines.length; ++i) { 10864 var line = chunk.lines[i]; 10865 if (line == lineObj) break; 10866 else h += line.height; 10867 } 10868 for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { 10869 for (var i = 0; i < p.children.length; ++i) { 10870 var cur = p.children[i]; 10871 if (cur == chunk) break; 10872 else h += cur.height; 10873 } 10874 } 10875 return h; 10876 } 10877 10878 // Get the bidi ordering for the given line (and cache it). Returns 10879 // false for lines that are fully left-to-right, and an array of 10880 // BidiSpan objects otherwise. 10881 function getOrder(line) { 10882 var order = line.order; 10883 if (order == null) order = line.order = bidiOrdering(line.text); 10884 return order; 10885 } 10886 10887 // HISTORY 10888 10889 function History(startGen) { 10890 // Arrays of change events and selections. Doing something adds an 10891 // event to done and clears undo. Undoing moves events from done 10892 // to undone, redoing moves them in the other direction. 10893 this.done = []; this.undone = []; 10894 this.undoDepth = Infinity; 10895 // Used to track when changes can be merged into a single undo 10896 // event 10897 this.lastModTime = this.lastSelTime = 0; 10898 this.lastOp = this.lastSelOp = null; 10899 this.lastOrigin = this.lastSelOrigin = null; 10900 // Used by the isClean() method 10901 this.generation = this.maxGeneration = startGen || 1; 10902 } 10903 10904 // Create a history change event from an updateDoc-style change 10905 // object. 10906 function historyChangeFromChange(doc, change) { 10907 var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)}; 10908 attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); 10909 linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true); 10910 return histChange; 10911 } 10912 10913 // Pop all selection events off the end of a history array. Stop at 10914 // a change event. 10915 function clearSelectionEvents(array) { 10916 while (array.length) { 10917 var last = lst(array); 10918 if (last.ranges) array.pop(); 10919 else break; 10920 } 10921 } 10922 10923 // Find the top change event in the history. Pop off selection 10924 // events that are in the way. 10925 function lastChangeEvent(hist, force) { 10926 if (force) { 10927 clearSelectionEvents(hist.done); 10928 return lst(hist.done); 10929 } else if (hist.done.length && !lst(hist.done).ranges) { 10930 return lst(hist.done); 10931 } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { 10932 hist.done.pop(); 10933 return lst(hist.done); 10934 } 10935 } 10936 10937 // Register a change in the history. Merges changes that are within 10938 // a single operation, ore are close together with an origin that 10939 // allows merging (starting with "+") into a single event. 10940 function addChangeToHistory(doc, change, selAfter, opId) { 10941 var hist = doc.history; 10942 hist.undone.length = 0; 10943 var time = +new Date, cur; 10944 10945 if ((hist.lastOp == opId || 10946 hist.lastOrigin == change.origin && change.origin && 10947 ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || 10948 change.origin.charAt(0) == "*")) && 10949 (cur = lastChangeEvent(hist, hist.lastOp == opId))) { 10950 // Merge this change into the last event 10951 var last = lst(cur.changes); 10952 if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { 10953 // Optimized case for simple insertion -- don't want to add 10954 // new changesets for every character typed 10955 last.to = changeEnd(change); 10956 } else { 10957 // Add new sub-event 10958 cur.changes.push(historyChangeFromChange(doc, change)); 10959 } 10960 } else { 10961 // Can not be merged, start a new event. 10962 var before = lst(hist.done); 10963 if (!before || !before.ranges) 10964 pushSelectionToHistory(doc.sel, hist.done); 10965 cur = {changes: [historyChangeFromChange(doc, change)], 10966 generation: hist.generation}; 10967 hist.done.push(cur); 10968 while (hist.done.length > hist.undoDepth) { 10969 hist.done.shift(); 10970 if (!hist.done[0].ranges) hist.done.shift(); 10971 } 10972 } 10973 hist.done.push(selAfter); 10974 hist.generation = ++hist.maxGeneration; 10975 hist.lastModTime = hist.lastSelTime = time; 10976 hist.lastOp = hist.lastSelOp = opId; 10977 hist.lastOrigin = hist.lastSelOrigin = change.origin; 10978 10979 if (!last) signal(doc, "historyAdded"); 10980 } 10981 10982 function selectionEventCanBeMerged(doc, origin, prev, sel) { 10983 var ch = origin.charAt(0); 10984 return ch == "*" || 10985 ch == "+" && 10986 prev.ranges.length == sel.ranges.length && 10987 prev.somethingSelected() == sel.somethingSelected() && 10988 new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500); 10989 } 10990 10991 // Called whenever the selection changes, sets the new selection as 10992 // the pending selection in the history, and pushes the old pending 10993 // selection into the 'done' array when it was significantly 10994 // different (in number of selected ranges, emptiness, or time). 10995 function addSelectionToHistory(doc, sel, opId, options) { 10996 var hist = doc.history, origin = options && options.origin; 10997 10998 // A new event is started when the previous origin does not match 10999 // the current, or the origins don't allow matching. Origins 11000 // starting with * are always merged, those starting with + are 11001 // merged when similar and close together in time. 11002 if (opId == hist.lastSelOp || 11003 (origin && hist.lastSelOrigin == origin && 11004 (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || 11005 selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) 11006 hist.done[hist.done.length - 1] = sel; 11007 else 11008 pushSelectionToHistory(sel, hist.done); 11009 11010 hist.lastSelTime = +new Date; 11011 hist.lastSelOrigin = origin; 11012 hist.lastSelOp = opId; 11013 if (options && options.clearRedo !== false) 11014 clearSelectionEvents(hist.undone); 11015 } 11016 11017 function pushSelectionToHistory(sel, dest) { 11018 var top = lst(dest); 11019 if (!(top && top.ranges && top.equals(sel))) 11020 dest.push(sel); 11021 } 11022 11023 // Used to store marked span information in the history. 11024 function attachLocalSpans(doc, change, from, to) { 11025 var existing = change["spans_" + doc.id], n = 0; 11026 doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) { 11027 if (line.markedSpans) 11028 (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; 11029 ++n; 11030 }); 11031 } 11032 11033 // When un/re-doing restores text containing marked spans, those 11034 // that have been explicitly cleared should not be restored. 11035 function removeClearedSpans(spans) { 11036 if (!spans) return null; 11037 for (var i = 0, out; i < spans.length; ++i) { 11038 if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } 11039 else if (out) out.push(spans[i]); 11040 } 11041 return !out ? spans : out.length ? out : null; 11042 } 11043 11044 // Retrieve and filter the old marked spans stored in a change event. 11045 function getOldSpans(doc, change) { 11046 var found = change["spans_" + doc.id]; 11047 if (!found) return null; 11048 for (var i = 0, nw = []; i < change.text.length; ++i) 11049 nw.push(removeClearedSpans(found[i])); 11050 return nw; 11051 } 11052 11053 // Used both to provide a JSON-safe object in .getHistory, and, when 11054 // detaching a document, to split the history in two 11055 function copyHistoryArray(events, newGroup, instantiateSel) { 11056 for (var i = 0, copy = []; i < events.length; ++i) { 11057 var event = events[i]; 11058 if (event.ranges) { 11059 copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); 11060 continue; 11061 } 11062 var changes = event.changes, newChanges = []; 11063 copy.push({changes: newChanges}); 11064 for (var j = 0; j < changes.length; ++j) { 11065 var change = changes[j], m; 11066 newChanges.push({from: change.from, to: change.to, text: change.text}); 11067 if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { 11068 if (indexOf(newGroup, Number(m[1])) > -1) { 11069 lst(newChanges)[prop] = change[prop]; 11070 delete change[prop]; 11071 } 11072 } 11073 } 11074 } 11075 return copy; 11076 } 11077 11078 // Rebasing/resetting history to deal with externally-sourced changes 11079 11080 function rebaseHistSelSingle(pos, from, to, diff) { 11081 if (to < pos.line) { 11082 pos.line += diff; 11083 } else if (from < pos.line) { 11084 pos.line = from; 11085 pos.ch = 0; 11086 } 11087 } 11088 11089 // Tries to rebase an array of history events given a change in the 11090 // document. If the change touches the same lines as the event, the 11091 // event, and everything 'behind' it, is discarded. If the change is 11092 // before the event, the event's positions are updated. Uses a 11093 // copy-on-write scheme for the positions, to avoid having to 11094 // reallocate them all on every rebase, but also avoid problems with 11095 // shared position objects being unsafely updated. 11096 function rebaseHistArray(array, from, to, diff) { 11097 for (var i = 0; i < array.length; ++i) { 11098 var sub = array[i], ok = true; 11099 if (sub.ranges) { 11100 if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } 11101 for (var j = 0; j < sub.ranges.length; j++) { 11102 rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); 11103 rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); 11104 } 11105 continue; 11106 } 11107 for (var j = 0; j < sub.changes.length; ++j) { 11108 var cur = sub.changes[j]; 11109 if (to < cur.from.line) { 11110 cur.from = Pos(cur.from.line + diff, cur.from.ch); 11111 cur.to = Pos(cur.to.line + diff, cur.to.ch); 11112 } else if (from <= cur.to.line) { 11113 ok = false; 11114 break; 11115 } 11116 } 11117 if (!ok) { 11118 array.splice(0, i + 1); 11119 i = 0; 11120 } 11121 } 11122 } 11123 11124 function rebaseHist(hist, change) { 11125 var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; 11126 rebaseHistArray(hist.done, from, to, diff); 11127 rebaseHistArray(hist.undone, from, to, diff); 11128 } 11129 11130 // EVENT UTILITIES 11131 11132 // Due to the fact that we still support jurassic IE versions, some 11133 // compatibility wrappers are needed. 11134 11135 var e_preventDefault = CodeMirror.e_preventDefault = function(e) { 11136 if (e.preventDefault) e.preventDefault(); 11137 else e.returnValue = false; 11138 }; 11139 var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) { 11140 if (e.stopPropagation) e.stopPropagation(); 11141 else e.cancelBubble = true; 11142 }; 11143 function e_defaultPrevented(e) { 11144 return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; 11145 } 11146 var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);}; 11147 11148 function e_target(e) {return e.target || e.srcElement;} 11149 function e_button(e) { 11150 var b = e.which; 11151 if (b == null) { 11152 if (e.button & 1) b = 1; 11153 else if (e.button & 2) b = 3; 11154 else if (e.button & 4) b = 2; 11155 } 11156 if (mac && e.ctrlKey && b == 1) b = 3; 11157 return b; 11158 } 11159 11160 // EVENT HANDLING 11161 11162 // Lightweight event framework. on/off also work on DOM nodes, 11163 // registering native DOM handlers. 11164 11165 var on = CodeMirror.on = function(emitter, type, f) { 11166 if (emitter.addEventListener) 11167 emitter.addEventListener(type, f, false); 11168 else if (emitter.attachEvent) 11169 emitter.attachEvent("on" + type, f); 11170 else { 11171 var map = emitter._handlers || (emitter._handlers = {}); 11172 var arr = map[type] || (map[type] = []); 11173 arr.push(f); 11174 } 11175 }; 11176 11177 var noHandlers = [] 11178 function getHandlers(emitter, type, copy) { 11179 var arr = emitter._handlers && emitter._handlers[type] 11180 if (copy) return arr && arr.length > 0 ? arr.slice() : noHandlers 11181 else return arr || noHandlers 11182 } 11183 11184 var off = CodeMirror.off = function(emitter, type, f) { 11185 if (emitter.removeEventListener) 11186 emitter.removeEventListener(type, f, false); 11187 else if (emitter.detachEvent) 11188 emitter.detachEvent("on" + type, f); 11189 else { 11190 var handlers = getHandlers(emitter, type, false) 11191 for (var i = 0; i < handlers.length; ++i) 11192 if (handlers[i] == f) { handlers.splice(i, 1); break; } 11193 } 11194 }; 11195 11196 var signal = CodeMirror.signal = function(emitter, type /*, values...*/) { 11197 var handlers = getHandlers(emitter, type, true) 11198 if (!handlers.length) return; 11199 var args = Array.prototype.slice.call(arguments, 2); 11200 for (var i = 0; i < handlers.length; ++i) handlers[i].apply(null, args); 11201 }; 11202 11203 var orphanDelayedCallbacks = null; 11204 11205 // Often, we want to signal events at a point where we are in the 11206 // middle of some work, but don't want the handler to start calling 11207 // other methods on the editor, which might be in an inconsistent 11208 // state or simply not expect any other events to happen. 11209 // signalLater looks whether there are any handlers, and schedules 11210 // them to be executed when the last operation ends, or, if no 11211 // operation is active, when a timeout fires. 11212 function signalLater(emitter, type /*, values...*/) { 11213 var arr = getHandlers(emitter, type, false) 11214 if (!arr.length) return; 11215 var args = Array.prototype.slice.call(arguments, 2), list; 11216 if (operationGroup) { 11217 list = operationGroup.delayedCallbacks; 11218 } else if (orphanDelayedCallbacks) { 11219 list = orphanDelayedCallbacks; 11220 } else { 11221 list = orphanDelayedCallbacks = []; 11222 setTimeout(fireOrphanDelayed, 0); 11223 } 11224 function bnd(f) {return function(){f.apply(null, args);};}; 11225 for (var i = 0; i < arr.length; ++i) 11226 list.push(bnd(arr[i])); 11227 } 11228 11229 function fireOrphanDelayed() { 11230 var delayed = orphanDelayedCallbacks; 11231 orphanDelayedCallbacks = null; 11232 for (var i = 0; i < delayed.length; ++i) delayed[i](); 11233 } 11234 11235 // The DOM events that CodeMirror handles can be overridden by 11236 // registering a (non-DOM) handler on the editor for the event name, 11237 // and preventDefault-ing the event in that handler. 11238 function signalDOMEvent(cm, e, override) { 11239 if (typeof e == "string") 11240 e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; 11241 signal(cm, override || e.type, cm, e); 11242 return e_defaultPrevented(e) || e.codemirrorIgnore; 11243 } 11244 11245 function signalCursorActivity(cm) { 11246 var arr = cm._handlers && cm._handlers.cursorActivity; 11247 if (!arr) return; 11248 var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); 11249 for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1) 11250 set.push(arr[i]); 11251 } 11252 11253 function hasHandler(emitter, type) { 11254 return getHandlers(emitter, type).length > 0 11255 } 11256 11257 // Add on and off methods to a constructor's prototype, to make 11258 // registering events on such objects more convenient. 11259 function eventMixin(ctor) { 11260 ctor.prototype.on = function(type, f) {on(this, type, f);}; 11261 ctor.prototype.off = function(type, f) {off(this, type, f);}; 11262 } 11263 11264 // MISC UTILITIES 11265 11266 // Number of pixels added to scroller and sizer to hide scrollbar 11267 var scrollerGap = 30; 11268 11269 // Returned or thrown by various protocols to signal 'I'm not 11270 // handling this'. 11271 var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}}; 11272 11273 // Reused option objects for setSelection & friends 11274 var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"}; 11275 11276 function Delayed() {this.id = null;} 11277 Delayed.prototype.set = function(ms, f) { 11278 clearTimeout(this.id); 11279 this.id = setTimeout(f, ms); 11280 }; 11281 11282 // Counts the column offset in a string, taking tabs into account. 11283 // Used mostly to find indentation. 11284 var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) { 11285 if (end == null) { 11286 end = string.search(/[^\s\u00a0]/); 11287 if (end == -1) end = string.length; 11288 } 11289 for (var i = startIndex || 0, n = startValue || 0;;) { 11290 var nextTab = string.indexOf("\t", i); 11291 if (nextTab < 0 || nextTab >= end) 11292 return n + (end - i); 11293 n += nextTab - i; 11294 n += tabSize - (n % tabSize); 11295 i = nextTab + 1; 11296 } 11297 }; 11298 11299 // The inverse of countColumn -- find the offset that corresponds to 11300 // a particular column. 11301 var findColumn = CodeMirror.findColumn = function(string, goal, tabSize) { 11302 for (var pos = 0, col = 0;;) { 11303 var nextTab = string.indexOf("\t", pos); 11304 if (nextTab == -1) nextTab = string.length; 11305 var skipped = nextTab - pos; 11306 if (nextTab == string.length || col + skipped >= goal) 11307 return pos + Math.min(skipped, goal - col); 11308 col += nextTab - pos; 11309 col += tabSize - (col % tabSize); 11310 pos = nextTab + 1; 11311 if (col >= goal) return pos; 11312 } 11313 } 11314 11315 var spaceStrs = [""]; 11316 function spaceStr(n) { 11317 while (spaceStrs.length <= n) 11318 spaceStrs.push(lst(spaceStrs) + " "); 11319 return spaceStrs[n]; 11320 } 11321 11322 function lst(arr) { return arr[arr.length-1]; } 11323 11324 var selectInput = function(node) { node.select(); }; 11325 if (ios) // Mobile Safari apparently has a bug where select() is broken. 11326 selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; 11327 else if (ie) // Suppress mysterious IE10 errors 11328 selectInput = function(node) { try { node.select(); } catch(_e) {} }; 11329 11330 function indexOf(array, elt) { 11331 for (var i = 0; i < array.length; ++i) 11332 if (array[i] == elt) return i; 11333 return -1; 11334 } 11335 function map(array, f) { 11336 var out = []; 11337 for (var i = 0; i < array.length; i++) out[i] = f(array[i], i); 11338 return out; 11339 } 11340 11341 function nothing() {} 11342 11343 function createObj(base, props) { 11344 var inst; 11345 if (Object.create) { 11346 inst = Object.create(base); 11347 } else { 11348 nothing.prototype = base; 11349 inst = new nothing(); 11350 } 11351 if (props) copyObj(props, inst); 11352 return inst; 11353 }; 11354 11355 function copyObj(obj, target, overwrite) { 11356 if (!target) target = {}; 11357 for (var prop in obj) 11358 if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) 11359 target[prop] = obj[prop]; 11360 return target; 11361 } 11362 11363 function bind(f) { 11364 var args = Array.prototype.slice.call(arguments, 1); 11365 return function(){return f.apply(null, args);}; 11366 } 11367 11368 var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; 11369 var isWordCharBasic = CodeMirror.isWordChar = function(ch) { 11370 return /\w/.test(ch) || ch > "\x80" && 11371 (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); 11372 }; 11373 function isWordChar(ch, helper) { 11374 if (!helper) return isWordCharBasic(ch); 11375 if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true; 11376 return helper.test(ch); 11377 } 11378 11379 function isEmpty(obj) { 11380 for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; 11381 return true; 11382 } 11383 11384 // Extending unicode characters. A series of a non-extending char + 11385 // any number of extending chars is treated as a single unit as far 11386 // as editing and measuring is concerned. This is not fully correct, 11387 // since some scripts/fonts/browsers also treat other configurations 11388 // of code points as a group. 11389 var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; 11390 function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); } 11391 11392 // DOM UTILITIES 11393 11394 function elt(tag, content, className, style) { 11395 var e = document.createElement(tag); 11396 if (className) e.className = className; 11397 if (style) e.style.cssText = style; 11398 if (typeof content == "string") e.appendChild(document.createTextNode(content)); 11399 else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); 11400 return e; 11401 } 11402 11403 var range; 11404 if (document.createRange) range = function(node, start, end, endNode) { 11405 var r = document.createRange(); 11406 r.setEnd(endNode || node, end); 11407 r.setStart(node, start); 11408 return r; 11409 }; 11410 else range = function(node, start, end) { 11411 var r = document.body.createTextRange(); 11412 try { r.moveToElementText(node.parentNode); } 11413 catch(e) { return r; } 11414 r.collapse(true); 11415 r.moveEnd("character", end); 11416 r.moveStart("character", start); 11417 return r; 11418 }; 11419 11420 function removeChildren(e) { 11421 for (var count = e.childNodes.length; count > 0; --count) 11422 e.removeChild(e.firstChild); 11423 return e; 11424 } 11425 11426 function removeChildrenAndAdd(parent, e) { 11427 return removeChildren(parent).appendChild(e); 11428 } 11429 11430 var contains = CodeMirror.contains = function(parent, child) { 11431 if (child.nodeType == 3) // Android browser always returns false when child is a textnode 11432 child = child.parentNode; 11433 if (parent.contains) 11434 return parent.contains(child); 11435 do { 11436 if (child.nodeType == 11) child = child.host; 11437 if (child == parent) return true; 11438 } while (child = child.parentNode); 11439 }; 11440 11441 function activeElt() { 11442 var activeElement = document.activeElement; 11443 while (activeElement && activeElement.root && activeElement.root.activeElement) 11444 activeElement = activeElement.root.activeElement; 11445 return activeElement; 11446 } 11447 // Older versions of IE throws unspecified error when touching 11448 // document.activeElement in some cases (during loading, in iframe) 11449 if (ie && ie_version < 11) activeElt = function() { 11450 try { return document.activeElement; } 11451 catch(e) { return document.body; } 11452 }; 11453 11454 function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); } 11455 var rmClass = CodeMirror.rmClass = function(node, cls) { 11456 var current = node.className; 11457 var match = classTest(cls).exec(current); 11458 if (match) { 11459 var after = current.slice(match.index + match[0].length); 11460 node.className = current.slice(0, match.index) + (after ? match[1] + after : ""); 11461 } 11462 }; 11463 var addClass = CodeMirror.addClass = function(node, cls) { 11464 var current = node.className; 11465 if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls; 11466 }; 11467 function joinClasses(a, b) { 11468 var as = a.split(" "); 11469 for (var i = 0; i < as.length; i++) 11470 if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i]; 11471 return b; 11472 } 11473 11474 // WINDOW-WIDE EVENTS 11475 11476 // These must be handled carefully, because naively registering a 11477 // handler for each editor will cause the editors to never be 11478 // garbage collected. 11479 11480 function forEachCodeMirror(f) { 11481 if (!document.body.getElementsByClassName) return; 11482 var byClass = document.body.getElementsByClassName("CodeMirror"); 11483 for (var i = 0; i < byClass.length; i++) { 11484 var cm = byClass[i].CodeMirror; 11485 if (cm) f(cm); 11486 } 11487 } 11488 11489 var globalsRegistered = false; 11490 function ensureGlobalHandlers() { 11491 if (globalsRegistered) return; 11492 registerGlobalHandlers(); 11493 globalsRegistered = true; 11494 } 11495 function registerGlobalHandlers() { 11496 // When the window resizes, we need to refresh active editors. 11497 var resizeTimer; 11498 on(window, "resize", function() { 11499 if (resizeTimer == null) resizeTimer = setTimeout(function() { 11500 resizeTimer = null; 11501 forEachCodeMirror(onResize); 11502 }, 100); 11503 }); 11504 // When the window loses focus, we want to show the editor as blurred 11505 on(window, "blur", function() { 11506 forEachCodeMirror(onBlur); 11507 }); 11508 } 11509 11510 // FEATURE DETECTION 11511 11512 // Detect drag-and-drop 11513 var dragAndDrop = function() { 11514 // There is *some* kind of drag-and-drop support in IE6-8, but I 11515 // couldn't get it to work yet. 11516 if (ie && ie_version < 9) return false; 11517 var div = elt('div'); 11518 return "draggable" in div || "dragDrop" in div; 11519 }(); 11520 11521 var zwspSupported; 11522 function zeroWidthElement(measure) { 11523 if (zwspSupported == null) { 11524 var test = elt("span", "\u200b"); 11525 removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); 11526 if (measure.firstChild.offsetHeight != 0) 11527 zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); 11528 } 11529 var node = zwspSupported ? elt("span", "\u200b") : 11530 elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); 11531 node.setAttribute("cm-text", ""); 11532 return node; 11533 } 11534 11535 // Feature-detect IE's crummy client rect reporting for bidi text 11536 var badBidiRects; 11537 function hasBadBidiRects(measure) { 11538 if (badBidiRects != null) return badBidiRects; 11539 var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); 11540 var r0 = range(txt, 0, 1).getBoundingClientRect(); 11541
11541if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780) 11542 var r1 = range(txt, 1, 2).getBoundingClientRect();
vendor: 14,748 bytes, lines 11542-11908
11542 11543 return badBidiRects = (r1.right - r0.right < 3); 11544 } 11545 11546 // See if "".split is the broken IE version, if so, provide an 11547 // alternative way to split lines. 11548 var splitLinesAuto = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) { 11549 var pos = 0, result = [], l = string.length; 11550 while (pos <= l) { 11551 var nl = string.indexOf("\n", pos); 11552 if (nl == -1) nl = string.length; 11553 var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); 11554 var rt = line.indexOf("\r"); 11555 if (rt != -1) { 11556 result.push(line.slice(0, rt)); 11557 pos += rt + 1; 11558 } else { 11559 result.push(line); 11560 pos = nl + 1; 11561 } 11562 } 11563 return result; 11564 } : function(string){return string.split(/\r\n?|\n/);}; 11565 11566 var hasSelection = window.getSelection ? function(te) { 11567 try { return te.selectionStart != te.selectionEnd; } 11568 catch(e) { return false; } 11569 } : function(te) { 11570 try {var range = te.ownerDocument.selection.createRange();} 11571 catch(e) {} 11572 if (!range || range.parentElement() != te) return false; 11573 return range.compareEndPoints("StartToEnd", range) != 0; 11574 }; 11575 11576 var hasCopyEvent = (function() { 11577 var e = elt("div"); 11578 if ("oncopy" in e) return true; 11579 e.setAttribute("oncopy", "return;"); 11580 return typeof e.oncopy == "function"; 11581 })(); 11582 11583 var badZoomedRects = null; 11584 function hasBadZoomedRects(measure) { 11585 if (badZoomedRects != null) return badZoomedRects; 11586 var node = removeChildrenAndAdd(measure, elt("span", "x")); 11587 var normal = node.getBoundingClientRect(); 11588 var fromRange = range(node, 0, 1).getBoundingClientRect(); 11589 return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1; 11590 } 11591 11592 // KEY NAMES 11593 11594 var keyNames = CodeMirror.keyNames = { 11595 3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", 11596 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", 11597 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", 11598 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 11599 106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 127: "Delete", 11600 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 11601 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", 11602 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert" 11603 }; 11604 (function() { 11605 // Number keys 11606 for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i); 11607 // Alphabetic keys 11608 for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); 11609 // Function keys 11610 for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; 11611 })(); 11612 11613 // BIDI HELPERS 11614 11615 function iterateBidiSections(order, from, to, f) { 11616 if (!order) return f(from, to, "ltr"); 11617 var found = false; 11618 for (var i = 0; i < order.length; ++i) { 11619 var part = order[i]; 11620 if (part.from < to && part.to > from || from == to && part.to == from) { 11621 f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); 11622 found = true; 11623 } 11624 } 11625 if (!found) f(from, to, "ltr"); 11626 } 11627 11628 function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } 11629 function bidiRight(part) { return part.level % 2 ? part.from : part.to; } 11630 11631 function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } 11632 function lineRight(line) { 11633 var order = getOrder(line); 11634 if (!order) return line.text.length; 11635 return bidiRight(lst(order)); 11636 } 11637 11638 function lineStart(cm, lineN) { 11639 var line = getLine(cm.doc, lineN); 11640 var visual = visualLine(line); 11641 if (visual != line) lineN = lineNo(visual); 11642 var order = getOrder(visual); 11643 var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); 11644 return Pos(lineN, ch); 11645 } 11646 function lineEnd(cm, lineN) { 11647 var merged, line = getLine(cm.doc, lineN); 11648 while (merged = collapsedSpanAtEnd(line)) { 11649 line = merged.find(1, true).line; 11650 lineN = null; 11651 } 11652 var order = getOrder(line); 11653 var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); 11654 return Pos(lineN == null ? lineNo(line) : lineN, ch); 11655 } 11656 function lineStartSmart(cm, pos) { 11657 var start = lineStart(cm, pos.line); 11658 var line = getLine(cm.doc, start.line); 11659 var order = getOrder(line); 11660 if (!order || order[0].level == 0) { 11661 var firstNonWS = Math.max(0, line.text.search(/\S/)); 11662 var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch; 11663 return Pos(start.line, inWS ? 0 : firstNonWS); 11664 } 11665 return start; 11666 } 11667 11668 function compareBidiLevel(order, a, b) { 11669 var linedir = order[0].level; 11670 if (a == linedir) return true; 11671 if (b == linedir) return false; 11672 return a < b; 11673 } 11674 var bidiOther; 11675 function getBidiPartAt(order, pos) { 11676 bidiOther = null; 11677 for (var i = 0, found; i < order.length; ++i) { 11678 var cur = order[i]; 11679 if (cur.from < pos && cur.to > pos) return i; 11680 if ((cur.from == pos || cur.to == pos)) { 11681 if (found == null) { 11682 found = i; 11683 } else if (compareBidiLevel(order, cur.level, order[found].level)) { 11684 if (cur.from != cur.to) bidiOther = found; 11685 return i; 11686 } else { 11687 if (cur.from != cur.to) bidiOther = i; 11688 return found; 11689 } 11690 } 11691 } 11692 return found; 11693 } 11694 11695 function moveInLine(line, pos, dir, byUnit) { 11696 if (!byUnit) return pos + dir; 11697 do pos += dir; 11698 while (pos > 0 && isExtendingChar(line.text.charAt(pos))); 11699 return pos; 11700 } 11701 11702 // This is needed in order to move 'visually' through bi-directional 11703 // text -- i.e., pressing left should make the cursor go left, even 11704 // when in RTL text. The tricky part is the 'jumps', where RTL and 11705 // LTR text touch each other. This often requires the cursor offset 11706 // to move more than one unit, in order to visually move one unit. 11707 function moveVisually(line, start, dir, byUnit) { 11708 var bidi = getOrder(line); 11709 if (!bidi) return moveLogically(line, start, dir, byUnit); 11710 var pos = getBidiPartAt(bidi, start), part = bidi[pos]; 11711 var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); 11712 11713 for (;;) { 11714 if (target > part.from && target < part.to) return target; 11715 if (target == part.from || target == part.to) { 11716 if (getBidiPartAt(bidi, target) == pos) return target; 11717 part = bidi[pos += dir]; 11718 return (dir > 0) == part.level % 2 ? part.to : part.from; 11719 } else { 11720 part = bidi[pos += dir]; 11721 if (!part) return null; 11722 if ((dir > 0) == part.level % 2) 11723 target = moveInLine(line, part.to, -1, byUnit); 11724 else 11725 target = moveInLine(line, part.from, 1, byUnit); 11726 } 11727 } 11728 } 11729 11730 function moveLogically(line, start, dir, byUnit) { 11731 var target = start + dir; 11732 if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir; 11733 return target < 0 || target > line.text.length ? null : target; 11734 } 11735 11736 // Bidirectional ordering algorithm 11737 // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm 11738 // that this (partially) implements. 11739 11740 // One-char codes used for character types: 11741 // L (L): Left-to-Right 11742 // R (R): Right-to-Left 11743 // r (AL): Right-to-Left Arabic 11744 // 1 (EN): European Number 11745 // + (ES): European Number Separator 11746 // % (ET): European Number Terminator 11747 // n (AN): Arabic Number 11748 // , (CS): Common Number Separator 11749 // m (NSM): Non-Spacing Mark 11750 // b (BN): Boundary Neutral 11751 // s (B): Paragraph Separator 11752 // t (S): Segment Separator 11753 // w (WS): Whitespace 11754 // N (ON): Other Neutrals 11755 11756 // Returns null if characters are ordered as they appear 11757 // (left-to-right), or an array of sections ({from, to, level} 11758 // objects) in the order in which they occur visually. 11759 var bidiOrdering = (function() { 11760 // Character types for codepoints 0 to 0xff 11761 var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; 11762 // Character types for codepoints 0x600 to 0x6ff 11763 var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm"; 11764 function charType(code) { 11765 if (code <= 0xf7) return lowTypes.charAt(code); 11766 else if (0x590 <= code && code <= 0x5f4) return "R"; 11767 else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600); 11768 else if (0x6ee <= code && code <= 0x8ac) return "r"; 11769 else if (0x2000 <= code && code <= 0x200b) return "w"; 11770 else if (code == 0x200c) return "b"; 11771 else return "L"; 11772 } 11773 11774 var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; 11775 var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; 11776 // Browsers seem to always treat the boundaries of block elements as being L. 11777 var outerType = "L"; 11778 11779 function BidiSpan(level, from, to) { 11780 this.level = level; 11781 this.from = from; this.to = to; 11782 } 11783 11784 return function(str) { 11785 if (!bidiRE.test(str)) return false; 11786 var len = str.length, types = []; 11787 for (var i = 0, type; i < len; ++i) 11788 types.push(type = charType(str.charCodeAt(i))); 11789 11790 // W1. Examine each non-spacing mark (NSM) in the level run, and 11791 // change the type of the NSM to the type of the previous 11792 // character. If the NSM is at the start of the level run, it will 11793 // get the type of sor. 11794 for (var i = 0, prev = outerType; i < len; ++i) { 11795 var type = types[i]; 11796 if (type == "m") types[i] = prev; 11797 else prev = type; 11798 } 11799 11800 // W2. Search backwards from each instance of a European number 11801 // until the first strong type (R, L, AL, or sor) is found. If an 11802 // AL is found, change the type of the European number to Arabic 11803 // number. 11804 // W3. Change all ALs to R. 11805 for (var i = 0, cur = outerType; i < len; ++i) { 11806 var type = types[i]; 11807 if (type == "1" && cur == "r") types[i] = "n"; 11808 else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } 11809 } 11810 11811 // W4. A single European separator between two European numbers 11812 // changes to a European number. A single common separator between 11813 // two numbers of the same type changes to that type. 11814 for (var i = 1, prev = types[0]; i < len - 1; ++i) { 11815 var type = types[i]; 11816 if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1"; 11817 else if (type == "," && prev == types[i+1] && 11818 (prev == "1" || prev == "n")) types[i] = prev; 11819 prev = type; 11820 } 11821 11822 // W5. A sequence of European terminators adjacent to European 11823 // numbers changes to all European numbers. 11824 // W6. Otherwise, separators and terminators change to Other 11825 // Neutral. 11826 for (var i = 0; i < len; ++i) { 11827 var type = types[i]; 11828 if (type == ",") types[i] = "N"; 11829 else if (type == "%") { 11830 for (var end = i + 1; end < len && types[end] == "%"; ++end) {} 11831 var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; 11832 for (var j = i; j < end; ++j) types[j] = replace; 11833 i = end - 1; 11834 } 11835 } 11836 11837 // W7. Search backwards from each instance of a European number 11838 // until the first strong type (R, L, or sor) is found. If an L is 11839 // found, then change the type of the European number to L. 11840 for (var i = 0, cur = outerType; i < len; ++i) { 11841 var type = types[i]; 11842 if (cur == "L" && type == "1") types[i] = "L"; 11843 else if (isStrong.test(type)) cur = type; 11844 } 11845 11846 // N1. A sequence of neutrals takes the direction of the 11847 // surrounding strong text if the text on both sides has the same 11848 // direction. European and Arabic numbers act as if they were R in 11849 // terms of their influence on neutrals. Start-of-level-run (sor) 11850 // and end-of-level-run (eor) are used at level run boundaries. 11851 // N2. Any remaining neutrals take the embedding direction. 11852 for (var i = 0; i < len; ++i) { 11853 if (isNeutral.test(types[i])) { 11854 for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {} 11855 var before = (i ? types[i-1] : outerType) == "L"; 11856 var after = (end < len ? types[end] : outerType) == "L"; 11857 var replace = before || after ? "L" : "R"; 11858 for (var j = i; j < end; ++j) types[j] = replace; 11859 i = end - 1; 11860 } 11861 } 11862 11863 // Here we depart from the documented algorithm, in order to avoid 11864 // building up an actual levels array. Since there are only three 11865 // levels (0, 1, 2) in an implementation that doesn't take 11866 // explicit embedding into account, we can build up the order on 11867 // the fly, without following the level-based algorithm. 11868 var order = [], m; 11869 for (var i = 0; i < len;) { 11870 if (countsAsLeft.test(types[i])) { 11871 var start = i; 11872 for (++i; i < len && countsAsLeft.test(types[i]); ++i) {} 11873 order.push(new BidiSpan(0, start, i)); 11874 } else { 11875 var pos = i, at = order.length; 11876 for (++i; i < len && types[i] != "L"; ++i) {} 11877 for (var j = pos; j < i;) { 11878 if (countsAsNum.test(types[j])) { 11879 if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j)); 11880 var nstart = j; 11881 for (++j; j < i && countsAsNum.test(types[j]); ++j) {} 11882 order.splice(at, 0, new BidiSpan(2, nstart, j)); 11883 pos = j; 11884 } else ++j; 11885 } 11886 if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i)); 11887 } 11888 } 11889 if (order[0].level == 1 && (m = str.match(/^\s+/))) { 11890 order[0].from = m[0].length; 11891 order.unshift(new BidiSpan(0, 0, m[0].length)); 11892 } 11893 if (lst(order).level == 1 && (m = str.match(/\s+$/))) { 11894 lst(order).to -= m[0].length; 11895 order.push(new BidiSpan(0, len - m[0].length, len)); 11896 } 11897 if (order[0].level == 2) 11898 order.unshift(new BidiSpan(1, order[0].to, order[0].to)); 11899 if (order[0].level != lst(order).level) 11900 order.push(new BidiSpan(order[0].level, len, len)); 11901 11902 return order; 11903 }; 11904 })(); 11905 11906 // THE END 11907 11908 CodeMirror.version = "5.
119088.0"; 11909 11910 return CodeMirror; 11911}); 11912 11913},{}],31:[function(_dereq_,module,exports){ 11914// CodeMirror, copyright (c) by Marijn Haverbeke and others 11915// Distributed under an MIT license: http://codemirror.net/LICENSE 11916 11917(function(mod) { 11918 if (typeof exports == "object" && typeof module == "object") // CommonJS 11919 mod(_dereq_("../../lib/codemirror")); 11920 else if (typeof define == "function" && define.amd) // AMD 11921 define(["../../lib/codemirror"], mod); 11922 else // Plain browser env 11923 mod(CodeMirror); 11924})(function(CodeMirror) { 11925"use strict"; 11926 11927CodeMirror.defineMode("clike", function(config, parserConfig) { 11928 var indentUnit = config.indentUnit, 11929 statementIndentUnit = parserConfig.statementIndentUnit || indentUnit, 11930 dontAlignCalls = parserConfig.dontAlignCalls, 11931 keywords = parserConfig.keywords || {}, 11932 types = parserConfig.types || {}, 11933 builtin = parserConfig.builtin || {}, 11934 blockKeywords = parserConfig.blockKeywords || {}, 11935 defKeywords = parserConfig.defKeywords || {}, 11936 atoms = parserConfig.atoms || {}, 11937 hooks = parserConfig.hooks || {}, 11938 multiLineStrings = parserConfig.multiLineStrings, 11939 indentStatements = parserConfig.indentStatements !== false, 11940 indentSwitch = parserConfig.indentSwitch !== false, 11941 namespaceSeparator = parserConfig.namespaceSeparator, 11942 isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/, 11943 isNumberChar = parserConfig.isNumberChar || /\d/, 11944 isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/, 11945 endStatement = parserConfig.endStatement || /^[;:,]$/; 11946 11947 var curPunc, isDefKeyword; 11948 11949 function tokenBase(stream, state) { 11950 var ch = stream.next(); 11951 if (hooks[ch]) { 11952 var result = hooks[ch](stream, state); 11953 if (result !== false) return result; 11954 } 11955 if (ch == '"' || ch == "'") { 11956 state.tokenize = tokenString(ch); 11957 return state.tokenize(stream, state); 11958 } 11959 if (isPunctuationChar.test(ch)) { 11960 curPunc = ch; 11961 return null; 11962 } 11963 if (isNumberChar.test(ch)) { 11964 stream.eatWhile(/[\w\.]/); 11965 return "number"; 11966 } 11967 if (ch == "/") { 11968 if (stream.eat("*")) { 11969 state.tokenize = tokenComment; 11970 return tokenComment(stream, state); 11971 } 11972 if (stream.eat("/")) { 11973 stream.skipToEnd(); 11974 return "comment"; 11975 } 11976 } 11977 if (isOperatorChar.test(ch)) { 11978 stream.eatWhile(isOperatorChar); 11979 return "operator"; 11980 } 11981 stream.eatWhile(/[\w\$_\xa1-\uffff]/); 11982 if (namespaceSeparator) while (stream.match(namespaceSeparator)) 11983 stream.eatWhile(/[\w\$_\xa1-\uffff]/); 11984 11985 var cur = stream.current(); 11986 if (contains(keywords, cur)) { 11987 if (contains(blockKeywords, cur)) curPunc = "newstatement"; 11988 if (contains(defKeywords, cur)) isDefKeyword = true; 11989 return "keyword"; 11990 } 11991 if (contains(types, cur)) return "variable-3"; 11992 if (contains(builtin, cur)) { 11993 if (contains(blockKeywords, cur)) curPunc = "newstatement"; 11994 return "builtin"; 11995 } 11996 if (contains(atoms, cur)) return "atom"; 11997 return "variable"; 11998 } 11999 12000 function tokenString(quote) { 12001 return function(stream, state) { 12002 var escaped = false, next, end = false; 12003 while ((next = stream.next()) != null) { 12004 if (next == quote && !escaped) {end = true; break;} 12005 escaped = !escaped && next == "\\"; 12006 } 12007 if (end || !(escaped || multiLineStrings)) 12008 state.tokenize = null; 12009 return "string"; 12010 }; 12011 } 12012 12013 function tokenComment(stream, state) { 12014 var maybeEnd = false, ch; 12015 while (ch = stream.next()) { 12016 if (ch == "/" && maybeEnd) { 12017 state.tokenize = null; 12018 break; 12019 } 12020 maybeEnd = (ch == "*"); 12021 } 12022 return "comment"; 12023 } 12024 12025 function Context(indented, column, type, align, prev) { 12026 this.indented = indented; 12027 this.column = column; 12028 this.type = type; 12029 this.align = align; 12030 this.prev = prev; 12031 } 12032 function isStatement(type) { 12033 return type == "statement" || type == "switchstatement" || type == "namespace"; 12034 } 12035 function pushContext(state, col, type) { 12036 var indent = state.indented;
12037 if (state.context && isStatement(state.context.type) && !isStatement(type)) 12038 indent = state.context.indented; 12039 return state.context = new Context(indent, col, type, null, state.context); 12040 } 12041 function popContext(state) { 12042 var t = state.context.type; 12043 if (t == ")" || t == "]" || t == "}") 12044 state.indented = state.context.indented; 12045 return state.context = state.context.prev; 12046 } 12047 12048 function typeBefore(stream, state) { 12049 if (state.prevToken == "variable" || state.prevToken == "variable-3") return true; 12050 if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, stream.start))) return true; 12051 } 12052 12053 function isTopScope(context) { 12054 for (;;) { 12055 if (!context || context.type == "top") return true; 12056 if (context.type == "}" && context.prev.type != "namespace") return false; 12057 context = context.prev; 12058 } 12059 } 12060 12061 // Interface 12062 12063 return { 12064 startState: function(basecolumn) { 12065 return { 12066 tokenize: null, 12067 context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), 12068 indented: 0, 12069 startOfLine: true, 12070 prevToken: null 12071 }; 12072 }, 12073 12074 token: function(stream, state) { 12075 var ctx = state.context; 12076 if (stream.sol()) { 12077 if (ctx.align == null) ctx.align = false; 12078 state.indented = stream.indentation(); 12079 state.startOfLine = true; 12080 } 12081 if (stream.eatSpace()) return null; 12082 curPunc = isDefKeyword = null; 12083 var style = (state.tokenize || tokenBase)(stream, state); 12084 if (style == "comment" || style == "meta") return style; 12085 if (ctx.align == null) ctx.align = true; 12086 12087 if (endStatement.test(curPunc)) while (isStatement(state.context.type)) popContext(state); 12088 else if (curPunc == "{") pushContext(state, stream.column(), "}"); 12089 else if (curPunc == "[") pushContext(state, stream.column(), "]"); 12090 else if (curPunc == "(") pushContext(state, stream.column(), ")"); 12091 else if (curPunc == "}") { 12092 while (isStatement(ctx.type)) ctx = popContext(state); 12093 if (ctx.type == "}") ctx = popContext(state); 12094 while (isStatement(ctx.type)) ctx = popContext(state); 12095 } 12096 else if (curPunc == ctx.type) popContext(state); 12097 else if (indentStatements && 12098 (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") || 12099 (isStatement(ctx.type) && curPunc == "newstatement"))) { 12100 var type = "statement"; 12101 if (curPunc == "newstatement" && indentSwitch && stream.current() == "switch") 12102 type = "switchstatement"; 12103 else if (style == "keyword" && stream.current() == "namespace") 12104 type = "namespace"; 12105 pushContext(state, stream.column(), type); 12106 } 12107 12108 if (style == "variable" && 12109 ((state.prevToken == "def" || 12110 (parserConfig.typeFirstDefinitions && typeBefore(stream, state) && 12111 isTopScope(state.context) && stream.match(/^\s*\(/, false))))) 12112 style = "def"; 12113 12114 if (hooks.token) { 12115 var result = hooks.token(stream, state, style); 12116 if (result !== undefined) style = result; 12117 } 12118 12119 if (style == "def" && parserConfig.styleDefs === false) style = "variable"; 12120 12121 state.startOfLine = false; 12122 state.prevToken = isDefKeyword ? "def" : style || curPunc; 12123 return style; 12124 }, 12125 12126 indent: function(state, textAfter) { 12127 if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass; 12128 var ctx = state.context, firstChar = textAfter && textAfter.charAt(0); 12129 if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev; 12130 if (hooks.indent) { 12131 var hook = hooks.indent(state, ctx, textAfter); 12132 if (typeof hook == "number") return hook 12133 } 12134 var closing = firstChar == ctx.type; 12135 var switchBlock = ctx.prev && ctx.prev.type == "switchstatement"; 12136 if (isStatement(ctx.type)) 12137 return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit); 12138 if (ctx.align && (!dontAlignCalls || ctx.type != ")")) 12139 return ctx.column + (closing ? 0 : 1); 12140 if (ctx.type == ")" && !closing) 12141 return ctx.indented + statementIndentUnit; 12142 12143 return ctx.indented + (closing ? 0 : indentUnit) + 12144 (!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0); 12145 }, 12146 12147 electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/, 12148 blockCommentStart: "/*", 12149 blockCommentEnd: "*/", 12150 lineComment: "//", 12151 fold: "brace" 12152 }; 12153}); 12154 12155 function words(str) { 12156 var obj = {}, words = str.split(" "); 12157 for (var i = 0; i < words.length; ++i) obj[words[i]] = true; 12158 return obj; 12159 } 12160 function contains(words, word) { 12161 if (typeof words === "function") { 12162 return words(word); 12163 } else { 12164 return words.propertyIsEnumerable(word); 12165 } 12166 } 12167 var cKeywords = "auto if break case register continue return default do sizeof " + 12168 "static else struct switch extern typedef float union for " + 12169 "goto while enum const volatile"; 12170 var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t"; 12171 12172 function cppHook(stream, state) { 12173 if (!state.startOfLine) return false;
12174 for (;;) { 12175 if (stream.skipTo("\\")) { 12176 stream.next(); 12177 if (stream.eol()) { 12178 state.tokenize = cppHook; 12179 break; 12180 } 12181 } else { 12182 stream.skipToEnd(); 12183 state.tokenize = null; 12184 break; 12185 } 12186 } 12187 return "meta"; 12188 } 12189 12190 function pointerHook(_stream, state) { 12191 if (state.prevToken == "variable-3") return "variable-3"; 12192 return false; 12193 } 12194 12195 function cpp14Literal(stream) { 12196 stream.eatWhile(/[\w\.']/); 12197 return "number"; 12198 } 12199 12200 function cpp11StringHook(stream, state) { 12201 stream.backUp(1); 12202 // Raw strings. 12203 if (stream.match(/(R|u8R|uR|UR|LR)/)) { 12204 var match = stream.match(/"([^\s\\()]{0,16})\(/); 12205 if (!match) { 12206 return false; 12207 } 12208 state.cpp11RawStringDelim = match[1]; 12209 state.tokenize = tokenRawString; 12210 return tokenRawString(stream, state); 12211 } 12212 // Unicode strings/chars. 12213 if (stream.match(/(u8|u|U|L)/)) { 12214 if (stream.match(/["']/, /* eat */ false)) { 12215 return "string"; 12216 } 12217 return false; 12218 } 12219 // Ignore this hook. 12220 stream.next(); 12221 return false; 12222 } 12223 12224 function cppLooksLikeConstructor(word) { 12225 var lastTwo = /(\w+)::(\w+)$/.exec(word); 12226 return lastTwo && lastTwo[1] == lastTwo[2]; 12227 } 12228 12229 // C#-style strings where "" escapes a quote. 12230 function tokenAtString(stream, state) { 12231 var next; 12232 while ((next = stream.next()) != null) { 12233 if (next == '"' && !stream.eat('"')) { 12234 state.tokenize = null; 12235 break; 12236 } 12237 } 12238 return "string"; 12239 } 12240 12241 // C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where 12242 // <delim> can be a string up to 16 characters long. 12243 function tokenRawString(stream, state) { 12244 // Escape characters that have special regex meanings. 12245 var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&'); 12246 var match = stream.match(new RegExp(".*?\\)" + delim + '"')); 12247 if (match) 12248 state.tokenize = null; 12249 else 12250 stream.skipToEnd(); 12251 return "string"; 12252 } 12253 12254 function def(mimes, mode) { 12255 if (typeof mimes == "string") mimes = [mimes]; 12256 var words = []; 12257 function add(obj) { 12258 if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop)) 12259 words.push(prop); 12260 } 12261 add(mode.keywords); 12262 add(mode.types); 12263 add(mode.builtin); 12264 add(mode.atoms); 12265 if (words.length) { 12266 mode.helperType = mimes[0]; 12267 CodeMirror.registerHelper("hintWords", mimes[0], words); 12268 } 12269 12270 for (var i = 0; i < mimes.length; ++i) 12271 CodeMirror.defineMIME(mimes[i], mode); 12272 } 12273 12274 def(["text/x-csrc", "text/x-c", "text/x-chdr"], { 12275 name: "clike", 12276 keywords: words(cKeywords), 12277 types: words(cTypes + " bool _Complex _Bool float_t double_t intptr_t intmax_t " + 12278 "int8_t int16_t int32_t int64_t uintptr_t uintmax_t uint8_t uint16_t " + 12279 "uint32_t uint64_t"), 12280 blockKeywords: words("case do else for if switch while struct"), 12281 defKeywords: words("struct"), 12282 typeFirstDefinitions: true, 12283 atoms: words("null true false"), 12284 hooks: {"#": cppHook, "*": pointerHook}, 12285 modeProps: {fold: ["brace", "include"]} 12286 }); 12287 12288 def(["text/x-c++src", "text/x-c++hdr"], { 12289 name: "clike", 12290 keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try explicit new " + 12291 "static_cast typeid catch operator template typename class friend private " + 12292 "this using const_cast inline public throw virtual delete mutable protected " + 12293 "alignas alignof constexpr decltype nullptr noexcept thread_local final " + 12294 "static_assert override"), 12295 types: words(cTypes + " bool wchar_t"), 12296 blockKeywords: words("catch class do else finally for if struct switch try while"), 12297 defKeywords: words("class namespace struct enum union"), 12298 typeFirstDefinitions: true, 12299 atoms: words("true false null"), 12300 hooks: { 12301 "#": cppHook, 12302 "*": pointerHook, 12303 "u": cpp11StringHook, 12304 "U": cpp11StringHook, 12305 "L": cpp11StringHook, 12306 "R": cpp11StringHook, 12307 "0": cpp14Literal, 12308 "1": cpp14Literal, 12309 "2": cpp14Literal, 12310 "3": cpp14Literal, 12311 "4": cpp14Literal, 12312 "5": cpp14Literal, 12313 "6": cpp14Literal, 12314 "7": cpp14Literal, 12315 "8": cpp14Literal, 12316 "9": cpp14Literal, 12317 token: function(stream, state, style) { 12318 if (style == "variable" && stream.peek() == "(" && 12319 (state.prevToken == ";" || state.prevToken == null || 12320 state.prevToken == "}") && 12321 cppLooksLikeConstructor(stream.current())) 12322 return "def"; 12323 } 12324 }, 12325 namespaceSeparator: "::", 12326 modeProps: {fold: ["brace", "include"]} 12327 }); 12328 12329 def("text/x-java", { 12330 name: "clike",
12331 keywords: words("abstract assert break case catch class const continue default " + 12332 "do else enum extends final finally float for goto if implements import " + 12333 "instanceof interface native new package private protected public " + 12334 "return static strictfp super switch synchronized this throw throws transient " + 12335 "try volatile while"), 12336 types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " + 12337 "Integer Long Number Object Short String StringBuffer StringBuilder Void"), 12338 blockKeywords: words("catch class do else finally for if switch try while"), 12339 defKeywords: words("class interface package enum"), 12340 typeFirstDefinitions: true, 12341 atoms: words("true false null"), 12342 endStatement: /^[;:]$/, 12343 hooks: { 12344 "@": function(stream) { 12345 stream.eatWhile(/[\w\$_]/); 12346 return "meta"; 12347 } 12348 }, 12349 modeProps: {fold: ["brace", "import"]} 12350 }); 12351 12352 def("text/x-csharp", { 12353 name: "clike", 12354 keywords: words("abstract as async await base break case catch checked class const continue" + 12355 " default delegate do else enum event explicit extern finally fixed for" + 12356 " foreach goto if implicit in interface internal is lock namespace new" + 12357 " operator out override params private protected public readonly ref return sealed" + 12358 " sizeof stackalloc static struct switch this throw try typeof unchecked" + 12359 " unsafe using virtual void volatile while add alias ascending descending dynamic from get" + 12360 " global group into join let orderby partial remove select set value var yield"), 12361 types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" + 12362 " Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" + 12363 " UInt64 bool byte char decimal double short int long object" + 12364 " sbyte float string ushort uint ulong"), 12365 blockKeywords: words("catch class do else finally for foreach if struct switch try while"), 12366 defKeywords: words("class interface namespace struct var"), 12367 typeFirstDefinitions: true, 12368 atoms: words("true false null"), 12369 hooks: { 12370 "@": function(stream, state) { 12371 if (stream.eat('"')) { 12372 state.tokenize = tokenAtString; 12373 return tokenAtString(stream, state); 12374 } 12375 stream.eatWhile(/[\w\$_]/); 12376 return "meta"; 12377 } 12378 } 12379 }); 12380 12381 function tokenTripleString(stream, state) { 12382 var escaped = false; 12383 while (!stream.eol()) { 12384 if (!escaped && stream.match('"""')) { 12385 state.tokenize = null; 12386 break; 12387 } 12388 escaped = stream.next() == "\\" && !escaped; 12389 } 12390 return "string"; 12391 } 12392 12393 def("text/x-scala", { 12394 name: "clike", 12395 keywords: words( 12396 12397 /* scala */ 12398 "abstract case catch class def do else extends final finally for forSome if " + 12399 "implicit import lazy match new null object override package private protected return " + 12400 "sealed super this throw trait try type val var while with yield _ : = => <- <: " + 12401 "<% >: # @ " + 12402 12403 /* package scala */ 12404 "assert assume require print println printf readLine readBoolean readByte readShort " + 12405 "readChar readInt readLong readFloat readDouble " + 12406 12407 ":: #:: " 12408 ), 12409 types: words( 12410 "AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " + 12411 "Enumeration Equiv Error Exception Fractional Function IndexedSeq Integral Iterable " + 12412 "Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " + 12413 "Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " + 12414 "StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " + 12415 12416 /* package java.lang */ 12417 "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " + 12418 "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " + 12419 "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " + 12420 "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void" 12421 ), 12422 multiLineStrings: true, 12423 blockKeywords: words("catch class do else finally for forSome if match switch try while"), 12424 defKeywords: words("class def object package trait type val var"), 12425 atoms: words("true false null"), 12426 indentStatements: false, 12427 indentSwitch: false, 12428 hooks: { 12429 "@": function(stream) { 12430 stream.eatWhile(/[\w\$_]/); 12431 return "meta"; 12432 }, 12433 '"': function(stream, state) { 12434 if (!stream.match('""')) return false;
12435 state.tokenize = tokenTripleString; 12436 return state.tokenize(stream, state); 12437 }, 12438 "'": function(stream) { 12439 stream.eatWhile(/[\w\$_\xa1-\uffff]/); 12440 return "atom"; 12441 } 12442 }, 12443 modeProps: {closeBrackets: {triples: '"'}} 12444 }); 12445 12446 def("text/x-kotlin", { 12447 name: "clike", 12448 keywords: words( 12449 /*keywords*/ 12450 "package as typealias class interface this super val " + 12451 "var fun for is in This throw return " + 12452 "break continue object if else while do try when !in !is as?" + 12453 12454 /*soft keywords*/ 12455 "file import where by get set abstract enum open inner override private public internal " + 12456 "protected catch finally out final vararg reified dynamic companion constructor init " + 12457 "sealed field property receiver param sparam lateinit data inline noinline tailrec " + 12458 "external annotation crossinline" 12459 ), 12460 types: words( 12461 /* package java.lang */ 12462 "Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " + 12463 "Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " + 12464 "Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " + 12465 "StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void" 12466 ), 12467 multiLineStrings: true, 12468 blockKeywords: words("catch class do else finally for if where try while enum"), 12469 defKeywords: words("class val var object package interface fun"), 12470 atoms: words("true false null this"), 12471 modeProps: {closeBrackets: {triples: '"'}} 12472 }); 12473 12474 def(["x-shader/x-vertex", "x-shader/x-fragment"], { 12475 name: "clike", 12476 keywords: words("sampler1D sampler2D sampler3D samplerCube " + 12477 "sampler1DShadow sampler2DShadow " + 12478 "const attribute uniform varying " + 12479 "break continue discard return " + 12480 "for while do if else struct " + 12481 "in out inout"), 12482 types: words("float int bool void " + 12483 "vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " + 12484 "mat2 mat3 mat4"), 12485 blockKeywords: words("for while do if else struct"), 12486 builtin: words("radians degrees sin cos tan asin acos atan " + 12487 "pow exp log exp2 sqrt inversesqrt " + 12488 "abs sign floor ceil fract mod min max clamp mix step smoothstep " + 12489 "length distance dot cross normalize ftransform faceforward " + 12490 "reflect refract matrixCompMult " + 12491 "lessThan lessThanEqual greaterThan greaterThanEqual " + 12492 "equal notEqual any all not " + 12493 "texture1D texture1DProj texture1DLod texture1DProjLod " + 12494 "texture2D texture2DProj texture2DLod texture2DProjLod " + 12495 "texture3D texture3DProj texture3DLod texture3DProjLod " + 12496 "textureCube textureCubeLod " + 12497 "shadow1D shadow2D shadow1DProj shadow2DProj " + 12498 "shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " + 12499 "dFdx dFdy fwidth " + 12500 "noise1 noise2 noise3 noise4"), 12501 atoms: words("true false " + 12502 "gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " + 12503 "gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " + 12504 "gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " + 12505 "gl_FogCoord gl_PointCoord " + 12506 "gl_Position gl_PointSize gl_ClipVertex " + 12507 "gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " + 12508 "gl_TexCoord gl_FogFragCoord " + 12509 "gl_FragCoord gl_FrontFacing " + 12510 "gl_FragData gl_FragDepth " + 12511 "gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " + 12512 "gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " + 12513 "gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " + 12514 "gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " + 12515 "gl_ProjectionMatrixInverseTranspose " + 12516 "gl_ModelViewProjectionMatrixInverseTranspose " + 12517 "gl_TextureMatrixInverseTranspose " + 12518 "gl_NormalScale gl_DepthRange gl_ClipPlane " + 12519 "gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " + 12520 "gl_FrontLightModelProduct gl_BackLightModelProduct " + 12521 "gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " + 12522 "gl_FogParameters " + 12523 "gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " + 12524 "gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " + 12525 "gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " + 12526 "gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " + 12527 "gl_MaxDrawBuffers"), 12528 indentSwitch: false, 12529 hooks: {"#": cppHook}, 12530 modeProps: {fold: ["brace", "include"]} 12531 }); 12532 12533 def("text/x-nesc", { 12534 name: "clike",
12535 keywords: words(cKeywords + "as atomic async call command component components configuration event generic " + 12536 "implementation includes interface module new norace nx_struct nx_union post provides " + 12537 "signal task uses abstract extends"), 12538 types: words(cTypes), 12539 blockKeywords: words("case do else for if switch while struct"), 12540 atoms: words("null true false"), 12541 hooks: {"#": cppHook}, 12542 modeProps: {fold: ["brace", "include"]} 12543 }); 12544 12545 def("text/x-objectivec", { 12546 name: "clike", 12547 keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " + 12548 "inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"), 12549 types: words(cTypes), 12550 atoms: words("YES NO NULL NILL ON OFF true false"), 12551 hooks: { 12552 "@": function(stream) { 12553 stream.eatWhile(/[\w\$]/); 12554 return "keyword"; 12555 }, 12556 "#": cppHook, 12557 indent: function(_state, ctx, textAfter) { 12558 if (ctx.type == "statement" && /^@\w/.test(textAfter)) return ctx.indented 12559 } 12560 }, 12561 modeProps: {fold: "brace"} 12562 }); 12563 12564 def("text/x-squirrel", { 12565 name: "clike", 12566 keywords: words("base break clone continue const default delete enum extends function in class" + 12567 " foreach local resume return this throw typeof yield constructor instanceof static"), 12568 types: words(cTypes), 12569 blockKeywords: words("case catch class else for foreach if switch try while"), 12570 defKeywords: words("function local class"), 12571 typeFirstDefinitions: true, 12572 atoms: words("true false null"), 12573 hooks: {"#": cppHook}, 12574 modeProps: {fold: ["brace", "include"]} 12575 }); 12576 12577 // Ceylon Strings need to deal with interpolation 12578 var stringTokenizer = null; 12579 function tokenCeylonString(type) { 12580 return function(stream, state) { 12581 var escaped = false, next, end = false; 12582 while (!stream.eol()) { 12583 if (!escaped && stream.match('"') && 12584 (type == "single" || stream.match('""'))) { 12585 end = true; 12586 break; 12587 } 12588 if (!escaped && stream.match('``')) { 12589 stringTokenizer = tokenCeylonString(type); 12590 end = true; 12591 break; 12592 } 12593 next = stream.next(); 12594 escaped = type == "single" && !escaped && next == "\\"; 12595 } 12596 if (end) 12597 state.tokenize = null; 12598 return "string"; 12599 } 12600 } 12601 12602 def("text/x-ceylon", { 12603 name: "clike", 12604 keywords: words("abstracts alias assembly assert assign break case catch class continue dynamic else" + 12605 " exists extends finally for function given if import in interface is let module new" + 12606 " nonempty object of out outer package return satisfies super switch then this throw" + 12607 " try value void while"), 12608 types: function(word) { 12609 // In Ceylon all identifiers that start with an uppercase are types 12610 var first = word.charAt(0); 12611 return (first === first.toUpperCase() && first !== first.toLowerCase()); 12612 }, 12613 blockKeywords: words("case catch class dynamic else finally for function if interface module new object switch try while"), 12614 defKeywords: words("class dynamic function interface module object package value"), 12615 builtin: words("abstract actual aliased annotation by default deprecated doc final formal late license" + 12616 " native optional sealed see serializable shared suppressWarnings tagged throws variable"), 12617 isPunctuationChar: /[\[\]{}\(\),;\:\.`]/, 12618 isOperatorChar: /[+\-*&%=<>!?|^~:\/]/, 12619 isNumberChar: /[\d#$]/, 12620 multiLineStrings: true, 12621 typeFirstDefinitions: true, 12622 atoms: words("true false null larger smaller equal empty finished"), 12623 indentSwitch: false, 12624 styleDefs: false, 12625 hooks: { 12626 "@": function(stream) { 12627 stream.eatWhile(/[\w\$_]/); 12628 return "meta"; 12629 }, 12630 '"': function(stream, state) { 12631 state.tokenize = tokenCeylonString(stream.match('""') ? "triple" : "single"); 12632 return state.tokenize(stream, state); 12633 }, 12634 '`': function(stream, state) { 12635 if (!stringTokenizer || !stream.match('`')) return false;
12636 state.tokenize = stringTokenizer; 12637 stringTokenizer = null; 12638 return state.tokenize(stream, state); 12639 }, 12640 "'": function(stream) { 12641 stream.eatWhile(/[\w\$_\xa1-\uffff]/); 12642 return "atom"; 12643 }, 12644 token: function(_stream, state, style) { 12645 if ((style == "variable" || style == "variable-3") && 12646 state.prevToken == ".") { 12647 return "variable-2"; 12648 } 12649 } 12650 }, 12651 modeProps: { 12652 fold: ["brace", "import"], 12653 closeBrackets: {triples: '"'} 12654 } 12655 }); 12656 12657}); 12658 12659},{"../../lib/codemirror":30}],32:[function(_dereq_,module,exports){ 12660_dereq_('../modules/web.dom.iterable'); 12661_dereq_('../modules/es6.string.iterator'); 12662module.exports = _dereq_('../modules/core.get-iterator'); 12663},{"../modules/core.get-iterator":95,"../modules/es6.string.iterator":104,"../modules/web.dom.iterable":106}],33:[function(_dereq_,module,exports){ 12664_dereq_('../../modules/es6.object.assign'); 12665module.exports = _dereq_('../../modules/$.core').Object.assign; 12666},{"../../modules/$.core":49,"../../modules/es6.object.assign":97}],34:[function(_dereq_,module,exports){ 12667var $ = _dereq_('../../modules/$'); 12668module.exports = function create(P, D){ 12669 return $.create(P, D); 12670}; 12671},{"../../modules/$":71}],35:[function(_dereq_,module,exports){ 12672var $ = _dereq_('../../modules/$'); 12673module.exports = function defineProperty(it, key, desc){ 12674 return $.setDesc(it, key, desc); 12675}; 12676},{"../../modules/$":71}],36:[function(_dereq_,module,exports){ 12677var $ = _dereq_('../../modules/$'); 12678_dereq_('../../modules/es6.object.get-own-property-descriptor'); 12679module.exports = function getOwnPropertyDescriptor(it, key){ 12680 return $.getDesc(it, key); 12681}; 12682},{"../../modules/$":71,"../../modules/es6.object.get-own-property-descriptor":98}],37:[function(_dereq_,module,exports){ 12683_dereq_('../../modules/es6.object.keys'); 12684module.exports = _dereq_('../../modules/$.core').Object.keys; 12685},{"../../modules/$.core":49,"../../modules/es6.object.keys":99}],38:[function(_dereq_,module,exports){ 12686_dereq_('../../modules/es6.object.set-prototype-of'); 12687module.exports = _dereq_('../../modules/$.core').Object.setPrototypeOf; 12688},{"../../modules/$.core":49,"../../modules/es6.object.set-prototype-of":100}],39:[function(_dereq_,module,exports){ 12689_dereq_('../modules/es6.object.to-string'); 12690_dereq_('../modules/es6.string.iterator'); 12691_dereq_('../modules/web.dom.iterable'); 12692_dereq_('../modules/es6.promise'); 12693module.exports = _dereq_('../modules/$.core').Promise; 12694},{"../modules/$.core":49,"../modules/es6.object.to-string":101,"../modules/es6.promise":102,"../modules/es6.string.iterator":104,"../modules/web.dom.iterable":106}],40:[function(_dereq_,module,exports){ 12695_dereq_('../modules/es6.object.to-string'); 12696_dereq_('../modules/es6.string.iterator'); 12697_dereq_('../modules/web.dom.iterable'); 12698_dereq_('../modules/es6.set'); 12699_dereq_('../modules/es7.set.to-json'); 12700module.exports = _dereq_('../modules/$.core').Set; 12701},{"../modules/$.core":49,"../modules/es6.object.to-string":101,"../modules/es6.set":103,"../modules/es6.string.iterator":104,"../modules/es7.set.to-json":105,"../modules/web.dom.iterable":106}],41:[function(_dereq_,module,exports){ 12702module.exports = function(it){ 12703 if(typeof it != 'function')throw TypeError(it + ' is not a function!'); 12704 return it; 12705}; 12706},{}],42:[function(_dereq_,module,exports){ 12707module.exports = function(){ /* empty */ }; 12708},{}],43:[function(_dereq_,module,exports){ 12709var isObject = _dereq_('./$.is-object'); 12710module.exports = function(it){ 12711 if(!isObject(it))throw TypeError(it + ' is not an object!'); 12712 return it; 12713}; 12714},{"./$.is-object":64}],44:[function(_dereq_,module,exports){ 12715// getting tag from 19.1.3.6 Object.prototype.toString() 12716var cof = _dereq_('./$.cof') 12717 , TAG = _dereq_('./$.wks')('toStringTag') 12718 // ES3 wrong here 12719 , ARG = cof(function(){ return arguments; }()) == 'Arguments'; 12720 12721module.exports = function(it){ 12722 var O, T, B; 12723 return it === undefined ? 'Undefined' : it === null ? 'Null' 12724 // @@toStringTag case 12725 : typeof (T = (O = Object(it))[TAG]) == 'string' ? T 12726 // builtinTag case 12727 : ARG ? cof(O) 12728 // ES3 arguments fallback 12729 : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; 12730}; 12731},{"./$.cof":45,"./$.wks":93}],45:[function(_dereq_,module,exports){ 12732var toString = {}.toString; 12733 12734module.exports = function(it){ 12735 return toString.call(it).slice(8, -1); 12736}; 12737},{}],46:[function(_dereq_,module,exports){ 12738'use strict'; 12739var $ = _dereq_('./$') 12740 , hide = _dereq_('./$.hide') 12741 , redefineAll = _dereq_('./$.redefine-all') 12742 , ctx = _dereq_('./$.ctx') 12743 , strictNew = _dereq_('./$.strict-new') 12744 , defined = _dereq_('./$.defined') 12745 , forOf = _dereq_('./$.for-of') 12746 , $iterDefine = _dereq_('./$.iter-define') 12747 , step = _dereq_('./$.iter-step') 12748 , ID = _dereq_('./$.uid')('id') 12749 , $has = _dereq_('./$.has') 12750 , isObject = _dereq_('./$.is-object') 12751 , setSpecies = _dereq_('./$.set-species') 12752 , DESCRIPTORS = _dereq_('./$.descriptors') 12753 , isExtensible = Object.isExtensible || isObject 12754 , SIZE = DESCRIPTORS ? '_s' : 'size' 12755 , id = 0; 12756 12757var fastKey = function(it, create){ 12758 // return primitive with prefix 12759 if(!isObject(it))return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; 12760 if(!$has(it, ID)){ 12761 // can't set id to frozen object 12762 if(!isExtensible(it))return 'F'; 12763 // not necessary to add id 12764 if(!create)return 'E'; 12765 // add missing object id 12766 hide(it, ID, ++id); 12767 // return object id with prefix 12768 } return 'O' + it[ID]; 12769}; 12770 12771var getEntry = function(that, key){ 12772 // fast case 12773 var index = fastKey(key), entry; 12774 if(index !== 'F')return that._i[index]; 12775 // frozen object case 12776 for(entry = that._f; entry; entry = entry.n){ 12777 if(entry.k == key)return entry; 12778 } 12779}; 12780 12781module.exports = { 12782 getConstructor: function(wrapper, NAME, IS_MAP, ADDER){ 12783 var C = wrapper(function(that, iterable){
12784 strictNew(that, C, NAME); 12785 that._i = $.create(null); // index 12786 that._f = undefined; // first entry 12787 that._l = undefined; // last entry 12788 that[SIZE] = 0; // size 12789 if(iterable != undefined)forOf(iterable, IS_MAP, that[ADDER], that); 12790 }); 12791 redefineAll(C.prototype, { 12792 // 23.1.3.1 Map.prototype.clear() 12793 // 23.2.3.2 Set.prototype.clear() 12794 clear: function clear(){ 12795 for(var that = this, data = that._i, entry = that._f; entry; entry = entry.n){ 12796 entry.r = true; 12797 if(entry.p)entry.p = entry.p.n = undefined; 12798 delete data[entry.i]; 12799 } 12800 that._f = that._l = undefined; 12801 that[SIZE] = 0; 12802 }, 12803 // 23.1.3.3 Map.prototype.delete(key) 12804 // 23.2.3.4 Set.prototype.delete(value) 12805 'delete': function(key){ 12806 var that = this 12807 , entry = getEntry(that, key); 12808 if(entry){ 12809 var next = entry.n 12810 , prev = entry.p; 12811 delete that._i[entry.i]; 12812 entry.r = true; 12813 if(prev)prev.n = next; 12814 if(next)next.p = prev; 12815 if(that._f == entry)that._f = next; 12816 if(that._l == entry)that._l = prev; 12817 that[SIZE]--; 12818 } return !!entry; 12819 }, 12820 // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined) 12821 // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined) 12822 forEach: function forEach(callbackfn /*, that = undefined */){ 12823 var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3) 12824 , entry; 12825 while(entry = entry ? entry.n : this._f){ 12826 f(entry.v, entry.k, this); 12827 // revert to the last existing entry 12828 while(entry && entry.r)entry = entry.p; 12829 } 12830 }, 12831 // 23.1.3.7 Map.prototype.has(key) 12832 // 23.2.3.7 Set.prototype.has(value) 12833 has: function has(key){ 12834 return !!getEntry(this, key); 12835 } 12836 }); 12837 if(DESCRIPTORS)$.setDesc(C.prototype, 'size', { 12838 get: function(){ 12839 return defined(this[SIZE]); 12840 } 12841 }); 12842 return C; 12843 }, 12844 def: function(that, key, value){ 12845 var entry = getEntry(that, key) 12846 , prev, index; 12847 // change existing entry 12848 if(entry){ 12849 entry.v = value; 12850 // create new entry 12851 } else { 12852 that._l = entry = { 12853 i: index = fastKey(key, true), // <- index 12854 k: key, // <- key 12855 v: value, // <- value 12856 p: prev = that._l, // <- previous entry 12857 n: undefined, // <- next entry 12858 r: false // <- removed 12859 }; 12860 if(!that._f)that._f = entry; 12861 if(prev)prev.n = entry; 12862 that[SIZE]++; 12863 // add to index 12864 if(index !== 'F')that._i[index] = entry; 12865 } return that; 12866 }, 12867 getEntry: getEntry, 12868 setStrong: function(C, NAME, IS_MAP){ 12869 // add .keys, .values, .entries, [@@iterator] 12870 // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11 12871 $iterDefine(C, NAME, function(iterated, kind){ 12872 this._t = iterated; // target 12873 this._k = kind; // kind 12874 this._l = undefined; // previous 12875 }, function(){ 12876 var that = this 12877 , kind = that._k 12878 , entry = that._l; 12879 // revert to the last existing entry 12880 while(entry && entry.r)entry = entry.p; 12881 // get next entry 12882 if(!that._t || !(that._l = entry = entry ? entry.n : that._t._f)){ 12883 // or finish the iteration 12884 that._t = undefined; 12885 return step(1); 12886 } 12887 // return step by kind 12888 if(kind == 'keys' )return step(0, entry.k); 12889 if(kind == 'values')return step(0, entry.v); 12890 return step(0, [entry.k, entry.v]); 12891 }, IS_MAP ? 'entries' : 'values' , !IS_MAP, true); 12892 12893 // add [@@species], 23.1.2.2, 23.2.2.2 12894 setSpecies(NAME); 12895 } 12896}; 12897},{"./$":71,"./$.ctx":50,"./$.defined":51,"./$.descriptors":52,"./$.for-of":56,"./$.has":58,"./$.hide":59,"./$.is-object":64,"./$.iter-define":67,"./$.iter-step":69,"./$.redefine-all":77,"./$.set-species":81,"./$.strict-new":85,"./$.uid":92}],47:[function(_dereq_,module,exports){ 12898// https://github.com/DavidBruant/Map-Set.prototype.toJSON 12899var forOf = _dereq_('./$.for-of') 12900 , classof = _dereq_('./$.classof'); 12901module.exports = function(NAME){ 12902 return function toJSON(){ 12903 if(classof(this) != NAME)throw TypeError(NAME + "#toJSON isn't generic"); 12904 var arr = []; 12905 forOf(this, false, arr.push, arr); 12906 return arr; 12907 }; 12908}; 12909},{"./$.classof":44,"./$.for-of":56}],48:[function(_dereq_,module,exports){ 12910'use strict'; 12911var $ = _dereq_('./$') 12912 , global = _dereq_('./$.global') 12913 , $export = _dereq_('./$.export') 12914 , fails = _dereq_('./$.fails') 12915 , hide = _dereq_('./$.hide') 12916 , redefineAll = _dereq_('./$.redefine-all') 12917 , forOf = _dereq_('./$.for-of') 12918 , strictNew = _dereq_('./$.strict-new') 12919 , isObject = _dereq_('./$.is-object') 12920 , setToStringTag = _dereq_('./$.set-to-string-tag') 12921 , DESCRIPTORS = _dereq_('./$.descriptors'); 12922 12923module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){ 12924 var Base = global[NAME] 12925 , C = Base 12926 , ADDER = IS_MAP ? 'set' : 'add' 12927 , proto = C && C.prototype 12928 , O = {}; 12929 if(!DESCRIPTORS || typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function(){ 12930 new C().entries().next(); 12931 }))){ 12932 // create collection constructor 12933 C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER); 12934 redefineAll(C.prototype, methods); 12935 } else { 12936 C = wrapper(function(target, iterable){
12937 strictNew(target, C, NAME); 12938 target._c = new Base; 12939 if(iterable != undefined)forOf(iterable, IS_MAP, target[ADDER], target); 12940 }); 12941 $.each.call('add,clear,delete,forEach,get,has,set,keys,values,entries'.split(','),function(KEY){ 12942 var IS_ADDER = KEY == 'add' || KEY == 'set'; 12943 if(KEY in proto && !(IS_WEAK && KEY == 'clear'))hide(C.prototype, KEY, function(a, b){ 12944 if(!IS_ADDER && IS_WEAK && !isObject(a))return KEY == 'get' ? undefined : false; 12945 var result = this._c[KEY](a === 0 ? 0 : a, b); 12946 return IS_ADDER ? this : result; 12947 }); 12948 }); 12949 if('size' in proto)$.setDesc(C.prototype, 'size', { 12950 get: function(){ 12951 return this._c.size; 12952 } 12953 }); 12954 } 12955 12956 setToStringTag(C, NAME); 12957 12958 O[NAME] = C; 12959 $export($export.G + $export.W + $export.F, O); 12960 12961 if(!IS_WEAK)common.setStrong(C, NAME, IS_MAP); 12962 12963 return C; 12964}; 12965},{"./$":71,"./$.descriptors":52,"./$.export":54,"./$.fails":55,"./$.for-of":56,"./$.global":57,"./$.hide":59,"./$.is-object":64,"./$.redefine-all":77,"./$.set-to-string-tag":82,"./$.strict-new":85}],49:[function(_dereq_,module,exports){ 12966var core = module.exports = {version: '1.2.6'}; 12967if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef 12968},{}],50:[function(_dereq_,module,exports){ 12969// optional / simple context binding 12970var aFunction = _dereq_('./$.a-function'); 12971module.exports = function(fn, that, length){ 12972 aFunction(fn); 12973 if(that === undefined)return fn; 12974 switch(length){ 12975 case 1: return function(a){ 12976 return fn.call(that, a); 12977 }; 12978 case 2: return function(a, b){ 12979 return fn.call(that, a, b); 12980 }; 12981 case 3: return function(a, b, c){ 12982 return fn.call(that, a, b, c); 12983 }; 12984 } 12985 return function(/* ...args */){ 12986 return fn.apply(that, arguments); 12987 }; 12988}; 12989},{"./$.a-function":41}],51:[function(_dereq_,module,exports){ 12990// 7.2.1 RequireObjectCoercible(argument) 12991module.exports = function(it){ 12992 if(it == undefined)throw TypeError("Can't call method on " + it); 12993 return it; 12994}; 12995},{}],52:[function(_dereq_,module,exports){ 12996// Thank's IE8 for his funny defineProperty 12997module.exports = !_dereq_('./$.fails')(function(){ 12998 return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7; 12999}); 13000},{"./$.fails":55}],53:[function(_dereq_,module,exports){ 13001var isObject = _dereq_('./$.is-object') 13002 , document = _dereq_('./$.global').document 13003 // in old IE typeof document.createElement is 'object' 13004 , is = isObject(document) && isObject(document.createElement); 13005module.exports = function(it){ 13006 return is ? document.createElement(it) : {}; 13007}; 13008},{"./$.global":57,"./$.is-object":64}],54:[function(_dereq_,module,exports){ 13009var global = _dereq_('./$.global') 13010 , core = _dereq_('./$.core') 13011 , ctx = _dereq_('./$.ctx') 13012 , PROTOTYPE = 'prototype'; 13013 13014var $export = function(type, name, source){ 13015 var IS_FORCED = type & $export.F 13016 , IS_GLOBAL = type & $export.G 13017 , IS_STATIC = type & $export.S 13018 , IS_PROTO = type & $export.P 13019 , IS_BIND = type & $export.B 13020 , IS_WRAP = type & $export.W 13021 , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) 13022 , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] 13023 , key, own, out; 13024 if(IS_GLOBAL)source = name; 13025 for(key in source){ 13026 // contains in native 13027 own = !IS_FORCED && target && key in target; 13028 if(own && key in exports)continue; 13029 // export native or passed 13030 out = own ? target[key] : source[key]; 13031 // prevent global pollution for namespaces 13032 exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] 13033 // bind timers to global for call from export context 13034 : IS_BIND && own ? ctx(out, global) 13035 // wrap global constructors for prevent change them in library 13036 : IS_WRAP && target[key] == out ? (function(C){ 13037 var F = function(param){ 13038 return this instanceof C ? new C(param) : C(param); 13039 }; 13040 F[PROTOTYPE] = C[PROTOTYPE]; 13041 return F; 13042 // make static versions for prototype methods 13043 })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; 13044 if(IS_PROTO)(exports[PROTOTYPE] || (exports[PROTOTYPE] = {}))[key] = out; 13045 } 13046}; 13047// type bitmap 13048$export.F = 1; // forced 13049$export.G = 2; // global 13050$export.S = 4; // static 13051$export.P = 8; // proto
13052$export.B = 16; // bind 13053$export.W = 32; // wrap 13054module.exports = $export; 13055},{"./$.core":49,"./$.ctx":50,"./$.global":57}],55:[function(_dereq_,module,exports){ 13056module.exports = function(exec){ 13057 try { 13058 return !!exec(); 13059 } catch(e){ 13060 return true; 13061 } 13062}; 13063},{}],56:[function(_dereq_,module,exports){ 13064var ctx = _dereq_('./$.ctx') 13065 , call = _dereq_('./$.iter-call') 13066 , isArrayIter = _dereq_('./$.is-array-iter') 13067 , anObject = _dereq_('./$.an-object') 13068 , toLength = _dereq_('./$.to-length') 13069 , getIterFn = _dereq_('./core.get-iterator-method'); 13070module.exports = function(iterable, entries, fn, that){ 13071 var iterFn = getIterFn(iterable) 13072 , f = ctx(fn, that, entries ? 2 : 1) 13073 , index = 0 13074 , length, step, iterator; 13075 if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!'); 13076 // fast case for arrays with default iterator 13077 if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){ 13078 entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); 13079 } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){ 13080 call(iterator, f, step.value, entries); 13081 } 13082}; 13083},{"./$.an-object":43,"./$.ctx":50,"./$.is-array-iter":63,"./$.iter-call":65,"./$.to-length":90,"./core.get-iterator-method":94}],57:[function(_dereq_,module,exports){ 13084// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 13085var global = module.exports = typeof window != 'undefined' && window.Math == Math 13086 ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); 13087if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef 13088},{}],58:[function(_dereq_,module,exports){ 13089var hasOwnProperty = {}.hasOwnProperty; 13090module.exports = function(it, key){ 13091 return hasOwnProperty.call(it, key); 13092}; 13093},{}],59:[function(_dereq_,module,exports){ 13094var $ = _dereq_('./$') 13095 , createDesc = _dereq_('./$.property-desc'); 13096module.exports = _dereq_('./$.descriptors') ? function(object, key, value){ 13097 return $.setDesc(object, key, createDesc(1, value)); 13098} : function(object, key, value){ 13099 object[key] = value; 13100 return object; 13101}; 13102},{"./$":71,"./$.descriptors":52,"./$.property-desc":76}],60:[function(_dereq_,module,exports){ 13103module.exports = _dereq_('./$.global').document && document.documentElement; 13104},{"./$.global":57}],61:[function(_dereq_,module,exports){ 13105// fast apply, http://jsperf.lnkit.com/fast-apply/5 13106module.exports = function(fn, args, that){ 13107 var un = that === undefined; 13108 switch(args.length){ 13109 case 0: return un ? fn() 13110 : fn.call(that); 13111 case 1: return un ? fn(args[0]) 13112 : fn.call(that, args[0]); 13113 case 2: return un ? fn(args[0], args[1]) 13114 : fn.call(that, args[0], args[1]); 13115 case 3: return un ? fn(args[0], args[1], args[2]) 13116 : fn.call(that, args[0], args[1], args[2]); 13117 case 4: return un ? fn(args[0], args[1], args[2], args[3]) 13118 : fn.call(that, args[0], args[1], args[2], args[3]); 13119 } return fn.apply(that, args); 13120}; 13121},{}],62:[function(_dereq_,module,exports){ 13122// fallback for non-array-like ES3 and non-enumerable old V8 strings 13123var cof = _dereq_('./$.cof'); 13124module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){ 13125 return cof(it) == 'String' ? it.split('') : Object(it); 13126}; 13127},{"./$.cof":45}],63:[function(_dereq_,module,exports){ 13128// check on default Array iterator 13129var Iterators = _dereq_('./$.iterators') 13130 , ITERATOR = _dereq_('./$.wks')('iterator') 13131 , ArrayProto = Array.prototype; 13132 13133module.exports = function(it){ 13134 return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); 13135}; 13136},{"./$.iterators":70,"./$.wks":93}],64:[function(_dereq_,module,exports){ 13137module.exports = function(it){ 13138 return typeof it === 'object' ? it !== null : typeof it === 'function'; 13139}; 13140},{}],65:[function(_dereq_,module,exports){ 13141// call something on iterator step with safe closing on error 13142var anObject = _dereq_('./$.an-object'); 13143module.exports = function(iterator, fn, value, entries){ 13144 try { 13145 return entries ? fn(anObject(value)[0], value[1]) : fn(value); 13146 // 7.4.6 IteratorClose(iterator, completion) 13147 } catch(e){ 13148 var ret = iterator['return']; 13149 if(ret !== undefined)anObject(ret.call(iterator)); 13150 throw e; 13151 } 13152}; 13153},{"./$.an-object":43}],66:[function(_dereq_,module,exports){ 13154'use strict'; 13155var $ = _dereq_('./$') 13156 , descriptor = _dereq_('./$.property-desc') 13157 , setToStringTag = _dereq_('./$.set-to-string-tag') 13158 , IteratorPrototype = {}; 13159 13160// 25.1.2.1.1 %IteratorPrototype%[@@iterator]() 13161_dereq_('./$.hide')(IteratorPrototype, _dereq_('./$.wks')('iterator'), function(){ return this; }); 13162 13163module.exports = function(Constructor, NAME, next){ 13164 Constructor.prototype = $.create(IteratorPrototype, {next: descriptor(1, next)}); 13165 setToStringTag(Constructor, NAME + ' Iterator'); 13166}; 13167},{"./$":71,"./$.hide":59,"./$.property-desc":76,"./$.set-to-string-tag":82,"./$.wks":93}],67:[function(_dereq_,module,exports){ 13168'use strict'; 13169var LIBRARY = _dereq_('./$.library') 13170 , $export = _dereq_('./$.export') 13171 , redefine = _dereq_('./$.redefine') 13172 , hide = _dereq_('./$.hide') 13173 , has = _dereq_('./$.has') 13174 , Iterators = _dereq_('./$.iterators') 13175 , $iterCreate = _dereq_('./$.iter-create') 13176 , setToStringTag = _dereq_('./$.set-to-string-tag') 13177 , getProto = _dereq_('./$').getProto 13178 , ITERATOR = _dereq_('./$.wks')('iterator') 13179 , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next` 13180 , FF_ITERATOR = '@@iterator' 13181 , KEYS = 'keys' 13182 , VALUES = 'values'; 13183 13184var returnThis = function(){ return this; }; 13185 13186module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED){ 13187 $iterCreate(Constructor, NAME, next); 13188 var getMethod = function(kind){ 13189 if(!BUGGY && kind in proto)return proto[kind]; 13190 switch(kind){ 13191 case KEYS: return function keys(){ return new Constructor(this, kind); }; 13192 case VALUES: return function values(){ return new Constructor(this, kind); }; 13193 } return function entries(){ return new Constructor(this, kind); }; 13194 }; 13195 var TAG = NAME + ' Iterator' 13196 , DEF_VALUES = DEFAULT == VALUES 13197 , VALUES_BUG = false 13198 , proto = Base.prototype 13199 , $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT] 13200 , $default = $native || getMethod(DEFAULT) 13201 , methods, key; 13202 // Fix native 13203 if($native){ 13204 var IteratorPrototype = getProto($default.call(new Base)); 13205 // Set @@toStringTag to native iterators 13206 setToStringTag(IteratorPrototype, TAG, true); 13207 // FF fix 13208 if(!LIBRARY && has(proto, FF_ITERATOR))hide(IteratorPrototype, ITERATOR, returnThis); 13209 // fix Array#{values, @@iterator}.name in V8 / FF 13210 if(DEF_VALUES && $native.name !== VALUES){ 13211 VALUES_BUG = true; 13212 $default = function values(){ return $native.call(this); }; 13213 } 13214 } 13215 // Define iterator 13216 if((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])){ 13217 hide(proto, ITERATOR, $default); 13218 } 13219 // Plug for library 13220 Iterators[NAME] = $default; 13221 Iterators[TAG] = returnThis; 13222 if(DEFAULT){ 13223 methods = { 13224 values: DEF_VALUES ? $default : getMethod(VALUES), 13225 keys: IS_SET ? $default : getMethod(KEYS),
13226 entries: !DEF_VALUES ? $default : getMethod('entries') 13227 }; 13228 if(FORCED)for(key in methods){ 13229 if(!(key in proto))redefine(proto, key, methods[key]); 13230 } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); 13231 } 13232 return methods; 13233}; 13234},{"./$":71,"./$.export":54,"./$.has":58,"./$.hide":59,"./$.iter-create":66,"./$.iterators":70,"./$.library":72,"./$.redefine":78,"./$.set-to-string-tag":82,"./$.wks":93}],68:[function(_dereq_,module,exports){ 13235var ITERATOR = _dereq_('./$.wks')('iterator') 13236 , SAFE_CLOSING = false; 13237 13238try { 13239 var riter = [7][ITERATOR](); 13240 riter['return'] = function(){ SAFE_CLOSING = true; }; 13241 Array.from(riter, function(){ throw 2; }); 13242} catch(e){ /* empty */ } 13243 13244module.exports = function(exec, skipClosing){ 13245 if(!skipClosing && !SAFE_CLOSING)return false; 13246 var safe = false; 13247 try { 13248 var arr = [7] 13249 , iter = arr[ITERATOR](); 13250 iter.next = function(){ return {done: safe = true}; }; 13251 arr[ITERATOR] = function(){ return iter; }; 13252 exec(arr); 13253 } catch(e){ /* empty */ } 13254 return safe; 13255}; 13256},{"./$.wks":93}],69:[function(_dereq_,module,exports){ 13257module.exports = function(done, value){ 13258 return {value: value, done: !!done}; 13259}; 13260},{}],70:[function(_dereq_,module,exports){ 13261module.exports = {}; 13262},{}],71:[function(_dereq_,module,exports){ 13263var $Object = Object; 13264module.exports = { 13265 create: $Object.create, 13266 getProto: $Object.getPrototypeOf, 13267 isEnum: {}.propertyIsEnumerable, 13268 getDesc: $Object.getOwnPropertyDescriptor, 13269 setDesc: $Object.defineProperty, 13270 setDescs: $Object.defineProperties, 13271 getKeys: $Object.keys, 13272 getNames: $Object.getOwnPropertyNames, 13273 getSymbols: $Object.getOwnPropertySymbols, 13274 each: [].forEach 13275}; 13276},{}],72:[function(_dereq_,module,exports){ 13277module.exports = true; 13278},{}],73:[function(_dereq_,module,exports){ 13279var global = _dereq_('./$.global') 13280 , macrotask = _dereq_('./$.task').set 13281 , Observer = global.MutationObserver || global.WebKitMutationObserver 13282 , process = global.process 13283 , Promise = global.Promise 13284 , isNode = _dereq_('./$.cof')(process) == 'process' 13285 , head, last, notify; 13286 13287var flush = function(){ 13288 var parent, domain, fn; 13289 if(isNode && (parent = process.domain)){ 13290 process.domain = null; 13291 parent.exit(); 13292 } 13293 while(head){ 13294 domain = head.domain; 13295 fn = head.fn; 13296 if(domain)domain.enter(); 13297 fn(); // <- currently we use it only for Promise - try / catch not required 13298 if(domain)domain.exit(); 13299 head = head.next; 13300 } last = undefined; 13301 if(parent)parent.enter(); 13302}; 13303 13304// Node.js 13305if(isNode){ 13306 notify = function(){ 13307 process.nextTick(flush); 13308 }; 13309// browsers with MutationObserver 13310} else if(Observer){ 13311 var toggle = 1 13312 , node = document.createTextNode(''); 13313 new Observer(flush).observe(node, {characterData: true}); // eslint-disable-line no-new 13314 notify = function(){ 13315 node.data = toggle = -toggle; 13316 }; 13317// environments with maybe non-completely correct, but existent Promise 13318} else if(Promise && Promise.resolve){ 13319 notify = function(){ 13320 Promise.resolve().then(flush); 13321 }; 13322// for other environments - macrotask based on: 13323// - setImmediate 13324// - MessageChannel 13325// - window.postMessag 13326// - onreadystatechange 13327// - setTimeout 13328} else { 13329 notify = function(){ 13330 // strange IE + webpack dev server bug - use .call(global) 13331 macrotask.call(global, flush); 13332 }; 13333} 13334 13335module.exports = function asap(fn){ 13336 var task = {fn: fn, next: undefined, domain: isNode && process.domain}; 13337 if(last)last.next = task; 13338 if(!head){ 13339 head = task; 13340 notify(); 13341 } last = task; 13342}; 13343},{"./$.cof":45,"./$.global":57,"./$.task":87}],74:[function(_dereq_,module,exports){ 13344// 19.1.2.1 Object.assign(target, source, ...) 13345var $ = _dereq_('./$') 13346 , toObject = _dereq_('./$.to-object') 13347 , IObject = _dereq_('./$.iobject'); 13348 13349// should work with symbols and should have deterministic property order (V8 bug) 13350module.exports = _dereq_('./$.fails')(function(){ 13351 var a = Object.assign 13352 , A = {} 13353 , B = {} 13354 , S = Symbol() 13355 , K = 'abcdefghijklmnopqrst'; 13356 A[S] = 7; 13357 K.split('').forEach(function(k){ B[k] = k; }); 13358 return a({}, A)[S] != 7 || Object.keys(a({}, B)).join('') != K; 13359}) ? function assign(target, source){ // eslint-disable-line no-unused-vars 13360 var T = toObject(target) 13361 , $$ = arguments 13362 , $$len = $$.length 13363 , index = 1 13364 , getKeys = $.getKeys 13365 , getSymbols = $.getSymbols 13366 , isEnum = $.isEnum; 13367 while($$len > index){ 13368 var S = IObject($$[index++]) 13369 , keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S) 13370 , length = keys.length 13371 , j = 0 13372 , key; 13373 while(length > j)if(isEnum.call(S, key = keys[j++]))T[key] = S[key]; 13374 } 13375 return T; 13376} : Object.assign; 13377},{"./$":71,"./$.fails":55,"./$.iobject":62,"./$.to-object":91}],75:[function(_dereq_,module,exports){
13378// most Object methods by ES6 should accept primitives 13379var $export = _dereq_('./$.export') 13380 , core = _dereq_('./$.core') 13381 , fails = _dereq_('./$.fails'); 13382module.exports = function(KEY, exec){ 13383 var fn = (core.Object || {})[KEY] || Object[KEY] 13384 , exp = {}; 13385 exp[KEY] = exec(fn); 13386 $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp); 13387}; 13388},{"./$.core":49,"./$.export":54,"./$.fails":55}],76:[function(_dereq_,module,exports){ 13389module.exports = function(bitmap, value){ 13390 return { 13391 enumerable : !(bitmap & 1), 13392 configurable: !(bitmap & 2), 13393 writable : !(bitmap & 4), 13394 value : value 13395 }; 13396}; 13397},{}],77:[function(_dereq_,module,exports){ 13398var redefine = _dereq_('./$.redefine'); 13399module.exports = function(target, src){ 13400 for(var key in src)redefine(target, key, src[key]); 13401 return target; 13402}; 13403},{"./$.redefine":78}],78:[function(_dereq_,module,exports){ 13404module.exports = _dereq_('./$.hide'); 13405},{"./$.hide":59}],79:[function(_dereq_,module,exports){ 13406// 7.2.9 SameValue(x, y) 13407module.exports = Object.is || function is(x, y){ 13408 return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y; 13409}; 13410},{}],80:[function(_dereq_,module,exports){ 13411// Works with __proto__ only. Old v8 can't work with null proto objects. 13412/* eslint-disable no-proto */ 13413var getDesc = _dereq_('./$').getDesc 13414 , isObject = _dereq_('./$.is-object') 13415 , anObject = _dereq_('./$.an-object'); 13416var check = function(O, proto){ 13417 anObject(O); 13418 if(!isObject(proto) && proto !== null)throw TypeError(proto + ": can't set as prototype!"); 13419}; 13420module.exports = { 13421 set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line 13422 function(test, buggy, set){ 13423 try { 13424 set = _dereq_('./$.ctx')(Function.call, getDesc(Object.prototype, '__proto__').set, 2); 13425 set(test, []); 13426 buggy = !(test instanceof Array); 13427 } catch(e){ buggy = true; } 13428 return function setPrototypeOf(O, proto){ 13429 check(O, proto); 13430 if(buggy)O.__proto__ = proto; 13431 else set(O, proto); 13432 return O; 13433 }; 13434 }({}, false) : undefined), 13435 check: check 13436}; 13437},{"./$":71,"./$.an-object":43,"./$.ctx":50,"./$.is-object":64}],81:[function(_dereq_,module,exports){ 13438'use strict'; 13439var core = _dereq_('./$.core') 13440 , $ = _dereq_('./$') 13441 , DESCRIPTORS = _dereq_('./$.descriptors') 13442 , SPECIES = _dereq_('./$.wks')('species'); 13443 13444module.exports = function(KEY){ 13445 var C = core[KEY]; 13446 if(DESCRIPTORS && C && !C[SPECIES])$.setDesc(C, SPECIES, { 13447 configurable: true, 13448 get: function(){ return this; } 13449 }); 13450}; 13451},{"./$":71,"./$.core":49,"./$.descriptors":52,"./$.wks":93}],82:[function(_dereq_,module,exports){ 13452var def = _dereq_('./$').setDesc 13453 , has = _dereq_('./$.has') 13454 , TAG = _dereq_('./$.wks')('toStringTag'); 13455 13456module.exports = function(it, tag, stat){ 13457 if(it && !has(it = stat ? it : it.prototype, TAG))def(it, TAG, {configurable: true, value: tag}); 13458}; 13459},{"./$":71,"./$.has":58,"./$.wks":93}],83:[function(_dereq_,module,exports){ 13460var global = _dereq_('./$.global') 13461 , SHARED = '__core-js_shared__' 13462 , store = global[SHARED] || (global[SHARED] = {}); 13463module.exports = function(key){ 13464 return store[key] || (store[key] = {}); 13465}; 13466},{"./$.global":57}],84:[function(_dereq_,module,exports){ 13467// 7.3.20 SpeciesConstructor(O, defaultConstructor) 13468var anObject = _dereq_('./$.an-object') 13469 , aFunction = _dereq_('./$.a-function') 13470 , SPECIES = _dereq_('./$.wks')('species'); 13471module.exports = function(O, D){ 13472 var C = anObject(O).constructor, S; 13473 return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); 13474}; 13475},{"./$.a-function":41,"./$.an-object":43,"./$.wks":93}],85:[function(_dereq_,module,exports){ 13476module.exports = function(it, Constructor, name){ 13477 if(!(it instanceof Constructor))throw TypeError(name + ": use the 'new' operator!"); 13478 return it; 13479}; 13480},{}],86:[function(_dereq_,module,exports){ 13481var toInteger = _dereq_('./$.to-integer') 13482 , defined = _dereq_('./$.defined'); 13483// true -> String#at 13484// false -> String#codePointAt 13485module.exports = function(TO_STRING){ 13486 return function(that, pos){ 13487 var s = String(defined(that)) 13488 , i = toInteger(pos) 13489 , l = s.length 13490 , a, b; 13491 if(i < 0 || i >= l)return TO_STRING ? '' : undefined;
vendor: 6,411 bytes, lines 13492-13668
13492 a = s.charCodeAt(i); 13493 return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff 13494 ? TO_STRING ? s.charAt(i) : a 13495 : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; 13496 }; 13497}; 13498},{"./$.defined":51,"./$.to-integer":88}],87:[function(_dereq_,module,exports){ 13499var ctx = _dereq_('./$.ctx') 13500 , invoke = _dereq_('./$.invoke') 13501 , html = _dereq_('./$.html') 13502 , cel = _dereq_('./$.dom-create') 13503 , global = _dereq_('./$.global') 13504 , process = global.process 13505 , setTask = global.setImmediate 13506 , clearTask = global.clearImmediate 13507 , MessageChannel = global.MessageChannel 13508 , counter = 0 13509 , queue = {} 13510 , ONREADYSTATECHANGE = 'onreadystatechange' 13511 , defer, channel, port; 13512var run = function(){ 13513 var id = +this; 13514 if(queue.hasOwnProperty(id)){ 13515 var fn = queue[id]; 13516 delete queue[id]; 13517 fn(); 13518 } 13519}; 13520var listner = function(event){ 13521 run.call(event.data); 13522}; 13523// Node.js 0.9+ & IE10+ has setImmediate, otherwise: 13524if(!setTask || !clearTask){ 13525 setTask = function setImmediate(fn){ 13526 var args = [], i = 1; 13527 while(arguments.length > i)args.push(arguments[i++]); 13528 queue[++counter] = function(){ 13529 invoke(typeof fn == 'function' ? fn : Function(fn), args); 13530 }; 13531 defer(counter); 13532 return counter; 13533 }; 13534 clearTask = function clearImmediate(id){ 13535 delete queue[id]; 13536 }; 13537 // Node.js 0.8- 13538 if(_dereq_('./$.cof')(process) == 'process'){ 13539 defer = function(id){ 13540 process.nextTick(ctx(run, id, 1)); 13541 }; 13542 // Browsers with MessageChannel, includes WebWorkers 13543 } else if(MessageChannel){ 13544 channel = new MessageChannel; 13545 port = channel.port2; 13546 channel.port1.onmessage = listner; 13547 defer = ctx(port.postMessage, port, 1); 13548 // Browsers with postMessage, skip WebWorkers 13549 // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' 13550 } else if(global.addEventListener && typeof postMessage == 'function' && !global.importScripts){ 13551 defer = function(id){ 13552 global.postMessage(id + '', '*'); 13553 }; 13554 global.addEventListener('message', listner, false); 13555 // IE8- 13556 } else if(ONREADYSTATECHANGE in cel('script')){ 13557 defer = function(id){ 13558 html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function(){ 13559 html.removeChild(this); 13560 run.call(id); 13561 }; 13562 }; 13563 // Rest old browsers 13564 } else { 13565 defer = function(id){ 13566 setTimeout(ctx(run, id, 1), 0); 13567 }; 13568 } 13569} 13570module.exports = { 13571 set: setTask, 13572 clear: clearTask 13573}; 13574},{"./$.cof":45,"./$.ctx":50,"./$.dom-create":53,"./$.global":57,"./$.html":60,"./$.invoke":61}],88:[function(_dereq_,module,exports){ 13575// 7.1.4 ToInteger 13576var ceil = Math.ceil 13577 , floor = Math.floor; 13578module.exports = function(it){ 13579 return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); 13580}; 13581},{}],89:[function(_dereq_,module,exports){ 13582// to indexed object, toObject with fallback for non-array-like ES3 strings 13583var IObject = _dereq_('./$.iobject') 13584 , defined = _dereq_('./$.defined'); 13585module.exports = function(it){ 13586 return IObject(defined(it)); 13587}; 13588},{"./$.defined":51,"./$.iobject":62}],90:[function(_dereq_,module,exports){ 13589// 7.1.15 ToLength 13590var toInteger = _dereq_('./$.to-integer') 13591 , min = Math.min; 13592module.exports = function(it){ 13593 return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 13594}; 13595},{"./$.to-integer":88}],91:[function(_dereq_,module,exports){ 13596// 7.1.13 ToObject(argument) 13597var defined = _dereq_('./$.defined'); 13598module.exports = function(it){ 13599 return Object(defined(it)); 13600}; 13601},{"./$.defined":51}],92:[function(_dereq_,module,exports){ 13602var id = 0 13603 , px = Math.random(); 13604module.exports = function(key){ 13605 return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); 13606}; 13607},{}],93:[function(_dereq_,module,exports){ 13608var store = _dereq_('./$.shared')('wks') 13609 , uid = _dereq_('./$.uid') 13610 , Symbol = _dereq_('./$.global').Symbol; 13611module.exports = function(name){ 13612 return store[name] || (store[name] = 13613 Symbol && Symbol[name] || (Symbol || uid)('Symbol.' + name)); 13614}; 13615},{"./$.global":57,"./$.shared":83,"./$.uid":92}],94:[function(_dereq_,module,exports){ 13616var classof = _dereq_('./$.classof') 13617 , ITERATOR = _dereq_('./$.wks')('iterator') 13618 , Iterators = _dereq_('./$.iterators'); 13619module.exports = _dereq_('./$.core').getIteratorMethod = function(it){ 13620 if(it != undefined)return it[ITERATOR] 13621 || it['@@iterator'] 13622 || Iterators[classof(it)]; 13623}; 13624},{"./$.classof":44,"./$.core":49,"./$.iterators":70,"./$.wks":93}],95:[function(_dereq_,module,exports){ 13625var anObject = _dereq_('./$.an-object') 13626 , get = _dereq_('./core.get-iterator-method'); 13627module.exports = _dereq_('./$.core').getIterator = function(it){ 13628 var iterFn = get(it); 13629 if(typeof iterFn != 'function')throw TypeError(it + ' is not iterable!'); 13630 return anObject(iterFn.call(it)); 13631}; 13632},{"./$.an-object":43,"./$.core":49,"./core.get-iterator-method":94}],96:[function(_dereq_,module,exports){ 13633'use strict'; 13634var addToUnscopables = _dereq_('./$.add-to-unscopables') 13635 , step = _dereq_('./$.iter-step') 13636 , Iterators = _dereq_('./$.iterators') 13637 , toIObject = _dereq_('./$.to-iobject'); 13638 13639// 22.1.3.4 Array.prototype.entries() 13640// 22.1.3.13 Array.prototype.keys() 13641// 22.1.3.29 Array.prototype.values() 13642// 22.1.3.30 Array.prototype[@@iterator]() 13643module.exports = _dereq_('./$.iter-define')(Array, 'Array', function(iterated, kind){ 13644 this._t = toIObject(iterated); // target 13645 this._i = 0; // next index 13646 this._k = kind; // kind 13647// 22.1.5.2.1 %ArrayIteratorPrototype%.next() 13648}, function(){ 13649 var O = this._t 13650 , kind = this._k 13651 , index = this._i++; 13652 if(!O || index >= O.length){ 13653 this._t = undefined; 13654 return step(1); 13655 } 13656 if(kind == 'keys' )return step(0, index); 13657 if(kind == 'values')return step(0, O[index]); 13658 return step(0, [index, O[index]]); 13659}, 'values'); 13660 13661// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) 13662Iterators.Arguments = Iterators.Array; 13663 13664addToUnscopables('keys'); 13665addToUnscopables('values'); 13666addToUnscopables('entries'); 13667},{"./$.add-to-unscopables":42,"./$.iter-define":67,"./$.iter-step":69,"./$.iterators":70,"./$.to-iobject":89}],97:[function(_dereq_,module,exports){ 13668// 19.1.3.1 Object.assign(target, source)
13669var $export = _dereq_('./$.export'); 13670 13671$export($export.S + $export.F, 'Object', {assign: _dereq_('./$.object-assign')}); 13672},{"./$.export":54,"./$.object-assign":74}],98:[function(_dereq_,module,exports){ 13673// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) 13674var toIObject = _dereq_('./$.to-iobject'); 13675 13676_dereq_('./$.object-sap')('getOwnPropertyDescriptor', function($getOwnPropertyDescriptor){ 13677 return function getOwnPropertyDescriptor(it, key){ 13678 return $getOwnPropertyDescriptor(toIObject(it), key); 13679 }; 13680}); 13681},{"./$.object-sap":75,"./$.to-iobject":89}],99:[function(_dereq_,module,exports){ 13682// 19.1.2.14 Object.keys(O) 13683var toObject = _dereq_('./$.to-object'); 13684 13685_dereq_('./$.object-sap')('keys', function($keys){ 13686 return function keys(it){ 13687 return $keys(toObject(it)); 13688 }; 13689}); 13690},{"./$.object-sap":75,"./$.to-object":91}],100:[function(_dereq_,module,exports){ 13691// 19.1.3.19 Object.setPrototypeOf(O, proto) 13692var $export = _dereq_('./$.export'); 13693$export($export.S, 'Object', {setPrototypeOf: _dereq_('./$.set-proto').set}); 13694},{"./$.export":54,"./$.set-proto":80}],101:[function(_dereq_,module,exports){ 13695 13696},{}],102:[function(_dereq_,module,exports){ 13697'use strict'; 13698var $ = _dereq_('./$') 13699 , LIBRARY = _dereq_('./$.library') 13700 , global = _dereq_('./$.global') 13701 , ctx = _dereq_('./$.ctx') 13702 , classof = _dereq_('./$.classof') 13703 , $export = _dereq_('./$.export') 13704 , isObject = _dereq_('./$.is-object') 13705 , anObject = _dereq_('./$.an-object') 13706 , aFunction = _dereq_('./$.a-function') 13707 , strictNew = _dereq_('./$.strict-new') 13708 , forOf = _dereq_('./$.for-of') 13709 , setProto = _dereq_('./$.set-proto').set 13710 , same = _dereq_('./$.same-value') 13711 , SPECIES = _dereq_('./$.wks')('species') 13712 , speciesConstructor = _dereq_('./$.species-constructor') 13713 , asap = _dereq_('./$.microtask') 13714 , PROMISE = 'Promise' 13715 , process = global.process 13716 , isNode = classof(process) == 'process' 13717 , P = global[PROMISE] 13718 , empty = function(){ /* empty */ } 13719 , Wrapper; 13720 13721var testResolve = function(sub){ 13722 var test = new P(empty), promise; 13723 if(sub)test.constructor = function(exec){ 13724 exec(empty, empty); 13725 }; 13726 (promise = P.resolve(test))['catch'](empty); 13727 return promise === test; 13728}; 13729 13730var USE_NATIVE = function(){ 13731 var works = false; 13732 function P2(x){ 13733 var self = new P(x); 13734 setProto(self, P2.prototype); 13735 return self; 13736 } 13737 try { 13738 works = P && P.resolve && testResolve(); 13739 setProto(P2, P); 13740 P2.prototype = $.create(P.prototype, {constructor: {value: P2}}); 13741 // actual Firefox has broken subclass support, test that 13742 if(!(P2.resolve(5).then(function(){}) instanceof P2)){ 13743 works = false; 13744 } 13745 // actual V8 bug, https://code.google.com/p/v8/issues/detail?id=4162 13746 if(works && _dereq_('./$.descriptors')){ 13747 var thenableThenGotten = false; 13748 P.resolve($.setDesc({}, 'then', { 13749 get: function(){ thenableThenGotten = true; } 13750 })); 13751 works = thenableThenGotten; 13752 } 13753 } catch(e){ works = false; } 13754 return works; 13755}(); 13756 13757// helpers 13758var sameConstructor = function(a, b){ 13759 // library wrapper special case 13760 if(LIBRARY && a === P && b === Wrapper)return true; 13761 return same(a, b); 13762}; 13763var getConstructor = function(C){ 13764 var S = anObject(C)[SPECIES]; 13765 return S != undefined ? S : C; 13766}; 13767var isThenable = function(it){ 13768 var then; 13769 return isObject(it) && typeof (then = it.then) == 'function' ? then : false; 13770}; 13771var PromiseCapability = function(C){ 13772 var resolve, reject; 13773 this.promise = new C(function($$resolve, $$reject){ 13774 if(resolve !== undefined || reject !== undefined)throw TypeError('Bad Promise constructor'); 13775 resolve = $$resolve; 13776 reject = $$reject; 13777 }); 13778 this.resolve = aFunction(resolve), 13779 this.reject = aFunction(reject) 13780}; 13781var perform = function(exec){ 13782 try { 13783 exec(); 13784 } catch(e){ 13785 return {error: e}; 13786 } 13787}; 13788var notify = function(record, isReject){ 13789 if(record.n)return; 13790 record.n = true; 13791 var chain = record.c; 13792 asap(function(){ 13793 var value = record.v 13794 , ok = record.s == 1 13795 , i = 0; 13796 var run = function(reaction){ 13797 var handler = ok ? reaction.ok : reaction.fail 13798 , resolve = reaction.resolve 13799 , reject = reaction.reject 13800 , result, then;
13801 try { 13802 if(handler){ 13803 if(!ok)record.h = true; 13804 result = handler === true ? value : handler(value); 13805 if(result === reaction.promise){ 13806 reject(TypeError('Promise-chain cycle')); 13807 } else if(then = isThenable(result)){ 13808 then.call(result, resolve, reject); 13809 } else resolve(result); 13810 } else reject(value); 13811 } catch(e){ 13812 reject(e); 13813 } 13814 }; 13815 while(chain.length > i)run(chain[i++]); // variable length - can't use forEach 13816 chain.length = 0; 13817 record.n = false; 13818 if(isReject)setTimeout(function(){ 13819 var promise = record.p 13820 , handler, console; 13821 if(isUnhandled(promise)){ 13822 if(isNode){ 13823 process.emit('unhandledRejection', value, promise); 13824 } else if(handler = global.onunhandledrejection){ 13825 handler({promise: promise, reason: value}); 13826 } else if((console = global.console) && console.error){ 13827 console.error('Unhandled promise rejection', value); 13828 } 13829 } record.a = undefined; 13830 }, 1); 13831 }); 13832}; 13833var isUnhandled = function(promise){ 13834 var record = promise._d 13835 , chain = record.a || record.c 13836 , i = 0 13837 , reaction; 13838 if(record.h)return false; 13839 while(chain.length > i){ 13840 reaction = chain[i++]; 13841 if(reaction.fail || !isUnhandled(reaction.promise))return false; 13842 } return true; 13843}; 13844var $reject = function(value){ 13845 var record = this; 13846 if(record.d)return; 13847 record.d = true; 13848 record = record.r || record; // unwrap 13849 record.v = value; 13850 record.s = 2; 13851 record.a = record.c.slice(); 13852 notify(record, true); 13853}; 13854var $resolve = function(value){ 13855 var record = this 13856 , then; 13857 if(record.d)return; 13858 record.d = true; 13859 record = record.r || record; // unwrap 13860 try { 13861 if(record.p === value)throw TypeError("Promise can't be resolved itself"); 13862 if(then = isThenable(value)){ 13863 asap(function(){ 13864 var wrapper = {r: record, d: false}; // wrap 13865 try { 13866 then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); 13867 } catch(e){ 13868 $reject.call(wrapper, e); 13869 } 13870 }); 13871 } else { 13872 record.v = value; 13873 record.s = 1; 13874 notify(record, false); 13875 } 13876 } catch(e){ 13877 $reject.call({r: record, d: false}, e); // wrap 13878 } 13879}; 13880 13881// constructor polyfill 13882if(!USE_NATIVE){ 13883 // 25.4.3.1 Promise(executor) 13884 P = function Promise(executor){ 13885 aFunction(executor); 13886 var record = this._d = { 13887 p: strictNew(this, P, PROMISE), // <- promise 13888 c: [], // <- awaiting reactions 13889 a: undefined, // <- checked in isUnhandled reactions 13890 s: 0, // <- state 13891 d: false, // <- done 13892 v: undefined, // <- value 13893 h: false, // <- handled rejection 13894 n: false // <- notify 13895 }; 13896 try { 13897 executor(ctx($resolve, record, 1), ctx($reject, record, 1)); 13898 } catch(err){ 13899 $reject.call(record, err); 13900 } 13901 }; 13902 _dereq_('./$.redefine-all')(P.prototype, { 13903 // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) 13904 then: function then(onFulfilled, onRejected){ 13905 var reaction = new PromiseCapability(speciesConstructor(this, P)) 13906 , promise = reaction.promise 13907 , record = this._d; 13908 reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; 13909 reaction.fail = typeof onRejected == 'function' && onRejected; 13910 record.c.push(reaction); 13911 if(record.a)record.a.push(reaction); 13912 if(record.s)notify(record, false); 13913 return promise; 13914 }, 13915 // 25.4.5.1 Promise.prototype.catch(onRejected) 13916 'catch': function(onRejected){ 13917 return this.then(undefined, onRejected); 13918 } 13919 }); 13920} 13921 13922$export($export.G + $export.W + $export.F * !USE_NATIVE, {Promise: P}); 13923_dereq_('./$.set-to-string-tag')(P, PROMISE); 13924_dereq_('./$.set-species')(PROMISE); 13925Wrapper = _dereq_('./$.core')[PROMISE]; 13926 13927// statics 13928$export($export.S + $export.F * !USE_NATIVE, PROMISE, { 13929 // 25.4.4.5 Promise.reject(r) 13930 reject: function reject(r){ 13931 var capability = new PromiseCapability(this) 13932 , $$reject = capability.reject; 13933 $$reject(r); 13934 return capability.promise; 13935 } 13936}); 13937$export($export.S + $export.F * (!USE_NATIVE || testResolve(true)), PROMISE, { 13938 // 25.4.4.6 Promise.resolve(x) 13939 resolve: function resolve(x){ 13940 // instanceof instead of internal slot check because we should fix it without replacement native Promise core 13941 if(x instanceof P && sameConstructor(x.constructor, this))return x; 13942 var capability = new PromiseCapability(this) 13943 , $$resolve = capability.resolve; 13944 $$resolve(x); 13945 return capability.promise; 13946 } 13947}); 13948$export($export.S + $export.F * !(USE_NATIVE && _dereq_('./$.iter-detect')(function(iter){ 13949 P.all(iter)['catch'](function(){}); 13950})), PROMISE, { 13951 // 25.4.4.1 Promise.all(iterable) 13952 all: function all(iterable){ 13953 var C = getConstructor(this) 13954 , capability = new PromiseCapability(C) 13955 , resolve = capability.resolve 13956 , reject = capability.reject 13957 , values = []; 13958 var abrupt = perform(function(){ 13959 forOf(iterable, false, values.push, values); 13960 var remaining = values.length 13961 , results = Array(remaining); 13962 if(remaining)$.each.call(values, function(promise, index){ 13963 var alreadyCalled = false;
13964 C.resolve(promise).then(function(value){ 13965 if(alreadyCalled)return; 13966 alreadyCalled = true; 13967 results[index] = value; 13968 --remaining || resolve(results); 13969 }, reject); 13970 }); 13971 else resolve(results); 13972 }); 13973 if(abrupt)reject(abrupt.error); 13974 return capability.promise; 13975 }, 13976 // 25.4.4.4 Promise.race(iterable) 13977 race: function race(iterable){ 13978 var C = getConstructor(this) 13979 , capability = new PromiseCapability(C) 13980 , reject = capability.reject; 13981 var abrupt = perform(function(){ 13982 forOf(iterable, false, function(promise){ 13983 C.resolve(promise).then(capability.resolve, reject); 13984 }); 13985 }); 13986 if(abrupt)reject(abrupt.error); 13987 return capability.promise; 13988 } 13989}); 13990},{"./$":71,"./$.a-function":41,"./$.an-object":43,"./$.classof":44,"./$.core":49,"./$.ctx":50,"./$.descriptors":52,"./$.export":54,"./$.for-of":56,"./$.global":57,"./$.is-object":64,"./$.iter-detect":68,"./$.library":72,"./$.microtask":73,"./$.redefine-all":77,"./$.same-value":79,"./$.set-proto":80,"./$.set-species":81,"./$.set-to-string-tag":82,"./$.species-constructor":84,"./$.strict-new":85,"./$.wks":93}],103:[function(_dereq_,module,exports){ 13991'use strict'; 13992var strong = _dereq_('./$.collection-strong'); 13993 13994// 23.2 Set Objects 13995_dereq_('./$.collection')('Set', function(get){ 13996 return function Set(){ return get(this, arguments.length > 0 ? arguments[0] : undefined); }; 13997}, { 13998 // 23.2.3.1 Set.prototype.add(value) 13999 add: function add(value){ 14000 return strong.def(this, value = value === 0 ? 0 : value, value); 14001 } 14002}, strong); 14003},{"./$.collection":48,"./$.collection-strong":46}],104:[function(_dereq_,module,exports){ 14004'use strict'; 14005var $at = _dereq_('./$.string-at')(true); 14006 14007// 21.1.3.27 String.prototype[@@iterator]() 14008_dereq_('./$.iter-define')(String, 'String', function(iterated){ 14009 this._t = String(iterated); // target 14010 this._i = 0; // next index 14011// 21.1.5.2.1 %StringIteratorPrototype%.next() 14012}, function(){ 14013 var O = this._t 14014 , index = this._i 14015 , point; 14016 if(index >= O.length)return {value: undefined, done: true}; 14017 point = $at(O, index); 14018 this._i += point.length; 14019 return {value: point, done: false}; 14020}); 14021},{"./$.iter-define":67,"./$.string-at":86}],105:[function(_dereq_,module,exports){ 14022// https://github.com/DavidBruant/Map-Set.prototype.toJSON 14023var $export = _dereq_('./$.export'); 14024 14025$export($export.P, 'Set', {toJSON: _dereq_('./$.collection-to-json')('Set')}); 14026},{"./$.collection-to-json":47,"./$.export":54}],106:[function(_dereq_,module,exports){ 14027_dereq_('./es6.array.iterator'); 14028var Iterators = _dereq_('./$.iterators'); 14029Iterators.NodeList = Iterators.HTMLCollection = Iterators.Array; 14030},{"./$.iterators":70,"./es6.array.iterator":96}],107:[function(_dereq_,module,exports){ 14031(function (global){ 14032/*! 14033ISC License 14034 14035Copyright (c) 2014-2018, Andrea Giammarchi, @WebReflection 14036 14037Permission to use, copy, modify, and/or distribute this software for any 14038purpose with or without fee is hereby granted, provided that the above 14039copyright notice and this permission notice appear in all copies. 14040 14041THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 14042REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 14043AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 14044INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 14045LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14046OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14047PERFORMANCE OF THIS SOFTWARE. 14048 14049*/ 14050// global window Object 14051// optional polyfill info 14052// 'auto' used by default, everything is feature detected 14053// 'force' use the polyfill even if not fully needed 14054function installCustomElements(window, polyfill) {'use strict'; 14055 14056 // DO NOT USE THIS FILE DIRECTLY, IT WON'T WORK 14057 // THIS IS A PROJECT BASED ON A BUILD SYSTEM 14058 // THIS FILE IS JUST WRAPPED UP RESULTING IN 14059 // build/document-register-element.node.js
vendor: 39,871 bytes, lines 14059-15557
14059 14060 14061 var 14062 document = window.document, 14063 Object = window.Object 14064 ; 14065 14066 var htmlClass = (function (info) { 14067 // (C) Andrea Giammarchi - @WebReflection - MIT Style 14068 var 14069 catchClass = /^[A-Z]+[a-z]/, 14070 filterBy = function (re) { 14071 var arr = [], tag; 14072 for (tag in register) { 14073 if (re.test(tag)) arr.push(tag); 14074 } 14075 return arr; 14076 }, 14077 add = function (Class, tag) { 14078 tag = tag.toLowerCase(); 14079 if (!(tag in register)) { 14080 register[Class] = (register[Class] || []).concat(tag); 14081 register[tag] = (register[tag.toUpperCase()] = Class); 14082 } 14083 }, 14084 register = (Object.create || Object)(null), 14085 htmlClass = {}, 14086 i, section, tags, Class 14087 ; 14088 for (section in info) { 14089 for (Class in info[section]) { 14090 tags = info[section][Class]; 14091 register[Class] = tags; 14092 for (i = 0; i < tags.length; i++) { 14093 register[tags[i].toLowerCase()] = 14094 register[tags[i].toUpperCase()] = Class; 14095 } 14096 } 14097 } 14098 htmlClass.get = function get(tagOrClass) { 14099 return typeof tagOrClass === 'string' ? 14100 (register[tagOrClass] || (catchClass.test(tagOrClass) ? [] : '')) : 14101 filterBy(tagOrClass); 14102 }; 14103 htmlClass.set = function set(tag, Class) { 14104 return (catchClass.test(tag) ? 14105 add(tag, Class) : 14106 add(Class, tag) 14107 ), htmlClass; 14108 }; 14109 return htmlClass; 14110 }({ 14111 "collections": { 14112 "HTMLAllCollection": [ 14113 "all" 14114 ], 14115 "HTMLCollection": [ 14116 "forms" 14117 ], 14118 "HTMLFormControlsCollection": [ 14119 "elements" 14120 ], 14121 "HTMLOptionsCollection": [ 14122 "options" 14123 ] 14124 }, 14125 "elements": { 14126 "Element": [ 14127 "element" 14128 ], 14129 "HTMLAnchorElement": [ 14130 "a" 14131 ], 14132 "HTMLAppletElement": [ 14133 "applet" 14134 ], 14135 "HTMLAreaElement": [ 14136 "area" 14137 ], 14138 "HTMLAttachmentElement": [ 14139 "attachment" 14140 ], 14141 "HTMLAudioElement": [ 14142 "audio" 14143 ], 14144 "HTMLBRElement": [ 14145 "br" 14146 ], 14147 "HTMLBaseElement": [ 14148 "base" 14149 ], 14150 "HTMLBodyElement": [ 14151 "body" 14152 ], 14153 "HTMLButtonElement": [ 14154 "button" 14155 ], 14156 "HTMLCanvasElement": [ 14157 "canvas" 14158 ], 14159 "HTMLContentElement": [ 14160 "content" 14161 ], 14162 "HTMLDListElement": [ 14163 "dl" 14164 ], 14165 "HTMLDataElement": [ 14166 "data" 14167 ], 14168 "HTMLDataListElement": [ 14169 "datalist" 14170 ], 14171 "HTMLDetailsElement": [ 14172 "details" 14173 ], 14174 "HTMLDialogElement": [ 14175 "dialog" 14176 ], 14177 "HTMLDirectoryElement": [ 14178 "dir" 14179 ], 14180 "HTMLDivElement": [ 14181 "div" 14182 ], 14183 "HTMLDocument": [ 14184 "document" 14185 ], 14186 "HTMLElement": [ 14187 "element", 14188 "abbr", 14189 "address", 14190 "article", 14191 "aside", 14192 "b", 14193 "bdi", 14194 "bdo", 14195 "cite", 14196 "code", 14197 "command", 14198 "dd", 14199 "dfn", 14200 "dt", 14201 "em", 14202 "figcaption", 14203 "figure", 14204 "footer", 14205 "header", 14206 "i", 14207 "kbd", 14208 "mark", 14209 "nav", 14210 "noscript", 14211 "rp", 14212 "rt", 14213 "ruby", 14214 "s", 14215 "samp", 14216 "section", 14217 "small", 14218 "strong", 14219 "sub", 14220 "summary", 14221 "sup", 14222 "u", 14223 "var", 14224 "wbr" 14225 ], 14226 "HTMLEmbedElement": [ 14227 "embed" 14228 ], 14229 "HTMLFieldSetElement": [ 14230 "fieldset" 14231 ], 14232 "HTMLFontElement": [ 14233 "font" 14234 ], 14235 "HTMLFormElement": [ 14236 "form" 14237 ], 14238 "HTMLFrameElement": [ 14239 "frame" 14240 ], 14241 "HTMLFrameSetElement": [ 14242 "frameset" 14243 ], 14244 "HTMLHRElement": [ 14245 "hr" 14246 ], 14247 "HTMLHeadElement": [ 14248 "head" 14249 ], 14250 "HTMLHeadingElement": [ 14251 "h1", 14252 "h2", 14253 "h3", 14254 "h4", 14255 "h5", 14256 "h6" 14257 ], 14258 "HTMLHtmlElement": [ 14259 "html" 14260 ], 14261 "HTMLIFrameElement": [ 14262 "iframe" 14263 ], 14264 "HTMLImageElement": [ 14265 "img" 14266 ], 14267 "HTMLInputElement": [ 14268 "input" 14269 ], 14270 "HTMLKeygenElement": [ 14271 "keygen" 14272 ], 14273 "HTMLLIElement": [ 14274 "li" 14275 ], 14276 "HTMLLabelElement": [ 14277 "label" 14278 ], 14279 "HTMLLegendElement": [ 14280 "legend" 14281 ], 14282 "HTMLLinkElement": [ 14283 "link" 14284 ], 14285 "HTMLMapElement": [ 14286 "map" 14287 ], 14288 "HTMLMarqueeElement": [ 14289 "marquee" 14290 ], 14291 "HTMLMediaElement": [ 14292 "media" 14293 ], 14294 "HTMLMenuElement": [ 14295 "menu" 14296 ], 14297 "HTMLMenuItemElement": [ 14298 "menuitem" 14299 ], 14300 "HTMLMetaElement": [ 14301 "meta" 14302 ], 14303 "HTMLMeterElement": [ 14304 "meter" 14305 ], 14306 "HTMLModElement": [ 14307 "del", 14308 "ins" 14309 ], 14310 "HTMLOListElement": [ 14311 "ol" 14312 ], 14313 "HTMLObjectElement": [ 14314 "object" 14315 ], 14316 "HTMLOptGroupElement": [ 14317 "optgroup" 14318 ], 14319 "HTMLOptionElement": [ 14320 "option" 14321 ], 14322 "HTMLOutputElement": [ 14323 "output" 14324 ], 14325 "HTMLParagraphElement": [ 14326 "p" 14327 ], 14328 "HTMLParamElement": [ 14329 "param" 14330 ], 14331 "HTMLPictureElement": [ 14332 "picture" 14333 ], 14334 "HTMLPreElement": [ 14335 "pre" 14336 ], 14337 "HTMLProgressElement": [ 14338 "progress" 14339 ], 14340 "HTMLQuoteElement": [ 14341 "blockquote", 14342 "q", 14343 "quote" 14344 ], 14345 "HTMLScriptElement": [ 14346 "script" 14347 ], 14348 "HTMLSelectElement": [ 14349 "select" 14350 ], 14351 "HTMLShadowElement": [ 14352 "shadow" 14353 ], 14354 "HTMLSlotElement": [ 14355 "slot" 14356 ], 14357 "HTMLSourceElement": [ 14358 "source" 14359 ], 14360 "HTMLSpanElement": [ 14361 "span" 14362 ], 14363 "HTMLStyleElement": [ 14364 "style" 14365 ], 14366 "HTMLTableCaptionElement": [ 14367 "caption" 14368 ], 14369 "HTMLTableCellElement": [ 14370 "td", 14371 "th" 14372 ], 14373 "HTMLTableColElement": [ 14374 "col", 14375 "colgroup" 14376 ], 14377 "HTMLTableElement": [ 14378 "table" 14379 ], 14380 "HTMLTableRowElement": [ 14381 "tr" 14382 ], 14383 "HTMLTableSectionElement": [ 14384 "thead", 14385 "tbody", 14386 "tfoot" 14387 ], 14388 "HTMLTemplateElement": [ 14389 "template" 14390 ], 14391 "HTMLTextAreaElement": [ 14392 "textarea" 14393 ], 14394 "HTMLTimeElement": [ 14395 "time" 14396 ], 14397 "HTMLTitleElement": [ 14398 "title" 14399 ], 14400 "HTMLTrackElement": [ 14401 "track" 14402 ], 14403 "HTMLUListElement": [ 14404 "ul" 14405 ], 14406 "HTMLUnknownElement": [ 14407 "unknown", 14408 "vhgroupv", 14409 "vkeygen" 14410 ], 14411 "HTMLVideoElement": [ 14412 "video" 14413 ] 14414 }, 14415 "nodes": { 14416 "Attr": [ 14417 "node" 14418 ], 14419 "Audio": [ 14420 "audio" 14421 ], 14422 "CDATASection": [ 14423 "node" 14424 ], 14425 "CharacterData": [ 14426 "node" 14427 ], 14428 "Comment": [ 14429 "#comment" 14430 ], 14431 "Document": [ 14432 "#document" 14433 ], 14434 "DocumentFragment": [ 14435 "#document-fragment" 14436 ], 14437 "DocumentType": [ 14438 "node" 14439 ], 14440 "HTMLDocument": [ 14441 "#document" 14442 ], 14443 "Image": [ 14444 "img" 14445 ], 14446 "Option": [ 14447 "option" 14448 ], 14449 "ProcessingInstruction": [ 14450 "node" 14451 ], 14452 "ShadowRoot": [ 14453 "#shadow-root" 14454 ], 14455 "Text": [ 14456 "#text" 14457 ], 14458 "XMLDocument": [ 14459 "xml" 14460 ] 14461 } 14462 })); 14463 14464 14465 14466 // passed at runtime, configurable via nodejs module 14467 if (typeof polyfill !== 'object') polyfill = {type: polyfill || 'auto'}; 14468 14469 var 14470 // V0 polyfill entry 14471 REGISTER_ELEMENT = 'registerElement', 14472 14473 // pseudo-random number used as expando/unique name on feature detection 14474 UID = window.Math.random() * 10e4 >> 0, 14475 14476 // IE < 11 only + old WebKit for attributes + feature detection 14477 EXPANDO_UID = '__' + REGISTER_ELEMENT + UID, 14478 14479 // shortcuts and costants 14480 ADD_EVENT_LISTENER = 'addEventListener', 14481 ATTACHED = 'attached', 14482 CALLBACK = 'Callback', 14483 DETACHED = 'detached', 14484 EXTENDS = 'extends', 14485 14486 ATTRIBUTE_CHANGED_CALLBACK = 'attributeChanged' + CALLBACK, 14487 ATTACHED_CALLBACK = ATTACHED + CALLBACK, 14488 CONNECTED_CALLBACK = 'connected' + CALLBACK, 14489 DISCONNECTED_CALLBACK = 'disconnected' + CALLBACK, 14490 CREATED_CALLBACK = 'created' + CALLBACK, 14491 DETACHED_CALLBACK = DETACHED + CALLBACK, 14492 14493 ADDITION = 'ADDITION', 14494 MODIFICATION = 'MODIFICATION', 14495 REMOVAL = 'REMOVAL', 14496 14497 DOM_ATTR_MODIFIED = 'DOMAttrModified', 14498 DOM_CONTENT_LOADED = 'DOMContentLoaded', 14499 DOM_SUBTREE_MODIFIED = 'DOMSubtreeModified', 14500 14501 PREFIX_TAG = '<', 14502 PREFIX_IS = '=', 14503 14504 // valid and invalid node names 14505 validName = /^[A-Z][._A-Z0-9]*-[-._A-Z0-9]*$/, 14506 invalidNames = [ 14507 'ANNOTATION-XML', 14508 'COLOR-PROFILE', 14509 'FONT-FACE', 14510 'FONT-FACE-SRC', 14511 'FONT-FACE-URI', 14512 'FONT-FACE-FORMAT', 14513 'FONT-FACE-NAME', 14514 'MISSING-GLYPH' 14515 ], 14516 14517 // registered types and their prototypes 14518 types = [], 14519 protos = [], 14520 14521 // to query subnodes 14522 query = '', 14523 14524 // html shortcut used to feature detect 14525 documentElement = document.documentElement, 14526 14527 // ES5 inline helpers || basic patches 14528 indexOf = types.indexOf || function (v) { 14529 for(var i = this.length; i-- && this[i] !== v;){} 14530 return i; 14531 }, 14532 14533 // other helpers / shortcuts 14534 OP = Object.prototype, 14535 hOP = OP.hasOwnProperty, 14536 iPO = OP.isPrototypeOf, 14537 14538 defineProperty = Object.defineProperty, 14539 empty = [], 14540 gOPD = Object.getOwnPropertyDescriptor, 14541 gOPN = Object.getOwnPropertyNames, 14542 gPO = Object.getPrototypeOf, 14543 sPO = Object.setPrototypeOf, 14544 14545 // jshint proto: true 14546 hasProto = !!Object.__proto__, 14547 14548 // V1 helpers 14549 fixGetClass = false, 14550 DRECEV1 = '__dreCEv1', 14551 customElements = window.customElements, 14552 usableCustomElements = !/^force/.test(polyfill.type) && !!( 14553 customElements && 14554 customElements.define && 14555 customElements.get && 14556 customElements.whenDefined 14557 ), 14558 Dict = Object.create || Object, 14559 Map = window.Map || function Map() { 14560 var K = [], V = [], i; 14561 return { 14562 get: function (k) { 14563 return V[indexOf.call(K, k)]; 14564 }, 14565 set: function (k, v) { 14566 i = indexOf.call(K, k); 14567 if (i < 0) V[K.push(k) - 1] = v; 14568 else V[i] = v; 14569 } 14570 }; 14571 }, 14572 Promise = window.Promise || function (fn) { 14573 var 14574 notify = [], 14575 done = false, 14576 p = { 14577 'catch': function () { 14578 return p; 14579 }, 14580 'then': function (cb) { 14581 notify.push(cb); 14582 if (done) setTimeout(resolve, 1); 14583 return p; 14584 } 14585 } 14586 ; 14587 function resolve(value) { 14588 done = true; 14589 while (notify.length) notify.shift()(value); 14590 } 14591 fn(resolve); 14592 return p; 14593 }, 14594 justCreated = false, 14595 constructors = Dict(null), 14596 waitingList = Dict(null), 14597 nodeNames = new Map(), 14598 secondArgument = function (is) { 14599 return is.toLowerCase(); 14600 }, 14601 14602 // used to create unique instances 14603 create = Object.create || function Bridge(proto) { 14604 // silly broken polyfill probably ever used but short enough to work 14605 return proto ? ((Bridge.prototype = proto), new Bridge()) : this; 14606 }, 14607 14608 // will set the prototype if possible 14609 // or copy over all properties 14610 setPrototype = sPO || ( 14611 hasProto ? 14612 function (o, p) { 14613 o.__proto__ = p; 14614 return o; 14615 } : ( 14616 (gOPN && gOPD) ? 14617 (function(){ 14618 function setProperties(o, p) { 14619 for (var 14620 key, 14621 names = gOPN(p), 14622 i = 0, length = names.length; 14623 i < length; i++ 14624 ) { 14625 key = names[i]; 14626 if (!hOP.call(o, key)) { 14627 defineProperty(o, key, gOPD(p, key)); 14628 } 14629 } 14630 } 14631 return function (o, p) { 14632 do { 14633 setProperties(o, p); 14634 } while ((p = gPO(p)) && !iPO.call(p, o)); 14635 return o; 14636 }; 14637 }()) : 14638 function (o, p) { 14639 for (var key in p) { 14640 o[key] = p[key]; 14641 } 14642 return o; 14643 } 14644 )), 14645 14646 // DOM shortcuts and helpers, if any 14647 14648 MutationObserver = window.MutationObserver || 14649 window.WebKitMutationObserver, 14650 14651 HTMLAnchorElement = window.HTMLAnchorElement, 14652 14653 HTMLElementPrototype = ( 14654 window.HTMLElement || 14655 window.Element || 14656 window.Node 14657 ).prototype, 14658 14659 IE8 = !iPO.call(HTMLElementPrototype, documentElement), 14660 14661 safeProperty = IE8 ? function (o, k, d) { 14662 o[k] = d.value; 14663 return o; 14664 } : defineProperty, 14665 14666 isValidNode = IE8 ? 14667 function (node) { 14668 return node.nodeType === 1; 14669 } : 14670 function (node) { 14671 return iPO.call(HTMLElementPrototype, node); 14672 }, 14673 14674 targets = IE8 && [], 14675 14676 attachShadow = HTMLElementPrototype.attachShadow, 14677 cloneNode = HTMLElementPrototype.cloneNode, 14678 closest = HTMLElementPrototype.closest || function (name) { 14679 var self = this; 14680 while (self && self.nodeName !== name) 14681 self = self.parentNode; 14682 return self; 14683 }, 14684 dispatchEvent = HTMLElementPrototype.dispatchEvent, 14685 getAttribute = HTMLElementPrototype.getAttribute, 14686 hasAttribute = HTMLElementPrototype.hasAttribute, 14687 removeAttribute = HTMLElementPrototype.removeAttribute, 14688 setAttribute = HTMLElementPrototype.setAttribute, 14689 14690 // replaced later on 14691 createElement = document.createElement, 14692 importNode = document.importNode, 14693 patchedCreateElement = createElement, 14694 14695 // shared observer for all attributes 14696 attributesObserver = MutationObserver && { 14697 attributes: true, 14698 characterData: true, 14699 attributeOldValue: true 14700 }, 14701 14702 // useful to detect only if there's no MutationObserver 14703 DOMAttrModified = MutationObserver || function(e) { 14704 doesNotSupportDOMAttrModified = false; 14705 documentElement.removeEventListener( 14706 DOM_ATTR_MODIFIED, 14707 DOMAttrModified 14708 ); 14709 }, 14710 14711 // will both be used to make DOMNodeInserted asynchronous 14712 asapQueue, 14713 asapTimer = 0, 14714 14715 // internal flags 14716 V0 = REGISTER_ELEMENT in document && 14717 !/^force-all/.test(polyfill.type), 14718 setListener = true, 14719 justSetup = false, 14720 doesNotSupportDOMAttrModified = true, 14721 dropDomContentLoaded = true, 14722 14723 // needed for the innerHTML helper 14724 notFromInnerHTMLHelper = true, 14725 14726 // optionally defined later on 14727 onSubtreeModified, 14728 callDOMAttrModified, 14729 getAttributesMirror, 14730 observer, 14731 observe, 14732 14733 // based on setting prototype capability 14734 // will check proto or the expando attribute 14735 // in order to setup the node once 14736 patchIfNotAlready, 14737 patch, 14738 14739 // used for tests 14740 tmp 14741 ; 14742 14743 // IE11 disconnectedCallback issue # 14744 // to be tested before any createElement patch 14745 if (MutationObserver) { 14746 // original fix: 14747 // https://github.com/javan/mutation-observer-inner-html-shim 14748 tmp = document.createElement('div'); 14749 tmp.innerHTML = '<div><div></div></div>'; 14750 new MutationObserver(function (mutations, observer) { 14751 if ( 14752 mutations[0] && 14753 mutations[0].type == 'childList' && 14754 !mutations[0].removedNodes[0].childNodes.length 14755 ) { 14756 tmp = gOPD(HTMLElementPrototype, 'innerHTML'); 14757 var set = tmp && tmp.set; 14758 if (set) 14759 defineProperty(HTMLElementPrototype, 'innerHTML', { 14760 set: function (value) { 14761 while (this.lastChild) 14762 this.removeChild(this.lastChild); 14763 set.call(this, value); 14764 } 14765 }); 14766 } 14767 observer.disconnect(); 14768 tmp = null; 14769 }).observe(tmp, {childList: true, subtree: true}); 14770 tmp.innerHTML = ""; 14771 } 14772 14773 // only if needed 14774 if (!V0) { 14775 14776 if (sPO || hasProto) { 14777 patchIfNotAlready = function (node, proto) { 14778 if (!iPO.call(proto, node)) { 14779 setupNode(node, proto); 14780 } 14781 }; 14782 patch = setupNode; 14783 } else { 14784 patchIfNotAlready = function (node, proto) { 14785 if (!node[EXPANDO_UID]) { 14786 node[EXPANDO_UID] = Object(true); 14787 setupNode(node, proto); 14788 } 14789 }; 14790 patch = patchIfNotAlready; 14791 } 14792 14793 if (IE8) { 14794 doesNotSupportDOMAttrModified = false; 14795 (function (){ 14796 var 14797 descriptor = gOPD(HTMLElementPrototype, ADD_EVENT_LISTENER), 14798 addEventListener = descriptor.value, 14799 patchedRemoveAttribute = function (name) { 14800 var e = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true}); 14801 e.attrName = name; 14802 e.prevValue = getAttribute.call(this, name); 14803 e.newValue = null; 14804 e[REMOVAL] = e.attrChange = 2; 14805 removeAttribute.call(this, name); 14806 dispatchEvent.call(this, e); 14807 }, 14808 patchedSetAttribute = function (name, value) { 14809 var 14810 had = hasAttribute.call(this, name), 14811 old = had && getAttribute.call(this, name), 14812 e = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true}) 14813 ; 14814 setAttribute.call(this, name, value); 14815 e.attrName = name; 14816 e.prevValue = had ? old : null; 14817 e.newValue = value; 14818 if (had) { 14819 e[MODIFICATION] = e.attrChange = 1; 14820 } else { 14821 e[ADDITION] = e.attrChange = 0; 14822 } 14823 dispatchEvent.call(this, e); 14824 }, 14825 onPropertyChange = function (e) { 14826 // jshint eqnull:true 14827 var 14828 node = e.currentTarget, 14829 superSecret = node[EXPANDO_UID], 14830 propertyName = e.propertyName, 14831 event 14832 ; 14833 if (superSecret.hasOwnProperty(propertyName)) { 14834 superSecret = superSecret[propertyName]; 14835 event = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true}); 14836 event.attrName = superSecret.name; 14837 event.prevValue = superSecret.value || null; 14838 event.newValue = (superSecret.value = node[propertyName] || null); 14839 if (event.prevValue == null) { 14840 event[ADDITION] = event.attrChange = 0; 14841 } else { 14842 event[MODIFICATION] = event.attrChange = 1; 14843 } 14844 dispatchEvent.call(node, event); 14845 } 14846 } 14847 ; 14848 descriptor.value = function (type, handler, capture) { 14849 if ( 14850 type === DOM_ATTR_MODIFIED && 14851 this[ATTRIBUTE_CHANGED_CALLBACK] && 14852 this.setAttribute !== patchedSetAttribute 14853 ) { 14854 this[EXPANDO_UID] = { 14855 className: { 14856 name: 'class', 14857 value: this.className 14858 } 14859 }; 14860 this.setAttribute = patchedSetAttribute; 14861 this.removeAttribute = patchedRemoveAttribute; 14862 addEventListener.call(this, 'propertychange', onPropertyChange); 14863 } 14864 addEventListener.call(this, type, handler, capture); 14865 }; 14866 defineProperty(HTMLElementPrototype, ADD_EVENT_LISTENER, descriptor); 14867 }()); 14868 } else if (!MutationObserver) { 14869 documentElement[ADD_EVENT_LISTENER](DOM_ATTR_MODIFIED, DOMAttrModified); 14870 documentElement.setAttribute(EXPANDO_UID, 1); 14871 documentElement.removeAttribute(EXPANDO_UID); 14872 if (doesNotSupportDOMAttrModified) { 14873 onSubtreeModified = function (e) { 14874 var 14875 node = this, 14876 oldAttributes, 14877 newAttributes, 14878 key 14879 ; 14880 if (node === e.target) { 14881 oldAttributes = node[EXPANDO_UID]; 14882 node[EXPANDO_UID] = (newAttributes = getAttributesMirror(node)); 14883 for (key in newAttributes) { 14884 if (!(key in oldAttributes)) { 14885 // attribute was added 14886 return callDOMAttrModified( 14887 0, 14888 node, 14889 key, 14890 oldAttributes[key], 14891 newAttributes[key], 14892 ADDITION 14893 ); 14894 } else if (newAttributes[key] !== oldAttributes[key]) { 14895 // attribute was changed 14896 return callDOMAttrModified( 14897 1, 14898 node, 14899 key, 14900 oldAttributes[key], 14901 newAttributes[key], 14902 MODIFICATION 14903 ); 14904 } 14905 } 14906 // checking if it has been removed 14907 for (key in oldAttributes) { 14908 if (!(key in newAttributes)) { 14909 // attribute removed 14910 return callDOMAttrModified( 14911 2, 14912 node, 14913 key, 14914 oldAttributes[key], 14915 newAttributes[key], 14916 REMOVAL 14917 ); 14918 } 14919 } 14920 } 14921 }; 14922 callDOMAttrModified = function ( 14923 attrChange, 14924 currentTarget, 14925 attrName, 14926 prevValue, 14927 newValue, 14928 action 14929 ) { 14930 var e = { 14931 attrChange: attrChange, 14932 currentTarget: currentTarget, 14933 attrName: attrName, 14934 prevValue: prevValue, 14935 newValue: newValue 14936 }; 14937 e[action] = attrChange; 14938 onDOMAttrModified(e); 14939 }; 14940 getAttributesMirror = function (node) { 14941 for (var 14942 attr, name, 14943 result = {}, 14944 attributes = node.attributes, 14945 i = 0, length = attributes.length; 14946 i < length; i++ 14947 ) { 14948 attr = attributes[i]; 14949 name = attr.name; 14950 if (name !== 'setAttribute') { 14951 result[name] = attr.value; 14952 } 14953 } 14954 return result; 14955 }; 14956 } 14957 } 14958 14959 // set as enumerable, writable and configurable 14960 document[REGISTER_ELEMENT] = function registerElement(type, options) { 14961 upperType = type.toUpperCase(); 14962 if (setListener) { 14963 // only first time document.registerElement is used 14964 // we need to set this listener 14965 // setting it by default might slow down for no reason 14966 setListener = false; 14967 if (MutationObserver) { 14968 observer = (function(attached, detached){ 14969 function checkEmAll(list, callback) { 14970 for (var i = 0, length = list.length; i < length; callback(list[i++])){} 14971 } 14972 return new MutationObserver(function (records) { 14973 for (var 14974 current, node, newValue, 14975 i = 0, length = records.length; i < length; i++ 14976 ) { 14977 current = records[i]; 14978 if (current.type === 'childList') { 14979 checkEmAll(current.addedNodes, attached); 14980 checkEmAll(current.removedNodes, detached); 14981 } else { 14982 node = current.target; 14983 if (notFromInnerHTMLHelper && 14984 node[ATTRIBUTE_CHANGED_CALLBACK] && 14985 current.attributeName !== 'style') { 14986 newValue = getAttribute.call(node, current.attributeName); 14987 if (newValue !== current.oldValue) { 14988 node[ATTRIBUTE_CHANGED_CALLBACK]( 14989 current.attributeName, 14990 current.oldValue, 14991 newValue 14992 ); 14993 } 14994 } 14995 } 14996 } 14997 }); 14998 }(executeAction(ATTACHED), executeAction(DETACHED))); 14999 observe = function (node) { 15000 observer.observe( 15001 node, 15002 { 15003 childList: true, 15004 subtree: true 15005 } 15006 ); 15007 return node; 15008 }; 15009 observe(document); 15010 if (attachShadow) { 15011 HTMLElementPrototype.attachShadow = function () { 15012 return observe(attachShadow.apply(this, arguments)); 15013 }; 15014 } 15015 } else { 15016 asapQueue = []; 15017 document[ADD_EVENT_LISTENER]('DOMNodeInserted', onDOMNode(ATTACHED)); 15018 document[ADD_EVENT_LISTENER]('DOMNodeRemoved', onDOMNode(DETACHED)); 15019 } 15020 15021 document[ADD_EVENT_LISTENER](DOM_CONTENT_LOADED, onReadyStateChange); 15022 document[ADD_EVENT_LISTENER]('readystatechange', onReadyStateChange); 15023 15024 document.importNode = function (node, deep) { 15025 switch (node.nodeType) { 15026 case 1: 15027 return setupAll(document, importNode, [node, !!deep]); 15028 case 11: 15029 for (var 15030 fragment = document.createDocumentFragment(), 15031 childNodes = node.childNodes, 15032 length = childNodes.length, 15033 i = 0; i < length; i++ 15034 ) 15035 fragment.appendChild(document.importNode(childNodes[i], !!deep)); 15036 return fragment; 15037 default: 15038 return cloneNode.call(node, !!deep); 15039 } 15040 }; 15041 15042 HTMLElementPrototype.cloneNode = function (deep) { 15043 return setupAll(this, cloneNode, [!!deep]); 15044 }; 15045 } 15046 15047 if (justSetup) return (justSetup = false); 15048 15049 if (-2 < ( 15050 indexOf.call(types, PREFIX_IS + upperType) + 15051 indexOf.call(types, PREFIX_TAG + upperType) 15052 )) { 15053 throwTypeError(type); 15054 } 15055 15056 if (!validName.test(upperType) || -1 < indexOf.call(invalidNames, upperType)) { 15057 throw new Error('The type ' + type + ' is invalid'); 15058 } 15059 15060 var 15061 constructor = function () { 15062 return extending ? 15063 document.createElement(nodeName, upperType) : 15064 document.createElement(nodeName); 15065 }, 15066 opt = options || OP, 15067 extending = hOP.call(opt, EXTENDS), 15068 nodeName = extending ? options[EXTENDS].toUpperCase() : upperType, 15069 upperType, 15070 i 15071 ; 15072 15073 if (extending && -1 < ( 15074 indexOf.call(types, PREFIX_TAG + nodeName) 15075 )) { 15076 throwTypeError(nodeName); 15077 } 15078 15079 i = types.push((extending ? PREFIX_IS : PREFIX_TAG) + upperType) - 1; 15080 15081 query = query.concat( 15082 query.length ? ',' : '', 15083 extending ? nodeName + '[is="' + type.toLowerCase() + '"]' : nodeName 15084 ); 15085 15086 constructor.prototype = ( 15087 protos[i] = hOP.call(opt, 'prototype') ? 15088 opt.prototype : 15089 create(HTMLElementPrototype) 15090 ); 15091 15092 if (query.length) loopAndVerify( 15093 document.querySelectorAll(query), 15094 ATTACHED 15095 ); 15096 15097 return constructor; 15098 }; 15099 15100 document.createElement = (patchedCreateElement = function (localName, typeExtension) { 15101 var 15102 is = getIs(typeExtension), 15103 node = is ? 15104 createElement.call(document, localName, secondArgument(is)) : 15105 createElement.call(document, localName), 15106 name = '' + localName, 15107 i = indexOf.call( 15108 types, 15109 (is ? PREFIX_IS : PREFIX_TAG) + 15110 (is || name).toUpperCase() 15111 ), 15112 setup = -1 < i 15113 ; 15114 if (is) { 15115 node.setAttribute('is', is = is.toLowerCase()); 15116 if (setup) { 15117 setup = isInQSA(name.toUpperCase(), is); 15118 } 15119 } 15120 notFromInnerHTMLHelper = !document.createElement.innerHTMLHelper; 15121 if (setup) patch(node, protos[i]); 15122 return node; 15123 }); 15124 15125 } 15126 15127 // needed due unbelievable IE11 behavior 15128 // https://github.com/WebReflection/document-register-element/issues/175#issuecomment-520904688 15129 addEventListener( 15130 'beforeunload', 15131 function () { 15132 delete document.createElement; 15133 delete document.importNode; 15134 delete document[REGISTER_ELEMENT]; 15135 }, 15136 false 15137 ); 15138 15139 function ASAP() { 15140 var queue = asapQueue.splice(0, asapQueue.length); 15141 asapTimer = 0; 15142 while (queue.length) { 15143 queue.shift().call( 15144 null, queue.shift() 15145 ); 15146 } 15147 } 15148 15149 function loopAndVerify(list, action) { 15150 for (var i = 0, length = list.length; i < length; i++) { 15151 verifyAndSetupAndAction(list[i], action); 15152 } 15153 } 15154 15155 function loopAndSetup(list) { 15156 for (var i = 0, length = list.length, node; i < length; i++) { 15157 node = list[i]; 15158 patch(node, protos[getTypeIndex(node)]); 15159 } 15160 } 15161 15162 function executeAction(action) { 15163 return function (node) { 15164 if (isValidNode(node)) { 15165 verifyAndSetupAndAction(node, action); 15166 if (query.length) loopAndVerify( 15167 node.querySelectorAll(query), 15168 action 15169 ); 15170 } 15171 }; 15172 } 15173 15174 function getTypeIndex(target) { 15175 var 15176 is = getAttribute.call(target, 'is'), 15177 nodeName = target.nodeName.toUpperCase(), 15178 i = indexOf.call( 15179 types, 15180 is ? 15181 PREFIX_IS + is.toUpperCase() : 15182 PREFIX_TAG + nodeName 15183 ) 15184 ; 15185 return is && -1 < i && !isInQSA(nodeName, is) ? -1 : i; 15186 } 15187 15188 function isInQSA(name, type) { 15189 return -1 < query.indexOf(name + '[is="' + type + '"]'); 15190 } 15191 15192 function onDOMAttrModified(e) { 15193 var 15194 node = e.currentTarget, 15195 attrChange = e.attrChange, 15196 attrName = e.attrName, 15197 target = e.target, 15198 addition = e[ADDITION] || 2, 15199 removal = e[REMOVAL] || 3 15200 ; 15201 if (notFromInnerHTMLHelper && 15202 (!target || target === node) && 15203 node[ATTRIBUTE_CHANGED_CALLBACK] && 15204 attrName !== 'style' && ( 15205 e.prevValue !== e.newValue || 15206 // IE9, IE10, and Opera 12 gotcha 15207 e.newValue === '' && ( 15208 attrChange === addition || 15209 attrChange === removal 15210 ) 15211 )) { 15212 node[ATTRIBUTE_CHANGED_CALLBACK]( 15213 attrName, 15214 attrChange === addition ? null : e.prevValue, 15215 attrChange === removal ? null : e.newValue 15216 ); 15217 } 15218 } 15219 15220 function onDOMNode(action) { 15221 var executor = executeAction(action); 15222 return function (e) { 15223 asapQueue.push(executor, e.target); 15224 if (asapTimer) clearTimeout(asapTimer); 15225 asapTimer = setTimeout(ASAP, 1); 15226 }; 15227 } 15228 15229 function onReadyStateChange(e) { 15230 if (dropDomContentLoaded) { 15231 dropDomContentLoaded = false; 15232 e.currentTarget.removeEventListener(DOM_CONTENT_LOADED, onReadyStateChange); 15233 } 15234 if (query.length) loopAndVerify( 15235 (e.target || document).querySelectorAll(query), 15236 e.detail === DETACHED ? DETACHED : ATTACHED 15237 ); 15238 if (IE8) purge(); 15239 } 15240 15241 function patchedSetAttribute(name, value) { 15242 // jshint validthis:true 15243 var self = this; 15244 setAttribute.call(self, name, value); 15245 onSubtreeModified.call(self, {target: self}); 15246 } 15247 15248 function setupAll(context, callback, args) { 15249 var 15250 node = callback.apply(context, args), 15251 i = getTypeIndex(node) 15252 ; 15253 if (-1 < i) patch(node, protos[i]); 15254 if (args.pop() && query.length) 15255 loopAndSetup(node.querySelectorAll(query)); 15256 return node; 15257 } 15258 15259 function setupNode(node, proto) { 15260 setPrototype(node, proto); 15261 if (observer) { 15262 observer.observe(node, attributesObserver); 15263 } else { 15264 if (doesNotSupportDOMAttrModified) { 15265 node.setAttribute = patchedSetAttribute; 15266 node[EXPANDO_UID] = getAttributesMirror(node); 15267 node[ADD_EVENT_LISTENER](DOM_SUBTREE_MODIFIED, onSubtreeModified); 15268 } 15269 node[ADD_EVENT_LISTENER](DOM_ATTR_MODIFIED, onDOMAttrModified); 15270 } 15271 if (node[CREATED_CALLBACK] && notFromInnerHTMLHelper) { 15272 node.created = true; 15273 node[CREATED_CALLBACK](); 15274 node.created = false; 15275 } 15276 } 15277 15278 function purge() { 15279 for (var 15280 node, 15281 i = 0, 15282 length = targets.length; 15283 i < length; i++ 15284 ) { 15285 node = targets[i]; 15286 if (!documentElement.contains(node)) { 15287 length--; 15288 targets.splice(i--, 1); 15289 verifyAndSetupAndAction(node, DETACHED); 15290 } 15291 } 15292 } 15293 15294 function throwTypeError(type) { 15295 throw new Error('A ' + type + ' type is already registered'); 15296 } 15297 15298 function verifyAndSetupAndAction(node, action) { 15299 var 15300 fn, 15301 i = getTypeIndex(node), 15302 counterAction 15303 ; 15304 if ((-1 < i) && !closest.call(node, 'TEMPLATE')) { 15305 patchIfNotAlready(node, protos[i]); 15306 i = 0; 15307 if (action === ATTACHED && !node[ATTACHED]) { 15308 node[DETACHED] = false; 15309 node[ATTACHED] = true; 15310 counterAction = 'connected'; 15311 i = 1; 15312 if (IE8 && indexOf.call(targets, node) < 0) { 15313 targets.push(node); 15314 } 15315 } else if (action === DETACHED && !node[DETACHED]) { 15316 node[ATTACHED] = false; 15317 node[DETACHED] = true; 15318 counterAction = 'disconnected'; 15319 i = 1; 15320 } 15321 if (i && (fn = ( 15322 node[action + CALLBACK] || 15323 node[counterAction + CALLBACK] 15324 ))) fn.call(node); 15325 } 15326 } 15327 15328 // V1 in da House! 15329 function CustomElementRegistry() {} 15330 15331 CustomElementRegistry.prototype = { 15332 constructor: CustomElementRegistry, 15333 // a workaround for the stubborn WebKit 15334 define: usableCustomElements ? 15335 function (name, Class, options) { 15336 if (options) { 15337 CERDefine(name, Class, options); 15338 } else { 15339 var NAME = name.toUpperCase(); 15340 constructors[NAME] = { 15341 constructor: Class, 15342 create: [NAME] 15343 }; 15344 nodeNames.set(Class, NAME); 15345 customElements.define(name, Class); 15346 } 15347 } : 15348 CERDefine, 15349 get: usableCustomElements ? 15350 function (name) { 15351 return customElements.get(name) || get(name); 15352 } : 15353 get, 15354 whenDefined: usableCustomElements ? 15355 function (name) { 15356 return Promise.race([ 15357 customElements.whenDefined(name), 15358 whenDefined(name) 15359 ]); 15360 } : 15361 whenDefined 15362 }; 15363 15364 function CERDefine(name, Class, options) { 15365 var 15366 is = options && options[EXTENDS] || '', 15367 CProto = Class.prototype, 15368 proto = create(CProto), 15369 attributes = Class.observedAttributes || empty, 15370 definition = {prototype: proto} 15371 ; 15372 // TODO: is this needed at all since it's inherited? 15373 // defineProperty(proto, 'constructor', {value: Class}); 15374 safeProperty(proto, CREATED_CALLBACK, { 15375 value: function () { 15376 if (justCreated) justCreated = false; 15377 else if (!this[DRECEV1]) { 15378 this[DRECEV1] = true; 15379 new Class(this); 15380 if (CProto[CREATED_CALLBACK]) 15381 CProto[CREATED_CALLBACK].call(this); 15382 var info = constructors[nodeNames.get(Class)]; 15383 if (!usableCustomElements || info.create.length > 1) { 15384 notifyAttributes(this); 15385 } 15386 } 15387 } 15388 }); 15389 safeProperty(proto, ATTRIBUTE_CHANGED_CALLBACK, { 15390 value: function (name) { 15391 if (-1 < indexOf.call(attributes, name)) { 15392 if (CProto[ATTRIBUTE_CHANGED_CALLBACK]) 15393 CProto[ATTRIBUTE_CHANGED_CALLBACK].apply(this, arguments); 15394 } 15395 } 15396 }); 15397 if (CProto[CONNECTED_CALLBACK]) { 15398 safeProperty(proto, ATTACHED_CALLBACK, { 15399 value: CProto[CONNECTED_CALLBACK] 15400 }); 15401 } 15402 if (CProto[DISCONNECTED_CALLBACK]) { 15403 safeProperty(proto, DETACHED_CALLBACK, { 15404 value: CProto[DISCONNECTED_CALLBACK] 15405 }); 15406 } 15407 if (is) definition[EXTENDS] = is; 15408 name = name.toUpperCase(); 15409 constructors[name] = { 15410 constructor: Class, 15411 create: is ? [is, secondArgument(name)] : [name] 15412 }; 15413 nodeNames.set(Class, name); 15414 document[REGISTER_ELEMENT](name.toLowerCase(), definition); 15415 whenDefined(name); 15416 waitingList[name].r(); 15417 } 15418 15419 function get(name) { 15420 var info = constructors[name.toUpperCase()]; 15421 return info && info.constructor; 15422 } 15423 15424 function getIs(options) { 15425 return typeof options === 'string' ? 15426 options : (options && options.is || ''); 15427 } 15428 15429 function notifyAttributes(self) { 15430 var 15431 callback = self[ATTRIBUTE_CHANGED_CALLBACK], 15432 attributes = callback ? self.attributes : empty, 15433 i = attributes.length, 15434 attribute 15435 ; 15436 while (i--) { 15437 attribute = attributes[i]; // || attributes.item(i); 15438 callback.call( 15439 self, 15440 attribute.name || attribute.nodeName, 15441 null, 15442 attribute.value || attribute.nodeValue 15443 ); 15444 } 15445 } 15446 15447 function whenDefined(name) { 15448 name = name.toUpperCase(); 15449 if (!(name in waitingList)) { 15450 waitingList[name] = {}; 15451 waitingList[name].p = new Promise(function (resolve) { 15452 waitingList[name].r = resolve; 15453 }); 15454 } 15455 return waitingList[name].p; 15456 } 15457 15458 function polyfillV1() { 15459 if (customElements) delete window.customElements; 15460 defineProperty(window, 'customElements', { 15461 configurable: true, 15462 value: new CustomElementRegistry() 15463 }); 15464 defineProperty(window, 'CustomElementRegistry', { 15465 configurable: true, 15466 value: CustomElementRegistry 15467 }); 15468 for (var 15469 patchClass = function (name) { 15470 var Class = window[name]; 15471 if (Class) { 15472 window[name] = function CustomElementsV1(self) { 15473 var info, isNative; 15474 if (!self) self = this; 15475 if (!self[DRECEV1]) { 15476 justCreated = true; 15477 info = constructors[nodeNames.get(self.constructor)]; 15478 isNative = usableCustomElements && info.create.length === 1; 15479 self = isNative ? 15480 Reflect.construct(Class, empty, info.constructor) : 15481 document.createElement.apply(document, info.create); 15482 self[DRECEV1] = true; 15483 justCreated = false; 15484 if (!isNative) notifyAttributes(self); 15485 } 15486 return self; 15487 }; 15488 window[name].prototype = Class.prototype; 15489 try { 15490 Class.prototype.constructor = window[name]; 15491 } catch(WebKit) { 15492 fixGetClass = true; 15493 defineProperty(Class, DRECEV1, {value: window[name]}); 15494 } 15495 } 15496 }, 15497 Classes = htmlClass.get(/^HTML[A-Z]*[a-z]/), 15498 i = Classes.length; 15499 i--; 15500 patchClass(Classes[i]) 15501 ) {} 15502 (document.createElement = function (name, options) { 15503 var is = getIs(options); 15504 return is ? 15505 patchedCreateElement.call(this, name, secondArgument(is)) : 15506 patchedCreateElement.call(this, name); 15507 }); 15508 if (!V0) { 15509 justSetup = true; 15510 document[REGISTER_ELEMENT](''); 15511 } 15512 } 15513 15514 // if customElements is not there at all 15515 if (!customElements || /^force/.test(polyfill.type)) polyfillV1(); 15516 else if(!polyfill.noBuiltIn) { 15517 // if available test extends work as expected 15518 try { 15519 (function (DRE, options, name) { 15520 var re = new RegExp('^<a\\s+is=(\'|")' + name + '\\1></a>$'); 15521 options[EXTENDS] = 'a'; 15522 DRE.prototype = create(HTMLAnchorElement.prototype); 15523 DRE.prototype.constructor = DRE; 15524 window.customElements.define(name, DRE, options); 15525 if ( 15526 !re.test(document.createElement('a', {is: name}).outerHTML) || 15527 !re.test((new DRE()).outerHTML) 15528 ) { 15529 throw options; 15530 } 15531 }( 15532 function DRE() { 15533 return Reflect.construct(HTMLAnchorElement, [], DRE); 15534 }, 15535 {}, 15536 'document-register-element-a' + UID 15537 )); 15538 } catch(o_O) { 15539 // or force the polyfill if not 15540 // and keep internal original reference 15541 polyfillV1(); 15542 } 15543 } 15544 15545 // FireFox only issue 15546 if(!polyfill.noBuiltIn) { 15547 try { 15548 if (createElement.call(document, 'a', 'a').outerHTML.indexOf('is') < 0) 15549 throw {}; 15550 } catch(FireFox) { 15551 secondArgument = function (is) { 15552 return {is: is.toLowerCase()}; 15553 }; 15554 } 15555 } 15556 15557}
15557 15558 15559module.exports = installCustomElements; 15560installCustomElements(global); 15561 15562}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 15563 15564},{}],108:[function(_dereq_,module,exports){ 15565(function (global){ 15566var win; 15567 15568if (typeof window !== "undefined") { 15569 win = window; 15570} else if (typeof global !== "undefined") { 15571 win = global; 15572} else if (typeof self !== "undefined"){ 15573 win = self; 15574} else { 15575 win = {}; 15576} 15577 15578module.exports = win; 15579 15580}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 15581 15582},{}],109:[function(_dereq_,module,exports){ 15583(function (global){ 15584(function (global, factory) { 15585 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 15586 typeof define === 'function' && define.amd ? define(factory) : 15587 (global.GlslCanvas = factory()); 15588}(this, (function () { 'use strict'; 15589 15590var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; 15591 15592var win; 15593 15594if (typeof window !== "undefined") { 15595 win = window; 15596} else if (typeof commonjsGlobal !== "undefined") { 15597 win = commonjsGlobal; 15598} else if (typeof self !== "undefined"){ 15599 win = self; 15600} else { 15601 win = {}; 15602} 15603 15604var window_1 = win; 15605 15606var isFunction_1 = isFunction; 15607 15608var toString = Object.prototype.toString; 15609 15610function isFunction (fn) { 15611 if (!fn) { 15612 return false 15613 } 15614 var string = toString.call(fn); 15615 return string === '[object Function]' || 15616 (typeof fn === 'function' && string !== '[object RegExp]') || 15617 (typeof window !== 'undefined' && 15618 // IE8 and below 15619 (fn === window.setTimeout || 15620 fn === window.alert || 15621 fn === window.confirm || 15622 fn === window.prompt)) 15623} 15624 15625var trim = function(string) { 15626 return string.replace(/^\s+|\s+$/g, ''); 15627}; 15628var isArray = function(arg) { 15629 return Object.prototype.toString.call(arg) === '[object Array]'; 15630 }; 15631 15632var parseHeaders = function (headers) { 15633 if (!headers) 15634 return {} 15635 15636 var result = {}; 15637 15638 var headersArr = trim(headers).split('\n'); 15639 15640 for (var i = 0; i < headersArr.length; i++) { 15641 var row = headersArr[i]; 15642 var index = row.indexOf(':') 15643 , key = trim(row.slice(0, index)).toLowerCase() 15644 , value = trim(row.slice(index + 1)); 15645 15646 if (typeof(result[key]) === 'undefined') { 15647 result[key] = value; 15648 } else if (isArray(result[key])) { 15649 result[key].push(value); 15650 } else { 15651 result[key] = [ result[key], value ]; 15652 } 15653 } 15654 15655 return result 15656}; 15657 15658var immutable = extend; 15659 15660var hasOwnProperty = Object.prototype.hasOwnProperty; 15661 15662function extend() { 15663 var target = {}; 15664 15665 for (var i = 0; i < arguments.length; i++) { 15666 var source = arguments[i]; 15667 15668 for (var key in source) { 15669 if (hasOwnProperty.call(source, key)) { 15670 target[key] = source[key]; 15671 } 15672 } 15673 } 15674 15675 return target 15676} 15677 15678"use strict"; 15679 15680 15681 15682 15683 15684var xhr = createXHR; 15685// Allow use of default import syntax in TypeScript 15686var default_1 = createXHR; 15687createXHR.XMLHttpRequest = window_1.XMLHttpRequest || noop; 15688createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window_1.XDomainRequest; 15689 15690forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { 15691 createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { 15692 options = initParams(uri, options, callback); 15693 options.method = method.toUpperCase(); 15694 return _createXHR(options) 15695 }; 15696}); 15697 15698function forEachArray(array, iterator) { 15699 for (var i = 0; i < array.length; i++) { 15700 iterator(array[i]); 15701 } 15702} 15703 15704function isEmpty(obj){ 15705 for(var i in obj){ 15706 if(obj.hasOwnProperty(i)) return false 15707 } 15708 return true 15709} 15710 15711function initParams(uri, options, callback) { 15712 var params = uri; 15713 15714 if (isFunction_1(options)) { 15715 callback = options; 15716 if (typeof uri === "string") { 15717 params = {uri:uri}; 15718 } 15719 } else { 15720 params = immutable(options, {uri: uri}); 15721 } 15722 15723 params.callback = callback; 15724 return params 15725} 15726 15727function createXHR(uri, options, callback) { 15728 options = initParams(uri, options, callback); 15729 return _createXHR(options) 15730} 15731 15732function _createXHR(options) { 15733 if(typeof options.callback === "undefined"){ 15734 throw new Error("callback argument missing") 15735 } 15736 15737 var called = false;
15738 var callback = function cbOnce(err, response, body){ 15739 if(!called){ 15740 called = true; 15741 options.callback(err, response, body); 15742 } 15743 }; 15744 15745 function readystatechange() { 15746 if (xhr.readyState === 4) { 15747 setTimeout(loadFunc, 0); 15748 } 15749 } 15750 15751 function getBody() { 15752 // Chrome with requestType=blob throws errors arround when even testing access to responseText 15753 var body = undefined; 15754 15755 if (xhr.response) { 15756 body = xhr.response; 15757 } else { 15758 body = xhr.responseText || getXml(xhr); 15759 } 15760 15761 if (isJson) { 15762 try { 15763 body = JSON.parse(body); 15764 } catch (e) {} 15765 } 15766 15767 return body 15768 } 15769 15770 function errorFunc(evt) { 15771 clearTimeout(timeoutTimer); 15772 if(!(evt instanceof Error)){ 15773 evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ); 15774 } 15775 evt.statusCode = 0; 15776 return callback(evt, failureResponse) 15777 } 15778 15779 // will load the data & process the response in a special response object 15780 function loadFunc() { 15781 if (aborted) return 15782 var status; 15783 clearTimeout(timeoutTimer); 15784 if(options.useXDR && xhr.status===undefined) { 15785 //IE8 CORS GET successful response doesn't have a status field, but body is fine 15786 status = 200; 15787 } else { 15788 status = (xhr.status === 1223 ? 204 : xhr.status); 15789 } 15790 var response = failureResponse; 15791 var err = null; 15792 15793 if (status !== 0){ 15794 response = { 15795 body: getBody(), 15796 statusCode: status, 15797 method: method, 15798 headers: {}, 15799 url: uri, 15800 rawRequest: xhr 15801 }; 15802 if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE 15803 response.headers = parseHeaders(xhr.getAllResponseHeaders()); 15804 } 15805 } else { 15806 err = new Error("Internal XMLHttpRequest Error"); 15807 } 15808 return callback(err, response, response.body) 15809 } 15810 15811 var xhr = options.xhr || null; 15812 15813 if (!xhr) { 15814 if (options.cors || options.useXDR) { 15815 xhr = new createXHR.XDomainRequest(); 15816 }else{ 15817 xhr = new createXHR.XMLHttpRequest(); 15818 } 15819 } 15820 15821 var key; 15822 var aborted; 15823 var uri = xhr.url = options.uri || options.url; 15824 var method = xhr.method = options.method || "GET"; 15825 var body = options.body || options.data; 15826 var headers = xhr.headers = options.headers || {}; 15827 var sync = !!options.sync; 15828 var isJson = false; 15829 var timeoutTimer; 15830 var failureResponse = { 15831 body: undefined, 15832 headers: {}, 15833 statusCode: 0, 15834 method: method, 15835 url: uri, 15836 rawRequest: xhr 15837 }; 15838 15839 if ("json" in options && options.json !== false) { 15840 isJson = true; 15841 headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json"); //Don't override existing accept header declared by user 15842 if (method !== "GET" && method !== "HEAD") { 15843 headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json"); //Don't override existing accept header declared by user 15844 body = JSON.stringify(options.json === true ? body : options.json); 15845 } 15846 } 15847 15848 xhr.onreadystatechange = readystatechange; 15849 xhr.onload = loadFunc; 15850 xhr.onerror = errorFunc; 15851 // IE9 must have onprogress be set to a unique function. 15852 xhr.onprogress = function () { 15853 // IE must die 15854 }; 15855 xhr.onabort = function(){ 15856 aborted = true; 15857 }; 15858 xhr.ontimeout = errorFunc; 15859 xhr.open(method, uri, !sync, options.username, options.password); 15860 //has to be after open 15861 if(!sync) { 15862 xhr.withCredentials = !!options.withCredentials; 15863 } 15864 // Cannot set timeout with sync request 15865 // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly 15866 // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent 15867 if (!sync && options.timeout > 0 ) { 15868 timeoutTimer = setTimeout(function(){ 15869 if (aborted) return 15870 aborted = true;//IE9 may still call readystatechange 15871 xhr.abort("timeout"); 15872 var e = new Error("XMLHttpRequest timeout"); 15873 e.code = "ETIMEDOUT"; 15874 errorFunc(e); 15875 }, options.timeout ); 15876 } 15877 15878 if (xhr.setRequestHeader) { 15879 for(key in headers){ 15880 if(headers.hasOwnProperty(key)){ 15881 xhr.setRequestHeader(key, headers[key]); 15882 } 15883 } 15884 } else if (options.headers && !isEmpty(options.headers)) { 15885 throw new Error("Headers cannot be set on an XDomainRequest object") 15886 } 15887 15888 if ("responseType" in options) { 15889 xhr.responseType = options.responseType; 15890 } 15891
15892 if ("beforeSend" in options && 15893 typeof options.beforeSend === "function" 15894 ) { 15895 options.beforeSend(xhr); 15896 } 15897 15898 // Microsoft Edge browser sends "undefined" when send is called with undefined value. 15899 // XMLHttpRequest spec says to pass null as body to indicate no body 15900 // See https://github.com/naugtur/xhr/issues/100. 15901 xhr.send(body || null); 15902 15903 return xhr 15904 15905 15906} 15907 15908function getXml(xhr) { 15909 // xhr.responseXML will throw Exception "InvalidStateError" or "DOMException" 15910 // See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseXML. 15911 try { 15912 if (xhr.responseType === "document") { 15913 return xhr.responseXML 15914 } 15915 var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"; 15916 if (xhr.responseType === "" && !firefoxBugTakenEffect) { 15917 return xhr.responseXML 15918 } 15919 } catch (e) {} 15920 15921 return null 15922} 15923 15924function noop() {} 15925 15926xhr.default = default_1; 15927 15928var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { 15929 return typeof obj; 15930} : function (obj) { 15931 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 15932}; 15933 15934 15935 15936 15937 15938var asyncGenerator = function () { 15939 function AwaitValue(value) { 15940 this.value = value; 15941 } 15942 15943 function AsyncGenerator(gen) { 15944 var front, back; 15945 15946 function send(key, arg) { 15947 return new Promise(function (resolve, reject) { 15948 var request = { 15949 key: key, 15950 arg: arg, 15951 resolve: resolve, 15952 reject: reject, 15953 next: null 15954 }; 15955 15956 if (back) { 15957 back = back.next = request; 15958 } else { 15959 front = back = request; 15960 resume(key, arg); 15961 } 15962 }); 15963 } 15964 15965 function resume(key, arg) { 15966 try { 15967 var result = gen[key](arg); 15968 var value = result.value; 15969 15970 if (value instanceof AwaitValue) { 15971 Promise.resolve(value.value).then(function (arg) { 15972 resume("next", arg); 15973 }, function (arg) { 15974 resume("throw", arg); 15975 }); 15976 } else { 15977 settle(result.done ? "return" : "normal", result.value); 15978 } 15979 } catch (err) { 15980 settle("throw", err); 15981 } 15982 } 15983 15984 function settle(type, value) { 15985 switch (type) { 15986 case "return": 15987 front.resolve({ 15988 value: value, 15989 done: true 15990 }); 15991 break; 15992 15993 case "throw": 15994 front.reject(value); 15995 break; 15996 15997 default: 15998 front.resolve({ 15999 value: value, 16000 done: false 16001 }); 16002 break; 16003 } 16004 16005 front = front.next; 16006 16007 if (front) { 16008 resume(front.key, front.arg); 16009 } else { 16010 back = null; 16011 } 16012 } 16013 16014 this._invoke = send; 16015 16016 if (typeof gen.return !== "function") { 16017 this.return = undefined; 16018 } 16019 } 16020 16021 if (typeof Symbol === "function" && Symbol.asyncIterator) { 16022 AsyncGenerator.prototype[Symbol.asyncIterator] = function () { 16023 return this; 16024 }; 16025 } 16026 16027 AsyncGenerator.prototype.next = function (arg) { 16028 return this._invoke("next", arg); 16029 }; 16030 16031 AsyncGenerator.prototype.throw = function (arg) { 16032 return this._invoke("throw", arg); 16033 }; 16034 16035 AsyncGenerator.prototype.return = function (arg) { 16036 return this._invoke("return", arg); 16037 }; 16038 16039 return { 16040 wrap: function (fn) { 16041 return function () { 16042 return new AsyncGenerator(fn.apply(this, arguments)); 16043 }; 16044 }, 16045 await: function (value) { 16046 return new AwaitValue(value); 16047 } 16048 }; 16049}(); 16050 16051 16052 16053 16054 16055var classCallCheck = function (instance, Constructor) { 16056 if (!(instance instanceof Constructor)) { 16057 throw new TypeError("Cannot call a class as a function"); 16058 } 16059}; 16060 16061var createClass = function () { 16062 function defineProperties(target, props) { 16063 for (var i = 0; i < props.length; i++) { 16064 var descriptor = props[i]; 16065 descriptor.enumerable = descriptor.enumerable || false; 16066 descriptor.configurable = true; 16067 if ("value" in descriptor) descriptor.writable = true; 16068 Object.defineProperty(target, descriptor.key, descriptor); 16069 } 16070 } 16071 16072 return function (Constructor, protoProps, staticProps) { 16073 if (protoProps) defineProperties(Constructor.prototype, protoProps); 16074 if (staticProps) defineProperties(Constructor, staticProps); 16075 return Constructor; 16076 }; 16077}(); 16078 16079 16080 16081 16082 16083 16084 16085 16086 16087 16088 16089 16090 16091 16092 16093 16094 16095 16096 16097 16098 16099 16100 16101 16102 16103 16104 16105 16106 16107 16108 16109 16110 16111 16112 16113 16114 16115 16116 16117 16118 16119var toConsumableArray = function (arr) { 16120 if (Array.isArray(arr)) { 16121 for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; 16122 16123 return arr2; 16124 } else { 16125 return Array.from(arr); 16126 } 16127}; 16128 16129var lastError = ''; 16130 16131/** 16132 * Creates the HTLM for a failure message 16133 * @param {string} canvasContainerId id of container of th 16134 * canvas. 16135 * @return {string} The html. 16136 */ 16137function makeFailHTML(msg) { 16138 return '\n<table style="background-color: #8CE; width: 100%; height: 100%;"><tr>\n<td align="center">\n<div style="display: table-cell; vertical-align: middle;">\n<div style="">' + msg + '</div>\n</div>\n</td></tr></table>\n'; 16139} 16140
16141/** 16142 * Message for getting a webgl browser 16143 * @type {string} 16144 */ 16145var GET_A_WEBGL_BROWSER = '\n\tThis page requires a browser that supports WebGL.<br/>\n\t<a href="http://get.webgl.org">Click here to upgrade your browser.</a>\n'; 16146 16147/** 16148 * Message for need better hardware 16149 * @type {string} 16150 */ 16151var OTHER_PROBLEM = '\n\tIt does not appear your computer can support WebGL.<br/>\n\t<a href="http://get.webgl.org/troubleshooting/">Click here for more information.</a>\n'; 16152 16153/** 16154 * Code to return in `onError` callback when the browser doesn't support webgl 16155 * @type {number} 16156 */ 16157var ERROR_BROWSER_SUPPORT = 1; 16158 16159/** 16160 * Code to return in `onError` callback there's any other problem related to webgl 16161 * @type {number} 16162 */ 16163var ERROR_OTHER = 2; 16164 16165/** 16166 * Creates a webgl context. If creation fails it will 16167 * change the contents of the container of the <canvas> 16168 * tag to an error message with the correct links for WebGL, 16169 * unless `onError` option is defined to a callback, 16170 * which allows for custom error handling.. 16171 * @param {Element} canvas. The canvas element to create a 16172 * context from. 16173 * @param {WebGLContextCreationAttributes} optAttribs Any 16174 * creation attributes you want to pass in. 16175 * @return {WebGLRenderingContext} The created context. 16176 */ 16177function setupWebGL(canvas, optAttribs, onError) { 16178 function showLink(str) { 16179 var container = canvas.parentNode; 16180 if (container) { 16181 container.innerHTML = makeFailHTML(str); 16182 } 16183 } 16184 16185 function handleError(errorCode, msg) { 16186 if (typeof onError === 'function') { 16187 onError(errorCode); 16188 } else { 16189 showLink(msg); 16190 } 16191 } 16192 16193 if (!window.WebGLRenderingContext) { 16194 handleError(ERROR_BROWSER_SUPPORT, GET_A_WEBGL_BROWSER); 16195 return null; 16196 } 16197 16198 var context = create3DContext(canvas, optAttribs); 16199 if (!context) { 16200 handleError(ERROR_OTHER, OTHER_PROBLEM); 16201 } else { 16202 context.getExtension('OES_standard_derivatives'); 16203 } 16204 return context; 16205} 16206 16207/** 16208 * Creates a webgl context. 16209 * @param {!Canvas} canvas The canvas tag to get context 16210 * from. If one is not passed in one will be created. 16211 * @return {!WebGLContext} The created context. 16212 */ 16213function create3DContext(canvas, optAttribs) {
16214 var names = ['webgl', 'experimental-webgl']; 16215 var context = null; 16216 for (var ii = 0; ii < names.length; ++ii) { 16217 try { 16218 context = canvas.getContext(names[ii], optAttribs); 16219 } catch (e) { 16220 if (context) { 16221 break; 16222 } 16223 } 16224 } 16225 return context; 16226} 16227 16228/* 16229 * Create a Vertex of a specific type (gl.VERTEX_SHADER/) 16230 */ 16231function createShader(main, source, type, offset) { 16232 var gl = main.gl; 16233 16234 var shader = gl.createShader(type); 16235 gl.shaderSource(shader, source); 16236 gl.compileShader(shader); 16237 16238 var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); 16239 16240 if (!compiled) { 16241 // Something went wrong during compilation; get the error 16242 lastError = gl.getShaderInfoLog(shader); 16243 console.error('*** Error compiling shader ' + shader + ':' + lastError); 16244 main.trigger('error', { 16245 shader: shader, 16246 source: source, 16247 type: type, 16248 error: lastError, 16249 offset: offset || 0 16250 }); 16251 gl.deleteShader(shader); 16252 return null; 16253 } 16254 16255 return shader; 16256} 16257 16258/** 16259 * Loads a shader. 16260 * @param {!WebGLContext} gl The WebGLContext to use. 16261 * @param {string} shaderSource The shader source. 16262 * @param {number} shaderType The type of shader. 16263 * @param {function(string): void) opt_errorCallback callback for errors. 16264 * @return {!WebGLShader} The created shader. 16265 */ 16266function createProgram(main, shaders, optAttribs, optLocations) { 16267 var gl = main.gl; 16268 16269 var program = gl.createProgram(); 16270 for (var ii = 0; ii < shaders.length; ++ii) { 16271 gl.attachShader(program, shaders[ii]); 16272 } 16273 if (optAttribs) { 16274 for (var _ii = 0; _ii < optAttribs.length; ++_ii) { 16275 gl.bindAttribLocation(program, optLocations ? optLocations[_ii] : _ii, optAttribs[_ii]); 16276 } 16277 } 16278 gl.linkProgram(program); 16279 16280 // Check the link status 16281 var linked = gl.getProgramParameter(program, gl.LINK_STATUS); 16282 if (!linked) { 16283 // something went wrong with the link 16284 lastError = gl.getProgramInfoLog(program); 16285 console.log('Error in program linking:' + lastError); 16286 gl.deleteProgram(program); 16287 return null; 16288 } 16289 return program; 16290} 16291 16292// By Brett Camber on 16293// https://github.com/tangrams/tangram/blob/master/src/gl/glsl.js 16294function parseUniforms(uniforms) { 16295 var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 16296 16297 var parsed = []; 16298 16299 for (var name in uniforms) { 16300 var uniform = uniforms[name]; 16301 var u = void 0; 16302 16303 if (prefix) { 16304 name = prefix + '.' + name; 16305 } 16306 16307 // Single float 16308 if (typeof uniform === 'number') { 16309 parsed.push({ 16310 type: 'float', 16311 method: '1f', 16312 name: name, 16313 value: uniform 16314 }); 16315 } 16316 // Array: vector, array of floats, array of textures, or array of structs 16317 else if (Array.isArray(uniform)) { 16318 // Numeric values 16319 if (typeof uniform[0] === 'number') { 16320 // float vectors (vec2, vec3, vec4) 16321 if (uniform.length === 1) { 16322 parsed.push({ 16323 type: 'float', 16324 method: '1f', 16325 name: name, 16326 value: uniform 16327 }); 16328 } 16329 // float vectors (vec2, vec3, vec4) 16330 else if (uniform.length >= 2 && uniform.length <= 4) { 16331 parsed.push({ 16332 type: 'vec' + uniform.length, 16333 method: uniform.length + 'fv', 16334 name: name, 16335 value: uniform 16336 }); 16337 } 16338 // float array 16339 else if (uniform.length > 4) { 16340 parsed.push({ 16341 type: 'float[]', 16342 method: '1fv', 16343 name: name + '[0]', 16344 value: uniform 16345 }); 16346 } 16347 // TODO: assume matrix for (typeof == Float32Array && length == 16)? 16348 } 16349 // Array of textures 16350 else if (typeof uniform[0] === 'string') { 16351 parsed.push({ 16352 type: 'sampler2D', 16353 method: '1i', 16354 name: name, 16355 value: uniform 16356 }); 16357 } 16358 // Array of arrays - but only arrays of vectors are allowed in this case 16359 else if (Array.isArray(uniform[0]) && typeof uniform[0][0] === 'number') { 16360 // float vectors (vec2, vec3, vec4) 16361 if (uniform[0].length >= 2 && uniform[0].length <= 4) { 16362 // Set each vector in the array 16363 for (u = 0; u < uniform.length; u++) { 16364 parsed.push({ 16365 type: 'vec' + uniform[0].length, 16366 method: uniform[u].length + 'fv', 16367 name: name + '[' + u + ']', 16368 value: uniform[u] 16369 }); 16370 } 16371 } 16372 // else error? 16373 } 16374 // Array of structures 16375 else if (_typeof(uniform[0]) === 'object') { 16376 for (u = 0; u < uniform.length; u++) { 16377 // Set each struct in the array
16378 parsed.push.apply(parsed, toConsumableArray(parseUniforms(uniform[u], name + '[' + u + ']'))); 16379 } 16380 } 16381 } 16382 // Boolean 16383 else if (typeof uniform === 'boolean') { 16384 parsed.push({ 16385 type: 'bool', 16386 method: '1i', 16387 name: name, 16388 value: uniform 16389 }); 16390 } 16391 // Texture 16392 else if (typeof uniform === 'string') { 16393 parsed.push({ 16394 type: 'sampler2D', 16395 method: '1i', 16396 name: name, 16397 value: uniform 16398 }); 16399 } 16400 // Structure 16401 else if ((typeof uniform === 'undefined' ? 'undefined' : _typeof(uniform)) === 'object') { 16402 // Set each field in the struct 16403 parsed.push.apply(parsed, toConsumableArray(parseUniforms(uniform, name))); 16404 } 16405 // TODO: support other non-float types? (int, etc.) 16406 } 16407 return parsed; 16408} 16409 16410function isCanvasVisible(canvas) { 16411 var bound = canvas.getBoundingClientRect(); 16412 return bound.top + bound.height > 0 && bound.top < (window.innerHeight || document.documentElement.clientHeight); 16413} 16414 16415function isPowerOf2(value) { 16416 return (value & value - 1) === 0; 16417} 16418 16419function isSafari() { 16420 return (/^((?!chrome|android).)*safari/i.test(navigator.userAgent) 16421 ); 16422} 16423 16424 16425 16426 16427 16428 16429 16430function isDiff(a, b) { 16431 if (a && b) { 16432 return a.toString() !== b.toString(); 16433 } 16434 return false; 16435} 16436 16437function getFile(url) { 16438 var httpRequest = new XMLHttpRequest(); 16439 httpRequest.open("GET", url, false); 16440 httpRequest.send(); 16441 if (httpRequest.status == 200) return httpRequest.responseText;else return ""; 16442} 16443 16444function subscribeMixin$1(target) { 16445 var listeners = new Set(); 16446 16447 return Object.assign(target, { 16448 on: function on(type, f) { 16449 var listener = {}; 16450 listener[type] = f; 16451 listeners.add(listener); 16452 }, 16453 off: function off(type, f) { 16454 if (f) { 16455 var listener = {}; 16456 listener[type] = f; 16457 listeners.delete(listener); 16458 } else { 16459 var _iteratorNormalCompletion = true; 16460 var _didIteratorError = false; 16461 var _iteratorError = undefined; 16462 16463 try { 16464 for (var _iterator = listeners[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { 16465 var item = _step.value; 16466 var _iteratorNormalCompletion2 = true; 16467 var _didIteratorError2 = false;
16468 var _iteratorError2 = undefined; 16469 16470 try { 16471 for (var _iterator2 = Object.keys(item)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { 16472 var key = _step2.value; 16473 16474 if (key === type) { 16475 listeners.delete(item); 16476 return; 16477 } 16478 } 16479 } catch (err) { 16480 _didIteratorError2 = true; 16481 _iteratorError2 = err; 16482 } finally { 16483 try { 16484 if (!_iteratorNormalCompletion2 && _iterator2.return) { 16485 _iterator2.return(); 16486 } 16487 } finally { 16488 if (_didIteratorError2) { 16489 throw _iteratorError2; 16490 } 16491 } 16492 } 16493 } 16494 } catch (err) { 16495 _didIteratorError = true; 16496 _iteratorError = err; 16497 } finally { 16498 try { 16499 if (!_iteratorNormalCompletion && _iterator.return) { 16500 _iterator.return(); 16501 } 16502 } finally { 16503 if (_didIteratorError) { 16504 throw _iteratorError; 16505 } 16506 } 16507 } 16508 } 16509 }, 16510 listSubscriptions: function listSubscriptions() { 16511 var _iteratorNormalCompletion3 = true; 16512 var _didIteratorError3 = false; 16513 var _iteratorError3 = undefined; 16514 16515 try { 16516 for (var _iterator3 = listeners[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { 16517 var item = _step3.value; 16518 16519 console.log(item); 16520 } 16521 } catch (err) { 16522 _didIteratorError3 = true; 16523 _iteratorError3 = err; 16524 } finally { 16525 try { 16526 if (!_iteratorNormalCompletion3 && _iterator3.return) { 16527 _iterator3.return(); 16528 } 16529 } finally { 16530 if (_didIteratorError3) { 16531 throw _iteratorError3; 16532 } 16533 } 16534 } 16535 }, 16536 subscribe: function subscribe(listener) { 16537 listeners.add(listener); 16538 }, 16539 unsubscribe: function unsubscribe(listener) { 16540 listeners.delete(listener); 16541 }, 16542 unsubscribeAll: function unsubscribeAll() { 16543 listeners.clear(); 16544 }, 16545 trigger: function trigger(event) { 16546 for (var _len = arguments.length, data = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 16547 data[_key - 1] = arguments[_key]; 16548 } 16549 16550 var _iteratorNormalCompletion4 = true; 16551 var _didIteratorError4 = false; 16552 var _iteratorError4 = undefined; 16553 16554 try { 16555 for (var _iterator4 = listeners[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { 16556 var listener = _step4.value; 16557 16558 if (typeof listener[event] === 'function') { 16559 listener[event].apply(listener, toConsumableArray(data)); 16560 } 16561 } 16562 } catch (err) { 16563 _didIteratorError4 = true; 16564 _iteratorError4 = err; 16565 } finally { 16566 try { 16567 if (!_iteratorNormalCompletion4 && _iterator4.return) { 16568 _iterator4.return(); 16569 } 16570 } finally { 16571 if (_didIteratorError4) { 16572 throw _iteratorError4; 16573 } 16574 } 16575 } 16576 } 16577 }); 16578} 16579 16580// Texture management 16581// GL texture wrapper object for keeping track of a global set of textures, keyed by a unique user-defined name 16582 16583var Texture = function () { 16584 function Texture(gl, name) { 16585 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 16586 classCallCheck(this, Texture); 16587 16588 subscribeMixin$1(this); 16589 16590 this.gl = gl; 16591 this.texture = gl.createTexture(); 16592 if (this.texture) { 16593 this.valid = true; 16594 } 16595 this.bind(); 16596 16597 this.name = name; 16598 this.source = null; 16599 this.sourceType = null; 16600 this.loading = null; // a Promise object to track the loading state of this texture 16601 16602 // Default to a 1-pixel black texture so we can safely render while we wait for an image to load 16603 // See: http://stackoverflow.com/questions/19722247/webgl-wait-for-texture-to-load 16604 this.setData(1, 1, new Uint8Array([0, 0, 0, 255]), { filtering: 'linear' }); 16605 this.setFiltering(options.filtering); 16606 16607 this.load(options); 16608 } 16609 16610 // Destroy a single texture instance 16611 16612 16613 createClass(Texture, [{ 16614 key: 'destroy', 16615 value: function destroy() { 16616 if (!this.valid) { 16617 return; 16618 } 16619 this.gl.deleteTexture(this.texture); 16620 this.texture = null; 16621 delete this.data; 16622 this.data = null; 16623 this.valid = false;
16624 } 16625 }, { 16626 key: 'bind', 16627 value: function bind(unit) { 16628 if (!this.valid) { 16629 return; 16630 } 16631 if (typeof unit === 'number') { 16632 if (Texture.activeUnit !== unit) { 16633 this.gl.activeTexture(this.gl.TEXTURE0 + unit); 16634 Texture.activeUnit = unit; 16635 } 16636 } 16637 if (Texture.activeTexture !== this.texture) { 16638 this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture); 16639 Texture.activeTexture = this.texture; 16640 } 16641 } 16642 }, { 16643 key: 'load', 16644 value: function load() { 16645 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 16646 16647 this.loading = null; 16648 16649 if (typeof options.url === 'string') { 16650 if (this.url === undefined || options.url !== this.url) { 16651 this.setUrl(options.url, options); 16652 } 16653 } else if (options.element) { 16654 this.setElement(options.element, options); 16655 } else if (options.data && options.width && options.height) { 16656 this.setData(options.width, options.height, options.data, options); 16657 } 16658 } 16659 16660 // Sets texture from an url 16661 16662 }, { 16663 key: 'setUrl', 16664 value: function setUrl(url) { 16665 var _this = this; 16666 16667 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 16668 16669 if (!this.valid) { 16670 return; 16671 } 16672 16673 this.url = url; // save URL reference (will be overwritten when element is loaded below) 16674 this.source = this.url; 16675 this.sourceType = 'url'; 16676 16677 this.loading = new Promise(function (resolve, reject) { 16678 var ext = url.split('.').pop().toLowerCase(); 16679 var isVideo = ext === 'ogv' || ext === 'webm' || ext === 'mp4'; 16680 16681 var element = undefined; 16682 if (isVideo) { 16683 element = document.createElement('video'); 16684 element.autoplay = true; 16685 16686 element.muted = true; /* required for modern browsers to autoplay video */ 16687 setTimeout(function () { 16688 element.play(); /* doesn't block promise but needs a more elegant solution */ 16689 }, 1); 16690 16691 options.filtering = 'nearest'; 16692 // element.preload = 'auto'; 16693 // element.style.display = 'none'; 16694 // document.body.appendChild(element); 16695 } else { 16696 element = new Image(); 16697 } 16698 16699 element.onload = function () { 16700 try { 16701 _this.setElement(element, options); 16702 } catch (e) { 16703 console.log('Texture \'' + _this.name + '\': failed to load url: \'' + _this.source + '\'', e, options); 16704 } 16705 resolve(_this); 16706 }; 16707 element.onerror = function (e) { 16708 // Warn and resolve on error 16709 console.log('Texture \'' + _this.name + '\': failed to load url: \'' + _this.source + '\'', e, options); 16710 resolve(_this); 16711 }; 16712 16713 // Safari has a bug loading data-URL elements with CORS enabled, so it must be disabled in that case 16714 // https://bugs.webkit.org/show_bug.cgi?id=123978 16715 if (!(isSafari() && _this.source.slice(0, 5) === 'data:')) { 16716 element.crossOrigin = 'anonymous'; 16717 } 16718 16719 element.src = _this.source; 16720 if (isVideo) { 16721 _this.setElement(element, options); 16722 } 16723 }); 16724 return this.loading; 16725 } 16726 16727 // Sets texture to a raw image buffer 16728 16729 }, { 16730 key: 'setData', 16731 value: function setData(width, height, data) { 16732 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; 16733 16734 this.width = width; 16735 this.height = height; 16736 16737 this.source = data; 16738 this.sourceType = 'data'; 16739 16740 this.update(options); 16741 this.setFiltering(options); 16742 16743 this.loading = Promise.resolve(this); 16744 return this.loading; 16745 } 16746 16747 // Sets the texture to track a element (canvas/image) 16748 16749 }, {
16750 key: 'setElement', 16751 value: function setElement(element, options) { 16752 var _this2 = this; 16753 16754 var el = element; 16755 16756 // a string element is interpeted as a CSS selector 16757 if (typeof element === 'string') { 16758 element = document.querySelector(element); 16759 } 16760 16761 if (element instanceof HTMLCanvasElement || element instanceof HTMLImageElement || element instanceof HTMLVideoElement) { 16762 this.source = element; 16763 this.sourceType = 'element'; 16764 16765 if (element instanceof HTMLVideoElement) { 16766 this.width = this.source.videoWidth; 16767 this.height = this.source.videoHeight; 16768 element.addEventListener('canplaythrough', function () { 16769 _this2.intervalID = setInterval(function () { 16770 _this2.update(options); 16771 }, 15); 16772 }, true); 16773 element.addEventListener('ended', function () { 16774 element.currentTime = 0; 16775 element.play(); 16776 }, true); 16777 } else { 16778 this.update(options); 16779 } 16780 this.setFiltering(options); 16781 } else { 16782 var msg = 'the \'element\' parameter (`element: ' + JSON.stringify(el) + '`) must be a CSS '; 16783 msg += 'selector string, or a <canvas>, <image> or <video> object'; 16784 console.log('Texture \'' + this.name + '\': ' + msg, options); 16785 } 16786 16787 this.loading = Promise.resolve(this); 16788 return this.loading; 16789 } 16790 16791 // Uploads current image or buffer to the GPU (can be used to update animated textures on the fly) 16792 16793 }, { 16794 key: 'update', 16795 value: function update() { 16796 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 16797 16798 if (!this.valid) { 16799 return; 16800 } 16801 16802 this.bind(); 16803 this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, options.UNPACK_FLIP_Y_WEBGL === false ? false : true); 16804 this.gl.pixelStorei(this.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, options.UNPACK_PREMULTIPLY_ALPHA_WEBGL || false); 16805 16806 // Image or Canvas element 16807 if (this.sourceType === 'element' && (this.source instanceof HTMLCanvasElement || this.source instanceof HTMLVideoElement || this.source instanceof HTMLImageElement && this.source.complete)) { 16808 if (this.source instanceof HTMLVideoElement) { 16809 this.width = this.source.videoWidth; 16810 this.height = this.source.videoHeight; 16811 } else { 16812 this.width = this.source.width; 16813 this.height = this.source.height; 16814 } 16815 this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, this.source); 16816 } 16817 // Raw image buffer 16818 else if (this.sourceType === 'data') { 16819 this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.width, this.height, 0, this.gl.RGBA, this.gl.UNSIGNED_BYTE, this.source); 16820 } 16821 this.trigger('loaded', this); 16822 } 16823 16824 // Determines appropriate filtering mode 16825 16826 }, { 16827 key: 'setFiltering', 16828 value: function setFiltering() { 16829 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 16830 16831 if (!this.valid) { 16832 return; 16833 } 16834 16835 this.powerOf2 = isPowerOf2(this.width) && isPowerOf2(this.height); 16836 // let defualtFilter = (this.powerOf2 ? 'mipmap' : 'linear'); 16837 // this.filtering = options.filtering || defualtFilter; 16838 this.filtering = options.filtering || 'linear'; 16839 16840 var gl = this.gl; 16841 this.bind(); 16842 16843 // For power-of-2 textures, the following presets are available: 16844 // mipmap: linear blend from nearest mip 16845 // linear: linear blend from original image (no mips) 16846 // nearest: nearest pixel from original image (no mips, 'blocky' look) 16847 if (this.powerOf2) { 16848 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, options.TEXTURE_WRAP_S || gl.REPEAT); 16849 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, options.TEXTURE_WRAP_T || gl.REPEAT); 16850 16851 if (this.filtering === 'mipmap') { 16852 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); // TODO: use trilinear filtering by defualt instead? 16853 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 16854 gl.generateMipmap(gl.TEXTURE_2D); 16855 } else if (this.filtering === 'linear') { 16856 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 16857 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 16858 } else if (this.filtering === 'nearest') { 16859 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 16860 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 16861 } 16862 } else { 16863 // WebGL has strict requirements on non-power-of-2 textures: 16864 // No mipmaps and must clamp to edge 16865 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 16866 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 16867 16868 if (this.filtering === 'mipmap') { 16869 this.filtering = 'linear'; 16870 } 16871 16872 if (this.filtering === 'nearest') { 16873 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 16874 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 16875 } else { 16876 // default to linear for non-power-of-2 textures 16877 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 16878 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 16879 } 16880 } 16881 } 16882 }]); 16883 return Texture; 16884}(); 16885 16886Texture.getMaxTextureSize = function (gl) { 16887 return gl.getParameter(gl.MAX_TEXTURE_SIZE); 16888}; 16889 16890// Global set of textures, by name 16891Texture.activeUnit = -1; 16892 16893/* 16894The MIT License (MIT) 16895 16896Copyright (c) 2015 Patricio Gonzalez Vivo ( http://www.patriciogonzalezvivo.com ) 16897 16898Permission is hereby granted, free of charge, to any person obtaining a copy of 16899this software and associated documentation files (the 'Software'), to deal in 16900the Software without restriction, including without limitation the rights to 16901use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 16902the Software, and to permit persons to whom the Software is furnished to do so, 16903subject to the following conditions: 16904 16905The above copyright notice and this permission notice shall be included in all 16906copies or substantial portions of the Software. 16907 16908THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16909IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 16910FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16911COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 16912IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16913CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16914*/ 16915 16916var GlslCanvas = function () { 16917 function GlslCanvas(canvas, contextOptions, options) { 16918 var _this = this; 16919 16920 classCallCheck(this, GlslCanvas); 16921 16922 subscribeMixin$1(this); 16923 16924 contextOptions = contextOptions || {}; 16925 options = options || {}; 16926 16927 if (canvas.hasAttribute('data-fullscreen') && (canvas.getAttribute('data-fullscreen') == "1" || canvas.getAttribute('data-fullscreen') == "true")) { 16928 this.width = window.innerWidth; 16929 this.height = window.innerHeight; 16930 canvas.width = window.innerWidth; 16931 canvas.height = window.innerHeight; 16932 } else { 16933 this.width = canvas.clientWidth; 16934 this.height = canvas.clientHeight; 16935 } 16936 16937 this.canvas = canvas; 16938 this.gl = undefined; 16939 this.deps = {}; 16940 this.program = undefined; 16941 this.textures = {}; 16942 this.buffers = {}; 16943 this.uniforms = {}; 16944 this.vbo = {}; 16945 this.isValid = false;
16946 this.animationFrameRequest = undefined; 16947 16948 this.BUFFER_COUNT = 0; 16949 // this.TEXTURE_COUNT = 0; 16950 16951 this.vertexString = contextOptions.vertexString || '\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nattribute vec2 a_position;\nattribute vec2 a_texcoord;\n\nvarying vec2 v_texcoord;\n\nvoid main() {\n gl_Position = vec4(a_position, 0.0, 1.0);\n v_texcoord = a_texcoord;\n}\n'; 16952 this.fragmentString = contextOptions.fragmentString || '\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nvarying vec2 v_texcoord;\n\nvoid main(){\n gl_FragColor = vec4(0.0);\n}\n'; 16953 16954 // GL Context 16955 var gl = setupWebGL(canvas, contextOptions, options.onError); 16956 if (!gl) { 16957 return; 16958 } 16959 this.gl = gl; 16960 this.timeLoad = this.timePrev = performance.now(); 16961 this.timeDelta = 0.0; 16962 this.forceRender = true; 16963 this.paused = false; 16964 this.realToCSSPixels = window.devicePixelRatio || 1; 16965 16966 // Allow alpha 16967 canvas.style.backgroundColor = contextOptions.backgroundColor || 'rgba(1,1,1,0)'; 16968 16969 // Load shader 16970 if (canvas.hasAttribute('data-fragment')) { 16971 this.fragmentString = canvas.getAttribute('data-fragment'); 16972 } else if (canvas.hasAttribute('data-fragment-url')) { 16973 var source = canvas.getAttribute('data-fragment-url'); 16974 xhr.get(source, function (error, response, body) { 16975 _this.load(body, _this.vertexString); 16976 }); 16977 } 16978 16979 // Load shader 16980 if (canvas.hasAttribute('data-vertex')) { 16981 this.vertexString = canvas.getAttribute('data-vertex'); 16982 } else if (canvas.hasAttribute('data-vertex-url')) { 16983 var _source = canvas.getAttribute('data-vertex-url'); 16984 xhr.get(_source, function (error, response, body) { 16985 _this.load(_this.fragmentString, body); 16986 }); 16987 } 16988 16989 this.load(); 16990 16991 if (!this.program) { 16992 return; 16993 } 16994 16995 // Define Vertex buffer 16996 var texCoordsLoc = gl.getAttribLocation(this.program, 'a_texcoord'); 16997 this.vbo.texCoords = gl.createBuffer(); 16998 this.gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo.texCoords); 16999 this.gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0]), gl.STATIC_DRAW); 17000 this.gl.enableVertexAttribArray(texCoordsLoc); 17001 this.gl.vertexAttribPointer(texCoordsLoc, 2, gl.FLOAT, false, 0, 0); 17002 17003 var verticesLoc = gl.getAttribLocation(this.program, 'a_position'); 17004 this.vbo.vertices = gl.createBuffer(); 17005 this.gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo.vertices); 17006 this.gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0]), gl.STATIC_DRAW); 17007 this.gl.enableVertexAttribArray(verticesLoc); 17008 this.gl.vertexAttribPointer(verticesLoc, 2, gl.FLOAT, false, 0, 0); 17009 17010 // load TEXTURES 17011 if (canvas.hasAttribute('data-textures')) { 17012 var imgList = canvas.getAttribute('data-textures').split(','); 17013 for (var nImg in imgList) { 17014 this.setUniform('u_tex' + nImg, imgList[nImg]); 17015 } 17016 } 17017 17018 // ========================== EVENTS 17019 var mouse = { 17020 x: 0, 17021 y: 0 17022 }; 17023 document.addEventListener('mousemove', function (e) { 17024 mouse.x = e.clientX || e.pageX; 17025 mouse.y = e.clientY || e.pageY; 17026 }, false); 17027 17028 var sandbox = this;
17029 function RenderLoop() { 17030 if (sandbox.nMouse > 1) { 17031 sandbox.setMouse(mouse); 17032 } 17033 17034 if (sandbox.resize()) { 17035 sandbox.forceRender = true; 17036 } 17037 17038 sandbox.render(); 17039 sandbox.animationFrameRequest = window.requestAnimationFrame(RenderLoop); 17040 } 17041 17042 // Start 17043 this.setMouse({ x: 0, y: 0 }); 17044 RenderLoop(); 17045 return this; 17046 } 17047 17048 createClass(GlslCanvas, [{ 17049 key: 'destroy', 17050 value: function destroy() { 17051 // Stop the animation 17052 cancelAnimationFrame(this.animationFrameRequest); 17053 17054 this.animated = false; 17055 this.isValid = false; 17056 for (var tex in this.textures) { 17057 if (tex.destroy) { 17058 tex.destroy(); 17059 } 17060 } 17061 this.textures = {}; 17062 for (var att in this.attribs) { 17063 this.gl.deleteBuffer(this.attribs[att]); 17064 } 17065 this.gl.useProgram(null); 17066 this.gl.deleteProgram(this.program); 17067 for (var key in this.buffers) { 17068 var buffer = this.buffers[key]; 17069 this.gl.deleteProgram(buffer.program); 17070 } 17071 17072 this.program = null; 17073 this.gl = null; 17074 } 17075 }, { 17076 key: 'load', 17077 value: function load(fragString, vertString) { 17078 var _this2 = this; 17079 17080 // Load vertex shader if there is one 17081 if (vertString) { 17082 this.vertexString = vertString; 17083 } 17084 17085 // Load fragment shader if there is one 17086 if (fragString) { 17087 this.fragmentString = fragString; 17088 } 17089 17090 var lines = this.fragmentString.split(/\r?\n/); 17091 this.fragmentString = "#define PLATFORM_WEBGL\n#line 0\n"; 17092 17093 lines.forEach(function (line, i) { 17094 var line_trim = line.trim(); 17095 if (line_trim.startsWith('#include \"lygia')) { 17096 var dep = line_trim.substring(15).replace(/\'|\"|\;|\s/g, ''); 17097 if (dep.endsWith('glsl')) { 17098 if (_this2.deps[dep] === undefined) { 17099 var url = "https://lygia.xyz" + dep; 17100 _this2.deps[dep] = getFile(url); 17101 } 17102 _this2.fragmentString += _this2.deps[dep] + '\n#line ' + (i + 1) + '\n'; 17103 } 17104 } else _this2.fragmentString += line + '\n'; 17105 }); 17106 17107 // console.log(this.fragmentString); 17108 17109 this.animated = false; 17110 this.nDelta = (this.fragmentString.match(/u_delta/g) || []).length; 17111 this.nTime = (this.fragmentString.match(/u_time/g) || []).length; 17112 this.nDate = (this.fragmentString.match(/u_date/g) || []).length; 17113 this.nMouse = (this.fragmentString.match(/u_mouse/g) || []).length; 17114 this.animated = this.nDate > 1 || this.nTime > 1 || this.nMouse > 1; 17115 17116 var nTextures = this.fragmentString.search(/sampler2D/g); 17117 if (nTextures) { 17118 var _lines = this.fragmentString.split('\n'); 17119 for (var i = 0; i < _lines.length; i++) { 17120 var match = _lines[i].match(/uniform\s*sampler2D\s*([\w]*);\s*\/\/\s*([\w|\:\/\/|\.|\-|\_]*)/i); 17121 if (match) { 17122 var ext = match[2].split('.').pop().toLowerCase(); 17123 if (match[1] && match[2] && (ext === 'jpg' || ext === 'jpeg' || ext === 'png' || ext === 'ogv' || ext === 'webm' || ext === 'mp4')) { 17124 this.setUniform(match[1], match[2]); 17125 } 17126 } 17127 var main = _lines[i].match(/\s*void\s*main\s*/g); 17128 if (main) { 17129 break; 17130 } 17131 } 17132 } 17133 17134 var vertexShader = createShader(this, this.vertexString, this.gl.VERTEX_SHADER); 17135 var fragmentShader = createShader(this, this.fragmentString, this.gl.FRAGMENT_SHADER); 17136 17137 // If Fragment shader fails load a empty one to sign the error 17138 if (!fragmentShader) { 17139 fragmentShader = createShader(this, 'void main(){\n\tgl_FragColor = vec4(1.0);\n}', this.gl.FRAGMENT_SHADER); 17140 this.isValid = false;
17141 } else { 17142 this.isValid = true; 17143 } 17144 17145 // Create and use program 17146 var program = createProgram(this, [vertexShader, fragmentShader]); //, [0,1],['a_texcoord','a_position']); 17147 this.gl.useProgram(program); 17148 17149 // Delete shaders 17150 // this.gl.detachShader(program, vertexShader); 17151 // this.gl.detachShader(program, fragmentShader); 17152 this.gl.deleteShader(vertexShader); 17153 this.gl.deleteShader(fragmentShader); 17154 17155 this.program = program; 17156 this.change = true; 17157 17158 this.BUFFER_COUNT = 0; 17159 var buffers = this.getBuffers(this.fragmentString); 17160 if (Object.keys(buffers).length) { 17161 this.loadPrograms(buffers); 17162 } 17163 this.buffers = buffers; 17164 this.texureIndex = this.BUFFER_COUNT; 17165 17166 // Trigger event 17167 this.trigger('load', {}); 17168 17169 this.forceRender = true; 17170 this.render(); 17171 } 17172 }, { 17173 key: 'test', 17174 value: function test(callback, fragString, vertString) { 17175 // Thanks to @thespite for the help here 17176 // https://www.khronos.org/registry/webgl/extensions/EXT_disjoint_timer_query/ 17177 var pre_test_vert = this.vertexString; 17178 var pre_test_frag = this.fragmentString; 17179 var pre_test_paused = this.paused; 17180 17181 var ext = this.gl.getExtension('EXT_disjoint_timer_query'); 17182 var query = ext.createQueryEXT(); 17183 var wasValid = this.isValid; 17184 17185 if (fragString || vertString) { 17186 this.load(fragString, vertString); 17187 wasValid = this.isValid; 17188 this.forceRender = true; 17189 this.render(); 17190 } 17191 17192 this.paused = true; 17193 ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query); 17194 this.forceRender = true; 17195 this.render(); 17196 ext.endQueryEXT(ext.TIME_ELAPSED_EXT); 17197 17198 var sandbox = this; 17199 function finishTest() { 17200 // Revert changes... go back to normal 17201 sandbox.paused = pre_test_paused; 17202 if (fragString || vertString) { 17203 sandbox.load(pre_test_frag, pre_test_vert); 17204 } 17205 } 17206 function waitForTest() { 17207 sandbox.forceRender = true; 17208 sandbox.render(); 17209 var available = ext.getQueryObjectEXT(query, ext.QUERY_RESULT_AVAILABLE_EXT); 17210 var disjoint = sandbox.gl.getParameter(ext.GPU_DISJOINT_EXT); 17211 if (available && !disjoint) { 17212 var ret = { 17213 wasValid: wasValid, 17214 frag: fragString || sandbox.fragmentString, 17215 vert: vertString || sandbox.vertexString, 17216 timeElapsedMs: ext.getQueryObjectEXT(query, ext.QUERY_RESULT_EXT) / 1000000.0 17217 }; 17218 finishTest(); 17219 callback(ret); 17220 } else { 17221 window.requestAnimationFrame(waitForTest); 17222 } 17223 } 17224 waitForTest(); 17225 } 17226 }, { 17227 key: 'loadTexture', 17228 value: function loadTexture(name, urlElementOrData, options) { 17229 var _this3 = this; 17230 17231 if (!options) { 17232 options = {}; 17233 } 17234 17235 if (typeof urlElementOrData === 'string') { 17236 options.url = urlElementOrData; 17237 } else if ((typeof urlElementOrData === 'undefined' ? 'undefined' : _typeof(urlElementOrData)) === 'object' && urlElementOrData.data && urlElementOrData.width && urlElementOrData.height) { 17238 options.data = urlElementOrData.data; 17239 options.width = urlElementOrData.width; 17240 options.height = urlElementOrData.height; 17241 } else if ((typeof urlElementOrData === 'undefined' ? 'undefined' : _typeof(urlElementOrData)) === 'object') { 17242 options.element = urlElementOrData; 17243 } 17244 17245 if (this.textures[name]) { 17246 if (this.textures[name]) { 17247 this.textures[name].load(options); 17248 this.textures[name].on('loaded', function (args) { 17249 _this3.forceRender = true; 17250 }); 17251 } 17252 } else { 17253 this.textures[name] = new Texture(this.gl, name, options); 17254 this.textures[name].on('loaded', function (args) { 17255 _this3.forceRender = true; 17256 }); 17257 } 17258 } 17259 }, {
17260 key: 'refreshUniforms', 17261 value: function refreshUniforms() { 17262 this.uniforms = {}; 17263 } 17264 }, { 17265 key: 'setUniform', 17266 value: function setUniform(name) { 17267 var u = {}; 17268 17269 for (var _len = arguments.length, value = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 17270 value[_key - 1] = arguments[_key]; 17271 } 17272 17273 u[name] = value; 17274 this.setUniforms(u); 17275 } 17276 }, { 17277 key: 'setUniforms', 17278 value: function setUniforms(uniforms) { 17279 var parsed = parseUniforms(uniforms); 17280 // Set each uniform 17281 for (var u in parsed) { 17282 if (parsed[u].type === 'sampler2D') { 17283 // For textures, we need to track texture units, so we have a special setter 17284 // this.uniformTexture(parsed[u].name, parsed[u].value[0]); 17285 this.loadTexture(parsed[u].name, parsed[u].value[0]); 17286 } else { 17287 this.uniform(parsed[u].method, parsed[u].type, parsed[u].name, parsed[u].value); 17288 } 17289 } 17290 this.forceRender = true; 17291 } 17292 }, { 17293 key: 'setMouse', 17294 value: function setMouse(mouse) { 17295 // set the mouse uniform 17296 var rect = this.canvas.getBoundingClientRect(); 17297 if (mouse && mouse.x && mouse.x >= rect.left && mouse.x <= rect.right && mouse.y && mouse.y >= rect.top && mouse.y <= rect.bottom) { 17298 17299 var mouse_x = (mouse.x - rect.left) * this.realToCSSPixels; 17300 var mouse_y = this.canvas.height - (mouse.y - rect.top) * this.realToCSSPixels; 17301 17302 this.uniform('2f', 'vec2', 'u_mouse', mouse_x, mouse_y); 17303 } 17304 } 17305 17306 // ex: program.uniform('3f', 'position', x, y, z); 17307 17308 }, { 17309 key: 'uniform', 17310 value: function uniform(method, type, name) { 17311 // 'value' is a method-appropriate arguments list 17312 this.uniforms[name] = this.uniforms[name] || {}; 17313 var uniform = this.uniforms[name]; 17314 17315 for (var _len2 = arguments.length, value = Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) { 17316 value[_key2 - 3] = arguments[_key2]; 17317 } 17318 17319 var change = isDiff(uniform.value, value); 17320 17321 // remember and keep track of uniforms location to save calls 17322 if (change || this.change || !uniform.location || !uniform.value) { 17323 uniform.name = name; 17324 uniform.type = type; 17325 uniform.value = value; 17326 uniform.method = 'uniform' + method; 17327 this.gl.useProgram(this.program); 17328 uniform.location = this.gl.getUniformLocation(this.program, name); 17329 this.gl[uniform.method].apply(this.gl, [uniform.location].concat(uniform.value)); 17330 // If there is change update and there is buffer update manually one by one 17331 for (var key in this.buffers) { 17332 var buffer = this.buffers[key]; 17333 this.gl.useProgram(buffer.program); 17334 var location = this.gl.getUniformLocation(buffer.program, name); 17335 this.gl[uniform.method].apply(this.gl, [location].concat(uniform.value)); 17336 } 17337 } 17338 } 17339 }, { 17340 key: 'uniformTexture', 17341 value: function uniformTexture(name, texture, options) { 17342 if (this.textures[name] === undefined) { 17343 this.loadTexture(name, texture, options); 17344 } else { 17345 this.uniform('1i', 'sampler2D', name, this.texureIndex); 17346 17347 for (var key in this.buffers) { 17348 var buffer = this.buffers[key]; 17349 this.gl.useProgram(buffer.program); 17350 this.gl.activeTexture(this.gl.TEXTURE0 + this.texureIndex); 17351 this.gl.bindTexture(this.gl.TEXTURE_2D, this.textures[name].texture); 17352 } 17353 this.gl.useProgram(this.program); 17354 this.gl.activeTexture(this.gl.TEXTURE0 + this.texureIndex); 17355 this.gl.bindTexture(this.gl.TEXTURE_2D, this.textures[name].texture); 17356 this.uniform('2f', 'vec2', name + 'Resolution', this.textures[name].width, this.textures[name].height); 17357 } 17358 } 17359 }, {
17360 key: 'resize', 17361 value: function resize() { 17362 if (this.width !== this.canvas.clientWidth || this.height !== this.canvas.clientHeight) { 17363 this.realToCSSPixels = window.devicePixelRatio || 1; 17364 17365 // Lookup the size the browser is displaying the canvas in CSS pixels 17366 // and compute a size needed to make our drawingbuffer match it in 17367 // device pixels. 17368 var displayWidth = Math.floor(this.gl.canvas.clientWidth * this.realToCSSPixels); 17369 var displayHeight = Math.floor(this.gl.canvas.clientHeight * this.realToCSSPixels); 17370 17371 // Check if the canvas is not the same size. 17372 if (this.gl.canvas.width !== displayWidth || this.gl.canvas.height !== displayHeight) { 17373 // Make the canvas the same size 17374 this.gl.canvas.width = displayWidth; 17375 this.gl.canvas.height = displayHeight; 17376 // Set the viewport to match 17377 this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height); 17378 } 17379 this.width = this.canvas.clientWidth; 17380 this.height = this.canvas.clientHeight; 17381 this.resizeSwappableBuffers(); 17382 return true; 17383 } else { 17384 return false; 17385 } 17386 } 17387 }, { 17388 key: 'render', 17389 value: function render() { 17390 this.visible = isCanvasVisible(this.canvas); 17391 if (this.forceRender || this.change || this.animated && this.visible && !this.paused) { 17392 17393 // Update Uniforms when are need 17394 var date = new Date(); 17395 var now = performance.now(); 17396 this.timeDelta = (now - this.timePrev) / 1000.0; 17397 this.timePrev = now; 17398 if (this.nDelta > 1) { 17399 // set the delta time uniform 17400 this.uniform('1f', 'float', 'u_delta', this.timeDelta); 17401 } 17402 17403 if (this.nTime > 1) { 17404 // set the elapsed time uniform 17405 this.uniform('1f', 'float', 'u_time', (now - this.timeLoad) / 1000.0); 17406 } 17407 17408 if (this.nDate) { 17409 // Set date uniform: year/month/day/time_in_sec 17410 this.uniform('4f', 'float', 'u_date', date.getFullYear(), date.getMonth(), date.getDate(), date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds() + date.getMilliseconds() * 0.001); 17411 } 17412 17413 // set the resolution uniform 17414 this.uniform('2f', 'vec2', 'u_resolution', this.canvas.width, this.canvas.height); 17415 17416 for (var key in this.buffers) { 17417 var buffer = this.buffers[key]; 17418 this.uniform('1i', 'sampler2D', buffer.name, buffer.bundle.input.index); 17419 } 17420 17421 this.texureIndex = this.BUFFER_COUNT; 17422 for (var tex in this.textures) { 17423 this.uniformTexture(tex); 17424 this.texureIndex++; 17425 } 17426 17427 this.renderPrograms(); 17428 17429 // Trigger event 17430 this.trigger('render', {}); 17431 this.change = false; 17432 this.forceRender = false;
17433 } 17434 } 17435 }, { 17436 key: 'pause', 17437 value: function pause() { 17438 this.paused = true; 17439 } 17440 }, { 17441 key: 'play', 17442 value: function play() { 17443 this.paused = false; 17444 } 17445 17446 // render main and buffers programs 17447 17448 }, { 17449 key: 'renderPrograms', 17450 value: function renderPrograms() { 17451 var gl = this.gl; 17452 var W = gl.canvas.width; 17453 var H = gl.canvas.height; 17454 17455 gl.viewport(0, 0, W, H); 17456 17457 for (var key in this.buffers) { 17458 var buffer = this.buffers[key]; 17459 buffer.bundle.render(W, H, buffer.program, buffer.name); 17460 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 17461 } 17462 17463 gl.useProgram(this.program); 17464 gl.drawArrays(gl.TRIANGLES, 0, 6); 17465 } 17466 17467 // parse input strings 17468 17469 }, { 17470 key: 'getBuffers', 17471 value: function getBuffers(fragString) { 17472 var buffers = {}; 17473 if (fragString) { 17474 fragString.replace(/(?:^\s*)((?:#if|#elif)(?:\s*)(defined\s*\(\s*BUFFER_)(\d+)(?:\s*\))|(?:#ifdef)(?:\s*BUFFER_)(\d+)(?:\s*))/gm, function () { 17475 var i = arguments[3] || arguments[4]; 17476 buffers['u_buffer' + i] = { 17477 fragment: '#define BUFFER_' + i + '\n' + fragString 17478 }; 17479 }); 17480 } 17481 return buffers; 17482 } 17483 17484 // load buffers programs 17485 17486 }, { 17487 key: 'loadPrograms', 17488 value: function loadPrograms(buffers) { 17489 var glsl = this; 17490 var gl = this.gl; 17491 var vertex = createShader(glsl, glsl.vertexString, gl.VERTEX_SHADER); 17492 for (var key in buffers) { 17493 var buffer = buffers[key]; 17494 var fragment = createShader(glsl, buffer.fragment, gl.FRAGMENT_SHADER, 1); 17495 if (!fragment) { 17496 fragment = createShader(glsl, 'void main(){\n\tgl_FragColor = vec4(1.0);\n}', gl.FRAGMENT_SHADER); 17497 glsl.isValid = false; 17498 } else { 17499 glsl.isValid = true; 17500 } 17501 var program = createProgram(glsl, [vertex, fragment]); 17502 buffer.name = key; 17503 buffer.program = program; 17504 buffer.bundle = glsl.createSwappableBuffer(glsl.canvas.width, glsl.canvas.height, program); 17505 gl.deleteShader(fragment); 17506 } 17507 gl.deleteShader(vertex); 17508 } 17509 17510 // create an input / output swappable buffer 17511 17512 }, { 17513 key: 'createSwappableBuffer', 17514 value: function createSwappableBuffer(W, H, program) { 17515 var input = this.createBuffer(W, H, program); 17516 var output = this.createBuffer(W, H, program); 17517 var gl = this.gl; 17518 return { 17519 input: input, 17520 output: output, 17521 swap: function swap() { 17522 var temp = input; 17523 input = output; 17524 output = temp; 17525 this.input = input; 17526 this.output = output; 17527 }, 17528 render: function render(W, H, program, name) { 17529 gl.useProgram(program); 17530 gl.viewport(0, 0, W, H); 17531 gl.bindFramebuffer(gl.FRAMEBUFFER, this.input.buffer); 17532 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.output.texture, 0); 17533 gl.drawArrays(gl.TRIANGLES, 0, 6); 17534 this.swap(); 17535 }, 17536 resize: function resize(W, H, program, name) { 17537 gl.useProgram(program); 17538 gl.viewport(0, 0, W, H); 17539 this.input.resize(W, H); 17540 this.output.resize(W, H); 17541 } 17542 }; 17543 } 17544 17545 // create a buffers 17546 17547 }, { 17548 key: 'createBuffer', 17549 value: function createBuffer(W, H, program) { 17550 var gl = this.gl; 17551 var index = this.BUFFER_COUNT; 17552 this.BUFFER_COUNT += 2; 17553 gl.getExtension('OES_texture_float'); 17554 var texture = gl.createTexture(); 17555 gl.activeTexture(gl.TEXTURE0 + index); 17556 gl.bindTexture(gl.TEXTURE_2D, texture); 17557 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, W, H, 0, gl.RGBA, gl.FLOAT, null); 17558 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 17559 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 17560 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 17561 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 17562 var buffer = gl.createFramebuffer(); 17563 return { 17564 index: index, 17565 texture: texture, 17566 buffer: buffer, 17567 W: W, 17568 H: H, 17569 resize: function resize(W, H) { 17570 gl.bindFramebuffer(gl.FRAMEBUFFER, buffer); 17571 var minW = Math.min(W, this.W); 17572 var minH = Math.min(H, this.H); 17573 var pixels = new Float32Array(minW * minH * 4); 17574 gl.readPixels(0, 0, minW, minH, gl.RGBA, gl.FLOAT, pixels); 17575 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 17576 var newIndex = index + 1; 17577 var newTexture = gl.createTexture(); 17578 gl.activeTexture(gl.TEXTURE0 + newIndex); 17579 gl.bindTexture(gl.TEXTURE_2D, newTexture); 17580 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, W, H, 0, gl.RGBA, gl.FLOAT, null); 17581 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 17582 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 17583 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 17584 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 17585 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, minW, minH, gl.RGBA, gl.FLOAT, pixels); 17586 var newBuffer = gl.createFramebuffer(); 17587 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 17588 gl.deleteTexture(texture); 17589 gl.activeTexture(gl.TEXTURE0 + index); 17590 gl.bindTexture(gl.TEXTURE_2D, newTexture); 17591 index = this.index = index; 17592 texture = this.texture = newTexture; 17593 buffer = this.buffer = newBuffer; 17594 this.W = W; 17595 this.H = H; 17596 } 17597 }; 17598 } 17599 17600 // resize buffers on canvas resize 17601 // consider applying a throttle of 50 ms on canvas resize 17602 // to avoid requestAnimationFrame and Gl violations 17603 17604 }, {
17605 key: 'resizeSwappableBuffers', 17606 value: function resizeSwappableBuffers() { 17607 var gl = this.gl; 17608 var W = gl.canvas.width, 17609 H = gl.canvas.height; 17610 gl.viewport(0, 0, W, H); 17611 for (var key in this.buffers) { 17612 var buffer = this.buffers[key]; 17613 buffer.bundle.resize(W, H, buffer.program, buffer.name); 17614 } 17615 gl.useProgram(this.program); 17616 } 17617 }, { 17618 key: 'version', 17619 value: function version() { 17620 return '0.1.7'; 17621 } 17622 }]); 17623 return GlslCanvas; 17624}(); 17625 17626function loadAllGlslCanvas() { 17627 var list = document.getElementsByClassName('glslCanvas'); 17628 if (list.length > 0) { 17629 window.glslCanvases = []; 17630 for (var i = 0; i < list.length; i++) { 17631 var sandbox = new GlslCanvas(list[i]); 17632 if (sandbox.isValid) { 17633 window.glslCanvases.push(sandbox); 17634 } 17635 } 17636 } 17637} 17638 17639window.addEventListener('load', function () { 17640 loadAllGlslCanvas(); 17641}); 17642 17643return GlslCanvas; 17644 17645}))); 17646 17647}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 17648 17649},{}],110:[function(_dereq_,module,exports){ 17650module.exports = isFunction 17651 17652var toString = Object.prototype.toString 17653 17654function isFunction (fn) { 17655 if (!fn) { 17656 return false 17657 } 17658 var string = toString.call(fn) 17659 return string === '[object Function]' || 17660 (typeof fn === 'function' && string !== '[object RegExp]') || 17661 (typeof window !== 'undefined' && 17662 // IE8 and below 17663 (fn === window.setTimeout || 17664 fn === window.alert || 17665 fn === window.confirm || 17666 fn === window.prompt)) 17667}; 17668 17669},{}],111:[function(_dereq_,module,exports){ 17670var trim = function(string) { 17671 return string.replace(/^\s+|\s+$/g, ''); 17672} 17673 , isArray = function(arg) { 17674 return Object.prototype.toString.call(arg) === '[object Array]'; 17675 } 17676 17677module.exports = function (headers) { 17678 if (!headers) 17679 return {} 17680 17681 var result = {} 17682 17683 var headersArr = trim(headers).split('\n') 17684 17685 for (var i = 0; i < headersArr.length; i++) { 17686 var row = headersArr[i] 17687 var index = row.indexOf(':') 17688 , key = trim(row.slice(0, index)).toLowerCase() 17689 , value = trim(row.slice(index + 1)) 17690 17691 if (typeof(result[key]) === 'undefined') { 17692 result[key] = value 17693 } else if (isArray(result[key])) { 17694 result[key].push(value) 17695 } else { 17696 result[key] = [ result[key], value ] 17697 } 17698 } 17699 17700 return result 17701} 17702 17703},{}],112:[function(_dereq_,module,exports){ 17704"use strict"; 17705var window = _dereq_("global/window") 17706var isFunction = _dereq_("is-function") 17707var parseHeaders = _dereq_("parse-headers") 17708var xtend = _dereq_("xtend") 17709 17710module.exports = createXHR 17711// Allow use of default import syntax in TypeScript 17712module.exports.default = createXHR; 17713createXHR.XMLHttpRequest = window.XMLHttpRequest || noop 17714createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest 17715 17716forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { 17717 createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { 17718 options = initParams(uri, options, callback) 17719 options.method = method.toUpperCase() 17720 return _createXHR(options) 17721 } 17722}) 17723 17724function forEachArray(array, iterator) { 17725 for (var i = 0; i < array.length; i++) { 17726 iterator(array[i]) 17727 } 17728} 17729 17730function isEmpty(obj){ 17731 for(var i in obj){ 17732 if(obj.hasOwnProperty(i)) return false 17733 } 17734 return true 17735} 17736 17737function initParams(uri, options, callback) { 17738 var params = uri 17739 17740 if (isFunction(options)) { 17741 callback = options 17742 if (typeof uri === "string") { 17743 params = {uri:uri} 17744 } 17745 } else { 17746 params = xtend(options, {uri: uri}) 17747 } 17748 17749 params.callback = callback 17750 return params 17751} 17752 17753function createXHR(uri, options, callback) { 17754 options = initParams(uri, options, callback) 17755 return _createXHR(options) 17756} 17757 17758function _createXHR(options) { 17759 if(typeof options.callback === "undefined"){ 17760 throw new Error("callback argument missing") 17761 } 17762 17763 var called = false 17764 var callback = function cbOnce(err, response, body){ 17765 if(!called){ 17766 called = true 17767 options.callback(err, response, body) 17768 } 17769 } 17770 17771 function readystatechange() { 17772 if (xhr.readyState === 4) { 17773 setTimeout(loadFunc, 0) 17774 } 17775 } 17776 17777 function getBody() { 17778 // Chrome with requestType=blob throws errors arround when even testing access to responseText 17779 var body = undefined 17780 17781 if (xhr.response) { 17782 body = xhr.response 17783 } else { 17784 body = xhr.responseText || getXml(xhr) 17785 } 17786 17787 if (isJson) { 17788 try { 17789 body = JSON.parse(body) 17790 } catch (e) {} 17791 } 17792 17793 return body 17794 } 17795 17796 function errorFunc(evt) { 17797 clearTimeout(timeoutTimer) 17798 if(!(evt instanceof Error)){ 17799 evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ) 17800 } 17801 evt.statusCode = 0 17802 return callback(evt, failureResponse) 17803 } 17804 17805 // will load the data & process the response in a special response object 17806 function loadFunc() { 17807 if (aborted) return 17808 var status 17809 clearTimeout(timeoutTimer) 17810 if(options.useXDR && xhr.status===undefined) { 17811 //IE8 CORS GET successful response doesn't have a status field, but body is fine 17812 status = 200 17813 } else { 17814 status = (xhr.status === 1223 ? 204 : xhr.status) 17815 } 17816 var response = failureResponse 17817 var err = null 17818 17819 if (status !== 0){ 17820 response = { 17821 body: getBody(), 17822 statusCode: status, 17823 method: method, 17824 headers: {},
vendor: 4,146 bytes, lines 17825-17952
17825 url: uri, 17826 rawRequest: xhr 17827 } 17828 if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE 17829 response.headers = parseHeaders(xhr.getAllResponseHeaders()) 17830 } 17831 } else { 17832 err = new Error("Internal XMLHttpRequest Error") 17833 } 17834 return callback(err, response, response.body) 17835 } 17836 17837 var xhr = options.xhr || null 17838 17839 if (!xhr) { 17840 if (options.cors || options.useXDR) { 17841 xhr = new createXHR.XDomainRequest() 17842 }else{ 17843 xhr = new createXHR.XMLHttpRequest() 17844 } 17845 } 17846 17847 var key 17848 var aborted 17849 var uri = xhr.url = options.uri || options.url 17850 var method = xhr.method = options.method || "GET" 17851 var body = options.body || options.data 17852 var headers = xhr.headers = options.headers || {} 17853 var sync = !!options.sync 17854 var isJson = false 17855 var timeoutTimer 17856 var failureResponse = { 17857 body: undefined, 17858 headers: {}, 17859 statusCode: 0, 17860 method: method, 17861 url: uri, 17862 rawRequest: xhr 17863 } 17864 17865 if ("json" in options && options.json !== false) { 17866 isJson = true 17867 headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user 17868 if (method !== "GET" && method !== "HEAD") { 17869 headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user 17870 body = JSON.stringify(options.json === true ? body : options.json) 17871 } 17872 } 17873 17874 xhr.onreadystatechange = readystatechange 17875 xhr.onload = loadFunc 17876 xhr.onerror = errorFunc 17877 // IE9 must have onprogress be set to a unique function. 17878 xhr.onprogress = function () { 17879 // IE must die 17880 } 17881 xhr.onabort = function(){ 17882 aborted = true; 17883 } 17884 xhr.ontimeout = errorFunc 17885 xhr.open(method, uri, !sync, options.username, options.password) 17886 //has to be after open 17887 if(!sync) { 17888 xhr.withCredentials = !!options.withCredentials 17889 } 17890 // Cannot set timeout with sync request 17891 // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly 17892 // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent 17893 if (!sync && options.timeout > 0 ) { 17894 timeoutTimer = setTimeout(function(){ 17895 if (aborted) return 17896 aborted = true//IE9 may still call readystatechange 17897 xhr.abort("timeout") 17898 var e = new Error("XMLHttpRequest timeout") 17899 e.code = "ETIMEDOUT" 17900 errorFunc(e) 17901 }, options.timeout ) 17902 } 17903 17904 if (xhr.setRequestHeader) { 17905 for(key in headers){ 17906 if(headers.hasOwnProperty(key)){ 17907 xhr.setRequestHeader(key, headers[key]) 17908 } 17909 } 17910 } else if (options.headers && !isEmpty(options.headers)) { 17911 throw new Error("Headers cannot be set on an XDomainRequest object") 17912 } 17913 17914 if ("responseType" in options) { 17915 xhr.responseType = options.responseType 17916 } 17917 17918 if ("beforeSend" in options && 17919 typeof options.beforeSend === "function" 17920 ) { 17921 options.beforeSend(xhr) 17922 } 17923 17924 // Microsoft Edge browser sends "undefined" when send is called with undefined value. 17925 // XMLHttpRequest spec says to pass null as body to indicate no body 17926 // See https://github.com/naugtur/xhr/issues/100. 17927 xhr.send(body || null) 17928 17929 return xhr 17930 17931 17932} 17933 17934function getXml(xhr) { 17935 // xhr.responseXML will throw Exception "InvalidStateError" or "DOMException" 17936 // See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseXML. 17937 try { 17938 if (xhr.responseType === "document") { 17939 return xhr.responseXML 17940 } 17941 var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror" 17942 if (xhr.responseType === "" && !firefoxBugTakenEffect) { 17943 return xhr.responseXML 17944 } 17945 } catch (e) {} 17946 17947 return null 17948} 17949 17950function noop() {} 17951 17952}
17952,{"global/window":108,"is-function":110,"parse-headers":111,"xtend":113}],113:[function(_dereq_,module,exports){ 17953module.exports = extend 17954 17955var hasOwnProperty = Object.prototype.hasOwnProperty; 17956 17957function extend() { 17958 var target = {} 17959 17960 for (var i = 0; i < arguments.length; i++) { 17961 var source = arguments[i] 17962 17963 for (var key in source) { 17964 if (hasOwnProperty.call(source, key)) { 17965 target[key] = source[key] 17966 } 17967 } 17968 } 17969 17970 return target 17971} 17972 17973},{}],114:[function(_dereq_,module,exports){ 17974"use strict"; 17975 17976var _createClass = _dereq_("babel-runtime/helpers/create-class")["default"]; 17977 17978var _classCallCheck = _dereq_("babel-runtime/helpers/class-call-check")["default"]; 17979 17980var _Object$keys = _dereq_("babel-runtime/core-js/object/keys")["default"]; 17981 17982var _Object$create = _dereq_("babel-runtime/core-js/object/create")["default"]; 17983 17984var _interopRequireDefault = _dereq_("babel-runtime/helpers/interop-require-default")["default"]; 17985 17986Object.defineProperty(exports, "__esModule", { 17987 value: true 17988}); 17989 17990_dereq_("document-register-element"); 17991 17992var _coreShader = _dereq_("./core/Shader"); 17993 17994var _coreShader2 = _interopRequireDefault(_coreShader); 17995 17996var _coreEditor = _dereq_("./core/Editor"); 17997 17998var _uiMenu = _dereq_("./ui/Menu"); 17999 18000var _uiMenu2 = _interopRequireDefault(_uiMenu); 18001 18002var _uiHelpers = _dereq_("./ui/Helpers"); 18003 18004var _uiHelpers2 = _interopRequireDefault(_uiHelpers); 18005 18006var _uiErrorsDisplay = _dereq_("./ui/ErrorsDisplay"); 18007 18008var _uiErrorsDisplay2 = _interopRequireDefault(_uiErrorsDisplay); 18009 18010var _uiVisualDebugger = _dereq_("./ui/VisualDebugger"); 18011 18012var _uiVisualDebugger2 = _interopRequireDefault(_uiVisualDebugger); 18013 18014var _uiExportIcon = _dereq_("./ui/ExportIcon"); 18015 18016var _uiExportIcon2 = _interopRequireDefault(_uiExportIcon); 18017 18018var _ioFileDrop = _dereq_("./io/FileDrop"); 18019 18020var _ioFileDrop2 = _interopRequireDefault(_ioFileDrop); 18021 18022var _ioHashWatch = _dereq_("./io/HashWatch"); 18023 18024var _ioHashWatch2 = _interopRequireDefault(_ioHashWatch); 18025 18026var _ioBufferManager = _dereq_("./io/BufferManager"); 18027 18028var _ioBufferManager2 = _interopRequireDefault(_ioBufferManager); 18029 18030var _ioLocalStorage = _dereq_("./io/LocalStorage"); 18031 18032var _ioLocalStorage2 = _interopRequireDefault(_ioLocalStorage); 18033 18034// Import Utils 18035 18036var _xhr = _dereq_("xhr"); 18037 18038var _xhr2 = _interopRequireDefault(_xhr); 18039 18040var _toolsMixin = _dereq_("./tools/mixin"); 18041 18042var _toolsDownload = _dereq_("./tools/download"); 18043 18044var _toolsCommon = _dereq_("./tools/common"); 18045 18046var _codemirror = _dereq_("codemirror"); 18047 18048var _codemirror2 = _interopRequireDefault(_codemirror); 18049 18050// // Cross storage for Openframe -- allows restricted access to certain localStorage operations 18051// // on the openframe domain 18052// import { CrossStorageClient } from "cross-storage"; 18053// import { getMode } from "codemirror"; 18054 18055var STORAGE_LAST_EDITOR_CONTENT = "last-content";var EMPTY_FRAG_SHADER = "// Author:\n// Title:\n\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\nuniform vec2 u_resolution;\nuniform vec2 u_mouse;\nuniform float u_time;\n\nvoid main() {\n vec2 st = gl_FragCoord.xy/u_resolution.xy;\n st.x *= u_resolution.x/u_resolution.y;\n\n vec3 color = vec3(0.);\n color = vec3(st.x,st.y,abs(sin(u_time)));\n\n gl_FragColor = vec4(color,1.0);\n}"; 18056 18057var GlslEditor = (function () { 18058 function GlslEditor(selector, options) { 18059 var _this = this; 18060 18061 _classCallCheck(this, GlslEditor); 18062 18063 this.createFontLink(); 18064 (0, _toolsMixin.subscribeMixin)(this); 18065 18066 if (typeof selector === "object" && selector.nodeType && selector.nodeType === 1) { 18067 this.container = selector; 18068 } else if (typeof selector === "string") { 18069 this.container = document.querySelector(selector); 18070 if (!this.container) { 18071 throw new Error("element " + selector + " not present"); 18072 } 18073 } else { 18074 console.log("Error, type " + typeof selector + " of " + selector + " is unknown"); 18075 return; 18076 } 18077 18078 this.options = {}; 18079 this.change = false; 18080 this.autoupdate = true; 18081 this.lygia_glob = null; 18082 18083 if (options) this.options = options; 18084 18085 if (this.options.imgs === undefined) this.options.imgs = []; 18086 18087 if (this.options.display_menu === undefined) this.options.display_menu = true; 18088 18089 if (this.container.hasAttribute("data-textures")) { 18090 var imgList = this.container.getAttribute("data-textures").split(","); 18091 for (var i in imgList) { 18092 this.options.imgs.push(imgList[i]); 18093 } 18094 } 18095 18096 // Default Theme 18097 if (!this.options.theme) this.options.theme = "default"; 18098 18099 // Default Context 18100 if (!this.options.frag) { 18101 var innerHTML = this.container.innerHTML.replace(/<br>/g, ""); 18102 innerHTML = innerHTML.replace(/<br>/g, ""); 18103 innerHTML = innerHTML.replace(/ /g, ""); 18104 innerHTML = innerHTML.replace(/</g, "<"); 18105 innerHTML = innerHTML.replace(/>/g, ">"); 18106 innerHTML = innerHTML.replace(/&/g, "&"); 18107 this.options.frag = innerHTML || EMPTY_FRAG_SHADER; 18108 18109 if (innerHTML) this.container.innerHTML = ""; 18110 } 18111 18112 // Default invisible Fragment header 18113 if (!this.options.frag_header) this.options.frag_header = ""; 18114 18115 // Default invisible Fragment footer 18116 if (!this.options.frag_footer) this.options.frag_footer = ""; 18117 18118 // Listen to hash changes 18119 if (this.options.watchHash) new _ioHashWatch2["default"](this); 18120 18121 // Load UI 18122 if (this.options.menu) this.menu = new _uiMenu2["default"](this); 18123
18124 // Support for multiple buffers 18125 if (this.options.multipleBuffers) this.bufferManager = new _ioBufferManager2["default"](this); 18126 18127 // Listen to file drops 18128 if (this.options.fileDrops) new _ioFileDrop2["default"](this); 18129 18130 if (this.options.indentUnit === undefined) this.options.indentUnit = 4; 18131 18132 if (this.options.tabSize === undefined) this.options.tabSize = 4; 18133 18134 if (this.options.indentWithTabs === undefined) this.options.indentWithTabs = false; 18135 18136 if (this.options.lineWrapping === undefined) this.options.lineWrapping = true; 18137 18138 if (this.options.autofocus === undefined) this.options.autofocus = true; 18139 18140 // CORE elements 18141 this.shader = new _coreShader2["default"](this); 18142 this.editor = (0, _coreEditor.initEditor)(this); 18143 18144 this.helpers = new _uiHelpers2["default"](this); 18145 this.errorsDisplay = new _uiErrorsDisplay2["default"](this); 18146 this.visualDebugger = new _uiVisualDebugger2["default"](this); 18147 18148 if (this.options.exportIcon) this["export"] = new _uiExportIcon2["default"](this); 18149 18150 // EVENTS 18151 this.editor.on("change", function () { 18152 if (_this.autoupdate) { 18153 _this.update(); 18154 } 18155 }); 18156 18157 if (this.options.canvas_follow) { 18158 this.shader.el.style.position = "relative"; 18159 18160 if (this.options.canvas_float) this.shader.el.style.float = this.options.canvas_float; 18161 18162 this.editor.on("cursorActivity", function (cm) { 18163 var height = cm.heightAtLine(cm.getCursor().line + 1, "local") - _this.shader.el.clientHeight; 18164 if (height < 0) { 18165 height = 0.0; 18166 } 18167 _this.shader.el.style.top = height.toString() + "px"; 18168 }); 18169 } 18170 18171 this.editor.on('inputRead', function (cm, change) { 18172 var cur = cm.getCursor(), 18173 token = cm.getTokenAt(cur); 18174 var line = token.string.trim(); 18175 18176 if (line.startsWith('#include')) { 18177 (function () { 18178 var path = line.substring(10); 18179 if (_this.lygia_glob === null) { 18180 (0, _toolsCommon.getJSON)('https://lygia.xyz/glsl.json', function (err, data) { 18181 if (err === null) { 18182 _this.lygia_glob = data; 18183 } 18184 }); 18185 } 18186 console.log('autocomplete for', path); 18187 18188 var start = token.start; 18189 var end = cur.ch; 18190 var lineN = cur.line; 18191 18192 var result = []; 18193 18194 if (_this.lygia_glob !== null) { 18195 _this.lygia_glob.forEach(function (w) { 18196 if (w.startsWith(path)) result.push('#include \"' + w + '\"'); 18197 }); 18198 result.sort(); 18199 } 18200 18201 if (result.length > 0) { 18202 _codemirror2["default"].showHint(cm, function () { 18203 var rta = { 18204 list: result, 18205 from: _codemirror2["default"].Pos(lineN, start), 18206 to: _codemirror2["default"].Pos(lineN, end) 18207 }; 18208 18209 console.log(rta); 18210 return rta; 18211 }, { completeSingle: true, alignWithWord: true }); 18212 } 18213 })(); 18214 } 18215 }); 18216 18217 // If the user bails for whatever reason, hastily shove the contents of 18218 // the editor into some kind of storage. This overwrites whatever was 18219 // there before. Note that there is not really a way of handling unload 18220 // with our own UI and logic, since this allows for widespread abuse 18221 // of normal browser functionality. 18222 window.addEventListener("beforeunload", function (event) { 18223 var content = {}; 18224 if (_this.bufferManager && _Object$keys(_this.bufferManager.buffers).length !== 0) { 18225 for (var key in _this.bufferManager.buffers) { 18226 content[key] = _this.bufferManager.buffers[key].getValue(); 18227 } 18228 } else { 18229 content[new Date().getTime().toString()] = _this.editor.getValue(); 18230 } 18231 18232 if (_this.options.menu) { 18233 _ioLocalStorage2["default"].setItem(STORAGE_LAST_EDITOR_CONTENT, JSON.stringify(content)); 18234 } 18235 }); 18236 18237 if (this.options.menu) { 18238 // If there is previus content load it. 18239 var oldContent = JSON.parse(_ioLocalStorage2["default"].getItem(STORAGE_LAST_EDITOR_CONTENT)); 18240 if (oldContent) { 18241 for (var key in oldContent) { 18242 this.open(oldContent[key], key); 18243 } 18244 } else { 18245 this["new"](); 18246 } 18247 } else { 18248 this["new"](); 18249 } 18250 18251 // if (this.options.menu || this.options.exportIcon) { 18252 // // setup CrossStorage client 18253 // this.storage = new CrossStorageClient("https://openframe.io/hub.html"); 18254 // this.storage.onConnect().then(() => { 18255 // console.log("Connected to OpenFrame [o]"); 18256 // }); 18257 // // }).bind(this); 18258 // } 18259 18260 return this; 18261 } 18262 18263 _createClass(GlslEditor, [{ 18264 key: "new", 18265 value: function _new() { 18266 this.setContent(this.options.frag || EMPTY_FRAG_SHADER, new Date().getTime().toString()); 18267 this.trigger("new_content", {}); 18268 this.options.frag = null; 18269 } 18270 }, { 18271 key: "setContent", 18272 value: function setContent(shader, tabName) { 18273 // If the string is CODE 18274 if (this.shader && this.shader.canvas) { 18275 if (this.debugging) { 18276 this.debugging = false;
18277 (0, _coreEditor.focusAll)(this.editor); 18278 } 18279 this.shader.canvas.load(this.options.frag_header + shader + this.options.frag_footer); 18280 } 18281 18282 if (this.editor) { 18283 if (tabName !== undefined && this.bufferManager !== undefined) { 18284 this.bufferManager.open(tabName, shader); 18285 this.bufferManager.select(tabName); 18286 } else { 18287 this.editor.setValue(shader); 18288 this.editor.setSize(null, this.editor.getDoc().height + "px"); 18289 this.editor.setSize(null, "auto"); 18290 this.filename = tabName; 18291 } 18292 } 18293 this.change = true; 18294 } 18295 }, { 18296 key: "open", 18297 value: function open(shader, tabName) { 18298 var _this2 = this; 18299 18300 if (typeof shader === "object") { 18301 (function () { 18302 var reader = new FileReader(); 18303 var ge = _this2; 18304 reader.onload = function (e) { 18305 ge.setContent(e.target.result, shader.name); 18306 }; 18307 reader.readAsText(shader); 18308 })(); 18309 } else if (typeof shader === "string") { 18310 if (/\.frag$/.test(shader) || /\.fs$/.test(shader)) { 18311 // If the string is an URL 18312 _xhr2["default"].get(shader, function (error, response, body) { 18313 if (error) { 18314 console.log("Error downloading ", shader, error); 18315 return; 18316 } 18317 _this2.setContent(body, tabName); 18318 }); 18319 } else { 18320 this.setContent(shader, tabName); 18321 } 18322 } 18323 } 18324 }, { 18325 key: "getContent", 18326 value: function getContent() { 18327 return this.editor.getValue(); 18328 } 18329 }, { 18330 key: "getAuthor", 18331 value: function getAuthor() { 18332 var content = this.getContent(); 18333 var result = content.match(/\/\/\s*[A|a]uthor\s*[\:]?\s*([\w|\s|\@|\(|\)|\-|\_]*)/i); 18334 if (result && !(result[1] === " " || result[1] === "")) { 18335 var author = result[1].replace(/(\r\n|\n|\r)/gm, ""); 18336 return author; 18337 } else { 18338 return "unknown"; 18339 } 18340 } 18341 }, { 18342 key: "getTitle", 18343 value: function getTitle() { 18344 var content = this.getContent(); 18345 var result = content.match(/\/\/\s*[T|t]itle\s*:\s*([\w|\s|\@|\(|\)|\-|\_]*)/i); 18346 if (result && !(result[1] === " " || result[1] === "")) { 18347 var title = result[1].replace(/(\r\n|\n|\r)/gm, ""); 18348 return title; 18349 } else if (this.bufferManager !== undefined) { 18350 return this.bufferManager.current; 18351 } else { 18352 return "unknown"; 18353 } 18354 } 18355 18356 // Returns Promise 18357 }, { 18358 key: "getOfToken", 18359 value: function getOfToken() { 18360 return this.storage.get("accessToken"); 18361 } 18362 }, { 18363 key: "download", 18364 value: function download() { 18365 var content = this.getContent(); 18366 var name = this.getTitle(); 18367 if (name !== "") { 18368 name += "-"; 18369 } 18370 name += new Date().getTime(); 18371 18372 // Download code 18373 var blob = new Blob([content], { type: "text/plain" }); 18374 (0, _toolsDownload.saveAs)(blob, name + ".frag"); 18375 this.editor.doc.markClean(); 18376 this.change = false; 18377 } 18378 }, { 18379 key: "update", 18380 value: function update() { 18381 if (this.debugging) { 18382 this.debugging = false; 18383 (0, _coreEditor.focusAll)(this.editor); 18384 } 18385 18386 if (this.visualDebugger.testingResults.length) this.visualDebugger.clean(); 18387 18388 this.shader.canvas.load(this.options.frag_header + this.editor.getValue() + this.options.frag_footer); 18389 } 18390 }, { 18391 key: "createFontLink", 18392 value: function createFontLink() { 18393 var head = document.getElementsByTagName("head")[0]; 18394 var link = document.createElement("link"); 18395 link.href = "https://fonts.googleapis.com/icon?family=Material+Icons"; 18396 link.type = "text/css"; 18397 link.rel = "stylesheet"; 18398 link.media = "screen,print"; 18399 head.appendChild(link); 18400 document.getElementsByTagName("head")[0].appendChild(link); 18401 } 18402 }, { 18403 key: "togglePresentationWindow", 18404 value: function togglePresentationWindow(flag) { 18405 this.pWindowOpen = flag; 18406 if (flag) this.shader.openWindow();else this.shader.closeWindow(); 18407 } 18408 }, { 18409 key: "onClosePresentationWindow", 18410 value: function onClosePresentationWindow() { 18411 this.pWindowOpen = false;
18412 } 18413 }]); 18414 18415 return GlslEditor; 18416})(); 18417 18418exports["default"] = GlslEditor; 18419 18420window.GlslEditor = GlslEditor; 18421 18422var GlslWebComponent = function GlslWebComponent() {}; 18423GlslWebComponent.prototype = _Object$create(HTMLElement.prototype); 18424GlslWebComponent.prototype.createdCallback = function createdCallback() { 18425 var options = { 18426 canvas_size: 150, 18427 canvas_follow: true, 18428 tooltips: true 18429 }; 18430 18431 for (var i = 0; i < this.attributes.length; i++) { 18432 var attribute = this.attributes[i]; 18433 if (attribute.specified) { 18434 var value = attribute.value; 18435 18436 if (value === "true") value = true;else if (value === "false") value = false;else if (parseInt(value)) value = parseInt(value); 18437 18438 options[attribute.name] = value; 18439 } 18440 } 18441 18442 this.glslEditor = new GlslEditor(this, options); 18443}; 18444 18445document.registerElement("glsl-editor", GlslWebComponent); 18446module.exports = exports["default"]; 18447 18448},{"./core/Editor":115,"./core/Shader":116,"./io/BufferManager":117,"./io/FileDrop":118,"./io/HashWatch":119,"./io/LocalStorage":120,"./tools/common":121,"./tools/download":123,"./tools/mixin":126,"./ui/ErrorsDisplay":128,"./ui/ExportIcon":129,"./ui/Helpers":130,"./ui/Menu":131,"./ui/VisualDebugger":133,"babel-runtime/core-js/object/create":3,"babel-runtime/core-js/object/keys":6,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11,"babel-runtime/helpers/interop-require-default":14,"codemirror":30,"document-register-element":107,"xhr":112}],115:[function(_dereq_,module,exports){ 18449// Import CodeMirror 18450'use strict'; 18451 18452var _Promise = _dereq_('babel-runtime/core-js/promise')['default']; 18453 18454var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 18455 18456Object.defineProperty(exports, '__esModule', { 18457 value: true 18458}); 18459exports.initEditor = initEditor; 18460exports.unfocusLine = unfocusLine; 18461exports.unfocusAll = unfocusAll; 18462exports.focusLine = focusLine; 18463exports.focusAll = focusAll; 18464 18465var _codemirror = _dereq_('codemirror'); 18466 18467var _codemirror2 = _interopRequireDefault(_codemirror); 18468 18469// Import CodeMirror addons and modules 18470 18471_dereq_('codemirror/addon/search/search'); 18472 18473_dereq_('codemirror/addon/search/searchcursor'); 18474 18475_dereq_('codemirror/addon/comment/comment'); 18476 18477_dereq_('codemirror/addon/dialog/dialog'); 18478 18479_dereq_('codemirror/addon/edit/matchbrackets'); 18480 18481_dereq_('codemirror/addon/edit/closebrackets'); 18482 18483_dereq_('codemirror/addon/wrap/hardwrap'); 18484 18485_dereq_('codemirror/addon/fold/foldcode'); 18486 18487_dereq_('codemirror/addon/fold/foldgutter'); 18488 18489_dereq_('codemirror/addon/fold/indent-fold'); 18490 18491_dereq_('codemirror/addon/hint/show-hint'); 18492 18493_dereq_('codemirror/addon/hint/javascript-hint'); 18494 18495_dereq_('codemirror/addon/display/rulers'); 18496 18497_dereq_('codemirror/addon/display/panel'); 18498 18499_dereq_('codemirror/addon/hint/show-hint'); 18500 18501_dereq_('codemirror/mode/clike/clike.js'); 18502 18503// Keymap 18504 18505_dereq_('codemirror/keymap/sublime'); 18506 18507var UNFOCUS_CLASS = 'ge_editor-unfocus'; 18508 18509function initEditor(main) { 18510 if (main.options.lineNumbers === undefined) main.options.lineNumbers = true; 18511 18512 // CREATE AND START CODEMIRROR 18513 var el = document.createElement('div'); 18514 el.setAttribute('class', 'ge_editor'); 18515 18516 // If there is a menu offset the editor to come after it 18517 if (main.menu) el.style.paddingTop = (main.menu.el.clientHeight || main.menu.el.offsetHeight || main.menu.el.scrollHeight) + 'px'; 18518 18519 main.container.appendChild(el); 18520 18521 function fillInclude(cm, option) { 18522 var _this = this; 18523 18524 return new _Promise(function (accept) { 18525 setTimeout(function () { 18526 var cur = cm.getCursor().line = cm.getLine(cur.line).trim(); 18527 var start = cur.ch, 18528 end = cur.ch; 18529 18530 if (line.startsWith('#include \"lygia')) { 18531 var _ret = (function () { 18532 var path = line.substring(10); 18533 if (_this.lygia_glob === null) { 18534 getJSON('https://lygia.xyz/glsl.json', function (err, data) { 18535 if (err === null) { 18536 _this.lygia_glob = data; 18537 } 18538 }); 18539 } 18540 console.log('autocomplete for', path); 18541 18542 var start = token.start; 18543 var end = cur.ch; 18544 var lineN = cur.line; 18545 18546 var result = []; 18547 18548 if (_this.lygia_glob !== null) { 18549 _this.lygia_glob.forEach(function (w) { 18550 if (w.startsWith(path)) result.push('#include \"' + w + '\"'); 18551 }); 18552 result.sort(); 18553 } 18554 18555 if (result.length > 0) { 18556 console.log(lineN, result); 18557 return { 18558 v: accept({ list: result, 18559 from: _codemirror2['default'].Pos(cur.line, start), 18560 to: _codemirror2['default'].Pos(cur.line, end) }) 18561 }; 18562 } 18563 })(); 18564 18565 if (typeof _ret === 'object') return _ret.v; 18566 } 18567 return accept(null); 18568 }, 100); 18569 }); 18570 } 18571 18572 var cm = (0, _codemirror2['default'])(el, { 18573 value: main.options.frag, 18574 viewportMargin: Infinity, 18575 lineNumbers: main.options.lineNumbers, 18576 matchBrackets: true, 18577 mode: 'x-shader/x-fragment', 18578 keyMap: 'sublime', 18579 autoCloseBrackets: true, 18580 extraKeys: { 'Ctrl-Space': 'autocomplete' }, 18581 showCursorWhenSelecting: true, 18582 theme: main.options.theme, 18583 dragDrop: false, 18584 indentUnit: main.options.indentUnit, 18585 tabSize: main.options.tabSize, 18586 indentWithTabs: main.options.indentWithTabs, 18587 gutters: main.options.lineNumbers ? ['CodeMirror-linenumbers', 'breakpoints'] : false, 18588 lineWrapping: main.options.lineWrapping, 18589 autofocus: main.options.autofocus 18590 }); 18591 18592 return cm; 18593} 18594 18595function unfocusLine(cm, line) { 18596 if (line === null) { 18597 return; 18598 } 18599 cm.getDoc().addLineClass(line, 'gutter', UNFOCUS_CLASS); 18600 cm.getDoc().addLineClass(line, 'text', UNFOCUS_CLASS); 18601} 18602 18603function unfocusAll(cm) { 18604 for (var i = 0, j = cm.getDoc().lineCount(); i <= j; i++) { 18605 unfocusLine(cm, i); 18606 } 18607} 18608 18609function focusLine(cm, line) { 18610 if (line === null) { 18611 return; 18612 } 18613 cm.getDoc().removeLineClass(line, 'gutter', UNFOCUS_CLASS); 18614 cm.getDoc().removeLineClass(line, 'text', UNFOCUS_CLASS); 18615} 18616 18617function focusAll(cm) { 18618 for (var i = 0, j = cm.getDoc().lineCount(); i <= j; i++) { 18619 focusLine(cm, i); 18620 } 18621} 18622 18623},{"babel-runtime/core-js/promise":8,"babel-runtime/helpers/interop-require-default":14,"codemirror":30,"codemirror/addon/comment/comment":15,"codemirror/addon/dialog/dialog":16,"codemirror/addon/display/panel":17,"codemirror/addon/display/rulers":18,"codemirror/addon/edit/closebrackets":19,"codemirror/addon/edit/matchbrackets":20,"codemirror/addon/fold/foldcode":21,"codemirror/addon/fold/foldgutter":22,"codemirror/addon/fold/indent-fold":23,"codemirror/addon/hint/javascript-hint":24,"codemirror/addon/hint/show-hint":25,"codemirror/addon/search/search":26,"codemirror/addon/search/searchcursor":27,"codemirror/addon/wrap/hardwrap":28,"codemirror/keymap/sublime":29,"codemirror/mode/clike/clike.js":31}],116:[function(_dereq_,module,exports){ 18624"use strict"; 18625 18626var _createClass = _dereq_("babel-runtime/helpers/create-class")["default"]; 18627 18628var _classCallCheck = _dereq_("babel-runtime/helpers/class-call-check")["default"]; 18629 18630var _interopRequireDefault = _dereq_("babel-runtime/helpers/interop-require-default")["default"]; 18631 18632Object.defineProperty(exports, "__esModule", { 18633 value: true 18634}); 18635 18636var _glslCanvas = _dereq_("glslCanvas"); 18637 18638var _glslCanvas2 = _interopRequireDefault(_glslCanvas); 18639 18640var _toolsInteractiveDom = _dereq_("../tools/interactiveDom"); 18641 18642var _toolsMediaCapture = _dereq_("../tools/mediaCapture"); 18643 18644var _toolsMediaCapture2 = _interopRequireDefault(_toolsMediaCapture); 18645 18646var _uiMenuItem = _dereq_("../ui/MenuItem"); 18647 18648var _uiMenuItem2 = _interopRequireDefault(_uiMenuItem); 18649 18650var _toolsDownload = _dereq_("../tools/download"); 18651 18652var CONTROLS_CLASSNAME = "ge_control"; 18653var CONTROLS_PANEL_CLASSNAME = "ge_control_panel"; 18654 18655var Shader = (function () { 18656 function Shader(main) { 18657 var _this = this; 18658 18659 _classCallCheck(this, Shader); 18660 18661 this.main = main; 18662 this.options = main.options; 18663 this.frag = ""; 18664 18665 // DOM CONTAINER 18666 this.el = document.createElement("div"); 18667 this.el.setAttribute("class", "ge_canvas_container"); 18668 // CREATE AND START GLSLCANVAS 18669 this.elCanvas = document.createElement("canvas"); 18670 this.elCanvas.setAttribute("class", "ge_canvas"); 18671 this.elCanvas.setAttribute("data-fragment", this.options.frag_header + this.options.frag + this.options.frag_footer); 18672 this.el.appendChild(this.elCanvas); 18673 var glslcanvas = new _glslCanvas2["default"](this.elCanvas, { 18674 premultipliedAlpha: false, 18675 preserveDrawingBuffer: true, 18676 backgroundColor: "rgba(1,1,1,1)" 18677 }); 18678 18679 var width = this.options.canvas_width || this.options.canvas_size || "250"; 18680 var height = this.options.canvas_height || this.options.canvas_size || "250"; 18681 glslcanvas.canvas.style.width = width + "px"; 18682 glslcanvas.canvas.style.height = height + "px"; 18683 glslcanvas.resize(); 18684 18685 this.canvas = glslcanvas; 18686 18687 if (this.options.imgs && this.options.imgs.length > 0) { 18688 for (var i in this.options.imgs) { 18689 this.canvas.setUniform("u_tex" + i, this.options.imgs[i]); 18690 } 18691 } 18692 18693 // Media Capture 18694 this.mediaCapture = new _toolsMediaCapture2["default"](); 18695 this.mediaCapture.setCanvas(this.elCanvas); 18696 this.canvas.on("render", function () { 18697 _this.mediaCapture.completeScreenshot(); 18698 }); 18699 18700 if (main.options.displayMenu) { 18701 // CONTROLS 18702 this.controlsContainer = document.createElement("ul"); 18703 this.controlsContainer.className = CONTROLS_CLASSNAME; 18704 this.controlPanel = document.createElement("ul"); 18705 this.controlPanel.className = CONTROLS_PANEL_CLASSNAME; 18706 this.controlsContainer.appendChild(this.controlPanel); 18707 this.el.appendChild(this.controlsContainer); 18708 this.controls = {}; 18709 // play/stop 18710 // this.controls.playPause = new MenuItem(this.controlPanel, 'ge_control_element', '<i class="material-icons">pause</i>', (event) => { 18711 this.controls.playPause = new _uiMenuItem2["default"](this.controlPanel, "ge_control_element", '<i class="material-icons">pause</i>', function (event) { 18712 event.stopPropagation(); 18713 event.preventDefault(); 18714 if (glslcanvas.paused) { 18715 glslcanvas.play(); 18716 // this.controls.playPause.name = '<i class="material-icons">pause</i>';//'Pause'; 18717 _this.controls.playPause.name = '<i class="material-icons">pause</i>'; //'Pause'; 18718 } else { 18719 glslcanvas.pause(); 18720 _this.controls.playPause.name = '<i class="material-icons">play_arrow</i>'; //'Play'; 18721 } 18722 }); 18723 // rec 18724 this.isCapturing = false;
18725 // let rec = new MenuItem(this.controlPanel, 'ge_control_element', '<i class="material-icons">fiber_manual_record</i>', (event) => { 18726 var rec = new _uiMenuItem2["default"](this.controlPanel, "ge_control_element", '<i class="material-icons"></i>', function (event) { 18727 event.stopPropagation(); 18728 event.preventDefault(); 18729 if (_this.isCapturing) { 18730 _this.stopVideoCapture(); 18731 } else { 18732 _this.startVideoCapture(); 18733 } 18734 }); 18735 this.controls.rec = rec; 18736 this.controls.rec.button.style.color = "red"; 18737 18738 // present mode (only if there is a presentation.html file to point to) 18739 // this.controls.presentationMode = new MenuItem(this.controlPanel, 'ge_control_element', '<i class="material-icons">open_in_new</i>', (event) => { 18740 this.controls.presentationMode = new _uiMenuItem2["default"](this.controlPanel, "ge_control_element", '<i class="material-icons">open_in_new</i>', function (event) { 18741 event.stopPropagation(); 18742 event.preventDefault(); 18743 if (main.pWindowOpen) { 18744 main.togglePresentationWindow(false); 18745 } else { 18746 main.togglePresentationWindow(true); 18747 } 18748 }); 18749 18750 this.elControl = this.el.getElementsByClassName(CONTROLS_CLASSNAME)[0]; 18751 this.elControl.addEventListener("mouseenter", function (event) { 18752 _this.showControls(); 18753 }); 18754 this.elControl.addEventListener("mouseleave", function (event) { 18755 _this.hideControls(); 18756 }); 18757 this.elCanvas.addEventListener("mousemove", function (event) { 18758 if (event.offsetY > _this.elCanvas.clientHeight * 0.66) { 18759 _this.showControls(); 18760 } else { 18761 _this.hideControls(); 18762 } 18763 }); 18764 this.hideControls(); 18765 } 18766 18767 // ========== EVENTS 18768 // Draggable/resizable/snappable 18769 if (main.options.canvas_draggable || main.options.canvas_resizable || main.options.canvas_snapable) { 18770 (0, _toolsInteractiveDom.subscribeInteractiveDom)(this.el, { 18771 move: main.options.canvas_draggable, 18772 resize: main.options.canvas_resizable, 18773 snap: main.options.canvas_snapable 18774 }); 18775 18776 if (main.options.canvas_size === "halfscreen") { 18777 this.el.snapRight(); 18778 } 18779 18780 this.el.on("move", function (event) { 18781 event.el.style.width = event.el.clientWidth + "px"; 18782 event.el.style.height = event.el.clientHeight + "px"; 18783 }); 18784 this.el.on("resize", function (event) { 18785 glslcanvas.canvas.style.width = event.el.clientWidth + "px"; 18786 glslcanvas.canvas.style.height = event.el.clientHeight + "px"; 18787 glslcanvas.resize(); 18788 }); 18789 } 18790 18791 // If there is a menu offset the editor to come after it 18792 if (main.menu) { 18793 this.el.style.top = (main.menu.el.clientHeight || main.menu.el.offsetHeight || main.menu.el.scrollHeight) + "px"; 18794 } 18795 18796 // Add all this to the main container 18797 main.container.appendChild(this.el); 18798 glslcanvas.resize(); 18799 } 18800 18801 _createClass(Shader, [{ 18802 key: "hideControls", 18803 value: function hideControls() { 18804 if (this.elControl && this.elControl.className === CONTROLS_CLASSNAME) { 18805 this.elControl.className = CONTROLS_CLASSNAME + " " + CONTROLS_CLASSNAME + "_hidden"; 18806 } 18807 } 18808 }, { 18809 key: "showControls", 18810 value: function showControls() { 18811 if (this.elControl && this.elControl.className === CONTROLS_CLASSNAME + " " + CONTROLS_CLASSNAME + "_hidden") { 18812 this.elControl.className = CONTROLS_CLASSNAME; 18813 } 18814 } 18815 }, { 18816 key: "requestRedraw", 18817 value: function requestRedraw() { 18818 this.canvas.forceRender = true; 18819 this.canvas.render(); 18820 } 18821 }, { 18822 key: "screenshot", 18823 value: function screenshot() { 18824 this.requestRedraw(); 18825 return this.mediaCapture.screenshot(); 18826 } 18827 }, { 18828 key: "startVideoCapture", 18829 value: function startVideoCapture() { 18830 this.requestRedraw(); 18831 if (this.mediaCapture.startVideoCapture()) { 18832 this.isCapturing = true; 18833 this.controls.rec.button.style.color = "white"; 18834 // this.controls.rec.name = '<i class="material-icons">stop</i>'; 18835 this.controls.rec.name = '<i class="material-icons"></i>'; 18836 } 18837 } 18838 }, { 18839 key: "stopVideoCapture", 18840 value: function stopVideoCapture() { 18841 if (this.isCapturing) { 18842 this.isCapturing = false;
18843 this.controls.rec.button.style.color = "red"; 18844 // this.controls.rec.name = '<i class="material-icons">fiber_manual_record</i>'; 18845 this.controls.rec.name = '<i class="material-icons">stop</i>'; 18846 this.mediaCapture.stopVideoCapture().then(function (video) { 18847 (0, _toolsDownload.saveAs)(video.blob, Number(new Date()) + ".webm"); 18848 }); 18849 } 18850 } 18851 }, { 18852 key: "openWindow", 18853 value: function openWindow() { 18854 this.originalSize = { 18855 width: this.canvas.canvas.clientWidth, 18856 height: this.canvas.canvas.clientHeight 18857 }; 18858 this.presentationWindow = window.open("", "_blank", "presentationWindow"); 18859 this.setUpPresentationWindow(); 18860 } 18861 }, { 18862 key: "closeWindow", 18863 value: function closeWindow() { 18864 if (this.presentationWindow) { 18865 this.presentationWindow.close(); 18866 } 18867 } 18868 }, { 18869 key: "setCanvasSize", 18870 value: function setCanvasSize(w, h) { 18871 this.canvas.canvas.style.width = w + "px"; 18872 this.canvas.canvas.style.height = h + "px"; 18873 } 18874 }, { 18875 key: "setUpPresentationWindow", 18876 value: function setUpPresentationWindow() { 18877 this.presentationWindow.document.body.appendChild(this.canvas.canvas); 18878 var d = this.presentationWindow.document; 18879 var div = d.createElement("div"); 18880 div.appendChild(d.createTextNode("Projector mode")); 18881 var span = this.presentationWindow.document.createElement("span"); 18882 div.appendChild(span); 18883 span.appendChild(d.createTextNode(" - If the canvas doesn't update, drag this window and reveal the editor")); 18884 d.body.appendChild(div); 18885 18886 d.title = "GLSL Editor"; 18887 d.body.style.padding = "0"; 18888 d.body.style.margin = "0"; 18889 d.body.style.background = "#171e22"; 18890 d.body.style.overflow = "hidden"; 18891 18892 div.style.position = "absolute"; 18893 div.style.width = "100%"; 18894 div.style.background = "rgba(0, 0, 0, 0.5)"; 18895 div.style.position = "absolute"; 18896 div.style.top = "0"; 18897 div.style.left = "0"; 18898 div.style.right = "0"; 18899 div.style.padding = "16px"; 18900 div.style.color = "#ffffff"; 18901 div.style.fontSize = "14px"; 18902 div.style.fontFamily = "Helvetica, Geneva, sans-serif"; 18903 div.style.fontWeight = "400"; 18904 div.style.letterSpacing = "0.1em"; 18905 div.style.textAlign = "center"; 18906 div.style.opacity = "1"; 18907 div.style.zIndex = "9999"; 18908 div.style.setProperty("-webkit-transition", "opacity 1.5s"); 18909 div.style.setProperty("-moz-transition", "opacity 1.5s"); 18910 div.style.setProperty("transition", "opacity 1.5s"); 18911 18912 span.style.color = "rgba(255, 255, 255, 0.5)"; 18913 18914 setTimeout(function () { 18915 div.style.opacity = 0; 18916 }, 4000); 18917 18918 this.setCanvasSize(this.presentationWindow.innerWidth, this.presentationWindow.innerHeight); 18919 this.presentationWindow.addEventListener("resize", this.onPresentationWindowResize.bind(this)); 18920 this.presentationWindow.addEventListener("unload", this.onPresentationWindowClose.bind(this)); 18921 } 18922 }, { 18923 key: "onPresentationWindowClose", 18924 value: function onPresentationWindowClose() { 18925 this.el.appendChild(this.canvas.canvas); 18926 this.setCanvasSize(this.originalSize.width, this.originalSize.height); 18927 this.canvas.resize(); 18928 18929 this.main.onClosePresentationWindow(); 18930 this.main.menu.onClosePresentationWindow(); 18931 this.presentationWindow = null; 18932 } 18933 }, { 18934 key: "onPresentationWindowResize", 18935 value: function onPresentationWindowResize() { 18936 if (this.presentationWindow) { 18937 this.setCanvasSize(this.presentationWindow.innerWidth, this.presentationWindow.innerHeight); 18938 this.canvas.resize(); 18939 } 18940 } 18941 }]); 18942 18943 return Shader; 18944})(); 18945 18946exports["default"] = Shader; 18947module.exports = exports["default"]; 18948 18949},{"../tools/download":123,"../tools/interactiveDom":124,"../tools/mediaCapture":125,"../ui/MenuItem":132,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11,"babel-runtime/helpers/interop-require-default":14,"glslCanvas":109}],117:[function(_dereq_,module,exports){ 18950// Import CodeMirror 18951'use strict'; 18952 18953var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 18954 18955var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 18956
18957var _Object$keys = _dereq_('babel-runtime/core-js/object/keys')['default']; 18958 18959var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 18960 18961Object.defineProperty(exports, '__esModule', { 18962 value: true 18963}); 18964 18965var _codemirror = _dereq_('codemirror'); 18966 18967var _codemirror2 = _interopRequireDefault(_codemirror); 18968 18969_dereq_('codemirror/mode/clike/clike.js'); 18970 18971var BufferManager = (function () { 18972 function BufferManager(main) { 18973 _classCallCheck(this, BufferManager); 18974 18975 this.main = main; 18976 this.buffers = {}; 18977 this.tabs = {}; 18978 this.current = 'untitled'; 18979 } 18980 18981 _createClass(BufferManager, [{ 18982 key: 'open', 18983 value: function open(name, content) { 18984 var _this = this; 18985 18986 if (!this.el) { 18987 // Create DOM element 18988 this.el = document.createElement('ul'); 18989 this.el.className = 'ge_panel'; 18990 } 18991 18992 if (this.main.change && this.current === 'untitled') { 18993 console.log('Open Current in a different tab'); 18994 this.open(this.current, this.main.getContent()); 18995 } 18996 18997 this.buffers[name] = _codemirror2['default'].Doc(content, 'x-shader/x-fragment'); 18998 18999 // Create a new tab 19000 var tab = document.createElement('li'); 19001 tab.setAttribute('class', 'ge_panel_tab'); 19002 tab.textContent = name; 19003 _codemirror2['default'].on(tab, 'click', function () { 19004 _this.select(name); 19005 }); 19006 19007 var close = tab.appendChild(document.createElement('a')); 19008 close.textContent = 'x'; 19009 close.setAttribute('class', 'ge_panel_tab_close'); 19010 _codemirror2['default'].on(close, 'click', function () { 19011 _this.close(name); 19012 }); 19013 19014 this.el.appendChild(tab); 19015 this.tabs[name] = tab; 19016 19017 if (this.el && !this.panel && this.getLength() > 1) { 19018 // Create Panel CM element 19019 this.panel = this.main.editor.addPanel(this.el, { position: 'top' }); 19020 } 19021 } 19022 }, { 19023 key: 'select', 19024 value: function select(name) { 19025 var buf = this.buffers[name]; 19026 19027 if (buf === undefined) { 19028 return; 19029 } 19030 19031 if (buf.getEditor()) { 19032 buf = buf.linkedDoc({ sharedHist: true }); 19033 } 19034 var old = this.main.editor.swapDoc(buf); 19035 var linked = old.iterLinkedDocs(function (doc) { 19036 linked = doc; 19037 }); 19038 if (linked) { 19039 // Make sure the document in buffers is the one the other view is looking at 19040 for (var bufferName in this.buffers) { 19041 if (this.buffers[bufferName] === old) { 19042 this.buffers[bufferName] = linked; 19043 } 19044 } 19045 old.unlinkDoc(linked); 19046 } 19047 if (this.main.options.autofocus) { 19048 this.main.editor.focus(); 19049 } 19050 this.main.setContent(this.main.getContent()); 19051 19052 if (this.tabs[this.current]) { 19053 this.tabs[this.current].setAttribute('class', 'ge_panel_tab'); 19054 } 19055 this.tabs[name].setAttribute('class', 'ge_panel_tab_active'); 19056 this.current = name; 19057 19058 this.main.editor.setSize(null, 'auto'); 19059 this.main.editor.getWrapperElement().style.height = 'auto'; 19060 19061 this.main.trigger('new_content', {}); 19062 } 19063 }, { 19064 key: 'close', 19065 value: function close(name) { 19066 var needChange = name === this.getCurrent(); 19067 19068 this.el.removeChild(this.tabs[name]); 19069 delete this.tabs[name]; 19070 delete this.buffers[name]; 19071 19072 if (this.getLength() === 1) { 19073 this.panel.clear(); 19074 this.panel = undefined; 19075 this.el = undefined; 19076 } 19077 19078 if (needChange) { 19079 for (var prop in this.tabs) { 19080 this.select(prop); 19081 break; 19082 } 19083 } 19084 } 19085 }, {
19086 key: 'getCurrent', 19087 value: function getCurrent() { 19088 return this.current; 19089 } 19090 }, { 19091 key: 'getLength', 19092 value: function getLength() { 19093 return _Object$keys(this.buffers).length; 19094 } 19095 }]); 19096 19097 return BufferManager; 19098})(); 19099 19100exports['default'] = BufferManager; 19101module.exports = exports['default']; 19102 19103},{"babel-runtime/core-js/object/keys":6,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11,"babel-runtime/helpers/interop-require-default":14,"codemirror":30,"codemirror/mode/clike/clike.js":31}],118:[function(_dereq_,module,exports){ 19104/* 19105Original: https://github.com/tangrams/tangram-play/blob/gh-pages/src/js/addons/ui/FileDrop.js 19106Author: Lou Huang (@saikofish) 19107*/ 19108 19109'use strict'; 19110 19111var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 19112 19113Object.defineProperty(exports, '__esModule', { 19114 value: true 19115}); 19116 19117var FileDrop = function FileDrop(main) { 19118 _classCallCheck(this, FileDrop); 19119 19120 // Set up drag/drop file listeners 19121 main.container.addEventListener('dragenter', function (event) { 19122 // Check to make sure that dropped items are files. 19123 // This prevents other drags (e.g. text in editor) 19124 // from turning on the file drop area. 19125 // See here: http://stackoverflow.com/questions/6848043/how-do-i-detect-a-file-is-being-dragged-rather-than-a-draggable-element-on-my-pa 19126 // Tested in Chrome, Firefox, Safari 8 19127 var types = event.dataTransfer.types; 19128 if (types !== null && (types.indexOf ? types.indexOf('Files') !== -1 : types.contains('application/x-moz-file'))) { 19129 event.preventDefault(); 19130 event.dataTransfer.dropEffect = 'copy'; 19131 } 19132 }, true); 19133 19134 main.container.addEventListener('dragover', function (event) { 19135 // Required to prevent browser from navigating to a file 19136 // instead of receiving a data transfer 19137 event.preventDefault(); 19138 }, false); 19139 19140 main.container.addEventListener('dragleave', function (event) { 19141 event.preventDefault(); 19142 }, true); 19143 19144 main.container.addEventListener('drop', function (event) { 19145 event.preventDefault(); 19146 if (event.dataTransfer.files.length > 0) { 19147 var file = event.dataTransfer.files[0]; 19148 main.open(file); 19149 } 19150 }, false); 19151}; 19152 19153exports['default'] = FileDrop; 19154module.exports = exports['default']; 19155 19156},{"babel-runtime/helpers/class-call-check":10}],119:[function(_dereq_,module,exports){ 19157'use strict'; 19158 19159var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 19160 19161var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 19162 19163Object.defineProperty(exports, '__esModule', { 19164 value: true 19165}); 19166 19167var HashWatch = (function () { 19168 function HashWatch(main) { 19169 var _this = this; 19170 19171 _classCallCheck(this, HashWatch); 19172 19173 this.main = main; 19174 this.check(); 19175 19176 window.addEventListener('hashchange', function () { 19177 _this.check(); 19178 }, false); 19179 } 19180 19181 _createClass(HashWatch, [{ 19182 key: 'check', 19183 value: function check() { 19184 if (window.location.hash !== '') { 19185 this.main.options.imgs = []; 19186 19187 var hashes = location.hash.split('&'); 19188 for (var i in hashes) { 19189 var ext = hashes[i].substr(hashes[i].lastIndexOf('.') + 1); 19190 var path = hashes[i]; 19191 19192 // Extract hash if is present 19193 if (path.search('#') === 0) { 19194 path = path.substr(1); 19195 } 19196 19197 var filename = path.split('/').pop(); 19198 19199 if (ext === 'frag') { 19200 this.main.open(path, filename.replace(/\.[^/.]+$/, '')); 19201 } else if (ext === 'png' || ext === 'jpg' || ext === 'PNG' || ext === 'JPG') { 19202 this.main.options.imgs.push(path); 19203 } 19204 } 19205 } 19206 19207 var query = parseQuery(window.location.search.slice(1)); 19208 if (query) { 19209 for (var key in query) { 19210 if (key === 'log') { 19211 if (this.main.bufferManager) { 19212 var logs = query.log.split(','); 19213 for (var i in logs) { 19214 this.main.open('https://thebookofshaders.com/log/' + logs[i] + '.frag', logs[i]); 19215 } 19216 } else { 19217 this.main.open('https://thebookofshaders.com/log/' + query.log + '.frag', query.log); 19218 } 19219 } else { 19220 var value = query[key]; 19221 if (value === 'true' || value === 'false') { 19222 value = value == 'true'; 19223 } else if (parseFloat(value)) { 19224 value = parseFloat(value); 19225 } 19226 this.main.options[key] = value; 19227 } 19228 } 19229 } 19230 } 19231 }]); 19232 19233 return HashWatch; 19234})(); 19235 19236exports['default'] = HashWatch; 19237 19238function parseQuery(qstr) { 19239 var query = {}; 19240 var a = qstr.split('&'); 19241 for (var i in a) { 19242 var b = a[i].split('='); 19243 query[decodeURIComponent(b[0])] = decodeURIComponent(b[1]); 19244 } 19245 return query; 19246} 19247module.exports = exports['default']; 19248 19249},{"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11}],120:[function(_dereq_,module,exports){ 19250/* 19251Original: https://github.com/tangrams/tangram-play/blob/gh-pages/src/js/addons/LocalStorage.js 19252Author: Lou Huang (@saikofish) 19253*/ 19254 19255/** 19256 * Local storage 19257 * 19258 * Provides a common interface for the application where modules can 19259 * request storage of values across multiple user sessions via the 19260 * browser's LocalStorage API. 19261 * 19262 * Browser support is good, so no fallbacks are implemented. 19263 * This module manages namespacing for Tangram Play to prevent name 19264 * collisions with other libraries, browser extensions, etc. 19265 */ 19266'use strict'; 19267 19268Object.defineProperty(exports, '__esModule', { 19269 value: true 19270}); 19271var LOCAL_STORAGE_PREFIX = 'glslEditor-'; 19272 19273var LocalStorage = { 19274 /** 19275 * setItem() 19276 * Namespaces key name to Tangram Play application and adds 19277 * the value to LocalStorage. 19278 */ 19279 setItem: function setItem(key, value) { 19280 if (window.localStorage) { 19281 window.localStorage.setItem(LOCAL_STORAGE_PREFIX + key, value); 19282 } 19283 }, 19284 19285 /** 19286 * pushItem() 19287 * Store values as an array. If the key doesn't exist as an object, create it. 19288 * Note that this overwrites an old value if it is present and not a JSON object
19288! 19289 * If it exists, retreive it, serialize it into JSON, push the new value, 19290 * re-encode to a string and then set it back in localStorage. 19291 * No other array methods are implemented. If you need to delete items, etc 19292 * then retrieve the string as normal, do the work in your script, and then 19293 * set it to the new stringified array instead of pushing it. 19294 */ 19295 pushItem: function pushItem(key, value) { 19296 var stored = undefined; 19297 stored = this.getItem(key); 19298 // In case there is a previously stored item here that is not 19299 // parseable JSON, don't fail 19300 try { 19301 stored = JSON.parse(stored); 19302 stored.arr = stored.arr || []; 19303 } catch (e) { 19304 stored = { arr: [] }; 19305 } 19306 stored.arr.push(value); 19307 this.setItem(key, JSON.stringify(stored)); 19308 }, 19309 19310 /** 19311 * getItem() 19312 * Retrieves value for the given key name and application namespace. 19313 */ 19314 getItem: function getItem(key) { 19315 if (window.localStorage) { 19316 return window.localStorage.getItem(LOCAL_STORAGE_PREFIX + key); 19317 } 19318 }, 19319 19320 /** 19321 * removeItem() 19322 * Removes key-value pair under the application namespace. 19323 */ 19324 removeItem: function removeItem(key) { 19325 if (window.localStorage) { 19326 window.localStorage.removeItem(LOCAL_STORAGE_PREFIX + key); 19327 } 19328 }, 19329 19330 /** 19331 * clear() 19332 * Loops through all values in localStorage under the application 19333 * namespace and removes them, preserving other key-value pairs in 19334 * localStorage. 19335 */ 19336 clear: function clear() { 19337 if (window.localStorage) { 19338 for (var key in window.localStorage) { 19339 if (key.indexOf(LOCAL_STORAGE_PREFIX) === 0) { 19340 window.localStorage.removeItem(LOCAL_STORAGE_PREFIX + key); 19341 } 19342 } 19343 } 19344 } 19345}; 19346 19347exports['default'] = LocalStorage; 19348module.exports = exports['default']; 19349 19350},{}],121:[function(_dereq_,module,exports){ 19351'use strict'; 19352 19353Object.defineProperty(exports, '__esModule', { 19354 value: true 19355}); 19356exports.getDomOrigin = getDomOrigin; 19357exports.getDevicePixelRatio = getDevicePixelRatio; 19358exports.getJSON = getJSON; 19359 19360function getDomOrigin(el) { 19361 var box = el.getBoundingClientRect ? el.getBoundingClientRect() : { top: 0, left: 0 }; 19362 var doc = el && el.ownerDocument; 19363 var body = doc.body; 19364 var win = doc.defaultView || doc.parentWindow || window; 19365 var docElem = doc.documentElement || body.parentNode; 19366 var clientTop = docElem.clientTop || body.clientTop || 0; // border on html or body or both 19367 var clientLeft = docElem.clientLeft || body.clientLeft || 0; 19368 19369 return { 19370 left: box.left + (win.pageXOffset || docElem.scrollLeft) - clientLeft, 19371 top: box.top + (win.pageYOffset || docElem.scrollTop) - clientTop 19372 }; 19373} 19374 19375function getDevicePixelRatio(ctx) { 19376 var devicePixelRatio = window.devicePixelRatio || 1; 19377 var backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; 19378 return devicePixelRatio / backingStoreRatio; 19379} 19380 19381function getJSON(url, callback) { 19382 var xhr = new XMLHttpRequest(); 19383 xhr.open('GET', url, true); 19384 xhr.responseType = 'json'; 19385 xhr.onload = function () { 19386 var status = xhr.status; 19387 if (status === 200) { 19388 callback(null, xhr.response); 19389 } else { 19390 callback(status, xhr.response); 19391 } 19392 }; 19393 xhr.send(); 19394} 19395 19396; 19397 19398},{}],122:[function(_dereq_,module,exports){ 19399'use strict'; 19400 19401Object.defineProperty(exports, '__esModule', { 19402 value: true 19403}); 19404exports.isCommented = isCommented; 19405exports.isLineAfterMain = isLineAfterMain; 19406exports.getVariableType = getVariableType; 19407exports.getShaderForTypeVarInLine = getShaderForTypeVarInLine; 19408exports.getResultRange = getResultRange; 19409exports.getMedian = getMedian; 19410exports.getDeltaSum = getDeltaSum; 19411exports.getHits = getHits; 19412 19413function isCommented(cm, nLine, match) { 19414 var token = cm.getTokenAt({ line: nLine, ch: match.index }); 19415 if (token && token.type) { 19416 return token.type === 'comment'; 19417 } 19418 return false;
19419} 19420 19421function isLineAfterMain(cm, nLine) { 19422 var totalLines = cm.getDoc().size; 19423 var voidRE = new RegExp('void main\\s*\\(\\s*[void]*\\)', 'i'); 19424 for (var i = 0; i < nLine && i < totalLines; i++) { 19425 // Do not start until being inside the main function 19426 var voidMatch = voidRE.exec(cm.getLine(i)); 19427 if (voidMatch) { 19428 return true; 19429 } 19430 } 19431 return false; 19432} 19433 19434function getVariableType(cm, sVariable) { 19435 var nLines = cm.getDoc().size; 19436 19437 // Show line where the value of the variable is been asigned 19438 var uniformRE = new RegExp('\\s*uniform\\s+(float|vec2|vec3|vec4)\\s+' + sVariable + '\\s*;'); 19439 var voidRE = new RegExp('void main\\s*\\(\\s*[void]*\\)', 'i'); 19440 var voidIN = false; 19441 var constructRE = new RegExp('(float|vec\\d)\\s+(' + sVariable + ')\\s*[;]?', 'i'); 19442 for (var i = 0; i < nLines; i++) { 19443 if (!voidIN) { 19444 // Do not start until being inside the main function 19445 var voidMatch = voidRE.exec(cm.getLine(i)); 19446 if (voidMatch) { 19447 voidIN = true; 19448 } else { 19449 var uniformMatch = uniformRE.exec(cm.getLine(i)); 19450 if (uniformMatch && !isCommented(cm, i, uniformMatch)) { 19451 return uniformMatch[1]; 19452 } 19453 } 19454 } else { 19455 var constructMatch = constructRE.exec(cm.getLine(i)); 19456 if (constructMatch && constructMatch[1] && !isCommented(cm, i, constructMatch)) { 19457 return constructMatch[1]; 19458 } 19459 } 19460 } 19461 return 'none'; 19462} 19463 19464function getShaderForTypeVarInLine(cm, sType, sVariable, nLine) { 19465 var frag = ''; 19466 var offset = 1; 19467 for (var i = 0; i < nLine + 1 && i < cm.getDoc().size; i++) { 19468 if (cm.getLine(i)) { 19469 frag += cm.getLine(i) + '\n'; 19470 } 19471 } 19472 19473 frag += '\tgl_FragColor = '; 19474 if (sType === 'float') { 19475 frag += 'vec4(vec3(' + sVariable + '),1.)'; 19476 } else if (sType === 'vec2') { 19477 frag += 'vec4(vec3(' + sVariable + ',0.),1.)'; 19478 } else if (sType === 'vec3') { 19479 frag += 'vec4(' + sVariable + ',1.)'; 19480 } else if (sType === 'vec4') { 19481 frag += sVariable; 19482 } 19483 frag += ';\n}\n'; 19484 19485 return frag; 19486} 19487 19488function getResultRange(testResults) { 19489 var minMS = '10000000.0'; 19490 var minLine = 0; 19491 var maxMS = '0.0'; 19492 var maxLine = 0; 19493 for (var i in testResults) { 19494 if (testResults[i].ms < minMS) { 19495 minMS = testResults[i].ms; 19496 minLine = testResults[i].line; 19497 } 19498 if (testResults[i].ms > maxMS) { 19499 maxMS = testResults[i].ms; 19500 maxLine = testResults[i].line; 19501 } 19502 } 19503 return { min: { line: minLine, ms: minMS }, max: { line: maxLine, ms: maxMS } }; 19504} 19505 19506function getMedian(values) { 19507 values.sort(function (a, b) { 19508 return a - b; 19509 }); 19510 19511 var half = Math.floor(values.length / 2); 19512 19513 if (values.length % 2) { 19514 return values[half]; 19515 } else { 19516 return (values[half - 1] + values[half]) / 2.0; 19517 } 19518} 19519 19520function getDeltaSum(testResults) { 19521 var total = 0.0; 19522 for (var i in testResults) { 19523 if (testResults[i].delta > 0) { 19524 total += testResults[i].delta; 19525 } 19526 } 19527 return total; 19528} 19529 19530function getHits(testResults) { 19531 var total = 0; 19532 for (var i in testResults) { 19533 if (testResults[i].delta > 0) { 19534 total++; 19535 } 19536 } 19537 return total; 19538} 19539 19540},{}],123:[function(_dereq_,module,exports){ 19541"use strict"; 19542 19543Object.defineProperty(exports, "__esModule", { 19544 value: true 19545}); 19546exports.saveAs = saveAs; 19547 19548function saveAs(blob, filename) { 19549 var url = URL.createObjectURL(blob); 19550 var link = document.createElement("a"); 19551 link.setAttribute("download", filename); 19552 link.setAttribute("href", url); 19553 link.click(); 19554} 19555 19556},{}],124:[function(_dereq_,module,exports){ 19557/* 19558 * Original code from: https://twitter.com/blurspline / https://github.com/zz85 19559 * See post @ http://www.lab4games.net/zz85/blog/2014/11/15/resizing-moving-snapping-windows-with-js-css/ 19560 */ 19561 19562'use strict'; 19563 19564Object.defineProperty(exports, '__esModule', { 19565 value: true 19566}); 19567exports.subscribeInteractiveDom = subscribeInteractiveDom; 19568 19569var _mixin = _dereq_('./mixin'); 19570 19571// Thresholds 19572var FULLSCREEN_MARGINS = -30; 19573var MARGINS = 10; 19574 19575function setBounds(element, x, y, w, h) { 19576 element.style.left = x + 'px'; 19577 element.style.top = y + 'px'; 19578 element.style.width = w + 'px'; 19579 element.style.height = h + 'px'; 19580} 19581 19582function subscribeInteractiveDom(dom, options) { 19583 (0, _mixin.subscribeMixin)(dom); 19584 19585 options = options || {}; 19586 options.resize = options.resize !== undefined ? options.resize : false;
19587 options.move = options.move !== undefined ? options.move : false; 19588 options.snap = options.snap !== undefined ? options.snap : false; 19589 19590 // Minimum resizable area 19591 var minWidth = 100; 19592 var minHeight = 100; 19593 19594 // End of what's configurable. 19595 var clicked = null; 19596 var onRightEdge, onBottomEdge, onLeftEdge, onTopEdge; 19597 19598 var rightScreenEdge, bottomScreenEdge; 19599 19600 var preSnapped; 19601 19602 var b, x, y; 19603 19604 var redraw = false; 19605 19606 var ghostdom = document.createElement('div'); 19607 ghostdom.className = 'ghostdom'; 19608 19609 if (options.snap) { 19610 dom.parentElement.appendChild(ghostdom); 19611 } 19612 19613 // Mouse events 19614 dom.addEventListener('mousedown', onMouseDown); 19615 document.addEventListener('mousemove', onMouseMove); 19616 document.addEventListener('mouseup', onMouseUp); 19617 19618 // Touch events 19619 dom.addEventListener('touchstart', onTouchDown, { passive: false }); 19620 document.addEventListener('touchmove', onTouchMove, { passive: false }); 19621 document.addEventListener('touchend', onTouchEnd, { passive: false }); 19622 19623 function hintHide() { 19624 setBounds(ghostdom, b.left, b.top, b.width, b.height); 19625 ghostdom.style.opacity = 0; 19626 } 19627 19628 function onTouchDown(event) { 19629 event.preventDefault(); 19630 event.stopPropagation(); 19631 if (event.touches.length === 1) { 19632 onDown(event.changedTouches[0]); 19633 } 19634 } 19635 19636 function onTouchMove(event) { 19637 event.preventDefault(); 19638 event.stopPropagation(); 19639 if (event.touches.length === 1) { 19640 onMove(event.changedTouches[0]); 19641 } 19642 } 19643 19644 function onTouchEnd(event) { 19645 event.preventDefault(); 19646 event.stopPropagation(); 19647 if (event.touches.length === 0) { 19648 onUp(event.changedTouches[0]); 19649 } 19650 } 19651 19652 function onMouseDown(event) { 19653 event.preventDefault(); 19654 event.stopPropagation(); 19655 onDown(event); 19656 } 19657 19658 function onMouseMove(event) { 19659 event.preventDefault(); 19660 event.stopPropagation(); 19661 onMove(event); 19662 } 19663 19664 function onMouseUp(event) { 19665 event.preventDefault(); 19666 event.stopPropagation(); 19667 onUp(event); 19668 } 19669 19670 function onDown(event) { 19671 calc(event); 19672 var isResizing = options.resize && (onRightEdge || onBottomEdge || onTopEdge || onLeftEdge); 19673 clicked = { 19674 x: x, 19675 y: y, 19676 cx: event.clientX, 19677 cy: event.clientY, 19678 w: b.width, 19679 h: b.height, 19680 isResizing: isResizing, 19681 isMoving: !isResizing && canMove(), 19682 onTopEdge: onTopEdge, 19683 onLeftEdge: onLeftEdge, 19684 onRightEdge: onRightEdge, 19685 onBottomEdge: onBottomEdge 19686 }; 19687 } 19688 19689 function canMove() { 19690 return options.move && x > 0 && x < b.width && y > 0 && y < b.height; // && y < 30; 19691 } 19692 19693 function calc(event) { 19694 b = dom.getBoundingClientRect(); 19695 x = event.clientX - b.left; 19696 y = event.clientY - b.top; 19697 19698 onTopEdge = y < MARGINS; 19699 onLeftEdge = x < MARGINS; 19700 onRightEdge = x >= b.width - MARGINS; 19701 onBottomEdge = y >= b.height - MARGINS; 19702 19703 rightScreenEdge = window.innerWidth - MARGINS; 19704 bottomScreenEdge = window.innerHeight - MARGINS; 19705 } 19706 19707 var e; 19708 19709 function onMove(event) { 19710 calc(event); 19711 e = event; 19712 redraw = true; 19713 } 19714 19715 function animate() { 19716 requestAnimationFrame(animate); 19717 19718 if (!redraw) { 19719 return; 19720 } 19721 redraw = false; 19722 19723 if (clicked && clicked.isResizing) { 19724 if (clicked.onRightEdge) { 19725 dom.style.width = Math.max(x, minWidth) + 'px'; 19726 } 19727 if (clicked.onBottomEdge) { 19728 dom.style.height = Math.max(y, minHeight) + 'px'; 19729 } 19730 19731 if (clicked.onLeftEdge) { 19732 var currentWidth = Math.max(clicked.cx - e.clientX + clicked.w, minWidth); 19733 if (currentWidth > minWidth) { 19734 dom.style.width = currentWidth + 'px'; 19735 dom.style.removeProperty('right'); 19736 dom.style.left = e.clientX + 'px'; 19737 } 19738 } 19739 19740 if (clicked.onTopEdge) { 19741 var currentHeight = Math.max(clicked.cy - e.clientY + clicked.h, minHeight); 19742 if (currentHeight > minHeight) { 19743 dom.style.height = currentHeight + 'px'; 19744 dom.style.removeProperty('bottom'); 19745 dom.style.top = e.clientY + 'px'; 19746 } 19747 } 19748 19749 hintHide(); 19750 dom.trigger('resize', { finish: false, el: dom }); 19751 return; 19752 } 19753 19754 if (clicked && clicked.isMoving) { 19755 if (options.snap) { 19756 if (b.top < FULLSCREEN_MARGINS || b.left < FULLSCREEN_MARGINS || b.right > window.innerWidth - FULLSCREEN_MARGINS || b.bottom > window.innerHeight - FULLSCREEN_MARGINS) { 19757 setBounds(ghostdom, 0, 0, window.innerWidth, window.innerHeight); 19758 ghostdom.style.opacity = 0.2; 19759 } else if (b.top < MARGINS) { 19760 setBounds(ghostdom, 0, 0, window.innerWidth, window.innerHeight / 2); 19761 ghostdom.style.opacity = 0.2; 19762 } else if (b.left < MARGINS) { 19763 setBounds(ghostdom, 0, 0, window.innerWidth / 2, window.innerHeight); 19764 ghostdom.style.opacity = 0.2; 19765 } else if (b.right > rightScreenEdge) { 19766 setBounds(ghostdom, window.innerWidth / 2, 0, window.innerWidth / 2, window.innerHeight); 19767 ghostdom.style.opacity = 0.2; 19768 } else if (b.bottom > bottomScreenEdge) { 19769 setBounds(ghostdom, 0, window.innerHeight / 2, window.innerWidth, window.innerWidth / 2); 19770 ghostdom.style.opacity = 0.2; 19771 } else { 19772 hintHide(); 19773 } 19774 19775 if (preSnapped) { 19776 setBounds(dom, e.clientX - preSnapped.width / 2, e.clientY - Math.min(clicked.y, preSnapped.height), preSnapped.width, preSnapped.height); 19777 return; 19778 } 19779 19780 // moving 19781 dom.style.removeProperty('right'); 19782 dom.style.removeProperty('bottom'); 19783 dom.style.top = e.clientY - clicked.y + 'px'; 19784 dom.style.left = e.clientX - clicked.x + 'px'; 19785 } else { 19786 var _x = e.clientX - clicked.x; 19787 var _y = e.clientY - clicked.y; 19788 19789 if (_x < 0) { 19790 _x = 0; 19791 } else if (_y < 0) { 19792 _y = 0; 19793 } else if (_x + dom.offsetWidth > window.innerWidth) { 19794 _x = window.innerWidth - dom.offsetWidth; 19795 } else if (_y + dom.offsetHeight > window.innerHeight) { 19796 _y = window.innerHeight - dom.offsetHeight; 19797 } 19798 19799 dom.style.removeProperty('right'); 19800 dom.style.removeProperty('bottom'); 19801 dom.style.left = _x + 'px'; 19802 dom.style.top = _y + 'px'; 19803 } 19804 19805 dom.trigger('move', { finish: false, el: dom }); 19806 return; 19807 } 19808 // This code executes when mouse moves without clicking 19809 19810 // style cursor 19811 if (options.resize && (onRightEdge && onBottomEdge || onLeftEdge && onTopEdge)) { 19812 dom.style.cursor = 'nwse-resize'; 19813 } else if (options.resize && (onRightEdge && onTopEdge || onBottomEdge && onLeftEdge)) { 19814 dom.style.cursor = 'nesw-resize'; 19815 } else if (options.resize && (onRightEdge || onLeftEdge)) { 19816 dom.style.cursor = 'ew-resize'; 19817 } else if (options.resize && (onBottomEdge || onTopEdge)) { 19818 dom.style.cursor = 'ns-resize'; 19819 } else if (canMove()) { 19820 dom.style.cursor = 'move'; 19821 } else { 19822 dom.style.cursor = 'default'; 19823 } 19824 } 19825 animate(); 19826 19827 function onUp(e) { 19828 calc(e); 19829 19830 if (clicked && clicked.isResizing) { 19831 dom.trigger('resize', { finish: true, el: dom }); 19832 } 19833 19834 if (options.snap && clicked && clicked.isMoving) { 19835 // Snap 19836 var snapped = { 19837 width: b.width,
19838 height: b.height 19839 }; 19840 19841 if (b.top < FULLSCREEN_MARGINS || b.left < FULLSCREEN_MARGINS || b.right > window.innerWidth - FULLSCREEN_MARGINS || b.bottom > window.innerHeight - FULLSCREEN_MARGINS) { 19842 setBounds(dom, 0, 0, window.innerWidth, window.innerHeight); 19843 preSnapped = snapped; 19844 } else if (b.top < MARGINS) { 19845 setBounds(dom, 0, 0, window.innerWidth, window.innerHeight / 2); 19846 preSnapped = snapped; 19847 } else if (b.left < MARGINS) { 19848 setBounds(dom, 0, 0, window.innerWidth / 2, window.innerHeight); 19849 preSnapped = snapped; 19850 } else if (b.right > rightScreenEdge) { 19851 setBounds(dom, window.innerWidth / 2, 0, window.innerWidth / 2, window.innerHeight); 19852 preSnapped = snapped; 19853 } else if (b.bottom > bottomScreenEdge) { 19854 setBounds(dom, 0, window.innerHeight / 2, window.innerWidth, window.innerWidth / 2); 19855 preSnapped = snapped; 19856 } else { 19857 preSnapped = null; 19858 } 19859 hintHide(); 19860 dom.trigger('move', { finish: true, el: dom }); 19861 dom.trigger('resize', { finish: true, el: dom }); 19862 } 19863 clicked = null; 19864 } 19865 19866 dom.snapRight = function () { 19867 var snapped = { 19868 width: dom.width, 19869 height: dom.height 19870 }; 19871 19872 setBounds(dom, window.innerWidth / 2, 0, window.innerWidth / 2, window.innerHeight); 19873 preSnapped = snapped; 19874 // hintHide(); 19875 dom.trigger('move', { finish: true, el: dom }); 19876 dom.trigger('resize', { finish: true, el: dom }); 19877 }; 19878 19879 return dom; 19880} 19881 19882},{"./mixin":126}],125:[function(_dereq_,module,exports){ 19883/* global MediaRecorder 19884Author: Brett Camper (@professorlemeza) 19885URL: https://github.com/tangrams/tangram/blob/master/src/utils/media_capture.js 19886*/ 19887'use strict'; 19888 19889var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 19890 19891var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 19892 19893var _Promise = _dereq_('babel-runtime/core-js/promise')['default']; 19894 19895Object.defineProperty(exports, '__esModule', { 19896 value: true 19897}); 19898 19899var _urls = _dereq_('./urls'); 19900 19901var MediaCapture = (function () { 19902 function MediaCapture() { 19903 _classCallCheck(this, MediaCapture); 19904 19905 this.queueScreenshot = null; 19906 this.videoCapture = null; 19907 } 19908 19909 _createClass(MediaCapture, [{ 19910 key: 'setCanvas', 19911 value: function setCanvas(canvas) { 19912 this.canvas = canvas; 19913 } 19914 19915 // Take a screenshot, returns a promise that resolves with the screenshot data when available 19916 }, { 19917 key: 'screenshot', 19918 value: function screenshot() { 19919 var _this = this; 19920 19921 if (this.queueScreenshot != null) { 19922 return this.queueScreenshot.promise; // only capture one screenshot at a time 19923 } 19924
19925 // Will resolve once rendering is complete and render buffer is captured 19926 this.queueScreenshot = {}; 19927 this.queueScreenshot.promise = new _Promise(function (resolve, reject) { 19928 _this.queueScreenshot.resolve = resolve; 19929 _this.queueScreenshot.reject = reject; 19930 }); 19931 return this.queueScreenshot.promise; 19932 } 19933 19934 // Called after rendering, captures render buffer and resolves promise with the image data 19935 }, { 19936 key: 'completeScreenshot', 19937 value: function completeScreenshot() { 19938 if (this.queueScreenshot != null) { 19939 // Get data URL, convert to blob 19940 // Strip host/mimetype/etc., convert base64 to binary without UTF-8 mangling 19941 // Adapted from: https://gist.github.com/unconed/4370822 19942 var url = this.canvas.toDataURL('image/png'); 19943 var data = atob(url.slice(22)); 19944 var buffer = new Uint8Array(data.length); 19945 for (var i = 0; i < data.length; ++i) { 19946 buffer[i] = data.charCodeAt(i); 19947 } 19948 var blob = new Blob([buffer], { type: 'image/png' }); 19949 19950 // Resolve with screenshot data 19951 this.queueScreenshot.resolve({ url: url, blob: blob, type: 'png' }); 19952 this.queueScreenshot = null; 19953 } 19954 } 19955 19956 // Starts capturing a video stream from the canvas 19957 }, { 19958 key: 'startVideoCapture', 19959 value: function startVideoCapture() { 19960 var _this2 = this; 19961 19962 if (typeof window.MediaRecorder !== 'function' || !this.canvas || typeof this.canvas.captureStream !== 'function') { 19963 console.log('warn: Video capture (Canvas.captureStream and/or MediaRecorder APIs) not supported by browser'); 19964 return false; 19965 } else if (this.videoCapture) { 19966 console.log('warn: Video capture already in progress, call Scene.stopVideoCapture() first'); 19967 return false; 19968 } 19969 19970 // Start a new capture 19971 try { 19972 (function () { 19973 var cap = _this2.videoCapture = {}; 19974 cap.chunks = []; 19975 cap.stream = _this2.canvas.captureStream(); 19976 cap.options = { mimeType: 'video/webm' }; // TODO: support other format options 19977 cap.mediaRecorder = new MediaRecorder(cap.stream, cap.options); 19978 cap.mediaRecorder.ondataavailable = function (event) { 19979 if (event.data.size > 0) { 19980 cap.chunks.push(event.data); 19981 } 19982 19983 // Stopped recording? Create the final capture file blob 19984 if (cap.resolve) { 19985 var blob = new Blob(cap.chunks, { type: cap.options.mimeType }); 19986 var url = (0, _urls.createObjectURL)(blob); 19987 19988 // Explicitly remove all stream tracks, and set objects to null 19989 if (cap.stream) { 19990 var tracks = cap.stream.getTracks() || []; 19991 tracks.forEach(function (track) { 19992 track.stop(); 19993 cap.stream.removeTrack(track); 19994 }); 19995 } 19996 cap.stream = null; 19997 cap.mediaRecorder = null; 19998 _this2.videoCapture = null; 19999 20000 cap.resolve({ url: url, blob: blob, type: 'webm' }); 20001 } 20002 }; 20003 cap.mediaRecorder.start(); 20004 })(); 20005 } catch (e) { 20006 this.videoCapture = null; 20007 console.log('error: Scene video capture failed', e); 20008 return false; 20009 } 20010 return true; 20011 } 20012 20013 // Stops capturing a video stream from the canvas, returns a promise that resolves with the video when available 20014 }, {
20015 key: 'stopVideoCapture', 20016 value: function stopVideoCapture() { 20017 var _this3 = this; 20018 20019 if (!this.videoCapture) { 20020 console.log('warn: No scene video capture in progress, call Scene.startVideoCapture() first'); 20021 return _Promise.resolve({}); 20022 } 20023 20024 // Promise that will resolve when final stream is available 20025 this.videoCapture.promise = new _Promise(function (resolve, reject) { 20026 _this3.videoCapture.resolve = resolve; 20027 _this3.videoCapture.reject = reject; 20028 }); 20029 20030 // Stop recording 20031 this.videoCapture.mediaRecorder.stop(); 20032 20033 return this.videoCapture.promise; 20034 } 20035 }]); 20036 20037 return MediaCapture; 20038})(); 20039 20040exports['default'] = MediaCapture; 20041module.exports = exports['default']; 20042 20043},{"./urls":127,"babel-runtime/core-js/promise":8,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11}],126:[function(_dereq_,module,exports){ 20044/* 20045Add events to a class or object: 20046 class MyClass { 20047 constructor() { 20048 subscribeMixin(this); // Add the mixing functions to the class 20049 ... 20050 this.trigger('something', { owner: this, content: 'that'}); // trigger an event passing some arguments 20051 20052Subscribe to events by doing: 20053 myClass.on('something', (args) => { 20054 console.log(args); 20055 }); 20056 20057Unsubscribe to events by doing: 20058 myClass.off('something'); 20059 20060or more presicelly: 20061 myClass.off('something', (args) => { 20062 console.log(args); 20063 }); 20064 20065Unsubscribe to all events by: 20066 myClass.offAll(); 20067*/ 20068 20069'use strict'; 20070 20071var _Set = _dereq_('babel-runtime/core-js/set')['default']; 20072 20073var _Object$assign = _dereq_('babel-runtime/core-js/object/assign')['default']; 20074 20075var _getIterator = _dereq_('babel-runtime/core-js/get-iterator')['default']; 20076 20077var _Object$keys = _dereq_('babel-runtime/core-js/object/keys')['default']; 20078 20079Object.defineProperty(exports, '__esModule', { 20080 value: true 20081}); 20082exports.subscribeMixin = subscribeMixin; 20083 20084function subscribeMixin(target) { 20085 var listeners = new _Set(); 20086 20087 return _Object$assign(target, { 20088 20089 on: function on(type, f) { 20090 var listener = {}; 20091 listener[type] = f; 20092 listeners.add(listener); 20093 }, 20094 20095 off: function off(type, f) { 20096 if (f) { 20097 var listener = {}; 20098 listener[type] = f; 20099 listeners['delete'](listener); 20100 } else { 20101 var _iteratorNormalCompletion = true; 20102 var _didIteratorError = false; 20103 var _iteratorError = undefined; 20104 20105 try { 20106 for (var _iterator = _getIterator(listeners), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { 20107 var item = _step.value; 20108 var _iteratorNormalCompletion2 = true; 20109 var _didIteratorError2 = false;
20110 var _iteratorError2 = undefined; 20111 20112 try { 20113 for (var _iterator2 = _getIterator(_Object$keys(item)), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { 20114 var key = _step2.value; 20115 20116 if (key === type) { 20117 listeners['delete'](item); 20118 return; 20119 } 20120 } 20121 } catch (err) { 20122 _didIteratorError2 = true; 20123 _iteratorError2 = err; 20124 } finally { 20125 try { 20126 if (!_iteratorNormalCompletion2 && _iterator2['return']) { 20127 _iterator2['return'](); 20128 } 20129 } finally { 20130 if (_didIteratorError2) { 20131 throw _iteratorError2; 20132 } 20133 } 20134 } 20135 } 20136 } catch (err) { 20137 _didIteratorError = true; 20138 _iteratorError = err; 20139 } finally { 20140 try { 20141 if (!_iteratorNormalCompletion && _iterator['return']) { 20142 _iterator['return'](); 20143 } 20144 } finally { 20145 if (_didIteratorError) { 20146 throw _iteratorError; 20147 } 20148 } 20149 } 20150 } 20151 }, 20152 20153 offAll: function offAll() { 20154 listeners.clear(); 20155 }, 20156 20157 trigger: function trigger(event) { 20158 var _iteratorNormalCompletion3 = true; 20159 var _didIteratorError3 = false; 20160 var _iteratorError3 = undefined; 20161 20162 try { 20163 for (var _len = arguments.length, data = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 20164 data[_key - 1] = arguments[_key]; 20165 } 20166 20167 for (var _iterator3 = _getIterator(listeners), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { 20168 var listener = _step3.value; 20169 20170 if (typeof listener[event] === 'function') { 20171 listener[event].apply(listener, data); 20172 } 20173 } 20174 } catch (err) { 20175 _didIteratorError3 = true; 20176 _iteratorError3 = err; 20177 } finally { 20178 try { 20179 if (!_iteratorNormalCompletion3 && _iterator3['return']) { 20180 _iterator3['return'](); 20181 } 20182 } finally { 20183 if (_didIteratorError3) { 20184 throw _iteratorError3; 20185 } 20186 } 20187 } 20188 }, 20189 20190 listSubscriptions: function listSubscriptions() { 20191 var _iteratorNormalCompletion4 = true; 20192 var _didIteratorError4 = false; 20193 var _iteratorError4 = undefined; 20194 20195 try { 20196 for (var _iterator4 = _getIterator(listeners), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { 20197 var item = _step4.value; 20198 20199 console.log(item); 20200 } 20201 } catch (err) { 20202 _didIteratorError4 = true; 20203 _iteratorError4 = err; 20204 } finally { 20205 try { 20206 if (!_iteratorNormalCompletion4 && _iterator4['return']) { 20207 _iterator4['return'](); 20208 } 20209 } finally { 20210 if (_didIteratorError4) { 20211 throw _iteratorError4; 20212 } 20213 } 20214 } 20215 } 20216 }); 20217} 20218 20219},{"babel-runtime/core-js/get-iterator":1,"babel-runtime/core-js/object/assign":2,"babel-runtime/core-js/object/keys":6,"babel-runtime/core-js/set":9}],127:[function(_dereq_,module,exports){ 20220'use strict'; 20221 20222Object.defineProperty(exports, '__esModule', { 20223 value: true 20224}); 20225exports.createObjectURL = createObjectURL; 20226var _createObjectURL = undefined; 20227 20228function createObjectURL(url) { 20229 if (_createObjectURL === undefined) { 20230 _createObjectURL = window.URL && window.URL.createObjectURL || window.webkitURL && window.webkitURL.createObjectURL; 20231 if (typeof _createObjectURL !== 'function') { 20232 _createObjectURL = null; 20233 console.log('window.URL.createObjectURL (or vendor prefix) not found, unable to create local blob URLs'); 20234 } 20235 } 20236 20237 if (_createObjectURL) { 20238 return _createObjectURL(url); 20239 } else { 20240 return url; 20241 } 20242} 20243 20244},{}],128:[function(_dereq_,module,exports){ 20245'use strict'; 20246 20247var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 20248 20249var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 20250 20251Object.defineProperty(exports, '__esModule', { 20252 value: true 20253}); 20254 20255var ErrorsDisplay = (function () { 20256 function ErrorsDisplay(main) { 20257 var _this = this; 20258 20259 _classCallCheck(this, ErrorsDisplay); 20260 20261 this.main = main; 20262 20263 // private variables 20264 this.widgets = []; 20265 20266 // EVENTS 20267 this.main.shader.canvas.on('error', function (arg) { 20268 if (_this.main.visualDebugger && _this.main.visualDebugger.testing) { 20269 _this.clean(); 20270 } else { 20271 _this.clean(); 20272 _this.addError(arg); 20273 } 20274 }); 20275 20276 this.main.editor.on('changes', function (cm, changesObjs) { 20277 if (_this.main.shader.canvas.isValid) { 20278 _this.clean(); 20279 } 20280 }); 20281 } 20282 20283 _createClass(ErrorsDisplay, [{ 20284 key: 'clean', 20285 value: function clean() { 20286 for (var i = 0; i < this.widgets.length; i++) { 20287 this.main.editor.removeLineWidget(this.widgets[i]); 20288 } 20289 this.widgets.length = 0; 20290 } 20291 }, {
20292 key: 'addError', 20293 value: function addError(args) { 20294 var re = /ERROR:\s+\d+:(\d+):\s+('.*)/g; 20295 var matches = re.exec(args.error); 20296 if (matches) { 20297 var numLines = 0; 20298 if (this.main.options.frag_header.length > 0) numLines += (this.main.options.frag_header.match(/\r?\n/g) || '').length; 20299 20300 var line = parseInt(matches[1]) - numLines; 20301 var er = matches[2]; 20302 var msg = document.createElement('div'); 20303 20304 var icon = msg.appendChild(document.createElement('span')); 20305 icon.className = 'ge-error-icon'; 20306 icon.innerHTML = 'x'; 20307 msg.appendChild(document.createTextNode(er)); 20308 msg.className = 'ge-error'; 20309 this.widgets.push(this.main.editor.addLineWidget(line, msg)); //, { coverGutter: false, noHScroll: true })); 20310 } 20311 } 20312 }]); 20313 20314 return ErrorsDisplay; 20315})(); 20316 20317exports['default'] = ErrorsDisplay; 20318module.exports = exports['default']; 20319 20320},{"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11}],129:[function(_dereq_,module,exports){ 20321'use strict'; 20322 20323var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 20324 20325var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 20326 20327Object.defineProperty(exports, '__esModule', { 20328 value: true 20329}); 20330 20331var _modalsExportModal = _dereq_('./modals/ExportModal'); 20332 20333var _modalsExportModal2 = _interopRequireDefault(_modalsExportModal); 20334 20335var ExportIcon = function ExportIcon(main) { 20336 var _this = this; 20337 20338 _classCallCheck(this, ExportIcon); 20339 20340 this.main = main; 20341 20342 this.el = document.createElement('div'); 20343 this.el.setAttribute('class', 'ge_export_icon'); 20344 this.el.innerHTML = '△'; 20345 // this.el.innerHTML = '<i class="material-icons">more_vert</i>'; 20346 this.el.addEventListener('click', function (event) { 20347 if (main.change || !_this.modal) { 20348 _this.modal = new _modalsExportModal2['default']('ge_export', { main: main }); 20349 } 20350 _this.modal.presentModal(event.target.offsetLeft, event.target.offsetTop); 20351 }, true); 20352 20353 this.main.container.appendChild(this.el); 20354}; 20355 20356exports['default'] = ExportIcon; 20357module.exports = exports['default']; 20358 20359},{"./modals/ExportModal":134,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/interop-require-default":14}],130:[function(_dereq_,module,exports){ 20360'use strict'; 20361 20362var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 20363 20364var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 20365 20366var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 20367 20368Object.defineProperty(exports, '__esModule', { 20369 value: true 20370}); 20371 20372var _pickersColorPicker = _dereq_('./pickers/ColorPicker'); 20373 20374var _pickersColorPicker2 = _interopRequireDefault(_pickersColorPicker); 20375 20376var _pickersVec3Picker = _dereq_('./pickers/Vec3Picker'); 20377 20378var _pickersVec3Picker2 = _interopRequireDefault(_pickersVec3Picker); 20379 20380var _pickersVec2Picker = _dereq_('./pickers/Vec2Picker'); 20381 20382var _pickersVec2Picker2 = _interopRequireDefault(_pickersVec2Picker); 20383 20384var _pickersFloatPicker = _dereq_('./pickers/FloatPicker'); 20385 20386var _pickersFloatPicker2 = _interopRequireDefault(_pickersFloatPicker); 20387 20388var _pickersTypesColor = _dereq_('./pickers/types/Color'); 20389 20390var _pickersTypesColor2 = _interopRequireDefault(_pickersTypesColor); 20391 20392var _modalsModal = _dereq_('./modals/Modal'); 20393 20394var _modalsModal2 = _interopRequireDefault(_modalsModal); 20395 20396// Return all pattern matches with captured groups 20397RegExp.prototype.execAll = function (string) { 20398 var match = null; 20399 var matches = []; 20400 while (match = this.exec(string)) { 20401 var matchArray = []; 20402 for (var i in match) { 20403 if (parseInt(i) == i) { 20404 matchArray.push(match[i]); 20405 } 20406 } 20407 matchArray.index = match.index; 20408 matches.push(matchArray); 20409 } 20410 return matches; 20411}; 20412 20413var Helpers = (function () { 20414 function Helpers(main) { 20415 var _this = this; 20416 20417 _classCallCheck(this, Helpers); 20418 20419 this.main = main; 20420 this.main.debugging = false;
20421 20422 var style = window.getComputedStyle(main.editor.getWrapperElement(), null); 20423 var bgColor = new _pickersTypesColor2['default'](style.background !== '' ? style.background : style.backgroundColor); 20424 var fgColor = new _pickersTypesColor2['default'](style.color); 20425 20426 this.properties = { 20427 bgColor: bgColor.getString('rgb'), 20428 fnColor: fgColor.getString('rgb'), 20429 dimColor: 'rgb(127, 127, 127)', 20430 selColor: 'rgb(40, 168, 107)', 20431 linkButton: true 20432 }; 20433 20434 // EVENTS 20435 var wrapper = this.main.editor.getWrapperElement(); 20436 wrapper.addEventListener('contextmenu', function (event) { 20437 var cursor = _this.main.editor.getCursor(true); 20438 var token = _this.main.editor.getTokenAt(cursor); 20439 if (token.type === 'variable') { 20440 _this.main.visualDebugger.debug(token.string, cursor.line); 20441 } else { 20442 _this.main.update(); 20443 } 20444 }); 20445 20446 wrapper.addEventListener('mouseup', function (event) { 20447 // bail out if we were doing a selection and not a click 20448 if (_this.main.editor.somethingSelected()) { 20449 return; 20450 } 20451 20452 var cursor = _this.main.editor.getCursor(true); 20453 20454 // see if there is a match on the cursor click 20455 var match = _this.getMatch(cursor); 20456 var token = _this.main.editor.getTokenAt(cursor); 20457 if (match) { 20458 _this.main.visualDebugger.clean(event); 20459 _this.main.update(); 20460 20461 // Toggles the trackpad to be off if it's already present. 20462 if (_this.activeModal && _this.activeModal.isVisible) { 20463 _this.activeModal.removeModal(); 20464 return; 20465 } 20466 20467 if (match.type === 'color') { 20468 _this.activeModal = new _pickersColorPicker2['default'](match.string, _this.properties); 20469 _this.activeModal.showAt(_this.main.editor); 20470 _this.activeModal.on('changed', function (color) { 20471 var newColor = color.getString('vec'); 20472 var start = { line: cursor.line, ch: match.start }; 20473 var end = { line: cursor.line, ch: match.end }; 20474 match.end = match.start + newColor.length; 20475 _this.main.editor.replaceRange(newColor, start, end, '+' + match.type); 20476 }); 20477 20478 _this.activeModal.on('linkButton', function (color) { 20479 _this.activeModal = new _pickersVec3Picker2['default'](color.getString('vec'), _this.properties); 20480 _this.activeModal.showAt(_this.main.editor); 20481 _this.activeModal.on('changed', function (dir) { 20482 var newDir = dir.getString('vec3'); 20483 var start = { line: cursor.line, ch: match.start }; 20484 var end = { line: cursor.line, ch: match.end }; 20485 match.end = match.start + newDir.length; 20486 _this.main.editor.replaceRange(newDir, start, end, '+' + match.type); 20487 }); 20488 }); 20489 } 20490 if (match.type === 'vec3') { 20491 _this.activeModal = new _pickersVec3Picker2['default'](match.string, _this.properties); 20492 _this.activeModal.showAt(_this.main.editor); 20493 _this.activeModal.on('changed', function (dir) { 20494 var newDir = dir.getString('vec3'); 20495 var start = { line: cursor.line, ch: match.start }; 20496 var end = { line: cursor.line, ch: match.end }; 20497 match.end = match.start + newDir.length; 20498 _this.main.editor.replaceRange(newDir, start, end, '+' + match.type); 20499 }); 20500 } else if (match.type === 'vec2') { 20501 _this.activeModal = new _pickersVec2Picker2['default'](match.string, _this.properties); 20502 _this.activeModal.showAt(_this.main.editor); 20503 _this.activeModal.on('changed', function (pos) { 20504 var newpos = pos.getString(); 20505 var start = { line: cursor.line, ch: match.start }; 20506 var end = { line: cursor.line, ch: match.end }; 20507 match.end = match.start + newpos.length; 20508 _this.main.editor.replaceRange(newpos, start, end, '+' + match.type); 20509 }); 20510 } else if (match.type === 'number') { 20511 _this.activeModal = new _pickersFloatPicker2['default'](match.string, _this.properties); 20512 _this.activeModal.showAt(_this.main.editor); 20513 _this.activeModal.on('changed', function (number) { 20514 var newNumber = number.getString(); 20515 var start = { line: cursor.line, ch: match.start }; 20516 var end = { line: cursor.line, ch: match.end }; 20517 match.end = match.start + newNumber.length; 20518 _this.main.editor.replaceRange(newNumber, start, end, '+' + match.type); 20519 }); 20520 } 20521 } else if (_this.main.options.tooltips && (token.type === 'builtin' || token.type === 'variable-3')) { 20522 _this.main.visualDebugger.clean(event); 20523 var html = '<p>Learn more about: <a href="https://thebookofshaders.com/glossary/?search=' + token.string + '" target="_blank">' + token.string + '</a></p>'; 20524 _this.activeModal = new _modalsModal2['default']('ge_tooltip', { innerHTML: html }); 20525 _this.activeModal.showAt(_this.main.editor); 20526 } else if (token.type === 'variable') { 20527 if (_this.main.visualDebugger) { 20528 _this.main.visualDebugger.clean(event); 20529 _this.main.visualDebugger.iluminate(token.string); 20530 } 20531 } 20532 }); 20533 } 20534 20535 _createClass(Helpers, [{ 20536 key: 'getMatch', 20537 value: function getMatch(cursor) { 20538 var types = ['color', 'vec3', 'vec2', 'number']; 20539 var rta = undefined; 20540 for (var i in types) { 20541 rta = this.getTypeMatch(cursor, types[i]); 20542 if (rta) { 20543 return rta; 20544 } 20545 } 20546 return; 20547 } 20548 }, {
20549 key: 'getTypeMatch', 20550 value: function getTypeMatch(cursor, type) { 20551 if (!type) { 20552 return; 20553 } 20554 var re = undefined; 20555 switch (type.toLowerCase()) { 20556 case 'color': 20557 re = /vec[3|4]\([\d|.|,\s]*\)/g; 20558 break; 20559 case 'vec3': 20560 re = /vec3\([-|\d|.|,\s]*\)/g; 20561 break; 20562 case 'vec2': 20563 re = /vec2\([-|\d|.|,\s]*\)/g; 20564 break; 20565 case 'number': 20566 re = /[-]?\d+\.\d+|\d+\.|\.\d+/g; 20567 break; 20568 default: 20569 console.error('invalid match selection'); 20570 return; 20571 } 20572 var line = this.main.editor.getLine(cursor.line); 20573 var matches = re.execAll(line); 20574 20575 if (matches) { 20576 for (var i = 0; i < matches.length; i++) { 20577 var val = matches[i][0]; 20578 var len = val.length; 20579 var start = matches[i].index; 20580 var end = matches[i].index + len; 20581 if (cursor.ch >= start && cursor.ch <= end) { 20582 return { 20583 type: type, 20584 start: start, 20585 end: end, 20586 string: val 20587 }; 20588 } 20589 } 20590 } 20591 return; 20592 } 20593 }]); 20594 20595 return Helpers; 20596})(); 20597 20598exports['default'] = Helpers; 20599module.exports = exports['default']; 20600 20601},{"./modals/Modal":135,"./pickers/ColorPicker":136,"./pickers/FloatPicker":137,"./pickers/Vec2Picker":139,"./pickers/Vec3Picker":140,"./pickers/types/Color":141,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11,"babel-runtime/helpers/interop-require-default":14}],131:[function(_dereq_,module,exports){ 20602'use strict'; 20603 20604var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 20605 20606var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 20607 20608Object.defineProperty(exports, '__esModule', { 20609 value: true 20610}); 20611 20612var _MenuItem = _dereq_('./MenuItem'); 20613 20614var _MenuItem2 = _interopRequireDefault(_MenuItem); 20615 20616var _modalsExportModal = _dereq_('./modals/ExportModal'); 20617 20618var _modalsExportModal2 = _interopRequireDefault(_modalsExportModal); 20619 20620var Menu = function Menu(main) { 20621 var _this = this; 20622 20623 _classCallCheck(this, Menu); 20624 20625 this.main = main; 20626 this.menus = {}; 20627 20628 // CREATE MENU Container 20629 this.el = document.createElement('ul'); 20630 this.el.setAttribute('class', 'ge_menu_bar'); 20631 20632 // NEW 20633 this.menus['new'] = new _MenuItem2['default'](this.el, 'ge_menu', '<i class="material-icons">add</i> New', function (event) { 20634 main['new'](); 20635 }); 20636 20637 // OPEN 20638 this.fileInput = document.createElement('input'); 20639 this.fileInput.setAttribute('type', 'file'); 20640 this.fileInput.setAttribute('accept', 'text/x-yaml'); 20641 this.fileInput.style.display = 'none'; 20642 this.fileInput.addEventListener('change', function (event) { 20643 main.open(event.target.files[0]); 20644 }); 20645 this.menus.open = new _MenuItem2['default'](this.el, 'ge_menu', '<i class="material-icons">folder_open</i> Open', function (event) { 20646 _this.fileInput.click(); 20647 }); 20648 20649 // this.menus.autoupdate.button.style.color = main.autoupdate ? 'white' : 'gray'; 20650 20651 // TEST 20652 this.menus.test = new _MenuItem2['default'](this.el, 'ge_menu', '<i class="material-icons">timeline</i> Test', function (event) { 20653 main.visualDebugger.check(); 20654 }); 20655 20656 // SHARE 20657 this.menus.share = new _MenuItem2['default'](this.el, 'ge_menu', '<i class="material-icons">arrow_upward</i> Export', function (event) { 20658 if (main.change || !_this.exportModal) { 20659 _this.exportModal = new _modalsExportModal2['default']('ge_export', { main: main, position: 'fixed' }); 20660 } 20661 20662 var bbox = _this.menus.share.el.getBoundingClientRect(); 20663 _this.exportModal.presentModal(bbox.left - 5, bbox.top + bbox.height + 5); 20664 }); 20665 20666 // AUTOUPDATE 20667 this.menus.autoupdate = new _MenuItem2['default'](this.el, 'ge_menu', ' <i class="material-icons">autorenew</i> Update: ON', function (event) { 20668 if (main.autoupdate) { 20669 main.autoupdate = false;
20670 _this.menus.autoupdate.name = '<i class="material-icons">autorenew</i> Update: OFF'; 20671 // this.menus.autoupdate.button.style.color = 'gray'; 20672 } else { 20673 main.autoupdate = true; 20674 main.update(); 20675 _this.menus.autoupdate.name = '<i class="material-icons">autorenew</i> Update: ON'; 20676 // this.menus.autoupdate.button.style.color = 'white'; 20677 } 20678 }); 20679 20680 main.container.appendChild(this.el); 20681}; 20682 20683exports['default'] = Menu; 20684module.exports = exports['default']; 20685 20686},{"./MenuItem":132,"./modals/ExportModal":134,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/interop-require-default":14}],132:[function(_dereq_,module,exports){ 20687'use strict'; 20688 20689var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 20690 20691var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 20692 20693Object.defineProperty(exports, '__esModule', { 20694 value: true 20695}); 20696 20697var MenuItem = (function () { 20698 function MenuItem(container, className, name, onClick) { 20699 _classCallCheck(this, MenuItem); 20700 20701 this.el = document.createElement('li'); 20702 this.button = document.createElement('button'); 20703 this.button.className = className + '_button'; 20704 this.el.appendChild(this.button); 20705 this.el.setAttribute('class', className); 20706 this.button.innerHTML = name; 20707 this.className = className; 20708 this.hiddenClass = className + '--hidden'; 20709 20710 // Attach listeners, including those for tooltip behavior 20711 this.button.addEventListener('click', onClick, true); 20712 20713 if (container) { 20714 container.appendChild(this.el); 20715 } 20716 } 20717 20718 _createClass(MenuItem, [{ 20719 key: 'hide', 20720 value: function hide() { 20721 this.el.setAttribute('class', this.className + ' ' + this.hiddenClass); 20722 } 20723 }, { 20724 key: 'show', 20725 value: function show() { 20726 this.el.setAttribute('class', this.className); 20727 } 20728 }, { 20729 key: 'name', 20730 set: function set(name) { 20731 this.button.innerHTML = name; 20732 } 20733 }]); 20734 20735 return MenuItem; 20736})(); 20737 20738exports['default'] = MenuItem; 20739module.exports = exports['default']; 20740 20741},{"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11}],133:[function(_dereq_,module,exports){ 20742'use strict'; 20743 20744var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 20745 20746var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 20747 20748Object.defineProperty(exports, '__esModule', { 20749 value: true 20750}); 20751 20752var _toolsDebugging = _dereq_('../tools/debugging'); 20753 20754var _coreEditorJs = _dereq_('../core/Editor.js'); 20755 20756var mainGE = {}; 20757var N_SAMPLES = 30; 20758 20759var VisualDebugger = (function () { 20760 function VisualDebugger(main) { 20761 var _this = this; 20762 20763 _classCallCheck(this, VisualDebugger); 20764 20765 this.main = main; 20766 this.breakpoint = null; 20767 mainGE = main; 20768 20769 this.testing = false; 20770 this.testingFrag = ''; 20771 this.testingLine = 0; 20772 this.testingResults = []; 20773 this.testingSamples = []; 20774 20775 this.main.editor.on('gutterClick', function (cm, n) { 20776 var info = cm.lineInfo(n); 20777 if (info && info.gutterMarkers && info.gutterMarkers.breakpoints) { 20778 // Check for an active variable (a variable that have been declare or modify in this line) 20779 var variableRE = new RegExp('\\s*[float|vec2|vec3|vec4]?\\s+([\\w|\\_]*)[\\.\\w]*?\\s+[\\+|\\-|\\\\|\\*]?\\=', 'i'); 20780 var match = variableRE.exec(info.text); 20781 if (match) { 20782 _this.debug(match[1], info.line); 20783 _this.breakpoint = info.line; 20784 } 20785 } 20786 }); 20787 } 20788 20789 _createClass(VisualDebugger, [{ 20790 key: 'check', 20791 value: function check() { 20792 // Clean previus records 20793 this.testingResults = []; 20794 20795 var cm = this.main.editor; 20796 var nLines = cm.getDoc().size; 20797 20798 var mainStartsAt = 0; 20799 for (var i = 0; i < nLines; i++) { 20800 if ((0, _toolsDebugging.isLineAfterMain)(cm, i)) { 20801 mainStartsAt = i; 20802 break; 20803 } 20804 } 20805 this.testLine(mainStartsAt); 20806 } 20807 }, {
20808 key: 'testLine', 20809 value: function testLine(nLine) { 20810 var cm = mainGE.editor; 20811 var visualDebugger = mainGE.visualDebugger; 20812 20813 // If is done testing... 20814 if (nLine >= cm.getDoc().size) { 20815 visualDebugger.testingLine = 0; 20816 visualDebugger.testing = false; 20817 20818 var results = visualDebugger.testingResults; 20819 var range = (0, _toolsDebugging.getResultRange)(results); 20820 var sum = (0, _toolsDebugging.getDeltaSum)(results); 20821 var hits = (0, _toolsDebugging.getHits)(results); 20822 20823 console.log('Test: ', range.max.ms + 'ms', results); 20824 cm.clearGutter('breakpoints'); 20825 for (var i in results) { 20826 var pct = results[i].delta / sum * 100; 20827 var size = results[i].delta / sum * 30; 20828 var markerHTML = '<div>' + results[i].ms.toFixed(2); 20829 if (results[i].delta > 0.) { 20830 markerHTML += '<span class="ge_assing_marker_pct '; 20831 if (pct > 100.0 / hits) { 20832 markerHTML += 'ge_assing_marker_slower'; 20833 } 20834 markerHTML += '" style="width: ' + size.toFixed(0) + 'px;" data="' + pct.toFixed(0) + '%"></span>'; 20835 } 20836 20837 cm.setGutterMarker(results[i].line, 'breakpoints', makeMarker(markerHTML + '</div>')); 20838 } 20839 return; 20840 } 20841 20842 if ((0, _toolsDebugging.isLineAfterMain)(cm, nLine)) { 20843 // If the line is inside the main function 20844 var shader = mainGE.shader.canvas; 20845 20846 // Check for an active variable (a variable that have been declare or modify in this line) 20847 var variableRE = new RegExp('\\s*[float|vec2|vec3|vec4]?\\s+([\\w|\\_]*)[\\.\\w]*?\\s+[\\+|\\-|\\\\|\\*]?\\=', 'i'); 20848 var match = variableRE.exec(cm.getLine(nLine)); 20849 if (match) { 20850 // if there is an active variable, get what type is 20851 var variable = match[1]; 20852 var type = (0, _toolsDebugging.getVariableType)(cm, variable); 20853 if (type === 'none') { 20854 // If it fails on finding the type keep going with the test on another line 20855 visualDebugger.testLine(nLine + 1); 20856 return; 20857 } 20858 20859 // Prepare 20860 visualDebugger.testing = true; 20861 visualDebugger.testingLine = nLine; 20862 visualDebugger.testingFrag = (0, _toolsDebugging.getShaderForTypeVarInLine)(cm, type, variable, nLine); 20863 visualDebugger.testingSamples = []; 20864 20865 (0, _coreEditorJs.unfocusAll)(cm); 20866 (0, _coreEditorJs.focusLine)(cm, nLine); 20867 mainGE.debugging = true; 20868 20869 shader.test(this.onTest, visualDebugger.testingFrag); 20870 } else { 20871 visualDebugger.testLine(nLine + 1); 20872 } 20873 } else { 20874 // If the line is not inside main function, test the next one... 20875 visualDebugger.testLine(nLine + 1); 20876 } 20877 } 20878 }, { 20879 key: 'onTest', 20880 value: function onTest(target) { 20881 var cm = mainGE.editor; 20882 var shader = mainGE.shader.canvas; 20883 var visualDebugger = mainGE.visualDebugger; 20884 20885 // If the test shader compiled... 20886 if (target.wasValid) { 20887 // get data, process and store. 20888 var elapsedMs = target.timeElapsedMs; 20889 20890 if (visualDebugger.testingSamples.length < N_SAMPLES - 1) { 20891 visualDebugger.testingSamples.push(elapsedMs); 20892 shader.test(visualDebugger.onTest, visualDebugger.testingFrag); 20893 } else { 20894 (0, _coreEditorJs.focusAll)(cm); 20895 mainGE.debugging = false; 20896 visualDebugger.testingSamples.push(elapsedMs); 20897 elapsedMs = (0, _toolsDebugging.getMedian)(visualDebugger.testingSamples); 20898 20899 var range = (0, _toolsDebugging.getResultRange)(visualDebugger.testingResults); 20900 var delta = elapsedMs - range.max.ms; 20901 if (visualDebugger.testingResults.length === 0) { 20902 delta = 0.0; 20903 } 20904 visualDebugger.testingResults.push({ line: visualDebugger.testingLine, ms: target.timeElapsedMs, delta: delta }); 20905 // console.log('Testing line:', visualDebugger.testingLine, elapsedMs, delta, range); 20906 20907 // Create gutter marker 20908 cm.setGutterMarker(visualDebugger.testingLine, 'breakpoints', makeMarker(elapsedMs.toFixed(2))); 20909 20910 // Test next line 20911 visualDebugger.testLine(visualDebugger.testingLine + 1); 20912 }; 20913 } else { 20914 console.log(target); 20915 // Test next line 20916 visualDebugger.testLine(visualDebugger.testingLine + 1); 20917 } 20918 } 20919 }, {
20920 key: 'debug', 20921 value: function debug(variable, nLine) { 20922 (0, _coreEditorJs.focusAll)(this.main.editor); 20923 this.main.debugging = false; 20924 20925 if ((0, _toolsDebugging.isLineAfterMain)(this.main.editor, nLine)) { 20926 var type = (0, _toolsDebugging.getVariableType)(this.main.editor, variable); 20927 if (type !== 'none') { 20928 event.preventDefault(); 20929 this.main.shader.canvas.load((0, _toolsDebugging.getShaderForTypeVarInLine)(this.main.editor, type, variable, nLine)); 20930 (0, _coreEditorJs.unfocusAll)(this.main.editor); 20931 (0, _coreEditorJs.focusLine)(this.main.editor, nLine); 20932 this.main.debugging = true; 20933 } 20934 } else { 20935 this.main.update(); 20936 } 20937 } 20938 }, { 20939 key: 'iluminate', 20940 value: function iluminate(variable) { 20941 if (this.main.debbuging && this.variable === this.variable) { 20942 return; 20943 } 20944 // this.clean(); 20945 20946 var cm = this.main.editor; 20947 20948 // Highlight all calls to a variable 20949 this.overlay = searchOverlay(variable, true); 20950 cm.addOverlay(this.overlay); 20951 if (cm.showMatchesOnScrollbar) { 20952 if (this.annotate) { 20953 this.annotate.clear();this.annotate = null; 20954 } 20955 this.annotate = cm.showMatchesOnScrollbar(variable, true); 20956 } 20957 } 20958 }, { 20959 key: 'clean', 20960 value: function clean(event) { 20961 if (event && event.target && event.target.className === 'ge_assing_marker') { 20962 return; 20963 } 20964 20965 var cm = this.main.editor; 20966 cm.clearGutter('breakpoints'); 20967 if (this.overlay) { 20968 cm.removeOverlay(this.overlay, true); 20969 } 20970 this.type = null; 20971 if (this.main.debbuging) { 20972 this.main.shader.canvas.load(this.main.options.frag_header + this.main.editor.getValue() + this.main.options.frag_footer); 20973 } 20974 this.main.debbuging = false; 20975 } 20976 }]); 20977 20978 return VisualDebugger; 20979})(); 20980 20981exports['default'] = VisualDebugger; 20982 20983function makeMarker(html, extraClass) { 20984 var marker = document.createElement('div'); 20985 marker.setAttribute('class', 'ge_assing_marker'); 20986 marker.innerHTML = html; 20987 return marker; 20988} 20989 20990function searchOverlay(query, caseInsensitive) { 20991 if (typeof query === 'string') { 20992 query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'), caseInsensitive ? 'gi' : 'g'); 20993 } else if (!query.global) { 20994 query = new RegExp(query.source, query.ignoreCase ? 'gi' : 'g'); 20995 } 20996 20997 return { 20998 token: function token(stream) { 20999 query.lastIndex = stream.pos; 21000 var match = query.exec(stream.string); 21001 if (match && match.index === stream.pos) { 21002 stream.pos += match[0].length || 1; 21003 return 'searching'; 21004 } else if (match) { 21005 stream.pos = match.index; 21006 } else { 21007 stream.skipToEnd(); 21008 } 21009 } 21010 }; 21011} 21012module.exports = exports['default']; 21013 21014},{"../core/Editor.js":115,"../tools/debugging":122,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11}],134:[function(_dereq_,module,exports){ 21015'use strict'; 21016 21017var _get = _dereq_('babel-runtime/helpers/get')['default']; 21018 21019var _inherits = _dereq_('babel-runtime/helpers/inherits')['default']; 21020 21021var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 21022 21023var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 21024 21025Object.defineProperty(exports, '__esModule', { 21026 value: true 21027}); 21028 21029var _MenuItem = _dereq_('../MenuItem'); 21030 21031var _MenuItem2 = _interopRequireDefault(_MenuItem); 21032 21033var _Modal2 = _dereq_('./Modal'); 21034 21035var _Modal3 = _interopRequireDefault(_Modal2); 21036 21037// import { saveOnServer, createOpenFrameArtwork } from '../../io/share'; 21038 21039var ExportModal = (function (_Modal) { 21040 _inherits(ExportModal, _Modal); 21041 21042 function ExportModal(CSS_PREFIX, properties) { 21043 _classCallCheck(this, ExportModal); 21044 21045 _get(Object.getPrototypeOf(ExportModal.prototype), 'constructor', this).call(this, CSS_PREFIX, properties); 21046 this.main = properties.main; 21047 21048 this.save = new _MenuItem2['default'](this.el, 'ge_sub_menu', 'Download file', function (event) { 21049 properties.main.download(); 21050 }); 21051
21052 // this.codeURL = new MenuItem(this.el, 'ge_sub_menu', 'Code URL...', (event) => { 21053 // saveOnServer(this.main, (event) => { 21054 // prompt('Use this url to share your code', 'http://thebookofshaders.com/edit.php?log=' + event.name); 21055 // this.removeModal(); 21056 // }); 21057 // }); 21058 21059 // this.shaderURL = new MenuItem(this.el, 'ge_sub_menu', 'Artwork URL...', (event) => { 21060 // saveOnServer(this.main, (event) => { 21061 // prompt('Use this url to share your artwork', 'http://player.thebookofshaders.com/?log=' + event.name); 21062 // this.removeModal(); 21063 // }); 21064 // }); 21065 21066 // let shareOF = new MenuItem(this.el, 'ge_sub_menu', 'Artwork to [o]', (event) => { 21067 // shareOF.el.innerHTML = 'Artwork to [o]: adding to collection'; 21068 // saveOnServer(this.main, (event) => { 21069 // createOpenFrameArtwork(this.main, event.name, event.url, (success) => { 21070 // if (success) { 21071 // shareOF.el.innerHTML = 'Artwork to [o]: added!'; 21072 // } 21073 // else { 21074 // shareOF.el.innerHTML = 'Artwork to [o]: failed :('; 21075 // } 21076 // setTimeout(() => { 21077 // shareOF.el.innerHTML = '[o]'; 21078 // this.removeModal(); 21079 // }, 4000); 21080 // }); 21081 // }); 21082 // }); 21083 } 21084 21085 return ExportModal; 21086})(_Modal3['default']); 21087 21088exports['default'] = ExportModal; 21089module.exports = exports['default']; 21090 21091},{"../MenuItem":132,"./Modal":135,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/get":12,"babel-runtime/helpers/inherits":13,"babel-runtime/helpers/interop-require-default":14}],135:[function(_dereq_,module,exports){ 21092'use strict'; 21093 21094var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 21095 21096var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 21097 21098Object.defineProperty(exports, '__esModule', { 21099 value: true 21100}); 21101exports.addEvent = addEvent; 21102exports.removeEvent = removeEvent; 21103 21104var _toolsMixin = _dereq_('../../tools/mixin'); 21105 21106var Modal = (function () { 21107 function Modal(CSS_PREFIX, properties) { 21108 _classCallCheck(this, Modal); 21109 21110 (0, _toolsMixin.subscribeMixin)(this); 21111 this.CSS_PREFIX = CSS_PREFIX; 21112 21113 properties = properties || {}; 21114 for (var prop in properties) { 21115 this[prop] = properties[prop]; 21116 } 21117 21118 this.el = document.createElement('div'); 21119 this.el.className = this.CSS_PREFIX + '_modal ge_modal'; 21120 this.el.style.backgroundColor = this.bgColor; 21121 this.el.innerHTML = this.innerHTML || ''; 21122 21123 if (this.elements) { 21124 for (var i = 0; i < this.elements.length; i++) { 21125 this.el.appendChild(this.elements[i]); 21126 } 21127 } 21128 21129 this.isVisible = false; 21130 } 21131 21132 /* Event handling */ 21133 21134 _createClass(Modal, [{ 21135 key: 'close', 21136 value: function close() { 21137 this.trigger('close'); 21138 } 21139 }, { 21140 key: 'showAt', 21141 value: function showAt(cm) { 21142 var cursor = cm.cursorCoords(true, 'page'); 21143 var x = cursor.left; 21144 var y = cursor.top; 21145 21146 y += 30; 21147 21148 this.presentModal(x, y); 21149 } 21150 }, { 21151 key: 'presentModal', 21152 value: function presentModal(x, y) { 21153 var _this = this; 21154 21155 // Listen for interaction outside of the modal 21156 window.setTimeout(function () { 21157 _this.onClickOutsideHandler = addEvent(document.body, 'click', _this.onClickOutside, _this); 21158 _this.onKeyPressHandler = addEvent(window, 'keydown', _this.onKeyPress, _this); 21159 }, 0); 21160 this.isVisible = true; 21161 21162 this.el.style.left = x + 'px'; 21163 this.el.style.top = y + 'px'; 21164 this.el.style.width = this.width + 'px'; 21165 this.el.style.height = this.height + 'px'; 21166 21167 if (this.position) { 21168 this.el.style.position = this.position; 21169 } 21170 21171 document.body.appendChild(this.el); 21172 21173 this.trigger('show'); 21174 } 21175 }, {
21176 key: 'getModalClass', 21177 value: function getModalClass() { 21178 return this.CSS_PREFIX + 'modal'; 21179 } 21180 }, { 21181 key: 'onKeyPress', 21182 value: function onKeyPress(event) { 21183 this.removeModal(); 21184 } 21185 }, { 21186 key: 'onClickOutside', 21187 value: function onClickOutside(event) { 21188 // HACKY!! 21189 // A click event fires on the body after mousedown - mousemove, simultaneously with 21190 // mouseup. So if someone started a mouse action inside the modal and then 21191 // mouseup'd outside of it, it fires a click event on the body, thus, causing the 21192 // modal to disappear when the user does not expect it to, since the mouse down event 21193 // did not start outside the modal. 21194 // There might be (or should be) a better way to track this, but right now, just cancel 21195 // the event if the target ends up being on the body directly rather than on one of the 21196 // other child elements. 21197 if (event.target === document.body) { 21198 return; 21199 } 21200 // end this specific hacky part 21201 var target = event.target; 21202 if (target) { 21203 while (target !== document.documentElement && !target.classList.contains(this.getModalClass())) { 21204 target = target.parentNode; 21205 } 21206 21207 if (!target.classList.contains(this.getModalClass())) { 21208 this.removeModal(); 21209 } 21210 } 21211 } 21212 21213 /** 21214 * Removes modal from DOM and destroys related event listeners 21215 */ 21216 }, { 21217 key: 'removeModal', 21218 value: function removeModal() { 21219 if (this.el && this.el.parentNode) { 21220 this.el.parentNode.removeChild(this.el); 21221 } 21222 removeEvent(document.body, 'click', this.onClickOutsideHandler); 21223 this.onClickOutsideHandler = null; 21224 removeEvent(window, 'keydown', this.onKeyPressHandler); 21225 this.onKeyPressHandler = null; 21226 21227 this.close(); 21228 this.isVisible = false; 21229 } 21230 }]); 21231 21232 return Modal; 21233})(); 21234 21235exports['default'] = Modal; 21236 21237function addEvent(element, event, callback, caller) { 21238 var handler = undefined; 21239 element.addEventListener(event, handler = function (e) { 21240 callback.call(caller, e); 21241 }, false); 21242 return handler; 21243} 21244 21245function removeEvent(element, event, callback) { 21246 element.removeEventListener(event, callback, false); 21247} 21248 21249},{"../../tools/mixin":126,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11}],136:[function(_dereq_,module,exports){ 21250/* 21251Original: https://github.com/tangrams/tangram-play/blob/gh-pages/src/js/addons/ui/widgets/ColorPickerModal.js 21252Author: Lou Huang (@saikofish) 21253*/ 21254 21255'use strict'; 21256 21257var _get = _dereq_('babel-runtime/helpers/get')['default']; 21258 21259var _inherits = _dereq_('babel-runtime/helpers/inherits')['default']; 21260 21261var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 21262 21263var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 21264 21265var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 21266 21267Object.defineProperty(exports, '__esModule', { 21268 value: true 21269}); 21270 21271var _Picker2 = _dereq_('./Picker'); 21272 21273var _Picker3 = _interopRequireDefault(_Picker2); 21274 21275var _typesColor = _dereq_('./types/Color'); 21276 21277var _typesColor2 = _interopRequireDefault(_typesColor); 21278 21279var _toolsCommon = _dereq_('../../tools/common'); 21280 21281var _toolsInteractiveDom = _dereq_('../../tools/interactiveDom'); 21282 21283// Some common use variables 21284var currentTarget = undefined; 21285var currentTargetHeight = 0; 21286var domCache = undefined; 21287 21288var ColorPicker = (function (_Picker) { 21289 _inherits(ColorPicker, _Picker); 21290 21291 function ColorPicker() { 21292 var color = arguments.length <= 0 || arguments[0] === undefined ? 'vec3(1.0,0.0,0.0)' : arguments[0]; 21293 var properties = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 21294 21295 _classCallCheck(this, ColorPicker); 21296 21297 _get(Object.getPrototypeOf(ColorPicker.prototype), 'constructor', this).call(this, 'ge_colorpicker_', properties); 21298 21299 this.width = 250; // in pixels 21300 this.height = 250; // in pixels 21301 21302 this.disc = { width: 200, height: 200 }; 21303 this.barlum = { width: 25, height: 200 }; 21304 21305 this.setValue(color); 21306 this.init(); 21307 } 21308 21309 // generic function for drawing a canvas disc 21310 21311 _createClass(ColorPicker, [{ 21312 key: 'init',
21313 value: function init() { 21314 var _this = this; 21315 21316 if (!domCache) { 21317 var modal = document.createElement('div'); 21318 var patch = document.createElement('div'); 21319 var map = document.createElement('div'); 21320 var disc = document.createElement('canvas'); 21321 var cover = document.createElement('div'); 21322 var cursor = document.createElement('div'); 21323 var barbg = document.createElement('div'); 21324 var barwhite = document.createElement('div'); 21325 var barlum = document.createElement('canvas'); 21326 var barcursors = document.createElement('div'); 21327 var leftcursor = document.createElement('div'); 21328 var rightcursor = document.createElement('div'); 21329 21330 modal.className = this.CSS_PREFIX + 'modal ge_picker_modal'; 21331 modal.style.backgroundColor = this.bgColor; 21332 patch.className = this.CSS_PREFIX + 'patch'; 21333 patch.style.backgroundColor = this.bgColor; 21334 map.className = this.CSS_PREFIX + 'hsv-map'; 21335 disc.className = this.CSS_PREFIX + 'disc'; 21336 disc.style.backgroundColor = this.bgColor; 21337 cover.className = this.CSS_PREFIX + 'disc-cover'; 21338 cursor.className = this.CSS_PREFIX + 'disc-cursor'; 21339 barbg.className = this.CSS_PREFIX + 'bar-bg'; 21340 barwhite.className = this.CSS_PREFIX + 'bar-white'; 21341 barlum.className = this.CSS_PREFIX + 'bar-luminance'; 21342 barcursors.className = this.CSS_PREFIX + 'bar-cursors'; 21343 leftcursor.className = this.CSS_PREFIX + 'bar-cursor-left'; 21344 rightcursor.className = this.CSS_PREFIX + 'bar-cursor-right'; 21345 21346 map.id = 'cp-map'; 21347 barcursors.id = 'cp-bar'; 21348 21349 modal.appendChild(patch); 21350 modal.appendChild(map); 21351 21352 map.appendChild(disc); 21353 map.appendChild(cover); 21354 map.appendChild(cursor); 21355 map.appendChild(barbg); 21356 map.appendChild(barwhite); 21357 map.appendChild(barlum); 21358 map.appendChild(barcursors); 21359 barcursors.appendChild(leftcursor); 21360 barcursors.appendChild(rightcursor); 21361 21362 domCache = modal; 21363 } 21364 21365 // Returns a clone of the cached document fragment 21366 this.el = domCache.cloneNode(true); 21367 (0, _toolsInteractiveDom.subscribeInteractiveDom)(this.el, { move: true, resize: false, snap: false }); 21368 21369 // TODO: Improve these references 21370 // The caching of references is likely to be important for speed 21371 this.dom = {}; 21372 this.dom.hsvMap = this.el.querySelector('.ge_colorpicker_hsv-map'); 21373 this.dom.hsvMapCover = this.dom.hsvMap.children[1]; // well... 21374 this.dom.hsvMapCursor = this.dom.hsvMap.children[2]; 21375 this.dom.hsvBarBGLayer = this.dom.hsvMap.children[3]; 21376 this.dom.hsvBarWhiteLayer = this.dom.hsvMap.children[4]; 21377 this.dom.hsvBarCursors = this.dom.hsvMap.children[6]; 21378 this.dom.hsvLeftCursor = this.dom.hsvBarCursors.children[0]; 21379 this.dom.hsvRightCursor = this.dom.hsvBarCursors.children[1]; 21380 21381 this.dom.colorDisc = this.el.querySelector('.ge_colorpicker_disc'); 21382 this.dom.luminanceBar = this.el.querySelector('.ge_colorpicker_bar-luminance'); 21383 21384 if (this.linkButton) { 21385 var lbutton = document.createElement('div'); 21386 lbutton.innerHTML = '+'; 21387 lbutton.className = this.CSS_PREFIX + 'link-button'; 21388 lbutton.style.color = this.fgColor; 21389 this.el.appendChild(lbutton); 21390 21391 lbutton.addEventListener('click', function () { 21392 _this.trigger('linkButton', _this.value); 21393 if (typeof _this.linkButton === 'function') { 21394 _this.linkButton(_this.value); 21395 } 21396 _this.removeModal(); 21397 }); 21398 } 21399 } 21400 }, {
21401 key: 'draw', 21402 value: function draw() { 21403 // Render color patch 21404 var patch = this.el.querySelector('.ge_colorpicker_patch'); 21405 patch.style.backgroundColor = this.value.getString('rgb'); 21406 21407 // Render HSV picker 21408 var color = this.value.colors; 21409 var colorDiscRadius = this.dom.colorDisc.offsetHeight / 2; 21410 var pi2 = Math.PI * 2; 21411 var x = Math.cos(pi2 - color.hsv.h * pi2); 21412 var y = Math.sin(pi2 - color.hsv.h * pi2); 21413 var r = color.hsv.s * (colorDiscRadius - 5); 21414 21415 this.dom.hsvMapCover.style.opacity = 1 - color.hsv.v / 255; 21416 // this is the faster version... 21417 this.dom.hsvBarWhiteLayer.style.opacity = 1 - color.hsv.s; 21418 this.dom.hsvBarBGLayer.style.backgroundColor = 'rgb(' + color.hueRGB.r + ',' + color.hueRGB.g + ',' + color.hueRGB.b + ')'; 21419 21420 this.dom.hsvMapCursor.style.cssText = 'left: ' + (x * r + colorDiscRadius) + 'px;' + 'top: ' + (y * r + colorDiscRadius) + 'px;' + 'border-color: ' + (color.luminance > 0.22 ? '#333;' : '#ddd'); 21421 21422 if (color.luminance > 0.22) { 21423 this.dom.hsvBarCursors.classList.add('ge_colorpicker_dark'); 21424 } else { 21425 this.dom.hsvBarCursors.classList.remove('ge_colorpicker_dark'); 21426 } 21427 21428 if (this.dom.hsvLeftCursor) { 21429 this.dom.hsvLeftCursor.style.top = this.dom.hsvRightCursor.style.top = (1 - color.hsv.v / 255) * colorDiscRadius * 2 + 'px'; 21430 } 21431 } 21432 }, { 21433 key: 'presentModal', 21434 value: function presentModal(x, y) { 21435 _get(Object.getPrototypeOf(ColorPicker.prototype), 'presentModal', this).call(this, x, y); 21436 21437 // // Listen for interaction on the HSV map 21438 this.onHsvDownHandler = (0, _Picker2.addEvent)(this.dom.hsvMap, 'mousedown', this.onHsvDown, this); 21439 21440 var colorDisc = this.dom.colorDisc; 21441 21442 if (colorDisc.getContext) { 21443 // HSV color wheel with white center 21444 var diskContext = colorDisc.getContext('2d'); 21445 var ratio = (0, _toolsCommon.getDevicePixelRatio)(diskContext); 21446 var width = this.disc.width / ratio; 21447 var height = this.disc.height / ratio; 21448 this.dom.colorDisc.width = width * ratio; 21449 this.dom.colorDisc.height = height * ratio; 21450 diskContext.scale(ratio, ratio); 21451 21452 drawDisk(diskContext, [width / 2, height / 2], [width / 2 - 1, height / 2 - 1], 360, function (ctx, angle) { 21453 var gradient = ctx.createRadialGradient(1, 1, 1, 1, 1, 0); 21454 gradient.addColorStop(0, 'hsl(' + (360 - angle + 0) + ', 100%, 50%)'); 21455 gradient.addColorStop(1, '#fff'); 21456 21457 ctx.fillStyle = gradient; 21458 ctx.fill(); 21459 }); 21460 21461 // gray border 21462 drawCircle(diskContext, [width / 2, height / 2], [width / 2, height / 2], this.bgColor, // '#303030', 21463 2 / ratio); 21464 21465 // draw the luminanceBar bar 21466 var ctx = this.dom.luminanceBar.getContext('2d'); 21467 this.dom.luminanceBar.width = this.barlum.width; 21468 this.dom.luminanceBar.height = this.barlum.height * ratio; 21469 ctx.scale(ratio, ratio); 21470 var gradient = ctx.createLinearGradient(0, 0, 0, this.barlum.height / ratio); 21471 21472 gradient.addColorStop(0, 'transparent'); 21473 gradient.addColorStop(1, 'black'); 21474 21475 ctx.fillStyle = gradient; 21476 ctx.fillRect(0, 0, 30, 200); 21477 } 21478 this.draw(); 21479 } 21480 21481 /** 21482 * Updates only the color value of the color picker 21483 * and the view. Designed to be called by external modules 21484 * so that it can update its internal value from an outside source. 21485 * Does no DOM creation & other initialization work. 21486 */ 21487 }, { 21488 key: 'setValue', 21489 value: function setValue(color) { 21490 this.value = new _typesColor2['default'](color); 21491 } 21492 21493 /* ---------------------------------- */ 21494 /* ---- HSV-circle color picker ----- */ 21495 /* ---------------------------------- */ 21496 21497 // Actions when user mouses down on HSV color map 21498 }, {
21499 key: 'onHsvDown', 21500 value: function onHsvDown(event) { 21501 var target = event.target || event.srcElement; 21502 event.preventDefault(); 21503 21504 currentTarget = target.id ? target : target.parentNode; 21505 currentTargetHeight = currentTarget.offsetHeight; // as diameter of circle 21506 21507 // Starts listening for mousemove and mouseup events 21508 this.onHsvMoveHandler = (0, _Picker2.addEvent)(this.el, 'mousemove', this.onHsvMove, this); 21509 this.onHsvUpHandler = (0, _Picker2.addEvent)(window, 'mouseup', this.onHsvUp, this); 21510 21511 this.onHsvMove(event); 21512 21513 // Hides mouse cursor and begins rendering loop 21514 this.dom.hsvMap.classList.add('ge_colorpicker_no-cursor'); 21515 this.renderer.start(); 21516 } 21517 21518 // Actions when user moves around on HSV color map 21519 }, { 21520 key: 'onHsvMove', 21521 value: function onHsvMove(event) { 21522 event.preventDefault(); 21523 event.stopPropagation(); 21524 21525 var r = undefined, 21526 x = undefined, 21527 y = undefined, 21528 h = undefined, 21529 s = undefined; 21530 if (event.target === this.dom.hsvMapCover && currentTarget === this.dom.hsvMap) { 21531 // the circle 21532 r = currentTargetHeight / 2, x = event.offsetX - r, y = event.offsetY - r, h = (360 - (Math.atan2(y, x) * 180 / Math.PI + (y < 0 ? 360 : 0))) / 360, s = Math.sqrt(x * x + y * y) / r; 21533 this.value.set({ h: h, s: s }, 'hsv'); 21534 } else if (event.target === this.dom.hsvBarCursors && currentTarget === this.dom.hsvBarCursors) { 21535 // the luminanceBar 21536 var v = (currentTargetHeight - event.offsetY) / currentTargetHeight; 21537 v = Math.max(0, Math.min(1, v)) * 255; 21538 this.value.set({ v: v }, 'hsv'); 21539 } 21540 21541 this.trigger('changed', this.value); 21542 } 21543 21544 // Actions when user mouses up on HSV color map 21545 }, { 21546 key: 'onHsvUp', 21547 value: function onHsvUp(event) { 21548 // Stops rendering and returns mouse cursor 21549 this.renderer.stop(); 21550 this.dom.hsvMap.classList.remove('ge_colorpicker_no-cursor'); 21551 this.destroyEvents(); 21552 } 21553 21554 // Destroy event listeners that exist during mousedown colorpicker interaction 21555 }, { 21556 key: 'destroyEvents', 21557 value: function destroyEvents() { 21558 (0, _Picker2.removeEvent)(this.el, 'mousemove', this.onHsvMoveHandler); 21559 this.onHsvMoveHandler = null; 21560 (0, _Picker2.removeEvent)(window, 'mouseup', this.onHsvUpHandler); 21561 this.onHsvUpHandler = null; 21562 } 21563 }, { 21564 key: 'close', 21565 value: function close() { 21566 this.destroyEvents(); 21567 (0, _Picker2.removeEvent)(this.dom.hsvMap, 'mousedown', this.onHsvDownHandler); 21568 this.onHsvDownHandler = null; 21569 } 21570 }]); 21571 21572 return ColorPicker; 21573})(_Picker3['default']); 21574 21575exports['default'] = ColorPicker; 21576function drawDisk(ctx, coords, radius, steps, colorCallback) { 21577 var x = coords[0] || coords; // coordinate on x-axis 21578 var y = coords[1] || coords; // coordinate on y-axis 21579 var a = radius[0] || radius; // radius on x-axis 21580 var b = radius[1] || radius; // radius on y-axis 21581 var angle = 360; 21582 var coef = Math.PI / 180; 21583 21584 ctx.save(); 21585 ctx.translate(x - a, y - b); 21586 ctx.scale(a, b); 21587 21588 steps = angle / steps || 360; 21589 21590 for (; angle > 0; angle -= steps) { 21591 ctx.beginPath(); 21592 if (steps !== 360) { 21593 ctx.moveTo(1, 1); // stroke 21594 } 21595 ctx.arc(1, 1, 1, (angle - steps / 2 - 1) * coef, (angle + steps / 2 + 1) * coef); 21596 21597 if (colorCallback) { 21598 colorCallback(ctx, angle); 21599 } else { 21600 ctx.fillStyle = 'black'; 21601 ctx.fill(); 21602 } 21603 } 21604 ctx.restore(); 21605} 21606 21607function drawCircle(ctx, coords, radius, color, width) { 21608 // uses drawDisk 21609 width = width || 1; 21610 radius = [(radius[0] || radius) - width / 2, (radius[1] || radius) - width / 2]; 21611 drawDisk(ctx, coords, radius, 1, function (ctx, angle) {
21612 ctx.restore(); 21613 ctx.lineWidth = width; 21614 ctx.strokeStyle = color || '#000'; 21615 ctx.stroke(); 21616 }); 21617} 21618module.exports = exports['default']; 21619 21620},{"../../tools/common":121,"../../tools/interactiveDom":124,"./Picker":138,"./types/Color":141,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11,"babel-runtime/helpers/get":12,"babel-runtime/helpers/inherits":13,"babel-runtime/helpers/interop-require-default":14}],137:[function(_dereq_,module,exports){ 21621'use strict'; 21622 21623var _get = _dereq_('babel-runtime/helpers/get')['default']; 21624 21625var _inherits = _dereq_('babel-runtime/helpers/inherits')['default']; 21626 21627var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 21628 21629var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 21630 21631var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 21632 21633Object.defineProperty(exports, '__esModule', { 21634 value: true 21635}); 21636 21637var _Picker2 = _dereq_('./Picker'); 21638 21639var _Picker3 = _interopRequireDefault(_Picker2); 21640 21641var _typesFloat = _dereq_('./types/Float'); 21642 21643var _typesFloat2 = _interopRequireDefault(_typesFloat); 21644 21645var FloatPicker = (function (_Picker) { 21646 _inherits(FloatPicker, _Picker); 21647 21648 function FloatPicker(number, properties) { 21649 _classCallCheck(this, FloatPicker); 21650 21651 _get(Object.getPrototypeOf(FloatPicker.prototype), 'constructor', this).call(this, 'ge_floatpicker_', properties); 21652 21653 this.width = this.width || 250; 21654 this.height = this.height || 40; 21655 21656 this.prevOffset = 0; 21657 this.scale = 2; 21658 21659 this.setValue(number || 1); 21660 this.create(); 21661 } 21662 21663 _createClass(FloatPicker, [{ 21664 key: 'draw', 21665 value: function draw() { 21666 this.ctx.clearRect(0, 0, this.width, this.height); 21667 21668 // horizontal line 21669 this.ctx.strokeStyle = this.dimColor; 21670 this.ctx.lineWidth = 1; 21671 this.ctx.beginPath(); 21672 this.ctx.moveTo(0, 0.5 + this.height * 0.5); 21673 this.ctx.lineTo(0 + this.width, 0.5 + this.height * 0.5); 21674 this.ctx.closePath(); 21675 this.ctx.stroke(); 21676 21677 // vertical line 21678 this.ctx.strokeStyle = this.fnColor; 21679 this.ctx.lineWidth = 1; 21680 this.ctx.beginPath(); 21681 this.ctx.moveTo(this.width * 0.5, 0); 21682 this.ctx.lineTo(this.width * 0.5, this.height); 21683 this.ctx.closePath(); 21684 this.ctx.stroke(); 21685 21686 // Triangle line 21687 this.ctx.fillStyle = this.overPoint ? this.selColor : this.fnColor; 21688 this.ctx.beginPath(); 21689 this.ctx.moveTo(this.width * 0.5, 5); 21690 this.ctx.lineTo(this.width * 0.48, 0); 21691 this.ctx.lineTo(this.width * 0.52, 0); 21692 this.ctx.closePath(); 21693 this.ctx.fill(); 21694 21695 var times = 3; 21696 var unit = 40; 21697 var step = this.width / unit; 21698 var sections = unit * times; 21699 21700 var offsetX = this.offsetX; 21701 21702 if (Math.abs(this.offsetX - this.width * 0.5) > this.width * 0.5) { 21703 offsetX = (this.offsetX - this.width * 0.5) % (this.width * 0.5) + this.width; 21704 } 21705 21706 this.ctx.strokeStyle = this.dimColor; 21707 this.ctx.beginPath(); 21708 for (var i = 0; i < sections; i++) { 21709 var l = i % (unit / 2) === 0 ? this.height * 0.35 : i % (unit / 4) === 0 ? this.height * 0.2 : this.height * 0.1; 21710 this.ctx.moveTo(i * step - offsetX, this.height * 0.5 - l); 21711 this.ctx.lineTo(i * step - offsetX, this.height * 0.5 + l); 21712 } 21713 this.ctx.stroke(); 21714 21715 var val = Math.round((this.value - this.min) / this.range * this.width); 21716 21717 // point 21718 this.ctx.strokeStyle = this.overPoint ? this.selColor : this.fnColor; 21719 this.ctx.lineWidth = 1; 21720 this.ctx.beginPath(); 21721 this.ctx.moveTo(this.offsetX + val, this.height * 0.5); 21722 this.ctx.lineTo(this.offsetX + val, this.height); 21723 this.ctx.closePath(); 21724 this.ctx.stroke(); 21725 21726 this.overPoint = false;
21727 } 21728 }, { 21729 key: 'onMouseDown', 21730 value: function onMouseDown(event) { 21731 this.prevOffset = event.offsetX; 21732 _get(Object.getPrototypeOf(FloatPicker.prototype), 'onMouseDown', this).call(this, event); 21733 } 21734 21735 // Actions when user moves around on HSV color map 21736 }, { 21737 key: 'onMouseMove', 21738 value: function onMouseMove(event) { 21739 var x = event.offsetX; 21740 21741 var vel = x - this.prevOffset; 21742 var offset = this.offsetX - vel; 21743 21744 var center = this.width / this.scale; 21745 this.setValue(offset / center); 21746 this.prevOffset = x; 21747 21748 // fire 'changed' 21749 var number = new _typesFloat2['default'](this.getValue()); 21750 this.trigger('changed', number); 21751 this.overPoint = true; 21752 } 21753 }, { 21754 key: 'setValue', 21755 value: function setValue(value) { 21756 if (typeof value === 'string') { 21757 this.value = parseFloat(value); 21758 } else if (typeof value === 'number') { 21759 this.value = value; 21760 } 21761 var center = this.width / this.scale; 21762 this.offsetX = this.value * center; 21763 } 21764 }]); 21765 21766 return FloatPicker; 21767})(_Picker3['default']); 21768 21769exports['default'] = FloatPicker; 21770module.exports = exports['default']; 21771 21772},{"./Picker":138,"./types/Float":143,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11,"babel-runtime/helpers/get":12,"babel-runtime/helpers/inherits":13,"babel-runtime/helpers/interop-require-default":14}],138:[function(_dereq_,module,exports){ 21773/* 21774Original: https://github.com/tangrams/tangram-play/blob/gh-pages/src/js/addons/ui/widgets/ColorPickerModal.js 21775Author: Lou Huang (@saikofish) 21776*/ 21777 21778'use strict'; 21779 21780var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 21781 21782var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 21783 21784Object.defineProperty(exports, '__esModule', { 21785 value: true 21786}); 21787exports.addEvent = addEvent; 21788exports.removeEvent = removeEvent; 21789 21790var _toolsCommon = _dereq_('../../tools/common'); 21791 21792var _toolsMixin = _dereq_('../../tools/mixin'); 21793 21794var Picker = (function () { 21795 function Picker(CSS_PREFIX, properties) { 21796 var _this = this; 21797 21798 _classCallCheck(this, Picker); 21799 21800 (0, _toolsMixin.subscribeMixin)(this); 21801 this.CSS_PREFIX = CSS_PREFIX; 21802 21803 this.bgColor = 'rgb(46, 48, 51)'; 21804 this.dimColor = 'rgb(100, 100, 100)'; 21805 this.fnColor = 'rgb(230, 230, 230)'; 21806 this.selColor = 'rgb(133, 204, 196)'; 21807 21808 properties = properties || {}; 21809 for (var prop in properties) { 21810 this[prop] = properties[prop]; 21811 } 21812 21813 /** 21814 * This initializes the renderer. It uses requestAnimationFrame() to 21815 * smoothly render changes in the color picker as user interacts with it. 21816 */ 21817 this.renderer = { 21818 // Stores a reference to the animation rendering loop. 21819 frame: null, 21820 21821 drawFrame: function drawFrame() { 21822 if (!_this.el) { 21823 return; 21824 } 21825 _this.draw(); 21826 }, 21827 21828 // Starts animation rendering loop 21829 start: function start() { 21830 _this.renderer.drawFrame(); 21831 _this.renderer.frame = window.requestAnimationFrame(_this.renderer.start); 21832 }, 21833 21834 // Stops animation rendering loop 21835 stop: function stop() { 21836 window.cancelAnimationFrame(_this.renderer.frame); 21837 } 21838 }; 21839 this.isVisible = false; 21840 } 21841 21842 /* Event handling */ 21843 21844 _createClass(Picker, [{ 21845 key: 'create', 21846 value: function create() { 21847 this.el = document.createElement('div'); 21848 this.el.className = this.CSS_PREFIX + 'modal ge_picker_modal'; 21849 this.el.style.backgroundColor = this.bgColor; 21850 21851 this.canvas = document.createElement('canvas'); 21852 this.canvas.className = this.CSS_PREFIX + 'canvas ge_picker_canvas'; 21853 this.canvas.style.backgroundColor = this.bgColor; 21854 21855 this.el.appendChild(this.canvas); 21856 this.ctx = this.canvas.getContext('2d'); 21857 21858 var ratio = (0, _toolsCommon.getDevicePixelRatio)(this.ctx); 21859 this.canvas.width = this.width * ratio; 21860 this.canvas.height = this.height * ratio; 21861 this.ctx.scale(ratio, ratio); 21862 } 21863 }, {
21864 key: 'draw', 21865 value: function draw() { 21866 // render rutine 21867 } 21868 }, { 21869 key: 'close', 21870 value: function close() { 21871 // Close rutine 21872 this.destroyEvents(); 21873 removeEvent(this.el, 'mousedown', this.onMouseDownHandler); 21874 this.onMouseDownHandler = null; 21875 } 21876 }, { 21877 key: 'destroyEvents', 21878 value: function destroyEvents() { 21879 removeEvent(this.el, 'mousemove', this.onMouseMoveHandler); 21880 this.onMouseMoveHandler = null; 21881 removeEvent(window, 'mouseup', this.onMouseUpHandler); 21882 this.onMouseUpHandler = null; 21883 } 21884 }, { 21885 key: 'setValue', 21886 value: function setValue(value) { 21887 this.value = value; 21888 } 21889 }, { 21890 key: 'getValue', 21891 value: function getValue() { 21892 return this.value; 21893 } 21894 }, { 21895 key: 'showAt', 21896 value: function showAt(cm) { 21897 var cursor = cm.cursorCoords(true, 'page'); 21898 var x = cursor.left; 21899 var y = cursor.top; 21900 21901 x -= this.width * 0.5; 21902 y += 30; 21903 21904 // // Check if desired x, y will be outside the viewport. 21905 // // Do not allow the modal to disappear off the edge of the window. 21906 // x = (x + this.width < window.innerWidth) ? x : (window.innerWidth - 20 - this.width); 21907 // y = (y + this.height < window.innerHeight) ? y : (window.innerHeight - 20 - this.height); 21908 21909 this.presentModal(x, y); 21910 } 21911 }, { 21912 key: 'presentModal', 21913 value: function presentModal(x, y) { 21914 var _this2 = this; 21915 21916 // Listen for interaction outside of the modal 21917 window.setTimeout(function () { 21918 _this2.onClickOutsideHandler = addEvent(document.body, 'click', _this2.onClickOutside, _this2); 21919 _this2.onKeyPressHandler = addEvent(window, 'keydown', _this2.onKeyPress, _this2); 21920 }, 0); 21921 this.isVisible = true; 21922 21923 this.el.style.left = x + 'px'; 21924 this.el.style.top = y + 'px'; 21925 this.el.style.width = this.width + 'px'; 21926 this.el.style.height = this.height + 'px'; 21927 document.body.appendChild(this.el); 21928 21929 this.onMouseDownHandler = addEvent(this.el, 'mousedown', this.onMouseDown, this); 21930 21931 this.renderer.drawFrame(); 21932 } 21933 21934 /** 21935 * Removes modal from DOM and destroys related event listeners 21936 */ 21937 }, { 21938 key: 'removeModal', 21939 value: function removeModal() { 21940 if (this.el && this.el.parentNode) { 21941 this.el.parentNode.removeChild(this.el); 21942 } 21943 removeEvent(document.body, 'click', this.onClickOutsideHandler); 21944 this.onClickOutsideHandler = null; 21945 removeEvent(window, 'keydown', this.onKeyPressHandler); 21946 this.onKeyPressHandler = null; 21947 21948 this.close(); 21949 this.isVisible = false; 21950 } 21951 }, { 21952 key: 'onKeyPress', 21953 value: function onKeyPress(event) { 21954 this.removeModal(); 21955 } 21956 }, { 21957 key: 'onClickOutside', 21958 value: function onClickOutside(event) { 21959 // HACKY!! 21960 // A click event fires on the body after mousedown - mousemove, simultaneously with 21961 // mouseup. So if someone started a mouse action inside the modal and then 21962 // mouseup'd outside of it, it fires a click event on the body, thus, causing the 21963 // modal to disappear when the user does not expect it to, since the mouse down event 21964 // did not start outside the modal. 21965 // There might be (or should be) a better way to track this, but right now, just cancel 21966 // the event if the target ends up being on the body directly rather than on one of the 21967 // other child elements. 21968 if (event.target === document.body) { 21969 return; 21970 } 21971 // end this specific hacky part 21972 21973 var target = event.target; 21974 21975 while (target !== document.documentElement && !target.classList.contains(this.CSS_PREFIX + 'modal')) { 21976 target = target.parentNode; 21977 } 21978 21979 if (!target.classList.contains(this.CSS_PREFIX + 'modal')) { 21980 this.removeModal(); 21981 } 21982 } 21983 }, {
21984 key: 'onMouseDown', 21985 value: function onMouseDown(event) { 21986 event.preventDefault(); 21987 21988 // Starts listening for mousemove and mouseup events 21989 this.onMouseMoveHandler = addEvent(this.el, 'mousemove', this.onMouseMove, this); 21990 this.onMouseUpHandler = addEvent(window, 'mouseup', this.onMouseUp, this); 21991 21992 this.onMouseMove(event); 21993 21994 this.renderer.start(); 21995 } 21996 }, { 21997 key: 'onMouseMove', 21998 value: function onMouseMove(event) {} 21999 }, { 22000 key: 'onMouseUp', 22001 value: function onMouseUp(event) { 22002 this.renderer.stop(); 22003 this.destroyEvents(); 22004 } 22005 }]); 22006 22007 return Picker; 22008})(); 22009 22010exports['default'] = Picker; 22011 22012function addEvent(element, event, callback, caller) { 22013 var handler = undefined; 22014 element.addEventListener(event, handler = function (e) { 22015 callback.call(caller, e); 22016 }, false); 22017 return handler; 22018} 22019 22020function removeEvent(element, event, callback) { 22021 element.removeEventListener(event, callback, false); 22022} 22023 22024},{"../../tools/common":121,"../../tools/mixin":126,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11}],139:[function(_dereq_,module,exports){ 22025'use strict'; 22026 22027var _get = _dereq_('babel-runtime/helpers/get')['default']; 22028 22029var _inherits = _dereq_('babel-runtime/helpers/inherits')['default']; 22030 22031var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 22032 22033var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 22034 22035var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 22036 22037Object.defineProperty(exports, '__esModule', { 22038 value: true 22039}); 22040 22041var _Picker2 = _dereq_('./Picker'); 22042 22043var _Picker3 = _interopRequireDefault(_Picker2); 22044 22045var _typesVector = _dereq_('./types/Vector'); 22046 22047var _typesVector2 = _interopRequireDefault(_typesVector); 22048 22049var Vec2Picker = (function (_Picker) { 22050 _inherits(Vec2Picker, _Picker); 22051 22052 function Vec2Picker(pos, properties) { 22053 _classCallCheck(this, Vec2Picker); 22054 22055 _get(Object.getPrototypeOf(Vec2Picker.prototype), 'constructor', this).call(this, 'ge_vec2picker_', properties); 22056 22057 this.width = this.width || 200; 22058 this.height = this.height || 200; 22059 22060 this.min = this.min || -1; 22061 this.max = this.max || 1; 22062 this.size = this.size || 6; 22063 this.range = this.max - this.min; 22064 this.overPoint = false; 22065 22066 var center = (this.range / 2 - this.max) * -1; 22067 this.setValue(pos || [center, center]); 22068 this.create(); 22069 } 22070 22071 _createClass(Vec2Picker, [{ 22072 key: 'draw', 22073 value: function draw() { 22074 this.ctx.clearRect(0, 0, this.width, this.height); 22075 22076 // frame 22077 this.ctx.strokeStyle = this.dimColor; 22078 this.ctx.lineWidth = 2; 22079 this.ctx.strokeRect(0, 0, this.width, this.height); 22080 22081 this.ctx.beginPath(); 22082 this.ctx.lineWidth = 0.25; 22083 var sections = 20; 22084 var step = this.width / sections; 22085 for (var i = 0; i < sections; i++) { 22086 this.ctx.moveTo(i * step, 0); 22087 this.ctx.lineTo(i * step, this.height); 22088 this.ctx.moveTo(0, i * step); 22089 this.ctx.lineTo(this.width, i * step); 22090 } 22091 this.ctx.stroke(); 22092 22093 // horizontal line 22094 this.ctx.strokeStyle = this.dimColor; 22095 this.ctx.lineWidth = 1.0; 22096 this.ctx.beginPath(); 22097 this.ctx.moveTo(0, 0.5 + this.height * 0.5); 22098 this.ctx.lineTo(this.width, 0.5 + this.height * 0.5); 22099 this.ctx.closePath(); 22100 this.ctx.stroke(); 22101 22102 // vertical line 22103 this.ctx.beginPath(); 22104 this.ctx.moveTo(0.5 + this.width * 0.5, 0); 22105 this.ctx.lineTo(0.5 + this.width * 0.5, this.height); 22106 this.ctx.closePath(); 22107 this.ctx.stroke(); 22108 22109 // // Triangle line 22110 // this.ctx.fillStyle = this.dimColor; 22111 // this.ctx.beginPath(); 22112 // this.ctx.moveTo(this.width * 0.5, 5); 22113 // this.ctx.lineTo(this.width * 0.48, 0); 22114 // this.ctx.lineTo(this.width * 0.52, 0); 22115 // this.ctx.closePath(); 22116 // this.ctx.fill(); 22117 22118 var x = Math.round((this.value.x - this.min) / this.range * this.width); 22119 var y = Math.round((1 - (this.value.y - this.min) / this.range) * this.height); 22120 22121 var half = this.size / 2; 22122 22123 if (x < half) { 22124 x = half; 22125 } 22126 if (x > this.width - half) { 22127 x = this.width - half; 22128 } 22129 if (y < half) { 22130 y = half; 22131 } 22132 if (y > this.height - half) { 22133 y = this.height - half; 22134 } 22135 22136 // point 22137 this.ctx.fillStyle = this.overPoint ? this.selColor : this.fnColor; 22138 this.ctx.beginPath(); 22139 var radius = this.overPoint ? 4 : 2; 22140 this.ctx.arc(x, y, radius, 0, 2 * Math.PI, false); 22141 this.ctx.fill(); 22142
22143 this.ctx.restore(); 22144 this.overPoint = false; 22145 } 22146 22147 // Actions when user moves around on HSV color map 22148 }, { 22149 key: 'onMouseMove', 22150 value: function onMouseMove(event) { 22151 var x = event.offsetX; 22152 var y = event.offsetY; 22153 22154 this.value.x = this.range / this.width * x - (this.range - this.max); 22155 this.value.y = (this.range / this.height * y - (this.range - this.max)) * -1; 22156 22157 // fire 'changed' 22158 this.trigger('changed', this.value); 22159 this.overPoint = true; 22160 } 22161 }, { 22162 key: 'setValue', 22163 value: function setValue(pos) { 22164 this.value = new _typesVector2['default'](pos); 22165 } 22166 }]); 22167 22168 return Vec2Picker; 22169})(_Picker3['default']); 22170 22171exports['default'] = Vec2Picker; 22172module.exports = exports['default']; 22173 22174},{"./Picker":138,"./types/Vector":145,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11,"babel-runtime/helpers/get":12,"babel-runtime/helpers/inherits":13,"babel-runtime/helpers/interop-require-default":14}],140:[function(_dereq_,module,exports){ 22175'use strict'; 22176 22177var _get = _dereq_('babel-runtime/helpers/get')['default']; 22178 22179var _inherits = _dereq_('babel-runtime/helpers/inherits')['default']; 22180 22181var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 22182 22183var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 22184 22185var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 22186 22187Object.defineProperty(exports, '__esModule', { 22188 value: true 22189}); 22190 22191var _Picker2 = _dereq_('./Picker'); 22192 22193var _Picker3 = _interopRequireDefault(_Picker2); 22194 22195var _typesVector = _dereq_('./types/Vector'); 22196 22197var _typesVector2 = _interopRequireDefault(_typesVector); 22198 22199var _typesMatrix = _dereq_('./types/Matrix'); 22200 22201var _typesMatrix2 = _interopRequireDefault(_typesMatrix); 22202 22203var Vec3Picker = (function (_Picker) { 22204 _inherits(Vec3Picker, _Picker); 22205 22206 function Vec3Picker(dir, properties) { 22207 _classCallCheck(this, Vec3Picker); 22208 22209 _get(Object.getPrototypeOf(Vec3Picker.prototype), 'constructor', this).call(this, 'ge_vec3picker_', properties); 22210 22211 this.width = this.width || 200; 22212 this.height = this.width || 200; 22213 this.scale = 50; 22214 22215 this.setValue(dir || [0, 0, 1]); 22216 this.create(); 22217 22218 this.camera = new _typesMatrix2['default'](); 22219 this.shapes = []; 22220 this.center = [0, 0, 0]; 22221 22222 this.shapes.push({ 22223 edgeColour: this.dimColor, 22224 nodes: [[this.width / 2 - 50, this.height / 2, 100], [this.width / 2 + 50, this.height / 2, 100], [this.width / 2, this.height / 2 - 50, 100], [this.width / 2, this.height / 2 + 50, 100], [this.width / 2, this.height / 2, 50], [this.width / 2, this.height / 2, 150]], 22225 edges: [[0, 1], [2, 3], [4, 5]] 22226 }); 22227 22228 this.shapes.push({ 22229 textColour: this.fnColor, 22230 nodes: [[this.width / 2 + 68, this.height / 2, 100], [this.width / 2 - 68, this.height / 2, 100], [this.width / 2, this.height / 2 + 68, 100], [this.width / 2, this.height / 2 - 68, 100], [this.width / 2, this.height / 2, 168], [this.width / 2, this.height / 2, 32]], 22231 text: ['x', '-x', 'y', '-y', 'z', '-z'] 22232 }); 22233 22234 this.setCenter(this.width / 2, this.height / 2, 100); 22235 22236 // Mouse events 22237 this.dragOffset = [0, 0]; 22238 this.overPoint = false; 22239 } 22240 22241 _createClass(Vec3Picker, [{ 22242 key: 'setCenter', 22243 value: function setCenter(x, y, z) { 22244 for (var s in this.shapes) { 22245 var shape = this.shapes[s]; 22246 22247 for (var n in shape.nodes) { 22248 shape.nodes[n][0] -= x; 22249 shape.nodes[n][1] -= y; 22250 shape.nodes[n][2] -= z; 22251 } 22252 } 22253 this.center = [x, y, z]; 22254 } 22255 }, { 22256 key: 'viewFromCamera', 22257 value: function viewFromCamera(node) { 22258 var A = this.camera.getMult(node); 22259 A.add(this.center); 22260 return [A.x, this.height - A.y]; 22261 } 22262 }, {
22263 key: 'draw', 22264 value: function draw() { 22265 this.ctx.clearRect(0, 0, this.width, this.height); 22266 22267 for (var s in this.shapes) { 22268 var shape = this.shapes[s]; 22269 if (shape.edgeColour) { 22270 this.drawShapeEdges(shape); 22271 } 22272 if (shape.nodeColour) { 22273 this.drawShapeNodes(shape); 22274 } 22275 if (shape.text) { 22276 this.drawShapeText(shape); 22277 } 22278 } 22279 22280 this.drawShapeEdges({ 22281 edgeColour: this.fnColor, 22282 nodes: [[0, 0, 0], this.point], 22283 edges: [[0, 1]] 22284 }); 22285 22286 this.drawShapeNodes({ 22287 nodeColour: this.overPoint ? this.selColor : this.fnColor, 22288 nodeRadius: this.overPoint ? 4 : 2, 22289 nodes: [this.point] 22290 }); 22291 } 22292 }, { 22293 key: 'drawShapeEdges', 22294 value: function drawShapeEdges(shape) { 22295 var nodes = shape.nodes; 22296 22297 this.ctx.strokeStyle = shape.edgeColour; 22298 for (var e in shape.edges) { 22299 var coord = this.viewFromCamera(nodes[shape.edges[e][0]]); 22300 this.ctx.lineWidth = 1; 22301 this.ctx.beginPath(); 22302 this.ctx.moveTo(coord[0], coord[1]); 22303 coord = this.viewFromCamera(nodes[shape.edges[e][1]]); 22304 this.ctx.lineTo(coord[0], coord[1]); 22305 this.ctx.stroke(); 22306 } 22307 } 22308 }, { 22309 key: 'drawShapeNodes', 22310 value: function drawShapeNodes(shape) { 22311 var radius = shape.nodeRadius || 4; 22312 this.ctx.fillStyle = shape.nodeColour; 22313 for (var n in shape.nodes) { 22314 var coord = this.viewFromCamera(shape.nodes[n]); 22315 this.ctx.beginPath(); 22316 this.ctx.arc(coord[0], coord[1], radius, 0, 2 * Math.PI, false); 22317 this.ctx.fill(); 22318 } 22319 } 22320 }, { 22321 key: 'drawShapeText', 22322 value: function drawShapeText(shape) { 22323 this.ctx.fillStyle = shape.textColour; 22324 for (var n in shape.nodes) { 22325 var coord = this.viewFromCamera(shape.nodes[n]); 22326 this.ctx.textBaseline = 'middle'; 22327 this.ctx.fillText(shape.text[n], coord[0], coord[1]); 22328 } 22329 } 22330 }, { 22331 key: 'onMouseDown', 22332 value: function onMouseDown(event) { 22333 var mouse = [event.offsetX, event.offsetY]; 22334 this.dragOffset = mouse; 22335 22336 var pos = new _typesVector2['default'](this.viewFromCamera(this.point)); 22337 var diff = pos.getSub(mouse); 22338 this.overPoint = diff.getLength() < 10; 22339 22340 _get(Object.getPrototypeOf(Vec3Picker.prototype), 'onMouseDown', this).call(this, event); 22341 this.onMouseUpHandler = (0, _Picker2.addEvent)(this.el, 'dblclick', this.onDbClick, this); 22342 } 22343 22344 // Actions when user moves around on HSV color map 22345 }, { 22346 key: 'onMouseMove', 22347 value: function onMouseMove(event) { 22348 var x = event.offsetX; 22349 var y = event.offsetY; 22350 22351 var dx = 0.01 * (x - this.dragOffset[0]); 22352 var dy = 0.01 * (y - this.dragOffset[1]); 22353 22354 if (this.overPoint) { 22355 var invM = this.camera.getInv(); 22356 var vel = invM.getMult([dx, -dy, 0.0]); 22357 vel.mult(2); 22358 this.value.add(vel); 22359 this.point = [this.value.x * this.scale, this.value.y * this.scale, this.value.z * this.scale]; 22360 // fire 'changed' 22361 this.trigger('changed', this.value); 22362 } else { 22363 this.camera.rotateX(dy); 22364 this.camera.rotateY(dx); 22365 } 22366 22367 this.dragOffset = [x, y]; 22368 } 22369 }, { 22370 key: 'onDbClick', 22371 value: function onDbClick(event) { 22372 var mouse = new _typesVector2['default']([event.offsetX, event.offsetY]); 22373 var axis = { 22374 x: [68, 0, 0], 22375 negX: [-68, 0, 0], 22376 y: [0, 68, 100], 22377 negY: [0, -68, 0] 22378 }; 22379 var selected = ''; 22380 for (var i in axis) { 22381 var pos = new _typesVector2['default'](this.viewFromCamera(axis[i])); 22382 var diff = pos.getSub(mouse); 22383 if (diff.getLength() < 10) { 22384 selected = i; 22385 break; 22386 } 22387 } 22388 this.camera = new _typesMatrix2['default'](); 22389 22390 if (selected === 'x') { 22391 this.camera.rotateY(-1.57079632679); 22392 } else if (selected === 'negX') { 22393 this.camera.rotateY(1.57079632679); 22394 } else if (selected === 'y') { 22395 this.camera.rotateX(-1.57079632679); 22396 } else if (selected === 'negY') { 22397 this.camera.rotateX(1.57079632679); 22398 } 22399 22400 this.draw(); 22401 } 22402 }, {
22403 key: 'destroyEvents', 22404 value: function destroyEvents() { 22405 _get(Object.getPrototypeOf(Vec3Picker.prototype), 'destroyEvents', this).call(this); 22406 (0, _Picker2.removeEvent)(this.el, 'dblclick', this.onDbClick); 22407 this.onMouseMoveHandler = null; 22408 } 22409 }, { 22410 key: 'setValue', 22411 value: function setValue(dir) { 22412 this.value = new _typesVector2['default'](dir); 22413 this.point = [this.value.x * this.scale, this.value.y * this.scale, this.value.z * this.scale]; 22414 } 22415 }]); 22416 22417 return Vec3Picker; 22418})(_Picker3['default']); 22419 22420exports['default'] = Vec3Picker; 22421module.exports = exports['default']; 22422 22423},{"./Picker":138,"./types/Matrix":144,"./types/Vector":145,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11,"babel-runtime/helpers/get":12,"babel-runtime/helpers/inherits":13,"babel-runtime/helpers/interop-require-default":14}],141:[function(_dereq_,module,exports){ 22424'use strict'; 22425 22426var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 22427 22428var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 22429 22430var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 22431 22432Object.defineProperty(exports, '__esModule', { 22433 value: true 22434}); 22435 22436var _ColorConverter = _dereq_('./ColorConverter'); 22437 22438var _ColorConverter2 = _interopRequireDefault(_ColorConverter); 22439 22440var Color = (function () { 22441 function Color(color) { 22442 _classCallCheck(this, Color); 22443 22444 this.colors = {}; 22445 this.set(color); 22446 } 22447 22448 _createClass(Color, [{ 22449 key: 'set', 22450 value: function set(color, type) { 22451 // color only full range 22452 if (typeof color === 'number') { 22453 type = type ? type : 'rgb'; 22454 this.colors[type] = {}; 22455 for (var n = 3; n--;) { 22456 var m = type[n] || type.charAt(n); // IE7 22457 this.colors[type][m] = color; 22458 } 22459 } else if (typeof color === 'string') { 22460 var parts = color.replace(/(?:#|\)|%)/g, '').split('('); 22461 if (parts[1]) { 22462 var values = (parts[1] || '').split(/,\s*/); 22463 type = type ? type : parts[1] ? parts[0].substr(0, 3) : 'rgb'; 22464 this.set(values, type); 22465 } else { 22466 this.set((0, _ColorConverter.getColorAsRGB)(color), 'rgb'); 22467 } 22468 } else if (color) { 22469 if (Array.isArray(color)) { 22470 var m = ''; 22471 type = type || 'rgb'; 22472 22473 this.colors[type] = this.colors[type] || {}; 22474 for (var _n = 3; _n--;) { 22475 m = type[_n] || type.charAt(_n); // IE7 22476 var i = color.length >= 3 ? _n : 0; 22477 this.colors[type][m] = parseFloat(color[i]); 22478 } 22479 22480 if (color.length === 4) { 22481 this.colors.alpha = parseFloat(color[3]); 22482 } 22483 } else if (type) { 22484 for (var _n2 in color) { 22485 this.colors[type][_n2] = (0, _ColorConverter.limitValue)(color[_n2] / (0, _ColorConverter.getValueRanges)(type)[_n2][1], 0, 1) * (0, _ColorConverter.getValueRanges)(type)[_n2][1]; 22486 } 22487 } 22488 } 22489 22490 if (!type) { 22491 return; 22492 } 22493 22494 if (type !== 'rgb') { 22495 var convert = _ColorConverter2['default']; 22496 this.colors.rgb = convert[type + '2rgb'](this.colors[type]); 22497 } 22498 this.convert(type); 22499 this.colors.hueRGB = _ColorConverter2['default'].hue2RGB(this.colors.hsv.h); 22500 this.colors.luminance = (0, _ColorConverter.getLuminance)(this.colors.rgb); 22501 } 22502 }, { 22503 key: 'convert', 22504 value: function convert(type) { 22505 var convert = _ColorConverter2['default'], 22506 ranges = (0, _ColorConverter.getValueRanges)(), 22507 exceptions = { hsl: 'hsv', cmyk: 'cmy', rgb: type }; 22508 22509 if (type !== 'alpha') { 22510 for (var typ in ranges) { 22511 if (!ranges[typ][typ]) { 22512 // no alpha|HEX 22513 if (type !== typ && typ !== 'XYZ') { 22514 var from = exceptions[typ] || 'rgb'; 22515 this.colors[typ] = convert[from + '2' + typ](this.colors[from]); 22516 } 22517 } 22518 } 22519 } 22520 } 22521 }, {
22522 key: 'get', 22523 value: function get(type) { 22524 if (type !== 'rgb') { 22525 var convert = _ColorConverter2['default']; 22526 this.colors[type] = convert['rgb2' + type](this.colors['rgb']); 22527 return this.colors[type]; 22528 } else { 22529 return this.colors['rgb']; 22530 } 22531 } 22532 }, { 22533 key: 'getString', 22534 value: function getString(type) { 22535 if (type === 'HEX') { 22536 var convert = _ColorConverter2['default']; 22537 return convert['rgb2' + type](this.colors['rgb']); 22538 } else { 22539 var color = this.get(type); 22540 var str = type, 22541 m = ''; 22542 if (type === 'vec') { 22543 str += this.colors.alpha ? 4 : 3; 22544 } 22545 str += '('; 22546 for (var n = 0; n < 3; n++) { 22547 m = type[n] || type.charAt(n); // IE7 22548 if (type === 'vec') { 22549 str += color[m].toFixed(3); 22550 } else { 22551 str += Math.floor(color[m]); 22552 } 22553 if (n !== 2) { 22554 str += ','; 22555 } 22556 } 22557 22558 if (this.colors.alpha) { 22559 str += ',' + this.colors.alpha.toFixed(3); 22560 } 22561 return str += ')'; 22562 } 22563 } 22564 }, { 22565 key: 'uniformType', 22566 value: function uniformType() { 22567 if (this.colors.alpha) { 22568 return 'vec4'; 22569 } 22570 return 'vec3'; 22571 } 22572 }, { 22573 key: 'uniformValue', 22574 value: function uniformValue() { 22575 var vec = this.get('vec'); 22576 var arr = [vec.v, vec.e, vec.c]; 22577 if (this.colors.alpha) { 22578 arr.push(this.colors.alpha); 22579 } 22580 return arr; 22581 } 22582 }, { 22583 key: 'uniformMethod', 22584 value: function uniformMethod(type) { 22585 if (this.colors.alpha) { 22586 return '4f'; 22587 } 22588 return '3f'; 22589 } 22590 }]); 22591 22592 return Color; 22593})(); 22594 22595exports['default'] = Color; 22596module.exports = exports['default']; 22597 22598},{"./ColorConverter":142,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11,"babel-runtime/helpers/interop-require-default":14}],142:[function(_dereq_,module,exports){ 22599'use strict'; 22600 22601var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 22602 22603var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 22604 22605Object.defineProperty(exports, '__esModule', { 22606 value: true 22607}); 22608exports.limitValue = limitValue; 22609exports.getLuminance = getLuminance; 22610exports.getColorAsRGB = getColorAsRGB; 22611exports.getValueRanges = getValueRanges; 22612var valueRanges = { 22613 rgb: { r: [0, 255], g: [0, 255], b: [0, 255] }, 22614 hsv: { h: [0, 1], s: [0, 1], v: [0, 255] }, 22615 hsl: { h: [0, 360], s: [0, 100], l: [0, 100] }, 22616 cmy: { c: [0, 100], m: [0, 100], y: [0, 100] }, 22617 cmyk: { c: [0, 100], m: [0, 100], y: [0, 100], k: [0, 100] }, 22618 Lab: { L: [0, 100], a: [-128, 127], b: [-128, 127] }, 22619 XYZ: { X: [0, 100], Y: [0, 100], Z: [0, 100] }, 22620 vec: { v: [0, 1], e: [0, 1], c: [0, 1] },
22621 alpha: { alpha: [0, 1] }, 22622 HEX: { HEX: [0, 16777215] } // maybe we don't need this 22623}; 22624 22625// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html for more 22626var XYZMatrix = { // Observer = 2° (CIE 1931), Illuminant = D65 22627 X: [0.4124564, 0.3575761, 0.1804375], 22628 Y: [0.2126729, 0.7151522, 0.0721750], 22629 Z: [0.0193339, 0.1191920, 0.9503041], 22630 R: [3.2404542, -1.5371385, -0.4985314], 22631 G: [-0.9692660, 1.8760108, 0.0415560], 22632 B: [0.0556434, -0.2040259, 1.0572252] 22633}; 22634 22635var XYZReference = { 22636 X: XYZMatrix.X[0] + XYZMatrix.X[1] + XYZMatrix.X[2], 22637 Y: XYZMatrix.Y[0] + XYZMatrix.Y[1] + XYZMatrix.Y[2], 22638 Z: XYZMatrix.Z[0] + XYZMatrix.Z[1] + XYZMatrix.Z[2] 22639}; 22640 22641var luminance = { r: 0.2126, g: 0.7152, b: 0.0722 }; // W3C 2.0 22642 22643var _colors; 22644 22645var ColorConverter = (function () { 22646 function ColorConverter() { 22647 _classCallCheck(this, ColorConverter); 22648 } 22649 22650 _createClass(ColorConverter, null, [{ 22651 key: 'vec2rgb', 22652 22653 // ------------------------ VEC ------------------------ // 22654 value: function vec2rgb(vec) { 22655 return { 22656 r: vec.v * valueRanges['rgb']['r'][1], 22657 g: vec.e * valueRanges['rgb']['g'][1], 22658 b: vec.c * valueRanges['rgb']['b'][1] 22659 }; 22660 } 22661 }, { 22662 key: 'rgb2vec', 22663 value: function rgb2vec(rgb) { 22664 return { 22665 v: rgb.r / valueRanges['rgb']['r'][1], 22666 e: rgb.g / valueRanges['rgb']['g'][1], 22667 c: rgb.b / valueRanges['rgb']['b'][1] 22668 }; 22669 } 22670 22671 // ------------------------ HEX ------------------------ // 22672 22673 }, { 22674 key: 'RGB2HEX', 22675 value: function RGB2HEX(rgb) { 22676 return ((rgb.r < 16 ? '0' : '') + rgb.r.toString(16) + (rgb.g < 16 ? '0' : '') + rgb.g.toString(16) + (rgb.b < 16 ? '0' : '') + rgb.b.toString(16)).toUpperCase(); 22677 } 22678 }, { 22679 key: 'HEX2rgb', 22680 value: function HEX2rgb(HEX) { 22681 HEX = HEX.split(''); // IE7 22682 return { 22683 r: parseInt(HEX[0] + HEX[HEX[3] ? 1 : 0], 16) / 255, 22684 g: parseInt(HEX[HEX[3] ? 2 : 1] + (HEX[3] || HEX[1]), 16) / 25
226845, 22685 b: parseInt((HEX[4] || HEX[2]) + (HEX[5] || HEX[2]), 16) / 255 22686 }; 22687 } 22688 22689 // ------------------------ HUE ------------------------ // 22690 22691 }, { 22692 key: 'hue2RGB', 22693 value: function hue2RGB(hue) { 22694 var h = hue * 6, 22695 22696 // mod = ~~h % 6, // Math.floor(h) -> faster in most browsers 22697 mod = Math.floor(h), 22698 i = h === 6 ? 0 : h - mod; 22699 return { 22700 r: Math.round([1, 1 - i, 0, 0, i, 1][mod] * 255), 22701 g: Math.round([i, 1, 1, 1 - i, 0, 0][mod] * 255), 22702 b: Math.round([0, 0, i, 1, 1, 1 - i][mod] * 255) 22703 }; 22704 } 22705 22706 // ------------------------ HSV ------------------------ // 22707 22708 }, { 22709 key: 'rgb2hsv', 22710 value: function rgb2hsv(rgb) { 22711 // faster 22712 var r = rgb.r, 22713 g = rgb.g, 22714 b = rgb.b, 22715 k = 0, 22716 chroma, 22717 min, 22718 s; 22719 22720 if (g < b) { 22721 g = b + (b = g, 0); 22722 k = -1; 22723 } 22724 min = b; 22725 if (r < g) { 22726 r = g + (g = r, 0); 22727 k = -2 / 6 - k; 22728 min = Math.min(g, b); // g < b ? g : b; ??? 22729 } 22730 chroma = r - min; 22731 s = r ? chroma / r : 0; 22732 return { 22733 h: s < 1e-15 ? _colors && _colors.hsl && _colors.hsl.h || 0 : chroma ? Math.abs(k + (g - b) / (6 * chroma)) : 0, 22734 s: r ? chroma / r : _colors && _colors.hsv && _colors.hsv.s || 0, // ??_colors.hsv.s || 0 22735 v: r 22736 }; 22737 } 22738 }, { 22739 key: 'hsv2rgb', 22740 value: function hsv2rgb(hsv) { 22741 var h = hsv.h * 6, 22742 s = hsv.s, 22743 v = hsv.v, 22744 22745 // i = ~~h, // Math.floor(h) -> faster in most browsers 22746 i = Math.floor(h), 22747 f = h - i, 22748 p = v * (1 - s), 22749 q = v * (1 - f * s), 22750 t = v * (1 - (1 - f) * s), 22751 mod = i % 6; 22752 22753 return { 22754 r: [v, q, p, p, t, v][mod], 22755 g: [t, v, v, q, p, p][mod], 22756 b: [p, p, t, v, v, q][mod] 22757 }; 22758 } 22759 22760 // ------------------------ HSL ------------------------ // 22761 22762 }, { 22763 key: 'hsv2hsl', 22764 value: function hsv2hsl(hsv) { 22765 var l = (2 - hsv.s) * hsv.v, 22766 s = hsv.s * hsv.v; 22767 22768 s = !hsv.s ? 0 : l < 1 ? l ? s / l : 0 : s / (2 - l); 22769 22770 return { 22771 h: hsv.h, 22772 s: !hsv.v && !s ? _colors && _colors.hsl && _colors.hsl.s || 0 : s, // ??? 22773 l: l / 2 22774 }; 22775 } 22776 }, { 22777 key: 'rgb2hsl', 22778 value: function rgb2hsl(rgb, dependent) { 22779 // not used in Color 22780 var hsv = ColorConverter.rgb2hsv(rgb); 22781 22782 return ColorConverter.hsv2hsl(dependent ? hsv : _colors.hsv = hsv); 22783 } 22784 }, { 22785 key: 'hsl2rgb', 22786 value: function hsl2rgb(hsl) { 22787 var h = hsl.h * 6, 22788 s = hsl.s, 22789 l = hsl.l, 22790 v = l < 0.5 ? l * (1 + s) : l + s - s * l, 22791 m = l + l - v, 22792 sv = v ? (v - m) / v : 0, 22793 22794 // sextant = ~~h, // Math.floor(h) -> faster in most browsers 22795 sextant = Math.floor(h), 22796 fract = h - sextant, 22797 vsf = v * sv * fract, 22798 t = m + vsf, 22799 q = v - vsf, 22800 mod = sextant % 6; 22801 22802 return { 22803 r: [v, q, m, m, t, v][mod], 22804 g: [t, v, v, q, m, m][mod], 22805 b: [m, m, t, v, v, q][mod] 22806 }; 22807 } 22808 22809 // ------------------------ CMYK ------------------------ // 22810 // Quote from Wikipedia: 22811 // 'Since RGB and CMYK spaces are both device-dependent spaces, there is no 22812 // simple or general conversion formula that converts between them. 22813 // Conversions are generally done through color management systems, using 22814 // color profiles that describe the spaces being converted. Nevertheless, the 22815 // conversions cannot be exact, since these spaces have very different gamuts.' 22816 // Translation: the following are just simple RGB to CMY(K) and visa versa conversion functions. 22817 22818 }, {
22819 key: 'rgb2cmy', 22820 value: function rgb2cmy(rgb) { 22821 return { 22822 c: 1 - rgb.r, 22823 m: 1 - rgb.g, 22824 y: 1 - rgb.b 22825 }; 22826 } 22827 }, { 22828 key: 'cmy2cmyk', 22829 value: function cmy2cmyk(cmy) { 22830 var k = Math.min(Math.min(cmy.c, cmy.m), cmy.y), 22831 t = 1 - k || 1e-20; 22832 22833 return { // regular 22834 c: (cmy.c - k) / t, 22835 m: (cmy.m - k) / t, 22836 y: (cmy.y - k) / t, 22837 k: k 22838 }; 22839 } 22840 }, { 22841 key: 'cmyk2cmy', 22842 value: function cmyk2cmy(cmyk) { 22843 var k = cmyk.k; 22844 22845 return { // regular 22846 c: cmyk.c * (1 - k) + k, 22847 m: cmyk.m * (1 - k) + k, 22848 y: cmyk.y * (1 - k) + k 22849 }; 22850 } 22851 }, { 22852 key: 'cmy2rgb', 22853 value: function cmy2rgb(cmy) { 22854 return { 22855 r: 1 - cmy.c, 22856 g: 1 - cmy.m, 22857 b: 1 - cmy.y 22858 }; 22859 } 22860 }, { 22861 key: 'rgb2cmyk', 22862 value: function rgb2cmyk(rgb) { 22863 var cmy = ColorConverter.rgb2cmy(rgb); // doppelt?? 22864 return ColorConverter.cmy2cmyk(cmy); 22865 } 22866 }, { 22867 key: 'cmyk2rgb', 22868 value: function cmyk2rgb(cmyk) { 22869 var cmy = ColorConverter.cmyk2cmy(cmyk); // doppelt?? 22870 return ColorConverter.cmy2rgb(cmy); 22871 } 22872 22873 // ------------------------ LAB ------------------------ // 22874 22875 }, { 22876 key: 'XYZ2rgb', 22877 value: function XYZ2rgb(XYZ) { 22878 var M = XYZMatrix, 22879 X = XYZ.X, 22880 Y = XYZ.Y, 22881 Z = XYZ.Z, 22882 r = X * M.R[0] + Y * M.R[1] + Z * M.R[2], 22883 g = X * M.G[0] + Y * M.G[1] + Z * M.G[2], 22884 b = X * M.B[0] + Y * M.B[1] + Z * M.B[2], 22885 N = 1 / 2.4; 22886 22887 M = 0.0031308; 22888 22889 r = r > M ? 1.055 * Math.pow(r, N) - 0.055 : 12.92 * r; 22890 g = g > M ? 1.055 * Math.pow(g, N) - 0.055 : 12.92 * g; 22891 b = b > M ? 1.055 * Math.pow(b, N) - 0.055 : 12.92 * b; 22892 22893 return { 22894 r: limitValue(r, 0, 1), 22895 g: limitValue(g, 0, 1), 22896 b: limitValue(b, 0, 1) 22897 }; 22898 } 22899 }, { 22900 key: 'rgb2XYZ', 22901 value: function rgb2XYZ(rgb) { 22902 var M = XYZMatrix, 22903 r = rgb.r, 22904 g = rgb.g, 22905 b = rgb.b, 22906 N = 0.04045; 22907 22908 r = r > N ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92; 22909 g = g > N ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92; 22910 b = b > N ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92; 22911 22912 return { 22913 X: r * M.X[0] + g * M.X[1] + b * M.X[2], 22914 Y: r * M.Y[0] + g * M.Y[1] + b * M.Y[2], 22915 Z: r * M.Z[0] + g * M.Z[1] + b * M.Z[2] 22916 }; 22917 } 22918 }, { 22919 key: 'XYZ2Lab', 22920 value: function XYZ2Lab(XYZ) { 22921 var R = XYZReference, 22922 X = XYZ.X / R.X, 22923 Y = XYZ.Y / R.Y, 22924 Z = XYZ.Z / R.Z, 22925 N = 16 / 116, 22926 M = 1 / 3, 22927 K = 0.008856, 22928 L = 7.787037; 22929 22930 X = X > K ? Math.pow(X, M) : L * X + N; 22931 Y = Y > K ? Math.pow(Y, M) : L * Y + N; 22932 Z = Z > K ? Math.pow(Z, M) : L * Z + N; 22933 22934 return { 22935 L: 116 * Y - 16, 22936 a: 500 * (X - Y), 22937 b: 200 * (Y - Z) 22938 }; 22939 } 22940 }, { 22941 key: 'Lab2XYZ', 22942 value: function Lab2XYZ(Lab) { 22943 var R = XYZReference, 22944 Y = (Lab.L + 16) / 116, 22945 X = Lab.a / 500 + Y, 22946 Z = Y - Lab.b / 200, 22947 X3 = Math.pow(X, 3), 22948 Y3 = Math.pow(Y, 3), 22949 Z3 = Math.pow(Z, 3), 22950 N = 16 / 116, 22951 K = 0.008856, 22952 L = 7.787037; 22953 22954 return { 22955 X: (X3 > K ? X3 : (X - N) / L) * R.X, 22956 Y: (Y3 > K ? Y3 : (Y - N) / L) * R.Y, 22957 Z: (Z3 > K ? Z3 : (Z - N) / L) * R.Z 22958 }; 22959 } 22960 }, {
22961 key: 'rgb2Lab', 22962 value: function rgb2Lab(rgb) { 22963 var XYZ = ColorConverter.rgb2XYZ(rgb); 22964 22965 return ColorConverter.XYZ2Lab(XYZ); 22966 } 22967 }, { 22968 key: 'Lab2rgb', 22969 value: function Lab2rgb(Lab) { 22970 var XYZ = ColorConverter.Lab2XYZ(Lab); 22971 22972 return ColorConverter.XYZ2rgb(XYZ); 22973 } 22974 }]); 22975 22976 return ColorConverter; 22977})(); 22978 22979exports['default'] = ColorConverter; 22980 22981function limitValue(value, min, max) { 22982 // return Math.max(min, Math.min(max, value)); // faster?? 22983 return value > max ? max : value < min ? min : value; 22984} 22985 22986function getLuminance(rgb, normalized) { 22987 var div = normalized ? 1 : 255, 22988 RGB = [rgb.r / div, rgb.g / div, rgb.b / div]; 22989 22990 for (var i = RGB.length; i--;) { 22991 RGB[i] = RGB[i] <= 0.03928 ? RGB[i] / 12.92 : Math.pow((RGB[i] + 0.055) / 1.055, 2.4); 22992 } 22993 return luminance.r * RGB[0] + luminance.g * RGB[1] + luminance.b * RGB[2]; 22994} 22995 22996function getColorAsRGB(color) { 22997 // Create a test element to apply a CSS color and retrieve 22998 // a normalized value from. 22999 var test = document.createElement('div'); 23000 test.style.backgroundColor = color; 23001 23002 // Chrome requires the element to be in DOM for styles to be computed. 23003 document.body.appendChild(test); 23004 23005 // Get the computed style from the browser, in the format of 23006 // rgb(x, x, x) 23007 var normalized = window.getComputedStyle(test).backgroundColor; 23008 23009 // In certain cases getComputedStyle() may return 23010 // 'transparent' as a value, which is useless(?) for the current 23011 // color picker. According to specifications, transparent 23012 // is a black with 0 alpha - rgba(0, 0, 0, 0) - but because 23013 // the picker does not currently handle alpha, we return the 23014 // black value. 23015 if (normalized === 'transparent') { 23016 normalized = 'rgb(0, 0, 0)'; 23017 } 23018 23019 // Garbage collection 23020 test.parentNode.removeChild(test); 23021 23022 return normalized; 23023} 23024 23025function getValueRanges(type) { 23026 if (!type) { 23027 return valueRanges; 23028 } else { 23029 return valueRanges[type]; 23030 } 23031} 23032 23033},{"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11}],143:[function(_dereq_,module,exports){ 23034'use strict'; 23035 23036var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 23037 23038var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 23039 23040Object.defineProperty(exports, '__esModule', { 23041 value: true 23042}); 23043 23044var Float = (function () { 23045 function Float(value) { 23046 _classCallCheck(this, Float); 23047 23048 this.value = value; 23049 } 23050 23051 _createClass(Float, [{ 23052 key: 'getString', 23053 value: function getString() { 23054 return this.value.toFixed(3); 23055 } 23056 }, { 23057 key: 'uniformType', 23058 value: function uniformType() { 23059 return 'float'; 23060 } 23061 }, { 23062 key: 'uniformValue', 23063 value: function uniformValue() { 23064 return [this.value]; 23065 } 23066 }, { 23067 key: 'uniformMethod', 23068 value: function uniformMethod() { 23069 return '1f'; 23070 } 23071 }]); 23072 23073 return Float; 23074})(); 23075 23076exports['default'] = Float; 23077module.exports = exports['default']; 23078 23079},{"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11}],144:[function(_dereq_,module,exports){ 23080'use strict'; 23081 23082var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 23083 23084var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 23085 23086var _interopRequireDefault = _dereq_('babel-runtime/helpers/interop-require-default')['default']; 23087 23088Object.defineProperty(exports, '__esModule', { 23089 value: true 23090}); 23091 23092var _Vector = _dereq_('./Vector'); 23093 23094var _Vector2 = _interopRequireDefault(_Vector); 23095 23096// TODO: 23097// - generalize this for mat2, mat3 and mat4 23098 23099var Matrix = (function () { 23100 function Matrix(m, type) { 23101 _classCallCheck(this, Matrix); 23102 23103 this.dim = 3; 23104 this.value = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]; 23105 if (m) { 23106 this.set(m, type); 23107 } 23108 } 23109 23110 _createClass(Matrix, [{ 23111 key: 'set', 23112 value: function set(m, type) { 23113 if (m.value[0][0]) { 23114 this.value = m.value; 23115 this.dim = m.dim; 23116 } else if (m[0][0]) { 23117 this.value = m; 23118 } 23119 } 23120 }, {
23121 key: 'rotateX', 23122 value: function rotateX(theta) { 23123 var c = Math.cos(theta); 23124 var s = Math.sin(theta); 23125 var T = [[1, 0, 0], [0, c, -s], [0, s, c]]; 23126 23127 this.value = this.getTransform(T); 23128 } 23129 }, { 23130 key: 'rotateY', 23131 value: function rotateY(theta) { 23132 var c = Math.cos(theta); 23133 var s = Math.sin(theta); 23134 var T = [[c, 0, s], [0, 1, 0], [-s, 0, c]]; 23135 23136 this.value = this.getTransform(T); 23137 } 23138 }, { 23139 key: 'getMult', 23140 value: function getMult(v) { 23141 if (v[0][0] || v.value && v.value[0][0]) { 23142 // TODO: what If v is a matrix 23143 console.log('TODO: what If v is a matrix'); 23144 } else { 23145 // If v is a vector 23146 var A = new _Vector2['default'](v); 23147 var B = []; 23148 for (var i = 0; i < A.dim; i++) { 23149 B.push(A.value[0] * this.value[i][0] + A.value[1] * this.value[i][1] + A.value[2] * this.value[i][2]); 23150 } 23151 return new _Vector2['default'](B); 23152 } 23153 } 23154 }, { 23155 key: 'getTransform', 23156 value: function getTransform(m) { 23157 var newMatrix = []; 23158 for (var row in m) { 23159 var t = m[row]; 23160 var newRow = []; 23161 newRow.push(t[0] * this.value[0][0] + t[1] * this.value[1][0] + t[2] * this.value[2][0]); 23162 newRow.push(t[0] * this.value[0][1] + t[1] * this.value[1][1] + t[2] * this.value[2][1]); 23163 newRow.push(t[0] * this.value[0][2] + t[1] * this.value[1][2] + t[2] * this.value[2][2]); 23164 newMatrix.push(newRow); 23165 } 23166 return newMatrix; 23167 } 23168 }, { 23169 key: 'getInv', 23170 value: function getInv() { 23171 var M = new Matrix(); 23172 var determinant = this.value[0][0] * (this.value[1][1] * this.value[2][2] - this.value[2][1] * this.value[1][2]) - this.value[0][1] * (this.value[1][0] * this.value[2][2] - this.value[1][2] * this.value[2][0]) + this.value[0][2] * (this.value[1][0] * this.value[2][1] - this.value[1][1] * this.value[2][0]); 23173 var invdet = 1 / determinant; 23174 M.value[0][0] = (this.value[1][1] * this.value[2][2] - this.value[2][1] * this.value[1][2]) * invdet; 23175 M.value[0][1] = -(this.value[0][1] * this.value[2][2] - this.value[0][2] * this.value[2][1]) * invdet; 23176 M.value[0][2] = (this.value[0][1] * this.value[1][2] - this.value[0][2] * this.value[1][1]) * invdet; 23177 M.value[1][0] = -(this.value[1][0] * this.value[2][2] - this.value[1][2] * this.value[2][0]) * invdet; 23178 M.value[1][1] = (this.value[0][0] * this.value[2][2] - this.value[0][2] * this.value[2][0]) * invdet; 23179 M.value[1][2] = -(this.value[0][0] * this.value[1][2] - this.value[1][0] * this.value[0][2]) * invdet; 23180 M.value[2][0] = (this.value[1][0] * this.value[2][1] - this.value[2][0] * this.value[1][1]) * invdet; 23181 M.value[2][1] = -(this.value[0][0] * this.value[2][1] - this.value[2][0] * this.value[0][1]) * invdet; 23182 M.value[2][2] = (this.value[0][0] * this.value[1][1] - this.value[1][0] * this.value[0][1]) * invdet; 23183 return M; 23184 } 23185 }]); 23186 23187 return Matrix; 23188})(); 23189 23190exports['default'] = Matrix; 23191module.exports = exports['default']; 23192 23193},{"./Vector":145,"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11,"babel-runtime/helpers/interop-require-default":14}],145:[function(_dereq_,module,exports){ 23194'use strict'; 23195 23196var _createClass = _dereq_('babel-runtime/helpers/create-class')['default']; 23197 23198var _classCallCheck = _dereq_('babel-runtime/helpers/class-call-check')['default']; 23199 23200Object.defineProperty(exports, '__esModule', { 23201 value: true 23202}); 23203 23204var Vector = (function () { 23205 function Vector(vec, type) { 23206 _classCallCheck(this, Vector); 23207 23208 this.value = [0, 0]; 23209 this.dim = 2; 23210 this.set(vec, type); 23211 } 23212 23213 _createClass(Vector, [{ 23214 key: 'set', 23215 value: function set(vec, type) { 23216 if (typeof vec === 'number') { 23217 type = type || 'vec2'; 23218 this.set([vec], type); 23219 } else if (typeof vec === 'string') { 23220 var parts = vec.replace(/(?:#|\)|\]|%)/g, '').split('('); 23221 var strValues = (parts[1] || parts[0].replace(/(\[)/g, '')).split(/,\s*/); 23222 type = type || (parts[1] ? parts[0].substr(0, 4) : 'vec' + strValues.length); 23223 var values = []; 23224 for (var i in strValues) { 23225 values.push(parseFloat(strValues[i])); 23226 } 23227 this.set(values, type); 23228 } else if (vec) { 23229 if (Array.isArray(vec)) { 23230 this.value = []; 23231 this.value.length = 0; 23232 this.dim = type ? Number(type.substr(3, 4)) : vec.length; 23233 var filler = vec.length === 1 ? vec[0] : 0; 23234 for (var i = 0; i < this.dim; i++) { 23235 this.value.push(vec[i] || filler); 23236 } 23237 } else if (vec.dim) { 23238 this.value = vec.value; 23239 this.dim = vec.dim; 23240 } 23241 } 23242 } 23243 }, {
23244 key: 'getString', 23245 value: function getString(type) { 23246 type = type || 'vec' + this.dim; 23247 23248 var len = this.dim; 23249 var str = ''; 23250 var head = type + '('; 23251 var end = ')'; 23252 23253 if (type === 'array') { 23254 head = '['; 23255 end = ']'; 23256 len = this.dim; 23257 } else { 23258 len = Number(type.substr(3, 4)); 23259 } 23260 23261 str = head; 23262 for (var i = 0; i < len; i++) { 23263 str += this.value[i].toFixed(3); 23264 if (i !== len - 1) { 23265 str += ','; 23266 } 23267 } 23268 return str += end; 23269 } 23270 }, { 23271 key: 'uniformType', 23272 value: function uniformType() { 23273 return 'vec' + this.dim; 23274 } 23275 }, { 23276 key: 'uniformValue', 23277 value: function uniformValue() { 23278 var arr = []; 23279 for (var i = 0; i < this.dim; i++) { 23280 arr.push(this.value[i]); 23281 } 23282 return arr; 23283 } 23284 }, { 23285 key: 'uniformMethod', 23286 value: function uniformMethod() { 23287 return this.dim + 'f'; 23288 } 23289 23290 // VECTOR OPERATIONS 23291 23292 }, { 23293 key: 'add', 23294 value: function add(v) { 23295 if (typeof v === 'number') { 23296 for (var i = 0; i < this.dim; i++) { 23297 this.value[i] = this.value[i] + v; 23298 } 23299 } else { 23300 var A = new Vector(v); 23301 var lim = Math.min(this.dim, A.dim); 23302 for (var i = 0; i < lim; i++) { 23303 this.value[i] = this.value[i] + A.value[i]; 23304 } 23305 } 23306 } 23307 }, { 23308 key: 'sub', 23309 value: function sub(v) { 23310 if (typeof v === 'number') { 23311 for (var i = 0; i < this.dim; i++) { 23312 this.value[i] = this.value[i] - v; 23313 } 23314 } else { 23315 var A = new Vector(v); 23316 var lim = Math.min(this.dim, A.dim); 23317 for (var i = 0; i < lim; i++) { 23318 this.value[i] = this.value[i] - A.value[i]; 23319 } 23320 } 23321 } 23322 }, { 23323 key: 'mult', 23324 value: function mult(v) { 23325 if (typeof v === 'number') { 23326 // Mulitply by scalar 23327 for (var i = 0; i < this.dim; i++) { 23328 this.value[i] = this.value[i] * v; 23329 } 23330 } else { 23331 // Multiply two vectors 23332 var A = new Vector(v); 23333 var lim = Math.min(this.dim, A.dim); 23334 for (var i = 0; i < lim; i++) { 23335 this.value[i] = this.value[i] * A.value[i]; 23336 } 23337 } 23338 } 23339 }, { 23340 key: 'div', 23341 value: function div(v) { 23342 if (typeof v === 'number') { 23343 // Mulitply by scalar 23344 for (var i = 0; i < this.dim; i++) { 23345 this.value[i] = this.value[i] / v; 23346 } 23347 } else { 23348 // Multiply two vectors 23349 var A = new Vector(v); 23350 var lim = Math.min(this.dim, A.dim); 23351 for (var i = 0; i < lim; i++) { 23352 this.value[i] = this.value[i] / A.value[i]; 23353 } 23354 } 23355 } 23356 }, { 23357 key: 'normalize', 23358 value: function normalize() { 23359 var l = this.getLength(); 23360 this.div(l); 23361 } 23362 }, { 23363 key: 'getAdd', 23364 value: function getAdd(v) { 23365 var A = new Vector(this); 23366 A.add(v); 23367 return A; 23368 } 23369 }, { 23370 key: 'getSub', 23371 value: function getSub(v) { 23372 var A = new Vector(this); 23373 A.sub(v); 23374 return A; 23375 } 23376 }, { 23377 key: 'getMult', 23378 value: function getMult(v) { 23379 var A = new Vector(this); 23380 A.mult(v); 23381 return A; 23382 } 23383 }, { 23384 key: 'getDiv', 23385 value: function getDiv(v) { 23386 var A = new Vector(this); 23387 A.div(v); 23388 return A; 23389 } 23390 }, {
23391 key: 'getLengthSq', 23392 value: function getLengthSq() { 23393 if (this.dim === 2) { 23394 return this.value[0] * this.value[0] + this.value[1] * this.value[1]; 23395 } else { 23396 return this.value[0] * this.value[0] + this.value[1] * this.value[1] + this.value[2] * this.value[2]; 23397 } 23398 } 23399 }, { 23400 key: 'getLength', 23401 value: function getLength() { 23402 return Math.sqrt(this.getLengthSq()); 23403 } 23404 }, { 23405 key: 'x', 23406 set: function set(v) { 23407 this.value[0] = v; 23408 }, 23409 get: function get() { 23410 return this.value[0] || 0.0; 23411 } 23412 }, { 23413 key: 'y', 23414 set: function set(v) { 23415 this.value[1] = v; 23416 }, 23417 get: function get() { 23418 return this.value[1] || 0.0; 23419 } 23420 }, { 23421 key: 'z', 23422 set: function set(v) { 23423 if (this.dim < 3) { 23424 while (this.dim < 3) { 23425 this.value.push(0); 23426 } 23427 this.dim = 3; 23428 } 23429 this.value[2] = v; 23430 }, 23431 get: function get() { 23432 return this.value[2] || 0.0; 23433 } 23434 }, { 23435 key: 'w', 23436 set: function set(v) { 23437 if (this.dim < 4) { 23438 while (this.dim < 4) { 23439 this.value.push(0); 23440 } 23441 this.dim = 4; 23442 } 23443 this.value[3] = v; 23444 }, 23445 get: function get() { 23446 return this.value[3] || 0.0; 23447 } 23448 }]); 23449 23450 return Vector; 23451})(); 23452 23453exports['default'] = Vector; 23454module.exports = exports['default']; 23455 23456},{"babel-runtime/helpers/class-call-check":10,"babel-runtime/helpers/create-class":11}]},{},[114])(114) 23457}); 23458 23459//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcnVudGltZS9jb3JlLWpzL2dldC1pdGVyYXRvci5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1ydW50aW1lL2NvcmUtanMvb2JqZWN0L2Fzc2lnbi5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1ydW50aW1lL2NvcmUtanMvb2JqZWN0L2NyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1ydW50aW1lL2NvcmUtanMvb2JqZWN0L2RlZmluZS1wcm9wZXJ0eS5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1ydW50aW1lL2NvcmUtanMvb2JqZWN0L2dldC1vd24tcHJvcGVydHktZGVzY3JpcHRvci
234595qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1ydW50aW1lL2NvcmUtanMvb2JqZWN0L2tleXMuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcnVudGltZS9jb3JlLWpzL29iamVjdC9zZXQtcHJvdG90eXBlLW9mLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXJ1bnRpbWUvY29yZS1qcy9wcm9taXNlLmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXJ1bnRpbWUvY29yZS1qcy9zZXQuanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcnVudGltZS9oZWxwZXJzL2NsYXNzLWNhbGwtY2hlY2suanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcnVudGltZS9oZWxwZXJzL2NyZWF0ZS1jbGFzcy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1ydW50aW1lL2hlbHBlcnMvZ2V0LmpzIiwibm9kZV9tb2R1bGVzL2JhYmVsLXJ1bnRpbWUvaGVscGVycy9pbmhlcml0cy5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1ydW50aW1lL2hlbHBlcnMvaW50ZXJvcC1yZXF1aXJlLWRlZmF1bHQuanMiLCJub2RlX21vZHVsZXMvY29kZW1pcnJvci9hZGRvbi9jb21tZW50L2NvbW1lbnQuanMiLCJub2RlX21vZHVsZXMvY29kZW1pcnJvci9hZGRvbi9kaWFsb2cvZGlhbG9nLmpzIiwibm9kZV9tb2R1bGVzL2NvZGVtaXJyb3IvYWRkb24vZGlzcGxheS9wYW5lbC5qcyIsIm5vZGVfbW9kdWxlcy9jb2RlbWlycm9yL2FkZG9uL2Rpc3BsYXkvcnVsZXJzLmpzIiwibm9kZV9tb2R1bGVzL2NvZGVtaXJyb3IvYWRkb24vZWRpdC9jbG9zZWJyYWNrZXRzLmpzIiwibm9kZV9tb2R1bGVzL2NvZGVtaXJyb3IvYWRkb24vZWRpdC9tYXRjaGJyYWNrZXRzLmpzIiwibm9kZV9tb2R1bGVzL2NvZGVtaXJyb3IvYWRkb24vZm9sZC9mb2xkY29kZS5qcyIsIm5vZGVfbW9kdWxlcy9jb2RlbWlycm9yL2FkZG9uL2ZvbGQvZm9sZGd1dHRlci5qcyIsIm5vZGVfbW9kdWxlcy9jb2RlbWlycm9yL2FkZG9uL2ZvbGQvaW5kZW50LWZvbGQuanMiLCJub2RlX21vZHVsZXMvY29kZW1pcnJvci9hZGRvbi9oaW50L2phdmFzY3JpcHQtaGludC5qcyIsIm5vZGVfbW9kdWxlcy9jb2RlbWlycm9yL2FkZG9uL2hpbnQvc2hvdy1oaW50LmpzIiwibm9kZV9tb2R1bGVzL2NvZGVtaXJyb3IvYWRkb24vc2VhcmNoL3NlYXJjaC5qcyIsIm5vZGVfbW9kdWxlcy9jb2RlbWlycm9yL2FkZG9uL3NlYXJjaC9zZWFyY2hjdXJzb3IuanMiLCJub2RlX21vZHVsZXMvY29kZW1pcnJvci9hZGRvbi93cmFwL2hhcmR3cmFwLmpzIiwibm9kZV9tb2R1bGVzL2NvZGVtaXJyb3Iva2V5bWFwL3N1YmxpbWUuanMiLCJub2RlX21vZHVsZXMvY29kZW1pcnJvci9saWIvY29kZW1pcnJvci5qcyIsIm5vZGVfbW9kdWxlcy9jb2RlbWlycm9yL21vZGUvY2xpa2UvY2xpa2UuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L2ZuL2dldC1pdGVyYXRvci5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvZm4vb2JqZWN0L2Fzc2lnbi5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvZm4vb2JqZWN0L2NyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvZm4vb2JqZWN0L2RlZmluZS1wcm9wZXJ0eS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvZm4vb2JqZWN0L2dldC1vd24tcHJvcGVydHktZGVzY3JpcHRvci
234595qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvZm4vb2JqZWN0L2tleXMuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L2ZuL29iamVjdC9zZXQtcHJvdG90eXBlLW9mLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9mbi9wcm9taXNlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9mbi9zZXQuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5hLWZ1bmN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuYWRkLXRvLXVuc2NvcGFibGVzLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuYW4tb2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuY2xhc3NvZi5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmNvZi5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmNvbGxlY3Rpb24tc3Ryb25nLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuY29sbGVjdGlvbi10by1qc29uLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuY29sbGVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmNvcmUuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5jdHguanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5kZWZpbmVkLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuZGVzY3JpcHRvcnMuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5kb20tY3JlYXRlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuZXhwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuZmFpbHMuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5mb3Itb2YuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5nbG9iYWwuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5oYXMuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5oaWRlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuaHRtbC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmludm9rZS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmlvYmplY3QuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5pcy1hcnJheS1pdGVyLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuaXMtb2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuaXRlci1jYWxsLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuaXRlci1jcmVhdGUuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5pdGVyLWRlZmluZS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLml0ZXItZGV0ZWN0LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuaXRlci1zdGVwLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuaXRlcmF0b3JzLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5saWJyYXJ5LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQubWljcm90YXNrLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQub2JqZWN0LWFzc2lnbi5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLm9iamVjdC1zYXAuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5wcm9wZXJ0eS1kZXNjLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQucmVkZWZpbmUtYWxsLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQucmVkZWZpbmUuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5zYW1lLXZhbHVlLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuc2V0LXByb3RvLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuc2V0LXNwZWNpZXMuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5zZXQtdG8tc3RyaW5nLXRhZy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnNoYXJlZC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnNwZWNpZXMtY29uc3RydWN0b3IuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5zdHJpY3QtbmV3LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuc3RyaW5nLWF0LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQudGFzay5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnRvLWludGVnZXIuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC50by1pb2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQudG8tbGVuZ3RoLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQudG8tb2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQudWlkLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQud2tzLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9jb3JlLmdldC1pdGVyYXRvci5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuYXJyYXkuaXRlcmF0b3IuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24uanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3IuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM2Lm9iamVjdC5rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5vYmplY3Quc2V0LXByb3RvdHlwZS1vZi5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYucHJvbWlzZS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuc2V0LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3IuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM3LnNldC50by1qc29uLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUuanMiLCJub2RlX21vZHVsZXMvZG9jdW1lbnQtcmVnaXN0ZXItZWxlbWVudC9idWlsZC9kb2N1bWVudC1yZWdpc3Rlci1lbGVtZW50Lm5vZGUuanMiLCJub2RlX21vZHVsZXMvZ2xvYmFsL3dpbmRvdy5qcyIsIm5vZGVfbW9kdWxlcy9nbHNsQ2FudmFzL2Rpc3QvR2xzbENhbnZhcy5qcyIsIm5vZGVfbW9kdWxlcy9pcy1mdW5jdGlvbi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9wYXJzZS1oZWFkZXJzL3BhcnNlLWhlYWRlcnMuanMiLCJub2RlX21vZHVsZXMveGhyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3h0ZW5kL2ltbXV0YWJsZS5qcyIsIi9ob21lL3BhdHJpY2lvL0Rlc2t0b3AvZ2xzbEVkaXRvci9zcmMvanMvR2xzbEVkaXRvci5qcyIsIi9ob21lL3BhdHJpY2lvL0Rlc2t0b3AvZ2xzbEVkaXRvci9zcmMvanMvY29yZS9FZGl0b3IuanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL2Nvcm
23459UvU2hhZGVyLmpzIiwiL2hvbWUvcGF0cmljaW8vRGVza3RvcC9nbHNsRWRpdG9yL3NyYy9qcy9pby9CdWZmZXJNYW5hZ2VyLmpzIiwiL2hvbWUvcGF0cmljaW8vRGVza3RvcC9nbHNsRWRpdG9yL3NyYy9qcy9pby9GaWxlRHJvcC5qcyIsIi9ob21lL3BhdHJpY2lvL0Rlc2t0b3AvZ2xzbEVkaXRvci9zcmMvanMvaW8vSGFzaFdhdGNoLmpzIiwiL2hvbWUvcGF0cmljaW8vRGVza3RvcC9nbHNsRWRpdG9yL3NyYy9qcy9pby9Mb2NhbFN0b3JhZ2UuanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3Rvb2xzL2NvbW1vbi5qcyIsIi9ob21lL3BhdHJpY2lvL0Rlc2t0b3AvZ2xzbEVkaXRvci9zcmMvanMvdG9vbHMvZGVidWdnaW5nLmpzIiwiL2hvbWUvcGF0cmljaW8vRGVza3RvcC9nbHNsRWRpdG9yL3NyYy9qcy90b29scy9kb3dubG9hZC5qcyIsIi9ob21lL3BhdHJpY2lvL0Rlc2t0b3AvZ2xzbEVkaXRvci9zcmMvanMvdG9vbHMvaW50ZXJhY3RpdmVEb20uanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3Rvb2xzL21lZGlhQ2FwdHVyZS5qcyIsIi9ob21lL3BhdHJpY2lvL0Rlc2t0b3AvZ2xzbEVkaXRvci9zcmMvanMvdG9vbHMvbWl4aW4uanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3Rvb2xzL3VybHMuanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3VpL0Vycm9yc0Rpc3BsYXkuanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3VpL0V4cG9ydEljb24uanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3VpL0hlbHBlcnMuanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3VpL01lbnUuanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3VpL01lbnVJdGVtLmpzIiwiL2hvbWUvcGF0cmljaW8vRGVza3RvcC9nbHNsRWRpdG9yL3NyYy9qcy91aS9WaXN1YWxEZWJ1Z2dlci5qcyIsIi9ob21lL3BhdHJpY2lvL0Rlc2t0b3AvZ2xzbEVkaXRvci9zcmMvanMvdWkvbW9kYWxzL0V4cG9ydE1vZGFsLmpzIiwiL2hvbWUvcGF0cmljaW8vRGVza3RvcC9nbHNsRWRpdG9yL3NyYy9qcy91aS9tb2RhbHMvTW9kYWwuanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3VpL3BpY2tlcnMvQ29sb3JQaWNrZXIuanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3VpL3BpY2tlcnMvRmxvYXRQaWNrZXIuanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3VpL3BpY2tlcnMvUGlja2VyLmpzIiwiL2hvbWUvcGF0cmljaW8vRGVza3RvcC9nbHNsRWRpdG9yL3NyYy9qcy91aS9waWNrZXJzL1ZlYzJQaWNrZXIuanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3VpL3BpY2tlcnMvVmVjM1BpY2tlci5qcyIsIi9ob21lL3BhdHJpY2lvL0Rlc2t0b3AvZ2xzbEVkaXRvci9zcmMvanMvdWkvcGlja2Vycy90eXBlcy9Db2xvci5qcyIsIi9ob21lL3BhdHJpY2lvL0Rlc2t0b3AvZ2xzbEVkaXRvci9zcmMvanMvdWkvcGlja2Vycy90eXBlcy9Db2xvckNvbnZlcnRlci5qcyIsIi9ob21lL3BhdHJpY2lvL0Rlc2t0b3AvZ2xzbEVkaXRvci9zcmMvanMvdWkvcGlja2Vycy90eXBlcy9GbG9hdC5qcyIsIi9ob21lL3BhdHJpY2lvL0Rlc2t0b3AvZ2xzbEVkaXRvci9zcmMvanMvdWkvcGlja2Vycy90eXBlcy9NYXRyaXguanMiLCIvaG9tZS9wYXRyaWNpby9EZXNrdG9wL2dsc2xFZGl0b3Ivc3JjL2pzL3VpL3BpY2tlcnMvdHlwZXMvVmVjdG9yLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7O0FDQUE7O0FDQUE7O0FDQUE7O0FDQUE7O0FDQUE7O0FDQUE7O0FDQUE7O0FDQUE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcE1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QU
23459FDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcmpCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0
23459FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0
23459E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QU
23459FDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4cFJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QU
23459FDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3h1QkE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBOztBQ0RBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0REE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBOztBQ0ZBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBOztBQ0ZBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7OztBQ0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0
23459FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN6L0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0
23459E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzlnRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2UEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O1FDbkJPLDJCQUEyQjs7MEJBQ2YsZUFBZTs7OzswQkFDRyxlQUFlOztzQkFFbkMsV0FBVzs7Ozt5QkFDUixjQUFjOzs7OytCQUNSLG9CQUFvQjs7OztnQ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UFDO0FBQy9DLG9CQUFJLFVBQVUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQy9DLG9CQUFJLFdBQVcsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDOztBQUVoRCxxQkFBSyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLHVCQUF1QixDQUFDO0FBQzVELHFCQUFLLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO0FBQzNDLHFCQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDO0FBQzVDLHFCQUFLLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO0FBQzNDLG1CQUFHLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDO0FBQzVDLG9CQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO0FBQzFDLG9CQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO0FBQzFDLHFCQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsWUFBWSxDQUFDO0FBQ2pELHNCQUFNLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsYUFBYSxDQUFDO0FBQ25ELHFCQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDO0FBQzdDLHdCQUFRLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsV0FBVyxDQUFDO0FBQ25ELHNCQUFNLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsZUFBZSxDQUFDO0FBQ3JELDBCQUFVLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsYUFBYSxDQUFDO0FBQ3ZELDBCQUFVLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQ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UFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBLEFBQUMsR0FDNUYsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBLEFBQUMsR0FDOUYsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBLEFBQUMsQ0FBQztBQUNuSCxnQkFBSSxNQUFNLEdBQUcsQ0FBQyxHQUFHLFdBQVcsQ0FBQztBQUM3QixhQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQSxHQUFJLE1BQU0sQ0FBQztBQUNyRyxhQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQSxBQUFDLEdBQUcsTUFBTSxDQUFDO0FBQ3RHLGFBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBLEdBQUksTUFBTSxDQUFDO0FBQ3JHLGFBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBLEFBQUMsR0FBRyxNQUFNLENBQUM7QUFDdEcsYUFBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUEsR0FBSSxNQUFNLENBQUM7QUFDckcsYUFBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUEsQUFBQyxHQUFHLE1BQU0sQ0FBQztBQUN0RyxhQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDL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lsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJtb2R1bGUuZXhwb3J0cyA9IHsgXCJkZWZhdWx0XCI6IHJlcXVpcmUoXCJjb3JlLWpzL2xpYnJhcnkvZm4vZ2V0LWl0ZXJhdG9yXCIpLCBfX2VzTW9kdWxlOiB0cnVlIH07IiwibW9kdWxlLmV4cG9ydHMgPSB7IFwiZGVmYXVsdFwiOiByZXF1aXJlKFwiY29yZS1qcy9saWJyYXJ5L2ZuL29iamVjdC9hc3NpZ25cIiksIF9fZXNNb2R1bGU6IHRydWUgfTsiLCJtb2R1bGUuZXhwb3J0cyA9IHsgXCJkZWZhdWx0XCI6IHJlcXVpcmUoXCJjb3JlLWpzL2xpYnJhcnkvZm4vb2JqZWN0L2NyZWF0ZVwiKSwgX19lc01vZHVsZTogdHJ1ZSB9OyIsIm1vZHVsZS5leHBvcnRzID0geyBcImRlZmF1bHRcIjogcmVxdWlyZShcImNvcmUtanMvbGlicmFyeS9mbi9vYmplY3QvZGVmaW5lLXByb3BlcnR5XCIpLCBfX2VzTW9kdWxlOiB0cnVlIH07IiwibW9kdWxlLmV4cG9ydHMgPSB7IFwiZGVmYXVsdFwiOiByZXF1aXJlKFwiY29yZS1qcy9saWJyYXJ5L2ZuL29iamVjdC9nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JcIiksIF9fZXNNb2R1bGU6IHRydWUgfTsiLCJtb2R1bGUuZXhwb3J0cyA9IHsgXCJkZWZhdWx0XCI6IHJlcXVpcmUoXCJjb3JlLWpzL2xpYnJhcnkvZm4vb2JqZWN0L2tleXNcIiksIF9fZXNNb2R1bGU6IHRydWUgfTsiLCJtb2R1bGUuZXhwb3J0cyA9IHsgXCJkZWZhdWx0XCI6IHJlcXVpcmUoXCJjb3JlLWpzL2xpYnJhcnkvZm4vb2JqZWN0L3NldC1wcm90b3R5cGUtb2ZcIiksIF9fZXNNb2R1bGU6IHRydWUgfTsiLCJtb2R1bGUuZXhwb3J0cyA9IHsgXCJkZWZhdWx0XCI6IHJlcXVpcmUoXCJjb3JlLWpzL2xpYnJhcnkvZm4vcHJvbWlzZVwiKSwgX19lc01vZHVsZTogdHJ1ZSB9OyIsIm1vZHVsZS5leHBvcnRzID0geyBcImRlZmF1bHRcIjogcmVxdWlyZShcImNvcmUtanMvbGlicmFyeS9mbi9zZXRcIiksIF9fZXNNb2R1bGU6IHRydWUgfTsiLCJcInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7XG4gIGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTtcbiAgfVxufTtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF9PYmplY3QkZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKFwiYmFiZWwtcnVudGltZS9jb3JlLWpzL29iamVjdC9kZWZpbmUtcHJvcGVydHlcIilbXCJkZWZhdWx0XCJdO1xuXG5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IChmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07XG4gICAgICBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7XG4gICAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7XG4gICAgICBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlO1xuXG4gICAgICBfT2JqZWN0JGRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci
234595rZXksIGRlc2NyaXB0b3IpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gICAgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTtcbiAgICBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTtcbiAgICByZXR1cm4gQ29uc3RydWN0b3I7XG4gIH07XG59KSgpO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX09iamVjdCRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKFwiYmFiZWwtcnVudGltZS9jb3JlLWpzL29iamVjdC9nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JcIilbXCJkZWZhdWx0XCJdO1xuXG5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IGZ1bmN0aW9uIGdldChfeCwgX3gyLCBfeDMpIHtcbiAgdmFyIF9hZ2FpbiA9IHRydWU7XG5cbiAgX2Z1bmN0aW9uOiB3aGlsZSAoX2FnYWluKSB7XG4gICAgdmFyIG9iamVjdCA9IF94LFxuICAgICAgICBwcm9wZXJ0eSA9IF94MixcbiAgICAgICAgcmVjZWl2ZXIgPSBfeDM7XG4gICAgX2FnYWluID0gZmFsc2U7XG4gICAgaWYgKG9iamVjdCA9PT0gbnVsbCkgb2JqZWN0ID0gRnVuY3Rpb24ucHJvdG90eXBlO1xuXG4gICAgdmFyIGRlc2MgPSBfT2JqZWN0JGdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIHByb3BlcnR5KTtcblxuICAgIGlmIChkZXNjID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTtcblxuICAgICAgaWYgKHBhcmVudCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgX3ggPSBwYXJlbnQ7XG4gICAgICAgIF94MiA9IHByb3BlcnR5O1xuICAgICAgICBfeDMgPSByZWNlaXZlcjtcbiAgICAgICAgX2FnYWluID0gdHJ1ZTtcbiAgICAgICAgZGVzYyA9IHBhcmVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgY29udGludWUgX2Z1bmN0aW9uO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXCJ2YWx1ZVwiIGluIGRlc2MpIHtcbiAgICAgIHJldHVybiBkZXNjLnZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB2Y
23459XIgZ2V0dGVyID0gZGVzYy5nZXQ7XG5cbiAgICAgIGlmIChnZXR0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpO1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTsiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF9PYmplY3QkY3JlYXRlID0gcmVxdWlyZShcImJhYmVsLXJ1bnRpbWUvY29yZS1qcy9vYmplY3QvY3JlYXRlXCIpW1wiZGVmYXVsdFwiXTtcblxudmFyIF9PYmplY3Qkc2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKFwiYmFiZWwtcnVudGltZS9jb3JlLWpzL29iamVjdC9zZXQtcHJvdG90eXBlLW9mXCIpW1wiZGVmYXVsdFwiXTtcblxuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBmdW5jdGlvbiAoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHtcbiAgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSBcImZ1bmN0aW9uXCIgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpO1xuICB9XG5cbiAgc3ViQ2xhc3MucHJvdG90eXBlID0gX09iamVjdCRjcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwge1xuICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICB2YWx1ZTogc3ViQ2xhc3MsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfVxuICB9KTtcbiAgaWYgKHN1cGVyQ2xhc3MpIF9PYmplY3Qkc2V0UHJvdG90eXBlT2YgPyBfT2JqZWN0JHNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7XG59O1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOyIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHtcbiAgICBcImRlZmF1bHRcIjogb2JqXG4gIH07XG59O1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOyIsIi8vIENvZGVNaXJyb3IsIGNvcHlyaWdodCAoYykgYnkgTWFyaWpuIEhhdmVyYmVrZSBhbmQgb3RoZXJzXG4vLyBEaXN0cmlidXRlZCB1bmRlciBhbiBNSVQgbGljZW5zZTogaHR0cDovL2NvZGVtaXJyb3IubmV0L0xJQ0VOU0VcblxuKGZ1bmN0aW9uKG1vZCkge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlID09IFwib2JqZWN0XCIpIC8vIENvbW1vbkpTXG4gICAgbW9kKHJlcXVpcmUoXCIuLi8uLi9saWIvY29kZW1pcnJvclwiKSk7XG4gIGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIC8vIEFNRFxuICAgIGRlZmluZShbXCIuLi8uLi9saWIvY29kZW1pcnJvclwiXSwgbW9kKTtcbiAgZWxzZSAvLyBQbGFpbiBicm93c2VyIGVudlxuICAgIG1vZChDb2RlTWlycm9yKTtcbn0pKGZ1bmN0aW9uKENvZGVNaXJyb3IpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgdmFyIG5vT3B0aW9ucyA9IHt9O1xuICB2YXIgbm9uV1MgPSAvW15cXHNcXHUwMGEwXS87XG4gIHZhciBQb3MgPSBDb2RlTWlycm9yLlBvcztcblxuICBmdW5jdGlvbiBmaXJzdE5vbldTKHN0cikge1xuICAgIHZhciBmb3VuZCA9IHN0ci5zZWFyY2gobm9uV1MpO1xuICAgIHJldHVybiBmb3VuZCA9PSAtMSA/IDAgOiBmb3VuZDtcbiAgfVxuXG4gIENvZGVNaXJyb3IuY29tbWFuZHMudG9nZ2xlQ29tbWVudCA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgY20udG9nZ2xlQ29tbWVudCgpO1xuICB9O1xuXG4gIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uKFwidG9nZ2xlQ29tbWVudFwiLCBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0gbm9PcHRpb25zO1xuICAgIHZhciBjbSA9IHRoaXM7XG4gICAgdmFyIG1pbkxpbmUgPSBJbmZpbml0eSwgcmFuZ2VzID0gdGhpcy5saXN0U2VsZWN0aW9ucygpLCBtb2RlID0gbnVsbDtcbiAgICBmb3IgKHZhciBpID0gcmFuZ2VzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2Y
23459XIgZnJvbSA9IHJhbmdlc1tpXS5mcm9tKCksIHRvID0gcmFuZ2VzW2ldLnRvKCk7XG4gICAgICBpZiAoZnJvbS5saW5lID49IG1pbkxpbmUpIGNvbnRpbnVlO1xuICAgICAgaWYgKHRvLmxpbmUgPj0gbWluTGluZSkgdG8gPSBQb3MobWluTGluZSwgMCk7XG4gICAgICBtaW5MaW5lID0gZnJvbS5saW5lO1xuICAgICAgaWYgKG1vZGUgPT0gbnVsbCkge1xuICAgICAgICBpZiAoY20udW5jb21tZW50KGZyb20sIHRvLCBvcHRpb25zKSkgbW9kZSA9IFwidW5cIjtcbiAgICAgICAgZWxzZSB7IGNtLmxpbmVDb21tZW50KGZyb20sIHRvLCBvcHRpb25zKTsgbW9kZSA9IFwibGluZVwiOyB9XG4gICAgICB9IGVsc2UgaWYgKG1vZGUgPT0gXCJ1blwiKSB7XG4gICAgICAgIGNtLnVuY29tbWVudChmcm9tLCB0bywgb3B0aW9ucyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjbS5saW5lQ29tbWVudChmcm9tLCB0bywgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbihcImxpbmVDb21tZW50XCIsIGZ1bmN0aW9uKGZyb20sIHRvLCBvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0gbm9PcHRpb25zO1xuICAgIHZhciBzZWxmID0gdGhpcywgbW9kZSA9IHNlbGYuZ2V0TW9kZUF0KGZyb20pO1xuICAgIHZhciBjb21tZW50U3RyaW5nID0gb3B0aW9ucy5saW5lQ29tbWVudCB8fCBtb2RlLmxpbmVDb21tZW50O1xuICAgIGlmICghY29tbWVudFN0cmluZykge1xuICAgICAgaWYgKG9wdGlvbnMuYmxvY2tDb21tZW50U3RhcnQgfHwgbW9kZS5ibG9ja0NvbW1lbnRTdGFydCkge1xuICAgICAgICBvcHRpb25zLmZ1bGxMaW5lcyA9IHRydWU7XG4gICAgICAgIHNlbGYuYmxvY2tDb21tZW50KGZyb20sIHRvLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGZpcnN0TGluZSA9IHNlbGYuZ2V0TGluZShmcm9tLmxpbmUpO1xuICAgIGlmIChmaXJzdExpbmUgPT0gbnVsbCkgcmV0dXJuO1xuICAgIHZhciBlbmQgPSBNYXRoLm1pbih0by5jaCAhPSAwIHx8IHRvLmxpbmUgPT0gZnJvbS5saW5lID8gdG8ubGluZSArIDEgOiB0by5saW5lLCBzZWxmLmxhc3RMaW5lKCkgKyAxKTtcbiAgICB2YXIgcGFkID0gb3B0aW9ucy5wYWRkaW5nID09IG51bGwgPyBcIiBcIiA6IG9wdGlvbnMucGFkZGluZztcbiAgICB2YXIgYmxhbmtMaW5lcyA9IG9wdGlvbnMuY29tbWVudEJsYW5rTGluZXMgfHwgZnJvbS5saW5lID09IHRvLmxpbmU7XG5cbiAgICBzZWxmLm9wZXJhdGlvbihmdW5jdGlvbigpIHtcbiAgICAgIGlmIChvcHRpb25zLmluZGVudCkge1xuICAgICAgICB2Y
23459XIgYmFzZVN0cmluZyA9IG51bGw7XG4gICAgICAgIGZvciAodmFyIGkgPSBmcm9tLmxpbmU7IGkgPCBlbmQ7ICsraSkge1xuICAgICAgICAgIHZhciBsaW5lID0gc2VsZi5nZXRMaW5lKGkpO1xuICAgICAgICAgIHZhciB3aGl0ZXNwYWNlID0gbGluZS5zbGljZSgwLCBmaXJzdE5vbldTKGxpbmUpKTtcbiAgICAgICAgICBpZiAoYmFzZVN0cmluZyA9PSBudWxsIHx8IGJhc2VTdHJpbmcubGVuZ3RoID4gd2hpdGVzcGFjZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGJhc2VTdHJpbmcgPSB3aGl0ZXNwYWNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBpID0gZnJvbS5saW5lOyBpIDwgZW5kOyArK2kpIHtcbiAgICAgICAgICB2YXIgbGluZSA9IHNlbGYuZ2V0TGluZShpKSwgY3V0ID0gYmFzZVN0cmluZy5sZW5ndGg7XG4gICAgICAgICAgaWYgKCFibGFua0xpbmVzICYmICFub25XUy50ZXN0KGxpbmUpKSBjb250aW51ZTtcbiAgICAgICAgICBpZiAobGluZS5zbGljZSgwLCBjdXQpICE9IGJhc2VTdHJpbmcpIGN1dCA9IGZpcnN0Tm9uV1MobGluZSk7XG4gICAgICAgICAgc2VsZi5yZXBsYWNlUmFuZ2UoYmFzZVN0cmluZyArIGNvbW1lbnRTdHJpbmcgKyBwYWQsIFBvcyhpLCAwKSwgUG9zKGksIGN1dCkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBpID0gZnJvbS5saW5lOyBpIDwgZW5kOyArK2kpIHtcbiAgICAgICAgICBpZiAoYmxhbmtMaW5lcyB8fCBub25XUy50ZXN0KHNlbGYuZ2V0TGluZShpKSkpXG4gICAgICAgICAgICBzZWxmLnJlcGxhY2VSYW5nZShjb21tZW50U3RyaW5nICsgcGFkLCBQb3MoaSwgMCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uKFwiYmxvY2tDb21tZW50XCIsIGZ1bmN0aW9uKGZyb20sIHRvLCBvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0gbm9PcHRpb25zO1xuICAgIHZhciBzZWxmID0gdGhpcywgbW9kZSA9IHNlbGYuZ2V0TW9kZUF0KGZyb20pO1xuICAgIHZhciBzdGFydFN0cmluZyA9IG9wdGlvbnMuYmxvY2tDb21tZW50U3RhcnQgfHwgbW9kZS5ibG9ja0NvbW1lbnRTdGFydDtcbiAgICB2YXIgZW5kU3RyaW5nID0gb3B0aW9ucy5ibG9ja0NvbW1lbnRFbmQgfHwgbW9kZS5ibG9ja0NvbW1lbnRFbmQ7XG4gICAgaWYgKCFzdGFydFN0cmluZyB8fCAhZW5kU3RyaW5nKSB7XG4gICAgICBpZiAoKG9wdGlvbnMubGluZUNvbW1lbnQgfHwgbW9kZS5saW5lQ29tbWVudCkgJiYgb3B0aW9ucy5mdWxsTGluZXMgIT0gZmFsc2UpXG4gICAgICAgIHNlbGYubGluZUNvbW1lbnQoZnJvbSwgdG8sIG9wdGlvbnMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBlbmQgPSBNYXRoLm1pbih0by5saW5lLCBzZWxmLmxhc3RMaW5lKCkpO1xuICAgIGlmIChlbmQgIT0gZnJvbS5saW5lICYmIHRvLmNoID09IDAgJiYgbm9uV1MudGVzdChzZWxmLmdldExpbmUoZW5kKSkpIC0tZW5kO1xuXG4gICAgdmFyIHBhZCA9IG9wdGlvbnMucGFkZGluZyA9PSBudWxsID8gXCIgXCIgOiBvcHRpb25zLnBhZGRpbmc7XG4gICAgaWYgKGZyb20ubGluZSA+IGVuZCkgcmV0dXJuO1xuXG4gICAgc2VsZi5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICBpZiAob3B0aW9ucy5mdWxsTGluZXMgIT0gZmFsc2UpIHtcbiAgICAgICAgdmFyIGxhc3RMaW5lSGFzVGV4dCA9IG5vbldTLnRlc3Qoc2VsZi5nZXRMaW5lKGVuZCkpO1xuICAgICAgICBzZWxmLnJlcGxhY2VSYW5nZShwYWQgKyBlbmRTdHJpbmcsIFBvcyhlbmQpKTtcbiAgICAgICAgc2VsZi5yZXBsYWNlUmFuZ2Uoc3RhcnRTdHJpbmcgKyBwYWQsIFBvcyhmcm9tLmxpbmUsIDApKTtcbiAgICAgICAgdmFyIGxlYWQgPSBvcHRpb25zLmJsb2NrQ29tbWVudExlYWQgfHwgbW9kZS5ibG9ja0NvbW1lbnRMZWFkO1xuICAgICAgICBpZiAobGVhZCAhPSBudWxsKSBmb3IgKHZhciBpID0gZnJvbS5saW5lICsgMTsgaSA8PSBlbmQ7ICsraSlcbiAgICAgICAgICBpZiAoaSAhPSBlbmQgfHwgbGFzdExpbmVIYXNUZXh0KVxuICAgICAgICAgICAgc2VsZi5yZXBsYWNlUmFuZ2UobGVhZCArIHBhZCwgUG9zKGksIDApKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlbGYucmVwbGFjZVJhbmdlKGVuZFN0cmluZywgdG8pO1xuICAgICAgICBzZWxmLnJlcGxhY2VSYW5nZShzdGFydFN0cmluZywgZnJvbSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uKFwidW5jb21tZW50XCIsIGZ1bmN0aW9uKGZyb20sIHRvLCBvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0gbm9PcHRpb25zO1xuICAgIHZhciBzZWxmID0gdGhpcywgbW9kZSA9IHNlbGYuZ2V0TW9kZUF0KGZyb20pO1xuICAgIHZhciBlbmQgPSBNYXRoLm1pbih0by5jaCAhPSAwIHx8IHRvLmxpbmUgPT0gZnJvbS5saW5lID8gdG8ubGluZSA6IHRvLmxpbmUgLSAxLCBzZWxmLmxhc3RMaW5lKCkpLCBzdGFydCA9IE1hdGgubWluKGZyb20ubGluZSwgZW5kKTtcblxuICAgIC8vIFRyeSBmaW5kaW5nIGxpbmUgY29tbWVudHNcbiAgICB2YXIgbGluZVN0cmluZyA9IG9wdGlvbnMubGluZUNvbW1lbnQgfHwgbW9kZS5saW5lQ29tbWVudCwgbGluZXMgPSBbXTtcbiAgICB2YXIgcGFkID0gb3B0aW9ucy5wYWRkaW5nID09IG51bGwgPyBcIiBcIiA6IG9wdGlvbnMucGFkZGluZywgZGlkU29tZXRoaW5nO1xuICAgIGxpbmVDb21tZW50OiB7XG4gICAgICBpZiAoIWxpbmVTdHJpbmcpIGJyZWFrIGxpbmVDb21tZW50O1xuICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDw9IGVuZDsgKytpKSB7XG4gICAgICAgIHZhciBsaW5lID0gc2VsZi5nZXRMaW5lKGkpO1xuICAgICAgICB2Y
23459XIgZm91bmQgPSBsaW5lLmluZGV4T2YobGluZVN0cmluZyk7XG4gICAgICAgIGlmIChmb3VuZCA+IC0xICYmICEvY29tbWVudC8udGVzdChzZWxmLmdldFRva2VuVHlwZUF0KFBvcyhpLCBmb3VuZCArIDEpKSkpIGZvdW5kID0gLTE7XG4gICAgICAgIGlmIChmb3VuZCA9PSAtMSAmJiAoaSAhPSBlbmQgfHwgaSA9PSBzdGFydCkgJiYgbm9uV1MudGVzdChsaW5lKSkgYnJlYWsgbGluZUNvbW1lbnQ7XG4gICAgICAgIGlmIChmb3VuZCA+IC0xICYmIG5vbldTLnRlc3QobGluZS5zbGljZSgwLCBmb3VuZCkpKSBicmVhayBsaW5lQ29tbWVudDtcbiAgICAgICAgbGluZXMucHVzaChsaW5lKTtcbiAgICAgIH1cbiAgICAgIHNlbGYub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgICAgICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPD0gZW5kOyArK2kpIHtcbiAgICAgICAgICB2YXIgbGluZSA9IGxpbmVzW2kgLSBzdGFydF07XG4gICAgICAgICAgdmFyIHBvcyA9IGxpbmUuaW5kZXhPZihsaW5lU3RyaW5nKSwgZW5kUG9zID0gcG9zICsgbGluZVN0cmluZy5sZW5ndGg7XG4gICAgICAgICAgaWYgKHBvcyA8IDApIGNvbnRpbnVlO1xuICAgICAgICAgIGlmIChsaW5lLnNsaWNlKGVuZFBvcywgZW5kUG9zICsgcGFkLmxlbmd0aCkgPT0gcGFkKSBlbmRQb3MgKz0gcGFkLmxlbmd0aDtcbiAgICAgICAgICBkaWRTb21ldGhpbmcgPSB0cnVlO1xuICAgICAgICAgIHNlbGYucmVwbGFjZVJhbmdlKFwiXCIsIFBvcyhpLCBwb3MpLCBQb3MoaSwgZW5kUG9zKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKGRpZFNvbWV0aGluZykgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gVHJ5IGJsb2NrIGNvbW1lbnRzXG4gICAgdmFyIHN0YXJ0U3RyaW5nID0gb3B0aW9ucy5ibG9ja0NvbW1lbnRTdGFydCB8fCBtb2RlLmJsb2NrQ29tbWVudFN0YXJ0O1xuICAgIHZhciBlbmRTdHJpbmcgPSBvcHRpb25zLmJsb2NrQ29tbWVudEVuZCB8fCBtb2RlLmJsb2NrQ29tbWVudEVuZDtcbiAgICBpZiAoIXN0YXJ0U3RyaW5nIHx8ICFlbmRTdHJpbmcpIHJldHVybiBmYWxzZTtcbiAgICB2YXIgbGVhZCA9IG9wdGlvbnMuYmxvY2tDb21tZW50TGVhZCB8fCBtb2RlLmJsb2NrQ29tbWVudExlYWQ7XG4gICAgdmFyIHN0YXJ0TGluZSA9IHNlbGYuZ2V0TGluZShzdGFydCksIGVuZExpbmUgPSBlbmQgPT0gc3RhcnQgPyBzdGFydExpbmUgOiBzZWxmLmdldExpbmUoZW5kKTtcbiAgICB2YXIgb3BlbiA9IHN0YXJ0TGluZS5pbmRleE9mKHN0YXJ0U3RyaW5nKSwgY2xvc2UgPSBlbmRMaW5lLmxhc3RJbmRleE9mKGVuZFN0cmluZyk7XG4gICAgaWYgKGNsb3NlID09IC0xICYmIHN0YXJ0ICE9IGVuZCkge1xuICAgICAgZW5kTGluZSA9IHNlbGYuZ2V0TGluZSgtLWVuZCk7XG4gICAgICBjbG9zZSA9IGVuZExpbmUubGFzdEluZGV4T2YoZW5kU3RyaW5nKTtcbiAgICB9XG4gICAgaWYgKG9wZW4gPT0gLTEgfHwgY2xvc2UgPT0gLTEgfHxcbiAgICAgICAgIS9jb21tZW50Ly50ZXN0KHNlbGYuZ2V0VG9rZW5UeXBlQXQoUG9zKHN0YXJ0LCBvcGVuICsgMSkpKSB8fFxuICAgICAgICAhL2NvbW1lbnQvLnRlc3Qoc2VsZi5nZXRUb2tlblR5cGVBdChQb3MoZW5kLCBjbG9zZSArIDEpKSkpXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBBdm9pZCBraWxsaW5nIGJsb2NrIGNvbW1lbnRzIGNvbXBsZXRlbHkgb3V0c2lkZSB0aGUgc2VsZWN0aW9uLlxuICAgIC8vIFBvc2l0aW9ucyBvZiB0aGUgbGFzdCBzdGFydFN0cmluZyBiZWZvcmUgdGhlIHN0YXJ0IG9mIHRoZSBzZWxlY3Rpb24sIGFuZCB0aGUgZmlyc3QgZW5kU3RyaW5nIGFmdGVyIGl0LlxuICAgIHZhciBsYXN0U3RhcnQgPSBzdGFydExpbmUubGFzdEluZGV4T2Yoc3RhcnRTdHJpbmcsIGZyb20uY2gpO1xuICAgIHZhciBmaXJzdEVuZCA9IGxhc3RTdGFydCA9PSAtMSA/IC0xIDogc3RhcnRMaW5lLnNsaWNlKDAsIGZyb20uY2gpLmluZGV4T2YoZW5kU3RyaW5nLCBsYXN0U3RhcnQgKyBzdGFydFN0cmluZy5sZW5ndGgpO1xuICAgIGlmIChsYXN0U3RhcnQgIT0gLTEgJiYgZmlyc3RFbmQgIT0gLTEgJiYgZmlyc3RFbmQgKyBlbmRTdHJpbmcubGVuZ3RoICE9IGZyb20uY2gpIHJldHVybiBmYWxzZTtcbiAgICAvLyBQb3NpdGlvbnMgb2YgdGhlIGZpcnN0IGVuZFN0cmluZyBhZnRlciB0aGUgZW5kIG9mIHRoZSBzZWxlY3Rpb24sIGFuZCB0aGUgbGFzdCBzdGFydFN0cmluZyBiZWZvcmUgaXQuXG4gICAgZmlyc3RFbmQgPSBlbmRMaW5lLmluZGV4T2YoZW5kU3RyaW5nLCB0by5jaCk7XG4gICAgdmFyIGFsbW9zdExhc3RTdGFydCA9IGVuZExpbmUuc2xpY2UodG8uY2gpLmxhc3RJbmRleE9mKHN0YXJ0U3RyaW5nLCBmaXJzdEVuZCAtIHRvLmNoKTtcbiAgICBsYXN0U3RhcnQgPSAoZmlyc3RFbmQgPT0gLTEgfHwgYWxtb3N0TGFzdFN0YXJ0ID09IC0xKSA/IC0xIDogdG8uY2ggKyBhbG1vc3RMYXN0U3RhcnQ7XG4gICAgaWYgKGZpcnN0RW5kICE9IC0xICYmIGxhc3RTdGFydCAhPSAtMSAmJiBsYXN0U3RhcnQgIT0gdG8uY2gpIHJldHVybiBmYWxzZTtcblxuICAgIHNlbGYub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgICAgc2VsZi5yZXBsYWNlUmFuZ2UoXCJcIiwgUG9zKGVuZCwgY2xvc2UgLSAocGFkICYmIGVuZExpbmUuc2xpY2UoY2xvc2UgLSBwYWQubGVuZ3RoLCBjbG9zZSkgPT0gcGFkID8gcGFkLmxlbmd0aCA6IDApKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFBvcyhlbmQsIGNsb3NlICsgZW5kU3RyaW5nLmxlbmd0aCkpO1xuICAgICAgdmFyIG9wZW5FbmQgPSBvcGVuICsgc3RhcnRTdHJpbmcubGVuZ3RoO1xuICAgICAgaWYgKHBhZCAmJiBzdGFydExpbmUuc2xpY2Uob3BlbkVuZCwgb3BlbkVuZCArIHBhZC5sZW5ndGgpID09IHBhZCkgb3BlbkVuZCArPSBwYWQubGVuZ3RoO1xuICAgICAgc2VsZi5yZXBsYWNlUmFuZ2UoXCJcIiwgUG9zKHN0YXJ0LCBvcGVuKSwgUG9zKHN0YXJ0LCBvcGVuRW5kKSk7XG4gICAgICBpZiAobGVhZCkgZm9yICh2YXIgaSA9IHN0YXJ0ICsgMTsgaSA8PSBlbmQ7ICsraSkge1xuICAgICAgICB2Y
23459XIgbGluZSA9IHNlbGYuZ2V0TGluZShpKSwgZm91bmQgPSBsaW5lLmluZGV4T2YobGVhZCk7XG4gICAgICAgIGlmIChmb3VuZCA9PSAtMSB8fCBub25XUy50ZXN0KGxpbmUuc2xpY2UoMCwgZm91bmQpKSkgY29udGludWU7XG4gICAgICAgIHZhciBmb3VuZEVuZCA9IGZvdW5kICsgbGVhZC5sZW5ndGg7XG4gICAgICAgIGlmIChwYWQgJiYgbGluZS5zbGljZShmb3VuZEVuZCwgZm91bmRFbmQgKyBwYWQubGVuZ3RoKSA9PSBwYWQpIGZvdW5kRW5kICs9IHBhZC5sZW5ndGg7XG4gICAgICAgIHNlbGYucmVwbGFjZVJhbmdlKFwiXCIsIFBvcyhpLCBmb3VuZCksIFBvcyhpLCBmb3VuZEVuZCkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0cnVlO1xuICB9KTtcbn0pO1xuIiwiLy8gQ29kZU1pcnJvciwgY29weXJpZ2h0IChjKSBieSBNYXJpam4gSGF2ZXJiZWtlIGFuZCBvdGhlcnNcbi8vIERpc3RyaWJ1dGVkIHVuZGVyIGFuIE1JVCBsaWNlbnNlOiBodHRwOi8vY29kZW1pcnJvci5uZXQvTElDRU5TRVxuXG4vLyBPcGVuIHNpbXBsZSBkaWFsb2dzIG9uIHRvcCBvZiBhbiBlZGl0b3IuIFJlbGllcyBvbiBkaWFsb2cuY3NzLlxuXG4oZnVuY3Rpb24obW9kKSB7XG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUgPT0gXCJvYmplY3RcIikgLy8gQ29tbW9uSlNcbiAgICBtb2QocmVxdWlyZShcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCJdLCBtb2QpO1xuICBlbHNlIC8vIFBsYWluIGJyb3dzZXIgZW52XG4gICAgbW9kKENvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24oQ29kZU1pcnJvcikge1xuICBmdW5jdGlvbiBkaWFsb2dEaXYoY20sIHRlbXBsYXRlLCBib3R0b20pIHtcbiAgICB2YXIgd3JhcCA9IGNtLmdldFdyYXBwZXJFbGVtZW50KCk7XG4gICAgdmFyIGRpYWxvZztcbiAgICBkaWFsb2cgPSB3cmFwLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIikpO1xuICAgIGlmIChib3R0b20pXG4gICAgICBkaWFsb2cuY2xhc3NOYW1lID0gXCJDb2RlTWlycm9yLWRpYWxvZyBDb2RlTWlycm9yLWRpYWxvZy1ib3R0b21cIjtcbiAgICBlbHNlXG4gICAgICBkaWFsb2cuY2xhc3NOYW1lID0gXCJDb2RlTWlycm9yLWRpYWxvZyBDb2RlTWlycm9yLWRpYWxvZy10b3BcIjtcblxuICAgIGlmICh0eXBlb2YgdGVtcGxhdGUgPT0gXCJzdHJpbmdcIikge1xuICAgICAgZGlhbG9nLmlubmVySFRNTCA9IHRlbXBsYXRlO1xuICAgIH0gZWxzZSB7IC8vIEFzc3VtaW5nIGl0J3MgYSBkZXRhY2hlZCBET00gZWxlbWVudC5cbiAgICAgIGRpYWxvZy5hcHBlbmRDaGlsZCh0ZW1wbGF0ZSk7XG4gICAgfVxuICAgIHJldHVybiBkaWFsb2c7XG4gIH1cblxuICBmdW5jdGlvbiBjbG9zZU5vdGlmaWNhdGlvbihjbSwgbmV3VmFsKSB7XG4gICAgaWYgKGNtLnN0YXRlLmN1cnJlbnROb3RpZmljYXRpb25DbG9zZSlcbiAgICAgIGNtLnN0YXRlLmN1cnJlbnROb3RpZmljYXRpb25DbG9zZSgpO1xuICAgIGNtLnN0YXRlLmN1cnJlbnROb3RpZmljYXRpb25DbG9zZSA9IG5ld1ZhbDtcbiAgfVxuXG4gIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uKFwib3BlbkRpYWxvZ1wiLCBmdW5jdGlvbih0ZW1wbGF0ZSwgY2FsbGJhY2ssIG9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcblxuICAgIGNsb3NlTm90aWZpY2F0aW9uKHRoaXMsIG51bGwpO1xuXG4gICAgdmFyIGRpYWxvZyA9IGRpYWxvZ0Rpdih0aGlzLCB0ZW1wbGF0ZSwgb3B0aW9ucy5ib3R0b20pO1xuICAgIHZhciBjbG9zZWQgPSBmYWxzZSwgbWUgPSB0aGlzO1xuICAgIGZ1bmN0aW9uIGNsb3NlKG5ld1ZhbCkge1xuICAgICAgaWYgKHR5cGVvZiBuZXdWYWwgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgaW5wLnZhbHVlID0gbmV3VmFsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGNsb3NlZCkgcmV0dXJuO1xuICAgICAgICBjbG9zZWQgPSB0cnVlO1xuICAgICAgICBkaWFsb2cucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChkaWFsb2cpO1xuICAgICAgICBtZS5mb2N1cygpO1xuXG4gICAgICAgIGlmIChvcHRpb25zLm9uQ2xvc2UpIG9wdGlvbnMub25DbG9zZShkaWFsb2cpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBpbnAgPSBkaWFsb2cuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJpbnB1dFwiKVswXSwgYnV0dG9uO1xuICAgIGlmIChpbnApIHtcbiAgICAgIGlmIChvcHRpb25zLnZhbHVlKSB7XG4gICAgICAgIGlucC52YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgICAgIGlmIChvcHRpb25zLnNlbGVjdFZhbHVlT25PcGVuICE9PSBmYWxzZSkge1xuICAgICAgICAgIGlucC5zZWxlY3QoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy5vbklucHV0KVxuICAgICAgICBDb2RlTWlycm9yLm9uKGlucCwgXCJpbnB1dFwiLCBmdW5jdGlvbihlKSB7IG9wdGlvbnMub25JbnB1dChlLCBpbnAudmFsdWUsIGNsb3NlKTt9KTtcbiAgICAgIGlmIChvcHRpb25zLm9uS2V5VXApXG4gICAgICAgIENvZGVNaXJyb3Iub24oaW5wLCBcImtleXVwXCIsIGZ1bmN0aW9uKGUpIHtvcHRpb25zLm9uS2V5VXAoZSwgaW5wLnZhbHVlLCBjbG9zZSk7fSk7XG5cbiAgICAgIENvZGVNaXJyb3Iub24oaW5wLCBcImtleWRvd25cIiwgZnVuY3Rpb24oZSkge1xuICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLm9uS2V5RG93biAmJiBvcHRpb25zLm9uS2V5RG93bihlLCBpbnAudmFsdWUsIGNsb3NlKSkgeyByZXR1cm47IH1cbiAgICAgICAgaWYgKGUua2V5Q29kZSA9PSAyNyB8fCAob3B0aW9ucy5jbG9zZU9uRW50ZXIgIT09IGZhbHNlICYmIGUua2V5Q29kZSA9PSAxMykpIHtcbiAgICAgICAgICBpbnAuYmx1cigpO1xuICAgICAgICAgIENvZGVNaXJyb3IuZV9zdG9wKGUpO1xuICAgICAgICAgIGNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGUua2V5Q29kZSA9PSAxMykgY2FsbGJhY2soaW5wLnZhbHVlLCBlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAob3B0aW9ucy5jbG9zZU9uQmx1ciAhPT0gZmFsc2UpIENvZGVNaXJyb3Iub24oaW5wLCBcImJsdXJcIiwgY2xvc2UpO1xuXG4gICAgICBpbnAuZm9jdXMoKTtcbiAgICB9IGVsc2UgaWYgKGJ1dHRvbiA9IGRpYWxvZy5nZXRFbGVtZW50c0J5VGFnTmFtZShcImJ1dHRvblwiKVswXSkge1xuICAgICAgQ29kZU1pcnJvci5vbihidXR0b24sIFwiY2xpY2tcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgIGNsb3NlKCk7XG4gICAgICAgIG1lLmZvY3VzKCk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKG9wdGlvbnMuY2xvc2VPbkJsdXIgIT09IGZhbHNlKSBDb2RlTWlycm9yLm9uKGJ1dHRvbiwgXCJibHVyXCIsIGNsb3NlKTtcblxuICAgICAgYnV0dG9uLmZvY3VzKCk7XG4gICAgfVxuICAgIHJldHVybi
23459BjbG9zZTtcbiAgfSk7XG5cbiAgQ29kZU1pcnJvci5kZWZpbmVFeHRlbnNpb24oXCJvcGVuQ29uZmlybVwiLCBmdW5jdGlvbih0ZW1wbGF0ZSwgY2FsbGJhY2tzLCBvcHRpb25zKSB7XG4gICAgY2xvc2VOb3RpZmljYXRpb24odGhpcywgbnVsbCk7XG4gICAgdmFyIGRpYWxvZyA9IGRpYWxvZ0Rpdih0aGlzLCB0ZW1wbGF0ZSwgb3B0aW9ucyAmJiBvcHRpb25zLmJvdHRvbSk7XG4gICAgdmFyIGJ1dHRvbnMgPSBkaWFsb2cuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJidXR0b25cIik7XG4gICAgdmFyIGNsb3NlZCA9IGZhbHNlLCBtZSA9IHRoaXMsIGJsdXJyaW5nID0gMTtcbiAgICBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICAgIGlmIChjbG9zZWQpIHJldHVybjtcbiAgICAgIGNsb3NlZCA9IHRydWU7XG4gICAgICBkaWFsb2cucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChkaWFsb2cpO1xuICAgICAgbWUuZm9jdXMoKTtcbiAgICB9XG4gICAgYnV0dG9uc1swXS5mb2N1cygpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYnV0dG9ucy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIGIgPSBidXR0b25zW2ldO1xuICAgICAgKGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gICAgICAgIENvZGVNaXJyb3Iub24oYiwgXCJjbGlja1wiLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgQ29kZU1pcnJvci5lX3ByZXZlbnREZWZhdWx0KGUpO1xuICAgICAgICAgIGNsb3NlKCk7XG4gICAgICAgICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjayhtZSk7XG4gICAgICAgIH0pO1xuICAgICAgfSkoY2FsbGJhY2tzW2ldKTtcbiAgICAgIENvZGVNaXJyb3Iub24oYiwgXCJibHVyXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICAtLWJsdXJyaW5nO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBpZiAoYmx1cnJpbmcgPD0gMCkgY2xvc2UoKTsgfSwgMjAwKTtcbiAgICAgIH0pO1xuICAgICAgQ29kZU1pcnJvci5vbihiLCBcImZvY3VzXCIsIGZ1bmN0aW9uKCkgeyArK2JsdXJyaW5nOyB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qXG4gICAqIG9wZW5Ob3RpZmljYXRpb25cbiAgICogT3BlbnMgYSBub3RpZmljYXRpb24sIHRoYXQgY2FuIGJlIGNsb3NlZCB3aXRoIGFuIG9wdGlvbmFsIHRpbWVyXG4gICAqIChkZWZhdWx0IDUwMDBtcyB0aW1lcikgYW5kIGFsd2F5cyBjbG9zZXMgb24gY2xpY2suXG4gICAqXG4gICAqIElmIGEgbm90aWZpY2F0aW9uIGlzIG9wZW5lZCB3aGlsZSBhbm90aGVyIGlzIG9wZW5lZCwgaXQgd2lsbCBjbG9zZSB0aGVcbiAgICogY3VycmVudGx5IG9wZW5lZCBvbmUgYW5kIG9wZW4gdGhlIG5ldyBvbmUgaW1tZWRpYXRlbHkuXG4gICAqL1xuICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbihcIm9wZW5Ob3RpZmljYXRpb25cIiwgZnVuY3Rpb24odGVtcGxhdGUsIG9wdGlvbnMpIHtcbiAgICBjbG9zZU5vdGlmaWNhdGlvbih0aGlzLCBjbG9zZSk7XG4gICAgdmFyIGRpYWxvZyA9IGRpYWxvZ0Rpdih0aGlzLCB0ZW1wbGF0ZSwgb3B0aW9ucyAmJiBvcHRpb25zLmJvdHRvbSk7XG4gICAgdmFyIGNsb3NlZCA9IGZhbHNlLCBkb25lVGltZXI7XG4gICAgdmFyIGR1cmF0aW9uID0gb3B0aW9ucyAmJiB0eXBlb2Ygb3B0aW9ucy5kdXJhdGlvbiAhPT0gXCJ1bmRlZmluZWRcIiA/IG9wdGlvbnMuZHVyYXRpb24gOiA1MDAwO1xuXG4gICAgZnVuY3Rpb24gY2xvc2UoKSB7XG4gICAgICBpZiAoY2xvc2VkKSByZXR1cm47XG4gICAgICBjbG9zZWQgPSB0cnVlO1xuICAgICAgY2xlYXJUaW1lb3V0KGRvbmVUaW1lcik7XG4gICAgICBkaWFsb2cucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChkaWFsb2cpO1xuICAgIH1cblxuICAgIENvZGVNaXJyb3Iub24oZGlhbG9nLCAnY2xpY2snLCBmdW5jdGlvbihlKSB7XG4gICAgICBDb2RlTWlycm9yLmVfcHJldmVudERlZmF1bHQoZSk7XG4gICAgICBjbG9zZSgpO1xuICAgIH0pO1xuXG4gICAgaWYgKGR1cmF0aW9uKVxuICAgICAgZG9uZVRpbWVyID0gc2V0VGltZW91dChjbG9zZSwgZHVyYXRpb24pO1xuXG4gICAgcmV0dXJuIGNsb3NlO1xuICB9KTtcbn0pO1xuIiwiLy8gQ29kZU1pcnJvciwgY29weXJpZ2h0IChjKSBieSBNYXJpam4gSGF2ZXJiZWtlIGFuZCBvdGhlcnNcbi8vIERpc3RyaWJ1dGVkIHVuZGVyIGFuIE1JVCBsaWNlbnNlOiBodHRwOi8vY29kZW1pcnJvci5uZXQvTElDRU5TRVxuXG4oZnVuY3Rpb24obW9kKSB7XG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUgPT0gXCJvYmplY3RcIikgLy8gQ29tbW9uSlNcbiAgICBtb2QocmVxdWlyZShcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCJdLCBtb2QpO1xuICBlbHNlIC8vIFBsYWluIGJyb3dzZXIgZW52XG4gICAgbW9kKENvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24oQ29kZU1pcnJvcikge1xuICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbihcImFkZFBhbmVsXCIsIGZ1bmN0aW9uKG5vZGUsIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgIGlmICghdGhpcy5zdGF0ZS5wYW5lbHMpIGluaXRQYW5lbHModGhpcyk7XG5cbiAgICB2YXIgaW5mbyA9IHRoaXMuc3RhdGUucGFuZWxzO1xuICAgIHZhciB3cmFwcGVyID0gaW5mby53cmFwcGVyO1xuICAgIHZhciBjbVdyYXBwZXIgPSB0aGlzLmdldFdyYXBwZXJFbGVtZW50KCk7XG5cbiAgICBpZiAob3B0aW9ucy5hZnRlciBpbnN0YW5jZW9mIFBhbmVsICYmICFvcHRpb25zLmFmdGVyLmNsZWFyZWQpIHtcbiAgICAgIHdyYXBwZXIuaW5zZXJ0QmVmb3JlKG5vZGUsIG9wdGlvbnMuYmVmb3JlLm5vZGUubmV4dFNpYmxpbmcpO1xuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5iZWZvcmUgaW5zdGFuY2VvZiBQYW5lbCAmJiAhb3B0aW9ucy5iZWZvcmUuY2xlYXJlZCkge1xuICAgICAgd3JhcHBlci5pbnNlcnRCZWZvcmUobm9kZSwgb3B0aW9ucy5iZWZvcmUubm9kZSk7XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLnJlcGxhY2UgaW5zdGFuY2VvZiBQYW5lbCAmJiAhb3B0aW9ucy5yZXBsYWNlLmNsZWFyZWQpIHtcbiAgICAgIHdyYXBwZXIuaW5zZXJ0QmVmb3JlKG5vZGUsIG9wdGlvbnMucmVwbGFjZS5ub2RlKTtcbiAgICAgIG9wdGlvbnMucmVwbGFjZS5jbGVhcigpO1xuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5wb3NpdGlvbiA9PSBcImJvdHRvbVwiKSB7XG4gICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5wb3NpdGlvbiA9PSBcImJlZm9yZS1ib3R0b21cIikge1xuICAgICAgd3JhcHBlci5pbnNlcnRCZWZvcmUobm9kZSwgY21XcmFwcGVyLm5leHRTaWJsaW5nKTtcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMucG9zaXRpb24gPT0gXCJhZnRlci10b3BcIikge1xuICAgICAgd3JhcHBlci5pbnNlcnRCZWZvcmUobm9kZSwgY21XcmFwcGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd3JhcHBlci5pbnNlcnRCZWZvcmUobm9kZSwgd3JhcHBlci5maXJzdENoaWxkKTtcbiAgICB9XG5cbiAgICB2YXIgaGVpZ2h0ID0gKG9wdGlvbnMgJiYgb3B0aW9ucy5oZWlnaHQpIHx8IG5vZGUub2Zmc2V0SGVpZ2h0O1xuICAgIHRoaXMuX3NldFNpemUobnVsbCwgaW5mby5oZWlnaHRMZWZ0IC09IGhlaWdodCk7XG4gICAgaW5mby5wYW5lbHMrKztcbiAgICByZXR1cm4gbmV3IFBhbmVsKHRoaXMsIG5vZGUsIG9wdGlvbnMsIGhlaWdodCk7XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIFBhbmVsKGNtLCBub2RlLCBvcHRpb25zLCBoZWlnaHQpIHtcbiAgICB0aGlzLmNtID0gY207XG4gICAgdGhpcy5ub2RlID0gbm9kZTtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIHRoaXMuY2xlYXJlZCA9IGZhbHNlO1xuICB9XG5cbiAgUGFuZWwucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuY2xlYXJlZCkgcmV0dXJuO1xuICAgIHRoaXMuY2xlYXJlZCA9IHRydWU7XG4gICAgdmFyIGluZm8gPSB0aGlzLmNtLnN0YXRlLnBhbmVscztcbiAgICB0aGlzLmNtLl9zZXRTaXplKG51bGwsIGluZm8uaGVpZ2h0TGVmdCArPSB0aGlzLmhlaWdodCk7XG4gICAgaW5mby53cmFwcGVyLnJlbW92ZUNoaWxkKHRoaXMubm9kZSk7XG4gICAgaWYgKC0taW5mby5wYW5lbHMgPT0gMCkgcmVtb3ZlUGFuZWxzKHRoaXMuY20pO1xuICB9O1xuXG4gIFBhbmVsLnByb3RvdHlwZS5jaGFuZ2VkI
23459D0gZnVuY3Rpb24oaGVpZ2h0KSB7XG4gICAgdmFyIG5ld0hlaWdodCA9IGhlaWdodCA9PSBudWxsID8gdGhpcy5ub2RlLm9mZnNldEhlaWdodCA6IGhlaWdodDtcbiAgICB2YXIgaW5mbyA9IHRoaXMuY20uc3RhdGUucGFuZWxzO1xuICAgIHRoaXMuY20uX3NldFNpemUobnVsbCwgaW5mby5oZWlnaHQgKz0gKG5ld0hlaWdodCAtIHRoaXMuaGVpZ2h0KSk7XG4gICAgdGhpcy5oZWlnaHQgPSBuZXdIZWlnaHQ7XG4gIH07XG5cbiAgZnVuY3Rpb24gaW5pdFBhbmVscyhjbSkge1xuICAgIHZhciB3cmFwID0gY20uZ2V0V3JhcHBlckVsZW1lbnQoKTtcbiAgICB2YXIgc3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSA/IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHdyYXApIDogd3JhcC5jdXJyZW50U3R5bGU7XG4gICAgdmFyIGhlaWdodCA9IHBhcnNlSW50KHN0eWxlLmhlaWdodCk7XG4gICAgdmFyIGluZm8gPSBjbS5zdGF0ZS5wYW5lbHMgPSB7XG4gICAgICBzZXRIZWlnaHQ6IHdyYXAuc3R5bGUuaGVpZ2h0LFxuICAgICAgaGVpZ2h0TGVmdDogaGVpZ2h0LFxuICAgICAgcGFuZWxzOiAwLFxuICAgICAgd3JhcHBlcjogZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKVxuICAgIH07XG4gICAgd3JhcC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShpbmZvLndyYXBwZXIsIHdyYXApO1xuICAgIHZhciBoYXNGb2N1cyA9IGNtLmhhc0ZvY3VzKCk7XG4gICAgaW5mby53cmFwcGVyLmFwcGVuZENoaWxkKHdyYXApO1xuICAgIGlmIChoYXNGb2N1cykgY20uZm9jdXMoKTtcblxuICAgIGNtLl9zZXRTaXplID0gY20uc2V0U2l6ZTtcbiAgICBpZiAoaGVpZ2h0ICE9IG51bGwpIGNtLnNldFNpemUgPSBmdW5jdGlvbih3aWR0aCwgbmV3SGVpZ2h0KSB7XG4gICAgICBpZiAobmV3SGVpZ2h0ID09IG51bGwpIHJldHVybiB0aGlzLl9zZXRTaXplKHdpZHRoLCBuZXdIZWlnaHQpO1xuICAgICAgaW5mby5zZXRIZWlnaHQgPSBuZXdIZWlnaHQ7XG4gICAgICBpZiAodHlwZW9mIG5ld0hlaWdodCAhPSBcIm51bWJlclwiKSB7XG4gICAgICAgIHZhciBweCA9IC9eKFxcZCtcXC4/XFxkKilweCQvLmV4ZWMobmV3SGVpZ2h0KTtcbiAgICAgICAgaWYgKHB4KSB7XG4gICAgICAgICAgbmV3SGVpZ2h0ID0gTnVtYmVyKHB4WzFdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbmZvLndyYXBwZXIuc3R5bGUuaGVpZ2h0ID0gbmV3SGVpZ2h0O1xuICAgICAgICAgIG5ld0hlaWdodCA9IGluZm8ud3JhcHBlci5vZmZzZXRIZWlnaHQ7XG4gICAgICAgICAgaW5mby53cmFwcGVyLnN0eWxlLmhlaWdodCA9IFwiXCI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNtLl9zZXRTaXplKHdpZHRoLCBpbmZvLmhlaWdodExlZnQgKz0gKG5ld0hlaWdodCAtIGhlaWdodCkpO1xuICAgICAgaGVpZ2h0ID0gbmV3SGVpZ2h0O1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVQYW5lbHMoY20pIHtcbiAgICB2YXIgaW5mbyA9IGNtLnN0YXRlLnBhbmVscztcbiAgICBjbS5zdGF0ZS5wYW5lbHMgPSBudWxsO1xuXG4gICAgdmFyIHdyYXAgPSBjbS5nZXRXcmFwcGVyRWxlbWVudCgpO1xuICAgIGluZm8ud3JhcHBlci5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZCh3cmFwLCBpbmZvLndyYXBwZXIpO1xuICAgIHdyYXAuc3R5bGUuaGVpZ2h0ID0gaW5mby5zZXRIZWlnaHQ7XG4gICAgY20uc2V0U2l6ZSA9IGNtLl9zZXRTaXplO1xuICAgIGNtLnNldFNpemUoKTtcbiAgfVxufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbihmdW5jdGlvbihtb2QpIHtcbiAgaWYgKHR5cGVvZiBleHBvcnRzID09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PSBcIm9iamVjdFwiKSAvLyBDb21tb25KU1xuICAgIG1vZChyZXF1aXJlKFwiLi4vLi4vbGliL2NvZGVtaXJyb3JcIikpO1xuICBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSAvLyBBTURcbiAgICBkZWZpbmUoW1wiLi4vLi4vbGliL2NvZGVtaXJyb3JcIl0sIG1vZCk7XG4gIGVsc2UgLy8gUGxhaW4gYnJvd3NlciBlbnZcbiAgICBtb2QoQ29kZU1pcnJvcik7XG59KShmdW5jdGlvbihDb2RlTWlycm9yKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuXG4gIENvZGVNaXJyb3IuZGVmaW5lT3B0aW9uKFwicnVsZXJzXCIsIGZhbHNlLCBmdW5jdGlvbihjbSwgdmFsLCBvbGQpIHtcbiAgICBpZiAob2xkICYmIG9sZCAhPSBDb2RlTWlycm9yLkluaXQpIHtcbiAgICAgIGNsZWFyUnVsZXJzKGNtKTtcbiAgICAgIGNtLm9mZihcInJlZnJlc2hcIiwgcmVmcmVzaFJ1bGVycyk7XG4gICAgfVxuICAgIGlmICh2YWwgJiYgdmFsLmxlbmd0aCkge1xuICAgICAgc2V0UnVsZXJzKGNtKTtcbiAgICAgIGNtLm9uKFwicmVmcmVzaFwiLCByZWZyZXNoUnVsZXJzKTtcbiAgICB9XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIGNsZWFyUnVsZXJzKGNtKSB7XG4gICAgZm9yICh2YXIgaSA9IGNtLmRpc3BsYXkubGluZVNwYWNlLmNoaWxkTm9kZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciBub2RlID0gY20uZGlzcGxheS5saW5lU3BhY2UuY2hpbGROb2Rlc1tpXTtcbiAgICAgIGlmICgvKF58XFxzKUNvZGVNaXJyb3ItcnVsZXIoJHxcXHMpLy50ZXN0KG5vZGUuY2xhc3NOYW1lKSlcbiAgICAgICAgbm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG5vZGUpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldFJ1bGVycyhjbSkge1xuICAgIHZhciB2YWwgPSBjbS5nZXRPcHRpb24oXCJydWxlcnNcIik7XG4gICAgdmFyIGN3ID0gY20uZGVmYXVsdENoYXJXaWR0aCgpO1xuICAgIHZhciBsZWZ0ID0gY20uY2hhckNvb3JkcyhDb2RlTWlycm9yLlBvcyhjbS5maXJzdExpbmUoKSwgMCksIFwiZGl2XCIpLmxlZnQ7XG4gICAgdmFyIG1pbkggPSBjbS5kaXNwbGF5LnNjcm9sbGVyLm9mZnNldEhlaWdodCArIDMwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2Y
23459XIgZWx0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgIGVsdC5jbGFzc05hbWUgPSBcIkNvZGVNaXJyb3ItcnVsZXJcIjtcbiAgICAgIHZhciBjb2wsIGNvbmYgPSB2YWxbaV07XG4gICAgICBpZiAodHlwZW9mIGNvbmYgPT0gXCJudW1iZXJcIikge1xuICAgICAgICBjb2wgPSBjb25mO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29sID0gY29uZi5jb2x1bW47XG4gICAgICAgIGlmIChjb25mLmNsYXNzTmFtZSkgZWx0LmNsYXNzTmFtZSArPSBcIiBcIiArIGNvbmYuY2xhc3NOYW1lO1xuICAgICAgICBpZiAoY29uZi5jb2xvcikgZWx0LnN0eWxlLmJvcmRlckNvbG9yID0gY29uZi5jb2xvcjtcbiAgICAgICAgaWYgKGNvbmYubGluZVN0eWxlKSBlbHQuc3R5bGUuYm9yZGVyTGVmdFN0eWxlID0gY29uZi5saW5lU3R5bGU7XG4gICAgICAgIGlmIChjb25mLndpZHRoKSBlbHQuc3R5bGUuYm9yZGVyTGVmdFdpZHRoID0gY29uZi53aWR0aDtcbiAgICAgIH1cbiAgICAgIGVsdC5zdHlsZS5sZWZ0ID0gKGxlZnQgKyBjb2wgKiBjdykgKyBcInB4XCI7XG4gICAgICBlbHQuc3R5bGUudG9wID0gXCItNTBweFwiO1xuICAgICAgZWx0LnN0eWxlLmJvdHRvbSA9IFwiLTIwcHhcIjtcbiAgICAgIGVsdC5zdHlsZS5taW5IZWlnaHQgPSBtaW5IICsgXCJweFwiO1xuICAgICAgY20uZGlzcGxheS5saW5lU3BhY2UuaW5zZXJ0QmVmb3JlKGVsdCwgY20uZGlzcGxheS5jdXJzb3JEaXYpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlZnJlc2hSdWxlcnMoY20pIHtcbiAgICBjbGVhclJ1bGVycyhjbSk7XG4gICAgc2V0UnVsZXJzKGNtKTtcbiAgfVxufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbihmdW5jdGlvbihtb2QpIHtcbiAgaWYgKHR5cGVvZiBleHBvcnRzID09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PSBcIm9iamVjdFwiKSAvLyBDb21tb25KU1xuICAgIG1vZChyZXF1aXJlKFwiLi4vLi4vbGliL2NvZGVtaXJyb3JcIikpO1xuICBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSAvLyBBTURcbiAgICBkZWZpbmUoW1wiLi4vLi4vbGliL2NvZGVtaXJyb3JcIl0sIG1vZCk7XG4gIGVsc2UgLy8gUGxhaW4gYnJvd3NlciBlbnZcbiAgICBtb2QoQ29kZU1pcnJvcik7XG59KShmdW5jdGlvbihDb2RlTWlycm9yKSB7XG4gIHZhciBkZWZhdWx0cyA9IHtcbiAgICBwYWlyczogXCIoKVtde30nJ1xcXCJcXFwiXCIsXG4gICAgdHJpcGxlczogXCJcIixcbiAgICBleHBsb2RlOiBcIltde31cIlxuICB9O1xuXG4gIHZhciBQb3MgPSBDb2RlTWlycm9yLlBvcztcblxuICBDb2RlTWlycm9yLmRlZmluZU9wdGlvbihcImF1dG9DbG9zZUJyYWNrZXRzXCIsIGZhbHNlLCBmdW5jdGlvbihjbSwgdmFsLCBvbGQpIHtcbiAgICBpZiAob2xkICYmIG9sZCAhPSBDb2RlTWlycm9yLkluaXQpIHtcbiAgICAgIGNtLnJlbW92ZUtleU1hcChrZXlNYXApO1xuICAgICAgY20uc3RhdGUuY2xvc2VCcmFja2V0cyA9IG51bGw7XG4gICAgfVxuICAgIGlmICh2YWwpIHtcbiAgICAgIGNtLnN0YXRlLmNsb3NlQnJhY2tldHMgPSB2YWw7XG4gICAgICBjbS5hZGRLZXlNYXAoa2V5TWFwKTtcbiAgICB9XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIGdldE9wdGlvbihjb25mLCBuYW1lKSB7XG4gICAgaWYgKG5hbWUgPT0gXCJwYWlyc1wiICYmIHR5cGVvZiBjb25mID09IFwic3RyaW5nXCIpIHJldHVybiBjb25mO1xuICAgIGlmICh0eXBlb2YgY29uZiA9PSBcIm9iamVjdFwiICYmIGNvbmZbbmFtZV0gIT0gbnVsbCkgcmV0dXJuIGNvbmZbbmFtZV07XG4gICAgcmV0dXJuIGRlZmF1bHRzW25hbWVdO1xuICB9XG5cbiAgdmFyIGJpbmQgPSBkZWZhdWx0cy5wYWlycyArIFwiYFwiO1xuICB2YXIga2V5TWFwID0ge0JhY2tzcGFjZTogaGFuZGxlQmFja3NwYWNlLCBFbnRlcjogaGFuZGxlRW50ZXJ9O1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJpbmQubGVuZ3RoOyBpKyspXG4gICAga2V5TWFwW1wiJ1wiICsgYmluZC5jaGFyQXQoaSkgKyBcIidcIl0gPSBoYW5kbGVyKGJpbmQuY2hhckF0KGkpKTtcblxuICBmdW5jdGlvbiBoYW5kbGVyKGNoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGNtKSB7IHJldHVybiBoYW5kbGVDaGFyKGNtLCBjaCk7IH07XG4gIH1cblxuICBmdW5jdGlvbiBnZXRDb25maWcoY20pIHtcbiAgICB2YXIgZGVmbHQgPSBjbS5zdGF0ZS5jbG9zZUJyYWNrZXRzO1xuICAgIGlmICghZGVmbHQpIHJldHVybiBudWxsO1xuICAgIHZhciBtb2RlID0gY20uZ2V0TW9kZUF0KGNtLmdldEN1cnNvcigpKTtcbiAgICByZXR1cm4gbW9kZS5jbG9zZUJyYWNrZXRzIHx8IGRlZmx0O1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlQmFja3NwYWNlKGNtKSB7XG4gICAgdmFyIGNvbmYgPSBnZXRDb25maWcoY20pO1xuICAgIGlmICghY29uZiB8fCBjbS5nZXRPcHRpb24oXCJkaXNhYmxlSW5wdXRcIikpIHJldHVybiBDb2RlTWlycm9yLlBhc3M7XG5cbiAgICB2YXIgcGFpcnMgPSBnZXRPcHRpb24oY29uZiwgXCJwYWlyc1wiKTtcbiAgICB2YXIgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKCFyYW5nZXNbaV0uZW1wdHkoKSkgcmV0dXJuIENvZGVNaXJyb3IuUGFzcztcbiAgICAgIHZhciBhcm91bmQgPSBjaGFyc0Fyb3VuZChjbSwgcmFuZ2VzW2ldLmhlYWQpO1xuICAgICAgaWYgKCFhcm91bmQgfHwgcGFpcnMuaW5kZXhPZihhcm91bmQpICUgMiAhPSAwKSByZXR1cm4gQ29kZU1pcnJvci5QYXNzO1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gcmFuZ2VzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2Y
23459XIgY3VyID0gcmFuZ2VzW2ldLmhlYWQ7XG4gICAgICBjbS5yZXBsYWNlUmFuZ2UoXCJcIiwgUG9zKGN1ci5saW5lLCBjdXIuY2ggLSAxKSwgUG9zKGN1ci5saW5lLCBjdXIuY2ggKyAxKSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlRW50ZXIoY20pIHtcbiAgICB2YXIgY29uZiA9IGdldENvbmZpZyhjbSk7XG4gICAgdmFyIGV4cGxvZGUgPSBjb25mICYmIGdldE9wdGlvbihjb25mLCBcImV4cGxvZGVcIik7XG4gICAgaWYgKCFleHBsb2RlIHx8IGNtLmdldE9wdGlvbihcImRpc2FibGVJbnB1dFwiKSkgcmV0dXJuIENvZGVNaXJyb3IuUGFzcztcblxuICAgIHZhciByYW5nZXMgPSBjbS5saXN0U2VsZWN0aW9ucygpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIXJhbmdlc1tpXS5lbXB0eSgpKSByZXR1cm4gQ29kZU1pcnJvci5QYXNzO1xuICAgICAgdmFyIGFyb3VuZCA9IGNoYXJzQXJvdW5kKGNtLCByYW5nZXNbaV0uaGVhZCk7XG4gICAgICBpZiAoIWFyb3VuZCB8fCBleHBsb2RlLmluZGV4T2YoYXJvdW5kKSAlIDIgIT0gMCkgcmV0dXJuIENvZGVNaXJyb3IuUGFzcztcbiAgICB9XG4gICAgY20ub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgICAgY20ucmVwbGFjZVNlbGVjdGlvbihcIlxcblxcblwiLCBudWxsKTtcbiAgICAgIGNtLmV4ZWNDb21tYW5kKFwiZ29DaGFyTGVmdFwiKTtcbiAgICAgIHJhbmdlcyA9IGNtLmxpc3RTZWxlY3Rpb25zKCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2Y
23459XIgbGluZSA9IHJhbmdlc1tpXS5oZWFkLmxpbmU7XG4gICAgICAgIGNtLmluZGVudExpbmUobGluZSwgbnVsbCwgdHJ1ZSk7XG4gICAgICAgIGNtLmluZGVudExpbmUobGluZSArIDEsIG51bGwsIHRydWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gY29udHJhY3RTZWxlY3Rpb24oc2VsKSB7XG4gICAgdmFyIGludmVydGVkID0gQ29kZU1pcnJvci5jbXBQb3Moc2VsLmFuY2hvciwgc2VsLmhlYWQpID4gMDtcbiAgICByZXR1cm4ge2FuY2hvcjogbmV3IFBvcyhzZWwuYW5jaG9yLmxpbmUsIHNlbC5hbmNob3IuY2ggKyAoaW52ZXJ0ZWQgPyAtMSA6IDEpKSxcbiAgICAgICAgICAgIGhlYWQ6IG5ldyBQb3Moc2VsLmhlYWQubGluZSwgc2VsLmhlYWQuY2ggKyAoaW52ZXJ0ZWQgPyAxIDogLTEpKX07XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVDaGFyKGNtLCBjaCkge1xuICAgIHZhciBjb25mID0gZ2V0Q29uZmlnKGNtKTtcbiAgICBpZiAoIWNvbmYgfHwgY20uZ2V0T3B0aW9uKFwiZGlzYWJsZUlucHV0XCIpKSByZXR1cm4gQ29kZU1pcnJvci5QYXNzO1xuXG4gICAgdmFyIHBhaXJzID0gZ2V0T3B0aW9uKGNvbmYsIFwicGFpcnNcIik7XG4gICAgdmFyIHBvcyA9IHBhaXJzLmluZGV4T2YoY2gpO1xuICAgIGlmIChwb3MgPT0gLTEpIHJldHVybiBDb2RlTWlycm9yLlBhc3M7XG4gICAgdmFyIHRyaXBsZXMgPSBnZXRPcHRpb24oY29uZiwgXCJ0cmlwbGVzXCIpO1xuXG4gICAgdmFyIGlkZW50aWNhbCA9IHBhaXJzLmNoYXJBdChwb3MgKyAxKSA9PSBjaDtcbiAgICB2YXIgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKTtcbiAgICB2YXIgb3BlbmluZyA9IHBvcyAlIDIgPT0gMDtcblxuICAgIHZhciB0eXBlLCBuZXh0O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2Y
23459XIgcmFuZ2UgPSByYW5nZXNbaV0sIGN1ciA9IHJhbmdlLmhlYWQsIGN1clR5cGU7XG4gICAgICB2YXIgbmV4dCA9IGNtLmdldFJhbmdlKGN1ciwgUG9zKGN1ci5saW5lLCBjdXIuY2ggKyAxKSk7XG4gICAgICBpZiAob3BlbmluZyAmJiAhcmFuZ2UuZW1wdHkoKSkge1xuICAgICAgICBjdXJUeXBlID0gXCJzdXJyb3VuZFwiO1xuICAgICAgfSBlbHNlIGlmICgoaWRlbnRpY2FsIHx8ICFvcGVuaW5nKSAmJiBuZXh0ID09IGNoKSB7XG4gICAgICAgIGlmICh0cmlwbGVzLmluZGV4T2YoY2gpID49IDAgJiYgY20uZ2V0UmFuZ2UoY3VyLCBQb3MoY3VyLmxpbmUsIGN1ci5jaCArIDMpKSA9PSBjaCArIGNoICsgY2gpXG4gICAgICAgICAgY3VyVHlwZSA9IFwic2tpcFRocmVlXCI7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBjdXJUeXBlID0gXCJza2lwXCI7XG4gICAgICB9IGVsc2UgaWYgKGlkZW50aWNhbCAmJiBjdXIuY2ggPiAxICYmIHRyaXBsZXMuaW5kZXhPZihjaCkgPj0gMCAmJlxuICAgICAgICAgICAgICAgICBjbS5nZXRSYW5nZShQb3MoY3VyLmxpbmUsIGN1ci5jaCAtIDIpLCBjdXIpID09IGNoICsgY2ggJiZcbiAgICAgICAgICAgICAgICAgKGN1ci5jaCA8PSAyIHx8IGNtLmdldFJhbmdlKFBvcyhjdXIubGluZSwgY3VyLmNoIC0gMyksIFBvcyhjdXIubGluZSwgY3VyLmNoIC0gMikpICE9IGNoKSkge1xuICAgICAgICBjdXJUeXBlID0gXCJhZGRGb3VyXCI7XG4gICAgICB9IGVsc2UgaWYgKGlkZW50aWNhbCkge1xuICAgICAgICBpZiAoIUNvZGVNaXJyb3IuaXNXb3JkQ2hhcihuZXh0KSAmJiBlbnRlcmluZ1N0cmluZyhjbSwgY3VyLCBjaCkpIGN1clR5cGUgPSBcImJvdGhcIjtcbiAgICAgICAgZWxzZSByZXR1cm4gQ29kZU1pcnJvci5QYXNzO1xuICAgICAgfSBlbHNlIGlmIChvcGVuaW5nICYmIChjbS5nZXRMaW5lKGN1ci5saW5lKS5sZW5ndGggPT0gY3VyLmNoIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzQ2xvc2luZ0JyYWNrZXQobmV4dCwgcGFpcnMpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIC9cXHMvLnRlc3QobmV4dCkpKSB7XG4gICAgICAgIGN1clR5cGUgPSBcImJvdGhcIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBDb2RlTWlycm9yLlBhc3M7XG4gICAgICB9XG4gICAgICBpZiAoIXR5cGUpIHR5cGUgPSBjdXJUeXBlO1xuICAgICAgZWxzZSBpZiAodHlwZSAhPSBjdXJUeXBlKSByZXR1cm4gQ29kZU1pcnJvci5QYXNzO1xuICAgIH1cblxuICAgIHZhciBsZWZ0ID0gcG9zICUgMiA/IHBhaXJzLmNoYXJBdChwb3MgLSAxKSA6IGNoO1xuICAgIHZhciByaWdodCA9IHBvcyAlIDIgPyBjaCA6IHBhaXJzLmNoYXJBdChwb3MgKyAxKTtcbiAgICBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodHlwZSA9PSBcInNraXBcIikge1xuICAgICAgICBjbS5leGVjQ29tbWFuZChcImdvQ2hhclJpZ2h0XCIpO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09IFwic2tpcFRocmVlXCIpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAzOyBpKyspXG4gICAgICAgICAgY20uZXhlY0NvbW1hbmQoXCJnb0NoYXJSaWdodFwiKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSBcInN1cnJvdW5kXCIpIHtcbiAgICAgICAgdmFyIHNlbHMgPSBjbS5nZXRTZWxlY3Rpb25zKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2Vscy5sZW5ndGg7IGkrKylcbiAgICAgICAgICBzZWxzW2ldID0gbGVmdCArIHNlbHNbaV0gKyByaWdodDtcbiAgICAgICAgY20ucmVwbGFjZVNlbGVjdGlvbnMoc2VscywgXCJhcm91bmRcIik7XG4gICAgICAgIHNlbHMgPSBjbS5saXN0U2VsZWN0aW9ucygpLnNsaWNlKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2Vscy5sZW5ndGg7IGkrKylcbiAgICAgICAgICBzZWxzW2ldID0gY29udHJhY3RTZWxlY3Rpb24oc2Vsc1tpXSk7XG4gICAgICAgIGNtLnNldFNlbGVjdGlvbnMoc2Vscyk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gXCJib3RoXCIpIHtcbiAgICAgICAgY20ucmVwbGFjZVNlbGVjdGlvbihsZWZ0ICsgcmlnaHQsIG51bGwpO1xuICAgICAgICBjbS50cmlnZ2VyRWxlY3RyaWMobGVmdCArIHJpZ2h0KTtcbiAgICAgICAgY20uZXhlY0NvbW1hbmQoXCJnb0NoYXJMZWZ0XCIpO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09IFwiYWRkRm91clwiKSB7XG4gICAgICAgIGNtLnJlcGxhY2VTZWxlY3Rpb24obGVmdCArIGxlZnQgKyBsZWZ0ICsgbGVmdCwgXCJiZWZvcmVcIik7XG4gICAgICAgIGNtLmV4ZWNDb21tYW5kKFwiZ29DaGFyUmlnaHRcIik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBpc0Nsb3NpbmdCcmFja2V0KGNoLCBwYWlycykge1xuICAgIHZhciBwb3MgPSBwYWlycy5sYXN0SW5kZXhPZihjaCk7XG4gICAgcmV0dXJuIHBvcyA+IC0xICYmIHBvcyAlIDIgPT0gMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNoYXJzQXJvdW5kKGNtLCBwb3MpIHtcbiAgICB2YXIgc3RyID0gY20uZ2V0UmFuZ2UoUG9zKHBvcy5saW5lLCBwb3MuY2ggLSAxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgUG9zKHBvcy5saW5lLCBwb3MuY2ggKyAxKSk7XG4gICAgcmV0dXJuIHN0ci5sZW5ndGggPT0gMiA/IHN0ciA6IG51bGw7XG4gIH1cblxuICAvLyBQcm9qZWN0IHRoZSB0b2tlbiB0eXBlIHRoYXQgd2lsbCBleGlzdHMgYWZ0ZXIgdGhlIGdpdmVuIGNoYXIgaXNcbiAgLy8gdHlwZWQsIGFuZCB1c2UgaXQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgaXQgd291bGQgY2F1c2UgdGhlIHN0YXJ0XG4gIC8vIG9mIGEgc3RyaW5nIHRva2VuLlxuICBmdW5jdGlvbiBlbnRlcmluZ1N0cmluZyhjbSwgcG9zLCBjaCkge1xuICAgIHZhciBsaW5lID0gY20uZ2V0TGluZShwb3MubGluZSk7XG4gICAgdmFyIHRva2VuID0gY20uZ2V0VG9rZW5BdChwb3MpO1xuICAgIGlmICgvXFxic3RyaW5nMj9cXGIvLnRlc3QodG9rZW4udHlwZSkpIHJldHVybiBmYWxzZTtcbiAgICB2YXIgc3RyZWFtID0gbmV3IENvZGVNaXJyb3IuU3RyaW5nU3RyZWFtKGxpbmUuc2xpY2UoMCwgcG9zLmNoKSArIGNoICsgbGluZS5zbGljZShwb3MuY2gpLCA0KTtcbiAgICBzdHJlYW0ucG9zID0gc3RyZWFtLnN0YXJ0ID0gdG9rZW4uc3RhcnQ7XG4gICAgZm9yICg7Oykge1xuICAgICAgdmFyIHR5cGUxID0gY20uZ2V0TW9kZSgpLnRva2VuKHN0cmVhbSwgdG9rZW4uc3RhdGUpO1xuICAgICAgaWYgKHN0cmVhbS5wb3MgPj0gcG9zLmNoICsgMSkgcmV0dXJuIC9cXGJzdHJpbmcyP1xcYi8udGVzdCh0eXBlMSk7XG4gICAgICBzdHJlYW0uc3RhcnQgPSBzdHJlYW0ucG9zO1xuICAgIH1cbiAgfVxufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbihmdW5jdGlvbihtb2QpIHtcbiAgaWYgKHR5cGVvZiBleHBvcnRzID09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PSBcIm9iamVjdFwiKSAvLyBDb21tb25KU1xuICAgIG1vZChyZXF1aXJlKFwiLi4vLi4vbGliL2NvZGVtaXJyb3JcIikpO1xuICBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSAvLyBBTURcbiAgICBkZWZpbmUoW1wiLi4vLi4vbGliL2NvZGVtaXJyb3JcIl0sIG1vZCk7XG4gIGVsc2UgLy8gUGxhaW4gYnJvd3NlciBlbnZcbiAgICBtb2QoQ29kZU1pcnJvcik7XG59KShmdW5jdGlvbihDb2RlTWlycm9yKSB7XG4gIHZhciBpZV9sdDggPSAvTVNJRSBcXGQvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiZcbiAgICAoZG9jdW1lbnQuZG9jdW1lbnRNb2RlID09IG51bGwgfHwgZG9jdW1lbnQuZG9jdW1lbnRNb2RlIDwgOCk7XG5cbiAgdmFyIFBvcyA9IENvZGVNaXJyb3IuUG9zO1xuXG4gIHZhciBtYXRjaGluZyA9IHtcIihcIjogXCIpPlwiLCBcIilcIjogXCIoPFwiLCBcIltc
23459IjogXCJdPlwiLCBcIl1cIjogXCJbPFwiLCBcIntcIjogXCJ9PlwiLCBcIn1cIjogXCJ7PFwifTtcblxuICBmdW5jdGlvbiBmaW5kTWF0Y2hpbmdCcmFja2V0KGNtLCB3aGVyZSwgc3RyaWN0LCBjb25maWcpIHtcbiAgICB2YXIgbGluZSA9IGNtLmdldExpbmVIYW5kbGUod2hlcmUubGluZSksIHBvcyA9IHdoZXJlLmNoIC0gMTtcbiAgICB2YXIgbWF0Y2ggPSAocG9zID49IDAgJiYgbWF0Y2hpbmdbbGluZS50ZXh0LmNoYXJBdChwb3MpXSkgfHwgbWF0Y2hpbmdbbGluZS50ZXh0LmNoYXJBdCgrK3BvcyldO1xuICAgIGlmICghbWF0Y2gpIHJldHVybiBudWxsO1xuICAgIHZhciBkaXIgPSBtYXRjaC5jaGFyQXQoMSkgPT0gXCI+XCIgPyAxIDogLTE7XG4gICAgaWYgKHN0cmljdCAmJiAoZGlyID4gMCkgIT0gKHBvcyA9PSB3aGVyZS5jaCkpIHJldHVybiBudWxsO1xuICAgIHZhciBzdHlsZSA9IGNtLmdldFRva2VuVHlwZUF0KFBvcyh3aGVyZS5saW5lLCBwb3MgKyAxKSk7XG5cbiAgICB2YXIgZm91bmQgPSBzY2FuRm9yQnJhY2tldChjbSwgUG9zKHdoZXJlLmxpbmUsIHBvcyArIChkaXIgPiAwID8gMSA6IDApKSwgZGlyLCBzdHlsZSB8fCBudWxsLCBjb25maWcpO1xuICAgIGlmIChmb3VuZCA9PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4ge2Zyb206IFBvcyh3aGVyZS5saW5lLCBwb3MpLCB0bzogZm91bmQgJiYgZm91bmQucG9zLFxuICAgICAgICAgICAgbWF0Y2g6IGZvdW5kICYmIGZvdW5kLmNoID09IG1hdGNoLmNoYXJBdCgwKSwgZm9yd2FyZDogZGlyID4gMH07XG4gIH1cblxuICAvLyBicmFja2V0UmVnZXggaXMgdXNlZCB0byBzcGVjaWZ5IHdoaWNoIHR5cGUgb2YgYnJhY2tldCB0byBzY2FuXG4gIC8vIHNob3VsZCBiZSBhIHJlZ2V4cCwgZS5nLiAvW1tcXF1dL1xuICAvL1xuICAvLyBOb3RlOiBJZiBcIndoZXJlXCIgaXMgb24gYW4gb3BlbiBicmFja2V0LCB0aGVuIHRoaXMgYnJhY2tldCBpcyBpZ25vcmVkLlxuICAvL1xuICAvLyBSZXR1cm5zIGZhbHNlIHdoZW4gbm8gYnJhY2tldCB3YXMgZm91bmQsIG51bGwgd2hlbiBpdCByZWFjaGVkXG4gIC8vIG1heFNjYW5MaW5lcyBhbmQgZ2F2ZSB1cFxuICBmdW5jdGlvbiBzY2FuRm9yQnJhY2tldChjbSwgd2hlcmUsIGRpciwgc3R5bGUsIGNvbmZpZykge1xuICAgIHZhciBtYXhTY2FuTGVuID0gKGNvbmZpZyAmJiBjb25maWcubWF4U2NhbkxpbmVMZW5ndGgpIHx8IDEwMDAwO1xuICAgIHZhciBtYXhTY2FuTGluZXMgPSAoY29uZmlnICYmIGNvbmZpZy5tYXhTY2FuTGluZXMpIHx8IDEwMDA7XG5cbiAgICB2YXIgc3RhY2sgPSBbXTtcbiAgICB2YXIgcmUgPSBjb25maWcgJiYgY29uZmlnLmJyYWNrZXRSZWdleCA/IGNvbmZpZy5icmFja2V0UmVnZXggOiAvWygpe31bXFxdXS87XG4gICAgdmFyIGxpbmVFbmQgPSBkaXIgPiAwID8gTWF0aC5taW4od2hlcmUubGluZSArIG1heFNjYW5MaW5lcywgY20ubGFzdExpbmUoKSArIDEpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDogTWF0aC5tYXgoY20uZmlyc3RMaW5lKCkgLSAxLCB3aGVyZS5saW5lIC0gbWF4U2NhbkxpbmVzKTtcbiAgICBmb3IgKHZhciBsaW5lTm8gPSB3aGVyZS5saW5lOyBsaW5lTm8gIT0gbGluZUVuZDsgbGluZU5vICs9IGRpcikge1xuICAgICAgdmFyIGxpbmUgPSBjbS5nZXRMaW5lKGxpbmVObyk7XG4gICAgICBpZiAoIWxpbmUpIGNvbnRpbnVlO1xuICAgICAgdmFyIHBvcyA9IGRpciA+IDAgPyAwIDogbGluZS5sZW5ndGggLSAxLCBlbmQgPSBkaXIgPiAwID8gbGluZS5sZW5ndGggOiAtMTtcbiAgICAgIGlmIChsaW5lLmxlbmd0aCA+IG1heFNjYW5MZW4pIGNvbnRpbnVlO1xuICAgICAgaWYgKGxpbmVObyA9PSB3aGVyZS5saW5lKSBwb3MgPSB3aGVyZS5jaCAtIChkaXIgPCAwID8gMSA6IDApO1xuICAgICAgZm9yICg7IHBvcyAhPSBlbmQ7IHBvcyArPSBkaXIpIHtcbiAgICAgICAgdmFyIGNoID0gbGluZS5jaGFyQXQocG9zKTtcbiAgICAgICAgaWYgKHJlLnRlc3QoY2gpICYmIChzdHlsZSA9PT0gdW5kZWZpbmVkIHx8IGNtLmdldFRva2VuVHlwZUF0KFBvcyhsaW5lTm8sIHBvcyArIDEpKSA9PSBzdHlsZSkpIHtcbiAgICAgICAgICB2Y
23459XIgbWF0Y2ggPSBtYXRjaGluZ1tjaF07XG4gICAgICAgICAgaWYgKChtYXRjaC5jaGFyQXQoMSkgPT0gXCI+XCIpID09IChkaXIgPiAwKSkgc3RhY2sucHVzaChjaCk7XG4gICAgICAgICAgZWxzZSBpZiAoIXN0YWNrLmxlbmd0aCkgcmV0dXJuIHtwb3M6IFBvcyhsaW5lTm8sIHBvcyksIGNoOiBjaH07XG4gICAgICAgICAgZWxzZSBzdGFjay5wb3AoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbGluZU5vIC0gZGlyID09IChkaXIgPiAwID8gY20ubGFzdExpbmUoKSA6IGNtLmZpcnN0TGluZSgpKSA/IGZhbHNlIDogbnVsbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1hdGNoQnJhY2tldHMoY20sIGF1dG9jbGVhciwgY29uZmlnKSB7XG4gICAgLy8gRGlzYWJsZSBicmFjZSBtYXRjaGluZyBpbiBsb25nIGxpbmVzLCBzaW5jZSBpdCdsbCBjYXVzZSBodWdlbHkgc2xvdyB1cGRhdGVzXG4gICAgdmFyIG1heEhpZ2hsaWdodExlbiA9IGNtLnN0YXRlLm1hdGNoQnJhY2tldHMubWF4SGlnaGxpZ2h0TGluZUxlbmd0aCB8fCAxMDAwO1xuICAgIHZhciBtYXJrcyA9IFtdLCByYW5nZXMgPSBjbS5saXN0U2VsZWN0aW9ucygpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbWF0Y2ggPSByYW5nZXNbaV0uZW1wdHkoKSAmJiBmaW5kTWF0Y2hpbmdCcmFja2V0KGNtLCByYW5nZXNbaV0uaGVhZCwgZmFsc2UsIGNvbmZpZyk7XG4gICAgICBpZiAobWF0Y2ggJiYgY20uZ2V0TGluZShtYXRjaC5mcm9tLmxpbmUpLmxlbmd0aCA8PSBtYXhIaWdobGlnaHRMZW4pIHtcbiAgICAgICAgdmFyIHN0eWxlID0gbWF0Y2gubWF0Y2ggPyBcIkNvZGVNaXJyb3ItbWF0Y2hpbmdicmFja2V0XCIgOiBcIkNvZGVNaXJyb3Itbm9ubWF0Y2hpbmdicmFja2V0XCI7XG4gICAgICAgIG1hcmtzLnB1c2goY20ubWFya1RleHQobWF0Y2guZnJvbSwgUG9zKG1hdGNoLmZyb20ubGluZSwgbWF0Y2guZnJvbS5jaCArIDEpLCB7Y2xhc3NOYW1lOiBzdHlsZX0pKTtcbiAgICAgICAgaWYgKG1hdGNoLnRvICYmIGNtLmdldExpbmUobWF0Y2gudG8ubGluZSkubGVuZ3RoIDw9IG1heEhpZ2hsaWdodExlbilcbiAgICAgICAgICBtYXJrcy5wdXNoKGNtLm1hcmtUZXh0KG1hdGNoLnRvLCBQb3MobWF0Y2gudG8ubGluZSwgbWF0Y2gudG8uY2ggKyAxKSwge2NsYXNzTmFtZTogc3R5bGV9KSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1hcmtzLmxlbmd0aCkge1xuICAgICAgLy8gS2x1ZGdlIHRvIHdvcmsgYXJvdW5kIHRoZSBJRSBidWcgZnJvbSBpc3N1ZSAjMTE5Mywgd2hlcmUgdGV4dFxuICAgICAgLy8gaW5wdXQgc3RvcHMgZ29pbmcgdG8gdGhlIHRleHRhcmUgd2hldmVyIHRoaXMgZmlyZXMuXG4gICAgICBpZiAoaWVfbHQ4ICYmIGNtLnN0YXRlLmZvY3VzZWQpIGNtLmZvY3VzKCk7XG5cbiAgICAgIHZhciBjbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7IGkrKykgbWFya3NbaV0uY2xlYXIoKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgaWYgKGF1dG9jbGVhcikgc2V0VGltZW91dChjbGVhciwgODAwKTtcbiAgICAgIGVsc2UgcmV0dXJuIGNsZWFyO1xuICAgIH1cbiAgfVxuXG4gIHZhciBjdXJyZW50bHlIaWdobGlnaHRlZCA9IG51bGw7XG4gIGZ1bmN0aW9uIGRvTWF0Y2hCcmFja2V0cyhjbSkge1xuICAgIGNtLm9wZXJhdGlvbihmdW5jdGlvbigpIHtcbiAgICAgIGlmIChjdXJyZW50bHlIaWdobGlnaHRlZCkge2N1cnJlbnRseUhpZ2hsaWdodGVkKCk7IGN1cnJlbnRseUhpZ2hsaWdodGVkID0gbnVsbDt9XG4gICAgICBjdXJyZW50bHlIaWdobGlnaHRlZCA9IG1hdGNoQnJhY2tldHMoY20sIGZhbHNlLCBjbS5zdGF0ZS5tYXRjaEJyYWNrZXRzKTtcbiAgICB9KTtcbiAgfVxuXG4gIENvZGVNaXJyb3IuZGVmaW5lT3B0aW9uKFwibWF0Y2hCcmFja2V0c1wiLCBmYWxzZSwgZnVuY3Rpb24oY20sIHZhbCwgb2xkKSB7XG4gICAgaWYgKG9sZCAmJiBvbGQgIT0gQ29kZU1pcnJvci5Jbml0KVxuICAgICAgY20ub2ZmKFwiY3Vyc29yQWN0aXZpdHlcIiwgZG9NYXRjaEJyYWNrZXRzKTtcbiAgICBpZiAodmFsKSB7XG4gICAgICBjbS5zdGF0ZS5tYXRjaEJyYWNrZXRzID0gdHlwZW9mIHZhbCA9PSBcIm9iamVjdFwiID8gdmFsIDoge307XG4gICAgICBjbS5vbihcImN1cnNvckFjdGl2aXR5XCIsIGRvTWF0Y2hCcmFja2V0cyk7XG4gICAgfVxuICB9KTtcblxuICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbihcIm1hdGNoQnJhY2tldHNcIiwgZnVuY3Rpb24oKSB7bWF0Y2hCcmFja2V0cyh0aGlzLCB0cnVlKTt9KTtcbiAgQ29kZU1pcnJvci5kZWZpbmVFeHRlbnNpb24oXCJmaW5kTWF0Y2hpbmdCcmFja2V0XCIsIGZ1bmN0aW9uKHBvcywgc3RyaWN0LCBjb25maWcpe1xuICAgIHJldHVybiBmaW5kTWF0Y2hpbmdCcmFja2V0KHRoaXMsIHBvcywgc3RyaWN0LCBjb25maWcpO1xuICB9KTtcbiAgQ29kZU1pcnJvci5kZWZpbmVFeHRlbnNpb24oXCJzY2FuRm9yQnJhY2tldFwiLCBmdW5jdGlvbihwb3MsIGRpciwgc3R5bGUsIGNvbmZpZyl7XG4gICAgcmV0dXJuIHNjYW5Gb3JCcmFja2V0KHRoaXMsIHBvcywgZGlyLCBzdHlsZSwgY29uZmlnKTtcbiAgfSk7XG59KTtcbiIsIi8vIENvZGVNaXJyb3IsIGNvcHlyaWdodCAoYykgYnkgTWFyaWpuIEhhdmVyYmVrZSBhbmQgb3RoZXJzXG4vLyBEaXN0cmlidXRlZCB1bmRlciBhbiBNSVQgbGljZW5zZTogaHR0cDovL2NvZGVtaXJyb3IubmV0L0xJQ0VOU0VcblxuKGZ1bmN0aW9uKG1vZCkge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlID09IFwib2JqZWN0XCIpIC8vIENvbW1vbkpTXG4gICAgbW9kKHJlcXVpcmUoXCIuLi8uLi9saWIvY29kZW1pcnJvclwiKSk7XG4gIGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIC8vIEFNRFxuICAgIGRlZmluZShbXCIuLi8uLi9saWIvY29kZW1pcnJvclwiXSwgbW9kKTtcbiAgZWxzZSAvLyBQbGFpbiBicm93c2VyIGVudlxuICAgIG1vZChDb2RlTWlycm9yKTtcbn0pKGZ1bmN0aW9uKENvZGVNaXJyb3IpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgZnVuY3Rpb24gZG9Gb2xkKGNtLCBwb3MsIG9wdGlvbnMsIGZvcmNlKSB7XG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5jYWxsKSB7XG4gICAgICB2Y
23459XIgZmluZGVyID0gb3B0aW9ucztcbiAgICAgIG9wdGlvbnMgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZmluZGVyID0gZ2V0T3B0aW9uKGNtLCBvcHRpb25zLCBcInJhbmdlRmluZGVyXCIpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHBvcyA9PSBcIm51bWJlclwiKSBwb3MgPSBDb2RlTWlycm9yLlBvcyhwb3MsIDApO1xuICAgIHZhciBtaW5TaXplID0gZ2V0T3B0aW9uKGNtLCBvcHRpb25zLCBcIm1pbkZvbGRTaXplXCIpO1xuXG4gICAgZnVuY3Rpb24gZ2V0UmFuZ2UoYWxsb3dGb2xkZWQpIHtcbiAgICAgIHZhciByYW5nZSA9IGZpbmRlcihjbSwgcG9zKTtcbiAgICAgIGlmICghcmFuZ2UgfHwgcmFuZ2UudG8ubGluZSAtIHJhbmdlLmZyb20ubGluZSA8IG1pblNpemUpIHJldHVybiBudWxsO1xuICAgICAgdmFyIG1hcmtzID0gY20uZmluZE1hcmtzQXQocmFuZ2UuZnJvbSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1hcmtzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGlmIChtYXJrc1tpXS5fX2lzRm9sZCAmJiBmb3JjZSAhPT0gXCJmb2xkXCIpIHtcbiAgICAgICAgICBpZiAoIWFsbG93Rm9sZGVkKSByZXR1cm4gbnVsbDtcbiAgICAgICAgICByYW5nZS5jbGVhcmVkID0gdHJ1ZTtcbiAgICAgICAgICBtYXJrc1tpXS5jbGVhcigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmFuZ2U7XG4gICAgfVxuXG4gICAgdmFyIHJhbmdlID0gZ2V0UmFuZ2UodHJ1ZSk7XG4gICAgaWYgKGdldE9wdGlvbihjbSwgb3B0aW9ucywgXCJzY2FuVXBcIikpIHdoaWxlICghcmFuZ2UgJiYgcG9zLmxpbmUgPiBjbS5maXJzdExpbmUoKSkge1xuICAgICAgcG9zID0gQ29kZU1pcnJvci5Qb3MocG9zLmxpbmUgLSAxLCAwKTtcbiAgICAgIHJhbmdlID0gZ2V0UmFuZ2UoZmFsc2UpO1xuICAgIH1cbiAgICBpZiAoIXJhbmdlIHx8IHJhbmdlLmNsZWFyZWQgfHwgZm9yY2UgPT09IFwidW5mb2xkXCIpIHJldHVybjtcblxuICAgIHZhciBteVdpZGdldCA9IG1ha2VXaWRnZXQoY20sIG9wdGlvbnMpO1xuICAgIENvZGVNaXJyb3Iub24obXlXaWRnZXQsIFwibW91c2Vkb3duXCIsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIG15UmFuZ2UuY2xlYXIoKTtcbiAgICAgIENvZGVNaXJyb3IuZV9wcmV2ZW50RGVmYXVsdChlKTtcbiAgICB9KTtcbiAgICB2YXIgbXlSYW5nZSA9IGNtLm1hcmtUZXh0KHJhbmdlLmZyb20sIHJhbmdlLnRvLCB7XG4gICAgICByZXBsYWNlZFdpdGg6IG15V2lkZ2V0LFxuICAgICAgY2xlYXJPbkVudGVyOiB0cnVlLFxuICAgICAgX19pc0ZvbGQ6IHRydWVcbiAgICB9KTtcbiAgICBteVJhbmdlLm9uKFwiY2xlYXJcIiwgZnVuY3Rpb24oZnJvbSwgdG8pIHtcbiAgICAgIENvZGVNaXJyb3Iuc2lnbmFsKGNtLCBcInVuZm9sZFwiLCBjbSwgZnJvbSwgdG8pO1xuICAgIH0pO1xuICAgIENvZGVNaXJyb3Iuc2lnbmFsKGNtLCBcImZvbGRcIiwgY20sIHJhbmdlLmZyb20sIHJhbmdlLnRvKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1ha2VXaWRnZXQoY20sIG9wdGlvbnMpIHtcbiAgICB2YXIgd2lkZ2V0ID0gZ2V0T3B0aW9uKGNtLCBvcHRpb25zLCBcIndpZGdldFwiKTtcbiAgICBpZiAodHlwZW9mIHdpZGdldCA9PSBcInN0cmluZ1wiKSB7XG4gICAgICB2Y
23459XIgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHdpZGdldCk7XG4gICAgICB3aWRnZXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgICAgIHdpZGdldC5hcHBlbmRDaGlsZCh0ZXh0KTtcbiAgICAgIHdpZGdldC5jbGFzc05hbWUgPSBcIkNvZGVNaXJyb3ItZm9sZG1hcmtlclwiO1xuICAgIH1cbiAgICByZXR1cm4gd2lkZ2V0O1xuICB9XG5cbiAgLy8gQ2x1bXN5IGJhY2t3YXJkcy1jb21wYXRpYmxlIGludGVyZmFjZVxuICBDb2RlTWlycm9yLm5ld0ZvbGRGdW5jdGlvbiA9IGZ1bmN0aW9uKHJhbmdlRmluZGVyLCB3aWRnZXQpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oY20sIHBvcykgeyBkb0ZvbGQoY20sIHBvcywge3JhbmdlRmluZGVyOiByYW5nZUZpbmRlciwgd2lkZ2V0OiB3aWRnZXR9KTsgfTtcbiAgfTtcblxuICAvLyBOZXctc3R5bGUgaW50ZXJmYWNlXG4gIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uKFwiZm9sZENvZGVcIiwgZnVuY3Rpb24ocG9zLCBvcHRpb25zLCBmb3JjZSkge1xuICAgIGRvRm9sZCh0aGlzLCBwb3MsIG9wdGlvbnMsIGZvcmNlKTtcbiAgfSk7XG5cbiAgQ29kZU1pcnJvci5kZWZpbmVFeHRlbnNpb24oXCJpc0ZvbGRlZFwiLCBmdW5jdGlvbihwb3MpIHtcbiAgICB2YXIgbWFya3MgPSB0aGlzLmZpbmRNYXJrc0F0KHBvcyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7ICsraSlcbiAgICAgIGlmIChtYXJrc1tpXS5fX2lzRm9sZCkgcmV0dXJuIHRydWU7XG4gIH0pO1xuXG4gIENvZGVNaXJyb3IuY29tbWFuZHMudG9nZ2xlRm9sZCA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgY20uZm9sZENvZGUoY20uZ2V0Q3Vyc29yKCkpO1xuICB9O1xuICBDb2RlTWlycm9yLmNvbW1hbmRzLmZvbGQgPSBmdW5jdGlvbihjbSkge1xuICAgIGNtLmZvbGRDb2RlKGNtLmdldEN1cnNvcigpLCBudWxsLCBcImZvbGRcIik7XG4gIH07XG4gIENvZGVNaXJyb3IuY29tbWFuZHMudW5mb2xkID0gZnVuY3Rpb24oY20pIHtcbiAgICBjbS5mb2xkQ29kZShjbS5nZXRDdXJzb3IoKSwgbnVsbCwgXCJ1bmZvbGRcIik7XG4gIH07XG4gIENvZGVNaXJyb3IuY29tbWFuZHMuZm9sZEFsbCA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgY20ub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgICAgZm9yICh2YXIgaSA9IGNtLmZpcnN0TGluZSgpLCBlID0gY20ubGFzdExpbmUoKTsgaSA8PSBlOyBpKyspXG4gICAgICAgIGNtLmZvbGRDb2RlKENvZGVNaXJyb3IuUG9zKGksIDApLCBudWxsLCBcImZvbGRcIik7XG4gICAgfSk7XG4gIH07XG4gIENvZGVNaXJyb3IuY29tbWFuZHMudW5mb2xkQWxsID0gZnVuY3Rpb24oY20pIHtcbiAgICBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKHZhciBpID0gY20uZmlyc3RMaW5lKCksIGUgPSBjbS5sYXN0TGluZSgpOyBpIDw9IGU7IGkrKylcbiAgICAgICAgY20uZm9sZENvZGUoQ29kZU1pcnJvci5Qb3MoaSwgMCksIG51bGwsIFwidW5mb2xkXCIpO1xuICAgIH0pO1xuICB9O1xuXG4gIENvZGVNaXJyb3IucmVnaXN0ZXJIZWxwZXIoXCJmb2xkXCIsIFwiY29tYmluZVwiLCBmdW5jdGlvbigpIHtcbiAgICB2YXIgZnVuY3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuICAgIHJldHVybiBmdW5jdGlvbihjbSwgc3RhcnQpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZnVuY3MubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGZvdW5kID0gZnVuY3NbaV0oY20sIHN0YXJ0KTtcbiAgICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmQ7XG4gICAgICB9XG4gICAgfTtcbiAgfSk7XG5cbiAgQ29kZU1pcnJvci5yZWdpc3RlckhlbHBlcihcImZvbGRcIiwgXCJhdXRvXCIsIGZ1bmN0aW9uKGNtLCBzdGFydCkge1xuICAgIHZhciBoZWxwZXJzID0gY20uZ2V0SGVscGVycyhzdGFydCwgXCJmb2xkXCIpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGVscGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGN1ciA9IGhlbHBlcnNbaV0oY20sIHN0YXJ0KTtcbiAgICAgIGlmIChjdXIpIHJldHVybiBjdXI7XG4gICAgfVxuICB9KTtcblxuICB2YXIgZGVmYXVsdE9wdGlvbnMgPSB7XG4gICAgcmFuZ2VGaW5kZXI6IENvZGVNaXJyb3IuZm9sZC5hdXRvLFxuICAgIHdpZGdldDogXCJcXHUyMTk0XCIsXG4gICAgbWluRm9sZFNpemU6IDAsXG4gICAgc2NhblVwOiBmYWxzZVxuICB9O1xuXG4gIENvZGVNaXJyb3IuZGVmaW5lT3B0aW9uKFwiZm9sZE9wdGlvbnNcIiwgbnVsbCk7XG5cbiAgZnVuY3Rpb24gZ2V0T3B0aW9uKGNtLCBvcHRpb25zLCBuYW1lKSB7XG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9uc1tuYW1lXSAhPT0gdW5kZWZpbmVkKVxuICAgICAgcmV0dXJuIG9wdGlvbnNbbmFtZV07XG4gICAgdmFyIGVkaXRvck9wdGlvbnMgPSBjbS5vcHRpb25zLmZvbGRPcHRpb25zO1xuICAgIGlmIChlZGl0b3JPcHRpb25zICYmIGVkaXRvck9wdGlvbnNbbmFtZV0gIT09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiBlZGl0b3JPcHRpb25zW25hbWVdO1xuICAgIHJldHVybiBkZWZhdWx0T3B0aW9uc1tuYW1lXTtcbiAgfVxuXG4gIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uKFwiZm9sZE9wdGlvblwiLCBmdW5jdGlvbihvcHRpb25zLCBuYW1lKSB7XG4gICAgcmV0dXJuIGdldE9wdGlvbih0aGlzLCBvcHRpb25zLCBuYW1lKTtcbiAgfSk7XG59KTtcbiIsIi8vIENvZGVNaXJyb3IsIGNvcHlyaWdodCAoYykgYnkgTWFyaWpuIEhhdmVyYmVrZSBhbmQgb3RoZXJzXG4vLyBEaXN0cmlidXRlZCB1bmRlciBhbiBNSVQgbGljZW5zZTogaHR0cDovL2NvZGVtaXJyb3IubmV0L0xJQ0VOU0VcblxuKGZ1bmN0aW9uKG1vZCkge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlID09IFwib2JqZWN0XCIpIC8vIENvbW1vbkpTXG4gICAgbW9kKHJlcXVpcmUoXCIuLi8uLi9saWIvY29kZW1pcnJvclwiKSwgcmVxdWlyZShcIi4vZm9sZGNvZGVcIikpO1xuICBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSAvLyBBTURcbiAgICBkZWZpbmUoW1wiLi4vLi4vbGliL2NvZGVtaXJyb3JcIiwgXCIuL2ZvbGRjb2RlXCJdLCBtb2QpO1xuICBlbHNlIC8vIFBsYWluIGJyb3dzZXIgZW52XG4gICAgbW9kKENvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24oQ29kZU1pcnJvcikge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBDb2RlTWlycm9yLmRlZmluZU9wdGlvbihcImZvbGRHdXR0ZXJcIiwgZmFsc2UsIGZ1bmN0aW9uKGNtLCB2YWwsIG9sZCkge1xuICAgIGlmIChvbGQgJiYgb2xkICE9IENvZGVNaXJyb3IuSW5pdCkge1xuICAgICAgY20uY2xlYXJHdXR0ZXIoY20uc3RhdGUuZm9sZEd1dHRlci5vcHRpb25zLmd1dHRlcik7XG4gICAgICBjbS5zdGF0ZS5mb2xkR3V0dGVyID0gbnVsbDtcbiAgICAgIGNtLm9mZihcImd1dHRlckNsaWNrXCIsIG9uR3V0dGVyQ2xpY2spO1xuICAgICAgY20ub2ZmKFwiY2hhbmdlXCIsIG9uQ2hhbmdlKTtcbiAgICAgIGNtLm9mZihcInZpZXdwb3J0Q2hhbmdlXCIsIG9uVmlld3BvcnRDaGFuZ2UpO1xuICAgICAgY20ub2ZmKFwiZm9sZFwiLCBvbkZvbGQpO1xuICAgICAgY20ub2ZmKFwidW5mb2xkXCIsIG9uRm9sZCk7XG4gICAgICBjbS5vZmYoXCJzd2FwRG9jXCIsIHVwZGF0ZUluVmlld3BvcnQpO1xuICAgIH1cbiAgICBpZiAodmFsKSB7XG4gICAgICBjbS5zdGF0ZS5mb2xkR3V0dGVyID0gbmV3IFN0YXRlKHBhcnNlT3B0aW9ucyh2YWwpKTtcbiAgICAgIHVwZGF0ZUluVmlld3BvcnQoY20pO1xuICAgICAgY20ub24oXCJndXR0ZXJDbGlja1wiLCBvbkd1dHRlckNsaWNrKTtcbiAgICAgIGNtLm9uKFwiY2hhbmdlXCIsIG9uQ2hhbmdlKTtcbiAgICAgIGNtLm9uKFwidmlld3BvcnRDaGFuZ2VcIiwgb25WaWV3cG9ydENoYW5nZSk7XG4gICAgICBjbS5vbihcImZvbGRcIiwgb25Gb2xkKTtcbiAgICAgIGNtLm9uKFwidW5mb2xkXCIsIG9uRm9sZCk7XG4gICAgICBjbS5vbihcInN3YXBEb2NcIiwgdXBkYXRlSW5WaWV3cG9ydCk7XG4gICAgfVxuICB9KTtcblxuICB2Y
23459XIgUG9zID0gQ29kZU1pcnJvci5Qb3M7XG5cbiAgZnVuY3Rpb24gU3RhdGUob3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgdGhpcy5mcm9tID0gdGhpcy50byA9IDA7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZU9wdGlvbnMob3B0cykge1xuICAgIGlmIChvcHRzID09PSB0cnVlKSBvcHRzID0ge307XG4gICAgaWYgKG9wdHMuZ3V0dGVyID09IG51bGwpIG9wdHMuZ3V0dGVyID0gXCJDb2RlTWlycm9yLWZvbGRndXR0ZXJcIjtcbiAgICBpZiAob3B0cy5pbmRpY2F0b3JPcGVuID09IG51bGwpIG9wdHMuaW5kaWNhdG9yT3BlbiA9IFwiQ29kZU1pcnJvci1mb2xkZ3V0dGVyLW9wZW5cIjtcbiAgICBpZiAob3B0cy5pbmRpY2F0b3JGb2xkZWQgPT0gbnVsbCkgb3B0cy5pbmRpY2F0b3JGb2xkZWQgPSBcIkNvZGVNaXJyb3ItZm9sZGd1dHRlci1mb2xkZWRcIjtcbiAgICByZXR1cm4gb3B0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzRm9sZGVkKGNtLCBsaW5lKSB7XG4gICAgdmFyIG1hcmtzID0gY20uZmluZE1hcmtzQXQoUG9zKGxpbmUpKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1hcmtzLmxlbmd0aDsgKytpKVxuICAgICAgaWYgKG1hcmtzW2ldLl9faXNGb2xkICYmIG1hcmtzW2ldLmZpbmQoKS5mcm9tLmxpbmUgPT0gbGluZSkgcmV0dXJuIG1hcmtzW2ldO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFya2VyKHNwZWMpIHtcbiAgICBpZiAodHlwZW9mIHNwZWMgPT0gXCJzdHJpbmdcIikge1xuICAgICAgdmFyIGVsdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBlbHQuY2xhc3NOYW1lID0gc3BlYyArIFwiIENvZGVNaXJyb3ItZ3V0dGVybWFya2VyLXN1YnRsZVwiO1xuICAgICAgcmV0dXJuIGVsdDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHNwZWMuY2xvbmVOb2RlKHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUZvbGRJbmZvKGNtLCBmcm9tLCB0bykge1xuICAgIHZhciBvcHRzID0gY20uc3RhdGUuZm9sZEd1dHRlci5vcHRpb25zLCBjdXIgPSBmcm9tO1xuICAgIHZhciBtaW5TaXplID0gY20uZm9sZE9wdGlvbihvcHRzLCBcIm1pbkZvbGRTaXplXCIpO1xuICAgIHZhciBmdW5jID0gY20uZm9sZE9wdGlvbihvcHRzLCBcInJhbmdlRmluZGVyXCIpO1xuICAgIGNtLmVhY2hMaW5lKGZyb20sIHRvLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICB2Y
23459XIgbWFyayA9IG51bGw7XG4gICAgICBpZiAoaXNGb2xkZWQoY20sIGN1cikpIHtcbiAgICAgICAgbWFyayA9IG1hcmtlcihvcHRzLmluZGljYXRvckZvbGRlZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcG9zID0gUG9zKGN1ciwgMCk7XG4gICAgICAgIHZhciByYW5nZSA9IGZ1bmMgJiYgZnVuYyhjbSwgcG9zKTtcbiAgICAgICAgaWYgKHJhbmdlICYmIHJhbmdlLnRvLmxpbmUgLSByYW5nZS5mcm9tLmxpbmUgPj0gbWluU2l6ZSlcbiAgICAgICAgICBtYXJrID0gbWFya2VyKG9wdHMuaW5kaWNhdG9yT3Blbik7XG4gICAgICB9XG4gICAgICBjbS5zZXRHdXR0ZXJNYXJrZXIobGluZSwgb3B0cy5ndXR0ZXIsIG1hcmspO1xuICAgICAgKytjdXI7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVJblZpZXdwb3J0KGNtKSB7XG4gICAgdmFyIHZwID0gY20uZ2V0Vmlld3BvcnQoKSwgc3RhdGUgPSBjbS5zdGF0ZS5mb2xkR3V0dGVyO1xuICAgIGlmICghc3RhdGUpIHJldHVybjtcbiAgICBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICB1cGRhdGVGb2xkSW5mbyhjbSwgdnAuZnJvbSwgdnAudG8pO1xuICAgIH0pO1xuICAgIHN0YXRlLmZyb20gPSB2cC5mcm9tOyBzdGF0ZS50byA9IHZwLnRvO1xuICB9XG5cbiAgZnVuY3Rpb24gb25HdXR0ZXJDbGljayhjbSwgbGluZSwgZ3V0dGVyKSB7XG4gICAgdmFyIHN0YXRlID0gY20uc3RhdGUuZm9sZEd1dHRlcjtcbiAgICBpZiAoIXN0YXRlKSByZXR1cm47XG4gICAgdmFyIG9wdHMgPSBzdGF0ZS5vcHRpb25zO1xuICAgIGlmIChndXR0ZXIgIT0gb3B0cy5ndXR0ZXIpIHJldHVybjtcbiAgICB2YXIgZm9sZGVkID0gaXNGb2xkZWQoY20sIGxpbmUpO1xuICAgIGlmIChmb2xkZWQpIGZvbGRlZC5jbGVhcigpO1xuICAgIGVsc2UgY20uZm9sZENvZGUoUG9zKGxpbmUsIDApLCBvcHRzLnJhbmdlRmluZGVyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uQ2hhbmdlKGNtKSB7XG4gICAgdmFyIHN0YXRlID0gY20uc3RhdGUuZm9sZEd1dHRlcjtcbiAgICBpZiAoIXN0YXRlKSByZXR1cm47XG4gICAgdmFyIG9wdHMgPSBzdGF0ZS5vcHRpb25zO1xuICAgIHN0YXRlLmZyb20gPSBzdGF0ZS50byA9IDA7XG4gICAgY2xlYXJUaW1lb3V0KHN0YXRlLmNoYW5nZVVwZGF0ZSk7XG4gICAgc3RhdGUuY2hhbmdlVXBkYXRlID0gc2V0VGltZW91dChmdW5jdGlvbigpIHsgdXBkYXRlSW5WaWV3cG9ydChjbSk7IH0sIG9wdHMuZm9sZE9uQ2hhbmdlVGltZVNwYW4gfHwgNjAwKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVmlld3BvcnRDaGFuZ2UoY20pIHtcbiAgICB2YXIgc3RhdGUgPSBjbS5zdGF0ZS5mb2xkR3V0dGVyO1xuICAgIGlmICghc3RhdGUpIHJldHVybjtcbiAgICB2YXIgb3B0cyA9IHN0YXRlLm9wdGlvbnM7XG4gICAgY2xlYXJUaW1lb3V0KHN0YXRlLmNoYW5nZVVwZGF0ZSk7XG4gICAgc3RhdGUuY2hhbmdlVXBkYXRlID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIHZhciB2cCA9IGNtLmdldFZpZXdwb3J0KCk7XG4gICAgICBpZiAoc3RhdGUuZnJvbSA9PSBzdGF0ZS50byB8fCB2cC5mcm9tIC0gc3RhdGUudG8gPiAyMCB8fCBzdGF0ZS5mcm9tIC0gdnAudG8gPiAyMCkge1xuICAgICAgICB1cGRhdGVJblZpZXdwb3J0KGNtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNtLm9wZXJhdGlvbihmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAodnAuZnJvbSA8IHN0YXRlLmZyb20pIHtcbiAgICAgICAgICAgIHVwZGF0ZUZvbGRJbmZvKGNtLCB2cC5mcm9tLCBzdGF0ZS5mcm9tKTtcbiAgICAgICAgICAgIHN0YXRlLmZyb20gPSB2cC5mcm9tO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodnAudG8gPiBzdGF0ZS50bykge1xuICAgICAgICAgICAgdXBkYXRlRm9sZEluZm8oY20sIHN0YXRlLnRvLCB2cC50byk7XG4gICAgICAgICAgICBzdGF0ZS50byA9IHZwLnRvO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSwgb3B0cy51cGRhdGVWaWV3cG9ydFRpbWVTcGFuIHx8IDQwMCk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkZvbGQoY20sIGZyb20pIHtcbiAgICB2YXIgc3RhdGUgPSBjbS5zdGF0ZS5mb2xkR3V0dGVyO1xuICAgIGlmICghc3RhdGUpIHJldHVybjtcbiAgICB2YXIgbGluZSA9IGZyb20ubGluZTtcbiAgICBpZiAobGluZSA+PSBzdGF0ZS5mcm9tICYmIGxpbmUgPCBzdGF0ZS50bylcbiAgICAgIHVwZGF0ZUZvbGRJbmZvKGNtLCBsaW5lLCBsaW5lICsgMSk7XG4gIH1cbn0pO1xuIiwiLy8gQ29kZU1pcnJvciwgY29weXJpZ2h0IChjKSBieSBNYXJpam4gSGF2ZXJiZWtlIGFuZCBvdGhlcnNcbi8vIERpc3RyaWJ1dGVkIHVuZGVyIGFuIE1JVCBsaWNlbnNlOiBodHRwOi8vY29kZW1pcnJvci5uZXQvTElDRU5TRVxuXG4oZnVuY3Rpb24obW9kKSB7XG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUgPT0gXCJvYmplY3RcIikgLy8gQ29tbW9uSlNcbiAgICBtb2QocmVxdWlyZShcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCJdLCBtb2QpO1xuICBlbHNlIC8vIFBsYWluIGJyb3dzZXIgZW52XG4gICAgbW9kKENvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24oQ29kZU1pcnJvcikge1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbkNvZGVNaXJyb3IucmVnaXN0ZXJIZWxwZXIoXCJmb2xkXCIsIFwiaW5kZW50XCIsIGZ1bmN0aW9uKGNtLCBzdGFydCkge1xuICB2YXIgdGFiU2l6ZSA9IGNtLmdldE9wdGlvbihcInRhYlNpemVcIiksIGZpcnN0TGluZSA9IGNtLmdldExpbmUoc3RhcnQubGluZSk7XG4gIGlmICghL1xcUy8udGVzdChmaXJzdExpbmUpKSByZXR1cm47XG4gIHZhciBnZXRJbmRlbnQgPSBmdW5jdGlvbihsaW5lKSB7XG4gICAgcmV0dXJuIENvZGVNaXJyb3IuY291bnRDb2x1bW4obGluZSwgbnVsbCwgdGFiU2l6ZSk7XG4gIH07XG4gIHZhciBteUluZGVudCA9IGdldEluZGVudChmaXJzdExpbmUpO1xuICB2YXIgbGFzdExpbmVJbkZvbGQgPSBudWxsO1xuICAvLyBHbyB0aHJvdWdoIGxpbmVzIHVudGlsIHdlIGZpbmQgYSBsaW5lIHRoYXQgZGVmaW5pdGVseSBkb2Vzbid0IGJlbG9uZyBpblxuICAvLyB0aGUgYmxvY2sgd2UncmUgZm9sZGluZywgb3IgdG8gdGhlIGVuZC5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0LmxpbmUgKyAxLCBlbmQgPSBjbS5sYXN0TGluZSgpOyBpIDw9IGVuZDsgKytpKSB7XG4gICAgdmFyIGN1ckxpbmUgPSBjbS5nZXRMaW5lKGkpO1xuICAgIHZhciBjdXJJbmRlbnQgPSBnZXRJbmRlbnQoY3VyTGluZSk7XG4gICAgaWYgKGN1ckluZGVudCA+IG15SW5kZW50KSB7XG4gICAgICAvLyBMaW5lcyB3aXRoIGEgZ3JlYXRlciBpbmRlbnQgYXJlIGNvbnNpZGVyZWQgcGFydCBvZiB0aGUgYmxvY2suXG4gICAgICBsYXN0TGluZUluRm9sZCA9IGk7XG4gICAgfSBlbHNlIGlmICghL1xcUy8udGVzdChjdXJMaW5lKSkge1xuICAgICAgLy8gRW1wdHkgbGluZXMgbWlnaHQgYmUgYnJlYWtzIHdpdGhpbiB0aGUgYmxvY2sgd2UncmUgdHJ5aW5nIHRvIGZvbGQuXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEEgbm9uLWVtcHR5IGxpbmUgYXQgYW4gaW5kZW50IGVxdWFsIHRvIG9yIGxlc3MgdGhhbiBvdXJzIG1hcmtzIHRoZVxuICAgICAgLy8gc3RhcnQgb2YgYW5vdGhlciBibG9jay5cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAobGFzdExpbmVJbkZvbGQpIHJldHVybi
23459B7XG4gICAgZnJvbTogQ29kZU1pcnJvci5Qb3Moc3RhcnQubGluZSwgZmlyc3RMaW5lLmxlbmd0aCksXG4gICAgdG86IENvZGVNaXJyb3IuUG9zKGxhc3RMaW5lSW5Gb2xkLCBjbS5nZXRMaW5lKGxhc3RMaW5lSW5Gb2xkKS5sZW5ndGgpXG4gIH07XG59KTtcblxufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbihmdW5jdGlvbihtb2QpIHtcbiAgaWYgKHR5cGVvZiBleHBvcnRzID09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PSBcIm9iamVjdFwiKSAvLyBDb21tb25KU1xuICAgIG1vZChyZXF1aXJlKFwiLi4vLi4vbGliL2NvZGVtaXJyb3JcIikpO1xuICBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSAvLyBBTURcbiAgICBkZWZpbmUoW1wiLi4vLi4vbGliL2NvZGVtaXJyb3JcIl0sIG1vZCk7XG4gIGVsc2UgLy8gUGxhaW4gYnJvd3NlciBlbnZcbiAgICBtb2QoQ29kZU1pcnJvcik7XG59KShmdW5jdGlvbihDb2RlTWlycm9yKSB7XG4gIHZhciBQb3MgPSBDb2RlTWlycm9yLlBvcztcblxuICBmdW5jdGlvbiBmb3JFYWNoKGFyciwgZikge1xuICAgIGZvciAodmFyIGkgPSAwLCBlID0gYXJyLmxlbmd0aDsgaSA8IGU7ICsraSkgZihhcnJbaV0pO1xuICB9XG5cbiAgZnVuY3Rpb24gYXJyYXlDb250YWlucyhhcnIsIGl0ZW0pIHtcbiAgICBpZiAoIUFycmF5LnByb3RvdHlwZS5pbmRleE9mKSB7XG4gICAgICB2Y
23459XIgaSA9IGFyci5sZW5ndGg7XG4gICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgIGlmIChhcnJbaV0gPT09IGl0ZW0pIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gYXJyLmluZGV4T2YoaXRlbSkgIT0gLTE7XG4gIH1cblxuICBmdW5jdGlvbiBzY3JpcHRIaW50KGVkaXRvciwga2V5d29yZHMsIGdldFRva2VuLCBvcHRpb25zKSB7XG4gICAgLy8gRmluZCB0aGUgdG9rZW4gYXQgdGhlIGN1cnNvclxuICAgIHZhciBjdXIgPSBlZGl0b3IuZ2V0Q3Vyc29yKCksIHRva2VuID0gZ2V0VG9rZW4oZWRpdG9yLCBjdXIpO1xuICAgIGlmICgvXFxiKD86c3RyaW5nfGNvbW1lbnQpXFxiLy50ZXN0KHRva2VuLnR5cGUpKSByZXR1cm47XG4gICAgdG9rZW4uc3RhdGUgPSBDb2RlTWlycm9yLmlubmVyTW9kZShlZGl0b3IuZ2V0TW9kZSgpLCB0b2tlbi5zdGF0ZSkuc3RhdGU7XG5cbiAgICAvLyBJZiBpdCdzIG5vdCBhICd3b3JkLXN0eWxlJyB0b2tlbiwgaWdub3JlIHRoZSB0b2tlbi5cbiAgICBpZiAoIS9eW1xcdyRfXSokLy50ZXN0KHRva2VuLnN0cmluZykpIHtcbiAgICAgIHRva2VuID0ge3N0YXJ0OiBjdXIuY2gsIGVuZDogY3VyLmNoLCBzdHJpbmc6IFwiXCIsIHN0YXRlOiB0b2tlbi5zdGF0ZSxcbiAgICAgICAgICAgICAgIHR5cGU6IHRva2VuLnN0cmluZyA9PSBcIi5cIiA/IFwicHJvcGVydHlcIiA6IG51bGx9O1xuICAgIH0gZWxzZSBpZiAodG9rZW4uZW5kID4gY3VyLmNoKSB7XG4gICAgICB0b2tlbi5lbmQgPSBjdXIuY2g7XG4gICAgICB0b2tlbi5zdHJpbmcgPSB0b2tlbi5zdHJpbmcuc2xpY2UoMCwgY3VyLmNoIC0gdG9rZW4uc3RhcnQpO1xuICAgIH1cblxuICAgIHZhciB0cHJvcCA9IHRva2VuO1xuICAgIC8vIElmIGl0IGlzIGEgcHJvcGVydHksIGZpbmQgb3V0IHdoYXQgaXQgaXMgYSBwcm9wZXJ0eSBvZi5cbiAgICB3aGlsZSAodHByb3AudHlwZSA9PSBcInByb3BlcnR5XCIpIHtcbiAgICAgIHRwcm9wID0gZ2V0VG9rZW4oZWRpdG9yLCBQb3MoY3VyLmxpbmUsIHRwcm9wLnN0YXJ0KSk7XG4gICAgICBpZiAodHByb3Auc3RyaW5nICE9IFwiLlwiKSByZXR1cm47XG4gICAgICB0cHJvcCA9IGdldFRva2VuKGVkaXRvciwgUG9zKGN1ci5saW5lLCB0cHJvcC5zdGFydCkpO1xuICAgICAgaWYgKCFjb250ZXh0KSB2YXIgY29udGV4dCA9IFtdO1xuICAgICAgY29udGV4dC5wdXNoKHRwcm9wKTtcbiAgICB9XG4gICAgcmV0dXJuIHtsaXN0OiBnZXRDb21wbGV0aW9ucyh0b2tlbiwgY29udGV4dCwga2V5d29yZHMsIG9wdGlvbnMpLFxuICAgICAgICAgICAgZnJvbTogUG9zKGN1ci5saW5lLCB0b2tlbi5zdGFydCksXG4gICAgICAgICAgICB0bzogUG9zKGN1ci5saW5lLCB0b2tlbi5lbmQpfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGphdmFzY3JpcHRIaW50KGVkaXRvciwgb3B0aW9ucykge1xuICAgIHJldHVybiBzY3JpcHRIaW50KGVkaXRvciwgamF2YXNjcmlwdEtleXdvcmRzLFxuICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChlLCBjdXIpIHtyZXR1cm4gZS5nZXRUb2tlbkF0KGN1cik7fSxcbiAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zKTtcbiAgfTtcbiAgQ29kZU1pcnJvci5yZWdpc3RlckhlbHBlcihcImhpbnRcIiwgXCJqYXZhc2NyaXB0XCIsIGphdmFzY3JpcHRIaW50KTtcblxuICBmdW5jdGlvbiBnZXRDb2ZmZWVTY3JpcHRUb2tlbihlZGl0b3IsIGN1cikge1xuICAvLyBUaGlzIGdldFRva2VuLCBpdCBpcyBmb3IgY29mZmVlc2NyaXB0LCBpbWl0YXRlcyB0aGUgYmVoYXZpb3Igb2ZcbiAgLy8gZ2V0VG9rZW5BdCBtZXRob2QgaW4gamF2YXNjcmlwdC5qcywgdGhhdCBpcywgcmV0dXJuaW5nIFwicHJvcGVydHlcIlxuICAvLyB0eXBlIGFuZCB0cmVhdCBcIi5cIiBhcyBpbmRlcGVuZW50IHRva2VuLlxuICAgIHZhciB0b2tlbiA9IGVkaXRvci5nZXRUb2tlbkF0KGN1cik7XG4gICAgaWYgKGN1ci5jaCA9PSB0b2tlbi5zdGFydCArIDEgJiYgdG9rZW4uc3RyaW5nLmNoYXJBdCgwKSA9PSAnLicpIHtcbiAgICAgIHRva2VuLmVuZCA9IHRva2VuLnN0YXJ0O1xuICAgICAgdG9rZW4uc3RyaW5nID0gJy4nO1xuICAgICAgdG9rZW4udHlwZSA9IFwicHJvcGVydHlcIjtcbiAgICB9XG4gICAgZWxzZSBpZiAoL15cXC5bXFx3JF9dKiQvLnRlc3QodG9rZW4uc3RyaW5nKSkge1xuICAgICAgdG9rZW4udHlwZSA9IFwicHJvcGVydHlcIjtcbiAgICAgIHRva2VuLnN0YXJ0Kys7XG4gICAgICB0b2tlbi5zdHJpbmcgPSB0b2tlbi5zdHJpbmcucmVwbGFjZSgvXFwuLywgJycpO1xuICAgIH1cbiAgICByZXR1cm4gdG9rZW47XG4gIH1cblxuICBmdW5jdGlvbiBjb2ZmZWVzY3JpcHRIaW50KGVkaXRvciwgb3B0aW9ucykge1xuICAgIHJldHVybiBzY3JpcHRIaW50KGVkaXRvciwgY29mZmVlc2NyaXB0S2V5d29yZHMsIGdldENvZmZlZVNjcmlwdFRva2VuLCBvcHRpb25zKTtcbiAgfVxuICBDb2RlTWlycm9yLnJlZ2lzdGVySGVscGVyKFwiaGludFwiLCBcImNvZmZlZXNjcmlwdFwiLCBjb2ZmZWVzY3JpcHRIaW50KTtcblxuICB2YXIgc3RyaW5nUHJvcHMgPSAoXCJjaGFyQXQgY2hhckNvZGVBdCBpbmRleE9mIGxhc3RJbmRleE9mIHN1YnN0cmluZyBzdWJzdHIgc2xpY2UgdHJpbSB0cmltTGVmdCB0cmltUmlnaHQgXCIgK1xuICAgICAgICAgICAgICAgICAgICAgXCJ0b1VwcGVyQ2FzZSB0b0xvd2VyQ2FzZSBzcGxpdCBjb25jYXQgbWF0Y2ggcmVwbGFjZSBzZWFyY2hcIikuc3BsaXQoXCIgXCIpO1xuICB2YXIgYXJyYXlQcm9wcyA9IChcImxlbmd0aCBjb25jYXQgam9pbiBzcGxpY2UgcHVzaCBwb3Agc2hpZnQgdW5zaGlmdCBzbGljZSByZXZlcnNlIHNvcnQgaW5kZXhPZiBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwibGFzdEluZGV4T2YgZXZlcnkgc29tZSBmaWx0ZXIgZm9yRWFjaCBtYXAgcmVkdWNlIHJlZHVjZVJpZ2h0IFwiKS5zcGxpdChcIiBcIik7XG4gIHZhciBmdW5jUHJvcHMgPSBcInByb3RvdHlwZSBhc
23459HBseSBjYWxsIGJpbmRcIi5zcGxpdChcIiBcIik7XG4gIHZhciBqYXZhc2NyaXB0S2V5d29yZHMgPSAoXCJicmVhayBjYXNlIGNhdGNoIGNvbnRpbnVlIGRlYnVnZ2VyIGRlZmF1bHQgZGVsZXRlIGRvIGVsc2UgZmFsc2UgZmluYWxseSBmb3IgZnVuY3Rpb24gXCIgK1xuICAgICAgICAgICAgICAgICAgXCJpZiBpbiBpbnN0YW5jZW9mIG5ldyBudWxsIHJldHVybiBzd2l0Y2ggdGhyb3cgdHJ1ZSB0cnkgdHlwZW9mIHZhciB2b2lkIHdoaWxlIHdpdGhcIikuc3BsaXQoXCIgXCIpO1xuICB2YXIgY29mZmVlc2NyaXB0S2V5d29yZHMgPSAoXCJhbmQgYnJlYWsgY2F0Y2ggY2xhc3MgY29udGludWUgZGVsZXRlIGRvIGVsc2UgZXh0ZW5kcyBmYWxzZSBmaW5hbGx5IGZvciBcIiArXG4gICAgICAgICAgICAgICAgICBcImlmIGluIGluc3RhbmNlb2YgaXNudCBuZXcgbm8gbm90IG51bGwgb2Ygb2ZmIG9uIG9yIHJldHVybiBzd2l0Y2ggdGhlbiB0aHJvdyB0cnVlIHRyeSB0eXBlb2YgdW50aWwgdm9pZCB3aGlsZSB3aXRoIHllc1wiKS5zcGxpdChcIiBcIik7XG5cbiAgZnVuY3Rpb24gZ2V0Q29tcGxldGlvbnModG9rZW4sIGNvbnRleHQsIGtleXdvcmRzLCBvcHRpb25zKSB7XG4gICAgdmFyIGZvdW5kID0gW10sIHN0YXJ0ID0gdG9rZW4uc3RyaW5nLCBnbG9iYWwgPSBvcHRpb25zICYmIG9wdGlvbnMuZ2xvYmFsU2NvcGUgfHwgd2luZG93O1xuICAgIGZ1bmN0aW9uIG1heWJlQWRkKHN0cikge1xuICAgICAgaWYgKHN0ci5sYXN0SW5kZXhPZihzdGFydCwgMCkgPT0gMCAmJiAhYXJyYXlDb250YWlucyhmb3VuZCwgc3RyKSkgZm91bmQucHVzaChzdHIpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBnYXRoZXJDb21wbGV0aW9ucyhvYmopIHtcbiAgICAgIGlmICh0eXBlb2Ygb2JqID09IFwic3RyaW5nXCIpIGZvckVhY2goc3RyaW5nUHJvcHMsIG1heWJlQWRkKTtcbiAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIEFycmF5KSBmb3JFYWNoKGFycmF5UHJvcHMsIG1heWJlQWRkKTtcbiAgICAgIGVsc2UgaWYgKG9iaiBpbnN0YW5jZW9mIEZ1bmN0aW9uKSBmb3JFYWNoKGZ1bmNQcm9wcywgbWF5YmVBZGQpO1xuICAgICAgZm9yICh2YXIgbmFtZSBpbiBvYmopIG1heWJlQWRkKG5hbWUpO1xuICAgIH1cblxuICAgIGlmIChjb250ZXh0ICYmIGNvbnRleHQubGVuZ3RoKSB7XG4gICAgICAvLyBJZiB0aGlzIGlzIGEgcHJvcGVydHksIHNlZSBpZiBpdCBiZWxvbmdzIHRvIHNvbWUgb2JqZWN0IHdlIGNhblxuICAgICAgLy8gZmluZCBpbiB0aGUgY3VycmVudCBlbnZpcm9ubWVudC5cbiAgICAgIHZhciBvYmogPSBjb250ZXh0LnBvcCgpLCBiYXNlO1xuICAgICAgaWYgKG9iai50eXBlICYmIG9iai50eXBlLmluZGV4T2YoXCJ2YXJpYWJsZVwiKSA9PT0gMCkge1xuICAgICAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmFkZGl0aW9uYWxDb250ZXh0KVxuICAgICAgICAgIGJhc2UgPSBvcHRpb25zLmFkZGl0aW9uYWxDb250ZXh0W29iai5zdHJpbmddO1xuICAgICAgICBpZiAoIW9wdGlvbnMgfHwgb3B0aW9ucy51c2VHbG9iYWxTY29wZSAhPT0gZmFsc2UpXG4gICAgICAgICAgYmFzZSA9IGJhc2UgfHwgZ2xvYmFsW29iai5zdHJpbmddO1xuICAgICAgfSBlbHNlIGlmIChvYmoudHlwZSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGJhc2UgPSBcIlwiO1xuICAgICAgfSBlbHNlIGlmIChvYmoudHlwZSA9PSBcImF0b21cIikge1xuICAgICAgICBiYXNlID0gMTtcbiAgICAgIH0gZWxzZSBpZiAob2JqLnR5cGUgPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGlmIChnbG9iYWwualF1ZXJ5ICE9IG51bGwgJiYgKG9iai5zdHJpbmcgPT0gJyQnIHx8IG9iai5zdHJpbmcgPT0gJ2pRdWVyeScpICYmXG4gICAgICAgICAgICAodHlwZW9mIGdsb2JhbC5qUXVlcnkgPT0gJ2Z1bmN0aW9uJykpXG4gICAgICAgICAgYmFzZSA9IGdsb2JhbC5qUXVlcnkoKTtcbiAgICAgICAgZWxzZSBpZiAoZ2xvYmFsLl8gIT0gbnVsbCAmJiAob2JqLnN0cmluZyA9PSAnXycpICYmICh0eXBlb2YgZ2xvYmFsLl8gPT0gJ2Z1bmN0aW9uJykpXG4gICAgICAgICAgYmFzZSA9IGdsb2JhbC5fKCk7XG4gICAgICB9XG4gICAgICB3aGlsZSAoYmFzZSAhPSBudWxsICYmIGNvbnRleHQubGVuZ3RoKVxuICAgICAgICBiYXNlID0gYmFzZVtjb250ZXh0LnBvcCgpLnN0cmluZ107XG4gICAgICBpZiAoYmFzZSAhPSBudWxsKSBnYXRoZXJDb21wbGV0aW9ucyhiYXNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgbm90LCBqdXN0IGxvb2sgaW4gdGhlIGdsb2JhbCBvYmplY3QgYW5kIGFueSBsb2NhbCBzY29wZVxuICAgICAgLy8gKHJlYWRpbmcgaW50byBKUyBtb2RlIGludGVybmFscyB0byBnZXQgYXQgdGhlIGxvY2FsIGFuZCBnbG9iYWwgdmFyaWFibGVzKVxuICAgICAgZm9yICh2YXIgdiA9IHRva2VuLnN0YXRlLmxvY2FsVmFyczsgdjsgdiA9IHYubmV4dCkgbWF5YmVBZGQodi5uYW1lKTtcbiAgICAgIGZvciAodmFyIHYgPSB0b2tlbi5zdGF0ZS5nbG9iYWxWYXJzOyB2OyB2ID0gdi5uZXh0KSBtYXliZUFkZCh2Lm5hbWUpO1xuICAgICAgaWYgKCFvcHRpb25zIHx8IG9wdGlvbnMudXNlR2xvYmFsU2NvcGUgIT09IGZhbHNlKVxuICAgICAgICBnYXRoZXJDb21wbGV0aW9ucyhnbG9iYWwpO1xuICAgICAgZm9yRWFjaChrZXl3b3JkcywgbWF5YmVBZGQpO1xuICAgIH1cbiAgICByZXR1cm4gZm91bmQ7XG4gIH1cbn0pO1xuIiwiLy8gQ29kZU1pcnJvciwgY29weXJpZ2h0IChjKSBieSBNYXJpam4gSGF2ZXJiZWtlIGFuZCBvdGhlcnNcbi8vIERpc3RyaWJ1dGVkIHVuZGVyIGFuIE1JVCBsaWNlbnNlOiBodHRwOi8vY29kZW1pcnJvci5uZXQvTElDRU5TRVxuXG4oZnVuY3Rpb24obW9kKSB7XG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUgPT0gXCJvYmplY3RcIikgLy8gQ29tbW9uSlNcbiAgICBtb2QocmVxdWlyZShcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCJdLCBtb2QpO1xuICBlbHNlIC8vIFBsYWluIGJyb3dzZXIgZW52XG4gICAgbW9kKENvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24oQ29kZU1pcnJvcikge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICB2Y
23459XIgSElOVF9FTEVNRU5UX0NMQVNTICAgICAgICA9IFwiQ29kZU1pcnJvci1oaW50XCI7XG4gIHZhciBBQ1RJVkVfSElOVF9FTEVNRU5UX0NMQVNTID0gXCJDb2RlTWlycm9yLWhpbnQtYWN0aXZlXCI7XG5cbiAgLy8gVGhpcyBpcyB0aGUgb2xkIGludGVyZmFjZSwga2VwdCBhcm91bmQgZm9yIG5vdyB0byBzdGF5XG4gIC8vIGJhY2t3YXJkcy1jb21wYXRpYmxlLlxuICBDb2RlTWlycm9yLnNob3dIaW50ID0gZnVuY3Rpb24oY20sIGdldEhpbnRzLCBvcHRpb25zKSB7XG4gICAgaWYgKCFnZXRIaW50cykgcmV0dXJuIGNtLnNob3dIaW50KG9wdGlvbnMpO1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYXN5bmMpIGdldEhpbnRzLmFzeW5jID0gdHJ1ZTtcbiAgICB2YXIgbmV3T3B0cyA9IHtoaW50OiBnZXRIaW50c307XG4gICAgaWYgKG9wdGlvbnMpIGZvciAodmFyIHByb3AgaW4gb3B0aW9ucykgbmV3T3B0c1twcm9wXSA9IG9wdGlvbnNbcHJvcF07XG4gICAgcmV0dXJuIGNtLnNob3dIaW50KG5ld09wdHMpO1xuICB9O1xuXG4gIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uKFwic2hvd0hpbnRcIiwgZnVuY3Rpb24ob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBwYXJzZU9wdGlvbnModGhpcywgdGhpcy5nZXRDdXJzb3IoXCJzdGFydFwiKSwgb3B0aW9ucyk7XG4gICAgdmFyIHNlbGVjdGlvbnMgPSB0aGlzLmxpc3RTZWxlY3Rpb25zKClcbiAgICBpZiAoc2VsZWN0aW9ucy5sZW5ndGggPiAxKSByZXR1cm47XG4gICAgLy8gQnkgZGVmYXVsdCwgZG9uJ3QgYWxsb3cgY29tcGxldGlvbiB3aGVuIHNvbWV0aGluZyBpcyBzZWxlY3RlZC5cbiAgICAvLyBBIGhpbnQgZnVuY3Rpb24gY2FuIGhhdmUgYSBgc3VwcG9ydHNTZWxlY3Rpb25gIHByb3BlcnR5IHRvXG4gICAgLy8gaW5kaWNhdGUgdGhhdCBpdCBjYW4gaGFuZGxlIHNlbGVjdGlvbnMuXG4gICAgaWYgKHRoaXMuc29tZXRoaW5nU2VsZWN0ZWQoKSkge1xuICAgICAgaWYgKCFvcHRpb25zLmhpbnQuc3VwcG9ydHNTZWxlY3Rpb24pIHJldHVybjtcbiAgICAgIC8vIERvbid0IHRyeSB3aXRoIGNyb3NzLWxpbmUgc2VsZWN0aW9uc1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWxlY3Rpb25zLmxlbmd0aDsgaSsrKVxuICAgICAgICBpZiAoc2VsZWN0aW9uc1tpXS5oZWFkLmxpbmUgIT0gc2VsZWN0aW9uc1tpXS5hbmNob3IubGluZSkgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlLmNvbXBsZXRpb25BY3RpdmUpIHRoaXMuc3RhdGUuY29tcGxldGlvbkFjdGl2ZS5jbG9zZSgpO1xuICAgIHZhciBjb21wbGV0aW9uID0gdGhpcy5zdGF0ZS5jb21wbGV0aW9uQWN0aXZlID0gbmV3IENvbXBsZXRpb24odGhpcywgb3B0aW9ucyk7XG4gICAgaWYgKCFjb21wbGV0aW9uLm9wdGlvbnMuaGludCkgcmV0dXJuO1xuXG4gICAgQ29kZU1pcnJvci5zaWduYWwodGhpcywgXCJzdGFydENvbXBsZXRpb25cIiwgdGhpcyk7XG4gICAgY29tcGxldGlvbi51cGRhdGUodHJ1ZSk7XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIENvbXBsZXRpb24oY20sIG9wdGlvbnMpIHtcbiAgICB0aGlzLmNtID0gY207XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLndpZGdldCA9IG51bGw7XG4gICAgdGhpcy5kZWJvdW5jZSA9IDA7XG4gICAgdGhpcy50aWNrID0gMDtcbiAgICB0aGlzLnN0YXJ0UG9zID0gdGhpcy5jbS5nZXRDdXJzb3IoXCJzdGFydFwiKTtcbiAgICB0aGlzLnN0YXJ0TGVuID0gdGhpcy5jbS5nZXRMaW5lKHRoaXMuc3RhcnRQb3MubGluZSkubGVuZ3RoIC0gdGhpcy5jbS5nZXRTZWxlY3Rpb24oKS5sZW5ndGg7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgY20ub24oXCJjdXJzb3JBY3Rpdml0eVwiLCB0aGlzLmFjdGl2aXR5RnVuYyA9IGZ1bmN0aW9uKCkgeyBzZWxmLmN1cnNvckFjdGl2aXR5KCk7IH0pO1xuICB9XG5cbiAgdmFyIHJlcXVlc3RBbmltYXRpb25GcmFtZSA9IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHwgZnVuY3Rpb24oZm4pIHtcbiAgICByZXR1cm4gc2V0VGltZW91dChmbiwgMTAwMC82MCk7XG4gIH07XG4gIHZhciBjYW5jZWxBbmltYXRpb25GcmFtZSA9IHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSB8fCBjbGVhclRpbWVvdXQ7XG5cbiAgQ29tcGxldGlvbi5wcm90b3R5cGUgPSB7XG4gICAgY2xvc2U6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLmFjdGl2ZSgpKSByZXR1cm47XG4gICAgICB0aGlzLmNtLnN0YXRlLmNvbXBsZXRpb25BY3RpdmUgPSBudWxsO1xuICAgICAgdGhpcy50aWNrID0gbnVsbDtcbiAgICAgIHRoaXMuY20ub2ZmKFwiY3Vyc29yQWN0aXZpdHlcIiwgdGhpcy5hY3Rpdml0eUZ1bmMpO1xuXG4gICAgICBpZiAodGhpcy53aWRnZXQgJiYgdGhpcy5kYXRhKSBDb2RlTWlycm9yLnNpZ25hbCh0aGlzLmRhdGEsIFwiY2xvc2VcIik7XG4gICAgICBpZiAodGhpcy53aWRnZXQpIHRoaXMud2lkZ2V0LmNsb3NlKCk7XG4gICAgICBDb2RlTWlycm9yLnNpZ25hbCh0aGlzLmNtLCBcImVuZENvbXBsZXRpb25cIiwgdGhpcy5jbSk7XG4gICAgfSxcblxuICAgIGFjdGl2ZTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5jbS5zdGF0ZS5jb21wbGV0aW9uQWN0aXZlID09IHRoaXM7XG4gICAgfSxcblxuICAgIHBpY2s6IGZ1bmN0aW9uKGRhdGEsIGkpIHtcbiAgICAgIHZhciBjb21wbGV0aW9uID0gZGF0YS5saXN0W2ldO1xuICAgICAgaWYgKGNvbXBsZXRpb24uaGludCkgY29tcGxldGlvbi5oaW50KHRoaXMuY20sIGRhdGEsIGNvbXBsZXRpb24pO1xuICAgICAgZWxzZSB0aGlzLmNtLnJlcGxhY2VSYW5nZShnZXRUZXh0KGNvbXBsZXRpb24pLCBjb21wbGV0aW9uLmZyb20gfHwgZGF0YS5mcm9tLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uLnRvIHx8IGRhdGEudG8sIFwiY29tcGxldGVcIik7XG4gICAgICBDb2RlTWlycm9yLnNpZ25hbChkYXRhLCBcInBpY2tcIiwgY29tcGxldGlvbik7XG4gICAgICB0aGlzLmNsb3NlKCk7XG4gICAgfSxcblxuICAgIGN1cnNvckFjdGl2aXR5OiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmRlYm91bmNlKSB7XG4gICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuZGVib3VuY2UpO1xuICAgICAgICB0aGlzLmRlYm91bmNlID0gMDtcbiAgICAgIH1cblxuICAgICAgdmFyIHBvcyA9IHRoaXMuY20uZ2V0Q3Vyc29yKCksIGxpbmUgPSB0aGlzLmNtLmdldExpbmUocG9zLmxpbmUpO1xuICAgICAgaWYgKHBvcy5saW5lICE9IHRoaXMuc3RhcnRQb3MubGluZSB8fCBsaW5lLmxlbmd0aCAtIHBvcy5jaCAhPSB0aGlzLnN0YXJ0TGVuIC0gdGhpcy5zdGFydFBvcy5jaCB8fFxuICAgICAgICAgI
23459HBvcy5jaCA8IHRoaXMuc3RhcnRQb3MuY2ggfHwgdGhpcy5jbS5zb21ldGhpbmdTZWxlY3RlZCgpIHx8XG4gICAgICAgICAgKHBvcy5jaCAmJiB0aGlzLm9wdGlvbnMuY2xvc2VDaGFyYWN0ZXJzLnRlc3QobGluZS5jaGFyQXQocG9zLmNoIC0gMSkpKSkge1xuICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgIHRoaXMuZGVib3VuY2UgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24oKSB7c2VsZi51cGRhdGUoKTt9KTtcbiAgICAgICAgaWYgKHRoaXMud2lkZ2V0KSB0aGlzLndpZGdldC5kaXNhYmxlKCk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIHVwZGF0ZTogZnVuY3Rpb24oZmlyc3QpIHtcbiAgICAgIGlmICh0aGlzLnRpY2sgPT0gbnVsbCkgcmV0dXJuO1xuICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuaGludC5hc3luYykge1xuICAgICAgICB0aGlzLmZpbmlzaFVwZGF0ZSh0aGlzLm9wdGlvbnMuaGludCh0aGlzLmNtLCB0aGlzLm9wdGlvbnMpLCBmaXJzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgbXlUaWNrID0gKyt0aGlzLnRpY2ssIHNlbGYgPSB0aGlzO1xuICAgICAgICB0aGlzLm9wdGlvbnMuaGludCh0aGlzLmNtLCBmdW5jdGlvbihkYXRhKSB7XG4gICAgICAgICAgaWYgKHNlbGYudGljayA9PSBteVRpY2spIHNlbGYuZmluaXNoVXBkYXRlKGRhdGEsIGZpcnN0KTtcbiAgICAgICAgfSwgdGhpcy5vcHRpb25zKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgZmluaXNoVXBkYXRlOiBmdW5jdGlvbihkYXRhLCBmaXJzdCkge1xuICAgICAgaWYgKHRoaXMuZGF0YSkgQ29kZU1pcnJvci5zaWduYWwodGhpcy5kYXRhLCBcInVwZGF0ZVwiKTtcbiAgICAgIGlmIChkYXRhICYmIHRoaXMuZGF0YSAmJiBDb2RlTWlycm9yLmNtcFBvcyhkYXRhLmZyb20sIHRoaXMuZGF0YS5mcm9tKSkgZGF0YSA9IG51bGw7XG4gICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuXG4gICAgICB2Y
23459XIgcGlja2VkID0gKHRoaXMud2lkZ2V0ICYmIHRoaXMud2lkZ2V0LnBpY2tlZCkgfHwgKGZpcnN0ICYmIHRoaXMub3B0aW9ucy5jb21wbGV0ZVNpbmdsZSk7XG4gICAgICBpZiAodGhpcy53aWRnZXQpIHRoaXMud2lkZ2V0LmNsb3NlKCk7XG4gICAgICBpZiAoZGF0YSAmJiBkYXRhLmxpc3QubGVuZ3RoKSB7XG4gICAgICAgIGlmIChwaWNrZWQgJiYgZGF0YS5saXN0Lmxlbmd0aCA9PSAxKSB7XG4gICAgICAgICAgdGhpcy5waWNrKGRhdGEsIDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMud2lkZ2V0ID0gbmV3IFdpZGdldCh0aGlzLCBkYXRhKTtcbiAgICAgICAgICBDb2RlTWlycm9yLnNpZ25hbChkYXRhLCBcInNob3duXCIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIHBhcnNlT3B0aW9ucyhjbSwgcG9zLCBvcHRpb25zKSB7XG4gICAgdmFyIGVkaXRvciA9IGNtLm9wdGlvbnMuaGludE9wdGlvbnM7XG4gICAgdmFyIG91dCA9IHt9O1xuICAgIGZvciAodmFyIHByb3AgaW4gZGVmYXVsdE9wdGlvbnMpIG91dFtwcm9wXSA9IGRlZmF1bHRPcHRpb25zW3Byb3BdO1xuICAgIGlmIChlZGl0b3IpIGZvciAodmFyIHByb3AgaW4gZWRpdG9yKVxuICAgICAgaWYgKGVkaXRvcltwcm9wXSAhPT0gdW5kZWZpbmVkKSBvdXRbcHJvcF0gPSBlZGl0b3JbcHJvcF07XG4gICAgaWYgKG9wdGlvbnMpIGZvciAodmFyIHByb3AgaW4gb3B0aW9ucylcbiAgICAgIGlmIChvcHRpb25zW3Byb3BdICE9PSB1bmRlZmluZWQpIG91dFtwcm9wXSA9IG9wdGlvbnNbcHJvcF07XG4gICAgaWYgKG91dC5oaW50LnJlc29sdmUpIG91dC5oaW50ID0gb3V0LmhpbnQucmVzb2x2ZShjbSwgcG9zKVxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRUZXh0KGNvbXBsZXRpb24pIHtcbiAgICBpZiAodHlwZW9mIGNvbXBsZXRpb24gPT0gXCJzdHJpbmdcIikgcmV0dXJuIGNvbXBsZXRpb247XG4gICAgZWxzZSByZXR1cm4gY29tcGxldGlvbi50ZXh0O1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRLZXlNYXAoY29tcGxldGlvbiwgaGFuZGxlKSB7XG4gICAgdmFyIGJhc2VNYXAgPSB7XG4gICAgICBVcDogZnVuY3Rpb24oKSB7aGFuZGxlLm1vdmVGb2N1cygtMSk7fSxcbiAgICAgIERvd246IGZ1bmN0aW9uKCkge2hhbmRsZS5tb3ZlRm9jdXMoMSk7fSxcbiAgICAgIFBhZ2VVcDogZnVuY3Rpb24oKSB7aGFuZGxlLm1vdmVGb2N1cygtaGFuZGxlLm1lbnVTaXplKCkgKyAxLCB0cnVlKTt9LFxuICAgICAgUGFnZURvd246IGZ1bmN0aW9uKCkge2hhbmRsZS5tb3ZlRm9jdXMoaGFuZGxlLm1lbnVTaXplKCkgLSAxLCB0cnVlKTt9LFxuICAgICAgSG9tZTogZnVuY3Rpb24oKSB7aGFuZGxlLnNldEZvY3VzKDApO30sXG4gICAgICBFbmQ6IGZ1bmN0aW9uKCkge2hhbmRsZS5zZXRGb2N1cyhoYW5kbGUubGVuZ3RoIC0gMSk7fSxcbiAgICAgIEVudGVyOiBoYW5kbGUucGljayxcbiAgICAgIFRhYjogaGFuZGxlLnBpY2ssXG4gICAgICBFc2M6IGhhbmRsZS5jbG9zZVxuICAgIH07XG4gICAgdmFyIGN1c3RvbSA9IGNvbXBsZXRpb24ub3B0aW9ucy5jdXN0b21LZXlzO1xuICAgIHZhciBvdXJNYXAgPSBjdXN0b20gPyB7fSA6IGJhc2VNYXA7XG4gICAgZnVuY3Rpb24gYWRkQmluZGluZyhrZXksIHZhbCkge1xuICAgICAgdmFyIGJvdW5kO1xuICAgICAgaWYgKHR5cGVvZiB2YWwgIT0gXCJzdHJpbmdcIilcbiAgICAgICAgYm91bmQgPSBmdW5jdGlvbihjbSkgeyByZXR1cm4gdmFsKGNtLCBoYW5kbGUpOyB9O1xuICAgICAgLy8gVGhpcyBtZWNoYW5pc20gaXMgZGVwcmVjYXRlZFxuICAgICAgZWxzZSBpZiAoYmFzZU1hcC5oYXNPd25Qcm9wZXJ0eSh2YWwpKVxuICAgICAgICBib3VuZCA9IGJhc2VNYXBbdmFsXTtcbiAgICAgIGVsc2VcbiAgICAgICAgYm91bmQgPSB2YWw7XG4gICAgICBvdXJNYXBba2V5XSA9IGJvdW5kO1xuICAgIH1cbiAgICBpZiAoY3VzdG9tKVxuICAgICAgZm9yICh2YXIga2V5IGluIGN1c3RvbSkgaWYgKGN1c3RvbS5oYXNPd25Qcm9wZXJ0eShrZXkpKVxuICAgICAgICBhZGRCaW5kaW5nKGtleSwgY3VzdG9tW2tleV0pO1xuICAgIHZhciBleHRyYSA9IGNvbXBsZXRpb24ub3B0aW9ucy5leHRyYUtleXM7XG4gICAgaWYgKGV4dHJhKVxuICAgICAgZm9yICh2YXIga2V5IGluIGV4dHJhKSBpZiAoZXh0cmEuaGFzT3duUHJvcGVydHkoa2V5KSlcbiAgICAgICAgYWRkQmluZGluZyhrZXksIGV4dHJhW2tleV0pO1xuICAgIHJldHVybiBvdXJNYXA7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRIaW50RWxlbWVudChoaW50c0VsZW1lbnQsIGVsKSB7XG4gICAgd2hpbGUgKGVsICYmIGVsICE9IGhpbnRzRWxlbWVudCkge1xuICAgICAgaWYgKGVsLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgPT09IFwiTElcIiAmJiBlbC5wYXJlbnROb2RlID09IGhpbnRzRWxlbWVudCkgcmV0dXJuIGVsO1xuICAgICAgZWwgPSBlbC5wYXJlbnROb2RlO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIFdpZGdldChjb21wbGV0aW9uLCBkYXRhKSB7XG4gICAgdGhpcy5jb21wbGV0aW9uID0gY29tcGxldGlvbjtcbiAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgIHRoaXMucGlja2VkID0gZmFsc2U7XG4gICAgdmFyIHdpZGdldCA9IHRoaXMsIGNtID0gY29tcGxldGlvbi5jbTtcblxuICAgIHZhciBoaW50cyA9IHRoaXMuaGludHMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidWxcIik7XG4gICAgaGludHMuY2xhc3NOYW1lID0gXCJDb2RlTWlycm9yLWhpbnRzXCI7XG4gICAgdGhpcy5zZWxlY3RlZEhpbnQgPSBkYXRhLnNlbGVjdGVkSGludCB8fCAwO1xuXG4gICAgdmFyIGNvbXBsZXRpb25zID0gZGF0YS5saXN0O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29tcGxldGlvbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBlbHQgPSBoaW50cy5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwibGlcIikpLCBjdXIgPSBjb21wbGV0aW9uc1tpXTtcbiAgICAgIHZhciBjbGFzc05hbWUgPSBISU5UX0VMRU1FTlRfQ0xBU1MgKyAoaSAhPSB0aGlzLnNlbGVjdGVkSGludCA/IFwiXCIgOiBcIiBcIiArIEFDVElWRV9ISU5UX0VMRU1FTlRfQ0xBU1MpO1xuICAgICAgaWYgKGN1ci5jbGFzc05hbWUgIT0gbnVsbCkgY2xhc3NOYW1lID0gY3VyLmNsYXNzTmFtZSArIFwiIFwiICsgY2xhc3NOYW1lO1xuICAgICAgZWx0LmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgICAgIGlmIChjdXIucmVuZGVyKSBjdXIucmVuZGVyKGVsdCwgZGF0YSwgY3VyKTtcbiAgICAgIGVsc2UgZWx0LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGN1ci5kaXNwbGF5VGV4dCB8fCBnZXRUZXh0KGN1cikpKTtcbiAgICAgIGVsdC5oaW50SWQgPSBpO1xuICAgIH1cblxuICAgI
23459HZhciBwb3MgPSBjbS5jdXJzb3JDb29yZHMoY29tcGxldGlvbi5vcHRpb25zLmFsaWduV2l0aFdvcmQgPyBkYXRhLmZyb20gOiBudWxsKTtcbiAgICB2YXIgbGVmdCA9IHBvcy5sZWZ0LCB0b3AgPSBwb3MuYm90dG9tLCBiZWxvdyA9IHRydWU7XG4gICAgaGludHMuc3R5bGUubGVmdCA9IGxlZnQgKyBcInB4XCI7XG4gICAgaGludHMuc3R5bGUudG9wID0gdG9wICsgXCJweFwiO1xuICAgIC8vIElmIHdlJ3JlIGF0IHRoZSBlZGdlIG9mIHRoZSBzY3JlZW4sIHRoZW4gd2Ugd2FudCB0aGUgbWVudSB0byBhcHBlYXIgb24gdGhlIGxlZnQgb2YgdGhlIGN1cnNvci5cbiAgICB2YXIgd2luVyA9IHdpbmRvdy5pbm5lcldpZHRoIHx8IE1hdGgubWF4KGRvY3VtZW50LmJvZHkub2Zmc2V0V2lkdGgsIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5vZmZzZXRXaWR0aCk7XG4gICAgdmFyIHdpbkggPSB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgTWF0aC5tYXgoZG9jdW1lbnQuYm9keS5vZmZzZXRIZWlnaHQsIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5vZmZzZXRIZWlnaHQpO1xuICAgIChjb21wbGV0aW9uLm9wdGlvbnMuY29udGFpbmVyIHx8IGRvY3VtZW50LmJvZHkpLmFwcGVuZENoaWxkKGhpbnRzKTtcbiAgICB2YXIgYm94ID0gaGludHMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksIG92ZXJsYXBZID0gYm94LmJvdHRvbSAtIHdpbkg7XG4gICAgaWYgKG92ZXJsYXBZID4gMCkge1xuICAgICAgdmFyIGhlaWdodCA9IGJveC5ib3R0b20gLSBib3gudG9wLCBjdXJUb3AgPSBwb3MudG9wIC0gKHBvcy5ib3R0b20gLSBib3gudG9wKTtcbiAgICAgIGlmIChjdXJUb3AgLSBoZWlnaHQgPiAwKSB7IC8vIEZpdHMgYWJvdmUgY3Vyc29yXG4gICAgICAgIGhpbnRzLnN0eWxlLnRvcCA9ICh0b3AgPSBwb3MudG9wIC0gaGVpZ2h0KSArIFwicHhcIjtcbiAgICAgICAgYmVsb3cgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSBpZiAoaGVpZ2h0ID4gd2luSCkge1xuICAgICAgICBoaW50cy5zdHlsZS5oZWlnaHQgPSAod2luSCAtIDUpICsgXCJweFwiO1xuICAgICAgICBoaW50cy5zdHlsZS50b3AgPSAodG9wID0gcG9zLmJvdHRvbSAtIGJveC50b3ApICsgXCJweFwiO1xuICAgICAgICB2Y
23459XIgY3Vyc29yID0gY20uZ2V0Q3Vyc29yKCk7XG4gICAgICAgIGlmIChkYXRhLmZyb20uY2ggIT0gY3Vyc29yLmNoKSB7XG4gICAgICAgICAgcG9zID0gY20uY3Vyc29yQ29vcmRzKGN1cnNvcik7XG4gICAgICAgICAgaGludHMuc3R5bGUubGVmdCA9IChsZWZ0ID0gcG9zLmxlZnQpICsgXCJweFwiO1xuICAgICAgICAgIGJveCA9IGhpbnRzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHZhciBvdmVybGFwWCA9IGJveC5yaWdodCAtIHdpblc7XG4gICAgaWYgKG92ZXJsYXBYID4gMCkge1xuICAgICAgaWYgKGJveC5yaWdodCAtIGJveC5sZWZ0ID4gd2luVykge1xuICAgICAgICBoaW50cy5zdHlsZS53aWR0aCA9ICh3aW5XIC0gNSkgKyBcInB4XCI7XG4gICAgICAgIG92ZXJsYXBYIC09IChib3gucmlnaHQgLSBib3gubGVmdCkgLSB3aW5XO1xuICAgICAgfVxuICAgICAgaGludHMuc3R5bGUubGVmdCA9IChsZWZ0ID0gcG9zLmxlZnQgLSBvdmVybGFwWCkgKyBcInB4XCI7XG4gICAgfVxuXG4gICAgY20uYWRkS2V5TWFwKHRoaXMua2V5TWFwID0gYnVpbGRLZXlNYXAoY29tcGxldGlvbiwge1xuICAgICAgbW92ZUZvY3VzOiBmdW5jdGlvbihuLCBhdm9pZFdyYXApIHsgd2lkZ2V0LmNoYW5nZUFjdGl2ZSh3aWRnZXQuc2VsZWN0ZWRIaW50ICsgbiwgYXZvaWRXcmFwKTsgfSxcbiAgICAgIHNldEZvY3VzOiBmdW5jdGlvbihuKSB7IHdpZGdldC5jaGFuZ2VBY3RpdmUobik7IH0sXG4gICAgICBtZW51U2l6ZTogZnVuY3Rpb24oKSB7IHJldHVybiB3aWRnZXQuc2NyZWVuQW1vdW50KCk7IH0sXG4gICAgICBsZW5ndGg6IGNvbXBsZXRpb25zLmxlbmd0aCxcbiAgICAgIGNsb3NlOiBmdW5jdGlvbigpIHsgY29tcGxldGlvbi5jbG9zZSgpOyB9LFxuICAgICAgcGljazogZnVuY3Rpb24oKSB7IHdpZGdldC5waWNrKCk7IH0sXG4gICAgICBkYXRhOiBkYXRhXG4gICAgfSkpO1xuXG4gICAgaWYgKGNvbXBsZXRpb24ub3B0aW9ucy5jbG9zZU9uVW5mb2N1cykge1xuICAgICAgdmFyIGNsb3NpbmdPbkJsdXI7XG4gICAgICBjbS5vbihcImJsdXJcIiwgdGhpcy5vbkJsdXIgPSBmdW5jdGlvbigpIHsgY2xvc2luZ09uQmx1ciA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNvbXBsZXRpb24uY2xvc2UoKTsgfSwgMTAwKTsgfSk7XG4gICAgICBjbS5vbihcImZvY3VzXCIsIHRoaXMub25Gb2N1cyA9IGZ1bmN0aW9uKCkgeyBjbGVhclRpbWVvdXQoY2xvc2luZ09uQmx1cik7IH0pO1xuICAgIH1cblxuICAgIHZhciBzdGFydFNjcm9sbCA9IGNtLmdldFNjcm9sbEluZm8oKTtcbiAgICBjbS5vbihcInNjcm9sbFwiLCB0aGlzLm9uU2Nyb2xsID0gZnVuY3Rpb24oKSB7XG4gICAgICB2Y
23459XIgY3VyU2Nyb2xsID0gY20uZ2V0U2Nyb2xsSW5mbygpLCBlZGl0b3IgPSBjbS5nZXRXcmFwcGVyRWxlbWVudCgpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgdmFyIG5ld1RvcCA9IHRvcCArIHN0YXJ0U2Nyb2xsLnRvcCAtIGN1clNjcm9sbC50b3A7XG4gICAgICB2YXIgcG9pbnQgPSBuZXdUb3AgLSAod2luZG93LnBhZ2VZT2Zmc2V0IHx8IChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgfHwgZG9jdW1lbnQuYm9keSkuc2Nyb2xsVG9wKTtcbiAgICAgIGlmICghYmVsb3cpIHBvaW50ICs9IGhpbnRzLm9mZnNldEhlaWdodDtcbiAgICAgIGlmIChwb2ludCA8PSBlZGl0b3IudG9wIHx8IHBvaW50ID49IGVkaXRvci5ib3R0b20pIHJldHVybiBjb21wbGV0aW9uLmNsb3NlKCk7XG4gICAgICBoaW50cy5zdHlsZS50b3AgPSBuZXdUb3AgKyBcInB4XCI7XG4gICAgICBoaW50cy5zdHlsZS5sZWZ0ID0gKGxlZnQgKyBzdGFydFNjcm9sbC5sZWZ0IC0gY3VyU2Nyb2xsLmxlZnQpICsgXCJweFwiO1xuICAgIH0pO1xuXG4gICAgQ29kZU1pcnJvci5vbihoaW50cywgXCJkYmxjbGlja1wiLCBmdW5jdGlvbihlKSB7XG4gICAgICB2YXIgdCA9IGdldEhpbnRFbGVtZW50KGhpbnRzLCBlLnRhcmdldCB8fCBlLnNyY0VsZW1lbnQpO1xuICAgICAgaWYgKHQgJiYgdC5oaW50SWQgIT0gbnVsbCkge3dpZGdldC5jaGFuZ2VBY3RpdmUodC5oaW50SWQpOyB3aWRnZXQucGljaygpO31cbiAgICB9KTtcblxuICAgIENvZGVNaXJyb3Iub24oaGludHMsIFwiY2xpY2tcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgdmFyIHQgPSBnZXRIaW50RWxlbWVudChoaW50cywgZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50KTtcbiAgICAgIGlmICh0ICYmIHQuaGludElkICE9IG51bGwpIHtcbiAgICAgICAgd2lkZ2V0LmNoYW5nZUFjdGl2ZSh0LmhpbnRJZCk7XG4gICAgICAgIGlmIChjb21wbGV0aW9uLm9wdGlvbnMuY29tcGxldGVPblNpbmdsZUNsaWNrKSB3aWRnZXQucGljaygpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgQ29kZU1pcnJvci5vbihoaW50cywgXCJtb3VzZWRvd25cIiwgZnVuY3Rpb24oKSB7XG4gICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Y20uZm9jdXMoKTt9LCAyMCk7XG4gICAgfSk7XG5cbiAgICBDb2RlTWlycm9yLnNpZ25hbChkYXRhLCBcInNlbGVjdFwiLCBjb21wbGV0aW9uc1swXSwgaGludHMuZmlyc3RDaGlsZCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBXaWRnZXQucHJvdG90eXBlID0ge1xuICAgIGNsb3NlOiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmNvbXBsZXRpb24ud2lkZ2V0ICE9IHRoaXMpIHJldHVybjtcbiAgICAgIHRoaXMuY29tcGxldGlvbi53aWRnZXQgPSBudWxsO1xuICAgICAgdGhpcy5oaW50cy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuaGludHMpO1xuICAgICAgdGhpcy5jb21wbGV0aW9uLmNtLnJlbW92ZUtleU1hcCh0aGlzLmtleU1hcCk7XG5cbiAgICAgIHZhciBjbSA9IHRoaXMuY29tcGxldGlvbi5jbTtcbiAgICAgIGlmICh0aGlzLmNvbXBsZXRpb24ub3B0aW9ucy5jbG9zZU9uVW5mb2N1cykge1xuICAgICAgICBjbS5vZmYoXCJibHVyXCIsIHRoaXMub25CbHVyKTtcbiAgICAgICAgY20ub2ZmKFwiZm9jdXNcIiwgdGhpcy5vbkZvY3VzKTtcbiAgICAgIH1cbiAgICAgIGNtLm9mZihcInNjcm9sbFwiLCB0aGlzLm9uU2Nyb2xsKTtcbiAgICB9LFxuXG4gICAgZGlzYWJsZTogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmNvbXBsZXRpb24uY20ucmVtb3ZlS2V5TWFwKHRoaXMua2V5TWFwKTtcbiAgICAgIHZhciB3aWRnZXQgPSB0aGlzO1xuICAgICAgdGhpcy5rZXlNYXAgPSB7RW50ZXI6IGZ1bmN0aW9uKCkgeyB3aWRnZXQucGlja2VkID0gdHJ1ZTsgfX07XG4gICAgICB0aGlzLmNvbXBsZXRpb24uY20uYWRkS2V5TWFwKHRoaXMua2V5TWFwKTtcbiAgICB9LFxuXG4gICAgcGljazogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmNvbXBsZXRpb24ucGljayh0aGlzLmRhdGEsIHRoaXMuc2VsZWN0ZWRIaW50KTtcbiAgICB9LFxuXG4gICAgY2hhbmdlQWN0aXZlOiBmdW5jdGlvbihpLCBhdm9pZFdyYXApIHtcbiAgICAgIGlmIChpID49IHRoaXMuZGF0YS5saXN0Lmxlbmd0aClcbiAgICAgICAgaSA9IGF2b2lkV3JhcCA/IHRoaXMuZGF0YS5saXN0Lmxlbmd0aCAtIDEgOiAwO1xuICAgICAgZWxzZSBpZiAoaSA8IDApXG4gICAgICAgIGkgPSBhdm9pZFdyYXAgPyAwICA6IHRoaXMuZGF0YS5saXN0Lmxlbmd0aCAtIDE7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZEhpbnQgPT0gaSkgcmV0dXJuO1xuICAgICAgdmFyIG5vZGUgPSB0aGlzLmhpbnRzLmNoaWxkTm9kZXNbdGhpcy5zZWxlY3RlZEhpbnRdO1xuICAgICAgbm9kZS5jbGFzc05hbWUgPSBub2RlLmNsYXNzTmFtZS5yZXBsYWNlKFwiIFwiICsgQUNUSVZFX0hJTlRfRUxFTUVOVF9DTEFTUywgXCJcIik7XG4gICAgICBub2RlID0gdGhpcy5oaW50cy5jaGlsZE5vZGVzW3RoaXMuc2VsZWN0ZWRIaW50ID0gaV07XG4gICAgICBub2RlLmNsYXNzTmFtZSArPSBcIiBcIiArIEFDVElWRV9ISU5UX0VMRU1FTlRfQ0xBU1M7XG4gICAgICBpZiAobm9kZS5vZmZzZXRUb3AgPCB0aGlzLmhpbnRzLnNjcm9sbFRvcClcbiAgICAgICAgdGhpcy5oaW50cy5zY3JvbGxUb3AgPSBub2RlLm9mZnNldFRvcCAtIDM7XG4gICAgICBlbHNlIGlmIChub2RlLm9mZnNldFRvcCArIG5vZGUub2Zmc2V0SGVpZ2h0ID4gdGhpcy5oaW50cy5zY3JvbGxUb3AgKyB0aGlzLmhpbnRzLmNsaWVudEhlaWdodClcbiAgICAgICAgdGhpcy5oaW50cy5zY3JvbGxUb3AgPSBub2RlLm9mZnNldFRvcCArIG5vZGUub2Zmc2V0SGVpZ2h0IC0gdGhpcy5oaW50cy5jbGllbnRIZWlnaHQgKyAzO1xuICAgICAgQ29kZU1pcnJvci5zaWduYWwodGhpcy5kYXRhLCBcInNlbGVjdFwiLCB0aGlzLmRhdGEubGlzdFt0aGlzLnNlbGVjdGVkSGludF0sIG5vZGUpO1xuICAgIH0sXG5cbiAgICBzY3JlZW5BbW91bnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIE1hdGguZmxvb3IodGhpcy5oaW50cy5jbGllbnRIZWlnaHQgLyB0aGlzLmhpbnRzLmZpcnN0Q2hpbGQub2Zmc2V0SGVpZ2h0KSB8fCAxO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBhcHBsaWNhYmxlSGVscGVycyhjbSwgaGVscGVycykge1xuICAgIGlmICghY20uc29tZXRoaW5nU2VsZWN0ZWQoKSkgcmV0dXJuIGhlbHBlcnNcbiAgICB2YXIgcmVzdWx0ID0gW11cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhlbHBlcnMubGVuZ3RoOyBpKyspXG4gICAgICBpZiAoaGVscGVyc1tpXS5zdXBwb3J0c1NlbGVjdGlvbikgcmVzdWx0LnB1c2goaGVscGVyc1tpXSlcbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICBmdW5jdGlvbiByZXNvbHZlQXV0b0hpbnRzKGNtLCBwb3MpIHtcbiAgICB2YXIgaGVscGVycyA9IGNtLmdldEhlbHBlcnMocG9zLCBcImhpbnRcIiksIHdvcmRzXG4gICAgaWYgKGhlbHBlcnMubGVuZ3RoKSB7XG4gICAgICB2Y
23459XIgYXN5bmMgPSBmYWxzZSwgcmVzb2x2ZWRcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGVscGVycy5sZW5ndGg7IGkrKykgaWYgKGhlbHBlcnNbaV0uYXN5bmMpIGFzeW5jID0gdHJ1ZVxuICAgICAgaWYgKGFzeW5jKSB7XG4gICAgICAgIHJlc29sdmVkID0gZnVuY3Rpb24oY20sIGNhbGxiYWNrLCBvcHRpb25zKSB7XG4gICAgICAgICAgdmFyIGFwcCA9IGFwcGxpY2FibGVIZWxwZXJzKGNtLCBoZWxwZXJzKVxuICAgICAgICAgIGZ1bmN0aW9uIHJ1bihpLCByZXN1bHQpIHtcbiAgICAgICAgICAgIGlmIChpID09IGFwcC5sZW5ndGgpIHJldHVybiBjYWxsYmFjayhudWxsKVxuICAgICAgICAgICAgdmFyIGhlbHBlciA9IGFwcFtpXVxuICAgICAgICAgICAgaWYgKGhlbHBlci5hc3luYykge1xuICAgICAgICAgICAgICBoZWxwZXIoY20sIGZ1bmN0aW9uKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQpIGNhbGxiYWNrKHJlc3VsdClcbiAgICAgICAgICAgICAgICBlbHNlIHJ1bihpICsgMSlcbiAgICAgICAgICAgICAgfSwgb3B0aW9ucylcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHZhciByZXN1bHQgPSBoZWxwZXIoY20sIG9wdGlvbnMpXG4gICAgICAgICAgICAgIGlmIChyZXN1bHQpIGNhbGxiYWNrKHJlc3VsdClcbiAgICAgICAgICAgICAgZWxzZSBydW4oaSArIDEpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJ1bigwKVxuICAgICAgICB9XG4gICAgICAgIHJlc29sdmVkLmFzeW5jID0gdHJ1ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZWQgPSBmdW5jdGlvbihjbSwgb3B0aW9ucykge1xuICAgICAgICAgIHZhciBhcHAgPSBhcHBsaWNhYmxlSGVscGVycyhjbSwgaGVscGVycylcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFwcC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGN1ciA9IGFwcFtpXShjbSwgb3B0aW9ucylcbiAgICAgICAgICAgIGlmIChjdXIgJiYgY3VyLmxpc3QubGVuZ3RoKSByZXR1cm4gY3VyXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXNvbHZlZC5zdXBwb3J0c1NlbGVjdGlvbiA9IHRydWVcbiAgICAgIHJldHVybiByZXNvbHZlZFxuICAgIH0gZWxzZSBpZiAod29yZHMgPSBjbS5nZXRIZWxwZXIoY20uZ2V0Q3Vyc29yKCksIFwiaGludFdvcmRzXCIpKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oY20pIHsgcmV0dXJuIENvZGVNaXJyb3IuaGludC5mcm9tTGlzdChjbSwge3dvcmRzOiB3b3Jkc30pIH1cbiAgICB9IGVsc2UgaWYgKENvZGVNaXJyb3IuaGludC5hbnl3b3JkKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oY20sIG9wdGlvbnMpIHsgcmV0dXJuIENvZGVNaXJyb3IuaGludC5hbnl3b3JkKGNtLCBvcHRpb25zKSB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHt9XG4gICAgfVxuICB9XG5cbiAgQ29kZU1pcnJvci5yZWdpc3RlckhlbHBlcihcImhpbnRcIiwgXCJhdXRvXCIsIHtcbiAgICByZXNvbHZlOiByZXNvbHZlQXV0b0hpbnRzXG4gIH0pO1xuXG4gIENvZGVNaXJyb3IucmVnaXN0ZXJIZWxwZXIoXCJoaW50XCIsIFwiZnJvbUxpc3RcIiwgZnVuY3Rpb24oY20sIG9wdGlvbnMpIHtcbiAgICB2YXIgY3VyID0gY20uZ2V0Q3Vyc29yKCksIHRva2VuID0gY20uZ2V0VG9rZW5BdChjdXIpO1xuICAgIHZhciB0byA9IENvZGVNaXJyb3IuUG9zKGN1ci5saW5lLCB0b2tlbi5lbmQpO1xuICAgIGlmICh0b2tlbi5zdHJpbmcgJiYgL1xcdy8udGVzdCh0b2tlbi5zdHJpbmdbdG9rZW4uc3RyaW5nLmxlbmd0aCAtIDFdKSkge1xuICAgICAgdmFyIHRlcm0gPSB0b2tlbi5zdHJpbmcsIGZyb20gPSBDb2RlTWlycm9yLlBvcyhjdXIubGluZSwgdG9rZW4uc3RhcnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2Y
23459XIgdGVybSA9IFwiXCIsIGZyb20gPSB0bztcbiAgICB9XG4gICAgdmFyIGZvdW5kID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvcHRpb25zLndvcmRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgd29yZCA9IG9wdGlvbnMud29yZHNbaV07XG4gICAgICBpZiAod29yZC5zbGljZSgwLCB0ZXJtLmxlbmd0aCkgPT0gdGVybSlcbiAgICAgICAgZm91bmQucHVzaCh3b3JkKTtcbiAgICB9XG5cbiAgICBpZiAoZm91bmQubGVuZ3RoKSByZXR1cm4ge2xpc3Q6IGZvdW5kLCBmcm9tOiBmcm9tLCB0bzogdG99O1xuICB9KTtcblxuICBDb2RlTWlycm9yLmNvbW1hbmRzLmF1dG9jb21wbGV0ZSA9IENvZGVNaXJyb3Iuc2hvd0hpbnQ7XG5cbiAgdmFyIGRlZmF1bHRPcHRpb25zID0ge1xuICAgIGhpbnQ6IENvZGVNaXJyb3IuaGludC5hdXRvLFxuICAgIGNvbXBsZXRlU2luZ2xlOiB0cnVlLFxuICAgIGFsaWduV2l0aFdvcmQ6IHRydWUsXG4gICAgY2xvc2VDaGFyYWN0ZXJzOiAvW1xccygpXFxbXFxde307Oj4sXS8sXG4gICAgY2xvc2VPblVuZm9jdXM6IHRydWUsXG4gICAgY29tcGxldGVPblNpbmdsZUNsaWNrOiBmYWxzZSxcbiAgICBjb250YWluZXI6IG51bGwsXG4gICAgY3VzdG9tS2V5czogbnVsbCxcbiAgICBleHRyYUtleXM6IG51bGxcbiAgfTtcblxuICBDb2RlTWlycm9yLmRlZmluZU9wdGlvbihcImhpbnRPcHRpb25zXCIsIG51bGwpO1xufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbi8vIERlZmluZSBzZWFyY2ggY29tbWFuZHMuIERlcGVuZHMgb24gZGlhbG9nLmpzIG9yIGFub3RoZXJcbi8vIGltcGxlbWVudGF0aW9uIG9mIHRoZSBvcGVuRGlhbG9nIG1ldGhvZC5cblxuLy8gUmVwbGFjZSB3b3JrcyBhIGxpdHRsZSBvZGRseSAtLSBpdCB3aWxsIGRvIHRoZSByZXBsYWNlIG9uIHRoZSBuZXh0XG4vLyBDdHJsLUcgKG9yIHdoYXRldmVyIGlzIGJvdW5kIHRvIGZpbmROZXh0KSBwcmVzcy4gWW91IHByZXZlbnQgYVxuLy8gcmVwbGFjZSBieSBtYWtpbmcgc3VyZSB0aGUgbWF0Y2ggaXMgbm8gbG9uZ2VyIHNlbGVjdGVkIHdoZW4gaGl0dGluZ1xuLy8gQ3RybC1HLlxuXG4oZnVuY3Rpb24obW9kKSB7XG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUgPT0gXCJvYmplY3RcIikgLy8gQ29tbW9uSlNcbiAgICBtb2QocmVxdWlyZShcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIpLCByZXF1aXJlKFwiLi9zZWFyY2hjdXJzb3JcIiksIHJlcXVpcmUoXCIuLi9kaWFsb2cvZGlhbG9nXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIsIFwiLi9zZWFyY2hjdXJzb3JcIiwgXCIuLi9kaWFsb2cvZGlhbG9nXCJdLCBtb2QpO1xuICBlbHNlIC8vIFBsYWluIGJyb3dzZXIgZW52XG4gICAgbW9kKENvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24oQ29kZU1pcnJvcikge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBmdW5jdGlvbiBzZWFyY2hPdmVybGF5KHF1ZXJ5LCBjYXNlSW5zZW5zaXRpdmUpIHtcbiAgICBpZiAodHlwZW9mIHF1ZXJ5ID09IFwic3RyaW5nXCIpXG4gICAgICBxdWVyeSA9IG5ldyBSZWdFeHAocXVlcnkucmVwbGFjZSgvW1xcLVxcW1xcXVxcL1xce1xcfVxcKFxcKVxcKlxcK1xcP1xcLlxcXFxcXF5cXCRcXHxdL2csIFwiXFxcXCQmXCIpLCBjYXNlSW5zZW5zaXRpdmUgPyBcImdpXCIgOiBcImdcIik7XG4gICAgZWxzZSBpZiAoIXF1ZXJ5Lmdsb2JhbClcbiAgICAgIHF1ZXJ5ID0gbmV3IFJlZ0V4cChxdWVyeS5zb3VyY2UsIHF1ZXJ5Lmlnbm9yZUNhc2UgPyBcImdpXCIgOiBcImdcIik7XG5cbiAgICByZXR1cm4ge3Rva2VuOiBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgIHF1ZXJ5Lmxhc3RJbmRleCA9IHN0cmVhbS5wb3M7XG4gICAgICB2Y
23459XIgbWF0Y2ggPSBxdWVyeS5leGVjKHN0cmVhbS5zdHJpbmcpO1xuICAgICAgaWYgKG1hdGNoICYmIG1hdGNoLmluZGV4ID09IHN0cmVhbS5wb3MpIHtcbiAgICAgICAgc3RyZWFtLnBvcyArPSBtYXRjaFswXS5sZW5ndGg7XG4gICAgICAgIHJldHVybiBcInNlYXJjaGluZ1wiO1xuICAgICAgfSBlbHNlIGlmIChtYXRjaCkge1xuICAgICAgICBzdHJlYW0ucG9zID0gbWF0Y2guaW5kZXg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHJlYW0uc2tpcFRvRW5kKCk7XG4gICAgICB9XG4gICAgfX07XG4gIH1cblxuICBmdW5jdGlvbiBTZWFyY2hTdGF0ZSgpIHtcbiAgICB0aGlzLnBvc0Zyb20gPSB0aGlzLnBvc1RvID0gdGhpcy5sYXN0UXVlcnkgPSB0aGlzLnF1ZXJ5ID0gbnVsbDtcbiAgICB0aGlzLm92ZXJsYXkgPSBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0U2VhcmNoU3RhdGUoY20pIHtcbiAgICByZXR1cm4gY20uc3RhdGUuc2VhcmNoIHx8IChjbS5zdGF0ZS5zZWFyY2ggPSBuZXcgU2VhcmNoU3RhdGUoKSk7XG4gIH1cblxuICBmdW5jdGlvbiBxdWVyeUNhc2VJbnNlbnNpdGl2ZShxdWVyeSkge1xuICAgIHJldHVybiB0eXBlb2YgcXVlcnkgPT0gXCJzdHJpbmdcIiAmJiBxdWVyeSA9PSBxdWVyeS50b0xvd2VyQ2FzZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0U2VhcmNoQ3Vyc29yKGNtLCBxdWVyeSwgcG9zKSB7XG4gICAgLy8gSGV1cmlzdGljOiBpZiB0aGUgcXVlcnkgc3RyaW5nIGlzIGFsbCBsb3dlcmNhc2UsIGRvIGEgY2FzZSBpbnNlbnNpdGl2ZSBzZWFyY2guXG4gICAgcmV0dXJuIGNtLmdldFNlYXJjaEN1cnNvcihxdWVyeSwgcG9zLCBxdWVyeUNhc2VJbnNlbnNpdGl2ZShxdWVyeSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcGVyc2lzdGVudERpYWxvZyhjbSwgdGV4dCwgZGVmbHQsIGYpIHtcbiAgICBjbS5vcGVuRGlhbG9nKHRleHQsIGYsIHtcbiAgICAgIHZhbHVlOiBkZWZsdCxcbiAgICAgIHNlbGVjdFZhbHVlT25PcGVuOiB0cnVlLFxuICAgICAgY2xvc2VPbkVudGVyOiBmYWxzZSxcbiAgICAgIG9uQ2xvc2U6IGZ1bmN0aW9uKCkgeyBjbGVhclNlYXJjaChjbSk7IH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRpYWxvZyhjbSwgdGV4dCwgc2hvcnRUZXh0LCBkZWZsdCwgZikge1xuICAgIGlmIChjbS5vcGVuRGlhbG9nKSBjbS5vcGVuRGlhbG9nKHRleHQsIGYsIHt2YWx1ZTogZGVmbHQsIHNlbGVjdFZhbHVlT25PcGVuOiB0cnVlfSk7XG4gICAgZWxzZSBmKHByb21wdChzaG9ydFRleHQsIGRlZmx0KSk7XG4gIH1cblxuICBmdW5jdGlvbiBjb25maXJtRGlhbG9nKGNtLCB0ZXh0LCBzaG9ydFRleHQsIGZzKSB7XG4gICAgaWYgKGNtLm9wZW5Db25maXJtKSBjbS5vcGVuQ29uZmlybSh0ZXh0LCBmcyk7XG4gICAgZWxzZSBpZiAoY29uZmlybShzaG9ydFRleHQpKSBmc1swXSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VTdHJpbmcoc3RyaW5nKSB7XG4gICAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC9cXFxcKC4pL2csIGZ1bmN0aW9uKF8sIGNoKSB7XG4gICAgICBpZiAoY2ggPT0gXCJuXCIpIHJldHVybiBcIlxcblwiXG4gICAgICBpZiAoY2ggPT0gXCJyXCIpIHJldHVybiBcIlxcclwiXG4gICAgICByZXR1cm4gY2hcbiAgICB9KVxuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VRdWVyeShxdWVyeSkge1xuICAgIHZhciBpc1JFID0gcXVlcnkubWF0Y2goL15cXC8oLiopXFwvKFthLXpdKikkLyk7XG4gICAgaWYgKGlzUkUpIHtcbiAgICAgIHRyeSB7IHF1ZXJ5ID0gbmV3IFJlZ0V4cChpc1JFWzFdLCBpc1JFWzJdLmluZGV4T2YoXCJpXCIpID09IC0xID8gXCJcIiA6IFwiaVwiKTsgfVxuICAgICAgY2F0Y2goZSkge30gLy8gTm90IGEgcmVndWxhciBleHByZXNzaW9uIGFmdGVyIGFsbCwgZG8gYSBzdHJpbmcgc2VhcmNoXG4gICAgfSBlbHNlIHtcbiAgICAgIHF1ZXJ5ID0gcGFyc2VTdHJpbmcocXVlcnkpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgcXVlcnkgPT0gXCJzdHJpbmdcIiA/IHF1ZXJ5ID09IFwiXCIgOiBxdWVyeS50ZXN0KFwiXCIpKVxuICAgICAgcXVlcnkgPSAveF4vO1xuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIHZhciBxdWVyeURpYWxvZyA9XG4gICAgJ1NlYXJjaDogPGlucHV0IHR5cGU9XCJ0ZXh0XCIgc3R5bGU9XCJ3aWR0aDogMTBlbVwiIGNsYXNzPVwiQ29kZU1pcnJvci1zZWFyY2gtZmllbGRcIi8+IDxzcGFuIHN0eWxlPVwiY29sb3I6ICM4ODhcIiBjbGFzcz1cIkNvZGVNaXJyb3Itc2VhcmNoLWhpbnRcIj4oVXNlIC9yZS8gc3ludGF4IGZvciByZWdleHAgc2VhcmNoKTwvc3Bhbj4nO1xuXG4gIGZ1bmN0aW9uIHN0YXJ0U2VhcmNoKGNtLCBzdGF0ZSwgcXVlcnkpIHtcbiAgICBzdGF0ZS5xdWVyeVRleHQgPSBxdWVyeTtcbiAgICBzdGF0ZS5xdWVyeSA9IHBhcnNlUXVlcnkocXVlcnkpO1xuICAgIGNtLnJlbW92ZU92ZXJsYXkoc3RhdGUub3ZlcmxheSwgcXVlcnlDYXNlSW5zZW5zaXRpdmUoc3RhdGUucXVlcnkpKTtcbiAgICBzdGF0ZS5vdmVybGF5ID0gc2VhcmNoT3ZlcmxheShzdGF0ZS5xdWVyeSwgcXVlcnlDYXNlSW5zZW5zaXRpdmUoc3RhdGUucXVlcnkpKTtcbiAgICBjbS5hZGRPdmVybGF5KHN0YXRlLm92ZXJsYXkpO1xuICAgIGlmIChjbS5zaG93TWF0Y2hlc09uU2Nyb2xsYmFyKSB7XG4gICAgICBpZiAoc3RhdGUuYW5ub3RhdGUpIHsgc3RhdGUuYW5ub3RhdGUuY2xlYXIoKTsgc3RhdGUuYW5ub3RhdGUgPSBudWxsOyB9XG4gICAgICBzdGF0ZS5hbm5vdGF0ZSA9IGNtLnNob3dNYXRjaGVzT25TY3JvbGxiYXIoc3RhdGUucXVlcnksIHF1ZXJ5Q2FzZUluc2Vuc2l0aXZlKHN0YXRlLnF1ZXJ5KSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZG9TZWFyY2goY20sIHJldiwgcGVyc2lzdGVudCkge1xuICAgIHZhciBzdGF0ZSA9IGdldFNlYXJjaFN0YXRlKGNtKTtcbiAgICBpZiAoc3RhdGUucXVlcnkpIHJldHVybiBmaW5kTmV4dChjbSwgcmV2KTtcbiAgICB2YXIgcSA9IGNtLmdldFNlbGVjdGlvbigpIHx8IHN0YXRlLmxhc3RRdWVyeTtcbiAgICBpZiAocGVyc2lzdGVudCAmJiBjbS5vcGVuRGlhbG9nKSB7XG4gICAgICB2Y
23459XIgaGlkaW5nID0gbnVsbFxuICAgICAgcGVyc2lzdGVudERpYWxvZyhjbSwgcXVlcnlEaWFsb2csIHEsIGZ1bmN0aW9uKHF1ZXJ5LCBldmVudCkge1xuICAgICAgICBDb2RlTWlycm9yLmVfc3RvcChldmVudCk7XG4gICAgICAgIGlmICghcXVlcnkpIHJldHVybjtcbiAgICAgICAgaWYgKHF1ZXJ5ICE9IHN0YXRlLnF1ZXJ5VGV4dCkgc3RhcnRTZWFyY2goY20sIHN0YXRlLCBxdWVyeSk7XG4gICAgICAgIGlmIChoaWRpbmcpIGhpZGluZy5zdHlsZS5vcGFjaXR5ID0gMVxuICAgICAgICBmaW5kTmV4dChjbSwgZXZlbnQuc2hpZnRLZXksIGZ1bmN0aW9uKF8sIHRvKSB7XG4gICAgICAgICAgdmFyIGRpYWxvZ1xuICAgICAgICAgIGlmICh0by5saW5lIDwgMyAmJiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yICYmXG4gICAgICAgICAgICAgIChkaWFsb2cgPSBjbS5kaXNwbGF5LndyYXBwZXIucXVlcnlTZWxlY3RvcihcIi5Db2RlTWlycm9yLWRpYWxvZ1wiKSkgJiZcbiAgICAgICAgICAgICAgZGlhbG9nLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmJvdHRvbSAtIDQgPiBjbS5jdXJzb3JDb29yZHModG8sIFwid2luZG93XCIpLnRvcClcbiAgICAgICAgICAgIChoaWRpbmcgPSBkaWFsb2cpLnN0eWxlLm9wYWNpdHkgPSAuNFxuICAgICAgICB9KVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRpYWxvZyhjbSwgcXVlcnlEaWFsb2csIFwiU2VhcmNoIGZvcjpcIiwgcSwgZnVuY3Rpb24ocXVlcnkpIHtcbiAgICAgICAgaWYgKHF1ZXJ5ICYmICFzdGF0ZS5xdWVyeSkgY20ub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHN0YXJ0U2VhcmNoKGNtLCBzdGF0ZSwgcXVlcnkpO1xuICAgICAgICAgIHN0YXRlLnBvc0Zyb20gPSBzdGF0ZS5wb3NUbyA9IGNtLmdldEN1cnNvcigpO1xuICAgICAgICAgIGZpbmROZXh0KGNtLCByZXYpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbmROZXh0KGNtLCByZXYsIGNhbGxiYWNrKSB7Y20ub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgIHZhciBzdGF0ZSA9IGdldFNlYXJjaFN0YXRlKGNtKTtcbiAgICB2YXIgY3Vyc29yID0gZ2V0U2VhcmNoQ3Vyc29yKGNtLCBzdGF0ZS5xdWVyeSwgcmV2ID8gc3RhdGUucG9zRnJvbSA6IHN0YXRlLnBvc1RvKTtcbiAgICBpZiAoIWN1cnNvci5maW5kKHJldikpIHtcbiAgICAgIGN1cnNvciA9IGdldFNlYXJjaEN1cnNvcihjbSwgc3RhdGUucXVlcnksIHJldiA/IENvZGVNaXJyb3IuUG9zKGNtLmxhc3RMaW5lKCkpIDogQ29kZU1pcnJvci5Qb3MoY20uZmlyc3RMaW5lKCksIDApKTtcbiAgICAgIGlmICghY3Vyc29yLmZpbmQocmV2KSkgcmV0dXJuO1xuICAgIH1cbiAgICBjbS5zZXRTZWxlY3Rpb24oY3Vyc29yLmZyb20oKSwgY3Vyc29yLnRvKCkpO1xuICAgIGNtLnNjcm9sbEludG9WaWV3KHtmcm9tOiBjdXJzb3IuZnJvbSgpLCB0bzogY3Vyc29yLnRvKCl9LCAyMCk7XG4gICAgc3RhdGUucG9zRnJvbSA9IGN1cnNvci5mcm9tKCk7IHN0YXRlLnBvc1RvID0gY3Vyc29yLnRvKCk7XG4gICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjayhjdXJzb3IuZnJvbSgpLCBjdXJzb3IudG8oKSlcbiAgfSk7fVxuXG4gIGZ1bmN0aW9uIGNsZWFyU2VhcmNoKGNtKSB7Y20ub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgIHZhciBzdGF0ZSA9IGdldFNlYXJjaFN0YXRlKGNtKTtcbiAgICBzdGF0ZS5sYXN0UXVlcnkgPSBzdGF0ZS5xdWVyeTtcbiAgICBpZiAoIXN0YXRlLnF1ZXJ5KSByZXR1cm47XG4gICAgc3RhdGUucXVlcnkgPSBzdGF0ZS5xdWVyeVRleHQgPSBudWxsO1xuICAgIGNtLnJlbW92ZU92ZXJsYXkoc3RhdGUub3ZlcmxheSk7XG4gICAgaWYgKHN0YXRlLmFubm90YXRlKSB7IHN0YXRlLmFubm90YXRlLmNsZWFyKCk7IHN0YXRlLmFubm90YXRlID0gbnVsbDsgfVxuICB9KTt9XG5cbiAgdmFyIHJlcGxhY2VRdWVyeURpYWxvZyA9XG4gICAgJyA8aW5wdXQgdHlwZT1cInRleHRcIiBzdHlsZT1cIndpZHRoOiAxMGVtXCIgY2xhc3M9XCJDb2RlTWlycm9yLXNlYXJjaC1maWVsZFwiLz4gPHNwYW4gc3R5bGU9XCJjb2xvcjogIzg4OFwiIGNsYXNzPVwiQ29kZU1pcnJvci1zZWFyY2gtaGludFwiPihVc2UgL3JlLyBzeW50YXggZm9yIHJlZ2V4cCBzZWFyY2gpPC9zcGFuPic7XG4gIHZhciByZXBsYWNlbWVudFF1ZXJ5RGlhbG9nID0gJ1dpdGg6IDxpbnB1dCB0eXBlPVwidGV4dFwiIHN0eWxlPVwid2lkdGg6IDEwZW1cIiBjbGFzcz1cIkNvZGVNaXJyb3Itc2VhcmNoLWZpZWxkXCIvPic7XG4gIHZhciBkb1JlcGxhY2VDb25maXJtID0gXCJSZXBsYWNlPyA8YnV0dG9uPlllczwvYnV0dG9uPiA8YnV0dG9uPk5vPC9idXR0b24+IDxidXR0b24+QWxsPC9idXR0b24+IDxidXR0b24+U3RvcDwvYnV0dG9uPlwiO1xuXG4gIGZ1bmN0aW9uIHJlcGxhY2VBbGwoY20sIHF1ZXJ5LCB0ZXh0KSB7XG4gICAgY20ub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgICAgZm9yICh2YXIgY3Vyc29yID0gZ2V0U2VhcmNoQ3Vyc29yKGNtLCBxdWVyeSk7IGN1cnNvci5maW5kTmV4dCgpOykge1xuICAgICAgICBpZiAodHlwZW9mIHF1ZXJ5ICE9IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICB2Y
23459XIgbWF0Y2ggPSBjbS5nZXRSYW5nZShjdXJzb3IuZnJvbSgpLCBjdXJzb3IudG8oKSkubWF0Y2gocXVlcnkpO1xuICAgICAgICAgIGN1cnNvci5yZXBsYWNlKHRleHQucmVwbGFjZSgvXFwkKFxcZCkvZywgZnVuY3Rpb24oXywgaSkge3JldHVybiBtYXRjaFtpXTt9KSk7XG4gICAgICAgIH0gZWxzZSBjdXJzb3IucmVwbGFjZSh0ZXh0KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlcGxhY2UoY20sIGFsbCkge1xuICAgIGlmIChjbS5nZXRPcHRpb24oXCJyZWFkT25seVwiKSkgcmV0dXJuO1xuICAgIHZhciBxdWVyeSA9IGNtLmdldFNlbGVjdGlvbigpIHx8IGdldFNlYXJjaFN0YXRlKGNtKS5sYXN0UXVlcnk7XG4gICAgdmFyIGRpYWxvZ1RleHQgPSBhbGwgPyBcIlJlcGxhY2UgYWxsOlwiIDogXCJSZXBsYWNlOlwiXG4gICAgZGlhbG9nKGNtLCBkaWFsb2dUZXh0ICsgcmVwbGFjZVF1ZXJ5RGlhbG9nLCBkaWFsb2dUZXh0LCBxdWVyeSwgZnVuY3Rpb24ocXVlcnkpIHtcbiAgICAgIGlmICghcXVlcnkpIHJldHVybjtcbiAgICAgIHF1ZXJ5ID0gcGFyc2VRdWVyeShxdWVyeSk7XG4gICAgICBkaWFsb2coY20sIHJlcGxhY2VtZW50UXVlcnlEaWFsb2csIFwiUmVwbGFjZSB3aXRoOlwiLCBcIlwiLCBmdW5jdGlvbih0ZXh0KSB7XG4gICAgICAgIHRleHQgPSBwYXJzZVN0cmluZyh0ZXh0KVxuICAgICAgICBpZiAoYWxsKSB7XG4gICAgICAgICAgcmVwbGFjZUFsbChjbSwgcXVlcnksIHRleHQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2xlYXJTZWFyY2goY20pO1xuICAgICAgICAgIHZhciBjdXJzb3IgPSBnZXRTZWFyY2hDdXJzb3IoY20sIHF1ZXJ5LCBjbS5nZXRDdXJzb3IoKSk7XG4gICAgICAgICAgdmFyIGFkdmFuY2UgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBzdGFydCA9IGN1cnNvci5mcm9tKCksIG1hdGNoO1xuICAgICAgICAgICAgaWYgKCEobWF0Y2ggPSBjdXJzb3IuZmluZE5leHQoKSkpIHtcbiAgICAgICAgICAgICAgY3Vyc29yID0gZ2V0U2VhcmNoQ3Vyc29yKGNtLCBxdWVyeSk7XG4gICAgICAgICAgICAgIGlmICghKG1hdGNoID0gY3Vyc29yLmZpbmROZXh0KCkpIHx8XG4gICAgICAgICAgICAgICAgICAoc3RhcnQgJiYgY3Vyc29yLmZyb20oKS5saW5lID09IHN0YXJ0LmxpbmUgJiYgY3Vyc29yLmZyb20oKS5jaCA9PSBzdGFydC5jaCkpIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNtLnNldFNlbGVjdGlvbihjdXJzb3IuZnJvbSgpLCBjdXJzb3IudG8oKSk7XG4gICAgICAgICAgICBjbS5zY3JvbGxJbnRvVmlldyh7ZnJvbTogY3Vyc29yLmZyb20oKSwgdG86IGN1cnNvci50bygpfSk7XG4gICAgICAgICAgICBjb25maXJtRGlhbG9nKGNtLCBkb1JlcGxhY2VDb25maXJtLCBcIlJlcGxhY2U/XCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtmdW5jdGlvbigpIHtkb1JlcGxhY2UobWF0Y2gpO30sIGFkdmFuY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbigpIHtyZXBsYWNlQWxsKGNtLCBxdWVyeSwgdGV4dCl9XSk7XG4gICAgICAgICAgfTtcbiAgICAgICAgICB2Y
23459XIgZG9SZXBsYWNlID0gZnVuY3Rpb24obWF0Y2gpIHtcbiAgICAgICAgICAgIGN1cnNvci5yZXBsYWNlKHR5cGVvZiBxdWVyeSA9PSBcInN0cmluZ1wiID8gdGV4dCA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0LnJlcGxhY2UoL1xcJChcXGQpL2csIGZ1bmN0aW9uKF8sIGkpIHtyZXR1cm4gbWF0Y2hbaV07fSkpO1xuICAgICAgICAgICAgYWR2YW5jZSgpO1xuICAgICAgICAgIH07XG4gICAgICAgICAgYWR2YW5jZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIENvZGVNaXJyb3IuY29tbWFuZHMuZmluZCA9IGZ1bmN0aW9uKGNtKSB7Y2xlYXJTZWFyY2goY20pOyBkb1NlYXJjaChjbSk7fTtcbiAgQ29kZU1pcnJvci5jb21tYW5kcy5maW5kUGVyc2lzdGVudCA9IGZ1bmN0aW9uKGNtKSB7Y2xlYXJTZWFyY2goY20pOyBkb1NlYXJjaChjbSwgZmFsc2UsIHRydWUpO307XG4gIENvZGVNaXJyb3IuY29tbWFuZHMuZmluZE5leHQgPSBkb1NlYXJjaDtcbiAgQ29kZU1pcnJvci5jb21tYW5kcy5maW5kUHJldiA9IGZ1bmN0aW9uKGNtKSB7ZG9TZWFyY2goY20sIHRydWUpO307XG4gIENvZGVNaXJyb3IuY29tbWFuZHMuY2xlYXJTZWFyY2ggPSBjbGVhclNlYXJjaDtcbiAgQ29kZU1pcnJvci5jb21tYW5kcy5yZXBsYWNlID0gcmVwbGFjZTtcbiAgQ29kZU1pcnJvci5jb21tYW5kcy5yZXBsYWNlQWxsID0gZnVuY3Rpb24oY20pIHtyZXBsYWNlKGNtLCB0cnVlKTt9O1xufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbihmdW5jdGlvbihtb2QpIHtcbiAgaWYgKHR5cGVvZiBleHBvcnRzID09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PSBcIm9iamVjdFwiKSAvLyBDb21tb25KU1xuICAgIG1vZChyZXF1aXJlKFwiLi4vLi4vbGliL2NvZGVtaXJyb3JcIikpO1xuICBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSAvLyBBTURcbiAgICBkZWZpbmUoW1wiLi4vLi4vbGliL2NvZGVtaXJyb3JcIl0sIG1vZCk7XG4gIGVsc2UgLy8gUGxhaW4gYnJvd3NlciBlbnZcbiAgICBtb2QoQ29kZU1pcnJvcik7XG59KShmdW5jdGlvbihDb2RlTWlycm9yKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuICB2YXIgUG9zID0gQ29kZU1pcnJvci5Qb3M7XG5cbiAgZnVuY3Rpb24gU2VhcmNoQ3Vyc29yKGRvYywgcXVlcnksIHBvcywgY2FzZUZvbGQpIHtcbiAgICB0aGlzLmF0T2NjdXJyZW5jZSA9IGZhbHNlOyB0aGlzLmRvYyA9IGRvYztcbiAgICBpZiAoY2FzZUZvbGQgPT0gbnVsbCAmJiB0eXBlb2YgcXVlcnkgPT0gXCJzdHJpbmdcIikgY2FzZUZvbGQgPSBmYWxzZTtcblxuICAgIHBvcyA9IHBvcyA/IGRvYy5jbGlwUG9zKHBvcykgOiBQb3MoMCwgMCk7XG4gICAgdGhpcy5wb3MgPSB7ZnJvbTogcG9zLCB0bzogcG9zfTtcblxuICAgIC8vIFRoZSBtYXRjaGVzIG1ldGhvZCBpcyBmaWxsZWQgaW4gYmFzZWQgb24gdGhlIHR5cGUgb2YgcXVlcnkuXG4gICAgLy8gSXQgdGFrZXMgYSBwb3NpdGlvbiBhbmQgYSBkaXJlY3Rpb24sIGFuZCByZXR1cm5zIGFuIG9iamVjdFxuICAgIC8vIGRlc2NyaWJpbmcgdGhlIG5leHQgb2NjdXJyZW5jZSBvZiB0aGUgcXVlcnksIG9yIG51bGwgaWYgbm9cbiAgICAvLyBtb3JlIG1hdGNoZXMgd2VyZSBmb3VuZC5cbiAgICBpZiAodHlwZW9mIHF1ZXJ5ICE9IFwic3RyaW5nXCIpIHsgLy8gUmVnZXhwIG1hdGNoXG4gICAgICBpZiAoIXF1ZXJ5Lmdsb2JhbCkgcXVlcnkgPSBuZXcgUmVnRXhwKHF1ZXJ5LnNvdXJjZSwgcXVlcnkuaWdub3JlQ2FzZSA/IFwiaWdcIiA6IFwiZ1wiKTtcbiAgICAgIHRoaXMubWF0Y2hlcyA9IGZ1bmN0aW9uKHJldmVyc2UsIHBvcykge1xuICAgICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICAgIHF1ZXJ5Lmxhc3RJbmRleCA9IDA7XG4gICAgICAgICAgdmFyIGxpbmUgPSBkb2MuZ2V0TGluZShwb3MubGluZSkuc2xpY2UoMCwgcG9zLmNoKSwgY3V0T2ZmID0gMCwgbWF0Y2gsIHN0YXJ0O1xuICAgICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICAgIHF1ZXJ5Lmxhc3RJbmRleCA9IGN1dE9mZjtcbiAgICAgICAgICAgIHZhciBuZXdNYXRjaCA9IHF1ZXJ5LmV4ZWMobGluZSk7XG4gICAgICAgICAgICBpZiAoIW5ld01hdGNoKSBicmVhaztcbiAgICAgICAgICAgIG1hdGNoID0gbmV3TWF0Y2g7XG4gICAgICAgICAgICBzdGFydCA9IG1hdGNoLmluZGV4O1xuICAgICAgICAgICAgY3V0T2ZmID0gbWF0Y2guaW5kZXggKyAobWF0Y2hbMF0ubGVuZ3RoIHx8IDEpO1xuICAgICAgICAgICAgaWYgKGN1dE9mZiA9PSBsaW5lLmxlbmd0aCkgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIHZhciBtYXRjaExlbiA9IChtYXRjaCAmJiBtYXRjaFswXS5sZW5ndGgpIHx8IDA7XG4gICAgICAgICAgaWYgKCFtYXRjaExlbikge1xuICAgICAgICAgICAgaWYgKHN0YXJ0ID09IDAgJiYgbGluZS5sZW5ndGggPT0gMCkge21hdGNoID0gdW5kZWZpbmVkO31cbiAgICAgICAgICAgIGVsc2UgaWYgKHN0YXJ0ICE9IGRvYy5nZXRMaW5lKHBvcy5saW5lKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgbWF0Y2hMZW4rKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcXVlcnkubGFzdEluZGV4ID0gcG9zLmNoO1xuICAgICAgICAgIHZhciBsaW5lID0gZG9jLmdldExpbmUocG9zLmxpbmUpLCBtYXRjaCA9IHF1ZXJ5LmV4ZWMobGluZSk7XG4gICAgICAgICAgdmFyIG1hdGNoTGVuID0gKG1hdGNoICYmIG1hdGNoWzBdLmxlbmd0aCkgfHwgMDtcbiAgICAgICAgICB2Y
23459XIgc3RhcnQgPSBtYXRjaCAmJiBtYXRjaC5pbmRleDtcbiAgICAgICAgICBpZiAoc3RhcnQgKyBtYXRjaExlbiAhPSBsaW5lLmxlbmd0aCAmJiAhbWF0Y2hMZW4pIG1hdGNoTGVuID0gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWF0Y2ggJiYgbWF0Y2hMZW4pXG4gICAgICAgICAgcmV0dXJuIHtmcm9tOiBQb3MocG9zLmxpbmUsIHN0YXJ0KSxcbiAgICAgICAgICAgICAgICAgIHRvOiBQb3MocG9zLmxpbmUsIHN0YXJ0ICsgbWF0Y2hMZW4pLFxuICAgICAgICAgICAgICAgICAgbWF0Y2g6IG1hdGNofTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHsgLy8gU3RyaW5nIHF1ZXJ5XG4gICAgICB2YXIgb3JpZ1F1ZXJ5ID0gcXVlcnk7XG4gICAgICBpZiAoY2FzZUZvbGQpIHF1ZXJ5ID0gcXVlcnkudG9Mb3dlckNhc2UoKTtcbiAgICAgIHZhciBmb2xkID0gY2FzZUZvbGQgPyBmdW5jdGlvbihzdHIpe3JldHVybiBzdHIudG9Mb3dlckNhc2UoKTt9IDogZnVuY3Rpb24oc3RyKXtyZXR1cm4gc3RyO307XG4gICAgICB2YXIgdGFyZ2V0ID0gcXVlcnkuc3BsaXQoXCJcXG5cIik7XG4gICAgICAvLyBEaWZmZXJlbnQgbWV0aG9kcyBmb3Igc2luZ2xlLWxpbmUgYW5kIG11bHRpLWxpbmUgcXVlcmllc1xuICAgICAgaWYgKHRhcmdldC5sZW5ndGggPT0gMSkge1xuICAgICAgICBpZiAoIXF1ZXJ5Lmxlbmd0aCkge1xuICAgICAgICAgIC8vIEVtcHR5IHN0cmluZyB3b3VsZCBtYXRjaCBhbnl0aGluZyBhbmQgbmV2ZXIgcHJvZ3Jlc3MsIHNvXG4gICAgICAgICAgLy8gd2UgZGVmaW5lIGl0IHRvIG1hdGNoIG5vdGhpbmcgaW5zdGVhZC5cbiAgICAgICAgICB0aGlzLm1hdGNoZXMgPSBmdW5jdGlvbigpIHt9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMubWF0Y2hlcyA9IGZ1bmN0aW9uKHJldmVyc2UsIHBvcykge1xuICAgICAgICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgICAgICAgdmFyIG9yaWcgPSBkb2MuZ2V0TGluZShwb3MubGluZSkuc2xpY2UoMCwgcG9zLmNoKSwgbGluZSA9IGZvbGQob3JpZyk7XG4gICAgICAgICAgICAgIHZhciBtYXRjaCA9IGxpbmUubGFzdEluZGV4T2YocXVlcnkpO1xuICAgICAgICAgICAgICBpZiAobWF0Y2ggPiAtMSkge1xuICAgICAgICAgICAgICAgIG1hdGNoID0gYWRqdXN0UG9zKG9yaWcsIGxpbmUsIG1hdGNoKTtcbiAgICAgICAgICAgICAgICByZXR1cm4ge2Zyb206IFBvcyhwb3MubGluZSwgbWF0Y2gpLCB0bzogUG9zKHBvcy5saW5lLCBtYXRjaCArIG9yaWdRdWVyeS5sZW5ndGgpfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICB2Y
23459XIgb3JpZyA9IGRvYy5nZXRMaW5lKHBvcy5saW5lKS5zbGljZShwb3MuY2gpLCBsaW5lID0gZm9sZChvcmlnKTtcbiAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IGxpbmUuaW5kZXhPZihxdWVyeSk7XG4gICAgICAgICAgICAgICBpZiAobWF0Y2ggPiAtMSkge1xuICAgICAgICAgICAgICAgICBtYXRjaCA9IGFkanVzdFBvcyhvcmlnLCBsaW5lLCBtYXRjaCkgKyBwb3MuY2g7XG4gICAgICAgICAgICAgICAgIHJldHVybiB7ZnJvbTogUG9zKHBvcy5saW5lLCBtYXRjaCksIHRvOiBQb3MocG9zLmxpbmUsIG1hdGNoICsgb3JpZ1F1ZXJ5Lmxlbmd0aCl9O1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBvcmlnVGFyZ2V0ID0gb3JpZ1F1ZXJ5LnNwbGl0KFwiXFxuXCIpO1xuICAgICAgICB0aGlzLm1hdGNoZXMgPSBmdW5jdGlvbihyZXZlcnNlLCBwb3MpIHtcbiAgICAgICAgICB2YXIgbGFzdCA9IHRhcmdldC5sZW5ndGggLSAxO1xuICAgICAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgICAgICBpZiAocG9zLmxpbmUgLSAodGFyZ2V0Lmxlbmd0aCAtIDEpIDwgZG9jLmZpcnN0TGluZSgpKSByZXR1cm47XG4gICAgICAgICAgICBpZiAoZm9sZChkb2MuZ2V0TGluZShwb3MubGluZSkuc2xpY2UoMCwgb3JpZ1RhcmdldFtsYXN0XS5sZW5ndGgpKSAhPSB0YXJnZXRbdGFyZ2V0Lmxlbmd0aCAtIDFdKSByZXR1cm47XG4gICAgICAgICAgICB2YXIgdG8gPSBQb3MocG9zLmxpbmUsIG9yaWdUYXJnZXRbbGFzdF0ubGVuZ3RoKTtcbiAgICAgICAgICAgIGZvciAodmFyIGxuID0gcG9zLmxpbmUgLSAxLCBpID0gbGFzdCAtIDE7IGkgPj0gMTsgLS1pLCAtLWxuKVxuICAgICAgICAgICAgICBpZiAodGFyZ2V0W2ldICE9IGZvbGQoZG9jLmdldExpbmUobG4pKSkgcmV0dXJuO1xuICAgICAgICAgICAgdmFyIGxpbmUgPSBkb2MuZ2V0TGluZShsbiksIGN1dCA9IGxpbmUubGVuZ3RoIC0gb3JpZ1RhcmdldFswXS5sZW5ndGg7XG4gICAgICAgICAgICBpZiAoZm9sZChsaW5lLnNsaWNlKGN1dCkpICE9IHRhcmdldFswXSkgcmV0dXJuO1xuICAgICAgICAgICAgcmV0dXJuIHtmcm9tOiBQb3MobG4sIGN1dCksIHRvOiB0b307XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChwb3MubGluZSArICh0YXJnZXQubGVuZ3RoIC0gMSkgPiBkb2MubGFzdExpbmUoKSkgcmV0dXJuO1xuICAgICAgICAgICAgdmFyIGxpbmUgPSBkb2MuZ2V0TGluZShwb3MubGluZSksIGN1dCA9IGxpbmUubGVuZ3RoIC0gb3JpZ1RhcmdldFswXS5sZW5ndGg7XG4gICAgICAgICAgICBpZiAoZm9sZChsaW5lLnNsaWNlKGN1dCkpICE9IHRhcmdldFswXSkgcmV0dXJuO1xuICAgICAgICAgICAgdmFyIGZyb20gPSBQb3MocG9zLmxpbmUsIGN1dCk7XG4gICAgICAgICAgICBmb3IgKHZhciBsbiA9IHBvcy5saW5lICsgMSwgaSA9IDE7IGkgPCBsYXN0OyArK2ksICsrbG4pXG4gICAgICAgICAgICAgIGlmICh0YXJnZXRbaV0gIT0gZm9sZChkb2MuZ2V0TGluZShsbikpKSByZXR1cm47XG4gICAgICAgICAgICBpZiAoZm9sZChkb2MuZ2V0TGluZShsbikuc2xpY2UoMCwgb3JpZ1RhcmdldFtsYXN0XS5sZW5ndGgpKSAhPSB0YXJnZXRbbGFzdF0pIHJldHVybjtcbiAgICAgICAgICAgIHJldHVybiB7ZnJvbTogZnJvbSwgdG86IFBvcyhsbiwgb3JpZ1RhcmdldFtsYXN0XS5sZW5ndGgpfTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgU2VhcmNoQ3Vyc29yLnByb3RvdHlwZSA9IHtcbiAgICBmaW5kTmV4dDogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMuZmluZChmYWxzZSk7fSxcbiAgICBmaW5kUHJldmlvdXM6IGZ1bmN0aW9uKCkge3JldHVybiB0aGlzLmZpbmQodHJ1ZSk7fSxcblxuICAgIGZpbmQ6IGZ1bmN0aW9uKHJldmVyc2UpIHtcbiAgICAgIHZhciBzZWxmID0gdGhpcywgcG9zID0gdGhpcy5kb2MuY2xpcFBvcyhyZXZlcnNlID8gdGhpcy5wb3MuZnJvbSA6IHRoaXMucG9zLnRvKTtcbiAgICAgIGZ1bmN0aW9uIHNhdmVQb3NBbmRGYWlsKGxpbmUp
23459IHtcbiAgICAgICAgdmFyIHBvcyA9IFBvcyhsaW5lLCAwKTtcbiAgICAgICAgc2VsZi5wb3MgPSB7ZnJvbTogcG9zLCB0bzogcG9zfTtcbiAgICAgICAgc2VsZi5hdE9jY3VycmVuY2UgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBmb3IgKDs7KSB7XG4gICAgICAgIGlmICh0aGlzLnBvcyA9IHRoaXMubWF0Y2hlcyhyZXZlcnNlLCBwb3MpKSB7XG4gICAgICAgICAgdGhpcy5hdE9jY3VycmVuY2UgPSB0cnVlO1xuICAgICAgICAgIHJldHVybiB0aGlzLnBvcy5tYXRjaCB8fCB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgICAgaWYgKCFwb3MubGluZSkgcmV0dXJuIHNhdmVQb3NBbmRGYWlsKDApO1xuICAgICAgICAgIHBvcyA9IFBvcyhwb3MubGluZS0xLCB0aGlzLmRvYy5nZXRMaW5lKHBvcy5saW5lLTEpLmxlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdmFyIG1heExpbmUgPSB0aGlzLmRvYy5saW5lQ291bnQoKTtcbiAgICAgICAgICBpZiAocG9zLmxpbmUgPT0gbWF4TGluZSAtIDEpIHJldHVybiBzYXZlUG9zQW5kRmFpbChtYXhMaW5lKTtcbiAgICAgICAgICBwb3MgPSBQb3MocG9zLmxpbmUgKyAxLCAwKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBmcm9tOiBmdW5jdGlvbigpIHtpZiAodGhpcy5hdE9jY3VycmVuY2UpIHJldHVybiB0aGlzLnBvcy5mcm9tO30sXG4gICAgdG86IGZ1bmN0aW9uKCkge2lmICh0aGlzLmF0T2NjdXJyZW5jZSkgcmV0dXJuIHRoaXMucG9zLnRvO30sXG5cbiAgICByZXBsYWNlOiBmdW5jdGlvbihuZXdUZXh0LCBvcmlnaW4pIHtcbiAgICAgIGlmICghdGhpcy5hdE9jY3VycmVuY2UpIHJldHVybjtcbiAgICAgIHZhciBsaW5lcyA9IENvZGVNaXJyb3Iuc3BsaXRMaW5lcyhuZXdUZXh0KTtcbiAgICAgIHRoaXMuZG9jLnJlcGxhY2VSYW5nZShsaW5lcywgdGhpcy5wb3MuZnJvbSwgdGhpcy5wb3MudG8sIG9yaWdpbik7XG4gICAgICB0aGlzLnBvcy50byA9IFBvcyh0aGlzLnBvcy5mcm9tLmxpbmUgKyBsaW5lcy5sZW5ndGggLSAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgbGluZXNbbGluZXMubGVuZ3RoIC0gMV0ubGVuZ3RoICsgKGxpbmVzLmxlbmd0aCA9PSAxID8gdGhpcy5wb3MuZnJvbS5jaCA6IDApKTtcbiAgICB9XG4gIH07XG5cbiAgLy8gTWFwcyBhIHBvc2l0aW9uIGluIGEgY2FzZS1mb2xkZWQgbGluZSBiYWNrIHRvIGEgcG9zaXRpb24gaW4gdGhlIG9yaWdpbmFsIGxpbmVcbiAgLy8gKGNvbXBlbnNhdGluZyBmb3IgY29kZXBvaW50cyBpbmNyZWFzaW5nIGluIG51bWJlciBkdXJpbmcgZm9sZGluZylcbiAgZnVuY3Rpb24gYWRqdXN0UG9zKG9yaWcsIGZvbGRlZCwgcG9zKSB7XG4gICAgaWYgKG9yaWcubGVuZ3RoID09IGZvbGRlZC5sZW5ndGgpIHJldHVybiBwb3M7XG4gICAgZm9yICh2YXIgcG9zMSA9IE1hdGgubWluKHBvcywgb3JpZy5sZW5ndGgpOzspIHtcbiAgICAgIHZhciBsZW4xID0gb3JpZy5zbGljZSgwLCBwb3MxKS50b0xvd2VyQ2FzZSgpLmxlbmd0aDtcbiAgICAgIGlmIChsZW4xIDwgcG9zKSArK3BvczE7XG4gICAgICBlbHNlIGlmIChsZW4xID4gcG9zKSAtLXBvczE7XG4gICAgICBlbHNlIHJldHVybiBwb3MxO1xuICAgIH1cbiAgfVxuXG4gIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uKFwiZ2V0U2VhcmNoQ3Vyc29yXCIsIGZ1bmN0aW9uKHF1ZXJ5LCBwb3MsIGNhc2VGb2xkKSB7XG4gICAgcmV0dXJuIG5ldyBTZWFyY2hDdXJzb3IodGhpcy5kb2MsIHF1ZXJ5LCBwb3MsIGNhc2VGb2xkKTtcbiAgfSk7XG4gIENvZGVNaXJyb3IuZGVmaW5lRG9jRXh0ZW5zaW9uKFwiZ2V0U2VhcmNoQ3Vyc29yXCIsIGZ1bmN0aW9uKHF1ZXJ5LCBwb3MsIGNhc2VGb2xkKSB7XG4gICAgcmV0dXJuIG5ldyBTZWFyY2hDdXJzb3IodGhpcywgcXVlcnksIHBvcywgY2FzZUZvbGQpO1xuICB9KTtcblxuICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbihcInNlbGVjdE1hdGNoZXNcIiwgZnVuY3Rpb24ocXVlcnksIGNhc2VGb2xkKSB7XG4gICAgdmFyIHJhbmdlcyA9IFtdO1xuICAgIHZhciBjdXIgPSB0aGlzLmdldFNlYXJjaEN1cnNvcihxdWVyeSwgdGhpcy5nZXRDdXJzb3IoXCJmcm9tXCIpLCBjYXNlRm9sZCk7XG4gICAgd2hpbGUgKGN1ci5maW5kTmV4dCgpKSB7XG4gICAgICBpZiAoQ29kZU1pcnJvci5jbXBQb3MoY3VyLnRvKCksIHRoaXMuZ2V0Q3Vyc29yKFwidG9cIikpID4gMCkgYnJlYWs7XG4gICAgICByYW5nZXMucHVzaCh7YW5jaG9yOiBjdXIuZnJvbSgpLCBoZWFkOiBjdXIudG8oKX0pO1xuICAgIH1cbiAgICBpZiAocmFuZ2VzLmxlbmd0aClcbiAgICAgIHRoaXMuc2V0U2VsZWN0aW9ucyhyYW5nZXMsIDApO1xuICB9KTtcbn0pO1xuIiwiLy8gQ29kZU1pcnJvciwgY29weXJpZ2h0IChjKSBieSBNYXJpam4gSGF2ZXJiZWtlIGFuZCBvdGhlcnNcbi8vIERpc3RyaWJ1dGVkIHVuZGVyIGFuIE1JVCBsaWNlbnNlOiBodHRwOi8vY29kZW1pcnJvci5uZXQvTElDRU5TRVxuXG4oZnVuY3Rpb24obW9kKSB7XG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUgPT0gXCJvYmplY3RcIikgLy8gQ29tbW9uSlNcbiAgICBtb2QocmVxdWlyZShcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCJdLCBtb2QpO1xuICBlbHNlIC8vIFBsYWluIGJyb3dzZXIgZW52XG4gICAgbW9kKENvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24oQ29kZU1pcnJvcikge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICB2YXIgUG9zID0gQ29kZU1pcnJvci5Qb3M7XG5cbiAgZnVuY3Rpb24gZmluZFBhcmFncmFwaChjbSwgcG9zLCBvcHRpb25zKSB7XG4gICAgdmFyIHN0YXJ0UkUgPSBvcHRpb25zLnBhcmFncmFwaFN0YXJ0IHx8IGNtLmdldEhlbHBlcihwb3MsIFwicGFyYWdyYXBoU3RhcnRcIik7XG4gICAgZm9yICh2YXIgc3RhcnQgPSBwb3MubGluZSwgZmlyc3QgPSBjbS5maXJzdExpbmUoKTsgc3RhcnQgPiBmaXJzdDsgLS1zdGFydCkge1xuICAgICAgdmFyIGxpbmUgPSBjbS5nZXRMaW5lKHN0YXJ0KTtcbiAgICAgIGlmIChzdGFydFJFICYmIHN0YXJ0UkUudGVzdChsaW5lKSkgYnJlYWs7XG4gICAgICBpZiAoIS9cXFMvLnRlc3QobGluZSkpIHsgKytzdGFydDsgYnJlYWs7IH1cbiAgICB9XG4gICAgdmFyIGVuZFJFID0gb3B0aW9ucy5wYXJhZ3JhcGhFbmQgfHwgY20uZ2V0SGVscGVyKHBvcywgXCJwYXJhZ3JhcGhFbmRcIik7XG4gICAgZm9yICh2YXIgZW5kID0gcG9zLmxpbmUgKyAxLCBsYXN0ID0gY20ubGFzdExpbmUoKTsgZW5kIDw9IGxhc3Q7ICsrZW5kKSB7XG4gICAgICB2Y
23459XIgbGluZSA9IGNtLmdldExpbmUoZW5kKTtcbiAgICAgIGlmIChlbmRSRSAmJiBlbmRSRS50ZXN0KGxpbmUpKSB7ICsrZW5kOyBicmVhazsgfVxuICAgICAgaWYgKCEvXFxTLy50ZXN0KGxpbmUpKSBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIHtmcm9tOiBzdGFydCwgdG86IGVuZH07XG4gIH1cblxuICBmdW5jdGlvbiBmaW5kQnJlYWtQb2ludCh0ZXh0LCBjb2x1bW4sIHdyYXBPbiwga2lsbFRyYWlsaW5nU3BhY2UpIHtcbiAgICBmb3IgKHZhciBhdCA9IGNvbHVtbjsgYXQgPiAwOyAtLWF0KVxuICAgICAgaWYgKHdyYXBPbi50ZXN0KHRleHQuc2xpY2UoYXQgLSAxLCBhdCArIDEpKSkgYnJlYWs7XG4gICAgZm9yICh2YXIgZmlyc3QgPSB0cnVlOzsgZmlyc3QgPSBmYWxzZSkge1xuICAgICAgdmFyIGVuZE9mVGV4dCA9IGF0O1xuICAgICAgaWYgKGtpbGxUcmFpbGluZ1NwYWNlKVxuICAgICAgICB3aGlsZSAodGV4dC5jaGFyQXQoZW5kT2ZUZXh0IC0gMSkgPT0gXCIgXCIpIC0tZW5kT2ZUZXh0O1xuICAgICAgaWYgKGVuZE9mVGV4dCA9PSAwICYmIGZpcnN0KSBhdCA9IGNvbHVtbjtcbiAgICAgIGVsc2UgcmV0dXJuIHtmcm9tOiBlbmRPZlRleHQsIHRvOiBhdH07XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gd3JhcFJhbmdlKGNtLCBmcm9tLCB0bywgb3B0aW9ucykge1xuICAgIGZyb20gPSBjbS5jbGlwUG9zKGZyb20pOyB0byA9IGNtLmNsaXBQb3ModG8pO1xuICAgIHZhciBjb2x1bW4gPSBvcHRpb25zLmNvbHVtbiB8fCA4MDtcbiAgICB2YXIgd3JhcE9uID0gb3B0aW9ucy53cmFwT24gfHwgL1xcc1xcU3wtW15cXC5cXGRdLztcbiAgICB2YXIga2lsbFRyYWlsaW5nID0gb3B0aW9ucy5raWxsVHJhaWxpbmdTcGFjZSAhPT0gZmFsc2U7XG4gICAgdmFyIGNoYW5nZXMgPSBbXSwgY3VyTGluZSA9IFwiXCIsIGN1ck5vID0gZnJvbS5saW5lO1xuICAgIHZhciBsaW5lcyA9IGNtLmdldFJhbmdlKGZyb20sIHRvLCBmYWxzZSk7XG4gICAgaWYgKCFsaW5lcy5sZW5ndGgpIHJldHVybiBudWxsO1xuICAgIHZhciBsZWFkaW5nU3BhY2UgPSBsaW5lc1swXS5tYXRjaCgvXlsgXFx0XSovKVswXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciB0ZXh0ID0gbGluZXNbaV0sIG9sZExlbiA9IGN1ckxpbmUubGVuZ3RoLCBzcGFjZUluc2VydGVkID0gMDtcbiAgICAgIGlmIChjdXJMaW5lICYmIHRleHQgJiYgIXdyYXBPbi50ZXN0KGN1ckxpbmUuY2hhckF0KGN1ckxpbmUubGVuZ3RoIC0gMSkgKyB0ZXh0LmNoYXJBdCgwKSkpIHtcbiAgICAgICAgY3VyTGluZSArPSBcIiBcIjtcbiAgICAgICAgc3BhY2VJbnNlcnRlZCA9IDE7XG4gICAgICB9XG4gICAgICB2Y
23459XIgc3BhY2VUcmltbWVkID0gXCJcIjtcbiAgICAgIGlmIChpKSB7XG4gICAgICAgIHNwYWNlVHJpbW1lZCA9IHRleHQubWF0Y2goL15cXHMqLylbMF07XG4gICAgICAgIHRleHQgPSB0ZXh0LnNsaWNlKHNwYWNlVHJpbW1lZC5sZW5ndGgpO1xuICAgICAgfVxuICAgICAgY3VyTGluZSArPSB0ZXh0O1xuICAgICAgaWYgKGkpIHtcbiAgICAgICAgdmFyIGZpcnN0QnJlYWsgPSBjdXJMaW5lLmxlbmd0aCA+IGNvbHVtbiAmJiBsZWFkaW5nU3BhY2UgPT0gc3BhY2VUcmltbWVkICYmXG4gICAgICAgICAgZmluZEJyZWFrUG9pbnQoY3VyTGluZSwgY29sdW1uLCB3cmFwT24sIGtpbGxUcmFpbGluZyk7XG4gICAgICAgIC8vIElmIHRoaXMgaXNuJ3QgYnJva2VuLCBvciBpcyBicm9rZW4gYXQgYSBkaWZmZXJlbnQgcG9pbnQsIHJlbW92ZSBvbGQgYnJlYWtcbiAgICAgICAgaWYgKCFmaXJzdEJyZWFrIHx8IGZpcnN0QnJlYWsuZnJvbSAhPSBvbGRMZW4gfHwgZmlyc3RCcmVhay50byAhPSBvbGRMZW4gKyBzcGFjZUluc2VydGVkKSB7XG4gICAgICAgICAgY2hhbmdlcy5wdXNoKHt0ZXh0OiBbc3BhY2VJbnNlcnRlZCA/IFwiIFwiIDogXCJcIl0sXG4gICAgICAgICAgICAgICAgICAgICAgICBmcm9tOiBQb3MoY3VyTm8sIG9sZExlbiksXG4gICAgICAgICAgICAgICAgICAgICAgICB0bzogUG9zKGN1ck5vICsgMSwgc3BhY2VUcmltbWVkLmxlbmd0aCl9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXJMaW5lID0gbGVhZGluZ1NwYWNlICsgdGV4dDtcbiAgICAgICAgICArK2N1ck5vO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAoY3VyTGluZS5sZW5ndGggPiBjb2x1bW4pIHtcbiAgICAgICAgdmFyIGJwID0gZmluZEJyZWFrUG9pbnQoY3VyTGluZSwgY29sdW1uLCB3cmFwT24sIGtpbGxUcmFpbGluZyk7XG4gICAgICAgIGNoYW5nZXMucHVzaCh7dGV4dDogW1wiXCIsIGxlYWRpbmdTcGFjZV0sXG4gICAgICAgICAgICAgICAgICAgICAgZnJvbTogUG9zKGN1ck5vLCBicC5mcm9tKSxcbiAgICAgICAgICAgICAgICAgICAgICB0bzogUG9zKGN1ck5vLCBicC50byl9KTtcbiAgICAgICAgY3VyTGluZSA9IGxlYWRpbmdTcGFjZSArIGN1ckxpbmUuc2xpY2UoYnAudG8pO1xuICAgICAgICArK2N1ck5vO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoY2hhbmdlcy5sZW5ndGgpIGNtLm9wZXJhdGlvbihmdW5jdGlvbigpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hhbmdlcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2Y
23459XIgY2hhbmdlID0gY2hhbmdlc1tpXTtcbiAgICAgICAgaWYgKGNoYW5nZS50ZXh0IHx8IENvZGVNaXJyb3IuY21wUG9zKGNoYW5nZS5mcm9tLCBjaGFuZ2UudG8pKVxuICAgICAgICAgIGNtLnJlcGxhY2VSYW5nZShjaGFuZ2UudGV4dCwgY2hhbmdlLmZyb20sIGNoYW5nZS50byk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGNoYW5nZXMubGVuZ3RoID8ge2Zyb206IGNoYW5nZXNbMF0uZnJvbSwgdG86IENvZGVNaXJyb3IuY2hhbmdlRW5kKGNoYW5nZXNbY2hhbmdlcy5sZW5ndGggLSAxXSl9IDogbnVsbDtcbiAgfVxuXG4gIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uKFwid3JhcFBhcmFncmFwaFwiLCBmdW5jdGlvbihwb3MsIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICBpZiAoIXBvcykgcG9zID0gdGhpcy5nZXRDdXJzb3IoKTtcbiAgICB2YXIgcGFyYSA9IGZpbmRQYXJhZ3JhcGgodGhpcywgcG9zLCBvcHRpb25zKTtcbiAgICByZXR1cm4gd3JhcFJhbmdlKHRoaXMsIFBvcyhwYXJhLmZyb20sIDApLCBQb3MocGFyYS50byAtIDEpLCBvcHRpb25zKTtcbiAgfSk7XG5cbiAgQ29kZU1pcnJvci5jb21tYW5kcy53cmFwTGluZXMgPSBmdW5jdGlvbihjbSkge1xuICAgIGNtLm9wZXJhdGlvbihmdW5jdGlvbigpIHtcbiAgICAgIHZhciByYW5nZXMgPSBjbS5saXN0U2VsZWN0aW9ucygpLCBhdCA9IGNtLmxhc3RMaW5lKCkgKyAxO1xuICAgICAgZm9yICh2YXIgaSA9IHJhbmdlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICB2Y
23459XIgcmFuZ2UgPSByYW5nZXNbaV0sIHNwYW47XG4gICAgICAgIGlmIChyYW5nZS5lbXB0eSgpKSB7XG4gICAgICAgICAgdmFyIHBhcmEgPSBmaW5kUGFyYWdyYXBoKGNtLCByYW5nZS5oZWFkLCB7fSk7XG4gICAgICAgICAgc3BhbiA9IHtmcm9tOiBQb3MocGFyYS5mcm9tLCAwKSwgdG86IFBvcyhwYXJhLnRvIC0gMSl9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNwYW4gPSB7ZnJvbTogcmFuZ2UuZnJvbSgpLCB0bzogcmFuZ2UudG8oKX07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNwYW4udG8ubGluZSA+PSBhdCkgY29udGludWU7XG4gICAgICAgIGF0ID0gc3Bhbi5mcm9tLmxpbmU7XG4gICAgICAgIHdyYXBSYW5nZShjbSwgc3Bhbi5mcm9tLCBzcGFuLnRvLCB7fSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgQ29kZU1pcnJvci5kZWZpbmVFeHRlbnNpb24oXCJ3cmFwUmFuZ2VcIiwgZnVuY3Rpb24oZnJvbSwgdG8sIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gd3JhcFJhbmdlKHRoaXMsIGZyb20sIHRvLCBvcHRpb25zIHx8IHt9KTtcbiAgfSk7XG5cbiAgQ29kZU1pcnJvci5kZWZpbmVFeHRlbnNpb24oXCJ3cmFwUGFyYWdyYXBoc0luUmFuZ2VcIiwgZnVuY3Rpb24oZnJvbSwgdG8sIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICB2YXIgY20gPSB0aGlzLCBwYXJhcyA9IFtdO1xuICAgIGZvciAodmFyIGxpbmUgPSBmcm9tLmxpbmU7IGxpbmUgPD0gdG8ubGluZTspIHtcbiAgICAgIHZhciBwYXJhID0gZmluZFBhcmFncmFwaChjbSwgUG9zKGxpbmUsIDApLCBvcHRpb25zKTtcbiAgICAgIHBhcmFzLnB1c2gocGFyYSk7XG4gICAgICBsaW5lID0gcGFyYS50bztcbiAgICB9XG4gICAgdmFyIG1hZGVDaGFuZ2UgPSBmYWxzZTtcbiAgICBpZiAocGFyYXMubGVuZ3RoKSBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKHZhciBpID0gcGFyYXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpXG4gICAgICAgIG1hZGVDaGFuZ2UgPSBtYWRlQ2hhbmdlIHx8IHdyYXBSYW5nZShjbSwgUG9zKHBhcmFzW2ldLmZyb20sIDApLCBQb3MocGFyYXNbaV0udG8gLSAxKSwgb3B0aW9ucyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG1hZGVDaGFuZ2U7XG4gIH0pO1xufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbi8vIEEgcm91Z2ggYXBwcm94aW1hdGlvbiBvZiBTdWJsaW1lIFRleHQncyBrZXliaW5kaW5nc1xuLy8gRGVwZW5kcyBvbiBhZGRvbi9zZWFyY2gvc2VhcmNoY3Vyc29yLmpzIGFuZCBvcHRpb25hbGx5IGFkZG9uL2RpYWxvZy9kaWFsb2dzLmpzXG5cbihmdW5jdGlvbihtb2QpIHtcbiAgaWYgKHR5cGVvZiBleHBvcnRzID09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PSBcIm9iamVjdFwiKSAvLyBDb21tb25KU1xuICAgIG1vZChyZXF1aXJlKFwiLi4vbGliL2NvZGVtaXJyb3JcIiksIHJlcXVpcmUoXCIuLi9hZGRvbi9zZWFyY2gvc2VhcmNoY3Vyc29yXCIpLCByZXF1aXJlKFwiLi4vYWRkb24vZWRpdC9tYXRjaGJyYWNrZXRzXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uL2xpYi9jb2RlbWlycm9yXCIsIFwiLi4vYWRkb24vc2VhcmNoL3NlYXJjaGN1cnNvclwiLCBcIi4uL2FkZG9uL2VkaXQvbWF0Y2hicmFja2V0c1wiXSwgbW9kKTtcbiAgZWxzZSAvLyBQbGFpbiBicm93c2VyIGVudlxuICAgIG1vZChDb2RlTWlycm9yKTtcbn0pKGZ1bmN0aW9uKENvZGVNaXJyb3IpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgdmFyIG1hcCA9IENvZGVNaXJyb3Iua2V5TWFwLnN1YmxpbWUgPSB7ZmFsbHRocm91Z2g6IFwiZGVmYXVsdFwifTtcbiAgdmFyIGNtZHMgPSBDb2RlTWlycm9yLmNvbW1hbmRzO1xuICB2YXIgUG9zID0gQ29kZU1pcnJvci5Qb3M7XG4gIHZhciBtYWMgPSBDb2RlTWlycm9yLmtleU1hcFtcImRlZmF1bHRcIl0gPT0gQ29kZU1pcnJvci5rZXlNYXAubWFjRGVmYXVsdDtcbiAgdmFyIGN0cmwgPSBtYWMgPyBcIkNtZC1cIiA6IFwiQ3RybC1cIjtcblxuICAvLyBUaGlzIGlzIG5vdCBleGFjdGx5IFN1YmxpbWUncyBhbGdvcml0aG0uIEkgY291bGRuJ3QgbWFrZSBoZWFkcyBvciB0YWlscyBvZiB0aGF0LlxuICBmdW5jdGlvbiBmaW5kUG9zU3Vid29yZChkb2MsIHN0YXJ0LCBkaXIpIHtcbiAgICBpZiAoZGlyIDwgMCAmJiBzdGFydC5jaCA9PSAwKSByZXR1cm4gZG9jLmNsaXBQb3MoUG9zKHN0YXJ0LmxpbmUgLSAxKSk7XG4gICAgdmFyIGxpbmUgPSBkb2MuZ2V0TGluZShzdGFydC5saW5lKTtcbiAgICBpZiAoZGlyID4gMCAmJiBzdGFydC5jaCA+PSBsaW5lLmxlbmd0aCkgcmV0dXJuIGRvYy5jbGlwUG9zKFBvcyhzdGFydC5saW5lICsgMSwgMCkpO1xuICAgIHZhciBzdGF0ZSA9IFwic3RhcnRcIiwgdHlwZTtcbiAgICBmb3IgKHZhciBwb3MgPSBzdGFydC5jaCwgZSA9IGRpciA8IDAgPyAwIDogbGluZS5sZW5ndGgsIGkgPSAwOyBwb3MgIT0gZTsgcG9zICs9IGRpciwgaSsrKSB7XG4gICAgICB2Y
23459XIgbmV4dCA9IGxpbmUuY2hhckF0KGRpciA8IDAgPyBwb3MgLSAxIDogcG9zKTtcbiAgICAgIHZhciBjYXQgPSBuZXh0ICE9IFwiX1wiICYmIENvZGVNaXJyb3IuaXNXb3JkQ2hhcihuZXh0KSA/IFwid1wiIDogXCJvXCI7XG4gICAgICBpZiAoY2F0ID09IFwid1wiICYmIG5leHQudG9VcHBlckNhc2UoKSA9PSBuZXh0KSBjYXQgPSBcIldcIjtcbiAgICAgIGlmIChzdGF0ZSA9PSBcInN0YXJ0XCIpIHtcbiAgICAgICAgaWYgKGNhdCAhPSBcIm9cIikgeyBzdGF0ZSA9IFwiaW5cIjsgdHlwZSA9IGNhdDsgfVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PSBcImluXCIpIHtcbiAgICAgICAgaWYgKHR5cGUgIT0gY2F0KSB7XG4gICAgICAgICAgaWYgKHR5cGUgPT0gXCJ3XCIgJiYgY2F0ID09IFwiV1wiICYmIGRpciA8IDApIHBvcy0tO1xuICAgICAgICAgIGlmICh0eXBlID09IFwiV1wiICYmIGNhdCA9PSBcIndcIiAmJiBkaXIgPiAwKSB7IHR5cGUgPSBcIndcIjsgY29udGludWU7IH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gUG9zKHN0YXJ0LmxpbmUsIHBvcyk7XG4gIH1cblxuICBmdW5jdGlvbiBtb3ZlU3Vid29yZChjbSwgZGlyKSB7XG4gICAgY20uZXh0ZW5kU2VsZWN0aW9uc0J5KGZ1bmN0aW9uKHJhbmdlKSB7XG4gICAgICBpZiAoY20uZGlzcGxheS5zaGlmdCB8fCBjbS5kb2MuZXh0ZW5kIHx8IHJhbmdlLmVtcHR5KCkpXG4gICAgICAgIHJldHVybiBmaW5kUG9zU3Vid29yZChjbS5kb2MsIHJhbmdlLmhlYWQsIGRpcik7XG4gICAgICBlbHNlXG4gICAgICAgIHJldHVybiBkaXIgPCAwID8gcmFuZ2UuZnJvbSgpIDogcmFuZ2UudG8oKTtcbiAgICB9KTtcbiAgfVxuXG4gIGNtZHNbbWFwW1wiQWx0LUxlZnRcIl0gPSBcImdvU3Vid29yZExlZnRcIl0gPSBmdW5jdGlvbihjbSkgeyBtb3ZlU3Vid29yZChjbSwgLTEpOyB9O1xuICBjbWRzW21hcFtcIkFsdC1SaWdodFwiXSA9IFwiZ29TdWJ3b3JkUmlnaHRcIl0gPSBmdW5jdGlvbihjbSkgeyBtb3ZlU3Vid29yZChjbSwgMSk7IH07XG5cbiAgdmFyIHNjcm9sbExpbmVDb21ibyA9IG1hYyA/IFwiQ3RybC1BbHQtXCIgOiBcIkN0cmwtXCI7XG5cbiAgY21kc1ttYXBbc2Nyb2xsTGluZUNvbWJvICsgXCJVcFwiXSA9IFwic2Nyb2xsTGluZVVwXCJdID0gZnVuY3Rpb24oY20pIHtcbiAgICB2YXIgaW5mbyA9IGNtLmdldFNjcm9sbEluZm8oKTtcbiAgICBpZiAoIWNtLnNvbWV0aGluZ1NlbGVjdGVkKCkpIHtcbiAgICAgIHZhciB2aXNpYmxlQm90dG9tTGluZSA9IGNtLmxpbmVBdEhlaWdodChpbmZvLnRvcCArIGluZm8uY2xpZW50SGVpZ2h0LCBcImxvY2FsXCIpO1xuICAgICAgaWYgKGNtLmdldEN1cnNvcigpLmxpbmUgPj0gdmlzaWJsZUJvdHRvbUxpbmUpXG4gICAgICAgIGNtLmV4ZWNDb21tYW5kKFwiZ29MaW5lVXBcIik7XG4gICAgfVxuICAgIGNtLnNjcm9sbFRvKG51bGwsIGluZm8udG9wIC0gY20uZGVmYXVsdFRleHRIZWlnaHQoKSk7XG4gIH07XG4gIGNtZHNbbWFwW3Njcm9sbExpbmVDb21ibyArIFwiRG93blwiXSA9IFwic2Nyb2xsTGluZURvd25cIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIHZhciBpbmZvID0gY20uZ2V0U2Nyb2xsSW5mbygpO1xuICAgIGlmICghY20uc29tZXRoaW5nU2VsZWN0ZWQoKSkge1xuICAgICAgdmFyIHZpc2libGVUb3BMaW5lID0gY20ubGluZUF0SGVpZ2h0KGluZm8udG9wLCBcImxvY2FsXCIpKzE7XG4gICAgICBpZiAoY20uZ2V0Q3Vyc29yKCkubGluZSA8PSB2aXNpYmxlVG9wTGluZSlcbiAgICAgICAgY20uZXhlY0NvbW1hbmQoXCJnb0xpbmVEb3duXCIpO1xuICAgIH1cbiAgICBjbS5zY3JvbGxUbyhudWxsLCBpbmZvLnRvcCArIGNtLmRlZmF1bHRUZXh0SGVpZ2h0KCkpO1xuICB9O1xuXG4gIGNtZHNbbWFwW1wiU2hpZnQtXCIgKyBjdHJsICsgXCJMXCJdID0gXCJzcGxpdFNlbGVjdGlvbkJ5TGluZVwiXSA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgdmFyIHJhbmdlcyA9IGNtLmxpc3RTZWxlY3Rpb25zKCksIGxpbmVSYW5nZXMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGZyb20gPSByYW5nZXNbaV0uZnJvbSgpLCB0byA9IHJhbmdlc1tpXS50bygpO1xuICAgICAgZm9yICh2YXIgbGluZSA9IGZyb20ubGluZTsgbGluZSA8PSB0by5saW5lOyArK2xpbmUpXG4gICAgICAgIGlmICghKHRvLmxpbmUgPiBmcm9tLmxpbmUgJiYgbGluZSA9PSB0by5saW5lICYmIHRvLmNoID09IDApKVxuICAgICAgICAgIGxpbmVSYW5nZXMucHVzaCh7YW5jaG9yOiBsaW5lID09IGZyb20ubGluZSA/IGZyb20gOiBQb3MobGluZSwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkOiBsaW5lID09IHRvLmxpbmUgPyB0byA6IFBvcyhsaW5lKX0pO1xuICAgIH1cbiAgICBjbS5zZXRTZWxlY3Rpb25zKGxpbmVSYW5nZXMsIDApO1xuICB9O1xuXG4gIG1hcFtcIlNoaWZ0LVRhYlwiXSA9IFwiaW5kZW50TGVzc1wiO1xuXG4gIGNtZHNbbWFwW1wiRXNjXCJdID0gXCJzaW5nbGVTZWxlY3Rpb25Ub3BcIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIHZhciByYW5nZSA9IGNtLmxpc3RTZWxlY3Rpb25zKClbMF07XG4gICAgY20uc2V0U2VsZWN0aW9uKHJhbmdlLmFuY2hvciwgcmFuZ2UuaGVhZCwge3Njcm9sbDogZmFsc2V9KTtcbiAgfTtcblxuICBjbWRzW21hcFtjdHJsICsgXCJMXCJdID0gXCJzZWxlY3RMaW5lXCJdID0gZnVuY3Rpb24oY20pIHtcbiAgICB2YXIgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKSwgZXh0ZW5kZWQgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHJhbmdlID0gcmFuZ2VzW2ldO1xuICAgICAgZXh0ZW5kZWQucHVzaCh7YW5jaG9yOiBQb3MocmFuZ2UuZnJvbSgpLmxpbmUsIDApLFxuICAgICAgICAgICAgICAgICAgICAgaGVhZDogUG9zKHJhbmdlLnRvKCkubGluZSArIDEsIDApfSk7XG4gICAgfVxuICAgIGNtLnNldFNlbGVjdGlvbnMoZXh0ZW5kZWQpO1xuICB9O1xuXG4gIG1hcFtcIlNoaWZ0LVwiICsgY3RybCArIFwiS1wiXSA9IFwiZGVsZXRlTGluZVwiO1xuXG4gIGZ1bmN0aW9uIGluc2VydExpbmUoY20sIGFib3ZlKSB7XG4gICAgY20ub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGxlbiA9IGNtLmxpc3RTZWxlY3Rpb25zKCkubGVuZ3RoLCBuZXdTZWxlY3Rpb24gPSBbXSwgbGFzdCA9IC0xO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICB2Y
23459XIgaGVhZCA9IGNtLmxpc3RTZWxlY3Rpb25zKClbaV0uaGVhZDtcbiAgICAgICAgaWYgKGhlYWQubGluZSA8PSBsYXN0KSBjb250aW51ZTtcbiAgICAgICAgdmFyIGF0ID0gUG9zKGhlYWQubGluZSArIChhYm92ZSA/IDAgOiAxKSwgMCk7XG4gICAgICAgIGNtLnJlcGxhY2VSYW5nZShcIlxcblwiLCBhdCwgbnVsbCwgXCIraW5zZXJ0TGluZVwiKTtcbiAgICAgICAgY20uaW5kZW50TGluZShhdC5saW5lLCBudWxsLCB0cnVlKTtcbiAgICAgICAgbmV3U2VsZWN0aW9uLnB1c2goe2hlYWQ6IGF0LCBhbmNob3I6IGF0fSk7XG4gICAgICAgIGxhc3QgPSBoZWFkLmxpbmUgKyAxO1xuICAgICAgfVxuICAgICAgY20uc2V0U2VsZWN0aW9ucyhuZXdTZWxlY3Rpb24pO1xuICAgIH0pO1xuICB9XG5cbiAgY21kc1ttYXBbY3RybCArIFwiRW50ZXJcIl0gPSBcImluc2VydExpbmVBZnRlclwiXSA9IGZ1bmN0aW9uKGNtKSB7IGluc2VydExpbmUoY20sIGZhbHNlKTsgfTtcblxuICBjbWRzW21hcFtcIlNoaWZ0LVwiICsgY3RybCArIFwiRW50ZXJcIl0gPSBcImluc2VydExpbmVCZWZvcmVcIl0gPSBmdW5jdGlvbihjbSkgeyBpbnNlcnRMaW5lKGNtLCB0cnVlKTsgfTtcblxuICBmdW5jdGlvbiB3b3JkQXQoY20sIHBvcykge1xuICAgIHZhciBzdGFydCA9IHBvcy5jaCwgZW5kID0gc3RhcnQsIGxpbmUgPSBjbS5nZXRMaW5lKHBvcy5saW5lKTtcbiAgICB3aGlsZSAoc3RhcnQgJiYgQ29kZU1pcnJvci5pc1dvcmRDaGFyKGxpbmUuY2hhckF0KHN0YXJ0IC0gMSkpKSAtLXN0YXJ0O1xuICAgIHdoaWxlIChlbmQgPCBsaW5lLmxlbmd0aCAmJiBDb2RlTWlycm9yLmlzV29yZENoYXIobGluZS5jaGFyQXQoZW5kKSkpICsrZW5kO1xuICAgIHJldHVybiB7ZnJvbTogUG9zKHBvcy5saW5lLCBzdGFydCksIHRvOiBQb3MocG9zLmxpbmUsIGVuZCksIHdvcmQ6IGxpbmUuc2xpY2Uoc3RhcnQsIGVuZCl9O1xuICB9XG5cbiAgY21kc1ttYXBbY3RybCArIFwiRFwiXSA9IFwic2VsZWN0TmV4dE9jY3VycmVuY2VcIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIHZhciBmcm9tID0gY20uZ2V0Q3Vyc29yKFwiZnJvbVwiKSwgdG8gPSBjbS5nZXRDdXJzb3IoXCJ0b1wiKTtcbiAgICB2YXIgZnVsbFdvcmQgPSBjbS5zdGF0ZS5zdWJsaW1lRmluZEZ1bGxXb3JkID09IGNtLmRvYy5zZWw7XG4gICAgaWYgKENvZGVNaXJyb3IuY21wUG9zKGZyb20sIHRvKSA9PSAwKSB7XG4gICAgICB2Y
23459XIgd29yZCA9IHdvcmRBdChjbSwgZnJvbSk7XG4gICAgICBpZiAoIXdvcmQud29yZCkgcmV0dXJuO1xuICAgICAgY20uc2V0U2VsZWN0aW9uKHdvcmQuZnJvbSwgd29yZC50byk7XG4gICAgICBmdWxsV29yZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciB0ZXh0ID0gY20uZ2V0UmFuZ2UoZnJvbSwgdG8pO1xuICAgICAgdmFyIHF1ZXJ5ID0gZnVsbFdvcmQgPyBuZXcgUmVnRXhwKFwiXFxcXGJcIiArIHRleHQgKyBcIlxcXFxiXCIpIDogdGV4dDtcbiAgICAgIHZhciBjdXIgPSBjbS5nZXRTZWFyY2hDdXJzb3IocXVlcnksIHRvKTtcbiAgICAgIGlmIChjdXIuZmluZE5leHQoKSkge1xuICAgICAgICBjbS5hZGRTZWxlY3Rpb24oY3VyLmZyb20oKSwgY3VyLnRvKCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3VyID0gY20uZ2V0U2VhcmNoQ3Vyc29yKHF1ZXJ5LCBQb3MoY20uZmlyc3RMaW5lKCksIDApKTtcbiAgICAgICAgaWYgKGN1ci5maW5kTmV4dCgpKVxuICAgICAgICAgIGNtLmFkZFNlbGVjdGlvbihjdXIuZnJvbSgpLCBjdXIudG8oKSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChmdWxsV29yZClcbiAgICAgIGNtLnN0YXRlLnN1YmxpbWVGaW5kRnVsbFdvcmQgPSBjbS5kb2Muc2VsO1xuICB9O1xuXG4gIHZhciBtaXJyb3IgPSBcIigpe31bXVwiO1xuICBmdW5jdGlvbiBzZWxlY3RCZXR3ZWVuQnJhY2tldHMoY20pIHtcbiAgICB2YXIgcG9zID0gY20uZ2V0Q3Vyc29yKCksIG9wZW5pbmcgPSBjbS5zY2FuRm9yQnJhY2tldChwb3MsIC0xKTtcbiAgICBpZiAoIW9wZW5pbmcpIHJldHVybjtcbiAgICBmb3IgKDs7KSB7XG4gICAgICB2Y
23459XIgY2xvc2luZyA9IGNtLnNjYW5Gb3JCcmFja2V0KHBvcywgMSk7XG4gICAgICBpZiAoIWNsb3NpbmcpIHJldHVybjtcbiAgICAgIGlmIChjbG9zaW5nLmNoID09IG1pcnJvci5jaGFyQXQobWlycm9yLmluZGV4T2Yob3BlbmluZy5jaCkgKyAxKSkge1xuICAgICAgICBjbS5zZXRTZWxlY3Rpb24oUG9zKG9wZW5pbmcucG9zLmxpbmUsIG9wZW5pbmcucG9zLmNoICsgMSksIGNsb3NpbmcucG9zLCBmYWxzZSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgcG9zID0gUG9zKGNsb3NpbmcucG9zLmxpbmUsIGNsb3NpbmcucG9zLmNoICsgMSk7XG4gICAgfVxuICB9XG5cbiAgY21kc1ttYXBbXCJTaGlmdC1cIiArIGN0cmwgKyBcIlNwYWNlXCJdID0gXCJzZWxlY3RTY29wZVwiXSA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgc2VsZWN0QmV0d2VlbkJyYWNrZXRzKGNtKSB8fCBjbS5leGVjQ29tbWFuZChcInNlbGVjdEFsbFwiKTtcbiAgfTtcbiAgY21kc1ttYXBbXCJTaGlmdC1cIiArIGN0cmwgKyBcIk1cIl0gPSBcInNlbGVjdEJldHdlZW5CcmFja2V0c1wiXSA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgaWYgKCFzZWxlY3RCZXR3ZWVuQnJhY2tldHMoY20pKSByZXR1cm4gQ29kZU1pcnJvci5QYXNzO1xuICB9O1xuXG4gIGNtZHNbbWFwW2N0cmwgKyBcIk1cIl0gPSBcImdvVG9CcmFja2V0XCJdID0gZnVuY3Rpb24oY20pIHtcbiAgICBjbS5leHRlbmRTZWxlY3Rpb25zQnkoZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgIHZhciBuZXh0ID0gY20uc2NhbkZvckJyYWNrZXQocmFuZ2UuaGVhZCwgMSk7XG4gICAgICBpZiAobmV4dCAmJiBDb2RlTWlycm9yLmNtcFBvcyhuZXh0LnBvcywgcmFuZ2UuaGVhZCkgIT0gMCkgcmV0dXJuIG5leHQucG9zO1xuICAgICAgdmFyIHByZXYgPSBjbS5zY2FuRm9yQnJhY2tldChyYW5nZS5oZWFkLCAtMSk7XG4gICAgICByZXR1cm4gcHJldiAmJiBQb3MocHJldi5wb3MubGluZSwgcHJldi5wb3MuY2ggKyAxKSB8fCByYW5nZS5oZWFkO1xuICAgIH0pO1xuICB9O1xuXG4gIHZhciBzd2FwTGluZUNvbWJvID0gbWFjID8gXCJDbWQtQ3RybC1cIiA6IFwiU2hpZnQtQ3RybC1cIjtcblxuICBjbWRzW21hcFtzd2FwTGluZUNvbWJvICsgXCJVcFwiXSA9IFwic3dhcExpbmVVcFwiXSA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgdmFyIHJhbmdlcyA9IGNtLmxpc3RTZWxlY3Rpb25zKCksIGxpbmVzVG9Nb3ZlID0gW10sIGF0ID0gY20uZmlyc3RMaW5lKCkgLSAxLCBuZXdTZWxzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciByYW5nZSA9IHJhbmdlc1tpXSwgZnJvbSA9IHJhbmdlLmZyb20oKS5saW5lIC0gMSwgdG8gPSByYW5nZS50bygpLmxpbmU7XG4gICAgICBuZXdTZWxzLnB1c2goe2FuY2hvcjogUG9zKHJhbmdlLmFuY2hvci5saW5lIC0gMSwgcmFuZ2UuYW5jaG9yLmNoKSxcbiAgICAgICAgICAgICAgICAgICAgaGVhZDogUG9zKHJhbmdlLmhlYWQubGluZSAtIDEsIHJhbmdlLmhlYWQuY2gpfSk7XG4gICAgICBpZiAocmFuZ2UudG8oKS5jaCA9PSAwICYmICFyYW5nZS5lbXB0eSgpKSAtLXRvO1xuICAgICAgaWYgKGZyb20gPiBhdCkgbGluZXNUb01vdmUucHVzaChmcm9tLCB0byk7XG4gICAgICBlbHNlIGlmIChsaW5lc1RvTW92ZS5sZW5ndGgpIGxpbmVzVG9Nb3ZlW2xpbmVzVG9Nb3ZlLmxlbmd0aCAtIDFdID0gdG87XG4gICAgICBhdCA9IHRvO1xuICAgIH1cbiAgICBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVzVG9Nb3ZlLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgIHZhciBmcm9tID0gbGluZXNUb01vdmVbaV0sIHRvID0gbGluZXNUb01vdmVbaSArIDFdO1xuICAgICAgICB2Y
23459XIgbGluZSA9IGNtLmdldExpbmUoZnJvbSk7XG4gICAgICAgIGNtLnJlcGxhY2VSYW5nZShcIlwiLCBQb3MoZnJvbSwgMCksIFBvcyhmcm9tICsgMSwgMCksIFwiK3N3YXBMaW5lXCIpO1xuICAgICAgICBpZiAodG8gPiBjbS5sYXN0TGluZSgpKVxuICAgICAgICAgIGNtLnJlcGxhY2VSYW5nZShcIlxcblwiICsgbGluZSwgUG9zKGNtLmxhc3RMaW5lKCkpLCBudWxsLCBcIitzd2FwTGluZVwiKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGNtLnJlcGxhY2VSYW5nZShsaW5lICsgXCJcXG5cIiwgUG9zKHRvLCAwKSwgbnVsbCwgXCIrc3dhcExpbmVcIik7XG4gICAgICB9XG4gICAgICBjbS5zZXRTZWxlY3Rpb25zKG5ld1NlbHMpO1xuICAgICAgY20uc2Nyb2xsSW50b1ZpZXcoKTtcbiAgICB9KTtcbiAgfTtcblxuICBjbWRzW21hcFtzd2FwTGluZUNvbWJvICsgXCJEb3duXCJdID0gXCJzd2FwTGluZURvd25cIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIHZhciByYW5nZXMgPSBjbS5saXN0U2VsZWN0aW9ucygpLCBsaW5lc1RvTW92ZSA9IFtdLCBhdCA9IGNtLmxhc3RMaW5lKCkgKyAxO1xuICAgIGZvciAodmFyIGkgPSByYW5nZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciByYW5nZSA9IHJhbmdlc1tpXSwgZnJvbSA9IHJhbmdlLnRvKCkubGluZSArIDEsIHRvID0gcmFuZ2UuZnJvbSgpLmxpbmU7XG4gICAgICBpZiAocmFuZ2UudG8oKS5jaCA9PSAwICYmICFyYW5nZS5lbXB0eSgpKSBmcm9tLS07XG4gICAgICBpZiAoZnJvbSA8IGF0KSBsaW5lc1RvTW92ZS5wdXNoKGZyb20sIHRvKTtcbiAgICAgIGVsc2UgaWYgKGxpbmVzVG9Nb3ZlLmxlbmd0aCkgbGluZXNUb01vdmVbbGluZXNUb01vdmUubGVuZ3RoIC0gMV0gPSB0bztcbiAgICAgIGF0ID0gdG87XG4gICAgfVxuICAgIGNtLm9wZXJhdGlvbihmdW5jdGlvbigpIHtcbiAgICAgIGZvciAodmFyIGkgPSBsaW5lc1RvTW92ZS5sZW5ndGggLSAyOyBpID49IDA7IGkgLT0gMikge1xuICAgICAgICB2Y
23459XIgZnJvbSA9IGxpbmVzVG9Nb3ZlW2ldLCB0byA9IGxpbmVzVG9Nb3ZlW2kgKyAxXTtcbiAgICAgICAgdmFyIGxpbmUgPSBjbS5nZXRMaW5lKGZyb20pO1xuICAgICAgICBpZiAoZnJvbSA9PSBjbS5sYXN0TGluZSgpKVxuICAgICAgICAgIGNtLnJlcGxhY2VSYW5nZShcIlwiLCBQb3MoZnJvbSAtIDEpLCBQb3MoZnJvbSksIFwiK3N3YXBMaW5lXCIpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgY20ucmVwbGFjZVJhbmdlKFwiXCIsIFBvcyhmcm9tLCAwKSwgUG9zKGZyb20gKyAxLCAwKSwgXCIrc3dhcExpbmVcIik7XG4gICAgICAgIGNtLnJlcGxhY2VSYW5nZShsaW5lICsgXCJcXG5cIiwgUG9zKHRvLCAwKSwgbnVsbCwgXCIrc3dhcExpbmVcIik7XG4gICAgICB9XG4gICAgICBjbS5zY3JvbGxJbnRvVmlldygpO1xuICAgIH0pO1xuICB9O1xuXG4gIG1hcFtjdHJsICsgXCIvXCJdID0gZnVuY3Rpb24oY20pIHtcbiAgICBjbS50b2dnbGVDb21tZW50KHsgaW5kZW50OiB0cnVlIH0pO1xuICB9XG5cbiAgY21kc1ttYXBbY3RybCArIFwiSlwiXSA9IFwiam9pbkxpbmVzXCJdID0gZnVuY3Rpb24oY20pIHtcbiAgICB2YXIgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKSwgam9pbmVkID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciByYW5nZSA9IHJhbmdlc1tpXSwgZnJvbSA9IHJhbmdlLmZyb20oKTtcbiAgICAgIHZhciBzdGFydCA9IGZyb20ubGluZSwgZW5kID0gcmFuZ2UudG8oKS5saW5lO1xuICAgICAgd2hpbGUgKGkgPCByYW5nZXMubGVuZ3RoIC0gMSAmJiByYW5nZXNbaSArIDFdLmZyb20oKS5saW5lID09IGVuZClcbiAgICAgICAgZW5kID0gcmFuZ2VzWysraV0udG8oKS5saW5lO1xuICAgICAgam9pbmVkLnB1c2goe3N0YXJ0OiBzdGFydCwgZW5kOiBlbmQsIGFuY2hvcjogIXJhbmdlLmVtcHR5KCkgJiYgZnJvbX0pO1xuICAgIH1cbiAgICBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICB2Y
23459XIgb2Zmc2V0ID0gMCwgcmFuZ2VzID0gW107XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGpvaW5lZC5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgb2JqID0gam9pbmVkW2ldO1xuICAgICAgICB2YXIgYW5jaG9yID0gb2JqLmFuY2hvciAmJiBQb3Mob2JqLmFuY2hvci5saW5lIC0gb2Zmc2V0LCBvYmouYW5jaG9yLmNoKSwgaGVhZDtcbiAgICAgICAgZm9yICh2YXIgbGluZSA9IG9iai5zdGFydDsgbGluZSA8PSBvYmouZW5kOyBsaW5lKyspIHtcbiAgICAgICAgICB2YXIgYWN0dWFsID0gbGluZSAtIG9mZnNldDtcbiAgICAgICAgICBpZiAobGluZSA9PSBvYmouZW5kKSBoZWFkID0gUG9zKGFjdHVhbCwgY20uZ2V0TGluZShhY3R1YWwpLmxlbmd0aCArIDEpO1xuICAgICAgICAgIGlmIChhY3R1YWwgPCBjbS5sYXN0TGluZSgpKSB7XG4gICAgICAgICAgICBjbS5yZXBsYWNlUmFuZ2UoXCIgXCIsIFBvcyhhY3R1YWwpLCBQb3MoYWN0dWFsICsgMSwgL15cXHMqLy5leGVjKGNtLmdldExpbmUoYWN0dWFsICsgMSkpWzBdLmxlbmd0aCkpO1xuICAgICAgICAgICAgKytvZmZzZXQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJhbmdlcy5wdXNoKHthbmNob3I6IGFuY2hvciB8fCBoZWFkLCBoZWFkOiBoZWFkfSk7XG4gICAgICB9XG4gICAgICBjbS5zZXRTZWxlY3Rpb25zKHJhbmdlcywgMCk7XG4gICAgfSk7XG4gIH07XG5cbiAgY21kc1ttYXBbXCJTaGlmdC1cIiArIGN0cmwgKyBcIkRcIl0gPSBcImR1cGxpY2F0ZUxpbmVcIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIGNtLm9wZXJhdGlvbihmdW5jdGlvbigpIHtcbiAgICAgIHZhciByYW5nZUNvdW50ID0gY20ubGlzdFNlbGVjdGlvbnMoKS5sZW5ndGg7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlQ291bnQ7IGkrKykge1xuICAgICAgICB2Y
23459XIgcmFuZ2UgPSBjbS5saXN0U2VsZWN0aW9ucygpW2ldO1xuICAgICAgICBpZiAocmFuZ2UuZW1wdHkoKSlcbiAgICAgICAgICBjbS5yZXBsYWNlUmFuZ2UoY20uZ2V0TGluZShyYW5nZS5oZWFkLmxpbmUpICsgXCJcXG5cIiwgUG9zKHJhbmdlLmhlYWQubGluZSwgMCkpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgY20ucmVwbGFjZVJhbmdlKGNtLmdldFJhbmdlKHJhbmdlLmZyb20oKSwgcmFuZ2UudG8oKSksIHJhbmdlLmZyb20oKSk7XG4gICAgICB9XG4gICAgICBjbS5zY3JvbGxJbnRvVmlldygpO1xuICAgIH0pO1xuICB9O1xuXG4gIG1hcFtjdHJsICsgXCJUXCJdID0gXCJ0cmFuc3Bvc2VDaGFyc1wiO1xuXG4gIGZ1bmN0aW9uIHNvcnRMaW5lcyhjbSwgY2FzZVNlbnNpdGl2ZSkge1xuICAgIHZhciByYW5nZXMgPSBjbS5saXN0U2VsZWN0aW9ucygpLCB0b1NvcnQgPSBbXSwgc2VsZWN0ZWQ7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCByYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciByYW5nZSA9IHJhbmdlc1tpXTtcbiAgICAgIGlmIChyYW5nZS5lbXB0eSgpKSBjb250aW51ZTtcbiAgICAgIHZhciBmcm9tID0gcmFuZ2UuZnJvbSgpLmxpbmUsIHRvID0gcmFuZ2UudG8oKS5saW5lO1xuICAgICAgd2hpbGUgKGkgPCByYW5nZXMubGVuZ3RoIC0gMSAmJiByYW5nZXNbaSArIDFdLmZyb20oKS5saW5lID09IHRvKVxuICAgICAgICB0byA9IHJhbmdlWysraV0udG8oKS5saW5lO1xuICAgICAgdG9Tb3J0LnB1c2goZnJvbSwgdG8pO1xuICAgIH1cbiAgICBpZiAodG9Tb3J0Lmxlbmd0aCkgc2VsZWN0ZWQgPSB0cnVlO1xuICAgIGVsc2UgdG9Tb3J0LnB1c2goY20uZmlyc3RMaW5lKCksIGNtLmxhc3RMaW5lKCkpO1xuXG4gICAgY20ub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJhbmdlcyA9IFtdO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0b1NvcnQubGVuZ3RoOyBpICs9IDIpIHtcbiAgICAgICAgdmFyIGZyb20gPSB0b1NvcnRbaV0sIHRvID0gdG9Tb3J0W2kgKyAxXTtcbiAgICAgICAgdmFyIHN0YXJ0ID0gUG9zKGZyb20sIDApLCBlbmQgPSBQb3ModG8pO1xuICAgICAgICB2Y
23459XIgbGluZXMgPSBjbS5nZXRSYW5nZShzdGFydCwgZW5kLCBmYWxzZSk7XG4gICAgICAgIGlmIChjYXNlU2Vuc2l0aXZlKVxuICAgICAgICAgIGxpbmVzLnNvcnQoKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGxpbmVzLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgICAgICAgdmFyIGF1ID0gYS50b1VwcGVyQ2FzZSgpLCBidSA9IGIudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgIGlmIChhdSAhPSBidSkgeyBhID0gYXU7IGIgPSBidTsgfVxuICAgICAgICAgICAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID09IGIgPyAwIDogMTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgY20ucmVwbGFjZVJhbmdlKGxpbmVzLCBzdGFydCwgZW5kKTtcbiAgICAgICAgaWYgKHNlbGVjdGVkKSByYW5nZXMucHVzaCh7YW5jaG9yOiBzdGFydCwgaGVhZDogZW5kfSk7XG4gICAgICB9XG4gICAgICBpZiAoc2VsZWN0ZWQpIGNtLnNldFNlbGVjdGlvbnMocmFuZ2VzLCAwKTtcbiAgICB9KTtcbiAgfVxuXG4gIGNtZHNbbWFwW1wiRjlcIl0gPSBcInNvcnRMaW5lc1wiXSA9IGZ1bmN0aW9uKGNtKSB7IHNvcnRMaW5lcyhjbSwgdHJ1ZSk7IH07XG4gIGNtZHNbbWFwW2N0cmwgKyBcIkY5XCJdID0gXCJzb3J0TGluZXNJbnNlbnNpdGl2ZVwiXSA9IGZ1bmN0aW9uKGNtKSB7IHNvcnRMaW5lcyhjbSwgZmFsc2UpOyB9O1xuXG4gIGNtZHNbbWFwW1wiRjJcIl0gPSBcIm5leHRCb29rbWFya1wiXSA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgdmFyIG1hcmtzID0gY20uc3RhdGUuc3VibGltZUJvb2ttYXJrcztcbiAgICBpZiAobWFya3MpIHdoaWxlIChtYXJrcy5sZW5ndGgpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gbWFya3Muc2hpZnQoKTtcbiAgICAgIHZhciBmb3VuZCA9IGN1cnJlbnQuZmluZCgpO1xuICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgIG1hcmtzLnB1c2goY3VycmVudCk7XG4gICAgICAgIHJldHVybiBjbS5zZXRTZWxlY3Rpb24oZm91bmQuZnJvbSwgZm91bmQudG8pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBjbWRzW21hcFtcIlNoaWZ0LUYyXCJdID0gXCJwcmV2Qm9va21hcmtcIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIHZhciBtYXJrcyA9IGNtLnN0YXRlLnN1YmxpbWVCb29rbWFya3M7XG4gICAgaWYgKG1hcmtzKSB3aGlsZSAobWFya3MubGVuZ3RoKSB7XG4gICAgICBtYXJrcy51bnNoaWZ0KG1hcmtzLnBvcCgpKTtcbiAgICAgIHZhciBmb3VuZCA9IG1hcmtzW21hcmtzLmxlbmd0aCAtIDFdLmZpbmQoKTtcbiAgICAgIGlmICghZm91bmQpXG4gICAgICAgIG1hcmtzLnBvcCgpO1xuICAgICAgZWxzZVxuICAgICAgICByZXR1cm4gY20uc2V0U2VsZWN0aW9uKGZvdW5kLmZyb20sIGZvdW5kLnRvKTtcbiAgICB9XG4gIH07XG5cbiAgY21kc1ttYXBbY3RybCArIFwiRjJcIl0gPSBcInRvZ2dsZUJvb2ttYXJrXCJdID0gZnVuY3Rpb24oY20pIHtcbiAgICB2YXIgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKTtcbiAgICB2YXIgbWFya3MgPSBjbS5zdGF0ZS5zdWJsaW1lQm9va21hcmtzIHx8IChjbS5zdGF0ZS5zdWJsaW1lQm9va21hcmtzID0gW10pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2Y
23459XIgZnJvbSA9IHJhbmdlc1tpXS5mcm9tKCksIHRvID0gcmFuZ2VzW2ldLnRvKCk7XG4gICAgICB2YXIgZm91bmQgPSBjbS5maW5kTWFya3MoZnJvbSwgdG8pO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBmb3VuZC5sZW5ndGg7IGorKykge1xuICAgICAgICBpZiAoZm91bmRbal0uc3VibGltZUJvb2ttYXJrKSB7XG4gICAgICAgICAgZm91bmRbal0uY2xlYXIoKTtcbiAgICAgICAgICBmb3IgKHZhciBrID0gMDsgayA8IG1hcmtzLmxlbmd0aDsgaysrKVxuICAgICAgICAgICAgaWYgKG1hcmtzW2tdID09IGZvdW5kW2pdKVxuICAgICAgICAgICAgICBtYXJrcy5zcGxpY2Uoay0tLCAxKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGogPT0gZm91bmQubGVuZ3RoKVxuICAgICAgICBtYXJrcy5wdXNoKGNtLm1hcmtUZXh0KGZyb20sIHRvLCB7c3VibGltZUJvb2ttYXJrOiB0cnVlLCBjbGVhcldoZW5FbXB0eTogZmFsc2V9KSk7XG4gICAgfVxuICB9O1xuXG4gIGNtZHNbbWFwW1wiU2hpZnQtXCIgKyBjdHJsICsgXCJGMlwiXSA9IFwiY2xlYXJCb29rbWFya3NcIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIHZhciBtYXJrcyA9IGNtLnN0YXRlLnN1YmxpbWVCb29rbWFya3M7XG4gICAgaWYgKG1hcmtzKSBmb3IgKHZhciBpID0gMDsgaSA8IG1hcmtzLmxlbmd0aDsgaSsrKSBtYXJrc1tpXS5jbGVhcigpO1xuICAgIG1hcmtzLmxlbmd0aCA9IDA7XG4gIH07XG5cbiAgY21kc1ttYXBbXCJBbHQtRjJcIl0gPSBcInNlbGVjdEJvb2ttYXJrc1wiXSA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgdmFyIG1hcmtzID0gY20uc3RhdGUuc3VibGltZUJvb2ttYXJrcywgcmFuZ2VzID0gW107XG4gICAgaWYgKG1hcmtzKSBmb3IgKHZhciBpID0gMDsgaSA8IG1hcmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2Y
23459XIgZm91bmQgPSBtYXJrc1tpXS5maW5kKCk7XG4gICAgICBpZiAoIWZvdW5kKVxuICAgICAgICBtYXJrcy5zcGxpY2UoaS0tLCAwKTtcbiAgICAgIGVsc2VcbiAgICAgICAgcmFuZ2VzLnB1c2goe2FuY2hvcjogZm91bmQuZnJvbSwgaGVhZDogZm91bmQudG99KTtcbiAgICB9XG4gICAgaWYgKHJhbmdlcy5sZW5ndGgpXG4gICAgICBjbS5zZXRTZWxlY3Rpb25zKHJhbmdlcywgMCk7XG4gIH07XG5cbiAgbWFwW1wiQWx0LVFcIl0gPSBcIndyYXBMaW5lc1wiO1xuXG4gIHZhciBjSyA9IGN0cmwgKyBcIksgXCI7XG5cbiAgZnVuY3Rpb24gbW9kaWZ5V29yZE9yU2VsZWN0aW9uKGNtLCBtb2QpIHtcbiAgICBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKSwgaW5kaWNlcyA9IFtdLCByZXBsYWNlbWVudHMgPSBbXTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciByYW5nZSA9IHJhbmdlc1tpXTtcbiAgICAgICAgaWYgKHJhbmdlLmVtcHR5KCkpIHsgaW5kaWNlcy5wdXNoKGkpOyByZXBsYWNlbWVudHMucHVzaChcIlwiKTsgfVxuICAgICAgICBlbHNlIHJlcGxhY2VtZW50cy5wdXNoKG1vZChjbS5nZXRSYW5nZShyYW5nZS5mcm9tKCksIHJhbmdlLnRvKCkpKSk7XG4gICAgICB9XG4gICAgICBjbS5yZXBsYWNlU2VsZWN0aW9ucyhyZXBsYWNlbWVudHMsIFwiYXJvdW5kXCIsIFwiY2FzZVwiKTtcbiAgICAgIGZvciAodmFyIGkgPSBpbmRpY2VzLmxlbmd0aCAtIDEsIGF0OyBpID49IDA7IGktLSkge1xuICAgICAgICB2Y
23459XIgcmFuZ2UgPSByYW5nZXNbaW5kaWNlc1tpXV07XG4gICAgICAgIGlmIChhdCAmJiBDb2RlTWlycm9yLmNtcFBvcyhyYW5nZS5oZWFkLCBhdCkgPiAwKSBjb250aW51ZTtcbiAgICAgICAgdmFyIHdvcmQgPSB3b3JkQXQoY20sIHJhbmdlLmhlYWQpO1xuICAgICAgICBhdCA9IHdvcmQuZnJvbTtcbiAgICAgICAgY20ucmVwbGFjZVJhbmdlKG1vZCh3b3JkLndvcmQpLCB3b3JkLmZyb20sIHdvcmQudG8pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgbWFwW2NLICsgY3RybCArIFwiQmFja3NwYWNlXCJdID0gXCJkZWxMaW5lTGVmdFwiO1xuXG4gIGNtZHNbbWFwW1wiQmFja3NwYWNlXCJdID0gXCJzbWFydEJhY2tzcGFjZVwiXSA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgaWYgKGNtLnNvbWV0aGluZ1NlbGVjdGVkKCkpIHJldHVybiBDb2RlTWlycm9yLlBhc3M7XG5cbiAgICB2YXIgY3Vyc29yID0gY20uZ2V0Q3Vyc29yKCk7XG4gICAgdmFyIHRvU3RhcnRPZkxpbmUgPSBjbS5nZXRSYW5nZSh7bGluZTogY3Vyc29yLmxpbmUsIGNoOiAwfSwgY3Vyc29yKTtcbiAgICB2YXIgY29sdW1uID0gQ29kZU1pcnJvci5jb3VudENvbHVtbih0b1N0YXJ0T2ZMaW5lLCBudWxsLCBjbS5nZXRPcHRpb24oXCJ0YWJTaXplXCIpKTtcbiAgICB2YXIgaW5kZW50VW5pdCA9IGNtLmdldE9wdGlvbihcImluZGVudFVuaXRcIik7XG5cbiAgICBpZiAodG9TdGFydE9mTGluZSAmJiAhL1xcUy8udGVzdCh0b1N0YXJ0T2ZMaW5lKSAmJiBjb2x1bW4gJSBpbmRlbnRVbml0ID09IDApIHtcbiAgICAgIHZhciBwcmV2SW5kZW50ID0gbmV3IFBvcyhjdXJzb3IubGluZSxcbiAgICAgICAgQ29kZU1pcnJvci5maW5kQ29sdW1uKHRvU3RhcnRPZkxpbmUsIGNvbHVtbiAtIGluZGVudFVuaXQsIGluZGVudFVuaXQpKTtcblxuICAgICAgLy8gSWYgbm8gc21hcnQgZGVsZXRlIGlzIGhhcHBlbmluZyAoZHVlIHRvIHRhYiBzaXppbmcpIGp1c3QgZG8gYSByZWd1bGFyIGRlbGV0ZVxuICAgICAgaWYgKHByZXZJbmRlbnQuY2ggPT0gY3Vyc29yLmNoKSByZXR1cm4gQ29kZU1pcnJvci5QYXNzO1xuXG4gICAgICByZXR1cm4gY20ucmVwbGFjZVJhbmdlKFwiXCIsIHByZXZJbmRlbnQsIGN1cnNvciwgXCIrZGVsZXRlXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gQ29kZU1pcnJvci5QYXNzO1xuICAgIH1cbiAgfTtcblxuICBjbWRzW21hcFtjSyArIGN0cmwgKyBcIktcIl0gPSBcImRlbExpbmVSaWdodFwiXSA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgY20ub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJhbmdlcyA9IGNtLmxpc3RTZWxlY3Rpb25zKCk7XG4gICAgICBmb3IgKHZhciBpID0gcmFuZ2VzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKVxuICAgICAgICBjbS5yZXBsYWNlUmFuZ2UoXCJcIiwgcmFuZ2VzW2ldLmFuY2hvciwgUG9zKHJhbmdlc1tpXS50bygpLmxpbmUpLCBcIitkZWxldGVcIik7XG4gICAgICBjbS5zY3JvbGxJbnRvVmlldygpO1xuICAgIH0pO1xuICB9O1xuXG4gIGNtZHNbbWFwW2NLICsgY3RybCArIFwiVVwiXSA9IFwidXBjYXNlQXRDdXJzb3JcIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIG1vZGlmeVdvcmRPclNlbGVjdGlvbihjbSwgZnVuY3Rpb24oc3RyKSB7IHJldHVybiBzdHIudG9VcHBlckNhc2UoKTsgfSk7XG4gIH07XG4gIGNtZHNbbWFwW2NLICsgY3RybCArIFwiTFwiXSA9IFwiZG93bmNhc2VBdEN1cnNvclwiXSA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgbW9kaWZ5V29yZE9yU2VsZWN0aW9uKGNtLCBmdW5jdGlvbihzdHIpIHsgcmV0dXJuIHN0ci50b0xvd2VyQ2FzZSgpOyB9KTtcbiAgfTtcblxuICBjbWRzW21hcFtjSyArIGN0cmwgKyBcIlNwYWNlXCJdID0gXCJzZXRTdWJsaW1lTWFya1wiXSA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgaWYgKGNtLnN0YXRlLnN1YmxpbWVNYXJrKSBjbS5zdGF0ZS5zdWJsaW1lTWFyay5jbGVhcigpO1xuICAgIGNtLnN0YXRlLnN1YmxpbWVNYXJrID0gY20uc2V0Qm9va21hcmsoY20uZ2V0Q3Vyc29yKCkpO1xuICB9O1xuICBjbWRzW21hcFtjSyArIGN0cmwgKyBcIkFcIl0gPSBcInNlbGVjdFRvU3VibGltZU1hcmtcIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIHZhciBmb3VuZCA9IGNtLnN0YXRlLnN1YmxpbWVNYXJrICYmIGNtLnN0YXRlLnN1YmxpbWVNYXJrLmZpbmQoKTtcbiAgICBpZiAoZm91bmQpIGNtLnNldFNlbGVjdGlvbihjbS5nZXRDdXJzb3IoKSwgZm91bmQpO1xuICB9O1xuICBjbWRzW21hcFtjSyArIGN0cmwgKyBcIldcIl0gPSBcImRlbGV0ZVRvU3VibGltZU1hcmtcIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIHZhciBmb3VuZCA9IGNtLnN0YXRlLnN1YmxpbWVNYXJrICYmIGNtLnN0YXRlLnN1YmxpbWVNYXJrLmZpbmQoKTtcbiAgICBpZiAoZm91bmQpIHtcbiAgICAgIHZhciBmcm9tID0gY20uZ2V0Q3Vyc29yKCksIHRvID0gZm91bmQ7XG4gICAgICBpZiAoQ29kZU1pcnJvci5jbXBQb3MoZnJvbSwgdG8pID4gMCkgeyB2YXIgdG1wID0gdG87IHRvID0gZnJvbTsgZnJvbSA9IHRtcDsgfVxuICAgICAgY20uc3RhdGUuc3VibGltZUtpbGxlZCA9IGNtLmdldFJhbmdlKGZyb20sIHRvKTtcbiAgICAgIGNtLnJlcGxhY2VSYW5nZShcIlwiLCBmcm9tLCB0byk7XG4gICAgfVxuICB9O1xuICBjbWRzW21hcFtjSyArIGN0cmwgKyBcIlhcIl0gPSBcInN3YXBXaXRoU3VibGltZU1hcmtcIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIHZhciBmb3VuZCA9IGNtLnN0YXRlLnN1YmxpbWVNYXJrICYmIGNtLnN0YXRlLnN1YmxpbWVNYXJrLmZpbmQoKTtcbiAgICBpZiAoZm91bmQpIHtcbiAgICAgIGNtLnN0YXRlLnN1YmxpbWVNYXJrLmNsZWFyKCk7XG4gICAgICBjbS5zdGF0ZS5zdWJsaW1lTWFyayA9IGNtLnNldEJvb2ttYXJrKGNtLmdldEN1cnNvcigpKTtcbiAgICAgIGNtLnNldEN1cnNvcihmb3VuZCk7XG4gICAgfVxuICB9O1xuICBjbWRzW21hcFtjSyArIGN0cmwgKyBcIllcIl0gPSBcInN1YmxpbWVZYW5rXCJdID0gZnVuY3Rpb24oY20pIHtcbiAgICBpZiAoY20uc3RhdGUuc3VibGltZUtpbGxlZCAhPSBudWxsKVxuICAgICAgY20ucmVwbGFjZVNlbGVjdGlvbihjbS5zdGF0ZS5zdWJsaW1lS2lsbGVkLCBudWxsLCBcInBhc3RlXCIpO1xuICB9O1xuXG4gIG1hcFtjSyArIGN0cmwgKyBcIkdcIl0gPSBcImNsZWFyQm9va21hcmtzXCI7XG4gIGNtZ
23459HNbbWFwW2NLICsgY3RybCArIFwiQ1wiXSA9IFwic2hvd0luQ2VudGVyXCJdID0gZnVuY3Rpb24oY20pIHtcbiAgICB2YXIgcG9zID0gY20uY3Vyc29yQ29vcmRzKG51bGwsIFwibG9jYWxcIik7XG4gICAgY20uc2Nyb2xsVG8obnVsbCwgKHBvcy50b3AgKyBwb3MuYm90dG9tKSAvIDIgLSBjbS5nZXRTY3JvbGxJbmZvKCkuY2xpZW50SGVpZ2h0IC8gMik7XG4gIH07XG5cbiAgY21kc1ttYXBbXCJTaGlmdC1BbHQtVXBcIl0gPSBcInNlbGVjdExpbmVzVXB3YXJkXCJdID0gZnVuY3Rpb24oY20pIHtcbiAgICBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciByYW5nZSA9IHJhbmdlc1tpXTtcbiAgICAgICAgaWYgKHJhbmdlLmhlYWQubGluZSA+IGNtLmZpcnN0TGluZSgpKVxuICAgICAgICAgIGNtLmFkZFNlbGVjdGlvbihQb3MocmFuZ2UuaGVhZC5saW5lIC0gMSwgcmFuZ2UuaGVhZC5jaCkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuICBjbWRzW21hcFtcIlNoaWZ0LUFsdC1Eb3duXCJdID0gXCJzZWxlY3RMaW5lc0Rvd253YXJkXCJdID0gZnVuY3Rpb24oY20pIHtcbiAgICBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciByYW5nZSA9IHJhbmdlc1tpXTtcbiAgICAgICAgaWYgKHJhbmdlLmhlYWQubGluZSA8IGNtLmxhc3RMaW5lKCkpXG4gICAgICAgICAgY20uYWRkU2VsZWN0aW9uKFBvcyhyYW5nZS5oZWFkLmxpbmUgKyAxLCByYW5nZS5oZWFkLmNoKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gZ2V0VGFyZ2V0KGNtKSB7XG4gICAgdmFyIGZyb20gPSBjbS5nZXRDdXJzb3IoXCJmcm9tXCIpLCB0byA9IGNtLmdldEN1cnNvcihcInRvXCIpO1xuICAgIGlmIChDb2RlTWlycm9yLmNtcFBvcyhmcm9tLCB0bykgPT0gMCkge1xuICAgICAgdmFyIHdvcmQgPSB3b3JkQXQoY20sIGZyb20pO1xuICAgICAgaWYgKCF3b3JkLndvcmQpIHJldHVybjtcbiAgICAgIGZyb20gPSB3b3JkLmZyb207XG4gICAgICB0byA9IHdvcmQudG87XG4gICAgfVxuICAgIHJldHVybiB7ZnJvbTogZnJvbSwgdG86IHRvLCBxdWVyeTogY20uZ2V0UmFuZ2UoZnJvbSwgdG8pLCB3b3JkOiB3b3JkfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbmRBbmRHb1RvKGNtLCBmb3J3YXJkKSB7XG4gICAgdmFyIHRhcmdldCA9IGdldFRhcmdldChjbSk7XG4gICAgaWYgKCF0YXJnZXQpIHJldHVybjtcbiAgICB2YXIgcXVlcnkgPSB0YXJnZXQucXVlcnk7XG4gICAgdmFyIGN1ciA9IGNtLmdldFNlYXJjaEN1cnNvcihxdWVyeSwgZm9yd2FyZCA/IHRhcmdldC50byA6IHRhcmdldC5mcm9tKTtcblxuICAgIGlmIChmb3J3YXJkID8gY3VyLmZpbmROZXh0KCkgOiBjdXIuZmluZFByZXZpb3VzKCkpIHtcbiAgICAgIGNtLnNldFNlbGVjdGlvbihjdXIuZnJvbSgpLCBjdXIudG8oKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1ciA9IGNtLmdldFNlYXJjaEN1cnNvcihxdWVyeSwgZm9yd2FyZCA/IFBvcyhjbS5maXJzdExpbmUoKSwgMClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGNtLmNsaXBQb3MoUG9zKGNtLmxhc3RMaW5lKCkpKSk7XG4gICAgICBpZiAoZm9yd2FyZCA/IGN1ci5maW5kTmV4dCgpIDogY3VyLmZpbmRQcmV2aW91cygpKVxuICAgICAgICBjbS5zZXRTZWxlY3Rpb24oY3VyLmZyb20oKSwgY3VyLnRvKCkpO1xuICAgICAgZWxzZSBpZiAodGFyZ2V0LndvcmQpXG4gICAgICAgIGNtLnNldFNlbGVjdGlvbih0YXJnZXQuZnJvbSwgdGFyZ2V0LnRvKTtcbiAgICB9XG4gIH07XG4gIGNtZHNbbWFwW2N0cmwgKyBcIkYzXCJdID0gXCJmaW5kVW5kZXJcIl0gPSBmdW5jdGlvbihjbSkgeyBmaW5kQW5kR29UbyhjbSwgdHJ1ZSk7IH07XG4gIGNtZHNbbWFwW1wiU2hpZnQtXCIgKyBjdHJsICsgXCJGM1wiXSA9IFwiZmluZFVuZGVyUHJldmlvdXNcIl0gPSBmdW5jdGlvbihjbSkgeyBmaW5kQW5kR29UbyhjbSxmYWxzZSk7IH07XG4gIGNtZHNbbWFwW1wiQWx0LUYzXCJdID0gXCJmaW5kQWxsVW5kZXJcIl0gPSBmdW5jdGlvbihjbSkge1xuICAgIHZhciB0YXJnZXQgPSBnZXRUYXJnZXQoY20pO1xuICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG4gICAgdmFyIGN1ciA9IGNtLmdldFNlYXJjaEN1cnNvcih0YXJnZXQucXVlcnkpO1xuICAgIHZhciBtYXRjaGVzID0gW107XG4gICAgdmFyIHByaW1hcnlJbmRleCA9IC0xO1xuICAgIHdoaWxlIChjdXIuZmluZE5leHQoKSkge1xuICAgICAgbWF0Y2hlcy5wdXNoKHthbmNob3I6IGN1ci5mcm9tKCksIGhlYWQ6IGN1ci50bygpfSk7XG4gICAgICBpZiAoY3VyLmZyb20oKS5saW5lIDw9IHRhcmdldC5mcm9tLmxpbmUgJiYgY3VyLmZyb20oKS5jaCA8PSB0YXJnZXQuZnJvbS5jaClcbiAgICAgICAgcHJpbWFyeUluZGV4Kys7XG4gICAgfVxuICAgIGNtLnNldFNlbGVjdGlvbnMobWF0Y2hlcywgcHJpbWFyeUluZGV4KTtcbiAgfTtcblxuICBtYXBbXCJTaGlmdC1cIiArIGN0cmwgKyBcIltc
23459Il0gPSBcImZvbGRcIjtcbiAgbWFwW1wiU2hpZnQtXCIgKyBjdHJsICsgXCJdXCJdID0gXCJ1bmZvbGRcIjtcbiAgbWFwW2NLICsgY3RybCArIFwiMFwiXSA9IG1hcFtjSyArIGN0cmwgKyBcImpcIl0gPSBcInVuZm9sZEFsbFwiO1xuXG4gIG1hcFtjdHJsICsgXCJJXCJdID0gXCJmaW5kSW5jcmVtZW50YWxcIjtcbiAgbWFwW1wiU2hpZnQtXCIgKyBjdHJsICsgXCJJXCJdID0gXCJmaW5kSW5jcmVtZW50YWxSZXZlcnNlXCI7XG4gIG1hcFtjdHJsICsgXCJIXCJdID0gXCJyZXBsYWNlXCI7XG4gIG1hcFtcIkYzXCJdID0gXCJmaW5kTmV4dFwiO1xuICBtYXBbXCJTaGlmdC1GM1wiXSA9IFwiZmluZFByZXZcIjtcblxuICBDb2RlTWlycm9yLm5vcm1hbGl6ZUtleU1hcChtYXApO1xufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbi8vIFRoaXMgaXMgQ29kZU1pcnJvciAoaHR0cDovL2NvZGVtaXJyb3IubmV0KSwgYSBjb2RlIGVkaXRvclxuLy8gaW1wbGVtZW50ZWQgaW4gSmF2YVNjcmlwdCBvbiB0b3Agb2YgdGhlIGJyb3dzZXIncyBET00uXG4vL1xuLy8gWW91IGNhbiBmaW5kIHNvbWUgdGVjaG5pY2FsIGJhY2tncm91bmQgZm9yIHNvbWUgb2YgdGhlIGNvZGUgYmVsb3dcbi8vIGF0IGh0dHA6Ly9tYXJpam5oYXZlcmJla2UubmwvYmxvZy8jY20taW50ZXJuYWxzIC5cblxuKGZ1bmN0aW9uKG1vZCkge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlID09IFwib2JqZWN0XCIpIC8vIENvbW1vbkpTXG4gICAgbW9kdWxlLmV4cG9ydHMgPSBtb2QoKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgcmV0dXJuIGRlZmluZShbXSwgbW9kKTtcbiAgZWxzZSAvLyBQbGFpbiBicm93c2VyIGVudlxuICAgIHRoaXMuQ29kZU1pcnJvciA9IG1vZCgpO1xufSkoZnVuY3Rpb24oKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuXG4gIC8vIEJST1dTRVIgU05JRkZJTkdcblxuICAvLyBLbHVkZ2VzIGZvciBidWdzIGFuZCBiZWhhdmlvciBkaWZmZXJlbmNlcyB0aGF0IGNhbid0IGJlIGZlYXR1cmVcbiAgLy8gZGV0ZWN0ZWQgYXJlIGVuYWJsZWQgYmFzZWQgb24gdXNlckFnZW50IGV0YyBzbmlmZmluZy5cbiAgdmFyIHVzZXJBZ2VudCA9IG5hdmlnYXRvci51c2VyQWdlbnQ7XG4gIHZhciBwbGF0Zm9ybSA9IG5hdmlnYXRvci5wbGF0Zm9ybTtcblxuICB2YXIgZ2Vja28gPSAvZ2Vja29cXC9cXGQvaS50ZXN0KHVzZXJBZ2VudCk7XG4gIHZhciBpZV91cHRvMTAgPSAvTVNJRSBcXGQvLnRlc3QodXNlckFnZW50KTtcbiAgdmFyIGllXzExdXAgPSAvVHJpZGVudFxcLyg/Ols3LTldfFxcZHsyLH0pXFwuLipydjooXFxkKykvLmV4ZWModXNlckFnZW50KTtcbiAgdmFyIGllID0gaWVfdXB0bzEwIHx8IGllXzExdXA7XG4gIHZhciBpZV92ZXJzaW9uID0gaWUgJiYgKGllX3VwdG8xMCA/IGRvY3VtZW50LmRvY3VtZW50TW9kZSB8fCA2IDogaWVfMTF1cFsxXSk7XG4gIHZhciB3ZWJraXQgPSAvV2ViS2l0XFwvLy50ZXN0KHVzZXJBZ2VudCk7XG4gIHZhciBxdHdlYmtpdCA9IHdlYmtpdCAmJiAvUXRcXC9cXGQrXFwuXFxkKy8udGVzdCh1c2VyQWdlbnQpO1xuICB2YXIgY2hyb21lID0gL0Nocm9tZVxcLy8udGVzdCh1c2VyQWdlbnQpO1xuICB2YXIgcHJlc3RvID0gL09wZXJhXFwvLy50ZXN0KHVzZXJBZ2VudCk7XG4gIHZhciBzYWZhcmkgPSAvQXBwbGUgQ29tcHV0ZXIvLnRlc3QobmF2aWdhdG9yLnZlbmRvcik7XG4gIHZhciBtYWNfZ2VNb3VudGFpbkxpb24gPSAvTWFjIE9TIFggMVxcZFxcRChbOC05XXxcXGRcXGQpXFxELy50ZXN0KHVzZXJBZ2VudCk7XG4gIHZhciBwaGFudG9tID0gL1BoYW50b21KUy8udGVzdCh1c2VyQWdlbnQpO1xuXG4gIHZhciBpb3MgPSAvQXBwbGVXZWJLaXQvLnRlc3QodXNlckFnZW50KSAmJiAvTW9iaWxlXFwvXFx3Ky8udGVzdCh1c2VyQWdlbnQpO1xuICAvLyBUaGlzIGlzIHdvZWZ1bGx5IGluY29tcGxldGUuIFN1Z2dlc3Rpb25zIGZvciBhbHRlcm5hdGl2ZSBtZXRob2RzIHdlbGNvbWUuXG4gIHZhciBtb2JpbGUgPSBpb3MgfHwgL0FuZHJvaWR8d2ViT1N8QmxhY2tCZXJyeXxPcGVyYSBNaW5pfE9wZXJhIE1vYml8SUVNb2JpbGUvaS50ZXN0KHVzZXJBZ2VudCk7XG4gIHZhciBtYWMgPSBpb3MgfHwgL01hYy8udGVzdChwbGF0Zm9ybS
vendor: 19,395 bytes, line 23459
23459k7XG4gIHZhciB3aW5kb3dzID0gL3dpbi9pLnRlc3QocGxhdGZvcm0pO1xuXG4gIHZhciBwcmVzdG9fdmVyc2lvbiA9IHByZXN0byAmJiB1c2VyQWdlbnQubWF0Y2goL1ZlcnNpb25cXC8oXFxkKlxcLlxcZCopLyk7XG4gIGlmIChwcmVzdG9fdmVyc2lvbikgcHJlc3RvX3ZlcnNpb24gPSBOdW1iZXIocHJlc3RvX3ZlcnNpb25bMV0pO1xuICBpZiAocHJlc3RvX3ZlcnNpb24gJiYgcHJlc3RvX3ZlcnNpb24gPj0gMTUpIHsgcHJlc3RvID0gZmFsc2U7IHdlYmtpdCA9IHRydWU7IH1cbiAgLy8gU29tZSBicm93c2VycyB1c2UgdGhlIHdyb25nIGV2ZW50IHByb3BlcnRpZXMgdG8gc2lnbmFsIGNtZC9jdHJsIG9uIE9TIFhcbiAgdmFyIGZsaXBDdHJsQ21kID0gbWFjICYmIChxdHdlYmtpdCB8fCBwcmVzdG8gJiYgKHByZXN0b192ZXJzaW9uID09IG51bGwgfHwgcHJlc3RvX3ZlcnNpb24gPCAxMi4xMSkpO1xuICB2YXIgY2FwdHVyZVJpZ2h0Q2xpY2sgPSBnZWNrbyB8fCAoaWUgJiYgaWVfdmVyc2lvbiA+PSA5KTtcblxuICAvLyBPcHRpbWl6ZSBzb21lIGNvZGUgd2hlbiB0aGVzZSBmZWF0dXJlcyBhcmUgbm90IHVzZWQuXG4gIHZhciBzYXdSZWFkT25seVNwYW5zID0gZmFsc2UsIHNhd0NvbGxhcHNlZFNwYW5zID0gZmFsc2U7XG5cbiAgLy8gRURJVE9SIENPTlNUUlVDVE9SXG5cbiAgLy8gQSBDb2RlTWlycm9yIGluc3RhbmNlIHJlcHJlc2VudHMgYW4gZWRpdG9yLiBUaGlzIGlzIHRoZSBvYmplY3RcbiAgLy8gdGhhdCB1c2VyIGNvZGUgaXMgdXN1YWxseSBkZWFsaW5nIHdpdGguXG5cbiAgZnVuY3Rpb24gQ29kZU1pcnJvcihwbGFjZSwgb3B0aW9ucykge1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDb2RlTWlycm9yKSkgcmV0dXJuIG5ldyBDb2RlTWlycm9yKHBsYWNlLCBvcHRpb25zKTtcblxuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgPSBvcHRpb25zID8gY29weU9iaihvcHRpb25zKSA6IHt9O1xuICAgIC8vIERldGVybWluZSBlZmZlY3RpdmUgb3B0aW9ucyBiYXNlZCBvbiBnaXZlbiB2YWx1ZXMgYW5kIGRlZmF1bHRzLlxuICAgIGNvcHlPYmooZGVmYXVsdHMsIG9wdGlvbnMsIGZhbHNlKTtcbiAgICBzZXRHdXR0ZXJzRm9yTGluZU51bWJlcnMob3B0aW9ucyk7XG5cbiAgICB2YXIgZG9jID0gb3B0aW9ucy52YWx1ZTtcbiAgICBpZiAodHlwZW9mIGRvYyA9PSBcInN0cmluZ1wiKSBkb2MgPSBuZXcgRG9jKGRvYywgb3B0aW9ucy5tb2RlLCBudWxsLCBvcHRpb25zLmxpbmVTZXBhcmF0b3IpO1xuICAgIHRoaXMuZG9jID0gZG9jO1xuXG4gICAgdmFyIGlucHV0ID0gbmV3IENvZGVNaXJyb3IuaW5wdXRTdHlsZXNbb3B0aW9ucy5pbnB1dFN0eWxlXSh0aGlzKTtcbiAgICB2YXIgZGlzcGxheSA9IHRoaXMuZGlzcGxheSA9IG5ldyBEaXNwbGF5KHBsYWNlLCBkb2MsIGlucHV0KTtcbiAgICBkaXNwbGF5LndyYXBwZXIuQ29kZU1pcnJvciA9IHRoaXM7XG4gICAgdXBkYXRlR3V0dGVycyh0aGlzKTtcbiAgICB0aGVtZUNoYW5nZWQodGhpcyk7XG4gICAgaWYgKG9wdGlvbnMubGluZVdyYXBwaW5nKVxuICAgICAgdGhpcy5kaXNwbGF5LndyYXBwZXIuY2xhc3NOYW1lICs9IFwiIENvZGVNaXJyb3Itd3JhcFwiO1xuICAgIGlmIChvcHRpb25zLmF1dG9mb2N1cyAmJiAhbW9iaWxlKSBkaXNwbGF5LmlucHV0LmZvY3VzKCk7XG4gICAgaW5pdFNjcm9sbGJhcnModGhpcyk7XG5cbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAga2V5TWFwczogW10sICAvLyBzdG9yZXMgbWFwcyBhZGRlZCBieSBhZGRLZXlNYXBcbiAgICAgIG92ZXJsYXlzOiBbXSwgLy8gaGlnaGxpZ2h0aW5nIG92ZXJsYXlzLCBhcyBhZGRlZCBieSBhZGRPdmVybGF5XG4gICAgICBtb2RlR2VuOiAwLCAgIC8vIGJ1bXBlZCB3aGVuIG1vZGUvb3ZlcmxheSBjaGFuZ2VzLCB1c2VkIHRvIGludmFsaWRhdGUgaGlnaGxpZ2h0aW5nIGluZm9cbiAgICAgIG92ZXJ3cml0ZTogZmFsc2UsXG4gICAgICBkZWxheWluZ0JsdXJFdmVudDogZmFsc2UsXG4gICAgICBmb2N1c2VkOiBmYWxzZSxcbiAgICAgIHN1cHByZXNzRWRpdHM6IGZhbHNlLCAvLyB1c2VkIHRvIGRpc2FibGUgZWRpdGluZyBkdXJpbmcga2V5IGhhbmRsZXJzIHdoZW4gaW4gcmVhZE9ubHkgbW9kZVxuICAgICAgcGFzdGVJbmNvbWluZzogZmFsc2UsIGN1dEluY29taW5nOiBmYWxzZSwgLy8gaGVscCByZWNvZ25pemUgcGFzdGUvY3V0IGVkaXRzIGluIGlucHV0LnBvbGxcbiAgICAgIHNlbGVjdGluZ1RleHQ6IGZhbHNlLFxuICAgICAgZHJhZ2dpbmdUZXh0OiBmYWxzZSxcbiAgICAgIGhpZ2hsaWdodDogbmV3IERlbGF5ZWQoKSwgLy8gc3RvcmVzIGhpZ2hsaWdodCB3b3JrZXIgdGltZW91dFxuICAgICAga2V5U2VxOiBudWxsLCAgLy8gVW5maW5pc2hlZCBrZXkgc2VxdWVuY2VcbiAgICAgIHNwZWNpYWxDaGFyczogbnVsbFxuICAgIH07XG5cbiAgICB2YXIgY20gPSB0aGlzO1xuXG4gICAgLy8gT3ZlcnJpZGUgbWFnaWMgdGV4dGFyZWEgY29udGVudCByZXN0b3JlIHRoYXQgSUUgc29tZXRpbWVzIGRvZXNcbiAgICAvLyBvbiBvdXIgaGlkZGVuIHRleHRhcmVhIG9uIHJlbG9hZFxuICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uIDwgMTEpIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNtLmRpc3BsYXkuaW5wdXQucmVzZXQodHJ1ZSk7IH0sIDIwKTtcblxuICAgIHJlZ2lzdGVyRXZlbnRIYW5kbGVycyh0aGlzKTtcbiAgICBlbnN1cmVHbG9iYWxIYW5kbGVycygpO1xuXG4gICAgc3RhcnRPcGVyYXRpb24odGhpcyk7XG4gICAgdGhpcy5jdXJPcC5mb3JjZVVwZGF0ZSA9IHRydWU7XG4gICAgYXR0YWNoRG9jKHRoaXMsIGRvYyk7XG5cbiAgICBpZiAoKG9wdGlvbnMuYXV0b2ZvY3VzICYmICFtb2JpbGUpIHx8IGNtLmhhc0ZvY3VzKCkpXG4gICAgICBzZXRUaW1lb3V0KGJpbmQob25Gb2N1cywgdGhpcyksIDIwKTtcbiAgICBlbHNlXG4gICAgICBvbkJsdXIodGhpcyk7XG5cbiAgICBmb3IgKHZhciBvcHQgaW4gb3B0aW9uSGFuZGxlcnMpIGlmIChvcHRpb25IYW5kbGVycy5oYXNPd25Qcm9wZXJ0eShvcHQpKVxuICAgICAgb3B0aW9uSGFuZGxlcnNbb3B0XSh0aGlzLCBvcHRpb25zW29wdF0sIEluaXQpO1xuICAgIG1heWJlVXBkYXRlTGluZU51bWJlcldpZHRoKHRoaXMpO1xuICAgIGlmIChvcHRpb25zLmZpbmlzaEluaXQpIG9wdGlvbnMuZmluaXNoSW5pdCh0aGlzKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluaXRIb29rcy5sZW5ndGg7ICsraSkgaW5pdEhvb2tzW2ldKHRoaXMpO1xuICAgIGVuZE9wZXJhdGlvbih0aGlzKTtcbiAgICAvLyBTdXBwcmVzcyBvcHRpbWl6ZWxlZ2liaWxpdHkgaW4gV2Via2l0LCBzaW5jZSBpdCBicmVha3MgdGV4dFxuICAgIC8vIG1lYXN1cmluZyBvbiBsaW5lIHdyYXBwaW5nIGJvdW5kYXJpZXMuXG4gICAgaWYgKHdlYmtpdCAmJiBvcHRpb25zLmxpbmVXcmFwcGluZyAmJlxuICAgICAgICBnZXRDb21wdXRlZFN0eWxlKGRpc3BsYXkubGluZURpdikudGV4dFJlbmRlcmluZyA9PSBcIm9wdGltaXplbGVnaWJpbGl0eVwiKVxuICAgICAgZGlzcGxheS5saW5lRGl2LnN0eWxlLnRleHRSZW5kZXJpbmcgPSBcImF1dG9cIjtcbiAgfVxuXG4gIC8vIERJU1BMQVkgQ09OU1RSVUNUT1JcblxuICAvLyBUaGUgZGlzcGxheSBoYW5kbGVzIHRoZSBET00gaW50ZWdyYXRpb24sIGJvdGggZm9yIGlucHV0IHJlYWRpbmdcbiAgLy8gYW5kIGNvbnRlbnQgZHJhd2luZy4gSXQgaG9sZHMgcmVmZXJlbmNlcyB0byBET00gbm9kZXMgYW5kXG4gIC8vIGRpc3BsYXktcmVsYXRlZCBzdGF0ZS5cblxuICBmdW5jdGlvbiBEaXNwbGF5KHBsYWNlLCBkb2MsIGlucHV0KSB7XG4gICAgdmFyIGQgPSB0aGlzO1xuICAgIHRoaXMuaW5wdXQgPSBpbnB1dDtcblxuICAgIC8vIENvdmVycyBib3R0b20tcmlnaHQgc3F1YXJlIHdoZW4gYm90aCBzY3JvbGxiYXJzIGFyZSBwcmVzZW50LlxuICAgIGQuc2Nyb2xsYmFyRmlsbGVyID0gZWx0KFwiZGl2XCIsIG51bGwsIFwiQ29kZU1pcnJvci1zY3JvbGxiYXItZmlsbGVyXCIpO1xuICAgIGQuc2Nyb2xsYmFyRmlsbGVyLnNldEF0dHJpYnV0ZShcImNtLW5vdC1jb250ZW50XCIsIFwidHJ1ZVwiKTtcbiAgICAvLyBDb3ZlcnMgYm90dG9tIG9mIGd1dHRlciB3aGVuIGNvdmVyR3V0dGVyTmV4dFRvU2Nyb2xsYmFyIGlzIG9uXG4gICAgLy8gYW5kIGggc2Nyb2xsYmFyIGlzIHByZXNlbnQuXG4gICAgZC5ndXR0ZXJGaWxsZXIgPSBlbHQoXCJkaXZcIiwgbnVsbCwgXCJDb2RlTWlycm9yLWd1dHRlci1maWxsZXJcIik7XG4gICAgZC5ndXR0ZXJGaWxsZXIuc2V0QXR0cmlidXRlKFwiY20tbm90LWNvbnRlbnRcIiwgXCJ0cnVlXCIpO1xuICAgIC8vIFdpbGwgY29udGFpbiB0aGUgYWN0dWFsIGNvZGUsIHBvc2l0aW9uZWQgdG8gY292ZXIgdGhlIHZpZXdwb3J0LlxuICAgIGQubGluZURpdiA9IGVsdChcImRpdlwiLCBudWxsLCBcIkNvZGVNaXJyb3ItY29kZVwiKTtcbiAgICAvLyBFbGVtZW50cyBhcmUgYWRkZWQgdG8gdGhlc2UgdG8gcmVwcmVzZW50IHNlbGVjdGlvbiBhbmQgY3Vyc29ycy5cbiAgICBkLnNlbGVjdGlvbkRpdiA9IGVsdChcImRpdlwiLCBudWxsLCBudWxsLCBcInBvc2l0aW9uOiByZWxhdGl2ZTsgei1pbmRleDogMVwiKTtcbiAgICBkLmN1cnNvckRpdiA9IGVsdChcImRpdlwiLCBudWxsLCBcIkNvZGVNaXJyb3ItY3Vyc29yc1wiKTtcbiAgICAvLyBBIHZpc2liaWxpdHk6IGhpZGRlbiBlbGVtZW50IHVzZWQgdG8gZmluZCB0aGUgc2l6ZSBvZiB0aGluZ3MuXG4gICAgZC5tZWFzdXJlID0gZWx0KFwiZGl2XCIsIG51bGwsIFwiQ29kZU1pcnJvci1tZWFzdXJlXCIpO1xuICAgIC8vIFdoZW4gbGluZXMgb3V0c2lkZSBvZiB0aGUgdmlld3BvcnQgYXJlIG1lYXN1cmVkLCB0aGV5IGFyZSBkcmF3biBpbiB0aGlzLlxuICAgIGQubGluZU1lYXN1cmUgPSBlbHQoXCJkaXZcIiwgbnVsbCwgXCJDb2RlTWlycm9yLW1lYXN1cmVcIik7XG4gICAgLy8gV3JhcHMgZXZlcnl0aGluZyB0aGF0IG5lZWRzIHRvIGV4aXN0IGluc2lkZSB0aGUgdmVydGljYWxseS1wYWRkZWQgY29vcmRpbmF0ZSBzeXN0ZW1cbiAgICBkLmxpbmVTcGFjZSA9IGVsdChcImRpdlwiLCBbZC5tZWFzdXJlLCBkLmxpbmVNZWFzdXJlLCBkLnNlbGVjdGlvbkRpdiwgZC5jdXJzb3JEaXYsIGQubGluZURpdl0sXG4gICAgICAgICAgICAgICAgICAgICAgbnVsbCwgXCJwb3NpdGlvbjogcmVsYXRpdmU7IG91dGxpbmU6IG5vbmVcIik7XG4gICAgLy8gTW92ZWQgYXJvdW5kIGl0cyBwYXJlbnQgdG8gY292ZXIgdmlzaWJsZSB2aWV3LlxuICAgIGQubW92ZXIgPSBlbHQoXCJkaXZcIiwgW2VsdChcImRpdlwiLCBbZC5saW5lU3BhY2VdLCBcIkNvZGVNaXJyb3ItbGluZXNcIildLCBudWxsLCBcInBvc2l0aW9uOiByZWxhdGl2ZVwiKTtcbiAgICAvLyBTZXQgdG8gdGhlIGhlaWdodCBvZiB0aGUgZG9jdW1lbnQsIGFsbG93aW5nIHNjcm9sbGluZy5cbiAgICBkLnNpemVyID0gZWx0KFwiZGl2XCIsIFtkLm1vdmVyXSwgXCJDb2RlTWlycm9yLXNpemVyXCIpO1xuICAgIGQuc2l6ZXJXaWR0aCA9IG51bGw7XG4gICAgLy8gQmVoYXZpb3Igb2YgZWx0cyB3aXRoIG92ZXJmbG93OiBhdXRvIGFuZCBwYWRkaW5nIGlzXG4gICAgLy8gaW5jb25zaXN0ZW50IGFjcm9zcyBicm93c2Vycy4gVGhpcyBpcyB1c2VkIHRvIGVuc3VyZSB0aGVcbiAgICAvLyBzY3JvbGxhYmxlIGFyZWEgaXMgYmlnIGVub3VnaC5cbiAgICBkLmhlaWdodEZvcmNlciA9IGVsdChcImRpdlwiLCBudWxsLCBudWxsLCBcInBvc2l0aW9uOiBhYnNvbHV0ZTsgaGVpZ2h0OiBcIiArIHNjcm9sbGVyR2FwICsgXCJweDsgd2lkdGg6IDFweDtcIik7XG4gICAgLy8gV2lsbCBjb250YWluIHRoZSBndXR0ZXJzLCBpZiBhbnkuXG4gICAgZC5ndXR0ZXJzID0gZWx0KFwiZGl2XCIsIG51bGwsIFwiQ29kZU1pcnJvci1ndXR0ZXJzXCIpO1xuICAgIGQubGluZUd1dHRlciA9IG51bGw7XG4gICAgLy8gQWN0dWFsIHNjcm9sbGFibGUgZWxlbWVudC5cbiAgICBkLnNjcm9sbGVyID0gZWx0KFwiZGl2XCIsIFtkLnNpemVyLCBkLmhlaWdodEZvcmNlciwgZC5ndXR0ZXJzXSwgXCJDb2RlTWlycm9yLXNjcm9sbFwiKTtcbiAgICBkLnNjcm9sbGVyLnNldEF0dHJpYnV0ZShcInRhYkluZGV4XCIsIFwiLTFcIik7XG4gICAgLy8gVGhlIGVsZW1lbnQgaW4gd2hpY2ggdGhlIGVkaXRvciBsaXZlcy5cbiAgICBkLndyYXBwZXIgPSBlbHQoXCJkaXZcIiwgW2Quc2Nyb2xsYmFyRmlsbGVyLCBkLmd1dHRlckZpbGxlciwgZC5zY3JvbGxlcl0sIFwiQ29kZU1pcnJvclwiKTtcblxuICAgIC8vIFdvcmsgYXJvdW5kIElFNyB6LWluZGV4IGJ1ZyAobm90IHBlcmZlY3QsIGhlbmNlIElFNyBub3QgcmVhbGx5IGJlaW5nIHN1cHBvcnRlZClcbiAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8IDgpIHsgZC5ndXR0ZXJzLnN0eWxlLnpJbmRleCA9IC0xOyBkLnNjcm9sbGVyLnN0eWxlLnBhZGRpbmdSaWdodCA9IDA7IH1cbiAgICBpZiAoIXdlYmtpdCAmJiAhKGdlY2tvICYmIG1vYmlsZSkpIGQuc2Nyb2xsZXIuZHJhZ2dhYmxlID0gdHJ1ZTtcblxuICAgIGlmIChwbGFjZSkge1xuICAgICAgaWYgKHBsYWNlLmFwcGVuZENoaWxkKSBwbGFjZS5hcHBlbmRDaGlsZChkLndyYXBwZXIpO1xuICAgICAgZWxzZSBwbGFjZShkLndyYXBwZXIpO1xuICAgIH1cblxuICAgIC8vIEN1cnJlbnQgcmVuZGVyZWQgcmFuZ2UgKG1heSBiZSBiaWdnZXIgdGhhbiB0aGUgdmlldyB3aW5kb3cpLlxuICAgIGQudmlld0Zyb20gPSBkLnZpZXdUbyA9IGRvYy5maXJzdDtcbiAgICBkLnJlcG9ydGVkVmlld0Zyb20gPSBkLnJlcG9ydGVkVmlld1RvID0gZG9jLmZpcnN0O1xuICAgIC8vIEluZm9ybWF0aW9uIGFib3V0IHRoZSByZW5kZXJlZCBsaW5lcy5cbiAgICBkLnZpZXcgPSBbXTtcbiAgICBkLnJlbmRlcmVkVmlldyA9IG51bGw7XG4gICAgLy8gSG9sZHMgaW5mbyBhYm91dCBhIHNpbmdsZSByZW5kZXJlZCBsaW5lIHdoZW4gaXQgd2FzIHJlbmRlcmVkXG4gICAgLy8gZm9yIG1lYXN1cmVtZW50LCB3aGlsZSBub3QgaW4gdmlldy5cbiAgICBkLmV4dGVybmFsTWVhc3VyZWQgPSBudWxsO1xuICAgIC8vIEVtcHR5IHNwYWNlIChpbiBwaXhlbHMpIGFib3ZlIHRoZSB2aWV3XG4gICAgZC52aWV3T2Zmc2V0ID0gMDtcbiAgICBkLmxhc3RXcmFwSGVpZ2h0ID0gZC5sYXN0V3JhcFdpZHRoID0gMDtcbiAgICBkLnVwZGF0ZUxpbmVOdW1iZXJzID0gbnVsbDtcblxuICAgIGQubmF0aXZlQmFyV2lkdGggPSBkLmJhckhlaWdodCA9IGQuYmFyV2lkdGggPSAwO1xuICAgIGQuc2Nyb2xsYmFyc0NsaXBwZWQgPSBmYWxzZTtcblxuICAgIC8vIFVzZWQgdG8gb25seSByZXNpemUgdGhlIGxpbmUgbnVtYmVyIGd1dHRlciB3aGVuIG5lY2Vzc2FyeSAod2hlblxuICAgIC8vIHRoZSBhbW91bnQgb2YgbGluZXMgY3Jvc3NlcyBhIGJvdW5kYXJ5IHRoYXQgbWFrZXMgaXRzIHdpZHRoIGNoYW5nZSlcbiAgICBkLmxpbmVOdW1XaWR0aCA9IGQubGluZU51bUlubmVyV2lkdGggPSBkLmxpbmVOdW1DaGFycyA9IG51bGw7XG4gICAgLy8gU2V0IHRvIHRydWUgd2hlbiBhIG5vbi1ob3Jpem9udGFsLXNjcm9sbGluZyBsaW5lIHdpZGdldCBpc1xuICAgIC8vIGFkZGVkLiBBcyBhbiBvcHRpbWl6YXRpb24sIGxpbmUgd2lkZ2V0IGFsaWduaW5nIGlzIHNraXBwZWQgd2hlblxuICAgIC8vIHRoaXMgaXMgZmFsc2UuXG4gICAgZC5hbGlnbldpZGdldHMgPSBmYWxzZTtcblxuICAgIGQuY2FjaGVkQ2hhcldpZHRoID0gZC5jYWNoZWRUZXh0SGVpZ2h0ID0gZC5jYWNoZWRQYWRkaW5nSCA9IG51bGw7XG5cbiAgICAvLyBUcmFja3MgdGhlIG1heGltdW0gbGluZSBsZW5ndGggc28gdGhhdCB0aGUgaG9yaXpvbnRhbCBzY3JvbGxiYXJcbiAgICAvLyBjYW4gYmUga2VwdCBzdGF0aWMgd2hlbiBzY3JvbGxpbmcuXG4gICAgZC5tYXhMaW5lID0gbnVsbDtcbiAgICBkLm1heExpbmVMZW5ndGggPSAwO1xuICAgIGQubWF4TGluZUNoYW5nZWQgPSBmYWxzZTtcblxuICAgIC8vIFVzZWQgZm9yIG1lYXN1cmluZyB3aGVlbCBzY3JvbGxpbmcgZ3JhbnVsYXJpdHlcbiAgICBkLndoZWVsRFggPSBkLndoZWVsRFkgPSBkLndoZWVsU3RhcnRYID0gZC53aGVlbFN0YXJ0WSA9IG51bGw7XG5cbiAgICAvLyBUcnVlIHdoZW4gc2hpZnQgaXMgaGVsZCBkb3duLlxuICAgIGQuc2hpZnQgPSBmYWxzZTtcblxuICAgIC8vIFVzZWQgdG8gdHJhY2sgd2hldGhlciBhbnl0aGluZyBoYXBwZW5lZCBzaW5jZSB0aGUgY29udGV4dCBtZW51XG4gICAgLy8gd2FzIG9wZW5lZC5cbiAgICBkLnNlbEZvckNvbnRleHRNZW51ID0gbnVsbDtcblxuICAgIGQuYWN0aXZlVG91Y2ggPSBudWxsO1xuXG4gICAgaW5wdXQuaW5pdChkKTtcbiAgfVxuXG4gIC8vIFNUQVRFIFVQREFURVNcblxuICAvLyBVc2VkIHRvIGdldCB0aGUgZWRpdG9yIGludG8gYSBjb25zaXN0ZW50IHN0YXRlIGFnYWluIHdoZW4gb3B0aW9ucyBjaGFuZ2UuXG5cbiAgZnVuY3Rpb24gbG9hZE1vZGUoY20pIHtcbiAgICBjbS5kb2MubW9kZSA9IENvZGVNaXJyb3IuZ2V0TW9kZShjbS5vcHRpb25zLCBjbS5kb2MubW9kZU9wdGlvbik7XG4gICAgcmVzZXRNb2RlU3RhdGUoY20pO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzZXRNb2RlU3RhdGUoY20pIHtcbiAgICBjbS5kb2MuaXRlcihmdW5jdGlvbihsaW5lKSB7XG4gICAgICBpZiAobGluZS5zdGF0ZUFmdGVyKSBsaW5lLnN0YXRlQWZ0ZXIgPSBudWxsO1xuICAgICAgaWYgKGxpbmUuc3R5bGVzKSBsaW5lLnN0eWxlcyA9IG51bGw7XG4gICAgfSk7XG4gICAgY20uZG9jLmZyb250aWVyID0gY20uZG9jLmZpcnN0O1xuICAgIHN0YXJ0V29ya2VyKGNtLCAxMDApO1xuICAgIGNtLnN0YXRlLm1vZGVHZW4rKztcbiAgICBpZiAoY20uY3VyT3ApIHJlZ0NoYW5nZShjbSk7XG4gIH1cblxuICBmdW5jdGlvbiB3cmFwcGluZ0NoYW5nZWQoY20pIHtcbiAgICBpZiAoY20ub3B0aW9ucy5saW5lV3JhcHBpbmcpIHtcbiAgICAgIGFkZENsYXNzKGNtLmRpc3BsYXkud3JhcHBlciwgXCJDb2RlTWlycm9yLXdyYXBcIik7XG4gICAgICBjbS5kaXNwbGF5LnNpemVyLnN0eWxlLm1pbldpZHRoID0gXCJcIjtcbiAgICAgIGNtLmRpc3BsYXkuc2l6ZXJXaWR0aCA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJtQ2xhc3MoY20uZGlzcGxheS53cmFwcGVyLCBcIkNvZGVNaXJyb3Itd3JhcFwiKTtcbiAgICAgIGZpbmRNYXhMaW5lKGNtKTtcbiAgICB9XG4gICAgZXN0aW1hdGVMaW5lSGVpZ2h0cyhjbSk7XG4gICAgcmVnQ2hhbmdlKGNtKTtcbiAgICBjbGVhckNhY2hlcyhjbSk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpe3VwZGF0ZVNjcm9sbGJhcnMoY20pO30sIDEwMCk7XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBlc3RpbWF0ZXMgdGhlIGhlaWdodCBvZiBhIGxpbmUsIHRvIHVzZSBhc1xuICAvLyBmaXJzdCBhcHByb3hpbWF0aW9uIHVudGlsIHRoZSBsaW5lIGJlY29tZXMgdmlzaWJsZSAoYW5kIGlzIHRodXNcbiAgLy8gcHJvcGVybHkgbWVhc3VyYWJsZSkuXG4gIGZ1bmN0aW9uIGVzdGltYXRlSGVpZ2h0KGNtKSB7XG4gICAgdmFyIHRoID0gdGV4dEhlaWdodChjbS5kaXNwbGF5KSwgd3JhcHBpbmcgPSBjbS5vcHRpb25zLmxpbmVXcmFwcGluZztcbiAgICB2YXIgcGVyTGluZSA9IHdyYXBwaW5nICYmIE1hdGgubWF4KDUsIGNtLmRpc3BsYXkuc2Nyb2xsZXIuY2xpZW50V2lkdGggLyBjaGFyV2lkdGgoY20uZGlzcGxheSkgLSAzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24obGluZSkge1xuICAgICAgaWYgKGxpbmVJc0hpZGRlbihjbS5kb2MsIGxpbmUpKSByZXR1cm4gMDtcblxuICAgICAgdmFyIHdpZGdldHNIZWlnaHQgPSAwO1xuICAgICAgaWYgKGxpbmUud2lkZ2V0cykgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lLndpZGdldHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGxpbmUud2lkZ2V0c1tpXS5oZWlnaHQpIHdpZGdldHNIZWlnaHQgKz0gbGluZS53aWRnZXRzW2ldLmhlaWdodDtcbiAgICAgIH1cblxuICAgICAgaWYgKHdyYXBwaW5nKVxuICAgICAgICByZXR1cm4gd2lkZ2V0c0hlaWdodCArIChNYXRoLmNlaWwobGluZS50ZXh0Lmxlbmd0aCAvIHBlckxpbmUpIHx8IDEpICogdGg7XG4gICAgICBlbHNlXG4gICAgICAgIHJldHVybiB3aWRnZXRzSGVpZ2h0ICsgdGg7XG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVzdGltYXRlTGluZUhlaWdodHMoY20pIHtcbiAgICB2YXIgZG9jID0gY20uZG9jLCBlc3QgPSBlc3RpbWF0ZUhlaWdodChjbSk7XG4gICAgZG9jLml0ZXIoZnVuY3Rpb24obGluZSkge1xuICAgICAgdmFyIGVzdEhlaWdodCA9IGVzdChsaW5lKTtcbiAgICAgIGlmIChlc3RIZWlnaHQgIT0gbGluZS5oZWlnaHQpIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgZXN0SGVpZ2h0KTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRoZW1lQ2hhbmdlZChjbSkge1xuICAgIGNtLmRpc3BsYXkud3JhcHBlci5jbGFzc05hbWUgPSBjbS5kaXNwbGF5LndyYXBwZXIuY2xhc3NOYW1lLnJlcGxhY2UoL1xccypjbS1zLVxcUysvZywgXCJcIikgK1xuICAgICAgY20ub3B0aW9ucy50aGVtZS5yZXBsYWNlKC8oXnxcXHMpXFxzKi9nLCBcIiBjbS1zLVwiKTtcbiAgICBjbGVhckNhY2hlcyhjbSk7XG4gIH1cblxuICBmdW5jdGlvbiBndXR0ZXJzQ2hhbmdlZChjbSkge1xuICAgIHVwZGF0ZUd1dHRlcnMoY20pO1xuICAgIHJlZ0NoYW5nZShjbSk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpe2FsaWduSG9yaXpvbnRhbGx5KGNtKTt9LCAyMCk7XG4gIH1cblxuICAvLyBSZWJ1aWxkIHRoZSBndXR0ZXIgZWxlbWVudHMsIGVuc3VyZSB0aGUgbWFyZ2luIHRvIHRoZSBsZWZ0IG9mIHRoZVxuICAvLyBjb2RlIG1hdGNoZXMgdGhlaXIgd2lkdGguXG4gIGZ1bmN0aW9uIHVwZGF0ZUd1dHRlcnMoY20pIHtcbiAgICB2YXIgZ3V0dGVycyA9IGNtLmRpc3BsYXkuZ3V0dGVycywgc3BlY3MgPSBjbS5vcHRpb25zLmd1dHRlcnM7XG4gICAgcmVtb3ZlQ2hpbGRyZW4oZ3V0dGVycyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzcGVjcy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIGd1dHRlckNsYXNzID0gc3BlY3NbaV07XG4gICAgICB2YXIgZ0VsdCA9IGd1dHRlcnMuYXBwZW5kQ2hpbGQoZWx0KFwiZGl2XCIsIG51bGwsIFwiQ29kZU1pcnJvci1ndXR0ZXIgXCIgKyBndXR0ZXJDbGFzcykpO1xuICAgICAgaWYgKGd1dHRlckNsYXNzID09IFwiQ29kZU1pcnJvci1saW5lbnVtYmVyc1wiKSB7XG4gICAgICAgIGNtLmRpc3BsYXkubGluZUd1dHRlciA9IGdFbHQ7XG4gICAgICAgIGdFbHQuc3R5bGUud2lkdGggPSAoY20uZGlzcGxheS5saW5lTnVtV2lkdGggfHwgMSkgKyBcInB4XCI7XG4gICAgICB9XG4gICAgfVxuICAgIGd1dHRlcnMuc3R5bGUuZGlzcGxheSA9IGkgPyBcIlwiIDogXCJub25lXCI7XG4gICAgdXBkYXRlR3V0dGVyU3BhY2UoY20pO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlR3V0dGVyU3BhY2UoY20pIHtcbiAgICB2YXIgd2lkdGggPSBjbS5kaXNwbGF5Lmd1dHRlcnMub2Zmc2V0V2lkdGg7XG4gICAgY20uZGlzcGxheS5zaXplci5zdHlsZS5tYXJnaW5MZWZ0ID0gd2lkdGggKyBcInB4XCI7XG4gIH1cblxuICAvLyBDb21wdXRlIHRoZSBjaGFyYWN0ZXIgbGVuZ3RoIG9mIGEgbGluZSwgdGFraW5nIGludG8gYWNjb3VudFxuICAvLyBjb2xsYXBzZWQgcmFuZ2VzIChzZWUgbWFya1RleHQpIHRoYXQgbWlnaHQgaGlkZSBwYXJ0cywgYW5kIGpvaW5cbiAgLy8gb3RoZXIgbGluZXMgb250byBpdC5cbiAgZnVuY3Rpb24gbGluZUxlbmd0aChsaW5lKSB7XG4gICAgaWYgKGxpbmUuaGVpZ2h0ID09IDApIHJldHVybiAwO1xuICAgIHZhciBsZW4gPSBsaW5lLnRleHQubGVuZ3RoLCBtZXJnZWQsIGN1ciA9IGxpbmU7XG4gICAgd2hpbGUgKG1lcmdlZCA9IGNvbGxhcHNlZFNwYW5BdFN0YXJ0KGN1cikpIHtcbiAgICAgIHZhciBmb3VuZCA9IG1lcmdlZC5maW5kKDAsIHRydWUpO1xuICAgICAgY3VyID0gZm91bmQuZnJvbS5saW5lO1xuICAgICAgbGVuICs9IGZvdW5kLmZyb20uY2ggLSBmb3VuZC50by5jaDtcbiAgICB9XG4gICAgY3VyID0gbGluZTtcbiAgICB3aGlsZSAobWVyZ2VkID0gY29sbGFwc2VkU3BhbkF0RW5kKGN1cikpIHtcbiAgICAgIHZhciBmb3VuZCA9IG1lcmdlZC5maW5kKDAsIHRydWUpO1xuICAgICAgbGVuIC09IGN1ci50ZXh0Lmxlbmd0aCAtIGZvdW5kLmZyb20uY2g7XG4gICAgICBjdXIgPSBmb3VuZC50by5saW5lO1xuICAgICAgbGVuICs9IGN1ci50ZXh0Lmxlbmd0aCAtIGZvdW5kLnRvLmNoO1xuICAgIH1cbiAgICByZXR1cm4gbGVuO1xuICB9XG5cbiAgLy8gRmluZCB0aGUgbG9uZ2VzdCBsaW5lIGluIHRoZSBkb2N1bWVudC5cbiAgZnVuY3Rpb24gZmluZE1heExpbmUoY20pIHtcbiAgICB2YXIgZCA9IGNtLmRpc3BsYXksIGRvYyA9IGNtLmRvYztcbiAgICBkLm1heExpbmUgPSBnZXRMaW5lKGRvYywgZG9jLmZpcnN0KTtcbiAgICBkLm1heExpbmVMZW5ndGggPSBsaW5lTGVuZ3RoKGQubWF4TGluZSk7XG4gICAgZC5tYXhMaW5lQ2hhbmdlZCA9IHRydWU7XG4gICAgZG9jLml0ZXIoZnVuY3Rpb24obGluZSkge1xuICAgICAgdmFyIGxlbiA9IGxpbmVMZW5ndGgobGluZSk7XG4gICAgICBpZiAobGVuID4gZC5tYXhMaW5lTGVuZ3RoKSB7XG4gICAgICAgIGQubWF4TGluZUxlbmd0aCA9IGxlbjtcbiAgICAgICAgZC5tYXhMaW5lID0gbGluZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIE1ha2Ugc3VyZSB0aGUgZ3V0dGVycyBvcHRpb25zIGNvbnRhaW5zIHRoZSBlbGVtZW50XG4gIC8vIFwiQ29kZU1pcnJvci1saW5lbnVtYmVyc1wiIHdoZW4gdGhlIGxpbmVOdW1iZXJzIG9wdGlvbiBpcyB0cnVlLlxuICBmdW5jdGlvbiBzZXRHdXR0ZXJzRm9yTGluZU51bWJlcnMob3B0aW9ucykge1xuICAgIHZhciBmb3VuZCA9IGluZGV4T2Yob3B0aW9ucy5ndXR0ZXJzLCBcIkNvZGVNaXJyb3ItbGluZW51bWJlcnNcIik7XG4gICAgaWYgKGZvdW5kID09IC0xICYmIG9wdGlvbnMubGluZU51bWJlcnMpIHtcbiAgICAgIG9wdGlvbnMuZ3V0dGVycyA9IG9wdGlvbnMuZ3V0dGVycy5jb25jYXQoW1wiQ29kZU1pcnJvci1saW5lbnVtYmVyc1wiXSk7XG4gICAgfSBlbHNlIGlmIChmb3VuZCA+IC0xICYmICFvcHRpb25zLmxpbmVOdW1iZXJzKSB7XG4gICAgICBvcHRpb25zLmd1dHRlcnMgPSBvcHRpb25zLmd1dHRlcnMuc2xpY2UoMCk7XG4gICAgICBvcHRpb25zLmd1dHRlcnMuc3BsaWNlKGZvdW5kLCAxKTtcbiAgICB9XG4gIH1cblxuICAvLyBTQ1JPTExCQVJTXG5cbiAgLy8gUHJlcGFyZSBET00gcmVhZHMgbmVlZGVkIHRvIHVwZGF0ZSB0aGUgc2Nyb2xsYmFycy4gRG9uZSBpbiBvbmVcbiAgLy8gc2hvdCB0byBtaW5pbWl6ZSB1cGRhdGUvbWVhc3VyZSByb3VuZHRyaXBzLlxuICBmdW5jdGlvbiBtZWFzdXJlRm9yU2Nyb2xsYmFycyhjbSkge1xuICAgIHZhciBkID0gY20uZGlzcGxheSwgZ3V0dGVyVyA9IGQuZ3V0dGVycy5vZmZzZXRXaWR0aDtcbiAgICB2YXIgZG9jSCA9IE1hdGgucm91bmQoY20uZG9jLmhlaWdodCArIHBhZGRpbmdWZXJ0KGNtLmRpc3BsYXkpKTtcbiAgICByZXR1cm4ge1xuICAgICAgY2xpZW50SGVpZ2h0OiBkLnNjcm9sbGVyLmNsaWVudEhlaWdodCxcbiAgICAgIHZpZXdIZWlnaHQ6IGQud3JhcHBlci5jbGllbnRIZWlnaHQsXG4gICAgICBzY3JvbGxXaWR0aDogZC5zY3JvbGxlci5zY3JvbGxXaWR0aCwgY2xpZW50V2lkdGg6IGQuc2Nyb2xsZXIuY2xpZW50V2lkdGgsXG4gICAgICB2aWV3V2lkdGg6IGQud3JhcHBlci5jbGllbnRXaWR0aCxcbiAgICAgIGJhckxlZnQ6IGNtLm9wdGlvbnMuZml4ZWRHdXR0ZXIgPyBndXR0ZXJXIDogMCxcbiAgICAgIGRvY0hlaWdodDogZG9jSCxcbiAgICAgIHNjcm9sbEhlaWdodDogZG9jSCArIHNjcm9sbEdhcChjbSkgKyBkLmJhckhlaWdodCxcbiAgICAgIG5hdGl2ZUJhcldpZHRoOiBkLm5hdGl2ZUJhcldpZHRoLFxuICAgICAgZ3V0dGVyV2lkdGg6IGd1dHRlcldcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gTmF0aXZlU2Nyb2xsYmFycyhwbGFjZSwgc2Nyb2xsLCBjbSkge1xuICAgIHRoaXMuY20gPSBjbTtcbiAgICB2YXIgdmVydCA9IHRoaXMudmVydCA9IGVsdChcImRpdlwiLCBbZWx0KFwiZGl2XCIsIG51bGwsIG51bGwsIFwibWluLXdpZHRoOiAxcHhcIildLCBcIkNvZGVNaXJyb3ItdnNjcm9sbGJhclwiKTtcbiAgICB2YXIgaG9yaXogPSB0aGlzLmhvcml6ID0gZWx0KFwiZGl2XCIsIFtlbHQoXCJkaXZcIiwgbnVsbCwgbnVsbCwgXCJoZWlnaHQ6IDEwMCU7IG1pbi1oZWlnaHQ6IDFweFwiKV0sIFwiQ29kZU1pcnJvci1oc2Nyb2xsYmFyXCIpO1xuICAgIHBsYWNlKHZlcnQpOyBwbGFjZShob3Jpeik7XG5cbiAgICBvbih2ZXJ0LCBcInNjcm9sbFwiLCBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh2ZXJ0LmNsaWVudEhlaWdodCkgc2Nyb2xsKHZlcnQuc2Nyb2xsVG9wLCBcInZlcnRpY2FsXCIpO1xuICAgIH0pO1xuICAgIG9uKGhvcml6LCBcInNjcm9sbFwiLCBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChob3Jpei5jbGllbnRXaWR0aCkgc2Nyb2xsKGhvcml6LnNjcm9sbExlZnQsIFwiaG9yaXpvbnRhbFwiKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY2hlY2tlZ
23459E92ZXJsYXkgPSBmYWxzZTtcbiAgICAvLyBOZWVkIHRvIHNldCBhIG1pbmltdW0gd2lkdGggdG8gc2VlIHRoZSBzY3JvbGxiYXIgb24gSUU3IChidXQgbXVzdCBub3Qgc2V0IGl0IG9uIElFOCkuXG4gICAgaWYgKGllICYmIGllX3ZlcnNpb24gPCA4KSB0aGlzLmhvcml6LnN0eWxlLm1pbkhlaWdodCA9IHRoaXMudmVydC5zdHlsZS5taW5XaWR0aCA9IFwiMThweFwiO1xuICB9XG5cbiAgTmF0aXZlU2Nyb2xsYmFycy5wcm90b3R5cGUgPSBjb3B5T2JqKHtcbiAgICB1cGRhdGU6IGZ1bmN0aW9uKG1lYXN1cmUpIHtcbiAgICAgIHZhciBuZWVkc0ggPSBtZWFzdXJlLnNjcm9sbFdpZHRoID4gbWVhc3VyZS5jbGllbnRXaWR0aCArIDE7XG4gICAgICB2YXIgbmVlZHNWID0gbWVhc3VyZS5zY3JvbGxIZWlnaHQgPiBtZWFzdXJlLmNsaWVudEhlaWdodCArIDE7XG4gICAgICB2YXIgc1dpZHRoID0gbWVhc3VyZS5uYXRpdmVCYXJXaWR0aDtcblxuICAgICAgaWYgKG5lZWRzVikge1xuICAgICAgICB0aGlzLnZlcnQuc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIjtcbiAgICAgICAgdGhpcy52ZXJ0LnN0eWxlLmJvdHRvbSA9IG5lZWRzSCA/IHNXaWR0aCArIFwicHhcIiA6IFwiMFwiO1xuICAgICAgICB2YXIgdG90YWxIZWlnaHQgPSBtZWFzdXJlLnZpZXdIZWlnaHQgLSAobmVlZHNIID8gc1dpZHRoIDogMCk7XG4gICAgICAgIC8vIEEgYnVnIGluIElFOCBjYW4gY2F1c2UgdGhpcyB2YWx1ZSB0byBiZSBuZWdhdGl2ZSwgc28gZ3VhcmQgaXQuXG4gICAgICAgIHRoaXMudmVydC5maXJzdENoaWxkLnN0eWxlLmhlaWdodCA9XG4gICAgICAgICAgTWF0aC5tYXgoMCwgbWVhc3VyZS5zY3JvbGxIZWlnaHQgLSBtZWFzdXJlLmNsaWVudEhlaWdodCArIHRvdGFsSGVpZ2h0KSArIFwicHhcIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudmVydC5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcbiAgICAgICAgdGhpcy52ZXJ0LmZpcnN0Q2hpbGQuc3R5bGUuaGVpZ2h0ID0gXCIwXCI7XG4gICAgICB9XG5cbiAgICAgIGlmIChuZWVkc0gpIHtcbiAgICAgICAgdGhpcy5ob3Jpei5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuICAgICAgICB0aGlzLmhvcml6LnN0eWxlLnJpZ2h0ID0gbmVlZHNWID8gc1dpZHRoICsgXCJweFwiIDogXCIwXCI7XG4gICAgICAgIHRoaXMuaG9yaXouc3R5bGUubGVmdCA9IG1lYXN1cmUuYmFyTGVmdCArIFwicHhcIjtcbiAgICAgICAgdmFyIHRvdGFsV2lkdGggPSBtZWFzdXJlLnZpZXdXaWR0aCAtIG1lYXN1cmUuYmFyTGVmdCAtIChuZWVkc1YgPyBzV2lkdGggOiAwKTtcbiAgICAgICAgdGhpcy5ob3Jpei5maXJzdENoaWxkLnN0eWxlLndpZHRoID1cbiAgICAgICAgICAobWVhc3VyZS5zY3JvbGxXaWR0aCAtIG1lYXN1cmUuY2xpZW50V2lkdGggKyB0b3RhbFdpZHRoKSArIFwicHhcIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaG9yaXouc3R5bGUuZGlzcGxheSA9IFwiXCI7XG4gICAgICAgIHRoaXMuaG9yaXouZmlyc3RDaGlsZC5zdHlsZS53aWR0aCA9IFwiMFwiO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuY2hlY2tlZE92ZXJsYXkgJiYgbWVhc3VyZS5jbGllbnRIZWlnaHQgPiAwKSB7XG4gICAgICAgIGlmIChzV2lkdGggPT0gMCkgdGhpcy5vdmVybGF5SGFjaygpO1xuICAgICAgICB0aGlzLmNoZWNrZWRPdmVybGF5ID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtyaWdodDogbmVlZHNWID8gc1dpZHRoIDogMCwgYm90dG9tOiBuZWVkc0ggPyBzV2lkdGggOiAwfTtcbiAgICB9LFxuICAgIHNldFNjcm9sbExlZnQ6IGZ1bmN0aW9uKHBvcykge1xuICAgICAgaWYgKHRoaXMuaG9yaXouc2Nyb2xsTGVmdCAhPSBwb3MpIHRoaXMuaG9yaXouc2Nyb2xsTGVmdCA9IHBvcztcbiAgICB9LFxuICAgIHNldFNjcm9sbFRvcDogZnVuY3Rpb24ocG9zKSB7XG4gICAgICBpZiAodGhpcy52ZXJ0LnNjcm9sbFRvcCAhPSBwb3MpIHRoaXMudmVydC5zY3JvbGxUb3AgPSBwb3M7XG4gICAgfSxcbiAgICBvdmVybGF5SGFjazogZnVuY3Rpb24oKSB7XG4gICAgICB2Y
23459XIgdyA9IG1hYyAmJiAhbWFjX2dlTW91bnRhaW5MaW9uID8gXCIxMnB4XCIgOiBcIjE4cHhcIjtcbiAgICAgIHRoaXMuaG9yaXouc3R5bGUubWluSGVpZ2h0ID0gdGhpcy52ZXJ0LnN0eWxlLm1pbldpZHRoID0gdztcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIHZhciBiYXJNb3VzZURvd24gPSBmdW5jdGlvbihlKSB7XG4gICAgICAgIGlmIChlX3RhcmdldChlKSAhPSBzZWxmLnZlcnQgJiYgZV90YXJnZXQoZSkgIT0gc2VsZi5ob3JpeilcbiAgICAgICAgICBvcGVyYXRpb24oc2VsZi5jbSwgb25Nb3VzZURvd24pKGUpO1xuICAgICAgfTtcbiAgICAgIG9uKHRoaXMudmVydCwgXCJtb3VzZWRvd25cIiwgYmFyTW91c2VEb3duKTtcbiAgICAgIG9uKHRoaXMuaG9yaXosIFwibW91c2Vkb3duXCIsIGJhck1vdXNlRG93bik7XG4gICAgfSxcbiAgICBjbGVhcjogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcGFyZW50ID0gdGhpcy5ob3Jpei5wYXJlbnROb2RlO1xuICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMuaG9yaXopO1xuICAgICAgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMudmVydCk7XG4gICAgfVxuICB9LCBOYXRpdmVTY3JvbGxiYXJzLnByb3RvdHlwZSk7XG5cbiAgZnVuY3Rpb24gTnVsbFNjcm9sbGJhcnMoKSB7fVxuXG4gIE51bGxTY3JvbGxiYXJzLnByb3RvdHlwZSA9IGNvcHlPYmooe1xuICAgIHVwZGF0ZTogZnVuY3Rpb24oKSB7IHJldHVybiB7Ym90dG9tOiAwLCByaWdodDogMH07IH0sXG4gICAgc2V0U2Nyb2xsTGVmdDogZnVuY3Rpb24oKSB7fSxcbiAgICBzZXRTY3JvbGxUb3A6IGZ1bmN0aW9uKCkge30sXG4gICAgY2xlYXI6IGZ1bmN0aW9uKCkge31cbiAgfSwgTnVsbFNjcm9sbGJhcnMucHJvdG90eXBlKTtcblxuICBDb2RlTWlycm9yLnNjcm9sbGJhck1vZGVsID0ge1wibmF0aXZlXCI6IE5hdGl2ZVNjcm9sbGJhcnMsIFwibnVsbFwiOiBOdWxsU2Nyb2xsYmFyc307XG5cbiAgZnVuY3Rpb24gaW5pdFNjcm9sbGJhcnMoY20pIHtcbiAgICBpZiAoY20uZGlzcGxheS5zY3JvbGxiYXJzKSB7XG4gICAgICBjbS5kaXNwbGF5LnNjcm9sbGJhcnMuY2xlYXIoKTtcbiAgICAgIGlmIChjbS5kaXNwbGF5LnNjcm9sbGJhcnMuYWRkQ2xhc3MpXG4gICAgICAgIHJtQ2xhc3MoY20uZGlzcGxheS53cmFwcGVyLCBjbS5kaXNwbGF5LnNjcm9sbGJhcnMuYWRkQ2xhc3MpO1xuICAgIH1cblxuICAgIGNtLmRpc3BsYXkuc2Nyb2xsYmFycyA9IG5ldyBDb2RlTWlycm9yLnNjcm9sbGJhck1vZGVsW2NtLm9wdGlvbnMuc2Nyb2xsYmFyU3R5bGVdKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIGNtLmRpc3BsYXkud3JhcHBlci5pbnNlcnRCZWZvcmUobm9kZSwgY20uZGlzcGxheS5zY3JvbGxiYXJGaWxsZXIpO1xuICAgICAgLy8gUHJldmVudCBjbGlja3MgaW4gdGhlIHNjcm9sbGJhcnMgZnJvbSBraWxsaW5nIGZvY3VzXG4gICAgICBvbihub2RlLCBcIm1vdXNlZG93blwiLCBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKGNtLnN0YXRlLmZvY3VzZWQpIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNtLmRpc3BsYXkuaW5wdXQuZm9jdXMoKTsgfSwgMCk7XG4gICAgICB9KTtcbiAgICAgIG5vZGUuc2V0QXR0cmlidXRlKFwiY20tbm90LWNvbnRlbnRcIiwgXCJ0cnVlXCIpO1xuICAgIH0sIGZ1bmN0aW9uKHBvcywgYXhpcykge1xuICAgICAgaWYgKGF4aXMgPT0gXCJob3Jpem9udGFsXCIpIHNldFNjcm9sbExlZnQoY20sIHBvcyk7XG4gICAgICBlbHNlIHNldFNjcm9sbFRvcChjbSwgcG9zKTtcbiAgICB9LCBjbSk7XG4gICAgaWYgKGNtLmRpc3BsYXkuc2Nyb2xsYmFycy5hZGRDbGFzcylcbiAgICAgIGFkZENsYXNzKGNtLmRpc3BsYXkud3JhcHBlciwgY20uZGlzcGxheS5zY3JvbGxiYXJzLmFkZENsYXNzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVNjcm9sbGJhcnMoY20sIG1lYXN1cmUpIHtcbiAgICBpZiAoIW1lYXN1cmUpIG1lYXN1cmUgPSBtZWFzdXJlRm9yU2Nyb2xsYmFycyhjbSk7XG4gICAgdmFyIHN0YXJ0V2lkdGggPSBjbS5kaXNwbGF5LmJhcldpZHRoLCBzdGFydEhlaWdodCA9IGNtLmRpc3BsYXkuYmFySGVpZ2h0O1xuICAgIHVwZGF0ZVNjcm9sbGJhcnNJbm5lcihjbSwgbWVhc3VyZSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0ICYmIHN0YXJ0V2lkdGggIT0gY20uZGlzcGxheS5iYXJXaWR0aCB8fCBzdGFydEhlaWdodCAhPSBjbS5kaXNwbGF5LmJhckhlaWdodDsgaSsrKSB7XG4gICAgICBpZiAoc3RhcnRXaWR0aCAhPSBjbS5kaXNwbGF5LmJhcldpZHRoICYmIGNtLm9wdGlvbnMubGluZVdyYXBwaW5nKVxuICAgICAgICB1cGRhdGVIZWlnaHRzSW5WaWV3cG9ydChjbSk7XG4gICAgICB1cGRhdGVTY3JvbGxiYXJzSW5uZXIoY20sIG1lYXN1cmVGb3JTY3JvbGxiYXJzKGNtKSk7XG4gICAgICBzdGFydFdpZHRoID0gY20uZGlzcGxheS5iYXJXaWR0aDsgc3RhcnRIZWlnaHQgPSBjbS5kaXNwbGF5LmJhckhlaWdodDtcbiAgICB9XG4gIH1cblxuICAvLyBSZS1zeW5jaHJvbml6ZSB0aGUgZmFrZSBzY3JvbGxiYXJzIHdpdGggdGhlIGFjdHVhbCBzaXplIG9mIHRoZVxuICAvLyBjb250ZW50LlxuICBmdW5jdGlvbiB1cGRhdGVTY3JvbGxiYXJzSW5uZXIoY20sIG1lYXN1cmUpIHtcbiAgICB2YXIgZCA9IGNtLmRpc3BsYXk7XG4gICAgdmFyIHNpemVzID0gZC5zY3JvbGxiYXJzLnVwZGF0ZShtZWFzdXJlKTtcblxuICAgIGQuc2l6ZXIuc3R5bGUucGFkZGluZ1JpZ2h0ID0gKGQuYmFyV2lkdGggPSBzaXplcy5yaWdodCkgKyBcInB4XCI7XG4gICAgZC5zaXplci5zdHlsZS5wYWRkaW5nQm90dG9tID0gKGQuYmFySGVpZ2h0ID0gc2l6ZXMuYm90dG9tKSArIFwicHhcIjtcblxuICAgIGlmIChzaXplcy5yaWdodCAmJiBzaXplcy5ib3R0b20pIHtcbiAgICAgIGQuc2Nyb2xsYmFyRmlsbGVyLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG4gICAgICBkLnNjcm9sbGJhckZpbGxlci5zdHlsZS5oZWlnaHQgPSBzaXplcy5ib3R0b20gKyBcInB4XCI7XG4gICAgICBkLnNjcm9sbGJhckZpbGxlci5zdHlsZS53aWR0aCA9IHNpemVzLnJpZ2h0ICsgXCJweFwiO1xuICAgIH0gZWxzZSBkLnNjcm9sbGJhckZpbGxlci5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcbiAgICBpZiAoc2l6ZXMuYm90dG9tICYmIGNtLm9wdGlvbnMuY292ZXJHdXR0ZXJOZXh0VG9TY3JvbGxiYXIgJiYgY20ub3B0aW9ucy5maXhlZEd1dHRlcikge1xuICAgICAgZC5ndXR0ZXJGaWxsZXIuc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIjtcbiAgICAgIGQuZ3V0dGVyRmlsbGVyLnN0eWxlLmhlaWdodCA9IHNpemVzLmJvdHRvbSArIFwicHhcIjtcbiAgICAgIGQuZ3V0dGVyRmlsbGVyLnN0eWxlLndpZHRoID0gbWVhc3VyZS5ndXR0ZXJXaWR0aCArIFwicHhcIjtcbiAgICB9IGVsc2UgZC5ndXR0ZXJGaWxsZXIuc3R5bGUuZGlzcGxheSA9IFwiXCI7XG4gIH1cblxuICAvLyBDb21wdXRlIHRoZSBsaW5lcyB0aGF0IGFyZSB2aXN
23459pYmxlIGluIGEgZ2l2ZW4gdmlld3BvcnQgKGRlZmF1bHRzXG4gIC8vIHRoZSB0aGUgY3VycmVudCBzY3JvbGwgcG9zaXRpb24pLiB2aWV3cG9ydCBtYXkgY29udGFpbiB0b3AsXG4gIC8vIGhlaWdodCwgYW5kIGVuc3VyZSAoc2VlIG9wLnNjcm9sbFRvUG9zKSBwcm9wZXJ0aWVzLlxuICBmdW5jdGlvbiB2aXNpYmxlTGluZXMoZGlzcGxheSwgZG9jLCB2aWV3cG9ydCkge1xuICAgIHZhciB0b3AgPSB2aWV3cG9ydCAmJiB2aWV3cG9ydC50b3AgIT0gbnVsbCA/IE1hdGgubWF4KDAsIHZpZXdwb3J0LnRvcCkgOiBkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbFRvcDtcbiAgICB0b3AgPSBNYXRoLmZsb29yKHRvcCAtIHBhZGRpbmdUb3AoZGlzcGxheSkpO1xuICAgIHZhciBib3R0b20gPSB2aWV3cG9ydCAmJiB2aWV3cG9ydC5ib3R0b20gIT0gbnVsbCA/IHZpZXdwb3J0LmJvdHRvbSA6IHRvcCArIGRpc3BsYXkud3JhcHBlci5jbGllbnRIZWlnaHQ7XG5cbiAgICB2YXIgZnJvbSA9IGxpbmVBdEhlaWdodChkb2MsIHRvcCksIHRvID0gbGluZUF0SGVpZ2h0KGRvYywgYm90dG9tKTtcbiAgICAvLyBFbnN1cmUgaXMgYSB7ZnJvbToge2xpbmUsIGNofSwgdG86IHtsaW5lLCBjaH19IG9iamVjdCwgYW5kXG4gICAgLy8gZm9yY2VzIHRob3NlIGxpbmVzIGludG8gdGhlIHZpZXdwb3J0IChpZiBwb3NzaWJsZSkuXG4gICAgaWYgKHZpZXdwb3J0ICYmIHZpZXdwb3J0LmVuc3VyZSkge1xuICAgICAgdmFyIGVuc3VyZUZyb20gPSB2aWV3cG9ydC5lbnN1cmUuZnJvbS5saW5lLCBlbnN1cmVUbyA9IHZpZXdwb3J0LmVuc3VyZS50by5saW5lO1xuICAgICAgaWYgKGVuc3VyZUZyb20gPCBmcm9tKSB7XG4gICAgICAgIGZyb20gPSBlbnN1cmVGcm9tO1xuICAgICAgICB0byA9IGxpbmVBdEhlaWdodChkb2MsIGhlaWdodEF0TGluZShnZXRMaW5lKGRvYywgZW5zdXJlRnJvbSkpICsgZGlzcGxheS53cmFwcGVyLmNsaWVudEhlaWdodCk7XG4gICAgICB9IGVsc2UgaWYgKE1hdGgubWluKGVuc3VyZVRvLCBkb2MubGFzdExpbmUoKSkgPj0gdG8pIHtcbiAgICAgICAgZnJvbSA9IGxpbmVBdEhlaWdodChkb2MsIGhlaWdodEF0TGluZShnZXRMaW5lKGRvYywgZW5zdXJlVG8pKSAtIGRpc3BsYXkud3JhcHBlci5jbGllbnRIZWlnaHQpO1xuICAgICAgICB0byA9IGVuc3VyZVRvO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge2Zyb206IGZyb20sIHRvOiBNYXRoLm1heCh0bywgZnJvbSArIDEpfTtcbiAgfVxuXG4gIC8vIExJTkUgTlVNQkVSU1xuXG4gIC8vIFJlLWFsaWduIGxpbmUgbnVtYmVycyBhbmQgZ3V0dGVyIG1hcmtzIHRvIGNvbXBlbnNhdGUgZm9yXG4gIC8vIGhvcml6b250YWwgc2Nyb2xsaW5nLlxuICBmdW5jdGlvbiBhbGlnbkhvcml6b250YWxseShjbSkge1xuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheSwgdmlldyA9IGRpc3BsYXkudmlldztcbiAgICBpZiAoIWRpc3BsYXkuYWxpZ25XaWRnZXRzICYmICghZGlzcGxheS5ndXR0ZXJzLmZpcnN0Q2hpbGQgfHwgIWNtLm9wdGlvbnMuZml4ZWRHdXR0ZXIpKSByZXR1cm47XG4gICAgdmFyIGNvbXAgPSBjb21wZW5zYXRlRm9ySFNjcm9sbChkaXNwbGF5KSAtIGRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsTGVmdCArIGNtLmRvYy5zY3JvbGxMZWZ0O1xuICAgIHZhciBndXR0ZXJXID0gZGlzcGxheS5ndXR0ZXJzLm9mZnNldFdpZHRoLCBsZWZ0ID0gY29tcCArIFwicHhcIjtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZpZXcubGVuZ3RoOyBpKyspIGlmICghdmlld1tpXS5oaWRkZW4pIHtcbiAgICAgIGlmIChjbS5vcHRpb25zLmZpeGVkR3V0dGVyICYmIHZpZXdbaV0uZ3V0dGVyKVxuICAgICAgICB2aWV3W2ldLmd1dHRlci5zdHlsZS5sZWZ0ID0gbGVmdDtcbiAgICAgIHZhciBhbGlnbiA9IHZpZXdbaV0uYWxpZ25hYmxlO1xuICAgICAgaWYgKGFsaWduKSBmb3IgKHZhciBqID0gMDsgaiA8IGFsaWduLmxlbmd0aDsgaisrKVxuICAgICAgICBhbGlnbltqXS5zdHlsZS5sZWZ0ID0gbGVmdDtcbiAgICB9XG4gICAgaWYgKGNtLm9wdGlvbnMuZml4ZWRHdXR0ZXIpXG4gICAgICBkaXNwbGF5Lmd1dHRlcnMuc3R5bGUubGVmdCA9IChjb21wICsgZ3V0dGVyVykgKyBcInB4XCI7XG4gIH1cblxuICAvLyBVc2VkIHRvIGVuc3VyZSB0aGF0IHRoZSBsaW5lIG51bWJlciBndXR0ZXIgaXMgc3RpbGwgdGhlIHJpZ2h0XG4gIC8vIHNpemUgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50IHNpemUuIFJldHVybnMgdHJ1ZSB3aGVuIGFuIHVwZGF0ZVxuICAvLyBpcyBuZWVkZWQuXG4gIGZ1bmN0aW9uIG1heWJlVXBkYXRlTGluZU51bWJlcldpZHRoKGNtKSB7XG4gICAgaWYgKCFjbS5vcHRpb25zLmxpbmVOdW1iZXJzKSByZXR1cm4gZmFsc2U7XG4gICAgdmFyIGRvYyA9IGNtLmRvYywgbGFzdCA9IGxpbmVOdW1iZXJGb3IoY20ub3B0aW9ucywgZG9jLmZpcnN0ICsgZG9jLnNpemUgLSAxKSwgZGlzcGxheSA9IGNtLmRpc3BsYXk7XG4gICAgaWYgKGxhc3QubGVuZ3RoICE9IGRpc3BsYXkubGluZU51bUNoYXJzKSB7XG4gICAgICB2Y
23459XIgdGVzdCA9IGRpc3BsYXkubWVhc3VyZS5hcHBlbmRDaGlsZChlbHQoXCJkaXZcIiwgW2VsdChcImRpdlwiLCBsYXN0KV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJDb2RlTWlycm9yLWxpbmVudW1iZXIgQ29kZU1pcnJvci1ndXR0ZXItZWx0XCIpKTtcbiAgICAgIHZhciBpbm5lclcgPSB0ZXN0LmZpcnN0Q2hpbGQub2Zmc2V0V2lkdGgsIHBhZGRpbmcgPSB0ZXN0Lm9mZnNldFdpZHRoIC0gaW5uZXJXO1xuICAgICAgZGlzcGxheS5saW5lR3V0dGVyLnN0eWxlLndpZHRoID0gXCJcIjtcbiAgICAgIGRpc3BsYXkubGluZU51bUlubmVyV2lkdGggPSBNYXRoLm1heChpbm5lclcsIGRpc3BsYXkubGluZUd1dHRlci5vZmZzZXRXaWR0aCAtIHBhZGRpbmcpICsgMTtcbiAgICAgIGRpc3BsYXkubGluZU51bVdpZHRoID0gZGlzcGxheS5saW5lTnVtSW5uZXJXaWR0aCArIHBhZGRpbmc7XG4gICAgICBkaXNwbGF5LmxpbmVOdW1DaGFycyA9IGRpc3BsYXkubGluZU51bUlubmVyV2lkdGggPyBsYXN0Lmxlbmd0aCA6IC0xO1xuICAgICAgZGlzcGxheS5saW5lR3V0dGVyLnN0eWxlLndpZHRoID0gZGlzcGxheS5saW5lTnVtV2lkdGggKyBcInB4XCI7XG4gICAgICB1cGRhdGVHdXR0ZXJTcGFjZShjbSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gbGluZU51bWJlckZvcihvcHRpb25zLCBpKSB7XG4gICAgcmV0dXJuIFN0cmluZyhvcHRpb25zLmxpbmVOdW1iZXJGb3JtYXR0ZXIoaSArIG9wdGlvbnMuZmlyc3RMaW5lTnVtYmVyKSk7XG4gIH1cblxuICAvLyBDb21wdXRlcyBkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbExlZnQgKyBkaXNwbGF5Lmd1dHRlcnMub2Zmc2V0V2lkdGgsXG4gIC8vIGJ1dCB1c2luZyBnZXRCb3VuZGluZ0NsaWVudFJlY3QgdG8gZ2V0IGEgc3ViLXBpeGVsLWFjY3VyYXRlXG4gIC8vIHJlc3VsdC5cbiAgZnVuY3Rpb24gY29tcGVuc2F0ZUZvckhTY3JvbGwoZGlzcGxheSkge1xuICAgIHJldHVybiBkaXNwbGF5LnNjcm9sbGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQgLSBkaXNwbGF5LnNpemVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQ7XG4gIH1cblxuICAvLyBESVNQTEFZIERSQVdJTkdcblxuICBmdW5jdGlvbiBEaXNwbGF5VXBkYXRlKGNtLCB2aWV3cG9ydCwgZm9yY2UpIHtcbiAgICB2YXIgZGlzcGxheSA9IGNtLmRpc3BsYXk7XG5cbiAgICB0aGlzLnZpZXdwb3J0ID0gdmlld3BvcnQ7XG4gICAgLy8gU3RvcmUgc29tZSB2YWx1ZXMgdGhhdCB3ZSdsbCBuZWVkIGxhdGVyIChidXQgZG9uJ3Qgd2FudCB0byBmb3JjZSBhIHJlbGF5b3V0IGZvcilcbiAgICB0aGlzLnZpc2libGUgPSB2aXNpYmxlTGluZXMoZGlzcGxheSwgY20uZG9jLCB2aWV3cG9ydCk7XG4gICAgdGhpcy5lZGl0b3JJc0hpZGRlbiA9ICFkaXNwbGF5LndyYXBwZXIub2Zmc2V0V2lkdGg7XG4gICAgdGhpcy53cmFwcGVySGVpZ2h0ID0gZGlzcGxheS53cmFwcGVyLmNsaWVudEhlaWdodDtcbiAgICB0aGlzLndyYXBwZXJXaWR0aCA9IGRpc3BsYXkud3JhcHBlci5jbGllbnRXaWR0aDtcbiAgICB0aGlzLm9sZERpc3BsYXlXaWR0aCA9IGRpc3BsYXlXaWR0aChjbSk7XG4gICAgdGhpcy5mb3JjZSA9IGZvcmNlO1xuICAgIHRoaXMuZGltcyA9IGdldERpbWVuc2lvbnMoY20pO1xuICAgIHRoaXMuZXZlbnRzID0gW107XG4gIH1cblxuICBEaXNwbGF5VXBkYXRlLnByb3RvdHlwZS5zaWduYWwgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gICAgaWYgKGhhc0hhbmRsZXIoZW1pdHRlciwgdHlwZSkpXG4gICAgICB0aGlzLmV2ZW50cy5wdXNoKGFyZ3VtZW50cyk7XG4gIH07XG4gIERpc3BsYXlVcGRhdGUucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5ldmVudHMubGVuZ3RoOyBpKyspXG4gICAgICBzaWduYWwuYXBwbHkobnVsbCwgdGhpcy5ldmVudHNbaV0pO1xuICB9O1xuXG4gIGZ1bmN0aW9uIG1heWJlQ2xpcFNjcm9sbGJhcnMoY20pIHtcbiAgICB2YXIgZGlzcGxheSA9IGNtLmRpc3BsYXk7XG4gICAgaWYgKCFkaXNwbGF5LnNjcm9sbGJhcnNDbGlwcGVkICYmIGRpc3BsYXkuc2Nyb2xsZXIub2Zmc2V0V2lkdGgpIHtcbiAgICAgIGRpc3BsYXkubmF0aXZlQmFyV2lkdGggPSBkaXNwbGF5LnNjcm9sbGVyLm9mZnNldFdpZHRoIC0gZGlzcGxheS5zY3JvbGxlci5jbGllbnRXaWR0aDtcbiAgICAgIGRpc3BsYXkuaGVpZ2h0Rm9yY2VyLnN0eWxlLmhlaWdodCA9IHNjcm9sbEdhcChjbSkgKyBcInB4XCI7XG4gICAgICBkaXNwbGF5LnNpemVyLnN0eWxlLm1hcmdpbkJvdHRvbSA9IC1kaXNwbGF5Lm5hdGl2ZUJhcldpZHRoICsgXCJweFwiO1xuICAgICAgZGlzcGxheS5zaXplci5zdHlsZS5ib3JkZXJSaWdodFdpZHRoID0gc2Nyb2xsR2FwKGNtKSArIFwicHhcIjtcbiAgICAgIGRpc3BsYXkuc2Nyb2xsYmFyc0NsaXBwZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8vIERvZXMgdGhlIGFjdHVhbCB1cGRhdGluZyBvZiB0aGUgbGluZSBkaXNwbGF5LiBCYWlscyBvdXRcbiAgLy8gKHJldHVybmluZyBmYWxzZSkgd2hlbiB0aGVyZSBpcyBub3RoaW5nIHRvIGJlIGRvbmUgYW5kIGZvcmNlZCBpc1xuICAvLyBmYWxzZS5cbiAgZnVuY3Rpb24gdXBkYXRlRGlzcGxheUlmTmVlZGVkKGNtLCB1cGRhdGUpIHtcbiAgICB2YXIgZGlzcGxheSA9IGNtLmRpc3BsYXksIGRvYyA9IGNtLmRvYztcblxuICAgIGlmICh1cGRhdGUuZWRpdG9ySXNIaWRkZW4pIHtcbiAgICAgIHJlc2V0VmlldyhjbSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQmFpbCBvdXQgaWYgdGhlIHZpc2libGUgYXJlYSBpcyBhbHJlYWR5IHJlbmRlcmVkIGFuZCBub3RoaW5nIGNoYW5nZWQuXG4gICAgaWYgKCF1cGRhdGUuZm9yY2UgJiZcbiAgICAgICAgdXBkYXRlLnZpc2libGUuZnJvbSA+PSBkaXNwbGF5LnZpZXdGcm9tICYmIHVwZGF0ZS52aXNpYmxlLnRvIDw9IGRpc3BsYXkudmlld1RvICYmXG4gICAgICAgIChkaXNwbGF5LnVwZGF0ZUxpbmVOdW1iZXJzID09IG51bGwgfHwgZGlzcGxheS51cGRhdGVMaW5lTnVtYmVycyA+PSBkaXNwbGF5LnZpZXdUbykgJiZcbiAgICAgICAgZGlzcGxheS5yZW5kZXJlZFZpZXcgPT0gZGlzcGxheS52aWV3ICYmIGNvdW50RGlydHlWaWV3KGNtKSA9PSAwKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKG1heWJlVXBkYXRlTGluZU51bWJlcldpZHRoKGNtKSkge1xuICAgICAgcmVzZXRWaWV3KGNtKTtcbiAgICAgIHVwZGF0ZS5kaW1zID0gZ2V0RGltZW5zaW9ucyhjbSk7XG4gICAgfVxuXG4gICAgLy8gQ29tcHV0ZSBhIHN1aXRhYmxlIG5ldyB2aWV3cG9ydCAoZnJvbSAmIHRvKVxuICAgIHZhciBlbmQgPSBkb2MuZmlyc3QgKyBkb2Muc2l6ZTtcbiAgICB2YXIgZnJvbSA9IE1hdGgubWF4KHVwZGF0ZS52aXNpYmxlLmZyb20gLSBjbS5vcHRpb25zLnZpZXdwb3J0TWFy
23459Z2luLCBkb2MuZmlyc3QpO1xuICAgIHZhciB0byA9IE1hdGgubWluKGVuZCwgdXBkYXRlLnZpc2libGUudG8gKyBjbS5vcHRpb25zLnZpZXdwb3J0TWFyZ2luKTtcbiAgICBpZiAoZGlzcGxheS52aWV3RnJvbSA8IGZyb20gJiYgZnJvbSAtIGRpc3BsYXkudmlld0Zyb20gPCAyMCkgZnJvbSA9IE1hdGgubWF4KGRvYy5maXJzdCwgZGlzcGxheS52aWV3RnJvbSk7XG4gICAgaWYgKGRpc3BsYXkudmlld1RvID4gdG8gJiYgZGlzcGxheS52aWV3VG8gLSB0byA8IDIwKSB0byA9IE1hdGgubWluKGVuZCwgZGlzcGxheS52aWV3VG8pO1xuICAgIGlmIChzYXdDb2xsYXBzZWRTcGFucykge1xuICAgICAgZnJvbSA9IHZpc3VhbExpbmVObyhjbS5kb2MsIGZyb20pO1xuICAgICAgdG8gPSB2aXN1YWxMaW5lRW5kTm8oY20uZG9jLCB0byk7XG4gICAgfVxuXG4gICAgdmFyIGRpZmZlcmVudCA9IGZyb20gIT0gZGlzcGxheS52aWV3RnJvbSB8fCB0byAhPSBkaXNwbGF5LnZpZXdUbyB8fFxuICAgICAgZGlzcGxheS5sYXN0V3JhcEhlaWdodCAhPSB1cGRhdGUud3JhcHBlckhlaWdodCB8fCBkaXNwbGF5Lmxhc3RXcmFwV2lkdGggIT0gdXBkYXRlLndyYXBwZXJXaWR0aDtcbiAgICBhZGp1c3RWaWV3KGNtLCBmcm9tLCB0byk7XG5cbiAgICBkaXNwbGF5LnZpZXdPZmZzZXQgPSBoZWlnaHRBdExpbmUoZ2V0TGluZShjbS5kb2MsIGRpc3BsYXkudmlld0Zyb20pKTtcbiAgICAvLyBQb3NpdGlvbiB0aGUgbW92ZXIgZGl2IHRvIGFsaWduIHdpdGggdGhlIGN1cnJlbnQgc2Nyb2xsIHBvc2l0aW9uXG4gICAgY20uZGlzcGxheS5tb3Zlci5zdHlsZS50b3AgPSBkaXNwbGF5LnZpZXdPZmZzZXQgKyBcInB4XCI7XG5cbiAgICB2YXIgdG9VcGRhdGUgPSBjb3VudERpcnR5VmlldyhjbSk7XG4gICAgaWYgKCFkaWZmZXJlbnQgJiYgdG9VcGRhdGUgPT0gMCAmJiAhdXBkYXRlLmZvcmNlICYmIGRpc3BsYXkucmVuZGVyZWRWaWV3ID09IGRpc3BsYXkudmlldyAmJlxuICAgICAgICAoZGlzcGxheS51cGRhdGVMaW5lTnVtYmVycyA9PSBudWxsIHx8IGRpc3BsYXkudXBkYXRlTGluZU51bWJlcnMgPj0gZGlzcGxheS52aWV3VG8pKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgLy8gRm9yIGJpZyBjaGFuZ2VzLCB3ZSBoaWRlIHRoZSBlbmNsb3NpbmcgZWxlbWVudCBkdXJpbmcgdGhlXG4gICAgLy8gdXBkYXRlLCBzaW5jZSB0aGF0IHNwZWVkcyB1cCB0aGUgb3BlcmF0aW9ucyBvbiBtb3N0IGJyb3dzZXJzLlxuICAgIHZhciBmb2N1c2VkID0gYWN0aXZlRWx0KCk7XG4gICAgaWYgKHRvVXBkYXRlID4gNCkgZGlzcGxheS5saW5lRGl2LnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICBwYXRjaERpc3BsYXkoY20sIGRpc3BsYXkudXBkYXRlTGluZU51bWJlcnMsIHVwZGF0ZS5kaW1zKTtcbiAgICBpZiAodG9VcGRhdGUgPiA0KSBkaXNwbGF5LmxpbmVEaXYuc3R5bGUuZGlzcGxheSA9IFwiXCI7XG4gICAgZGlzcGxheS5yZW5kZXJlZFZpZXcgPSBkaXNwbGF5LnZpZXc7XG4gICAgLy8gVGhlcmUgbWlnaHQgaGF2ZSBiZWVuIGEgd2lkZ2V0IHdpdGggYSBmb2N1c2VkIGVsZW1lbnQgdGhhdCBnb3RcbiAgICAvLyBoaWRkZW4gb3IgdXBkYXRlZCwgaWYgc28gcmUtZm9jdXMgaX
23459QuXG4gICAgaWYgKGZvY3VzZWQgJiYgYWN0aXZlRWx0KCkgIT0gZm9jdXNlZCAmJiBmb2N1c2VkLm9mZnNldEhlaWdodCkgZm9jdXNlZC5mb2N1cygpO1xuXG4gICAgLy8gUHJldmVudCBzZWxlY3Rpb24gYW5kIGN1cnNvcnMgZnJvbSBpbnRlcmZlcmluZyB3aXRoIHRoZSBzY3JvbGxcbiAgICAvLyB3aWR0aCBhbmQgaGVpZ2h0LlxuICAgIHJlbW92ZUNoaWxkcmVuKGRpc3BsYXkuY3Vyc29yRGl2KTtcbiAgICByZW1vdmVDaGlsZHJlbihkaXNwbGF5LnNlbGVjdGlvbkRpdik7XG4gICAgZGlzcGxheS5ndXR0ZXJzLnN0eWxlLmhlaWdodCA9IGRpc3BsYXkuc2l6ZXIuc3R5bGUubWluSGVpZ2h0ID0gMDtcblxuICAgIGlmIChkaWZmZXJlbnQpIHtcbiAgICAgIGRpc3BsYXkubGFzdFdyYXBIZWlnaHQgPSB1cGRhdGUud3JhcHBlckhlaWdodDtcbiAgICAgIGRpc3BsYXkubGFzdFdyYXBXaWR0aCA9IHVwZGF0ZS53cmFwcGVyV2lkdGg7XG4gICAgICBzdGFydFdvcmtlcihjbSwgNDAwKTtcbiAgICB9XG5cbiAgICBkaXNwbGF5LnVwZGF0ZUxpbmVOdW1iZXJzID0gbnVsbDtcblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gcG9zdFVwZGF0ZURpc3BsYXkoY20sIHVwZGF0ZSkge1xuICAgIHZhciB2aWV3cG9ydCA9IHVwZGF0ZS52aWV3cG9ydDtcbiAgICBmb3IgKHZhciBmaXJzdCA9IHRydWU7OyBmaXJzdCA9IGZhbHNlKSB7XG4gICAgICBpZiAoIWZpcnN0IHx8ICFjbS5vcHRpb25zLmxpbmVXcmFwcGluZyB8fCB1cGRhdGUub2xkRGlzcGxheVdpZHRoID09IGRpc3BsYXlXaWR0aChjbSkpIHtcbiAgICAgICAgLy8gQ2xpcCBmb3JjZWQgdmlld3BvcnQgdG8gYWN0dWFsIHNjcm9sbGFibGUgYXJlYS5cbiAgICAgICAgaWYgKHZpZXdwb3J0ICYmIHZpZXdwb3J0LnRvcCAhPSBudWxsKVxuICAgICAgICAgIHZpZXdwb3J0ID0ge3RvcDogTWF0aC5taW4oY20uZG9jLmhlaWdodCArIHBhZGRpbmdWZXJ0KGNtLmRpc3BsYXkpIC0gZGlzcGxheUhlaWdodChjbSksIHZpZXdwb3J0LnRvcCl9O1xuICAgICAgICAvLyBVcGRhdGVkIGxpbmUgaGVpZ2h0cyBtaWdodCByZXN1bHQgaW4gdGhlIGRyYXduIGFyZWEgbm90XG4gICAgICAgIC8vIGFjdHVhbGx5IGNvdmVyaW5nIHRoZSB2aWV3cG9ydC4gS2VlcCBsb29waW5nIHVudGlsIGl0IGRvZXMuXG4gICAgICAgIHVwZGF0ZS52aXNpYmxlID0gdmlzaWJsZUxpbmVzKGNtLmRpc3BsYXksIGNtLmRvYywgdmlld3BvcnQpO1xuICAgICAgICBpZiAodXBkYXRlLnZpc2libGUuZnJvbSA+PSBjbS5kaXNwbGF5LnZpZXdGcm9tICYmIHVwZGF0ZS52aXNpYmxlLnRvIDw9IGNtLmRpc3BsYXkudmlld1RvKVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKCF1cGRhdGVEaXNwbGF5SWZOZWVkZWQoY20sIHVwZGF0ZSkpIGJyZWFrO1xuICAgICAgdXBkYXRlSGVpZ2h0c0luVmlld3BvcnQoY20pO1xuICAgICAgdmFyIGJhck1lYXN1cmUgPSBtZWFzdXJlRm9yU2Nyb2xsYmFycyhjbSk7XG4gICAgICB1cGRhdGVTZWxlY3Rpb24oY20pO1xuICAgICAgc2V0RG9jdW1lbnRIZWlnaHQoY20sIGJhck1lYXN1cmUpO1xuICAgICAgdXBkYXRlU2Nyb2xsYmFycyhjbSwgYmFyTWVhc3VyZSk7XG4gICAgfVxuXG4gICAgdXBkYXRlLnNpZ25hbChjbSwgXCJ1cGRhdGVcIiwgY20pO1xuICAgIGlmIChjbS5kaXNwbGF5LnZpZXdGcm9tICE9IGNtLmRpc3BsYXkucmVwb3J0ZWRWaWV3RnJvbSB8fCBjbS5kaXNwbGF5LnZpZXdUbyAhPSBjbS5kaXNwbGF5LnJlcG9ydGVkVmlld1RvKSB7XG4gICAgICB1cGRhdGUuc2lnbmFsKGNtLCBcInZpZXdwb3J0Q2hhbmdlXCIsIGNtLCBjbS5kaXNwbGF5LnZpZXdGcm9tLCBjbS5kaXNwbGF5LnZpZXdUbyk7XG4gICAgICBjbS5kaXNwbGF5LnJlcG9ydGVkVmlld0Zyb20gPSBjbS5kaXNwbGF5LnZpZXdGcm9tOyBjbS5kaXNwbGF5LnJlcG9ydGVkVmlld1RvID0gY20uZGlzcGxheS52aWV3VG87XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlRGlzcGxheVNpbXBsZShjbSwgdmlld3BvcnQpIHtcbiAgICB2YXIgdXBkYXRlID0gbmV3IERpc3BsYXlVcGRhdGUoY20sIHZpZXdwb3J0KTtcbiAgICBpZiAodXBkYXRlRGlzcGxheUlmTmVlZGVkKGNtLCB1cGRhdGUpKSB7XG4gICAgICB1cGRhdGVIZWlnaHRzSW5WaWV3cG9ydChjbSk7XG4gICAgICBwb3N0VXBkYXRlRGlzcGxheShjbSwgdXBkYXRlKTtcbiAgICAgIHZhciBiYXJNZWFzdXJlID0gbWVhc3VyZUZvclNjcm9sbGJhcnMoY20pO1xuICAgICAgdXBkYXRlU2VsZWN0aW9uKGNtKTtcbiAgICAgIHNldERvY3VtZW50SGVpZ2h0KGNtLCBiYXJNZWFzdXJlKTtcbiAgICAgIHVwZGF0ZVNjcm9sbGJhcnMoY20sIGJhck1lYXN1cmUpO1xuICAgICAgdXBkYXRlLmZpbmlzaCgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNldERvY3VtZW50SGVpZ2h0KGNtLCBtZWFzdXJlKSB7XG4gICAgY20uZGlzcGxheS5zaXplci5zdHlsZS5taW5IZWlnaHQgPSBtZWFzdXJlLmRvY0hlaWdodCArIFwicHhcIjtcbiAgICB2YXIgdG90YWwgPSBtZWFzdXJlLmRvY0hlaWdodCArIGNtLmRpc3BsYXkuYmFySGVpZ2h0O1xuICAgIGNtLmRpc3BsYXkuaGVpZ2h0Rm9yY2VyLnN0eWxlLnRvcCA9IHRvdGFsICsgXCJweFwiO1xuICAgIGNtLmRpc3BsYXkuZ3V0dGVycy5zdHlsZS5oZWlnaHQgPSBNYXRoLm1heCh0b3RhbCArIHNjcm9sbEdhcChjbSksIG1lYXN1cmUuY2xpZW50SGVpZ2h0KSArIFwicHhcIjtcbiAgfVxuXG4gIC8vIFJlYWQgdGhlIGFjdHVhbCBoZWlnaHRzIG9mIHRoZSByZW5kZXJlZCBsaW5lcywgYW5kIHVwZGF0ZSB0aGVpclxuICAvLyBzdG9yZWQgaGVpZ2h0cyB0byBtYXRjaC5cbiAgZnVuY3Rpb24gdXBkYXRlSGVpZ2h0c0luVmlld3BvcnQoY20pIHtcbiAgICB2YXIgZGlzcGxheSA9IGNtLmRpc3BsYXk7XG4gICAgdmFyIHByZXZCb3R0b20gPSBkaXNwbGF5LmxpbmVEaXYub2Zmc2V0VG9wO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGlzcGxheS52aWV3Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2Y
23459XIgY3VyID0gZGlzcGxheS52aWV3W2ldLCBoZWlnaHQ7XG4gICAgICBpZiAoY3VyLmhpZGRlbikgY29udGludWU7XG4gICAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8IDgpIHtcbiAgICAgICAgdmFyIGJvdCA9IGN1ci5ub2RlLm9mZnNldFRvcCArIGN1ci5ub2RlLm9mZnNldEhlaWdodDtcbiAgICAgICAgaGVpZ2h0ID0gYm90IC0gcHJldkJvdHRvbTtcbiAgICAgICAgcHJldkJvdHRvbSA9IGJvdDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBib3ggPSBjdXIubm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgaGVpZ2h0ID0gYm94LmJvdHRvbSAtIGJveC50b3A7XG4gICAgICB9XG4gICAgICB2YXIgZGlmZiA9IGN1ci5saW5lLmhlaWdodCAtIGhlaWdodDtcbiAgICAgIGlmIChoZWlnaHQgPCAyKSBoZWlnaHQgPSB0ZXh0SGVpZ2h0KGRpc3BsYXkpO1xuICAgICAgaWYgKGRpZmYgPiAuMDAxIHx8IGRpZmYgPCAtLjAwMSkge1xuICAgICAgICB1cGRhdGVMaW5lSGVpZ2h0KGN1ci5saW5lLCBoZWlnaHQpO1xuICAgICAgICB1cGRhdGVXaWRnZXRIZWlnaHQoY3VyLmxpbmUpO1xuICAgICAgICBpZiAoY3VyLnJlc3QpIGZvciAodmFyIGogPSAwOyBqIDwgY3VyLnJlc3QubGVuZ3RoOyBqKyspXG4gICAgICAgICAgdXBkYXRlV2lkZ2V0SGVpZ2h0KGN1ci5yZXN0W2pdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBSZWFkIGFuZCBzdG9yZSB0aGUgaGVpZ2h0IG9mIGxpbmUgd2lkZ2V0cyBhc3NvY2lhdGVkIHdpdGggdGhlXG4gIC8vIGdpdmVuIGxpbmUuXG4gIGZ1bmN0aW9uIHVwZGF0ZVdpZGdldEhlaWdodChsaW5lKSB7XG4gICAgaWYgKGxpbmUud2lkZ2V0cykgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lLndpZGdldHMubGVuZ3RoOyArK2kpXG4gICAgICBsaW5lLndpZGdldHNbaV0uaGVpZ2h0ID0gbGluZS53aWRnZXRzW2ldLm
vendor: 15,580 bytes, line 23459
234595vZGUub2Zmc2V0SGVpZ2h0O1xuICB9XG5cbiAgLy8gRG8gYSBidWxrLXJlYWQgb2YgdGhlIERPTSBwb3NpdGlvbnMgYW5kIHNpemVzIG5lZWRlZCB0byBkcmF3IHRoZVxuICAvLyB2aWV3LCBzbyB0aGF0IHdlIGRvbid0IGludGVybGVhdmUgcmVhZGluZyBhbmQgd3JpdGluZyB0byB0aGUgRE9NLlxuICBmdW5jdGlvbiBnZXREaW1lbnNpb25zKGNtKSB7XG4gICAgdmFyIGQgPSBjbS5kaXNwbGF5LCBsZWZ0ID0ge30sIHdpZHRoID0ge307XG4gICAgdmFyIGd1dHRlckxlZnQgPSBkLmd1dHRlcnMuY2xpZW50TGVmdDtcbiAgICBmb3IgKHZhciBuID0gZC5ndXR0ZXJzLmZpcnN0Q2hpbGQsIGkgPSAwOyBuOyBuID0gbi5uZXh0U2libGluZywgKytpKSB7XG4gICAgICBsZWZ0W2NtLm9wdGlvbnMuZ3V0dGVyc1tpXV0gPSBuLm9mZnNldExlZnQgKyBuLmNsaWVudExlZnQgKyBndXR0ZXJMZWZ0O1xuICAgICAgd2lkdGhbY20ub3B0aW9ucy5ndXR0ZXJzW2ldXSA9IG4uY2xpZW50V2lkdGg7XG4gICAgfVxuICAgIHJldHVybiB7Zml4ZWRQb3M6IGNvbXBlbnNhdGVGb3JIU2Nyb2xsKGQpLFxuICAgICAgICAgICAgZ3V0dGVyVG90YWxXaWR0aDogZC5ndXR0ZXJzLm9mZnNldFdpZHRoLFxuICAgICAgICAgICAgZ3V0dGVyTGVmdDogbGVmdCxcbiAgICAgICAgICAgIGd1dHRlcldpZHRoOiB3aWR0aCxcbiAgICAgICAgICAgIHdyYXBwZXJXaWR0aDogZC53cmFwcGVyLmNsaWVudFdpZHRofTtcbiAgfVxuXG4gIC8vIFN5bmMgdGhlIGFjdHVhbCBkaXNwbGF5IERPTSBzdHJ1Y3R1cmUgd2l0aCBkaXNwbGF5LnZpZXcsIHJlbW92aW5nXG4gIC8vIG5vZGVzIGZvciBsaW5lcyB0aGF0IGFyZSBubyBsb25nZXIgaW4gdmlldywgYW5kIGNyZWF0aW5nIHRoZSBvbmVzXG4gIC8vIHRoYXQgYXJlIG5vdCB0aGVyZSB5ZXQsIGFuZCB1cGRhdGluZyB0aGUgb25lcyB0aGF0IGFyZSBvdXQgb2ZcbiAgLy8gZGF0ZS5cbiAgZnVuY3Rpb24gcGF0Y2hEaXNwbGF5KGNtLCB1cGRhdGVOdW1iZXJzRnJvbSwgZGltcykge1xuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheSwgbGluZU51bWJlcnMgPSBjbS5vcHRpb25zLmxpbmVOdW1iZXJzO1xuICAgIHZhciBjb250YWluZXIgPSBkaXNwbGF5LmxpbmVEaXYsIGN1ciA9IGNvbnRhaW5lci5maXJzdENoaWxkO1xuXG4gICAgZnVuY3Rpb24gcm0obm9kZSkge1xuICAgICAgdmFyIG5leHQgPSBub2RlLm5leHRTaWJsaW5nO1xuICAgICAgLy8gV29ya3MgYXJvdW5kIGEgdGhyb3ctc2Nyb2xsIGJ1ZyBpbiBPUyBYIFdlYmtpdFxuICAgICAgaWYgKHdlYmtpdCAmJiBtYWMgJiYgY20uZGlzcGxheS5jdXJyZW50V2hlZWxUYXJnZXQgPT0gbm9kZSlcbiAgICAgICAgbm9kZS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG4gICAgICBlbHNlXG4gICAgICAgIG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTtcbiAgICAgIHJldHVybiBuZXh0O1xuICAgIH1cblxuICAgIHZhciB2aWV3ID0gZGlzcGxheS52aWV3LCBsaW5lTiA9IGRpc3BsYXkudmlld0Zyb207XG4gICAgLy8gTG9vcCBvdmVyIHRoZSBlbGVtZW50cyBpbiB0aGUgdmlldywgc3luY2luZyBjdXIgKHRoZSBET00gbm9kZXNcbiAgICAvLyBpbiBkaXNwbGF5LmxpbmVEaXYpIHdpdGggdGhlIHZpZXcgYXMgd2UgZ28uXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2aWV3Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbGluZVZpZXcgPSB2aWV3W2ldO1xuICAgICAgaWYgKGxpbmVWaWV3LmhpZGRlbikge1xuICAgICAgfSBlbHNlIGlmICghbGluZVZpZXcubm9kZSB8fCBsaW5lVmlldy5ub2RlLnBhcmVudE5vZGUgIT0gY29udGFpbmVyKSB7IC8vIE5vdCBkcmF3biB5ZXRcbiAgICAgICAgdmFyIG5vZGUgPSBidWlsZExpbmVFbGVtZW50KGNtLCBsaW5lVmlldywgbGluZU4sIGRpbXMpO1xuICAgICAgICBjb250YWluZXIuaW5zZXJ0QmVmb3JlKG5vZGUsIGN1cik7XG4gICAgICB9IGVsc2UgeyAvLyBBbHJlYWR5IGRyYXduXG4gICAgICAgIHdoaWxlIChjdXIgIT0gbGluZVZpZXcubm9kZSkgY3VyID0gcm0oY3VyKTtcbiAgICAgICAgdmFyIHVwZGF0ZU51bWJlciA9IGxpbmVOdW1iZXJzICYmIHVwZGF0ZU51bWJlcnNGcm9tICE9IG51bGwgJiZcbiAgICAgICAgICB1cGRhdGVOdW1iZXJzRnJvbSA8PSBsaW5lTiAmJiBsaW5lVmlldy5saW5lTnVtYmVyO1xuICAgICAgICBpZiAobGluZVZpZXcuY2hhbmdlcykge1xuICAgICAgICAgIGlmIChpbmRleE9mKGxpbmVWaWV3LmNoYW5nZXMsIFwiZ3V0dGVyXCIpID4gLTEpIHVwZGF0ZU51bWJlciA9IGZhbHNlO1xuICAgICAgICAgIHVwZGF0ZUxpbmVGb3JDaGFuZ2VzKGNtLCBsaW5lVmlldywgbGluZU4sIGRpbXMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1cGRhdGVOdW1iZXIpIHtcbiAgICAgICAgICByZW1vdmVDaGlsZHJlbihsaW5lVmlldy5saW5lTnVtYmVyKTtcbiAgICAgICAgICBsaW5lVmlldy5saW5lTnVtYmVyLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGxpbmVOdW1iZXJGb3IoY20ub3B0aW9ucywgbGluZU4pKSk7XG4gICAgICAgIH1cbiAgICAgICAgY3VyID0gbGluZVZpZXcubm9kZS5uZXh0U2libGluZztcbiAgICAgIH1cbiAgICAgIGxpbmVOICs9IGxpbmVWaWV3LnNpemU7XG4gICAgfVxuICAgIHdoaWxlIChjdXIpIGN1ciA9IHJtKGN1cik7XG4gIH1cblxuICAvLyBXaGVuIGFuIGFzcGVjdCBvZiBhIGxpbmUgY2hhbmdlcywgYSBzdHJpbmcgaXMgYWRkZWQgdG9cbiAgLy8gbGluZVZpZXcuY2hhbmdlcy4gVGhpcyB1cGRhdGVzIHRoZSByZWxldmFudCBwYXJ0IG9mIHRoZSBsaW5lJ3NcbiAgLy8gRE9NIHN0cnVjdHVyZS5cbiAgZnVuY3Rpb24gdXBkYXRlTGluZUZvckNoYW5nZXMoY20sIGxpbmVWaWV3LCBsaW5lTiwgZGltcykge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbGluZVZpZXcuY2hhbmdlcy5sZW5ndGg7IGorKykge1xuICAgICAgdmFyIHR5cGUgPSBsaW5lVmlldy5jaGFuZ2VzW2pdO1xuICAgICAgaWYgKHR5cGUgPT0gXCJ0ZXh0XCIpIHVwZGF0ZUxpbmVUZXh0KGNtLCBsaW5lVmlldyk7XG4gICAgICBlbHNlIGlmICh0eXBlID09IFwiZ3V0dGVyXCIpIHVwZGF0ZUxpbmVHdXR0ZXIoY20sIGxpbmVWaWV3LCBsaW5lTiwgZGltcyk7XG4gICAgICBlbHNlIGlmICh0eXBlID09IFwiY2xhc3NcIikgdXBkYXRlTGluZUNsYXNzZXMobGluZVZpZXcpO1xuICAgICAgZWxzZSBpZiAodHlwZSA9PSBcIndpZGdldFwiKSB1cGRhdGVMaW5lV2lkZ2V0cyhjbSwgbGluZVZpZXcsIGRpbXMpO1xuICAgIH1cbiAgICBsaW5lVmlldy5jaGFuZ2VzID0gbnVsbDtcbiAgfVxuXG4gIC8vIExpbmVzIHdpdGggZ3V0dGVyIGVsZW1lbnRzLCB3aWRnZXRzIG9yIGEgYmFja2dyb3VuZCBjbGFzcyBuZWVkIHRvXG4gIC8vIGJlIHdyYXBwZWQsIGFuZCBoYXZlIHRoZSBleHRyYSBlbGVtZW50cyBhZGRlZCB0byB0aGUgd3JhcHBlciBkaXZcbiAgZnVuY3Rpb24gZW5zdXJlTGluZVdyYXBwZWQobGluZVZpZXcpIHtcbiAgICBpZiAobGluZVZpZXcubm9kZSA9PSBsaW5lVmlldy50ZXh0KSB7XG4gICAgICBsaW5lVmlldy5ub2RlID0gZWx0KFwiZGl2XCIsIG51bGwsIG51bGwsIFwicG9zaXRpb246IHJlbGF0aXZlXCIpO1xuICAgICAgaWYgKGxpbmVWaWV3LnRleHQucGFyZW50Tm9kZSlcbiAgICAgICAgbGluZVZpZXcudGV4dC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChsaW5lVmlldy5ub2RlLCBsaW5lVmlldy50ZXh0KTtcbiAgICAgIGxpbmVWaWV3Lm5vZGUuYXBwZW5kQ2hpbGQobGluZVZpZXcudGV4dCk7XG4gICAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8IDgpIGxpbmVWaWV3Lm5vZGUuc3R5bGUuekluZGV4ID0gMjtcbiAgICB9XG4gICAgcmV0dXJuIGxpbmVWaWV3Lm5vZGU7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVMaW5lQmFja2dyb3VuZChsaW5lVmlldykge1xuICAgIHZhciBjbHMgPSBsaW5lVmlldy5iZ0NsYXNzID8gbGluZVZpZXcuYmdDbGFzcyArIFwiIFwiICsgKGxpbmVWaWV3LmxpbmUuYmdDbGFzcyB8fCBcIlwiKSA6IGxpbmVWaWV3LmxpbmUuYmdDbGFzcztcbiAgICBpZiAoY2xzKSBjbHMgKz0gXCIgQ29kZU1pcnJvci1saW5lYmFja2dyb3VuZFwiO1xuICAgIGlmIChsaW5lVmlldy5iYWNrZ3JvdW5kKSB7XG4gICAgICBpZiAoY2xzKSBsaW5lVmlldy5iYWNrZ3JvdW5kLmNsYXNzTmFtZSA9IGNscztcbiAgICAgIGVsc2UgeyBsaW5lVmlldy5iYWNrZ3JvdW5kLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobGluZVZpZXcuYmFja2dyb3VuZCk7IGxpbmVWaWV3LmJhY2tncm91bmQgPSBudWxsOyB9XG4gICAgfSBlbHNlIGlmIChjbHMpIHtcbiAgICAgIHZhciB3cmFwID0gZW5zdXJlTGluZVdyYXBwZWQobGluZVZpZXcpO1xuICAgICAgbGluZVZpZXcuYmFja2dyb3VuZCA9IHdyYXAuaW5zZXJ0QmVmb3JlKGVsdChcImRpdlwiLCBudWxsLCBjbHMpLCB3cmFwLmZpcnN0Q2hpbGQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFdyYXBwZXIgYXJvdW5kIGJ1aWxkTGluZUNvbnRlbnQgd2hpY2ggd2lsbCByZXVzZSB0aGUgc3RydWN0dXJlXG4gIC8vIGluIGRpc3BsYXkuZXh0ZXJuYWxNZWFzdXJlZCB3aGVuIHBvc3NpYmxlLlxuICBmdW5jdGlvbiBnZXRMaW5lQ29udGVudChjbSwgbGluZVZpZXcpIHtcbiAgICB2YXIgZXh0ID0gY20uZGlzcGxheS5leHRlcm5hbE1lYXN1cmVkO1xuICAgIGlmIChleHQgJiYgZXh0LmxpbmUgPT0gbGluZVZpZXcubGluZSkge1xuICAgICAgY20uZGlzcGxheS5leHRlcm5hbE1lYXN1cmVkID0gbnVsbDtcbiAgICAgIGxpbmVWaWV3Lm1lYXN1cmUgPSBleHQubWVhc3VyZTtcbiAgICAgIHJldHVybiBleHQuYnVpbHQ7XG4gICAgfVxuICAgIHJldHVybiBidWlsZExpbmVDb250ZW50KGNtLCBsaW5lVmlldyk7XG4gIH1cblxuICAvLyBSZWRyYXcgdGhlIGxpbmUncyB0ZXh0LiBJbnRlcmFjdHMgd2l0aCB0aGUgYmFja2dyb3VuZCBhbmQgdGV4dFxuICAvLyBjbGFzc2VzIGJlY2F1c2UgdGhlIG1vZGUgbWF5IG91dHB1dCB0b2tlbnMgdGhhdCBpbmZsdWVuY2UgdGhlc2VcbiAgLy8gY2xhc3Nlcy5cbiAgZnVuY3Rpb24gdXBkYXRlTGluZVRleHQoY20sIGxpbmVWaWV3KSB7XG4gICAgdmFyIGNscyA9IGxpbmVWaWV3LnRleHQuY2xhc3NOYW1lO1xuICAgIHZhciBidWlsdCA9IGdldExpbmVDb250ZW50KGNtLCBsaW5lVmlldyk7XG4gICAgaWYgKGxpbmVWaWV3LnRleHQgPT0gbGluZVZpZXcubm9kZSkgbGluZVZpZXcubm9kZSA9IGJ1aWx0LnByZTtcbiAgICBsaW5lVmlldy50ZXh0LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGJ1aWx0LnByZSwgbGluZVZpZXcudGV4dCk7XG4gICAgbGluZVZpZXcudGV4dCA9IGJ1aWx0LnByZTtcbiAgICBpZiAoYnVpbHQuYmdDbGFzcyAhPSBsaW5lVmlldy5iZ0NsYXNzIHx8IGJ1aWx0LnRleHRDbGFzcyAhPSBsaW5lVmlldy50ZXh0Q2xhc3MpIHtcbiAgICAgIGxpbmVWaWV3LmJnQ2xhc3MgPSBidWlsdC5iZ0NsYXNzO1xuICAgICAgbGluZVZpZXcudGV4dENsYXNzID0gYnVpbHQudGV4dENsYXNzO1xuICAgICAgdXBkYXRlTGluZUNsYXNzZXMobGluZVZpZXcpO1xuICAgIH0gZWxzZSBpZiAoY2xzKSB7XG4gICAgICBsaW5lVmlldy50ZXh0LmNsYXNzTmFtZSA9IGNscztcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVMaW5lQ2xhc3NlcyhsaW5lVmlldykge1xuICAgIHVwZGF0ZUxpbmVCYWNrZ3JvdW5kKGxpbmVWaWV3KTtcbiAgICBpZiAobGluZVZpZXcubGluZS53cmFwQ2xhc3MpXG4gICAgICBlbnN1cmVMaW5lV3JhcHBlZChsaW5lVmlldykuY2xhc3NOYW1lID0gbGluZVZpZXcubGluZS53cmFwQ2xhc3M7XG4gICAgZWxzZSBpZiAobGluZVZpZXcubm9kZSAhPSBsaW5lVmlldy50ZXh0KVxuICAgICAgbGluZVZpZXcubm9kZS5jbGFzc05hbWUgPSBcIlwiO1xuICAgIHZhciB0ZXh0Q2xhc3MgPSBsaW5lVmlldy50ZXh0Q2xhc3MgPyBsaW5lVmlldy50ZXh0Q2xhc3MgKyBcIiBcIiArIChsaW5lVmlldy5saW5lLnRleHRDbGFzcyB8fCBcIlwiKSA6IGxpbmVWaWV3LmxpbmUudGV4dENsYXNzO1xuICAgIGxpbmVWaWV3LnRleHQuY2xhc3NOYW1lID0gdGV4dENsYXNzIHx8IFwiXCI7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVMaW5lR3V0dGVyKGNtLCBsaW5lVmlldywgbGluZU4sIGRpbXMpIHtcbiAgICBpZiAobGluZVZpZXcuZ3V0dGVyKSB7XG4gICAgICBsaW5lVmlldy5ub2RlLnJlbW92ZUNoaWxkKGxpbmVWaWV3Lmd1dHRlcik7XG4gICAgICBsaW5lVmlldy5ndXR0ZXIgPSBudWxsO1xuICAgIH1cbiAgICBpZiAobGluZVZpZXcuZ3V0dGVyQmFja2dyb3VuZCkge1xuICAgICAgbGluZVZpZXcubm9kZS5yZW1vdmVDaGlsZChsaW5lVmlldy5ndXR0ZXJCYWNrZ3JvdW5kKTtcbiAgICAgIGxpbmVWaWV3Lmd1dHRlckJhY2tncm91bmQgPSBudWxsO1xuICAgIH1cbiAgICBpZiAobGluZVZpZXcubGluZS5ndXR0ZXJDbGFzcykge1xuICAgICAgdmFyIHdyYXAgPSBlbnN1cmVMaW5lV3JhcHBlZChsaW5lVmlldyk7XG4gICAgICBsaW5lVmlldy5ndXR0ZXJCYWNrZ3JvdW5kID0gZWx0KFwiZGl2XCIsIG51bGwsIFwiQ29kZU1pcnJvci1ndXR0ZXItYmFja2dyb3VuZCBcIiArIGxpbmVWaWV3LmxpbmUuZ3V0dGVyQ2xhc3MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwibGVmdDogXCIgKyAoY20ub3B0aW9ucy5maXhlZEd1dHRlciA/IGRpbXMuZml4ZWRQb3MgOiAtZGltcy5ndXR0ZXJUb3RhbFdpZHRoKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwicHg7IHdpZHRoOiBcIiArIGRpbXMuZ3V0dGVyVG90YWxXaWR0aCArIFwicHhcIik7XG4gICAgICB3cmFwLmluc2VydEJlZm9yZShsaW5lVmlldy5ndXR0ZXJCYWNrZ3JvdW5kLCBsaW5lVmlldy50ZXh0KTtcbiAgICB9XG4gICAgdmFyIG1hcmtlcnMgPSBsaW5lVmlldy5saW5lLmd1dHRlck1hcmtlcnM7XG4gICAgaWYgKGNtLm9wdGlvbnMubGluZU51bWJlcnMgfHwgbWFya2Vycykge1xuICAgICAgdmFyIHdyYXAgPSBlbnN1cmVMaW5lV3JhcHBlZChsaW5lVmlldyk7XG4gICAgICB2YXIgZ3V0dGVyV3JhcCA9IGxpbmVWaWV3Lmd1dHRlciA9IGVsdChcImRpdlwiLCBudWxsLCBcIkNvZGVNaXJyb3ItZ3V0dGVyLXdyYXBwZXJcIiwgXCJsZWZ0OiBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY20ub3B0aW9ucy5maXhlZEd1dHRlciA/IGRpbXMuZml4ZWRQb3MgOiAtZGltcy5ndXR0ZXJUb3RhbFdpZHRoKSArIFwicHhcIik7XG4gICAgICBjbS5kaXNwbGF5LmlucHV0LnNldFVuZWRpdGFibGUoZ3V0dGVyV3JhcCk7XG4gICAgICB3cmFwLmluc2VydEJlZm9yZShndXR0ZXJXcmFwLCBsaW5lVmlldy50ZXh0KTtcbiAgICAgIGlmIChsaW5lVmlldy5saW5lLmd1dHRlckNsYXNzKVxuICAgICAgICBndXR0ZXJXcmFwLmNsYXNzTmFtZSArPSBcIiBcIiArIGxpbmVWaWV3LmxpbmUuZ3V0dGVyQ2xhc3M7XG4gICAgICBpZiAoY20ub3B0aW9ucy5saW5lTnVtYmVycyAmJiAoIW1hcmtlcnMgfHwgIW1hcmtlcnNbXCJDb2RlTWlycm9yLWxpbmVudW1iZXJzXCJdKSlcbiAgICAgICAgbGluZVZpZXcubGluZU51bWJlciA9IGd1dHRlcldyYXAuYXBwZW5kQ2hpbGQoXG4gICAgICAgICAgZWx0KFwiZGl2XCIsIGxpbmVOdW1iZXJGb3IoY20ub3B0aW9ucywgbGluZU4pLFxuICAgICAgICAgICAgICBcIkNvZGVNaXJyb3ItbGluZW51bWJlciBDb2RlTWlycm9yLWd1dHRlci1lbHRcIixcbiAgICAgICAgICAgICAgXCJsZWZ0OiBcIiArIGRpbXMuZ3V0dGVyTGVmdFtcIkNvZGVNaXJyb3ItbGluZW51bWJlcnNcIl0gKyBcInB4OyB3aWR0aDogXCJcbiAgICAgICAgICAgICAgKyBjbS5kaXNwbGF5LmxpbmVOdW1Jbm5lcldpZHRoICsgXCJweFwiKSk7XG4gICAgICBpZiAobWFya2VycykgZm9yICh2YXIgayA9IDA7IGsgPCBjbS5vcHRpb25zLmd1dHRlcnMubGVuZ3RoOyArK2spIHtcbiAgICAgICAgdmFyIGlkID0gY20ub3B0aW9ucy5ndXR0ZXJzW2tdLCBmb3VuZCA9IG1hcmtlcnMuaGFzT3duUHJvcGVydHkoaWQpICYmIG1hcmtlcnNbaWRdO1xuICAgICAgICBpZiAoZm91bmQpXG4gICAgICAgICAgZ3V0dGVyV3JhcC5hcHBlbmRDaGlsZChlbHQoXCJkaXZcIiwgW2ZvdW5kXSwgXCJDb2RlTWlycm9yLWd1dHRlci1lbHRcIiwgXCJsZWZ0OiBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltcy5ndXR0ZXJMZWZ0W2lkXSArIFwicHg7IHdpZHRoOiBcIiArIGRpbXMuZ3V0dGVyV2lkdGhbaWRdICsgXCJweFwiKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTGluZVdpZGdldHMoY20sIGxpbmVWaWV3LCBkaW1zKSB7XG4gICAgaWYgKGxpbmVWaWV3LmFsaWduYWJsZSkgbGluZVZpZXcuYWxpZ25hYmxlID0gbnVsbDtcbiAgICBmb3IgKHZhciBub2RlID0gbGluZVZpZXcubm9kZS5maXJzdENoaWxkLCBuZXh0OyBub2RlOyBub2RlID0gbmV4dCkge1xuICAgICAgdmFyIG5leHQgPSBub2RlLm5leHRTaWJsaW5nO1xuICAgICAgaWYgKG5vZGUuY2xhc3NOYW1lID09IFwiQ29kZU1pcnJvci1saW5ld2lkZ2V0XCIpXG4gICAgICAgIGxpbmVWaWV3Lm5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgfVxuICAgIGluc2VydExpbmVXaWRnZXRzKGNtLCBsaW5lVmlldywgZGltcyk7XG4gIH1cblxuICAvLyBCdWlsZCBhIGxpbmUncyBET00gcmVwcmVzZW50YXRpb24gZnJvbSBzY3JhdGNoXG4gIGZ1bmN0aW9uIGJ1aWxkTGluZUVsZW1lbnQoY20sIGxpbmVWaWV3LCBsaW5lTiwgZGltcykge1xuICAgIHZhciBidWlsdCA9IGdldExpbmVDb250ZW50KGNtLCBsaW5lVmlldyk7XG4gICAgbGluZVZpZXcudGV4dCA9IGxpbmVWaWV3Lm5vZGUgPSBidWlsdC5wcmU7XG4gICAgaWYgKGJ1aWx0LmJnQ2xhc3MpIGxpbmVWaWV3LmJnQ2xhc3MgPSBidWlsdC5iZ0NsYXNzO1xuICAgIGlmIChidWlsdC50ZXh0Q2xhc3MpIGxpbmVWaWV3LnRleHRDbGFzcyA9IGJ1aWx0LnRleHRDbGFzcztcblxuICAgIHVwZGF0ZUxpbmVDbGFzc2VzKGxpbmVWaWV3KTtcbiAgICB1cGRhdGVMaW5lR3V0dGVyKGNtLCBsaW5lVmlldywgbGluZU4sIGRpbXMpO1xuICAgIGluc2VydExpbmVXaWRnZXRzKGNtLCBsaW5lVmlldywgZGltcyk7XG4gICAgcmV0dXJuIGxpbmVWaWV3Lm5vZGU7XG4gIH1cblxuICAvLyBBIGxpbmVWaWV3IG1heSBjb250YWluIG11bHRpcGxlIGxvZ2ljYWwgbGluZXMgKHdoZW4gbWVyZ2VkIGJ5XG4gIC8vIGNvbGxhcHNlZCBzcGFucykuIFRoZSB3aWRnZXRzIGZvciBhbGwgb2YgdGhlbSBuZWVkIHRvIGJlIGRyYXduLlxuICBmdW5jdGlvbiBpbnNlcnRMaW5lV2lkZ2V0cyhjbSwgbGluZVZpZXcsIGRpbXMpIHtcbiAgICBpbnNlcnRMaW5lV2lkZ2V0c0ZvcihjbSwgbGluZVZpZXcubGluZSwgbGluZVZpZXcsIGRpbXMsIHRydWUpO1xuICAgIGlmIChsaW5lVmlldy5yZXN0KSBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVWaWV3LnJlc3QubGVuZ3RoOyBpKyspXG4gICAgICBpbnNlcnRMaW5lV2lkZ2V0c0ZvcihjbSwgbGluZVZpZXcucmVzdFtpXSwgbGluZVZpZXcsIGRpbXMsIGZhbHNlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc2VydExpbmVXaWRnZXRzRm9yKGNtLCBsaW5lLCBsaW5lVmlldywgZGltcywgYWxsb3dBYm92ZSkge1xuICAgIGlmICghbGluZS53aWRnZXRzKSByZXR1cm47XG4gICAgdmFyIHdyYXAgPSBlbnN1cmVMaW5lV3JhcHBlZChsaW5lVmlldyk7XG4gICAgZm9yICh2YXIgaSA9IDAsIHdzID0gbGluZS53aWRnZXRzOyBpIDwgd3MubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciB3aWRnZXQgPSB3c1tpXSwgbm9kZSA9IGVsdChcImRpdlwiLCBbd2lkZ2V0Lm5vZGVdLCBcIkNvZGVNaXJyb3ItbGluZXdpZGdldFwiKTtcbiAgICAgIGlmICghd2lkZ2V0LmhhbmRsZU1vdXNlRXZlbnRzKSBub2RlLnNldEF0dHJpYnV0ZShcImNtLWlnbm9yZS1ldmVudHNcIiwgXCJ0cnVlXCIpO1xuICAgICAgcG9zaXRpb25MaW5lV2lkZ2V0KHdpZGdldCwgbm9kZSwgbGluZVZpZXcsIGRpbXMpO1xuICAgICAgY20uZGlzcGxheS5pbnB1dC5zZXRVbmVkaXRhYmxlKG5vZGUpO1xuICAgICAgaWYgKGFsbG93QWJvdmUgJiYgd2lkZ2V0LmFib3ZlKVxuICAgICAgICB3cmFwLmluc2VydEJlZm9yZShub2RlLCBsaW5lVmlldy5ndXR0ZXIgfHwgbGluZVZpZXcudGV4dCk7XG4gICAgICBlbHNlXG4gICAgICAgIHdyYXAuYXBwZW5kQ2hpbGQobm9kZSk7XG4gICAgICBzaWduYWxMYXRlcih3aWRnZXQsIFwicmVkcmF3XCIpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHBvc2l0aW9uTGluZVdpZGdldCh3aWRnZXQsIG5vZGUsIGxpbmVWaWV3LCBkaW1zKSB7XG4gICAgaWYgKHdpZGdldC5ub0hTY3JvbGwpIHtcbiAgICAgIChsaW5lVmlldy5hbGlnbmFibGUgfHwgKGxpbmVWaWV3LmFsaWduYWJsZSA9IFtdKSkucHVzaChub2RlKTtcbiAgICAgIHZhciB3aWR0aCA9IGRpbXMud3JhcHBlcldpZHRoO1xuICAgICAgbm9kZS5zdHlsZS5sZWZ0ID0gZGltcy5maXhlZFBvcyArIFwicHhcIjtcbiAgICAgIGlmICghd2lkZ2V0LmNvdmVyR3V0dGVyKSB7XG4gICAgICAgIHdpZHRoIC09IGRpbXMuZ3V0dGVyVG90YWxXaWR0aDtcbiAgICAgICAgbm9kZS5zdHlsZS5wYWRkaW5nTGVmdCA9IGRpbXMuZ3V0dGVyVG90YWxXaWR0aCArIFwicHhcIjtcbiAgICAgIH1cbiAgICAgIG5vZGUuc3R5bGUud2lkdGggPSB3aWR0aCArIFwicHhcIjtcbiAgICB9XG4gICAgaWYgKHdpZGdldC5jb3Zlckd1dHRlcikge1xuICAgICAgbm9kZS5zdHlsZS56SW5kZXggPSA1O1xuICAgICAgbm9kZS5zdHlsZS5wb3NpdGlvbiA9IFwicmVsYXRpdmVcIjtcbiAgICAgIGlmICghd2lkZ2V0Lm5vSFNjcm9sbCkgbm9kZS5zdHlsZS5tYXJnaW5MZWZ0ID0gLWRpbXMuZ3V0dGVyVG90YWxXaWR0aCArIFwicHhcIjtcbiAgICB9XG4gIH1cblxuICAvLyBQT1NJVElPTiBPQkpFQ1RcblxuICAvLyBBIFBvcyBpbnN0YW5jZSByZXByZXNlbnRzIGEgcG9zaXRpb24gd2l0aGluIHRoZSB0ZXh0LlxuICB2YXIgUG9zID0gQ29kZU1pcnJvci5Qb3MgPSBmdW5jdGlvbihsaW5lLCBjaCkge1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBQb3MpKSByZXR1cm4gbmV3IFBvcyhsaW5lLCBjaCk7XG4gICAgdGhpcy5saW5lID0gbGluZTsgdGhpcy5jaCA9IGNoO1xuICB9O1xuXG4gIC8vIENvbXBhcmUgdHdvIHBvc2l0aW9ucywgcmV0dXJuIDAgaWYgdGhleSBhcmUgdGhlIHNhbWUsIGEgbmVnYXRpdmVcbiAgLy8gbnVtYmVyIHdoZW4gYSBpcyBsZXNzLCBhbmQgYSBwb3NpdGl2ZSBudW1iZXIgb3RoZXJ3aXNlLlxuICB2YXIgY21wID0gQ29kZU1pcnJvci5jbXBQb3MgPSBmdW5jdGlvbihhLCBiKSB7IHJldHVybiBhLmxpbmUgLSBiLmxpbmUgfHwgYS5jaCAtIGIuY2g7IH07XG5cbiAgZnVuY3Rpb24gY29weVBvcyh4KSB7cmV0dXJuIFBvcyh4LmxpbmUsIHguY2gpO31cbiAgZnVuY3Rpb24gbWF4UG9zKGEsIGIpIHsgcmV0dXJuIGNtcChhLCBiKSA8IDAgPyBiIDogYTsgfVxuICBmdW5jdGlvbiBtaW5Qb3MoYSwgYikgeyByZXR1cm4gY21wKGEsIGIpIDwgMCA/IGEgOiBiOyB9XG5cbiAgLy8gSU5QVVQgSEFORExJTkdcblxuICBmdW5jdGlvbiBlbnN1cmVGb2N1cyhjbSkge1xuICAgIGlmICghY20uc3RhdGUuZm9jdXNlZCkgeyBjbS5kaXNwbGF5LmlucHV0LmZvY3VzKCk7IG9uRm9jdXMoY20pOyB9XG4gIH1cblxuIC
23459BmdW5jdGlvbiBpc1JlYWRPbmx5KGNtKSB7XG4gICAgcmV0dXJuIGNtLm9wdGlvbnMucmVhZE9ubHkgfHwgY20uZG9jLmNhbnRFZGl0O1xuICB9XG5cbiAgLy8gVGhpcyB3aWxsIGJlIHNldCB0byBhbiBhcnJheSBvZiBzdHJpbmdzIHdoZW4gY29weWluZywgc28gdGhhdCxcbiAgLy8gd2hlbiBwYXN0aW5nLCB3ZSBrbm93IHdoYXQga2luZCBvZiBzZWxlY3Rpb25zIHRoZSBjb3BpZWQgdGV4dFxuICAvLyB3YXMgbWFkZSBvdXQgb2YuXG4gIHZhciBsYXN0Q29waWVkID0gbnVsbDtcblxuICBmdW5jdGlvbiBhcHBseVRleHRJbnB1dChjbSwgaW5zZXJ0ZWQsIGRlbGV0ZWQsIHNlbCwgb3JpZ2luKSB7XG4gICAgdmFyIGRvYyA9IGNtLmRvYztcbiAgICBjbS5kaXNwbGF5LnNoaWZ0ID0gZmFsc2U7XG4gICAgaWYgKCFzZWwpIHNlbCA9IGRvYy5zZWw7XG5cbiAgICB2YXIgcGFzdGUgPSBjbS5zdGF0ZS5wYXN0ZUluY29taW5nIHx8IG9yaWdpbiA9PSBcInBhc3RlXCI7XG4gICAgdmFyIHRleHRMaW5lcyA9IGRvYy5zcGxpdExpbmVzKGluc2VydGVkKSwgbXVsdGlQYXN0ZSA9IG51bGw7XG4gICAgLy8gV2hlbiBwYXNpbmcgTiBsaW5lcyBpbnRvIE4gc2VsZWN0aW9ucywgaW5zZXJ0IG9uZSBsaW5lIHBlciBzZWxlY3Rpb25cbiAgICBpZiAocGFzdGUgJiYgc2VsLnJhbmdlcy5sZW5ndGggPiAxKSB7XG4gICAgICBpZiAobGFzdENvcGllZCAmJiBsYXN0Q29waWVkLmpvaW4oXCJcXG5cIikgPT0gaW5zZXJ0ZWQpIHtcbiAgICAgICAgaWYgKHNlbC5yYW5nZXMubGVuZ3RoICUgbGFzdENvcGllZC5sZW5ndGggPT0gMCkge1xuICAgICAgICAgIG11bHRpUGFzdGUgPSBbXTtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxhc3RDb3BpZWQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBtdWx0aVBhc3RlLnB1c2goZG9jLnNwbGl0TGluZXMobGFzdENvcGllZFtpXSkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRleHRMaW5lcy5sZW5ndGggPT0gc2VsLnJhbmdlcy5sZW5ndGgpIHtcbiAgICAgICAgbXVsdGlQYXN0ZSA9IG1hcCh0ZXh0TGluZXMsIGZ1bmN0aW9uKGwpIHsgcmV0dXJuIFtsXTsgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gTm9ybWFsIGJlaGF2aW9yIGlzIHRvIGluc2VydCB0aGUgbmV3IHRleHQgaW50byBldmVyeSBzZWxlY3Rpb25cbiAgICBmb3IgKHZhciBpID0gc2VsLnJhbmdlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIHJhbmdlID0gc2VsLnJhbmdlc1tpXTtcbiAgICAgIHZhciBmcm9tID0gcmFuZ2UuZnJvbSgpLCB0byA9IHJhbmdlLnRvKCk7XG4gICAgICBpZiAocmFuZ2UuZW1wdHkoKSkge1xuICAgICAgICBpZiAoZGVsZXRlZCAmJiBkZWxldGVkID4gMCkgLy8gSGFuZGxlIGRlbGV0aW9uXG4gICAgICAgICAgZnJvbSA9IFBvcyhmcm9tLmxpbmUsIGZyb20uY2ggLSBkZWxldGVkKTtcbiAgICAgICAgZWxzZSBpZiAoY20uc3RhdGUub3ZlcndyaXRlICYmICFwYXN0ZSkgLy8gSGFuZGxlIG92ZXJ3cml0ZVxuICAgICAgICAgIHRvID0gUG9zKHRvLmxpbmUsIE1hdGgubWluKGdldExpbmUoZG9jLCB0by5saW5lKS50ZXh0Lmxlbmd0aCwgdG8uY2ggKyBsc3QodGV4dExpbmVzKS5sZW5ndGgpKTtcbiAgICAgIH1cbiAgICAgIHZhciB1cGRhdGVJbnB1dCA9IGNtLmN1ck9wLnVwZGF0ZUlucHV0O1xuICAgICAgdmFyIGNoYW5nZUV2ZW50ID0ge2Zyb206IGZyb20sIHRvOiB0bywgdGV4dDogbXVsdGlQYXN0ZSA/IG11bHRpUGFzdGVbaSAlIG11bHRpUGFzdGUubGVuZ3RoXSA6IHRleHRMaW5lcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW46IG9yaWdpbiB8fCAocGFzdGUgPyBcInBhc3RlXCIgOiBjbS5zdGF0ZS5jdXRJbmNvbWluZyA/IFwiY3V0XCIgOiBcIitpbnB1dFwiKX07XG4gICAgICBtYWtlQ2hhbmdlKGNtLmRvYywgY2hhbmdlRXZlbnQpO1xuICAgICAgc2lnbmFsTGF0ZXIoY20sIFwiaW5wdXRSZWFkXCIsIGNtLCBjaGFuZ2VFdmVudCk7XG4gICAgfVxuICAgIGlmIChpbnNlcnRlZCAmJiAhcGFzdGUpXG4gICAgICB0cmlnZ2VyRWxlY3RyaWMoY20sIGluc2VydGVkKTtcblxuICAgIGVuc3VyZUN1cnNvclZpc2libGUoY20pO1xuICAgIGNtLmN1ck9wLnVwZGF0ZUlucHV0ID0gdXBkYXRlSW5wdXQ7XG4gICAgY20uY3VyT3AudHlwaW5nID0gdHJ1ZTtcbiAgICBjbS5zdGF0ZS5wYXN0ZUluY29taW5nID0gY20uc3RhdGUuY3V0SW5jb21pbmcgPSBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZVBhc3RlKGUsIGNtKSB7XG4gICAgdmFyIHBhc3RlZCA9IGUuY2xpcGJvYXJkRGF0YSAmJiBlLmNsaXBib2FyZERhdGEuZ2V0RGF0YShcInRleHQvcGxhaW5cIik7XG4gICAgaWYgKHBhc3RlZCkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKCFpc1JlYWRPbmx5KGNtKSAmJiAhY20ub3B0aW9ucy5kaXNhYmxlSW5wdXQpXG4gICAgICAgIHJ1bkluT3AoY20sIGZ1bmN0aW9uKCkgeyBhcHBseVRleHRJbnB1dChjbSwgcGFzdGVkLCAwLCBudWxsLCBcInBhc3RlXCIpOyB9KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHRyaWdnZXJFbGVjdHJpYyhjbSwgaW5zZXJ0ZWQpIHtcbiAgICAvLyBXaGVuIGFuICdlbGVjdHJpYycgY2hhcmFjdGVyIGlzIGluc2VydGVkLCBpbW1lZGlhdGVseSB0cmlnZ2VyIGEgcmVpbmRlbnRcbiAgICBpZiAoIWNtLm9wdGlvbnMuZWxlY3RyaWNDaGFycyB8fCAhY20ub3B0aW9ucy5zbWFydEluZGVudCkgcmV0dXJuO1xuICAgIHZhciBzZWwgPSBjbS5kb2Muc2VsO1xuXG4gICAgZm9yICh2YXIgaSA9IHNlbC5yYW5nZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHZhciByYW5nZSA9IHNlbC5yYW5nZXNbaV07XG4gICAgICBpZiAocmFuZ2UuaGVhZC5jaCA+IDEwMCB8fCAoaSAmJiBzZWwucmFuZ2VzW2kgLSAxXS5oZWFkLmxpbmUgPT0gcmFuZ2UuaGVhZC5saW5lKSkgY29udGludWU7XG4gICAgICB2Y
23459XIgbW9kZSA9IGNtLmdldE1vZGVBdChyYW5nZS5oZWFkKTtcbiAgICAgIHZhciBpbmRlbnRlZCA9IGZhbHNlO1xuICAgICAgaWYgKG1vZGUuZWxlY3RyaWNDaGFycykge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1vZGUuZWxlY3RyaWNDaGFycy5sZW5ndGg7IGorKylcbiAgICAgICAgICBpZiAoaW5zZXJ0ZWQuaW5kZXhPZihtb2RlLmVsZWN0cmljQ2hhcnMuY2hhckF0KGopKSA+IC0xKSB7XG4gICAgICAgICAgICBpbmRlbnRlZCA9IGluZGVudExpbmUoY20sIHJhbmdlLmhlYWQubGluZSwgXCJzbWFydFwiKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobW9kZS5lbGVjdHJpY0lucHV0KSB7XG4gICAgICAgIGlmIChtb2RlLmVsZWN0cmljSW5wdXQudGVzdChnZXRMaW5lKGNtLmRvYywgcmFuZ2UuaGVhZC5saW5lKS50ZXh0LnNsaWNlKDAsIHJhbmdlLmhlYWQuY2gpKSlcbiAgICAgICAgICBpbmRlbnRlZCA9IGluZGVudExpbmUoY20sIHJhbmdlLmhlYWQubGluZSwgXCJzbWFydFwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChpbmRlbnRlZCkgc2lnbmFsTGF0ZXIoY20sIFwiZWxlY3RyaWNJbnB1dFwiLCBjbSwgcmFuZ2UuaGVhZC5saW5lKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjb3B5YWJsZVJhbmdlcyhjbSkge1xuICAgIHZhciB0ZXh0ID0gW10sIHJhbmdlcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY20uZG9jLnNlbC5yYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBsaW5lID0gY20uZG9jLnNlbC5yYW5nZXNbaV0uaGVhZC5saW5lO1xuICAgICAgdmFyIGxpbmVSYW5nZSA9IHthbmNob3I6IFBvcyhsaW5lLCAwKSwgaGVhZDogUG9zKGxpbmUgKyAxLCAwKX07XG4gICAgICByYW5nZXMucHVzaChsaW5lUmFuZ2UpO1xuICAgICAgdGV4dC5wdXNoKGNtLmdldFJhbmdlKGxpbmVSYW5nZS5hbmNob3IsIGxpbmVSYW5nZS5oZWFkKSk7XG4gICAgfVxuICAgIHJldHVybiB7dGV4dDogdGV4dCwgcmFuZ2VzOiByYW5nZXN9O1xuICB9XG5cbiAgZnVuY3Rpb24gZGlzYWJsZUJyb3dzZXJNYWdpYyhmaWVsZCkge1xuICAgIGZpZWxkLnNldEF0dHJpYnV0ZShcImF1dG9jb3JyZWN0XCIsIFwib2ZmXCIpO1xuICAgIGZpZWxkLnNldEF0dHJpYnV0ZShcImF1dG9jYXBpdGFsaXplXCIsIFwib2ZmXCIpO1xuICAgIGZpZWxkLnNldEF0dHJpYnV0ZShcInNwZWxsY2hlY2tcIiwgXCJmYWxzZVwiKTtcbiAgfVxuXG4gIC8vIFRFWFRBUkVBIElOUFVUIFNUWUxFXG5cbiAgZnVuY3Rpb24gVGV4dGFyZWFJbnB1dChjbSkge1xuICAgIHRoaXMuY20gPSBjbTtcbiAgICAvLyBTZWUgaW5wdXQucG9sbCBhbmQgaW5wdXQucmVzZXRcbiAgICB0aGlzLnByZXZJbnB1dCA9IFwiXCI7XG5cbiAgICAvLyBGbGFnIHRoYXQgaW5kaWNhdGVzIHdoZXRoZXIgd2UgZXhwZWN0IGlucHV0IHRvIGFwcGVhciByZWFsIHNvb25cbiAgICAvLyBub3cgKGFmdGVyIHNvbWUgZXZlbnQgbGlrZSAna2V5cHJlc3MnIG9yICdpbnB1dCcpIGFuZCBhcmVcbiAgICAvLyBwb2xsaW5nIGludGVuc2l2ZWx5LlxuICAgIHRoaXMucG9sbGluZ0Zhc3QgPSBmYWxzZTtcbiAgICAvLyBTZWxmLXJlc2V0dGluZyB0aW1lb3V0IGZvciB0aGUgcG9sbGVyXG4gICAgdGhpcy5wb2xsaW5nID0gbmV3IERlbGF5ZWQoKTtcbiAgICAvLyBUcmFja3Mgd2hlbiBpbnB1dC5yZXNldCBoYXMgcHVudGVkIHRvIGp1c3QgcHV0dGluZyBhIHNob3J0XG4gICAgLy8gc3RyaW5nIGludG8gdGhlIHRleHRhcmVhIGluc3RlYWQgb2YgdGhlIGZ1bGwgc2VsZWN0aW9uLlxuICAgIHRoaXMuaW5hY2N1cmF0ZVNlbGVjdGlvbiA9IGZhbHNlO1xuICAgIC8vIFVzZWQgdG8gd29yayBhcm91bmQgSUUgaXNzdWUgd2l0aCBzZWxlY3Rpb24gYmVpbmcgZm9yZ290dGVuIHdoZW4gZm9jdXMgbW92ZXMgYXdheSBmcm9tIHRleHRhcmVhXG4gICAgdGhpcy5oYXNTZWxlY3Rpb24gPSBmYWxzZTtcbiAgICB0aGlzLmNvbXBvc2luZyA9IG51bGw7XG4gIH07XG5cbiAgZnVuY3Rpb24gaGlkZGVuVGV4dGFyZWEoKSB7XG4gICAgdmFyIHRlID0gZWx0KFwidGV4dGFyZWFcIiwgbnVsbCwgbnVsbCwgXCJwb3NpdGlvbjogYWJzb2x1dGU7IHBhZGRpbmc6IDA7IHdpZHRoOiAxcHg7IGhlaWdodDogMWVtOyBvdXRsaW5lOiBub25lXCIpO1xuICAgIHZhciBkaXYgPSBlbHQoXCJkaXZcIiwgW3RlXSwgbnVsbCwgXCJvdmVyZmxvdzogaGlkZGVuOyBwb3NpdGlvbjogcmVsYXRpdmU7IHdpZHRoOiAzcHg7IGhlaWdodDogMHB4O1wiKTtcbiAgICAvLyBUaGUgdGV4dGFyZWEgaXMga2VwdCBwb3NpdGlvbmVkIG5lYXIgdGhlIGN1cnNvciB0byBwcmV2ZW50IHRoZVxuICAgIC8vIGZhY3QgdGhhdCBpdCdsbCBiZSBzY3JvbGxlZCBpbnRvIHZpZXcgb24gaW5wdXQgZnJvbSBzY3JvbGxpbmdcbiAgICAvLyBvdXIgZmFrZSBjdXJzb3Igb3V0IG9mIHZpZXcuIE9uIHdlYmtpdCwgd2hlbiB3cmFwPW9mZiwgcGFzdGUgaXNcbiAgICAvLyB2ZXJ5IHNsb3cuIFNvIG1ha2UgdGhlIGFyZWEgd2lkZSBpbnN0ZWFkLlxuICAgIGlmICh3ZWJraXQpIHRlLnN0eWxlLndpZHRoID0gXCIxMDAwcHhcIjtcbiAgICBlbHNlIHRlLnNldEF0dHJpYnV0ZShcIndyYXBcIiwgXCJvZmZcIik7XG4gICAgLy8gSWYgYm9yZGVyOiAwOyAtLSBpT1MgZmFpbHMgdG8gb3BlbiBrZXlib2FyZCAoaXNzdWUgIzEyODcpXG4gICAgaWYgKGlvcykgdGUuc3R5bGUuYm9yZGVyID0gXCIxcHggc29saWQgYmxhY2tcIjtcbiAgICBkaXNhYmxlQnJvd3Nlck1hZ2ljKHRlKTtcbiAgICByZXR1cm4gZGl2O1xuICB9XG5cbiAgVGV4dGFyZWFJbnB1dC5wcm90b3R5cGUgPSBjb3B5T2JqKHtcbiAgICBpbml0OiBmdW5jdGlvbihkaXNwbGF5KSB7XG4gICAgICB2Y
23459XIgaW5wdXQgPSB0aGlzLCBjbSA9IHRoaXMuY207XG5cbiAgICAgIC8vIFdyYXBzIGFuZCBoaWRlcyBpbnB1dCB0ZXh0YXJlYVxuICAgICAgdmFyIGRpdiA9IHRoaXMud3JhcHBlciA9IGhpZGRlblRleHRhcmVhKCk7XG4gICAgICAvLyBUaGUgc2VtaWhpZGRlbiB0ZXh0YXJlYSB0aGF0IGlzIGZvY3VzZWQgd2hlbiB0aGUgZWRpdG9yIGlzXG4gICAgICAvLyBmb2N1c2VkLCBhbmQgcmVjZWl2ZXMgaW5wdXQuXG4gICAgICB2YXIgdGUgPSB0aGlzLnRleHRhcmVhID0gZGl2LmZpcnN0Q2hpbGQ7XG4gICAgICBkaXNwbGF5LndyYXBwZXIuaW5zZXJ0QmVmb3JlKGRpdiwgZGlzcGxheS53cmFwcGVyLmZpcnN0Q2hpbGQpO1xuXG4gICAgICAvLyBOZWVkZWQgdG8gaGlkZSBiaWcgYmx1ZSBibGlua2luZyBjdXJzb3Igb24gTW9iaWxlIFNhZmFyaSAoZG9lc24ndCBzZWVtIHRvIHdvcmsgaW4gaU9TIDggYW55bW9yZSlcbiAgICAgIGlmIChpb3MpIHRlLnN0eWxlLndpZHRoID0gXCIwcHhcIjtcblxuICAgICAgb24odGUsIFwiaW5wdXRcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uID49IDkgJiYgaW5wdXQuaGFzU2VsZWN0aW9uKSBpbnB1dC5oYXNTZWxlY3Rpb24gPSBudWxsO1xuICAgICAgICBpbnB1dC5wb2xsKCk7XG4gICAgICB9KTtcblxuICAgICAgb24odGUsIFwicGFzdGVcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgICBpZiAoaGFuZGxlUGFzdGUoZSwgY20pKSByZXR1cm4gdHJ1ZTtcblxuICAgICAgICBjbS5zdGF0ZS5wYXN0ZUluY29taW5nID0gdHJ1ZTtcbiAgICAgICAgaW5wdXQuZmFzdFBvbGwoKTtcbiAgICAgIH0pO1xuXG4gICAgICBmdW5jdGlvbiBwcmVwYXJlQ29weUN1dChlKSB7XG4gICAgICAgIGlmIChjbS5zb21ldGhpbmdTZWxlY3RlZCgpKSB7XG4gICAgICAgICAgbGFzdENvcGllZCA9IGNtLmdldFNlbGVjdGlvbnMoKTtcbiAgICAgICAgICBpZiAoaW5wdXQuaW5hY2N1cmF0ZVNlbGVjdGlvbikge1xuICAgICAgICAgICAgaW5wdXQucHJldklucHV0ID0gXCJcIjtcbiAgICAgICAgICAgIGlucHV0LmluYWNjdXJhdGVTZWxlY3Rpb24gPSBmYWxzZTtcbiAgICAgICAgICAgIHRlLnZhbHVlID0gbGFzdENvcGllZC5qb2luKFwiXFxuXCIpO1xuICAgICAgICAgICAgc2VsZWN0SW5wdXQodGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghY20ub3B0aW9ucy5saW5lV2lzZUNvcHlDdXQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHJhbmdlcyA9IGNvcHlhYmxlUmFuZ2VzKGNtKTtcbiAgICAgICAgICBsYXN0Q29waWVkID0gcmFuZ2VzLnRleHQ7XG4gICAgICAgICAgaWYgKGUudHlwZSA9PSBcImN1dFwiKSB7XG4gICAgICAgICAgICBjbS5zZXRTZWxlY3Rpb25zKHJhbmdlcy5yYW5nZXMsIG51bGwsIHNlbF9kb250U2Nyb2xsKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5wdXQucHJldklucHV0ID0gXCJcIjtcbiAgICAgICAgICAgIHRlLnZhbHVlID0gcmFuZ2VzLnRleHQuam9pbihcIlxcblwiKTtcbiAgICAgICAgICAgIHNlbGVjdElucHV0KHRlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGUudHlwZSA9PSBcImN1dFwiKSBjbS5zdGF0ZS5jdXRJbmNvbWluZyA9IHRydWU7XG4gICAgICB9XG4gICAgICBvbih0ZSwgXCJjdXRcIiwgcHJlcGFyZUNvcHlDdXQpO1xuICAgICAgb24odGUsIFwiY29weVwiLCBwcmVwYXJlQ29weUN1dCk7XG5cbiAgICAgIG9uKGRpc3BsYXkuc2Nyb2xsZXIsIFwicGFzdGVcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgICBpZiAoZXZlbnRJbldpZGdldChkaXNwbGF5LCBlKSkgcmV0dXJuO1xuICAgICAgICBjbS5zdGF0ZS5wYXN0ZUluY29taW5nID0gdHJ1ZTtcbiAgICAgICAgaW5wdXQuZm9jdXMoKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBQcmV2ZW50IG5vcm1hbCBzZWxlY3Rpb24gaW4gdGhlIGVkaXRvciAod2UgaGFuZGxlIG91ciBvd24pXG4gICAgICBvbihkaXNwbGF5LmxpbmVTcGFjZSwgXCJzZWxlY3RzdGFydFwiLCBmdW5jdGlvbihlKSB7XG4gICAgICAgIGlmICghZXZlbnRJbldpZGdldChkaXNwbGF5LCBlKSkgZV9wcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgIH0pO1xuXG4gICAgICBvbih0ZSwgXCJjb21wb3NpdGlvbnN0YXJ0XCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICB2Y
23459XIgc3RhcnQgPSBjbS5nZXRDdXJzb3IoXCJmcm9tXCIpO1xuICAgICAgICBpZiAoaW5wdXQuY29tcG9zaW5nKSBpbnB1dC5jb21wb3NpbmcucmFuZ2UuY2xlYXIoKVxuICAgICAgICBpbnB1dC5jb21wb3NpbmcgPSB7XG4gICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgIHJhbmdlOiBjbS5tYXJrVGV4dChzdGFydCwgY20uZ2V0Q3Vyc29yKFwidG9cIiksIHtjbGFzc05hbWU6IFwiQ29kZU1pcnJvci1jb21wb3NpbmdcIn0pXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICAgIG9uKHRlLCBcImNvbXBvc2l0aW9uZW5kXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoaW5wdXQuY29tcG9zaW5nKSB7XG4gICAgICAgICAgaW5wdXQucG9sbCgpO1xuICAgICAgICAgIGlucHV0LmNvbXBvc2luZy5yYW5nZS5jbGVhcigpO1xuICAgICAgICAgIGlucHV0LmNvbXBvc2luZyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBwcmVwYXJlU2VsZWN0aW9uOiBmdW5jdGlvbigpIHtcbiAgICAgIC8vIFJlZHJhdyB0aGUgc2VsZWN0aW9uIGFuZC9vciBjdXJzb3JcbiAgICAgIHZhciBjbSA9IHRoaXMuY20sIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCBkb2MgPSBjbS5kb2M7XG4gICAgICB2YXIgcmVzdWx0ID0gcHJlcGFyZVNlbGVjdGlvbihjbSk7XG5cbiAgICAgIC8vIE1vdmUgdGhlIGhpZGRlbiB0ZXh0YXJlYSBuZWFyIHRoZSBjdXJzb3IgdG8gcHJldmVudCBzY3JvbGxpbmcgYXJ0aWZhY3RzXG4gICAgICBpZiAoY20ub3B0aW9ucy5tb3ZlSW5wdXRXaXRoQ3Vyc29yKSB7XG4gICAgICAgIHZhciBoZWFkUG9zID0gY3Vyc29yQ29vcmRzKGNtLCBkb2Muc2VsLnByaW1hcnkoKS5oZWFkLCBcImRpdlwiKTtcbiAgICAgICAgdmFyIHdyYXBPZmYgPSBkaXNwbGF5LndyYXBwZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksIGxpbmVPZmYgPSBkaXNwbGF5LmxpbmVEaXYuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHJlc3VsdC50ZVRvcCA9IE1hdGgubWF4KDAsIE1hdGgubWluKGRpc3BsYXkud3JhcHBlci5jbGllbnRIZWlnaHQgLSAxMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZFBvcy50b3AgKyBsaW5lT2ZmLnRvcCAtIHdyYXBPZmYudG9wKSk7XG4gICAgICAgIHJlc3VsdC50ZUxlZnQgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihkaXNwbGF5LndyYXBwZXIuY2xpZW50V2lkdGggLSAxMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRQb3MubGVmdCArIGxpbmVPZmYubGVmdCAtIHdyYXBPZmYubGVmdCkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG5cbiAgICBzaG93U2VsZWN0aW9uOiBmdW5jdGlvbihkcmF3bikge1xuICAgICAgdmFyIGNtID0gdGhpcy5jbSwgZGlzcGxheSA9IGNtLmRpc3BsYXk7XG4gICAgICByZW1vdmVDaGlsZHJlbkFuZEFkZChkaXNwbGF5LmN1cnNvckRpdiwgZHJhd24uY3Vyc29ycyk7XG4gICAgICByZW1vdmVDaGlsZHJlbkFuZEFkZChkaXNwbGF5LnNlbGVjdGlvbkRpdiwgZHJhd24uc2VsZWN0aW9uKTtcbiAgICAgIGlmIChkcmF3bi50ZVRvcCAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMud3JhcHBlci5zdHlsZS50b3AgPSBkcmF3bi50ZVRvcCArIFwicHhcIjtcbiAgICAgICAgdGhpcy53cmFwcGVyLnN0eWxlLmxlZnQgPSBkcmF3bi50ZUxlZnQgKyBcInB4XCI7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8vIFJlc2V0IHRoZSBpbnB1dCB0byBjb3JyZXNwb25kIHRvIHRoZSBzZWxlY3Rpb24gKG9yIHRvIGJlIGVtcHR5LFxuICAgIC8vIHdoZW4gbm90IHR5cGluZyBhbmQgbm90aGluZyBpcyBzZWxlY3RlZClcbiAgICByZXNldDogZnVuY3Rpb24odHlwaW5nKSB7XG4gICAgICBpZiAodGhpcy5jb250ZXh0TWVudVBlbmRpbmcpIHJldHVybjtcbiAgICAgIHZhciBtaW5pbWFsLCBzZWxlY3RlZCwgY20gPSB0aGlzLmNtLCBkb2MgPSBjbS5kb2M7XG4gICAgICBpZiAoY20uc29tZXRoaW5nU2VsZWN0ZWQoKSkge1xuICAgICAgICB0aGlzLnByZXZJbnB1dCA9IFwiXCI7XG4gICAgICAgIHZhciByYW5nZSA9IGRvYy5zZWwucHJpbWFyeSgpO1xuICAgICAgICBtaW5pbWFsID0gaGFzQ29weUV2ZW50ICYmXG4gICAgICAgICAgKHJhbmdlLnRvKCkubGluZSAtIHJhbmdlLmZyb20oKS5saW5lID4gMTAwIHx8IChzZWxlY3RlZCA9IGNtLmdldFNlbGVjdGlvbigpKS5sZW5ndGggPiAxMDAwKTtcbiAgICAgICAgdmFyIGNvbnRlbnQgPSBtaW5pbWFsID8gXCItXCIgOiBzZWxlY3RlZCB8fCBjbS5nZXRTZWxlY3Rpb24oKTtcbiAgICAgICAgdGhpcy50ZXh0YXJlYS52YWx1ZSA9IGNvbnRlbnQ7XG4gICAgICAgIGlmIChjbS5zdGF0ZS5mb2N1c2VkKSBzZWxlY3RJbnB1dCh0aGlzLnRleHRhcmVhKTtcbiAgICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPj0gOSkgdGhpcy5oYXNTZWxlY3Rpb24gPSBjb250ZW50O1xuICAgICAgfSBlbHNlIGlmICghdHlwaW5nKSB7XG4gICAgICAgIHRoaXMucHJldklucHV0ID0gdGhpcy50ZXh0YXJlYS52YWx1ZSA9IFwiXCI7XG4gICAgICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uID49IDkpIHRoaXMuaGFzU2VsZWN0aW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHRoaXMuaW5hY2N1cmF0ZVNlbGVjdGlvbiA9IG1pbmltYWw7XG4gICAgfSxcblxuICAgIGdldEZpZWxkOiBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMudGV4dGFyZWE7IH0sXG5cbiAgICBzdXBwb3J0c1RvdWNoOiBmdW5jdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9LFxuXG4gICAgZm9jdXM6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuY20ub3B0aW9ucy5yZWFkT25seSAhPSBcIm5vY3Vyc29yXCIgJiYgKCFtb2JpbGUgfHwgYWN0aXZlRWx0KCkgIT0gdGhpcy50ZXh0YXJlYSkpIHtcbiAgICAgICAgdHJ5IHsgdGhpcy50ZXh0YXJlYS5mb2N1cygpOyB9XG4gICAgICAgIGNhdGNoIChlKSB7fSAvLyBJRTggd2lsbCB0aHJvdyBpZiB0aGUgdGV4dGFyZWEgaXMgZGlzcGxheTogbm9uZSBvciBub3QgaW4gRE9NXG4gICAgICB9XG4gICAgfSxcblxuICAgIGJsdXI6IGZ1bmN0aW9uKCkgeyB0aGlzLnRleHRhcmVhLmJsdXIoKTsgfSxcblxuICAgI
23459HJlc2V0UG9zaXRpb246IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy53cmFwcGVyLnN0eWxlLnRvcCA9IHRoaXMud3JhcHBlci5zdHlsZS5sZWZ0ID0gMDtcbiAgICB9LFxuXG4gICAgcmVjZWl2ZWRGb2N1czogZnVuY3Rpb24oKSB7IHRoaXMuc2xvd1BvbGwoKTsgfSxcblxuICAgIC8vIFBvbGwgZm9yIGlucHV0IGNoYW5nZXMsIHVzaW5nIHRoZSBub3JtYWwgcmF0ZSBvZiBwb2xsaW5nLiBUaGlzXG4gICAgLy8gcnVucyBhcyBsb25nIGFzIHRoZSBlZGl0b3IgaXMgZm9jdXNlZC5cbiAgICBzbG93UG9sbDogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaW5wdXQgPSB0aGlzO1xuICAgICAgaWYgKGlucHV0LnBvbGxpbmdGYXN0KSByZXR1cm47XG4gICAgICBpbnB1dC5wb2xsaW5nLnNldCh0aGlzLmNtLm9wdGlvbnMucG9sbEludGVydmFsLCBmdW5jdGlvbigpIHtcbiAgICAgICAgaW5wdXQucG9sbCgpO1xuICAgICAgICBpZiAoaW5wdXQuY20uc3RhdGUuZm9jdXNlZCkgaW5wdXQuc2xvd1BvbGwoKTtcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICAvLyBXaGVuIGFuIGV2ZW50IGhhcyBqdXN0IGNvbWUgaW4gdGhhdCBpcyBsaWtlbHkgdG8gYWRkIG9yIGNoYW5nZVxuICAgIC8vIHNvbWV0aGluZyBpbiB0aGUgaW5wdXQgdGV4dGFyZWEsIHdlIHBvbGwgZmFzdGVyLCB0byBlbnN1cmUgdGhhdFxuICAgIC8vIHRoZSBjaGFuZ2UgYXBwZWFycyBvbiB0aGUgc2NyZWVuIHF1aWNrbHkuXG4gICAgZmFzdFBvbGw6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG1pc3NlZCA9IGZhbHNlLCBpbnB1dCA9IHRoaXM7XG4gICAgICBpbnB1dC5wb2xsaW5nRmFzdCA9IHRydWU7XG4gICAgICBmdW5jdGlvbiBwKCkge1xuICAgICAgICB2Y
23459XIgY2hhbmdlZCA9IGlucHV0LnBvbGwoKTtcbiAgICAgICAgaWYgKCFjaGFuZ2VkICYmICFtaXNzZWQpIHttaXNzZWQgPSB0cnVlOyBpbnB1dC5wb2xsaW5nLnNldCg2MCwgcCk7fVxuICAgICAgICBlbHNlIHtpbnB1dC5wb2xsaW5nRmFzdCA9IGZhbHNlOyBpbnB1dC5zbG93UG9sbCgpO31cbiAgICAgIH1cbiAgICAgIGlucHV0LnBvbGxpbmcuc2V0KDIwLCBwKTtcbiAgICB9LFxuXG4gICAgLy8gUmVhZCBpbnB1dCBmcm9tIHRoZSB0ZXh0YXJlYSwgYW5kIHVwZGF0ZSB0aGUgZG9jdW1lbnQgdG8gbWF0Y2guXG4gICAgLy8gV2hlbiBzb21ldGhpbmcgaXMgc2VsZWN0ZWQsIGl0IGlzIHByZXNlbnQgaW4gdGhlIHRleHRhcmVhLCBhbmRcbiAgICAvLyBzZWxlY3RlZCAodW5sZXNzIGl0IGlzIGh1Z2UsIGluIHdoaWNoIGNhc2UgYSBwbGFjZWhvbGRlciBpc1xuICAgIC8vIHVzZWQpLiBXaGVuIG5vdGhpbmcgaXMgc2VsZWN0ZWQsIHRoZSBjdXJzb3Igc2l0cyBhZnRlciBwcmV2aW91c2x5XG4gICAgLy8gc2VlbiB0ZXh0IChjYW4gYmUgZW1wdHkpLCB3aGljaCBpcyBzdG9yZWQgaW4gcHJldklucHV0ICh3ZSBtdXN0XG4gICAgLy8gbm90IHJlc2V0IHRoZSB0ZXh0YXJlYSB3aGVuIHR5cGluZywgYmVjYXVzZSB0aGF0IGJyZWFrcyBJTUUpLlxuICAgIHBvbGw6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGNtID0gdGhpcy5jbSwgaW5wdXQgPSB0aGlzLnRleHRhcmVhLCBwcmV2SW5wdXQgPSB0aGlzLnByZXZJbnB1dDtcbiAgICAgIC8vIFNpbmNlIHRoaXMgaXMgY2FsbGVkIGEgKmxvdCosIHRyeSB0byBiYWlsIG91dCBhcyBjaGVhcGx5IGFzXG4gICAgICAvLyBwb3NzaWJsZSB3aGVuIGl0IGlzIGNsZWFyIHRoYXQgbm90aGluZyBoYXBwZW5lZC4gaGFzU2VsZWN0aW9uXG4gICAgICAvLyB3aWxsIGJlIHRoZSBjYXNlIHdoZW4gdGhlcmUgaXMgYSBsb3Qgb2YgdGV4dCBpbiB0aGUgdGV4dGFyZWEsXG4gICAgICAvLyBpbiB3aGljaCBjYXNlIHJlYWRpbmcgaXRzIHZhbHVlIHdvdWxkIGJlIGV4cGVuc2l2ZS5cbiAgICAgIGlmICh0aGlzLmNvbnRleHRNZW51UGVuZGluZyB8fCAhY20uc3RhdGUuZm9jdXNlZCB8fFxuICAgICAgICAgIChoYXNTZWxlY3Rpb24oaW5wdXQpICYmICFwcmV2SW5wdXQgJiYgIXRoaXMuY29tcG9zaW5nKSB8fFxuICAgICAgICAgIGlzUmVhZE9ubHkoY20pIHx8IGNtLm9wdGlvbnMuZGlzYWJsZUlucHV0IHx8IGNtLnN0YXRlLmtleVNlcSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICB2Y
23459XIgdGV4dCA9IGlucHV0LnZhbHVlO1xuICAgICAgLy8gSWYgbm90aGluZyBjaGFuZ2VkLCBiYWlsLlxuICAgICAgaWYgKHRleHQgPT0gcHJldklucHV0ICYmICFjbS5zb21ldGhpbmdTZWxlY3RlZCgpKSByZXR1cm4gZmFsc2U7XG4gICAgICAvLyBXb3JrIGFyb3VuZCBub25zZW5zaWNhbCBzZWxlY3Rpb24gcmVzZXR0aW5nIGluIElFOS8xMCwgYW5kXG4gICAgICAvLyBpbmV4cGxpY2FibGUgYXBwZWFyYW5jZSBvZiBwcml2YXRlIGFyZWEgdW5pY29kZSBjaGFyYWN0ZXJzIG9uXG4gICAgICAvLyBzb21lIGtleSBjb21ib3MgaW4gTWFjICgjMjY4OSkuXG4gICAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA+PSA5ICYmIHRoaXMuaGFzU2VsZWN0aW9uID09PSB0ZXh0IHx8XG4gICAgICAgICAgbWFjICYmIC9bXFx1ZjcwMC1cXHVmN2ZmXS8udGVzdCh0ZXh0KSkge1xuICAgICAgICBjbS5kaXNwbGF5LmlucHV0LnJlc2V0KCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNtLmRvYy5zZWwgPT0gY20uZGlzcGxheS5zZWxGb3JDb250ZXh0TWVudSkge1xuICAgICAgICB2YXIgZmlyc3QgPSB0ZXh0LmNoYXJDb2RlQXQoMCk7XG4gICAgICAgIGlmIChmaXJzdCA9PSAweDIwMGIgJiYgIXByZXZJbnB1dCkgcHJldklucHV0ID0gXCJcXHUyMDBiXCI7XG4gICAgICAgIGlmIChmaXJzdCA9PSAweDIxZGEpIHsgdGhpcy5yZXNldCgpOyByZXR1cm4gdGhpcy5jbS5leGVjQ29tbWFuZChcInVuZG9cIik7IH1cbiAgICAgIH1cbiAgICAgIC8vIEZpbmQgdGhlIHBhcnQgb2YgdGhlIGlucHV0IHRoYXQgaXMgYWN0dWFsbHkgbmV3XG4gICAgICB2Y
23459XIgc2FtZSA9IDAsIGwgPSBNYXRoLm1pbihwcmV2SW5wdXQubGVuZ3RoLCB0ZXh0Lmxlbmd0aCk7XG4gICAgICB3aGlsZSAoc2FtZSA8IGwgJiYgcHJldklucHV0LmNoYXJDb2RlQXQoc2FtZSkgPT0gdGV4dC5jaGFyQ29kZUF0KHNhbWUpKSArK3NhbWU7XG5cbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIHJ1bkluT3AoY20sIGZ1bmN0aW9uKCkge1xuICAgICAgICBhcHBseVRleHRJbnB1dChjbSwgdGV4dC5zbGljZShzYW1lKSwgcHJldklucHV0Lmxlbmd0aCAtIHNhbWUsXG4gICAgICAgICAgICAgICAgICAgICAgIG51bGwsIHNlbGYuY29tcG9zaW5nID8gXCIqY29tcG9zZVwiIDogbnVsbCk7XG5cbiAgICAgICAgLy8gRG9uJ3QgbGVhdmUgbG9uZyB0ZXh0IGluIHRoZSB0ZXh0YXJlYSwgc2luY2UgaXQgbWFrZXMgZnVydGhlciBwb2xsaW5nIHNsb3dcbiAgICAgICAgaWYgKHRleHQubGVuZ3RoID4gMTAwMCB8fCB0ZXh0LmluZGV4T2YoXCJcXG5cIikgPiAtMSkgaW5wdXQudmFsdWUgPSBzZWxmLnByZXZJbnB1dCA9IFwiXCI7XG4gICAgICAgIGVsc2Ugc2VsZi5wcmV2SW5wdXQgPSB0ZXh0O1xuXG4gICAgICAgIGlmIChzZWxmLmNvbXBvc2luZykge1xuICAgICAgICAgIHNlbGYuY29tcG9zaW5nLnJhbmdlLmNsZWFyKCk7XG4gICAgICAgICAgc2VsZi5jb21wb3NpbmcucmFuZ2UgPSBjbS5tYXJrVGV4dChzZWxmLmNvbXBvc2luZy5zdGFydCwgY20uZ2V0Q3Vyc29yKFwidG9cIiksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2xhc3NOYW1lOiBcIkNvZGVNaXJyb3ItY29tcG9zaW5nXCJ9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuXG4gICAgZW5zdXJlUG9sbGVkOiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLnBvbGxpbmdGYXN0ICYmIHRoaXMucG9sbCgpKSB0aGlzLnBvbGxpbmdGYXN0ID0gZmFsc2U7XG4gICAgfSxcblxuICAgIG9uS2V5UHJlc3M6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPj0gOSkgdGhpcy5oYXNTZWxlY3Rpb24gPSBudWxsO1xuICAgICAgdGhpcy5mYXN0UG9sbCgpO1xuICAgIH0sXG5cbiAgICBvbkNvbnRleHRNZW51OiBmdW5jdGlvbihlKSB7XG4gICAgICB2Y
23459XIgaW5wdXQgPSB0aGlzLCBjbSA9IGlucHV0LmNtLCBkaXNwbGF5ID0gY20uZGlzcGxheSwgdGUgPSBpbnB1dC50ZXh0YXJlYTtcbiAgICAgIHZhciBwb3MgPSBwb3NGcm9tTW91c2UoY20sIGUpLCBzY3JvbGxQb3MgPSBkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbFRvcDtcbiAgICAgIGlmICghcG9zIHx8IHByZXN0bykgcmV0dXJuOyAvLyBPcGVyYSBpcyBkaWZmaWN1bHQuXG5cbiAgICAgIC8vIFJlc2V0IHRoZSBjdXJyZW50IHRleHQgc2VsZWN0aW9uIG9ubHkgaWYgdGhlIGNsaWNrIGlzIGRvbmUgb3V0c2lkZSBvZiB0aGUgc2VsZWN0aW9uXG4gICAgICAvLyBhbmQgJ3Jlc2V0U2VsZWN0aW9uT25Db250ZXh0TWVudScgb3B0aW9uIGlzIHRydWUuXG4gICAgICB2YXIgcmVzZXQgPSBjbS5vcHRpb25zLnJlc2V0U2VsZWN0aW9uT25Db250ZXh0TWVudTtcbiAgICAgIGlmIChyZXNldCAmJiBjbS5kb2Muc2VsLmNvbnRhaW5zKHBvcykgPT0gLTEpXG4gICAgICAgIG9wZXJhdGlvbihjbSwgc2V0U2VsZWN0aW9uKShjbS5kb2MsIHNpbXBsZVNlbGVjdGlvbihwb3MpLCBzZWxfZG9udFNjcm9sbCk7XG5cbiAgICAgIHZhciBvbGRDU1MgPSB0ZS5zdHlsZS5jc3NUZXh0O1xuICAgICAgaW5wdXQud3JhcHBlci5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICAgIHRlLnN0eWxlLmNzc1RleHQgPSBcInBvc2l0aW9uOiBmaXhlZDsgd2lkdGg6IDMwcHg7IGhlaWdodDogMzBweDsgdG9wOiBcIiArIChlLmNsaWVudFkgLSA1KSArXG4gICAgICAgIFwicHg7IGxlZnQ6IFwiICsgKGUuY2xpZW50WCAtIDUpICsgXCJweDsgei1pbmRleDogMTAwMDsgYmFja2dyb3VuZDogXCIgK1xuICAgICAgICAoaWUgPyBcInJnYmEoMjU1LCAyNTUsIDI1NSwgLjA1KVwiIDogXCJ0cmFuc3BhcmVudFwiKSArXG4gICAgICAgIFwiOyBvdXRsaW5lOiBub25lOyBib3JkZXItd2lkdGg6IDA7IG91dGxpbmU6IG5vbmU7IG92ZXJmbG93OiBoaWRkZW47IG9wYWNpdHk6IC4wNTsgZmlsdGVyOiBhbHBoYShvcGFjaXR5PTUpO1wiO1xuICAgICAgaWYgKHdlYmtpdCkgdmFyIG9sZFNjcm9sbFkgPSB3aW5kb3cuc2Nyb2xsWTsgLy8gV29yayBhcm91bmQgQ2hyb21lIGlzc3VlICgjMjcxMilcbiAgICAgIGRpc3BsYXkuaW5wdXQuZm9jdXMoKTtcbiAgICAgIGlmICh3ZWJraXQpIHdpbmRvdy5zY3JvbGxUbyhudWxsLCBvbGRTY3JvbGxZKTtcbiAgICAgIGRpc3BsYXkuaW5wdXQucmVzZXQoKTtcbiAgICAgIC8vIEFkZHMgXCJTZWxlY3QgYWxsXCIgdG8gY29udGV4dCBtZW51IGluIEZGXG4gICAgICBpZiAoIWNtLnNvbWV0aGluZ1NlbGVjdGVkKCkpIHRlLnZhbHVlID0gaW5wdXQucHJldklucHV0ID0gXCIgXCI7XG4gICAgICBpbnB1dC5jb250ZXh0TWVudVBlbmRpbmcgPSB0cnVlO1xuICAgICAgZGlzcGxheS5zZWxGb3JDb250ZXh0TWVudSA9IGNtLmRvYy5zZWw7XG4gICAgICBjbGVhclRpbWVvdXQoZGlzcGxheS5kZXRlY3RpbmdTZWxlY3RBbGwpO1xuXG4gICAgICAvLyBTZWxlY3QtYWxsIHdpbGwgYmUgZ3JleWVkIG91dCBpZiB0aGVyZSdzIG5vdGhpbmcgdG8gc2VsZWN0LCBzb1xuICAgICAgLy8gdGhpcyBhZGRzIGEgemVyby13aWR0aCBzcGFjZSBzbyB0aGF0IHdlIGNhbiBsYXRlciBjaGVjayB3aGV0aGVyXG4gICAgICAvLyBpdCBnb3Qgc2VsZWN0ZWQuXG4gICAgICBmdW5jdGlvbiBwcmVwYXJlU2VsZWN0QWxsSGFjaygpIHtcbiAgICAgICAgaWYgKHRlLnNlbGVjdGlvblN0YXJ0ICE9IG51bGwpIHtcbiAgICAgICAgICB2Y
23459XIgc2VsZWN0ZWQgPSBjbS5zb21ldGhpbmdTZWxlY3RlZCgpO1xuICAgICAgICAgIHZhciBleHR2YWwgPSBcIlxcdTIwMGJcIiArIChzZWxlY3RlZCA/IHRlLnZhbHVlIDogXCJcIik7XG4gICAgICAgICAgdGUudmFsdWUgPSBcIlxcdTIxZGFcIjsgLy8gVXNlZCB0byBjYXRjaCBjb250ZXh0LW1lbnUgdW5kb1xuICAgICAgICAgIHRlLnZhbHVlID0gZXh0dmFsO1xuICAgICAgICAgIGlucHV0LnByZXZJbnB1dCA9IHNlbGVjdGVkID8gXCJcIiA6IFwiXFx1MjAwYlwiO1xuICAgICAgICAgIHRlLnNlbGVjdGlvblN0YXJ0ID0gMTsgdGUuc2VsZWN0aW9uRW5kID0gZXh0dmFsLmxlbmd0aDtcbiAgICAgICAgICAvLyBSZS1zZXQgdGhpcywgaW4gY2FzZSBzb21lIG90aGVyIGhhbmRsZXIgdG91Y2hlZCB0aGVcbiAgICAgICAgICAvLyBzZWxlY3Rpb24gaW4gdGhlIG1lYW50aW1lLlxuICAgICAgICAgIGRpc3BsYXkuc2VsRm9yQ29udGV4dE1lbnUgPSBjbS5kb2Muc2VsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmdW5jdGlvbiByZWhpZGUoKSB7XG4gICAgICAgIGlucHV0LmNvbnRleHRNZW51UGVuZGluZyA9IGZhbHNlO1xuICAgICAgICBpbnB1dC53cmFwcGVyLnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuICAgICAgICB0ZS5zdHlsZS5jc3NUZXh0ID0gb2xkQ1NTO1xuICAgICAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8IDkpIGRpc3BsYXkuc2Nyb2xsYmFycy5zZXRTY3JvbGxUb3AoZGlzcGxheS5zY3JvbGxlci5zY3JvbGxUb3AgPSBzY3JvbGxQb3MpO1xuXG4gICAgICAgIC8vIFRyeSB0byBkZXRlY3QgdGhlIHVzZXIgY2hvb3Npbmcgc2VsZWN0LWFsbFxuICAgICAgICBpZiAodGUuc2VsZWN0aW9uU3RhcnQgIT0gbnVsbCkge1xuICAgICAgICAgIGlmICghaWUgfHwgKGllICYmIGllX3ZlcnNpb24gPCA5KSkgcHJlcGFyZVNlbGVjdEFsbEhhY2soKTtcbiAgICAgICAgICB2Y
23459XIgaSA9IDAsIHBvbGwgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGlmIChkaXNwbGF5LnNlbEZvckNvbnRleHRNZW51ID09IGNtLmRvYy5zZWwgJiYgdGUuc2VsZWN0aW9uU3RhcnQgPT0gMCAmJlxuICAgICAgICAgICAgICAgIHRlLnNlbGVjdGlvbkVuZCA+IDAgJiYgaW5wdXQucHJldklucHV0ID09IFwiXFx1MjAwYlwiKVxuICAgICAgICAgICAgICBvcGVyYXRpb24oY20sIGNvbW1hbmRzLnNlbGVjdEFsbCkoY20pO1xuICAgICAgICAgICAgZWxzZSBpZiAoaSsrIDwgMTApIGRpc3BsYXkuZGV0ZWN0aW5nU2VsZWN0QWxsID0gc2V0VGltZW91dChwb2xsLCA1MDApO1xuICAgICAgICAgICAgZWxzZSBkaXNwbGF5LmlucHV0LnJlc2V0KCk7XG4gICAgICAgICAgfTtcbiAgICAgICAgICBkaXNwbGF5LmRldGVjdGluZ1NlbGVjdEFsbCA9IHNldFRpbWVvdXQocG9sbCwgMjAwKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA+PSA5KSBwcmVwYXJlU2VsZWN0QWxsSGFjaygpO1xuICAgICAgaWYgKGNhcHR1cmVSaWdodENsaWNrKSB7XG4gICAgICAgIGVfc3RvcChlKTtcbiAgICAgICAgdmFyIG1vdXNldXAgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICBvZmYod2luZG93LCBcIm1vdXNldXBcIiwgbW91c2V1cCk7XG4gICAgICAgICAgc2V0VGltZW91dChyZWhpZGUsIDIwKTtcbiAgICAgICAgfTtcbiAgICAgICAgb24od2luZG93LCBcIm1vdXNldXBcIiwgbW91c2V1cCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRUaW1lb3V0KHJlaGlkZSwgNTApO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICByZWFkT25seUNoYW5nZWQ6IGZ1bmN0aW9uKHZhbCkge1xuICAgICAgaWYgKCF2YWwpIHRoaXMucmVzZXQoKTtcbiAgICB9LFxuXG4gICAgc2V0VW5lZGl0YWJsZTogbm90aGluZyxcblxuICAgIG5lZWRzQ29udGVudEF0dHJpYnV0ZTogZmFsc2VcbiAgfSwgVGV4dGFyZWFJbnB1dC5wcm90b3R5cGUpO1xuXG4gIC8vIENPTlRFTlRFRElUQUJMRSBJTlBVVCBTVFlMRVxuXG4gIGZ1bmN0aW9uIENvbnRlbnRFZGl0YWJsZUlucHV0KGNtKSB7XG4gICAgdGhpcy5jbSA9IGNtO1xuICAgIHRoaXMubGFzdEFuY2hvck5vZGUgPSB0aGlzLmxhc3RBbmNob3JPZmZzZXQgPSB0aGlzLmxhc3RGb2N1c05vZGUgPSB0aGlzLmxhc3RGb2N1c09mZnNldCA9IG51bGw7XG4gICAgdGhpcy5wb2xsaW5nID0gbmV3IERlbGF5ZWQoKTtcbiAgICB0aGlzLmdyYWNlUGVyaW9kID0gZmFsc2U7XG4gIH1cblxuICBDb250ZW50RWRpdGFibGVJbnB1dC5wcm90b3R5cGUgPSBjb3B5T2JqKHtcbiAgICBpbml0OiBmdW5jdGlvbihkaXNwbGF5KSB7XG4gICAgICB2Y
23459XIgaW5wdXQgPSB0aGlzLCBjbSA9IGlucHV0LmNtO1xuICAgICAgdmFyIGRpdiA9IGlucHV0LmRpdiA9IGRpc3BsYXkubGluZURpdjtcbiAgICAgIGRpc2FibGVCcm93c2VyTWFnaWMoZGl2KTtcblxuICAgICAgb24oZGl2LCBcInBhc3RlXCIsIGZ1bmN0aW9uKGUpIHsgaGFuZGxlUGFzdGUoZSwgY20pOyB9KVxuXG4gICAgICBvbihkaXYsIFwiY29tcG9zaXRpb25zdGFydFwiLCBmdW5jdGlvbihlKSB7XG4gICAgICAgIHZhciBkYXRhID0gZS5kYXRhO1xuICAgICAgICBpbnB1dC5jb21wb3NpbmcgPSB7c2VsOiBjbS5kb2Muc2VsLCBkYXRhOiBkYXRhLCBzdGFydERhdGE6IGRhdGF9O1xuICAgICAgICBpZiAoIWRhdGEpIHJldHVybjtcbiAgICAgICAgdmFyIHByaW0gPSBjbS5kb2Muc2VsLnByaW1hcnkoKTtcbiAgICAgICAgdmFyIGxpbmUgPSBjbS5nZXRMaW5lKHByaW0uaGVhZC5saW5lKTtcbiAgICAgICAgdmFyIGZvdW5kID0gbGluZS5pbmRleE9mKGRhdGEsIE1hdGgubWF4KDAsIHByaW0uaGVhZC5jaCAtIGRhdGEubGVuZ3RoKSk7XG4gICAgICAgIGlmIChmb3VuZCA+IC0xICYmIGZvdW5kIDw9IHByaW0uaGVhZC5jaClcbiAgICAgICAgICBpbnB1dC5jb21wb3Npbmcuc2VsID0gc2ltcGxlU2VsZWN0aW9uKFBvcyhwcmltLmhlYWQubGluZSwgZm91bmQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9zKHByaW0uaGVhZC5saW5lLCBmb3VuZCArIGRhdGEubGVuZ3RoKSk7XG4gICAgICB9KTtcbiAgICAgIG9uKGRpdiwgXCJjb21wb3NpdGlvbnVwZGF0ZVwiLCBmdW5jdGlvbihlKSB7XG4gICAgICAgIGlucHV0LmNvbXBvc2luZy5kYXRhID0gZS5kYXRhO1xuICAgICAgfSk7XG4gICAgICBvbihkaXYsIFwiY29tcG9zaXRpb25lbmRcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgICB2Y
23459XIgb3VycyA9IGlucHV0LmNvbXBvc2luZztcbiAgICAgICAgaWYgKCFvdXJzKSByZXR1cm47XG4gICAgICAgIGlmIChlLmRhdGEgIT0gb3Vycy5zdGFydERhdGEgJiYgIS9cXHUyMDBiLy50ZXN0KGUuZGF0YSkpXG4gICAgICAgICAgb3Vycy5kYXRhID0gZS5kYXRhO1xuICAgICAgICAvLyBOZWVkIGEgc21hbGwgZGVsYXkgdG8gcHJldmVudCBvdGhlciBjb2RlIChpbnB1dCBldmVudCxcbiAgICAgICAgLy8gc2VsZWN0aW9uIHBvbGxpbmcpIGZyb20gZG9pbmcgZGFtYWdlIHdoZW4gZmlyZWQgcmlnaHQgYWZ0ZXJcbiAgICAgICAgLy8gY29tcG9zaXRpb25lbmQuXG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKCFvdXJzLmhhbmRsZWQpXG4gICAgICAgICAgICBpbnB1dC5hcHBseUNvbXBvc2l0aW9uKG91cnMpO1xuICAgICAgICAgIGlmIChpbnB1dC5jb21wb3NpbmcgPT0gb3VycylcbiAgICAgICAgICAgIGlucHV0LmNvbXBvc2luZyA9IG51bGw7XG4gICAgICAgIH0sIDUwKTtcbiAgICAgIH0pO1xuXG4gICAgICBvbihkaXYsIFwidG91Y2hzdGFydFwiLCBmdW5jdGlvbigpIHtcbiAgICAgICAgaW5wdXQuZm9yY2VDb21wb3NpdGlvbkVuZCgpO1xuICAgICAgfSk7XG5cbiAgICAgIG9uKGRpdiwgXCJpbnB1dFwiLCBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKGlucHV0LmNvbXBvc2luZykgcmV0dXJuO1xuICAgICAgICBpZiAoaXNSZWFkT25seShjbSkgfHwgIWlucHV0LnBvbGxDb250ZW50KCkpXG4gICAgICAgICAgcnVuSW5PcChpbnB1dC5jbSwgZnVuY3Rpb24oKSB7cmVnQ2hhbmdlKGNtKTt9KTtcbiAgICAgIH0pO1xuXG4gICAgICBmdW5jdGlvbiBvbkNvcHlDdXQoZSkge1xuICAgICAgICBpZiAoY20uc29tZXRoaW5nU2VsZWN0ZWQoKSkge1xuICAgICAgICAgIGxhc3RDb3BpZWQgPSBjbS5nZXRTZWxlY3Rpb25zKCk7XG4gICAgICAgICAgaWYgKGUudHlwZSA9PSBcImN1dFwiKSBjbS5yZXBsYWNlU2VsZWN0aW9uKFwiXCIsIG51bGwsIFwiY3V0XCIpO1xuICAgICAgICB9IGVsc2UgaWYgKCFjbS5vcHRpb25zLmxpbmVXaXNlQ29weUN1dCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2Y
23459XIgcmFuZ2VzID0gY29weWFibGVSYW5nZXMoY20pO1xuICAgICAgICAgIGxhc3RDb3BpZWQgPSByYW5nZXMudGV4dDtcbiAgICAgICAgICBpZiAoZS50eXBlID09IFwiY3V0XCIpIHtcbiAgICAgICAgICAgIGNtLm9wZXJhdGlvbihmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgY20uc2V0U2VsZWN0aW9ucyhyYW5nZXMucmFuZ2VzLCAwLCBzZWxfZG9udFNjcm9sbCk7XG4gICAgICAgICAgICAgIGNtLnJlcGxhY2VTZWxlY3Rpb24oXCJcIiwgbnVsbCwgXCJjdXRcIik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gaU9TIGV4cG9zZXMgdGhlIGNsaXBib2FyZCBBUEksIGJ1dCBzZWVtcyB0byBkaXNjYXJkIGNvbnRlbnQgaW5zZXJ0ZWQgaW50byBpdFxuICAgICAgICBpZiAoZS5jbGlwYm9hcmREYXRhICYmICFpb3MpIHtcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgZS5jbGlwYm9hcmREYXRhLmNsZWFyRGF0YSgpO1xuICAgICAgICAgIGUuY2xpcGJvYXJkRGF0YS5zZXREYXRhKFwidGV4dC9wbGFpblwiLCBsYXN0Q29waWVkLmpvaW4oXCJcXG5cIikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE9sZC1mYXNoaW9uZWQgYnJpZWZseS1mb2N1cy1hLXRleHRhcmVhIGhhY2tcbiAgICAgICAgICB2YXIga2x1ZGdlID0gaGlkZGVuVGV4dGFyZWEoKSwgdGUgPSBrbHVkZ2UuZmlyc3RDaGlsZDtcbiAgICAgICAgICBjbS5kaXNwbGF5LmxpbmVTcGFjZS5pbnNlcnRCZWZvcmUoa2x1ZGdlLCBjbS5kaXNwbGF5LmxpbmVTcGFjZS5maXJzdENoaWxkKTtcbiAgICAgICAgICB0ZS52YWx1ZSA9IGxhc3RDb3BpZWQuam9pbihcIlxcblwiKTtcbiAgICAgICAgICB2Y
23459XIgaGFkRm9jdXMgPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuICAgICAgICAgIHNlbGVjdElucHV0KHRlKTtcbiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY20uZGlzcGxheS5saW5lU3BhY2UucmVtb3ZlQ2hpbGQoa2x1ZGdlKTtcbiAgICAgICAgICAgIGhhZEZvY3VzLmZvY3VzKCk7XG4gICAgICAgICAgfSwgNTApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBvbihkaXYsIFwiY29weVwiLCBvbkNvcHlDdXQpO1xuICAgICAgb24oZGl2LCBcImN1dFwiLCBvbkNvcHlDdXQpO1xuICAgIH0sXG5cbiAgICBwcmVwYXJlU2VsZWN0aW9uOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZXN1bHQgPSBwcmVwYXJlU2VsZWN0aW9uKHRoaXMuY20sIGZhbHNlKTtcbiAgICAgIHJlc3VsdC5mb2N1cyA9IHRoaXMuY20uc3RhdGUuZm9jdXNlZDtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIHNob3dTZWxlY3Rpb246IGZ1bmN0aW9uKGluZm8pIHtcbiAgICAgIGlmICghaW5mbyB8fCAhdGhpcy5jbS5kaXNwbGF5LnZpZXcubGVuZ3RoKSByZXR1cm47XG4gICAgICBpZiAoaW5mby5mb2N1cykgdGhpcy5zaG93UHJpbWFyeVNlbGVjdGlvbigpO1xuICAgICAgdGhpcy5zaG93TXVsdGlwbGVTZWxlY3Rpb25zKGluZm8pO1xuICAgIH0sXG5cbiAgICBzaG93UHJpbWFyeVNlbGVjdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpLCBwcmltID0gdGhpcy5jbS5kb2Muc2VsLnByaW1hcnkoKTtcbiAgICAgIHZhciBjdXJBbmNob3IgPSBkb21Ub1Bvcyh0aGlzLmNtLCBzZWwuYW5jaG9yTm9kZSwgc2VsLmFuY2hvck9mZnNldCk7XG4gICAgICB2Y
23459XIgY3VyRm9jdXMgPSBkb21Ub1Bvcyh0aGlzLmNtLCBzZWwuZm9jdXNOb2RlLCBzZWwuZm9jdXNPZmZzZXQpO1xuICAgICAgaWYgKGN1ckFuY2hvciAmJiAhY3VyQW5jaG9yLmJhZCAmJiBjdXJGb2N1cyAmJiAhY3VyRm9jdXMuYmFkICYmXG4gICAgICAgICAgY21wKG1pblBvcyhjdXJBbmNob3IsIGN1ckZvY3VzKSwgcHJpbS5mcm9tKCkpID09IDAgJiZcbiAgICAgICAgICBjbXAobWF4UG9zKGN1ckFuY2hvciwgY3VyRm9jdXMpLCBwcmltLnRvKCkpID09IDApXG4gICAgICAgIHJldHVybjtcblxuICAgICAgdmFyIHN0YXJ0ID0gcG9zVG9ET00odGhpcy5jbSwgcHJpbS5mcm9tKCkpO1xuICAgICAgdmFyIGVuZCA9IHBvc1RvRE9NKHRoaXMuY20sIHByaW0udG8oKSk7XG4gICAgICBpZiAoIXN0YXJ0ICYmICFlbmQpIHJldHVybjtcblxuICAgICAgdmFyIHZpZXcgPSB0aGlzLmNtLmRpc3BsYXkudmlldztcbiAgICAgIHZhciBvbGQgPSBzZWwucmFuZ2VDb3VudCAmJiBzZWwuZ2V0UmFuZ2VBdCgwKTtcbiAgICAgIGlmICghc3RhcnQpIHtcbiAgICAgICAgc3RhcnQgPSB7bm9kZTogdmlld1swXS5tZWFzdXJlLm1hcFsyXSwgb2Zmc2V0OiAwfTtcbiAgICAgIH0gZWxzZSBpZiAoIWVuZCkgeyAvLyBGSVhNRSBkYW5nZXJvdXNseSBoYWNreVxuICAgICAgICB2YXIgbWVhc3VyZSA9IHZpZXdbdmlldy5sZW5ndGggLSAxXS5tZWFzdXJlO1xuICAgICAgICB2YXIgbWFwID0gbWVhc3VyZS5tYXBzID8gbWVhc3VyZS5tYXBzW21lYXN1cmUubWFwcy5sZW5ndGggLSAxXSA6IG1lYXN1cmUubWFwO1xuICAgICAgICBlbmQgPSB7bm9kZTogbWFwW21hcC5sZW5ndGggLSAxXSwgb2Zmc2V0OiBtYXBbbWFwLmxlbmd0aCAtIDJdIC0gbWFwW21hcC5sZW5ndGggLSAzXX07XG4gICAgICB9XG5cbiAgICAgIHRyeSB7IHZhciBybmcgPSByYW5nZShzdGFydC5ub2RlLCBzdGFydC5vZmZzZXQsIGVuZC5vZmZzZXQsIGVuZC5ub2RlKTsgfVxuICAgICAgY2F0Y2goZSkge30gLy8gT3VyIG1vZGVsIG9mIHRoZSBET00gbWlnaHQgYmUgb3V0ZGF0ZWQsIGluIHdoaWNoIGNhc2UgdGhlIHJhbmdlIHdlIHRyeSB0byBzZXQgY2FuIGJlIGltcG9zc2libGVcbiAgICAgIGlmIChybmcpIHtcbiAgICAgICAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgICBzZWwuYWRkUmFuZ2Uocm5nKTt
vendor: 7,661 bytes, line 23459
23459cbiAgICAgICAgaWYgKG9sZCAmJiBzZWwuYW5jaG9yTm9kZSA9PSBudWxsKSBzZWwuYWRkUmFuZ2Uob2xkKTtcbiAgICAgICAgZWxzZSBpZiAoZ2Vja28pIHRoaXMuc3RhcnRHcmFjZVBlcmlvZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5yZW1lbWJlclNlbGVjdGlvbigpO1xuICAgIH0sXG5cbiAgICBzdGFydEdyYWNlUGVyaW9kOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBpbnB1dCA9IHRoaXM7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5ncmFjZVBlcmlvZCk7XG4gICAgICB0aGlzLmdyYWNlUGVyaW9kID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgaW5wdXQuZ3JhY2VQZXJpb2QgPSBmYWxzZTtcbiAgICAgICAgaWYgKGlucHV0LnNlbGVjdGlvbkNoYW5nZWQoKSlcbiAgICAgICAgICBpbnB1dC5jbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7IGlucHV0LmNtLmN1ck9wLnNlbGVjdGlvbkNoYW5nZWQgPSB0cnVlOyB9KTtcbiAgICAgIH0sIDIwKTtcbiAgICB9LFxuXG4gICAgc2hvd011bHRpcGxlU2VsZWN0aW9uczogZnVuY3Rpb24oaW5mbykge1xuICAgICAgcmVtb3ZlQ2hpbGRyZW5BbmRBZGQodGhpcy5jbS5kaXNwbGF5LmN1cnNvckRpdiwgaW5mby5jdXJzb3JzKTtcbiAgICAgIHJlbW92ZUNoaWxkcmVuQW5kQWRkKHRoaXMuY20uZGlzcGxheS5zZWxlY3Rpb25EaXYsIGluZm8uc2VsZWN0aW9uKTtcbiAgICB9LFxuXG4gICAgcmVtZW1iZXJTZWxlY3Rpb246IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICAgIHRoaXMubGFzdEFuY2hvck5vZGUgPSBzZWwuYW5jaG9yTm9kZTsgdGhpcy5sYXN0QW5jaG9yT2Zmc2V0ID0gc2VsLmFuY2hvck9mZnNldDtcbiAgICAgIHRoaXMubGFzdEZvY3VzTm9kZSA9IHNlbC5mb2N1c05vZGU7IHRoaXMubGFzdEZvY3VzT2Zmc2V0ID0gc2VsLmZvY3VzT2Zmc2V0O1xuICAgIH0sXG5cbiAgICBzZWxlY3Rpb25JbkVkaXRvcjogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgICAgaWYgKCFzZWwucmFuZ2VDb3VudCkgcmV0dXJuIGZhbHNlO1xuICAgICAgdmFyIG5vZGUgPSBzZWwuZ2V0UmFuZ2VBdCgwKS5jb21tb25BbmNlc3RvckNvbnRhaW5lcjtcbiAgICAgIHJldHVybiBjb250YWlucyh0aGlzLmRpdiwgbm9kZSk7XG4gICAgfSxcblxuICAgIGZvY3VzOiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmNtLm9wdGlvbnMucmVhZE9ubHkgIT0gXCJub2N1cnNvclwiKSB0aGlzLmRpdi5mb2N1cygpO1xuICAgIH0sXG4gICAgYmx1cjogZnVuY3Rpb24oKSB7IHRoaXMuZGl2LmJsdXIoKTsgfSxcbiAgICBnZXRGaWVsZDogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLmRpdjsgfSxcblxuICAgIHN1cHBvcnRzVG91Y2g6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfSxcblxuICAgIHJlY2VpdmVkRm9jdXM6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGlucHV0ID0gdGhpcztcbiAgICAgIGlmICh0aGlzLnNlbGVjdGlvbkluRWRpdG9yKCkpXG4gICAgICAgIHRoaXMucG9sbFNlbGVjdGlvbigpO1xuICAgICAgZWxzZVxuICAgICAgICBydW5Jbk9wKHRoaXMuY20sIGZ1bmN0aW9uKCkgeyBpbnB1dC5jbS5jdXJPcC5zZWxlY3Rpb25DaGFuZ2VkID0gdHJ1ZTsgfSk7XG5cbiAgICAgIGZ1bmN0aW9uIHBvbGwoKSB7XG4gICAgICAgIGlmIChpbnB1dC5jbS5zdGF0ZS5mb2N1c2VkKSB7XG4gICAgICAgICAgaW5wdXQucG9sbFNlbGVjdGlvbigpO1xuICAgICAgICAgIGlucHV0LnBvbGxpbmcuc2V0KGlucHV0LmNtLm9wdGlvbnMucG9sbEludGVydmFsLCBwb2xsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5wb2xsaW5nLnNldCh0aGlzLmNtLm9wdGlvbnMucG9sbEludGVydmFsLCBwb2xsKTtcbiAgICB9LFxuXG4gICAgc2VsZWN0aW9uQ2hhbmdlZDogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgICAgcmV0dXJuIHNlbC5hbmNob3JOb2RlICE9IHRoaXMubGFzdEFuY2hvck5vZGUgfHwgc2VsLmFuY2hvck9mZnNldCAhPSB0aGlzLmxhc3RBbmNob3JPZmZzZXQgfHxcbiAgICAgICAgc2VsLmZvY3VzTm9kZSAhPSB0aGlzLmxhc3RGb2N1c05vZGUgfHwgc2VsLmZvY3VzT2Zmc2V0ICE9IHRoaXMubGFzdEZvY3VzT2Zmc2V0O1xuICAgIH0sXG5cbiAgICBwb2xsU2VsZWN0aW9uOiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghdGhpcy5jb21wb3NpbmcgJiYgIXRoaXMuZ3JhY2VQZXJpb2QgJiYgdGhpcy5zZWxlY3Rpb25DaGFuZ2VkKCkpIHtcbiAgICAgICAgdmFyIHNlbCA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKSwgY20gPSB0aGlzLmNtO1xuICAgICAgICB0aGlzLnJlbWVtYmVyU2VsZWN0aW9uKCk7XG4gICAgICAgIHZhciBhbmNob3IgPSBkb21Ub1BvcyhjbSwgc2VsLmFuY2hvck5vZGUsIHNlbC5hbmNob3JPZmZzZXQpO1xuICAgICAgICB2YXIgaGVhZCA9IGRvbVRvUG9zKGNtLCBzZWwuZm9jdXNOb2RlLCBzZWwuZm9jdXNPZmZzZXQpO1xuICAgICAgICBpZiAoYW5jaG9yICYmIGhlYWQpIHJ1bkluT3AoY20sIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHNldFNlbGVjdGlvbihjbS5kb2MsIHNpbXBsZVNlbGVjdGlvbihhbmNob3IsIGhlYWQpLCBzZWxfZG9udFNjcm9sbCk7XG4gICAgICAgICAgaWYgKGFuY2hvci5iYWQgfHwgaGVhZC5iYWQpIGNtLmN1ck9wLnNlbGVjdGlvbkNoYW5nZWQgPSB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgcG9sbENvbnRlbnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGNtID0gdGhpcy5jbSwgZGlzcGxheSA9IGNtLmRpc3BsYXksIHNlbCA9IGNtLmRvYy5zZWwucHJpbWFyeSgpO1xuICAgICAgdmFyIGZyb20gPSBzZWwuZnJvbSgpLCB0byA9IHNlbC50bygpO1xuICAgICAgaWYgKGZyb20ubGluZSA8IGRpc3BsYXkudmlld0Zyb20gfHwgdG8ubGluZSA+IGRpc3BsYXkudmlld1RvIC0gMSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgICB2YXIgZnJvbUluZGV4O1xuICAgICAgaWYgKGZyb20ubGluZSA9PSBkaXNwbGF5LnZpZXdGcm9tIHx8IChmcm9tSW5kZXggPSBmaW5kVmlld0luZGV4KGNtLCBmcm9tLmxpbmUpKSA9PSAwKSB7XG4gICAgICAgIHZhciBmcm9tTGluZSA9IGxpbmVObyhkaXNwbGF5LnZpZXdbMF0ubGluZSk7XG4gICAgICAgIHZhciBmcm9tTm9kZSA9IGRpc3BsYXkudmlld1swXS5ub2RlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGZyb21MaW5lID0gbGluZU5vKGRpc3BsYXkudmlld1tmcm9tSW5kZXhdLmxpbmUpO1xuICAgICAgICB2YXIgZnJvbU5vZGUgPSBkaXNwbGF5LnZpZXdbZnJvbUluZGV4IC0gMV0ubm9kZS5uZXh0U2libGluZztcbiAgICAgIH1cbiAgICAgIHZhciB0b0luZGV4ID0gZmluZFZpZXdJbmRleChjbSwgdG8ubGluZSk7XG4gICAgICBpZiAodG9JbmRleCA9PSBkaXNwbGF5LnZpZXcubGVuZ3RoIC0gMSkge1xuICAgICAgICB2YXIgdG9MaW5lID0gZGlzcGxheS52aWV3VG8gLSAxO1xuICAgICAgICB2YXIgdG9Ob2RlID0gZGlzcGxheS5saW5lRGl2Lmxhc3RDaGlsZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciB0b0xpbmUgPSBsaW5lTm8oZGlzcGxheS52aWV3W3RvSW5kZXggKyAxXS5saW5lKSAtIDE7XG4gICAgICAgIHZhciB0b05vZGUgPSBkaXNwbGF5LnZpZXdbdG9JbmRleCArIDFdLm5vZGUucHJldmlvdXNTaWJsaW5nO1xuICAgICAgfVxuXG4gICAgICB2YXIgbmV3VGV4dCA9IGNtLmRvYy5zcGxpdExpbmVzKGRvbVRleHRCZXR3ZWVuKGNtLCBmcm9tTm9kZSwgdG9Ob2RlLCBmcm9tTGluZSwgdG9MaW5lKSk7XG4gICAgICB2YXIgb2xkVGV4dCA9IGdldEJldHdlZW4oY20uZG9jLCBQb3MoZnJvbUxpbmUsIDApLCBQb3ModG9MaW5lLCBnZXRMaW5lKGNtLmRvYywgdG9MaW5lKS50ZXh0Lmxlbmd0aCkpO1xuICAgICAgd2hpbGUgKG5ld1RleHQubGVuZ3RoID4gMSAmJiBvbGRUZXh0Lmxlbmd0aCA+IDEpIHtcbiAgICAgICAgaWYgKGxzdChuZXdUZXh0KSA9PSBsc3Qob2xkVGV4dCkpIHsgbmV3VGV4dC5wb3AoKTsgb2xkVGV4dC5wb3AoKTsgdG9MaW5lLS07IH1cbiAgICAgICAgZWxzZSBpZiAobmV3VGV4dFswXSA9PSBvbGRUZXh0WzBdKSB7IG5ld1RleHQuc2hpZnQoKTsgb2xkVGV4dC5zaGlmdCgpOyBmcm9tTGluZSsrOyB9XG4gICAgICAgIGVsc2UgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHZhciBjdXRGcm9udCA9IDAsIGN1dEVuZCA9IDA7XG4gICAgICB2YXIgbmV3VG9wID0gbmV3VGV4dFswXSwgb2xkVG9wID0gb2xkVGV4dFswXSwgbWF4Q3V0RnJvbnQgPSBNYXRoLm1pbihuZXdUb3AubGVuZ3RoLCBvbGRUb3AubGVuZ3RoKTtcbiAgICAgIHdoaWxlIChjdXRGcm9udCA8IG1heEN1dEZyb250ICYmIG5ld1RvcC5jaGFyQ29kZUF0KGN1dEZyb250KSA9PSBvbGRUb3AuY2hhckNvZGVBdChjdXRGcm9udCkpXG4gICAgICAgICsrY3V0RnJvbnQ7XG4gICAgICB2YXIgbmV3Qm90ID0gbHN0KG5ld1RleHQpLCBvbGRCb3QgPSBsc3Qob2xkVGV4dCk7XG4gICAgICB2YXIgbWF4Q3V0RW5kID0gTWF0aC5taW4obmV3Qm90Lmxlbmd0aCAtIChuZXdUZXh0Lmxlbmd0aCA9PSAxID8gY3V0RnJvbnQgOiAwKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRCb3QubGVuZ3RoIC0gKG9sZFRleHQubGVuZ3RoID09IDEgPyBjdXRGcm9udCA6IDApKTtcbiAgICAgIHdoaWxlIChjdXRFbmQgPCBtYXhDdXRFbmQgJiZcbiAgICAgICAgICAgICBuZXdCb3QuY2hhckNvZGVBdChuZXdCb3QubGVuZ3RoIC0gY3V0RW5kIC0gMSkgPT0gb2xkQm90LmNoYXJDb2RlQXQob2xkQm90Lmxlbmd0aCAtIGN1dEVuZCAtIDEpKVxuICAgICAgICArK2N1dEVuZDtcblxuICAgICAgbmV3VGV4dFtuZXdUZXh0Lmxlbmd0aCAtIDFdID0gbmV3Qm90LnNsaWNlKDAsIG5ld0JvdC5sZW5ndGggLSBjdXRFbmQpO1xuICAgICAgbmV3VGV4dFswXSA9IG5ld1RleHRbMF0uc2xpY2UoY3V0RnJvbnQpO1xuXG4gICAgICB2YXIgY2hGcm9tID0gUG9zKGZyb21MaW5lLCBjdXRGcm9udCk7XG4gICAgICB2YXIgY2hUbyA9IFBvcyh0b0xpbmUsIG9sZFRleHQubGVuZ3RoID8gbHN0KG9sZFRleHQpLmxlbmd0aCAtIGN1dEVuZCA6IDApO1xuICAgICAgaWYgKG5ld1RleHQubGVuZ3RoID4gMSB8fCBuZXdUZXh0WzBdIHx8IGNtcChjaEZyb20sIGNoVG8pKSB7XG4gICAgICAgIHJlcGxhY2VSYW5nZShjbS5kb2MsIG5ld1RleHQsIGNoRnJvbSwgY2hUbywgXCIraW5wdXRcIik7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBlbnN1cmVQb2xsZWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5mb3JjZUNvbXBvc2l0aW9uRW5kKCk7XG4gICAgfSxcbiAgICByZXNldDogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmZvcmNlQ29tcG9zaXRpb25FbmQoKTtcbiAgICB9LFxuICAgIGZvcmNlQ29tcG9zaXRpb25FbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLmNvbXBvc2luZyB8fCB0aGlzLmNvbXBvc2luZy5oYW5kbGVkKSByZXR1cm47XG4gICAgICB0aGlzLmFwcGx5Q29tcG9zaXRpb24odGhpcy5jb21wb3NpbmcpO1xuICAgICAgdGhpcy5jb21wb3NpbmcuaGFuZGxlZCA9IHRydWU7XG4gICAgICB0aGlzLmRpdi5ibHVyKCk7XG4gICAgICB0aGlzLmRpdi5mb2N1cygpO1xuICAgIH0sXG4gICAgYXBwbHlDb21wb3NpdGlvbjogZnVuY3Rpb24oY29tcG9zaW5nKSB7XG4gICAgICBpZiAo
23459aXNSZWFkT25seSh0aGlzLmNtKSlcbiAgICAgICAgb3BlcmF0aW9uKHRoaXMuY20sIHJlZ0NoYW5nZSkodGhpcy5jbSlcbiAgICAgIGVsc2UgaWYgKGNvbXBvc2luZy5kYXRhICYmIGNvbXBvc2luZy5kYXRhICE9IGNvbXBvc2luZy5zdGFydERhdGEpXG4gICAgICAgIG9wZXJhdGlvbih0aGlzLmNtLCBhcHBseVRleHRJbnB1dCkodGhpcy5jbSwgY29tcG9zaW5nLmRhdGEsIDAsIGNvbXBvc2luZy5zZWwpO1xuICAgIH0sXG5cbiAgICBzZXRVbmVkaXRhYmxlOiBmdW5jdGlvbihub2RlKSB7XG4gICAgICBub2RlLmNvbnRlbnRFZGl0YWJsZSA9IFwiZmFsc2VcIlxuICAgIH0sXG5cbiAgICBvbktleVByZXNzOiBmdW5jdGlvbihlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBpZiAoIWlzUmVhZE9ubHkodGhpcy5jbSkpXG4gICAgICAgIG9wZXJhdGlvbih0aGlzLmNtLCBhcHBseVRleHRJbnB1dCkodGhpcy5jbSwgU3RyaW5nLmZyb21DaGFyQ29kZShlLmNoYXJDb2RlID09IG51bGwgPyBlLmtleUNvZGUgOiBlLmNoYXJDb2RlKSwgMCk7XG4gICAgfSxcblxuICAgIHJlYWRPbmx5Q2hhbmdlZDogZnVuY3Rpb24odmFsKSB7XG4gICAgICB0aGlzLmRpdi5jb250ZW50RWRpdGFibGUgPSBTdHJpbmcodmFsICE9IFwibm9jdXJzb3JcIilcbiAgICB9LFxuXG4gICAgb25Db250ZXh0TWVudTogbm90aGluZyxcbiAgICByZXNldFBvc2l0aW9uOiBub3RoaW5nLFxuXG4gICAgbmVlZHNDb250ZW50QXR0cmlidXRlOiB0cnVlXG4gIH0sIENvbnRlbnRFZGl0YWJsZUlucHV0LnByb3RvdHlwZSk7XG5cbiAgZnVuY3Rpb24gcG9zVG9ET00oY20sIHBvcykge1xuICAgIHZhciB2aWV3ID0gZmluZFZpZXdGb3JMaW5lKGNtLCBwb3MubGluZSk7XG4gICAgaWYgKCF2aWV3IHx8IHZpZXcuaGlkZGVuKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgbGluZSA9IGdldExpbmUoY20uZG9jLCBwb3MubGluZSk7XG4gICAgdmFyIGluZm8gPSBtYXBGcm9tTGluZVZpZXcodmlldywgbGluZSwgcG9zLmxpbmUpO1xuXG4gICAgdmFyIG9yZGVyID0gZ2V0T3JkZXIobGluZSksIHNpZGUgPSBcImxlZnRcIjtcbiAgICBpZiAob3JkZXIpIHtcbiAgICAgIHZhciBwYXJ0UG9zID0gZ2V0QmlkaVBhcnRBdChvcmRlciwgcG9zLmNoKTtcbiAgICAgIHNpZGUgPSBwYXJ0UG9zICUgMiA/IFwicmlnaHRcIiA6IFwibGVmdFwiO1xuICAgIH1cbiAgICB2YXIgcmVzdWx0ID0gbm9kZUFuZE9mZnNldEluTGluZU1hcChpbmZvLm1hcCwgcG9zLmNoLCBzaWRlKTtcbiAgICByZXN1bHQub2Zmc2V0ID0gcmVzdWx0LmNvbGxhcHNlID09IFwicmlnaHRcIiA/IHJlc3VsdC5lbmQgOiByZXN1bHQuc3RhcnQ7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJhZFBvcyhwb3MsIGJhZCkgeyBpZiAoYmFkKSBwb3MuYmFkID0gdHJ1ZTsgcmV0dXJuIHBvczsgfVxuXG4gIGZ1bmN0aW9uIGRvbVRvUG9zKGNtLCBub2RlLCBvZmZzZXQpIHtcbiAgICB2YXIgbGluZU5vZGU7XG4gICAgaWYgKG5vZGUgPT0gY20uZGlzcGxheS5saW5lRGl2KSB7XG4gICAgICBsaW5lTm9kZSA9IGNtLmRpc3BsYXkubGluZURpdi5jaGlsZE5vZGVzW29mZnNldF07XG4gICAgICBpZiAoIWxpbmVOb2RlKSByZXR1cm4gYmFkUG9zKGNtLmNsaXBQb3MoUG9zKGNtLmRpc3BsYXkudmlld1RvIC0gMSkpLCB0cnVlKTtcbiAgICAgIG5vZGUgPSBudWxsOyBvZmZzZXQgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxpbmVOb2RlID0gbm9kZTs7IGxpbmVOb2RlID0gbGluZU5vZGUucGFyZW50Tm9kZSkge1xuICAgICAgICBpZiAoIWxpbmVOb2RlIHx8IGxpbmVOb2RlID09IGNtLmRpc3BsYXkubGluZURpdikgcmV0dXJuIG51bGw7XG4gICAgICAgIGlmIChsaW5lTm9kZS5wYXJlbnROb2RlICYmIGxpbmVOb2RlLnBhcmVudE5vZGUgPT0gY20uZGlzcGxheS5saW5lRGl2KSBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjbS5kaXNwbGF5LnZpZXcubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBsaW5lVmlldyA9IGNtLmRpc3BsYXkudmlld1tpXTtcbiAgICAgIGlmIChsaW5lVmlldy5ub2RlID09IGxpbmVOb2RlKVxuICAgICAgICByZXR1cm4gbG9jYXRlTm9kZUluTGluZVZpZXcobGluZVZpZXcsIG5vZGUsIG9mZnNldCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbG9jYXRlTm9kZUluTGluZVZpZXcobGluZVZpZXcsIG5vZGUsIG9mZnNldCkge1xuICAgIHZhciB3cmFwcGVyID0gbGluZVZpZXcudGV4dC5maXJzdENoaWxkLCBiYWQgPSBmYWxzZTtcbiAgICBpZiAoIW5vZGUgfHwgIWNvbnRhaW5zKHdyYXBwZXIsIG5vZGUpKSByZXR1cm4gYmFkUG9zKFBvcyhsaW5lTm8obGluZVZpZXcubGluZSksIDApLCB0cnVlKTtcbiAgICBpZiAobm9kZSA9PSB3cmFwcGVyKSB7XG4gICAgICBiYWQgPSB0cnVlO1xuICAgICAgbm9kZSA9IHdyYXBwZXIuY2hpbGROb2Rlc1tvZmZzZXRdO1xuICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIGlmICghbm9kZSkge1xuICAgICAgICB2Y
23459XIgbGluZSA9IGxpbmVWaWV3LnJlc3QgPyBsc3QobGluZVZpZXcucmVzdCkgOiBsaW5lVmlldy5saW5lO1xuICAgICAgICByZXR1cm4gYmFkUG9zKFBvcyhsaW5lTm8obGluZSksIGxpbmUudGV4dC5sZW5ndGgpLCBiYWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciB0ZXh0Tm9kZSA9IG5vZGUubm9kZVR5cGUgPT0gMyA/IG5vZGUgOiBudWxsLCB0b3BOb2RlID0gbm9kZTtcbiAgICBpZiAoIXRleHROb2RlICYmIG5vZGUuY2hpbGROb2Rlcy5sZW5ndGggPT0gMSAmJiBub2RlLmZpcnN0Q2hpbGQubm9kZVR5cGUgPT0gMykge1xuICAgICAgdGV4dE5vZGUgPSBub2RlLmZpcnN0Q2hpbGQ7XG4gICAgICBpZiAob2Zmc2V0KSBvZmZzZXQgPSB0ZXh0Tm9kZS5ub2RlVmFsdWUubGVuZ3RoO1xuICAgIH1cbiAgICB3aGlsZSAodG9wTm9kZS5wYXJlbnROb2RlICE9IHdyYXBwZXIpIHRvcE5vZGUgPSB0b3BOb2RlLnBhcmVudE5vZGU7XG4gICAgdmFyIG1lYXN1cmUgPSBsaW5lVmlldy5tZWFzdXJlLCBtYXBzID0gbWVhc3VyZS5tYXBzO1xuXG4gICAgZnVuY3Rpb24gZmluZCh0ZXh0Tm9kZSwgdG9wTm9kZSwgb2Zmc2V0KSB7XG4gICAgICBmb3IgKHZhciBpID0gLTE7IGkgPCAobWFwcyA/IG1hcHMubGVuZ3RoIDogMCk7IGkrKykge1xuICAgICAgICB2YXIgbWFwID0gaSA8IDAgPyBtZWFzdXJlLm1hcCA6IG1hcHNbaV07XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWFwLmxlbmd0aDsgaiArPSAzKSB7XG4gICAgICAgICAgdmFyIGN1ck5vZGUgPSBtYXBbaiArIDJdO1xuICAgICAgICAgIGlmIChjdXJOb2RlID09IHRleHROb2RlIHx8IGN1ck5vZGUgPT0gdG9wTm9kZSkge1xuICAgICAgICAgICAgdmFyIGxpbmUgPSBsaW5lTm8oaSA8IDAgPyBsaW5lVmlldy5saW5lIDogbGluZVZpZXcucmVzdFtpXSk7XG4gICAgICAgICAgICB2Y
23459XIgY2ggPSBtYXBbal0gKyBvZmZzZXQ7XG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgMCB8fCBjdXJOb2RlICE9IHRleHROb2RlKSBjaCA9IG1hcFtqICsgKG9mZnNldCA/IDEgOiAwKV07XG4gICAgICAgICAgICByZXR1cm4gUG9zKGxpbmUsIGNoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIGZvdW5kID0gZmluZCh0ZXh0Tm9kZSwgdG9wTm9kZSwgb2Zmc2V0KTtcbiAgICBpZiAoZm91bmQpIHJldHVybiBiYWRQb3MoZm91bmQsIGJhZCk7XG5cbiAgICAvLyBGSVhNRSB0aGlzIGlzIGFsbCByZWFsbHkgc2hha3kuIG1pZ2h0IGhhbmRsZSB0aGUgZmV3IGNhc2VzIGl0IG5lZWRzIHRvIGhhbmRsZSwgYnV0IGxpa2VseSB0byBjYXVzZSBwcm9ibGVtc1xuICAgIGZvciAodmFyIGFmdGVyID0gdG9wTm9kZS5uZXh0U2libGluZywgZGlzdCA9IHRleHROb2RlID8gdGV4dE5vZGUubm9kZVZhbHVlLmxlbmd0aCAtIG9mZnNldCA6IDA7IGFmdGVyOyBhZnRlciA9IGFmdGVyLm5leHRTaWJsaW5nKSB7XG4gICAgICBmb3VuZCA9IGZpbmQoYWZ0ZXIsIGFmdGVyLmZpcnN0Q2hpbGQsIDApO1xuICAgICAgaWYgKGZvdW5kKVxuICAgICAgICByZXR1cm4gYmFkUG9zKFBvcyhmb3VuZC5saW5lLCBmb3VuZC5jaCAtIGRpc3QpLCBiYWQpO1xuICAgICAgZWxzZVxuICAgICAgICBkaXN0ICs9IGFmdGVyLnRleHRDb250ZW50Lmxlbmd0aDtcbiAgICB9XG4gICAgZm9yICh2YXIgYmVmb3JlID0gdG9wTm9kZS5wcmV2aW91c1NpYmxpbmcsIGRpc3QgPSBvZmZzZXQ7IGJlZm9yZTsgYmVmb3JlID0gYmVmb3JlLnByZXZpb3VzU2libGluZykge1xuICAgICAgZm91bmQgPSBmaW5kKGJlZm9yZSwgYmVmb3JlLmZpcnN0Q2hpbGQsIC0xKTtcbiAgICAgIGlmIChmb3VuZClcbiAgICAgICAgcmV0dXJuIGJhZFBvcyhQb3MoZm91bmQubGluZSwgZm91bmQuY2ggKyBkaXN0KSwgYmFkKTtcbiAgICAgIGVsc2VcbiAgICAgICAgZGlzdCArPSBhZnRlci50ZXh0Q29udGVudC5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZG9tVGV4dEJldHdlZW4oY20sIGZyb20sIHRvLCBmcm9tTGluZSwgdG9MaW5lKSB7XG4gICAgdmFyIHRleHQgPSBcIlwiLCBjbG9zaW5nID0gZmFsc2UsIGxpbmVTZXAgPSBjbS5kb2MubGluZVNlcGFyYXRvcigpO1xuICAgIGZ1bmN0aW9uIHJlY29nbml6ZU1hcmtlcihpZCkgeyByZXR1cm4gZnVuY3Rpb24obWFya2VyKSB7IHJldHVybiBtYXJrZXIuaWQgPT0gaWQ7IH07IH1cbiAgICBmdW5jdGlvbiB3YWxrKG5vZGUpIHtcbiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDEpIHtcbiAgICAgICAgdmFyIGNtVGV4dCA9IG5vZGUuZ2V0QXR0cmlidXRlKFwiY20tdGV4dFwiKTtcbiAgICAgICAgaWYgKGNtVGV4dCAhPSBudWxsKSB7XG4gICAgICAgICAgaWYgKGNtVGV4dCA9PSBcIlwiKSBjbVRleHQgPSBub2RlLnRleHRDb250ZW50LnJlcGxhY2UoL1xcdTIwMGIvZywgXCJcIik7XG4gICAgICAgICAgdGV4dCArPSBjbVRleHQ7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtYXJrZXJJRCA9IG5vZGUuZ2V0QXR0cmlidXRlKFwiY20tbWFya2VyXCIpLCByYW5nZTtcbiAgICAgICAgaWYgKG1hcmtlcklEKSB7XG4gICAgICAgICAgdmFyIGZvdW5kID0gY20uZmluZE1hcmtzKFBvcyhmcm9tTGluZSwgMCksIFBvcyh0b0xpbmUgKyAxLCAwKSwgcmVjb2duaXplTWFya2VyKCttYXJrZXJJRCkpO1xuICAgICAgICAgIGlmIChmb3VuZC5sZW5ndGggJiYgKHJhbmdlID0gZm91bmRbMF0uZmluZCgpKSlcbiAgICAgICAgICAgIHRleHQgKz0gZ2V0QmV0d2VlbihjbS5kb2MsIHJhbmdlLmZyb20sIHJhbmdlLnRvKS5qb2luKGxpbmVTZXApO
234591xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9kZS5nZXRBdHRyaWJ1dGUoXCJjb250ZW50ZWRpdGFibGVcIikgPT0gXCJmYWxzZVwiKSByZXR1cm47XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKVxuICAgICAgICAgIHdhbGsobm9kZS5jaGlsZE5vZGVzW2ldKTtcbiAgICAgICAgaWYgKC9eKHByZXxkaXZ8cCkkL2kudGVzdChub2RlLm5vZGVOYW1lKSlcbiAgICAgICAgICBjbG9zaW5nID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSBpZiAobm9kZS5ub2RlVHlwZSA9PSAzKSB7XG4gICAgICAgIHZhciB2YWwgPSBub2RlLm5vZGVWYWx1ZTtcbiAgICAgICAgaWYgKCF2YWwpIHJldHVybjtcbiAgICAgICAgaWYgKGNsb3NpbmcpIHtcbiAgICAgICAgICB0ZXh0ICs9IGxpbmVTZXA7XG4gICAgICAgICAgY2xvc2luZyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHRleHQgKz0gdmFsO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKDs7KSB7XG4gICAgICB3YWxrKGZyb20pO1xuICAgICAgaWYgKGZyb20gPT0gdG8pIGJyZWFrO1xuICAgICAgZnJvbSA9IGZyb20ubmV4dFNpYmxpbmc7XG4gICAgfVxuICAgIHJldHVybiB0ZXh0O1xuICB9XG5cbiAgQ29kZU1pcnJvci5pbnB1dFN0eWxlcyA9IHtcInRleHRhcmVhXCI6IFRleHRhcmVhSW5wdXQsIFwiY29udGVudGVkaXRhYmxlXCI6IENvbnRlbnRFZGl0YWJsZUlucHV0fTtcblxuICAvLyBTRUxFQ1RJT04gLyBDVVJTT1JcblxuICAvLyBTZWxlY3Rpb24gb2JqZWN0cyBhcmUgaW1tdXRhYmxlLiBBIG5ldyBvbmUgaXMgY3JlYXRlZCBldmVyeSB0aW1lXG4gIC8vIHRoZSBzZWxlY3Rpb24gY2hhbmdlcy4gQSBzZWxlY3Rpb24gaXMgb25lIG9yIG1vcmUgbm9uLW92ZXJsYXBwaW5nXG4gIC8vIChhbmQgbm9uLXRvdWNoaW5nKSByYW5nZXMsIHNvcnRlZCwgYW5kIGFuIGludGVnZXIgdGhhdCBpbmRpY2F0ZXNcbiAgLy8gd2hpY2ggb25lIGlzIHRoZSBwcmltYXJ5IHNlbGVjdGlvbiAodGhlIG9uZSB0aGF0J3Mgc2Nyb2xsZWQgaW50b1xuICAvLyB2aWV3LCB0aGF0IGdldEN1cnNvciByZXR1cm5zLCBldGMpLlxuICBmdW5jdGlvbiBTZWxlY3Rpb24ocmFuZ2VzLCBwcmltSW5kZXgpIHtcbiAgICB0aGlzLnJhbmdlcyA9IHJhbmdlcztcbiAgICB0aGlzLnByaW1JbmRleCA9IHByaW1JbmRleDtcbiAgfVxuXG4gIFNlbGVjdGlvbi5wcm90b3R5cGUgPSB7XG4gICAgcHJpbWFyeTogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLnJhbmdlc1t0aGlzLnByaW1JbmRleF07IH0sXG4gICAgZXF1YWxzOiBmdW5jdGlvbihvdGhlcikge1xuICAgICAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybiB0cnVlO1xuICAgICAgaWYgKG90aGVyLnByaW1JbmRleCAhPSB0aGlzLnByaW1JbmRleCB8fCBvdGhlci5yYW5nZXMubGVuZ3RoICE9IHRoaXMucmFuZ2VzLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2Y
23459XIgaGVyZSA9IHRoaXMucmFuZ2VzW2ldLCB0aGVyZSA9IG90aGVyLnJhbmdlc1tpXTtcbiAgICAgICAgaWYgKGNtcChoZXJlLmFuY2hvciwgdGhlcmUuYW5jaG9yKSAhPSAwIHx8IGNtcChoZXJlLmhlYWQsIHRoZXJlLmhlYWQpICE9IDApIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG4gICAgZGVlcENvcHk6IGZ1bmN0aW9uKCkge1xuICAgICAgZm9yICh2YXIgb3V0ID0gW10sIGkgPSAwOyBpIDwgdGhpcy5yYW5nZXMubGVuZ3RoOyBpKyspXG4gICAgICAgIG91dFtpXSA9IG5ldyBSYW5nZShjb3B5UG9zKHRoaXMucmFuZ2VzW2ldLmFuY2hvciksIGNvcHlQb3ModGhpcy5yYW5nZXNbaV0uaGVhZCkpO1xuICAgICAgcmV0dXJuIG5ldyBTZWxlY3Rpb24ob3V0LCB0aGlzLnByaW1JbmRleCk7XG4gICAgfSxcbiAgICBzb21ldGhpbmdTZWxlY3RlZDogZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucmFuZ2VzLmxlbmd0aDsgaSsrKVxuICAgICAgICBpZiAoIXRoaXMucmFuZ2VzW2ldLmVtcHR5KCkpIHJldHVybiB0cnVlO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG4gICAgY29udGFpbnM6IGZ1bmN0aW9uKHBvcywgZW5kKSB7XG4gICAgICBpZiAoIWVuZCkgZW5kID0gcG9zO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLnJhbmdlc1tpXTtcbiAgICAgICAgaWYgKGNtcChlbmQsIHJhbmdlLmZyb20oKSkgPj0gMCAmJiBjbXAocG9zLCByYW5nZS50bygpKSA8PSAwKVxuICAgICAgICAgIHJldHVybiBpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBSYW5nZShhbmNob3IsIGhlYWQpIHtcbiAgICB0aGlzLmFuY2hvciA9IGFuY2hvcjsgdGhpcy5oZWFkID0gaGVhZDtcbiAgfVxuXG4gIFJhbmdlLnByb3RvdHlwZSA9IHtcbiAgICBmcm9tOiBmdW5jdGlvbigpIHsgcmV0dXJuIG1pblBvcyh0aGlzLmFuY2hvciwgdGhpcy5oZWFkKTsgfSxcbiAgICB0bzogZnVuY3Rpb24oKSB7IHJldHVybiBtYXhQb3ModGhpcy5hbmNob3IsIHRoaXMuaGVhZCk7IH0sXG4gICAgZW1wdHk6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuaGVhZC5saW5lID09IHRoaXMuYW5jaG9yLmxpbmUgJiYgdGhpcy5oZWFkLmNoID09IHRoaXMuYW5jaG9yLmNoO1xuICAgIH1cbiAgfTtcblxuICAvLyBUYWtlIGFuIHVuc29ydGVkLCBwb3RlbnRpYWxseSBvdmVybGFwcGluZyBzZXQgb2YgcmFuZ2VzLCBhbmRcbiAgLy8gYnVpbGQgYSBzZWxlY3Rpb24gb3V0IG9mIGl0LiAnQ29uc3VtZXMnIHJhbmdlcyBhcnJheSAobW9kaWZ5aW5nXG4gIC8vIGl0KS5cbiAgZnVuY3Rpb24gbm9ybWFsaXplU2VsZWN0aW9uKHJhbmdlcywgcHJpbUluZGV4KSB7XG4gICAgdmFyIHByaW0gPSByYW5nZXNbcHJpbUluZGV4XTtcbiAgICByYW5nZXMuc29ydChmdW5jdGlvbihhLCBiKSB7IHJldHVybiBjbXAoYS5mcm9tKCksIGIuZnJvbSgpKTsgfSk7XG4gICAgcHJpbUluZGV4ID0gaW5kZXhPZihyYW5nZXMsIHByaW0pO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2Y
23459XIgY3VyID0gcmFuZ2VzW2ldLCBwcmV2ID0gcmFuZ2VzW2kgLSAxXTtcbiAgICAgIGlmIChjbXAocHJldi50bygpLCBjdXIuZnJvbSgpKSA+PSAwKSB7XG4gICAgICAgIHZhciBmcm9tID0gbWluUG9zKHByZXYuZnJvbSgpLCBjdXIuZnJvbSgpKSwgdG8gPSBtYXhQb3MocHJldi50bygpLCBjdXIudG8oKSk7XG4gICAgICAgIHZhciBpbnYgPSBwcmV2LmVtcHR5KCkgPyBjdXIuZnJvbSgpID09IGN1ci5oZWFkIDogcHJldi5mcm9tKCkgPT0gcHJldi5oZWFkO1xuICAgICAgICBpZiAoaSA8PSBwcmltSW5kZXgpIC0tcHJpbUluZGV4O1xuICAgICAgICByYW5nZXMuc3BsaWNlKC0taSwgMiwgbmV3IFJhbmdlKGludiA/IHRvIDogZnJvbSwgaW52ID8gZnJvbSA6IHRvKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgU2VsZWN0aW9uKHJhbmdlcywgcHJpbUluZGV4KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNpbXBsZVNlbGVjdGlvbihhbmNob3IsIGhlYWQpIHtcbiAgICByZXR1cm4gbmV3IFNlbGVjdGlvbihbbmV3IFJhbmdlKGFuY2hvciwgaGVhZCB8fCBhbmNob3IpXSwgMCk7XG4gIH1cblxuICAvLyBNb3N0IG9mIHRoZSBleHRlcm5hbCBBUEkgY2xpcHMgZ2l2ZW4gcG9zaXRpb25zIHRvIG1ha2Ugc3VyZSB0aGV5XG4gIC8vIGFjdHVhbGx5IGV4aXN0IHdpdGhpbiB0aGUgZG9jdW1lbnQuXG4gIGZ1bmN0aW9uIGNsaXBMaW5lKGRvYywgbikge3JldHVybiBNYXRoLm1heChkb2MuZmlyc3QsIE1hdGgubWluKG4sIGRvYy5maXJzdCArIGRvYy5zaXplIC0gMSkpO31cbiAgZnVuY3Rpb24gY2xpcFBvcyhkb2MsIHBvcykge1xuICAgIGlmIChwb3MubGluZSA8IGRvYy5maXJzdCkgcmV0dXJuIFBvcyhkb2MuZmlyc3QsIDApO1xuICAgIHZhciBsYXN0ID0gZG9jLmZpcnN0ICsgZG9jLnNpemUgLSAxO1xuICAgIGlmIChwb3MubGluZSA+IGxhc3QpIHJldHVybiBQb3MobGFzdCwgZ2V0TGluZShkb2MsIGxhc3QpLnRleHQubGVuZ3RoKTtcbiAgICByZXR1cm4gY2xpcFRvTGVuKHBvcywgZ2V0TGluZShkb2MsIHBvcy5saW5lKS50ZXh0Lmxlbmd0aCk7XG4gIH1cbiAgZnVuY3Rpb24gY2xpcFRvTGVuKHBvcywgbGluZWxlbikge1xuICAgIHZhciBjaCA9IHBvcy5jaDtcbiAgICBpZiAoY2ggPT0gbnVsbCB8fCBjaCA+IGxpbmVsZW4pIHJldHVybiBQb3MocG9zLmxpbmUsIGxpbmVsZW4pO1xuICAgIGVsc2UgaWYgKGNoIDwgMCkgcmV0dXJuIFBvcyhwb3MubGluZSwgMCk7XG4gICAgZWxzZSByZXR1cm4gcG9zO1xuICB9XG4gIGZ1bmN0aW9uIGlzTGluZShkb2MsIGwpIHtyZXR1cm4gbCA+PSBkb2MuZmlyc3QgJiYgbCA8IGRvYy5maXJzdCArIGRvYy5zaXplO31cbiAgZnVuY3Rpb24gY2xpcFBvc0FycmF5KGRvYywgYXJyYXkpIHtcbiAgICBmb3IgKHZhciBvdXQgPSBbXSwgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgb3V0W2ldID0gY2xpcFBvcyhkb2MsIGFycmF5W2ldKTtcbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgLy8gU0VMRUNUSU9OIFVQREFURVNcblxuICAvLyBUaGUgJ3Njcm9sbCcgcGFyYW1ldGVyIGdpdmVuIHRvIG1hbnkgb2YgdGhlc2UgaW5kaWNhdGVkIHdoZXRoZXJcbiAgLy8gdGhlIG5ldyBjdXJzb3IgcG9zaXRpb24gc2hvdWxkIGJlIHNjcm9sbGVkIGludG8gdmlldyBhZnRlclxuICAvLyBtb2RpZnlpbmcgdGhlIHNlbGVjdGlvbi5cblxuICAvLyBJZiBzaGlmdCBpcyBoZWxkIG9yIHRoZSBleHRlbmQgZmxhZyBpcyBzZXQsIGV4dGVuZHMgYSByYW5nZSB0b1xuICAvLyBpbmNsdWRlIGEgZ2l2ZW4gcG9zaXRpb24gKGFuZCBvcHRpb25hbGx5IGEgc2Vjb25kIHBvc2l0aW9uKS5cbiAgLy8gT3RoZXJ3aXNlLCBzaW1wbHkgcmV0dXJucyB0aGUgcmFuZ2UgYmV0d2VlbiB0aGUgZ2l2ZW4gcG9zaXRpb25zLlxuICAvLyBVc2VkIGZvciBjdXJzb3IgbW90aW9uIGFuZCBzdWNoLlxuICBmdW5jdGlvbiBleHRlbmRSYW5nZShkb2MsIHJhbmdlLCBoZWFkLCBvdGhlcikge1xuICAgIGlmIChkb2MuY20gJiYgZG9jLmNtLmRpc3BsYXkuc2hpZnQgfHwgZG9jLmV4dGVuZCkge1xuICAgICAgdmFyIGFuY2hvciA9IHJhbmdlLmFuY2hvcjtcbiAgICAgIGlmIChvdGhlcikge1xuICAgICAgICB2Y
23459XIgcG9zQmVmb3JlID0gY21wKGhlYWQsIGFuY2hvcikgPCAwO1xuICAgICAgICBpZiAocG9zQmVmb3JlICE9IChjbXAob3RoZXIsIGFuY2hvcikgPCAwKSkge1xuICAgICAgICAgIGFuY2hvciA9IGhlYWQ7XG4gICAgICAgICAgaGVhZCA9IG90aGVyO1xuICAgICAgICB9IGVsc2UgaWYgKHBvc0JlZm9yZSAhPSAoY21wKGhlYWQsIG90aGVyKSA8IDApKSB7XG4gICAgICAgICAgaGVhZCA9IG90aGVyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFJhbmdlKGFuY2hvciwgaGVhZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgUmFuZ2Uob3RoZXIgfHwgaGVhZCwgaGVhZCk7XG4gICAgfVxuICB9XG5cbiAgLy8gRXh0ZW5kIHRoZSBwcmltYXJ5IHNlbGVjdGlvbiByYW5nZSwgZGlzY2FyZCB0aGUgcmVzdC5cbiAgZnVuY3Rpb24gZXh0ZW5kU2VsZWN0aW9uKGRvYywgaGVhZCwgb3RoZXIsIG9wdGlvbnMpIHtcbiAgICBzZXRTZWxlY3Rpb24oZG9jLCBuZXcgU2VsZWN0aW9uKFtleHRlbmRSYW5nZShkb2MsIGRvYy5zZWwucHJpbWFyeSgpLCBoZWFkLCBvdGhlcildLCAwKSwgb3B0aW9ucyk7XG4gIH1cblxuICAvLyBFeHRlbmQgYWxsIHNlbGVjdGlvbnMgKHBvcyBpcyBhbiBhcnJheSBvZiBzZWxlY3Rpb25zIHdpdGggbGVuZ3RoXG4gIC8vIGVxdWFsIHRoZSBudW1iZXIgb2Ygc2VsZWN0aW9ucylcbiAgZnVuY3Rpb24gZXh0ZW5kU2VsZWN0aW9ucyhkb2MsIGhlYWRzLCBvcHRpb25zKSB7XG4gICAgZm9yICh2YXIgb3V0ID0gW10sIGkgPSAwOyBpIDwgZG9jLnNlbC5yYW5nZXMubGVuZ3RoOyBpKyspXG4gICAgICBvdXRbaV0gPSBleHRlbmRSYW5nZShkb2MsIGRvYy5zZWwucmFuZ2VzW2ldLCBoZWFkc1tpXSwgbnVsbCk7XG4gICAgdmFyIG5ld1NlbCA9IG5vcm1hbGl6ZVNlbGVjdGlvbihvdXQsIGRvYy5zZWwucHJpbUluZGV4KTtcbiAgICBzZXRTZWxlY3Rpb24oZG9jLCBuZXdTZWwsIG9wdGlvbnMpO1xuICB9XG5cbiAgLy8gVXBkYXRlcyBhIHNpbmdsZSByYW5nZSBpbiB0aGUgc2VsZWN0aW9uLlxuICBmdW5jdGlvbiByZXBsYWNlT25lU2VsZWN0aW9uKGRvYywgaSwgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgICB2YXIgcmFuZ2VzID0gZG9jLnNlbC5yYW5nZXMuc2xpY2UoMCk7XG4gICAgcmFuZ2VzW2ldID0gcmFuZ2U7XG4gICAgc2V0U2VsZWN0aW9uKGRvYywgbm9ybWFsaXplU2VsZWN0aW9uKHJhbmdlcywgZG9jLnNlbC5wcmltSW5kZXgpLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8vIFJlc2V0IHRoZSBzZWxlY3Rpb24gdG8gYSBzaW5nbGUgcmFuZ2UuXG4gIGZ1bmN0aW9uIHNldFNpbXBsZVNlbGVjdGlvbihkb2MsIGFuY2hvciwgaGVhZCwgb3B0aW9ucykge1xuICAgIHNldFNlbGVjdGlvbihkb2MsIHNpbXBsZVNlbGVjdGlvbihhbmNob3IsIGhlYWQpLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8vIEdpdmUgYmVmb3JlU2VsZWN0aW9uQ2hhbmdlIGhhbmRsZXJzIGEgY2hhbmdlIHRvIGluZmx1ZW5jZSBhXG4gIC8vIHNlbGVjdGlvbiB1cGRhdGUuXG4gIGZ1bmN0aW9uIGZpbHRlclNlbGVjdGlvbkNoYW5nZShkb2MsIHNlbCkge1xuICAgIHZhciBvYmogPSB7XG4gICAgICByYW5nZXM6IHNlbC5yYW5nZXMsXG4gICAgICB1cGRhdGU6IGZ1bmN0aW9uKHJhbmdlcykge1xuICAgICAgICB0aGlzLnJhbmdlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICB0aGlzLnJhbmdlc1tpXSA9IG5ldyBSYW5nZShjbGlwUG9zKGRvYywgcmFuZ2VzW2ldLmFuY2hvciksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcFBvcyhkb2MsIHJhbmdlc1tpXS5oZWFkKSk7XG4gICAgICB9XG4gICAgfTtcbiAgICBzaWduYWwoZG9jLCBcImJlZm9yZVNlbGVjdGlvbkNoYW5nZVwiLCBkb2MsIG9iaik7XG4gICAgaWYgKGRvYy5jbSkgc2lnbmFsKGRvYy5jbSwgXCJiZWZvcmVTZWxlY3Rpb25DaGFuZ2VcIiwgZG9jLmNtLCBvYmopO1xuICAgIGlmIChvYmoucmFuZ2VzICE9IHNlbC5yYW5nZXMpIHJldHVybiBub3JtYWxpemVTZWxlY3Rpb24ob2JqLnJhbmdlcywgb2JqLnJhbmdlcy5sZW5ndGggLSAxKTtcbiAgICBlbHNlIHJldHVybiBzZWw7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRTZWxlY3Rpb25SZXBsYWNlSGlzdG9yeShkb2MsIHNlbCwgb3B0aW9ucykge1xuICAgIHZhciBkb25lID0gZG9jLmhpc3RvcnkuZG9uZSwgbGFzdCA9IGxzdChkb25lKTtcbiAgICBpZiAobGFzdCAmJiBsYXN0LnJhbmdlcykge1xuICAgICAgZG9uZVtkb25lLmxlbmd0aCAtIDFdID0gc2VsO1xuICAgICAgc2V0U2VsZWN0aW9uTm9VbmRvKGRvYywgc2VsLCBvcHRpb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2V0U2VsZWN0aW9uKGRvYywgc2VsLCBvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvLyBTZXQgYSBuZXcgc2VsZWN0aW9uLlxuICBmdW5jdGlvbiBzZXRTZWxlY3Rpb24oZG9jLCBzZWwsIG9wdGlvbnMpIHtcbiAgICBzZXRTZWxlY3Rpb25Ob1VuZG8oZG9jLCBzZWwsIG9wdGlvbnMpO1xuICAgIGFkZFNlbGVjdGlvblRvSGlzdG9yeShkb2MsIGRvYy5zZWwsIGRvYy5jbSA/IGRvYy5jbS5jdXJPcC5pZCA6IE5hTiwgb3B0aW9ucyk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRTZWxlY3Rpb25Ob1VuZG8oZG9jLCBzZWwsIG9wdGlvbnMpIHtcbiAgICBpZiAoaGFzSGFuZGxlcihkb2MsIFwiYmVmb3JlU2VsZWN0aW9uQ2hhbmdlXCIpIHx8IGRvYy5jbSAmJiBoYXNIYW5kbGVyKGRvYy5jbSwgXCJiZWZvcmVTZWxlY3Rpb25DaGFuZ2VcIikpXG4gICAgICBzZWwgPSBmaWx0ZXJTZWxlY3Rpb25DaGFuZ2UoZG9jLCBzZWwpO1xuXG4gICAgdmFyIGJpYXMgP
23459SBvcHRpb25zICYmIG9wdGlvbnMuYmlhcyB8fFxuICAgICAgKGNtcChzZWwucHJpbWFyeSgpLmhlYWQsIGRvYy5zZWwucHJpbWFyeSgpLmhlYWQpIDwgMCA/IC0xIDogMSk7XG4gICAgc2V0U2VsZWN0aW9uSW5uZXIoZG9jLCBza2lwQXRvbWljSW5TZWxlY3Rpb24oZG9jLCBzZWwsIGJpYXMsIHRydWUpKTtcblxuICAgIGlmICghKG9wdGlvbnMgJiYgb3B0aW9ucy5zY3JvbGwgPT09IGZhbHNlKSAmJiBkb2MuY20pXG4gICAgICBlbnN1cmVDdXJzb3JWaXNpYmxlKGRvYy5jbSk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRTZWxlY3Rpb25Jbm5lcihkb2MsIHNlbCkge1xuICAgIGlmIChzZWwuZXF1YWxzKGRvYy5zZWwpKSByZXR1cm47XG5cbiAgICBkb2Muc2VsID0gc2VsO1xuXG4gICAgaWYgKGRvYy5jbSkge1xuICAgICAgZG9jLmNtLmN1ck9wLnVwZGF0ZUlucHV0ID0gZG9jLmNtLmN1ck9wLnNlbGVjdGlvbkNoYW5nZWQgPSB0cnVlO1xuICAgICAgc2lnbmFsQ3Vyc29yQWN0aXZpdHkoZG9jLmNtKTtcbiAgICB9XG4gICAgc2lnbmFsTGF0ZXIoZG9jLCBcImN1cnNvckFjdGl2aXR5XCIsIGRvYyk7XG4gIH1cblxuICAvLyBWZXJpZnkgdGhhdCB0aGUgc2VsZWN0aW9uIGRvZXMgbm90IHBhcnRpYWxseSBzZWxlY3QgYW55IGF0b21pY1xuICAvLyBtYXJrZWQgcmFuZ2VzLlxuICBmdW5jdGlvbiByZUNoZWNrU2VsZWN0aW9uKGRvYykge1xuICAgIHNldFNlbGVjdGlvbklubmVyKGRvYywgc2tpcEF0b21pY0luU2VsZWN0aW9uKGRvYywgZG9jLnNlbCwgbnVsbCwgZmFsc2UpLCBzZWxfZG9udFNjcm9sbCk7XG4gIH1cblxuICAvLyBSZXR1cm4gYSBzZWxlY3Rpb24gdGhhdCBkb2VzIG5vdCBwYXJ0aWFsbHkgc2VsZWN0IGFueSBhdG9taWNcbiAgLy8gcmFuZ2VzLlxuICBmdW5jdGlvbiBza2lwQXRvbWljSW5TZWxlY3Rpb24oZG9jLCBzZWwsIGJpYXMsIG1heUNsZWFyKSB7XG4gICAgdmFyIG91dDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlbC5yYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciByYW5nZSA9IHNlbC5yYW5nZXNbaV07XG4gICAgICB2Y
23459XIgbmV3QW5jaG9yID0gc2tpcEF0b21pYyhkb2MsIHJhbmdlLmFuY2hvciwgYmlhcywgbWF5Q2xlYXIpO1xuICAgICAgdmFyIG5ld0hlYWQgPSBza2lwQXRvbWljKGRvYywgcmFuZ2UuaGVhZCwgYmlhcywgbWF5Q2xlYXIpO1xuICAgICAgaWYgKG91dCB8fCBuZXdBbmNob3IgIT0gcmFuZ2UuYW5jaG9yIHx8IG5ld0hlYWQgIT0gcmFuZ2UuaGVhZCkge1xuICAgICAgICBpZiAoIW91dCkgb3V0ID0gc2VsLnJhbmdlcy5zbGljZSgwLCBpKTtcbiAgICAgICAgb3V0W2ldID0gbmV3IFJhbmdlKG5ld0FuY2hvciwgbmV3SGVhZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXQgPyBub3JtYWxpemVTZWxlY3Rpb24ob3V0LCBzZWwucHJpbUluZGV4KSA6IHNlbDtcbiAgfVxuXG4gIC8vIEVuc3VyZSBhIGdpdmVuIHBvc2l0aW9uIGlzIG5vdCBpbnNpZGUgYW4gYXRvbWljIHJhbmdlLlxuICBmdW5jdGlvbiBza2lwQXRvbWljKGRvYywgcG9zLCBiaWFzLCBtYXlDbGVhcikge1xuICAgIHZhciBmbGlwcGVkID0gZmFsc2UsIGN1clBvcyA9IHBvcztcbiAgICB2YXIgZGlyID0gYmlhcyB8fCAxO1xuICAgIGRvYy5jYW50RWRpdCA9IGZhbHNlO1xuICAgIHNlYXJjaDogZm9yICg7Oykge1xuICAgICAgdmFyIGxpbmUgPSBnZXRMaW5lKGRvYywgY3VyUG9zLmxpbmUpO1xuICAgICAgaWYgKGxpbmUubWFya2VkU3BhbnMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lLm1hcmtlZFNwYW5zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIHNwID0gbGluZS5tYXJrZWRTcGFuc1tpXSwgbSA9IHNwLm1hcmtlcjtcbiAgICAgICAgICBpZiAoKHNwLmZyb20gPT0gbnVsbCB8fCAobS5pbmNsdXNpdmVMZWZ0ID8gc3AuZnJvbSA8PSBjdXJQb3MuY2ggOiBzcC5mcm9tIDwgY3VyUG9zLmNoKSkgJiZcbiAgICAgICAgICAgICAgKHNwLnRvID09IG51bGwgfHwgKG0uaW5jbHVzaXZlUmlnaHQgPyBzcC50byA+PSBjdXJQb3MuY2ggOiBzcC50byA+IGN1clBvcy5jaCkpKSB7XG4gICAgICAgICAgICBpZiAobWF5Q2xlYXIpIHtcbiAgICAgICAgICAgICAgc2lnbmFsKG0sIFwiYmVmb3JlQ3Vyc29yRW50ZXJcIik7XG4gICAgICAgICAgICAgIGlmIChtLmV4cGxpY2l0bHlDbGVhcmVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsaW5lLm1hcmtlZFNwYW5zKSBicmVhaztcbiAgICAgICAgICAgICAgICBlbHNlIHstLWk7IGNvbnRpbnVlO31cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFtLmF0b21pYykgY29udGludWU7XG4gICAgICAgICAgICB2Y
23459XIgbmV3UG9zID0gbS5maW5kKGRpciA8IDAgPyAtMSA6IDEpO1xuICAgICAgICAgICAgaWYgKGNtcChuZXdQb3MsIGN1clBvcykgPT0gMCkge1xuICAgICAgICAgICAgICBuZXdQb3MuY2ggKz0gZGlyO1xuICAgICAgICAgICAgICBpZiAobmV3UG9zLmNoIDwgMCkge1xuICAgICAgICAgICAgICAgIGlmIChuZXdQb3MubGluZSA+IGRvYy5maXJzdCkgbmV3UG9zID0gY2xpcFBvcyhkb2MsIFBvcyhuZXdQb3MubGluZSAtIDEpKTtcbiAgICAgICAgICAgICAgICBlbHNlIG5ld1BvcyA9IG51bGw7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3UG9zLmNoID4gbGluZS50ZXh0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGlmIChuZXdQb3MubGluZSA8IGRvYy5maXJzdCArIGRvYy5zaXplIC0gMSkgbmV3UG9zID0gUG9zKG5ld1Bvcy5saW5lICsgMSwgMCk7XG4gICAgICAgICAgICAgICAgZWxzZSBuZXdQb3MgPSBudWxsO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmICghbmV3UG9zKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZsaXBwZWQpIHtcbiAgICAgICAgICAgICAgICAgIC8vIERyaXZlbiBpbiBhIGNvcm5lciAtLSBubyB2YWxpZCBjdXJzb3IgcG9zaXRpb24gZm91bmQgYXQgYWxsXG4gICAgICAgICAgICAgICAgICAvLyAtLSB0cnkgYWdhaW4gKndpdGgqIGNsZWFyaW5nLCBpZiB3ZSBkaWRuJ3QgYWxyZWFkeVxuICAgICAgICAgICAgICAgICAgaWYgKCFtYXlDbGVhcikgcmV0dXJuIHNraXBBdG9taWMoZG9jLCBwb3MsIGJpYXMsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCB0dXJuIG9mZiBlZGl0aW5nIHVudGlsIGZ1cnRoZXIgbm90aWNlLCBhbmQgcmV0dXJuIHRoZSBzdGFydCBvZiB0aGUgZG9jXG4gICAgICAgICAgICAgICAgICBkb2MuY2FudEVkaXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIFBvcyhkb2MuZmlyc3QsIDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmbGlwcGVkID0gdHJ1ZTsgbmV3UG9zID0gcG9zOyBkaXIgPSAtZGlyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJQb3MgPSBuZXdQb3M7XG4gICAgICAgICAgICBjb250aW51ZSBzZWFyY2g7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gY3VyUG9zO1xuICAgIH1cbiAgfVxuXG4gIC8vIFNFTEVDVElPTiBEUkFXSU5HXG5cbiAgZnVuY3Rpb24gdXBkYXRlU2VsZWN0aW9uKGNtKSB7XG4gICAgY20uZGlzcGxheS5pbnB1dC5zaG93U2VsZWN0aW9uKGNtLmRpc3BsYXkuaW5wdXQucHJlcGFyZVNlbGVjdGlvbigpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByZXBhcmVTZWxlY3Rpb24oY20sIHByaW1hcnkpIHtcbiAgICB2YXIgZG9jID0gY20uZG9jLCByZXN1bHQgPSB7fTtcbiAgICB2YXIgY3VyRnJhZ21lbnQgPSByZXN1bHQuY3Vyc29ycyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICB2YXIgc2VsRnJhZ21lbnQgPSByZXN1bHQuc2VsZWN0aW9uID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkb2Muc2VsLnJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHByaW1hcnkgPT09IGZhbHNlICYmIGkgPT0gZG9jLnNlbC5wcmltSW5kZXgpIGNvbnRpbnVlO1xuICAgICAgdmFyIHJhbmdlID0gZG9jLnNlbC5yYW5nZXNbaV07XG4gICAgICB2Y
23459XIgY29sbGFwc2VkID0gcmFuZ2UuZW1wdHkoKTtcbiAgICAgIGlmIChjb2xsYXBzZWQgfHwgY20ub3B0aW9ucy5zaG93Q3Vyc29yV2hlblNlbGVjdGluZylcbiAgICAgICAgZHJhd1NlbGVjdGlvbkN1cnNvcihjbSwgcmFuZ2UuaGVhZCwgY3VyRnJhZ21lbnQpO1xuICAgICAgaWYgKCFjb2xsYXBzZWQpXG4gICAgICAgIGRyYXdTZWxlY3Rpb25SYW5nZShjbSwgcmFuZ2UsIHNlbEZyYWdtZW50KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIERyYXdzIGEgY3Vyc29yIGZvciB0aGUgZ2l2ZW4gcmFuZ2VcbiAgZnVuY3Rpb24gZHJhd1NlbGVjdGlvbkN1cnNvcihjbSwgaGVhZCwgb3V0cHV0KSB7XG4gICAgdmFyIHBvcyA9IGN1cnNvckNvb3JkcyhjbSwgaGVhZCwgXCJkaXZcIiwgbnVsbCwgbnVsbCwgIWNtLm9wdGlvbnMuc2luZ2xlQ3Vyc29ySGVpZ2h0UGVyTGluZSk7XG5cbiAgICB2YXIgY3Vyc29yID0gb3V0cHV0LmFwcGVuZENoaWxkKGVsdChcImRpdlwiLCBcIlxcdTAwYTBcIiwgXCJDb2RlTWlycm9yLWN1cnNvclwiKSk7XG4gICAgY3Vyc29yLnN0eWxlLmxlZnQgPSBwb3MubGVmdCArIFwicHhcIjtcbiAgICBjdXJzb3Iuc3R5bGUudG9wID0gcG9zLnRvcCArIFwicHhcIjtcbiAgICBjdXJzb3Iuc3R5bGUuaGVpZ2h0ID0gTWF0aC5tYXgoMCwgcG9zLmJvdHRvbSAtIHBvcy50b3ApICogY20ub3B0aW9ucy5jdXJzb3JIZWlnaHQgKyBcInB4XCI7XG5cbiAgICBpZiAocG9zLm90aGVyKSB7XG4gICAgICAvLyBTZWNvbmRhcnkgY3Vyc29yLCBzaG93biB3aGVuIG9uIGEgJ2p1bXAnIGluIGJpLWRpcmVjdGlvbmFsIHRleHRcbiAgICAgIHZhciBvdGhlckN1cnNvciA9IG91dHB1dC5hcHBlbmRDaGlsZChlbHQoXCJkaXZcIiwgXCJcXHUwMGEwXCIsIFwiQ29kZU1pcnJvci1jdXJzb3IgQ29kZU1pcnJvci1zZWNvbmRhcnljdXJzb3JcIikpO1xuICAgICAgb3RoZXJDdXJzb3Iuc3R5bGUuZGlzcGxheSA9IFwiXCI7XG4gICAgICBvdGhlckN1cnNvci5zdHlsZS5sZWZ0ID0gcG9zLm90aGVyLmxlZnQgKyBcInB4XCI7XG4gICAgICBvdGhlckN1cnNvci5zdHlsZS50b3AgPSBwb3Mub3RoZXIudG9wICsgXCJweFwiO1xuICAgICAgb3RoZXJDdXJzb3Iuc3R5bGUuaGVpZ2h0ID0gKHBvcy5vdGhlci5ib3R0b20gLSBwb3Mub3RoZXIudG9wKSAqIC44NSArIFwicHhcIjtcbiAgICB9XG4gIH1cblxuICAvLyBEcmF3cyB0aGUgZ2l2ZW4gcmFuZ2UgYXMgYSBoaWdobGlnaHRlZCBzZWxlY3Rpb25cbiAgZnVuY3Rpb24gZHJhd1NlbGVjdGlvblJhbmdlKGNtLCByYW5nZSwgb3V0cHV0KSB7XG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCBkb2MgPSBjbS5kb2M7XG4gICAgdmFyIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgIHZhciBwYWRkaW5nID0gcGFkZGluZ0goY20uZGlzcGxheSksIGxlZnRTaWRlID0gcGFkZGluZy5sZWZ0O1xuICAgIHZhciByaWdodFNpZGUgPSBNYXRoLm1heChkaXNwbGF5LnNpemVyV2lkdGgsIGRpc3BsYXlXaWR0aChjbSkgLSBkaXNwbGF5LnNpemVyLm9mZnNldExlZnQpIC0gcGFkZGluZy5yaWdodDtcblxuICAgIGZ1bmN0aW9uIGFkZChsZWZ0LCB0b3AsIHdpZHRoLCBib3R0b20pIHtcbiAgICAgIGlmICh0b3AgPCAwKSB0b3AgPSAwO1xuICAgICAgdG9wID0gTWF0aC5yb3VuZCh0b3ApO1xuICAgICAgYm90dG9tID0gTWF0aC5yb3VuZChib3R0b20pO1xuICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoZWx0KFwiZGl2XCIsIG51bGwsIFwiQ29kZU1pcnJvci1zZWxlY3RlZFwiLCBcInBvc2l0aW9uOiBhYnNvbHV0ZTsgbGVmdDogXCIgKyBsZWZ0ICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInB4OyB0b3A6IFwiICsgdG9wICsgXCJweDsgd2lkdGg6IFwiICsgKHdpZHRoID09IG51bGwgPyByaWdodFNpZGUgLSBsZWZ0IDogd2lkdGgpICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInB4OyBoZWlnaHQ6IFwiICsgKGJvdHRvbSAtIHRvcCkgKyBcInB4XCIpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkcmF3Rm9yTGluZShsaW5lLCBmcm9tQXJnLCB0b0FyZykge1xuICAgICAgdmFyIGxpbmVPYmogPSBnZXRMaW5lKGRvYywgbGluZSk7XG4gICAgICB2Y
23459XIgbGluZUxlbiA9IGxpbmVPYmoudGV4dC5sZW5ndGg7XG4gICAgICB2YXIgc3RhcnQsIGVuZDtcbiAgICAgIGZ1bmN0aW9uIGNvb3JkcyhjaCwgYmlhcykge1xuICAgICAgICByZXR1cm4gY2hhckNvb3JkcyhjbSwgUG9zKGxpbmUsIGNoKSwgXCJkaXZcIiwgbGluZU9iaiwgYmlhcyk7XG4gICAgICB9XG5cbiAgICAgIGl0ZXJhdGVCaWRpU2VjdGlvbnMoZ2V0T3JkZXIobGluZU9iaiksIGZyb21BcmcgfHwgMCwgdG9BcmcgPT0gbnVsbCA/IGxpbmVMZW4gOiB0b0FyZywgZnVuY3Rpb24oZnJvbSwgdG8sIGRpcikge1xuICAgICAgICB2YXIgbGVmdFBvcyA9IGNvb3Jkcyhmcm9tLCBcImxlZnRcIiksIHJpZ2h0UG9zLCBsZWZ0LCByaWdodDtcbiAgICAgICAgaWYgKGZyb20gPT0gdG8pIHtcbiAgICAgICAgICByaWdodFBvcyA9IGxlZnRQb3M7XG4gICAgICAgICAgbGVmdCA9IHJpZ2h0ID0gbGVmdFBvcy5sZWZ0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJpZ2h0UG9zID0gY29vcmRzKHRvIC0gMSwgXCJyaWdodFwiKTtcbiAgICAgICAgICBpZiAoZGlyID09IFwicnRsXCIpIHsgdmFyIHRtcCA9IGxlZnRQb3M7IGxlZnRQb3MgPSByaWdodFBvczsgcmlnaHRQb3MgPSB0bXA7IH1cbiAgICAgICAgICBsZWZ0ID0gbGVmdFBvcy5sZWZ0O1xuICAgICAgICAgIHJpZ2h0ID0gcmlnaHRQb3MucmlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZyb21BcmcgPT0gbnVsbCAmJiBmcm9tID09IDApIGxlZnQgPSBsZWZ0U2lkZTtcbiAgICAgICAgaWYgKHJpZ2h0UG9zLnRvcCAtIGxlZnRQb3MudG9wID4gMykgeyAvLyBEaWZmZXJlbnQgbGluZXMsIGRyYXcgdG9wIHBhcnRcbiAgICAgICAgICBhZGQobGVmdCwgbGVmdFBvcy50b3AsIG51bGwsIGxlZnRQb3MuYm90dG9tKTtcbiAgICAgICAgICBsZWZ0ID0gbGVmdFNpZGU7XG4gICAgICAgICAgaWYgKGxlZnRQb3MuYm90dG9tIDwgcmlnaHRQb3MudG9wKSBhZGQobGVmdCwgbGVmdFBvcy5ib3R0b20sIG51bGwsIHJpZ2h0UG9zLnRvcCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRvQXJnID09IG51bGwgJiYgdG8gPT0gbGluZUxlbikgcmlnaHQgPSByaWdodFNpZGU7XG4gICAgICAgIGlmICghc3RhcnQgfHwgbGVmdFBvcy50b3AgPCBzdGFydC50b3AgfHwgbGVmdFBvcy50b3AgPT0gc3RhcnQudG9wICYmIGxlZnRQb3MubGVmdCA8IHN0YXJ0LmxlZnQpXG4gICAgICAgICAgc3RhcnQgPSBsZWZ0UG9zO1xuICAgICAgICBpZiAoIWVuZCB8fCByaWdodFBvcy5ib3R0b20gPiBlbmQuYm90dG9tIHx8IHJpZ2h0UG9zLmJvdHRvbSA9PSBlbmQuYm90dG9tICYmIHJpZ2h0UG9zLnJpZ2h0ID4gZW5kLnJpZ2h0KVxuICAgICAgICAgIGVuZCA9IHJpZ2h0UG9zO1xuICAgICAgICBpZiAobGVmdCA8IGxlZnRTaWRlICsgMSkgbGVmdCA9IGxlZnRTaWRlO1xuICAgICAgICBhZGQobGVmdCwgcmlnaHRQb3MudG9wLCByaWdodCAtIGxlZnQsIHJpZ2h0UG9zLmJvdHRvbSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7c3RhcnQ6IHN0YXJ0LCBlbmQ6IGVuZH07XG4gICAgfVxuXG4gICAgdmFyIHNGcm9tID0gcmFuZ2UuZnJvbSgpLCBzVG8gPSByYW5nZS50bygpO1xuICAgIGlmIChzRnJvbS5saW5lID09IHNUby5saW5lKSB7XG4gICAgICBkcmF3Rm9yTGluZShzRnJvbS5saW5lLCBzRnJvbS5jaCwgc1RvLmNoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGZyb21MaW5lID0gZ2V0TGluZShkb2MsIHNGcm9tLmxpbmUpLCB0b0xpbmUgPSBnZXRMaW5lKGRvYywgc1RvLmxpbmUpO1xuICAgICAgdmFyIHNpbmdsZVZMaW5lID0gdmlzdWFsTGluZShmcm9tTGluZSkgPT0gdmlzdWFsTGluZSh0b0xpbmUpO1xuICAgICAgdmFyIGxlZnRFbmQgPSBkcmF3Rm9yTGluZShzRnJvbS5saW5lLCBzRnJvbS5jaCwgc2luZ2xlVkxpbmUgPyBmcm9tTGluZS50ZXh0Lmxlbmd0aCArIDEgOiBudWxsKS5lbmQ7XG4gICAgICB2Y
23459XIgcmlnaHRTdGFydCA9IGRyYXdGb3JMaW5lKHNUby5saW5lLCBzaW5nbGVWTGluZSA/IDAgOiBudWxsLCBzVG8uY2gpLnN0YXJ0O1xuICAgICAgaWYgKHNpbmdsZVZMaW5lKSB7XG4gICAgICAgIGlmIChsZWZ0RW5kLnRvcCA8IHJpZ2h0U3RhcnQudG9wIC0gMikge1xuICAgICAgICAgIGFkZChsZWZ0RW5kLnJpZ2h0LCBsZWZ0RW5kLnRvcCwgbnVsbCwgbGVmdEVuZC5ib3R0b20pO1xuICAgICAgICAgIGFkZChsZWZ0U2lkZSwgcmlnaHRTdGFydC50b3AsIHJpZ2h0U3RhcnQubGVmdCwgcmlnaHRTdGFydC5ib3R0b20pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFkZChsZWZ0RW5kLnJpZ2h0LCBsZWZ0RW5kLnRvcCwgcmlnaHRTdGFydC5sZWZ0IC0gbGVmdEVuZC5yaWdodCwgbGVmdEVuZC5ib3R0b20pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobGVmdEVuZC5ib3R0b20gPCByaWdodFN0YXJ0LnRvcClcbiAgICAgICAgYWRkKGxlZnRTaWRlLCBsZWZ0RW5kLmJvdHRvbSwgbnVsbCwgcmlnaHRTdGFydC50b3ApO1xuICAgIH1cblxuICAgIG91dHB1dC5hcHBlbmRDaGlsZChmcmFnbWVudCk7XG4gIH1cblxuICAvLyBDdXJzb3ItYmxpbmtpbmdcbiAgZnVuY3Rpb24gcmVzdGFydEJsaW5rKGNtKSB7XG4gICAgaWYgKCFjbS5zdGF0ZS5mb2N1c2VkKSByZXR1cm47XG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5O1xuICAgIGNsZWFySW50ZXJ2YWwoZGlzcGxheS5ibGlua2VyKTtcbiAgICB2YXIgb24gPSB0cnVlO1xuICAgIGRpc3BsYXkuY3Vyc29yRGl2LnN0eWxlLnZpc2liaWxpdHkgPSBcIlwiO1xuICAgIGlmIChjbS5vcHRpb25zLmN1cnNvckJsaW5rUmF0ZSA+IDApXG4gICAgICBkaXNwbGF5LmJsaW5rZXIgPSBzZXRJbnRlcnZhbChmdW5jdGlvbigpIHtcbiAgICAgICAgZGlzcGxheS5jdXJzb3JEaXYuc3R5bGUudmlzaWJpbGl0eSA9IChvbiA9ICFvbikgPyBcIlwiIDogXCJoaWRkZW5cIjtcbiAgICAgIH0sIGNtLm9wdGlvbnMuY3Vyc29yQmxpbmtSYXRlKTtcbiAgICBlbHNlIGlmIChjbS5vcHRpb25zLmN1cnNvckJsaW5rUmF0ZSA8IDApXG4gICAgICBkaXNwbGF5LmN1cnNvckRpdi5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcbiAgfVxuXG4gIC8vIEhJR0hMSUdIVCBXT1JLRVJcblxuICBmdW5jdGlvbiBzdGFydFdvcmtlcihjbSwgdGltZSkge1xuICAgIGlmIChjbS5kb2MubW9kZS5zdGFydFN0YXRlICYmIGNtLmRvYy5mcm9udGllciA8IGNtLmRpc3BsYXkudmlld1RvKVxuICAgICAgY20uc3RhdGUuaGlnaGxpZ2h0LnNldCh0aW1lLCBiaW5kKGhpZ2hsaWdodFdvcmtlciwgY20pKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhpZ2hsaWdodFdvcmtlcihjbSkge1xuICAgIHZhciBkb2MgPSBjbS5kb2M7XG4gICAgaWYgKGRvYy5mcm9udGllciA8IGRvYy5maXJzdCkgZG9jLmZyb250aWVyID0gZG9jLmZpcnN0O1xuICAgIGlmIChkb2MuZnJvbnRpZXIgPj0gY20uZGlzcGxheS52aWV3VG8pIHJldHVybjtcbiAgICB2YXIgZW5kID0gK25ldyBEYXRlICsgY20ub3B0aW9ucy53b3JrVGltZTtcbiAgICB2YXIgc3RhdGUgPSBjb3B5U3RhdGUoZG9jLm1vZGUsIGdldFN0YXRlQmVmb3JlKGNtLCBkb2MuZnJvbnRpZXIpKTtcbiAgICB2YXIgY2hhbmdlZExpbmVzID0gW107XG5cbiAgICBkb2MuaXRlcihkb2MuZnJvbnRpZXIsIE1hdGgubWluKGRvYy5maXJzdCArIGRvYy5zaXplLCBjbS5kaXNwbGF5LnZpZXdUbyArIDUwMCksIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgIGlmIChkb2MuZnJvbnRpZXIgPj0gY20uZGlzcGxheS52aWV3RnJvbSkgeyAvLyBWaXNpYmxlXG4gICAgICAgIHZhciBvbGRTdHlsZXMgPSBsaW5lLnN0eWxlcywgdG9vTG9uZyA9IGxpbmUudGV4dC5sZW5ndGggPiBjbS5vcHRpb25zLm1heEhpZ2hsaWdodExlbmd0aDtcbiAgICAgICAgdmFyIGhpZ2hsaWdodGVkID0gaGlnaGxpZ2h0TGluZShjbSwgbGluZSwgdG9vTG9uZyA/IGNvcHlTdGF0ZShkb2MubW9kZSwgc3RhdGUpIDogc3RhdGUsIHRydWUpO1xuICAgICAgICBsaW5lLnN0eWxlcyA9IGhpZ2hsaWdodGVkLnN0eWxlcztcbiAgICAgICAgdmFyIG9sZENscyA9IGxpbmUuc3R5bGVDbGFzc2VzLCBuZXdDbHMgPSBoaWdobGlnaHRlZC5jbGFzc2VzO1xuICAgICAgICBpZiAobmV3Q2xzKSBsaW5lLnN0eWxlQ2xhc3NlcyA9IG5ld0NscztcbiAgICAgICAgZWxzZSBpZiAob2xkQ2xzKSBsaW5lLnN0eWxlQ2xhc3NlcyA9IG51bGw7XG4gICAgICAgIHZhciBpc2NoYW5nZSA9ICFvbGRTdHlsZXMgfHwgb2xkU3R5bGVzLmxlbmd0aCAhPSBsaW5lLnN0eWxlcy5sZW5ndGggfHxcbiAgICAgICAgICBvbGRDbHMgIT0gbmV3Q2xzICYmICghb2xkQ2xzIHx8ICFuZXdDbHMgfHwgb2xkQ2xzLmJnQ2xhc3MgIT0gbmV3Q2xzLmJnQ2xhc3MgfHwgb2xkQ2xzLnRleHRDbGFzcyAhPSBuZXdDbHMudGV4dENsYXNzKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7ICFpc2NoYW5nZSAmJiBpIDwgb2xkU3R5bGVzLmxlbmd0aDsgKytpKSBpc2NoYW5nZSA9IG9sZFN0eWxlc1tpXSAhPSBsaW5lLnN0eWxlc1tpXTtcbiAgICAgICAgaWYgKGlzY2hhbmdlKSBjaGFuZ2VkTGluZXMucHVzaChkb2MuZnJvbnRpZXIpO1xuICAgICAgICBsaW5lLnN0YXRlQWZ0ZXIgPSB0b29Mb25nID8gc3RhdGUgOiBjb3B5U3RhdGUoZG9jLm1vZGUsIHN0YXRlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChsaW5lLnRleHQubGVuZ3RoIDw9IGNtLm9wdGlvbnMubWF4SGlnaGxpZ2h0TGVuZ3RoKVxuICAgICAgICAgIHByb2Nlc3NMaW5lKGNtLCBsaW5lLnRleHQsIHN0YXRlKTtcbiAgICAgICAgbGluZS5zdGF0ZUFmdGVyID0gZG9jLmZyb250aWVyICUgNSA9PSAwID8gY29weVN0YXRl
23459KGRvYy5tb2RlLCBzdGF0ZSkgOiBudWxsO1xuICAgICAgfVxuICAgICAgKytkb2MuZnJvbnRpZXI7XG4gICAgICBpZiAoK25ldyBEYXRlID4gZW5kKSB7XG4gICAgICAgIHN0YXJ0V29ya2VyKGNtLCBjbS5vcHRpb25zLndvcmtEZWxheSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChjaGFuZ2VkTGluZXMubGVuZ3RoKSBydW5Jbk9wKGNtLCBmdW5jdGlvbigpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hhbmdlZExpbmVzLmxlbmd0aDsgaSsrKVxuICAgICAgICByZWdMaW5lQ2hhbmdlKGNtLCBjaGFuZ2VkTGluZXNbaV0sIFwidGV4dFwiKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEZpbmRzIHRoZSBsaW5lIHRvIHN0YXJ0IHdpdGggd2hlbiBzdGFydGluZyBhIHBhcnNlLiBUcmllcyB0b1xuICAvLyBmaW5kIGEgbGluZSB3aXRoIGEgc3RhdGVBZnRlciwgc28gdGhhdCBpdCBjYW4gc3RhcnQgd2l0aCBhXG4gIC8vIHZhbGlkIHN0YXRlLiBJZiB0aGF0IGZhaWxzLCBpdCByZXR1cm5zIHRoZSBsaW5lIHdpdGggdGhlXG4gIC8vIHNtYWxsZXN0IGluZGVudGF0aW9uLCB3aGljaCB0ZW5kcyB0byBuZWVkIHRoZSBsZWFzdCBjb250ZXh0IHRvXG4gIC8vIHBhcnNlIGNvcnJlY3RseS5cbiAgZnVuY3Rpb24gZmluZFN0YXJ0TGluZShjbSwgbiwgcHJlY2lzZSkge1xuICAgIHZhciBtaW5pbmRlbnQsIG1pbmxpbmUsIGRvYyA9IGNtLmRvYztcbiAgICB2YXIgbGltID0gcHJlY2lzZSA/IC0xIDogbiAtIChjbS5kb2MubW9kZS5pbm5lck1vZGUgPyAxMDAwIDogMTAwKTtcbiAgICBmb3IgKHZhciBzZWFyY2ggPSBuOyBzZWFyY2ggPiBsaW07IC0tc2VhcmNoKSB7XG4gICAgICBpZiAoc2VhcmNoIDw9IGRvYy5maXJzdCkgcmV0dXJuIGRvYy5maXJzdDtcbiAgICAgIHZhciBsaW5lID0gZ2V0TGluZShkb2MsIHNlYXJjaCAtIDEpO1xuICAgICAgaWYgKGxpbmUuc3RhdGVBZnRlciAmJiAoIXByZWNpc2UgfHwgc2VhcmNoIDw9IGRvYy5mcm9udGllcikpIHJldHVybiBzZWFyY2g7XG4gICAgICB2Y
23459XIgaW5kZW50ZWQgPSBjb3VudENvbHVtbihsaW5lLnRleHQsIG51bGwsIGNtLm9wdGlvbnMudGFiU2l6ZSk7XG4gICAgICBpZiAobWlubGluZSA9PSBudWxsIHx8IG1pbmluZGVudCA+IGluZGVudGVkKSB7XG4gICAgICAgIG1pbmxpbmUgPSBzZWFyY2ggLSAxO1xuICAgICAgICBtaW5pbmRlbnQgPSBpbmRlbnRlZDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1pbmxpbmU7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTdGF0ZUJlZm9yZShjbSwgbiwgcHJlY2lzZSkge1xuICAgIHZhciBkb2MgPSBjbS5kb2MsIGRpc3BsYXkgPSBjbS5kaXNwbGF5O1xuICAgIGlmICghZG9jLm1vZGUuc3RhcnRTdGF0ZSkgcmV0dXJuIHRydWU7XG4gICAgdmFyIHBvcyA9IGZpbmRTdGFydExpbmUoY20sIG4sIHByZWNpc2UpLCBzdGF0ZSA9IHBvcyA+IGRvYy5maXJzdCAmJiBnZXRMaW5lKGRvYywgcG9zLTEpLnN0YXRlQWZ0ZXI7XG4gICAgaWYgKCFzdGF0ZSkgc3RhdGUgPSBzdGFydFN0YXRlKGRvYy5tb2RlKTtcbiAgICBlbHNlIHN0YXRlID0gY29weVN0YXRlKGRvYy5tb2RlLCBzdGF0ZSk7XG4gICAgZG9jLml0ZXIocG9zLCBuLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICBwcm9jZXNzTGluZShjbSwgbGluZS50ZXh0LCBzdGF0ZSk7XG4gICAgICB2YXIgc2F2ZSA9IHBvcyA9PSBuIC0gMSB8fCBwb3MgJSA1ID09IDAgfHwgcG9zID49IGRpc3BsYXkudmlld0Zyb20gJiYgcG9zIDwgZGlzcGxheS52aWV3VG87XG4gICAgICBsaW5lLnN0YXRlQWZ0ZXIgPSBzYXZlID8gY29weVN0YXRlKGRvYy5tb2RlLCBzdGF0ZSkgOiBudWxsO1xuICAgICAgKytwb3M7XG4gICAgfSk7XG4gICAgaWYgKHByZWNpc2UpIGRvYy5mcm9udGllciA9IHBvcztcbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICAvLyBQT1NJVElPTiBNRUFTVVJFTUVOVFxuXG4gIGZ1bmN0aW9uIHBhZGRpbmdUb3AoZGlzcGxheSkge3JldHVybiBkaXNwbGF5LmxpbmVTcGFjZS5vZmZzZXRUb3A7fVxuICBmdW5jdGlvbiBwYWRkaW5nVmVydChkaXNwbGF5KSB7cmV0dXJuIGRpc3BsYXkubW92ZXIub2Zmc2V0SGVpZ2h0IC0gZGlzcGxheS5saW5lU3BhY2Uub2Zmc2V0SGVpZ2h0O31cbiAgZnVuY3Rpb24gcGFkZGluZ0goZGlzcGxheSkge1xuICAgIGlmIChkaXNwbGF5LmNhY2hlZFBhZGRpbmdIKSByZXR1cm4gZGlzcGxheS5jYWNoZWRQYWRkaW5nSDtcbiAgICB2YXIgZSA9IHJlbW92ZUNoaWxkcmVuQW5kQWRkKGRpc3BsYXkubWVhc3VyZSwgZWx0KFwicHJlXCIsIFwieFwiKSk7XG4gICAgdmFyIHN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUgPyB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlKSA6IGUuY3VycmVudFN0eWxlO1xuICAgIHZhciBkYXRhID0ge2xlZnQ6IHBhcnNlSW50KHN0eWxlLnBhZGRpbmdMZWZ0KSwgcmlnaHQ6IHBhcnNlSW50KHN0eWxlLnBhZGRpbmdSaWdodCl9O1xuICAgIGlmICghaXNOYU4oZGF0YS5sZWZ0KSAmJiAhaXNOYU4oZGF0YS5yaWdodCkpIGRpc3BsYXkuY2FjaGVkUGFkZGluZ0ggPSBkYXRhO1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgZnVuY3Rpb24gc2Nyb2xsR2FwKGNtKSB7IHJldHVybiBzY3JvbGxlckdhcCAtIGNtLmRpc3BsYXkubmF0aXZlQmFyV2lkdGg7IH1cbiAgZnVuY3Rpb24gZGlzcGxheVdpZHRoKGNtKSB7XG4gICAgcmV0dXJuIGNtLmRpc3BsYXkuc2Nyb2xsZXIuY2xpZW50V2lkdGggLSBzY3JvbGxHYXAoY20pIC0gY20uZGlzcGxheS5iYXJXaWR0aDtcbiAgfVxuICBmdW5jdGlvbiBkaXNwbGF5SGVpZ2h0KGNtKSB7XG4gICAgcmV0dXJuIGNtLmRpc3BsYXkuc2Nyb2xsZXIuY2xpZW50SGVpZ2h0IC0gc2Nyb2xsR2FwKGNtKSAtIGNtLmRpc3BsYXkuYmFySGVpZ2h0O1xuICB9XG5cbiAgLy8gRW5zdXJlIHRoZSBsaW5lVmlldy53cmFwcGluZy5oZWlnaHRzIGFycmF5IGlzIHBvcHVsYXRlZC4gVGhpcyBpc1xuICAvLyBhbiBhcnJheSBvZiBib3R0b20gb2Zmc2V0cyBmb3IgdGhlIGxpbmVzIHRoYXQgbWFrZSB1cCBhIGRyYXduXG4gIC8vIGxpbmUuIFdoZW4gbGluZVdyYXBwaW5nIGlzIG9uLCB0aGVyZSBtaWdodCBiZSBtb3JlIHRoYW4gb25lXG4gIC8vIGhlaWdodC5cbiAgZnVuY3Rpb24gZW5zdXJlTGluZUhlaWdodHMoY20sIGxpbmVWaWV3LCByZWN0KSB7XG4gICAgdmFyIHdyYXBwaW5nID0gY20ub3B0aW9ucy5saW5lV3JhcHBpbmc7XG4gICAgdmFyIGN1cldpZHRoID0gd3JhcHBpbmcgJiYgZGlzcGxheVdpZHRoKGNtKTtcbiAgICBpZiAoIWxpbmVWaWV3Lm1lYXN1cmUuaGVpZ2h0cyB8fCB3cmFwcGluZyAmJiBsaW5lVmlldy5tZWFzdXJlLndpZHRoICE9IGN1cldpZHRoKSB7XG4gICAgICB2Y
23459XIgaGVpZ2h0cyA9IGxpbmVWaWV3Lm1lYXN1cmUuaGVpZ2h0cyA9IFtdO1xuICAgICAgaWYgKHdyYXBwaW5nKSB7XG4gICAgICAgIGxpbmVWaWV3Lm1lYXN1cmUud2lkdGggPSBjdXJXaWR0aDtcbiAgICAgICAgdmFyIHJlY3RzID0gbGluZVZpZXcudGV4dC5maXJzdENoaWxkLmdldENsaWVudFJlY3RzKCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVjdHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgdmFyIGN1ciA9IHJlY3RzW2ldLCBuZXh0ID0gcmVjdHNbaSArIDFdO1xuICAgICAgICAgIGlmIChNYXRoLmFicyhjdXIuYm90dG9tIC0gbmV4dC5ib3R0b20pID4gMilcbiAgICAgICAgICAgIGhlaWdodHMucHVzaCgoY3VyLmJvdHRvbSArIG5leHQudG9wKSAvIDIgLSByZWN0LnRvcCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGhlaWdodHMucHVzaChyZWN0LmJvdHRvbSAtIHJlY3QudG9wKTtcbiAgICB9XG4gIH1cblxuICAvLyBGaW5kIGEgbGluZSBtYXAgKG1hcHBpbmcgY2hhcmFjdGVyIG9mZnNldHMgdG8gdGV4dCBub2RlcykgYW5kIGFcbiAgLy8gbWVhc3VyZW1lbnQgY2FjaGUgZm9yIHRoZSBnaXZlbiBsaW5lIG51bWJlci4gKEEgbGluZSB2aWV3IG1pZ2h0XG4gIC8vIGNvbnRhaW4gbXVsdGlwbGUgbGluZXMgd2hlbiBjb2xsYXBzZWQgcmFuZ2VzIGFyZSBwcmVzZW50LilcbiAgZnVuY3Rpb24gbWFwRnJvbUxpbmVWaWV3KGxpbmVWaWV3LCBsaW5lLCBsaW5lTikge1xuICAgIGlmIChsaW5lVmlldy5saW5lID09IGxpbmUpXG4gICAgICByZXR1cm4ge21hcDogbGluZVZpZXcubWVhc3VyZS5tYXAsIGNhY2hlOiBsaW5lVmlldy5tZWFzdXJlLmNhY2hlfTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVWaWV3LnJlc3QubGVuZ3RoOyBpKyspXG4gICAgICBpZiAobGluZVZpZXcucmVzdFtpXSA9PSBsaW5lKVxuICAgICAgICByZXR1cm4ge21hcDogbGluZVZpZXcubWVhc3VyZS5tYXBzW2ldLCBjYWNoZTogbGluZVZpZXcubWVhc3VyZS5jYWNoZXNbaV19O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZVZpZXcucmVzdC5sZW5ndGg7IGkrKylcbiAgICAgIGlmIChsaW5lTm8obGluZVZpZXcucmVzdFtpXSkgPiBsaW5lTilcbiAgICAgICAgcmV0dXJuIHttYXA6IGxpbmVWaWV3Lm1lYXN1cmUubWFwc1tpXSwgY2FjaGU6IGxpbmVWaWV3Lm1lYXN1cmUuY2FjaGVzW2ldLCBiZWZvcmU6IHRydWV9O1xuICB9XG5cbiAgLy8gUmVuZGVyIGEgbGluZSBpbnRvIHRoZSBoaWRkZW4gbm9kZSBkaXNwbGF5LmV4dGVybmFsTWVhc3VyZWQuIFVzZWRcbiAgLy8gd2hlbiBtZWFzdXJlbWVudCBpcyBuZWVkZWQgZm9yIGEgbGluZSB0aGF0J3Mgbm90IGluIHRoZSB2aWV3cG9ydC5cbiAgZnVuY3Rpb24gdXBkYXRlRXh0ZXJuYWxNZWFzdXJlbWVudChjbSwgbGluZSkge1xuICAgIGxpbmUgPSB2aXN1YWxMaW5lKGxpbmUpO1xuICAgIHZhciBsaW5lTiA9IGxpbmVObyhsaW5lKTtcbiAgICB2YXIgdmlldyA9IGNtLmRpc3BsYXkuZXh0ZXJuYWxNZWFzdXJlZCA9IG5ldyBMaW5lVmlldyhjbS5kb2MsIGxpbmUsIGxpbmVOKTtcbiAgICB2aWV3LmxpbmVOID0gbGluZU47XG4gICAgdmFyIGJ1aWx0ID0gdmlldy5idWlsdCA9IGJ1aWxkTGluZUNvbnRlbnQoY20sIHZpZXcpO1xuICAgIHZpZXcudGV4dCA9IGJ1aWx0LnByZTtcbiAgICByZW1vdmVDaGlsZHJlbkFuZEFkZChjbS5kaXNwbGF5LmxpbmVNZWFzdXJlLCBidWlsdC5wcmUpO1xuICAgIHJldHVybiB2aWV3O1xuICB9XG5cbiAgLy8gR2V0IGEge3RvcCwgYm90dG9tLCBsZWZ0LCByaWdodH0gYm94IChpbiBsaW5lLWxvY2FsIGNvb3JkaW5hdGVzKVxuICAvLyBmb3IgYSBnaXZlbiBjaGFyYWN0ZXIuXG4gIGZ1bmN0aW9uIG1lYXN1cmVDaGFyKGNtLCBsaW5lLCBjaCwgYmlhcykge1xuICAgIHJldHVybiBtZWFzdXJlQ2hhclByZXBhcmVkKGNtLCBwcmVwYXJlTWVhc3VyZUZvckxpbmUoY20sIGxpbmUpLCBjaCwgYmlhcyk7XG4gIH1cblxuICAvLyBGaW5kIGEgbGluZSB2aWV3IHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIGdpdmVuIGxpbmUgbnVtYmVyLlxuICBmdW5jdGlvbiBmaW5kVmlld0ZvckxpbmUoY20sIGxpbmVOKSB7XG4gICAgaWYgKGxpbmVOID49IGNtLmRpc3BsYXkudmlld0Zyb20gJiYgbGluZU4gPCBjbS5kaXNwbGF5LnZpZXdUbylcbiAgICAgIHJldHVybiBjbS5kaXNwbGF5LnZpZXdbZmluZFZpZXdJbmRleChjbSwgbGluZU4pXTtcbiAgICB2YXIgZXh0ID0gY20uZGlzcGxheS5leHRlcm5hbE1lYXN1cmVkO1xuICAgIGlmIChleHQgJiYgbGluZU4gPj0gZXh0LmxpbmVOICYmIGxpbmVOIDwgZXh0LmxpbmVOICsgZXh0LnNpemUpXG4gICAgICByZXR1cm4gZXh0O1xuICB9XG5cbiAgLy8gTWVhc3VyZW1lbnQgY2FuIGJlIHNwbGl0IGluIHR3byBzdGVwcywgdGhlIHNldC11cCB3b3JrIHRoYXRcbiAgLy8gYXBwbGllcyB0byB0aGUgd2hvbGUgbGluZSwgYW5kIHRoZSBtZWFzdXJlbWVudCBvZiB0aGUgYWN0dWFsXG4gIC8vIGNoYXJhY3Rlci4gRnVuY3Rpb25zIGxpa2UgY29vcmRzQ2hhciwgdGhhdCBuZWVkIHRvIGRvIGEgbG90IG9mXG4gIC8vIG1lYXN1cmVtZW50cyBpbiBhIHJvdywgY2FuIHRodXMgZW5zdXJlIHRoYXQgdGhlIHNldC11cCB3b3JrIGlzXG4gIC8vIG9ubHkgZG9uZSBvbmNlLlxuICBmdW5jdGlvbiBwcmVwYXJlTWVhc3VyZUZvckxpbmUoY20sIGxpbmUpIHtcbiAgICB2YXIgbGluZU4gPSBsaW5lTm8obGluZSk7XG4gICAgdmFyIHZpZXcgPSBmaW5kVmlld0ZvckxpbmUoY20sIGxpbmVOKTtcbiAgICBpZiAodmlldyAmJiAhdmlldy50ZXh0KSB7XG4gICAgICB2aWV3ID0gbnVsbDtcbiAgICB9IGVsc2UgaWYgKHZpZXcgJiYgdmlldy5jaGFuZ2VzKSB7XG4gICAgICB1cGRhdGVMaW5lRm9yQ2hhbmdlcyhjbSwgdmlldywgbGluZU4sIGdldERpbWVuc2lvbnMoY20pKTtcbiAgICAgIGNtLmN1ck9wLmZvcmNlVXBkYXRlID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCF2aWV3KVxuICAgICAgdmlldyA9IHVwZGF0ZUV4dGVybmFsTWVhc3VyZW1lbnQoY20sIGxpbmUpO1xuXG4gICAgdmFyIGluZm8gPSBtYXBGcm9tTGluZVZpZXcodmlldywgbGluZSwgbGluZU4pO1xuICAgIHJldHVybi
23459B7XG4gICAgICBsaW5lOiBsaW5lLCB2aWV3OiB2aWV3LCByZWN0OiBudWxsLFxuICAgICAgbWFwOiBpbmZvLm1hcCwgY2FjaGU6IGluZm8uY2FjaGUsIGJlZm9yZTogaW5mby5iZWZvcmUsXG4gICAgICBoYXNIZWlnaHRzOiBmYWxzZVxuICAgIH07XG4gIH1cblxuICAvLyBHaXZlbiBhIHByZXBhcmVkIG1lYXN1cmVtZW50IG9iamVjdCwgbWVhc3VyZXMgdGhlIHBvc2l0aW9uIG9mIGFuXG4gIC8vIGFjdHVhbCBjaGFyYWN0ZXIgKG9yIGZldGNoZXMgaXQgZnJvbSB0aGUgY2FjaGUpLlxuICBmdW5jdGlvbiBtZWFzdXJlQ2hhclByZXBhcmVkKGNtLCBwcmVwYXJlZCwgY2gsIGJpYXMsIHZhckhlaWdodCkge1xuICAgIGlmIChwcmVwYXJlZC5iZWZvcmUpIGNoID0gLTE7XG4gICAgdmFyIGtleSA9IGNoICsgKGJpYXMgfHwgXCJcIiksIGZvdW5kO1xuICAgIGlmIChwcmVwYXJlZC5jYWNoZS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICBmb3VuZCA9IHByZXBhcmVkLmNhY2hlW2tleV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghcHJlcGFyZWQucmVjdClcbiAgICAgICAgcHJlcGFyZWQucmVjdCA9IHByZXBhcmVkLnZpZXcudGV4dC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGlmICghcHJlcGFyZWQuaGFzSGVpZ2h0cykge1xuICAgICAgICBlbnN1cmVMaW5lSGVpZ2h0cyhjbSwgcHJlcGFyZWQudmlldywgcHJlcGFyZWQucmVjdCk7XG4gICAgICAgIHByZXBhcmVkLmhhc0hlaWdodHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgZm91bmQgPSBtZWFzdXJlQ2hhcklubmVyKGNtLCBwcmVwYXJlZCwgY2gsIGJpYXMpO1xuICAgICAgaWYgKCFmb3VuZC5ib2d1cykgcHJlcGFyZWQuY2FjaGVba2V5XSA9IGZvdW5kO1xuICAgIH1cbiAgICByZXR1cm4ge2xlZnQ6IGZvdW5kLmxlZnQsIHJpZ2h0OiBmb3VuZC5yaWdodCxcbiAgICAgICAgICAgIHRvcDogdmFySGVpZ2h0ID8gZm91bmQucnRvcCA6IGZvdW5kLnRvcCxcbiAgICAgICAgICAgIGJvdHRvbTogdmFySGVpZ2h0ID8gZm91bmQucmJvdHRvbSA6IGZvdW5kLmJvdHRvbX07XG4gIH1cblxuICB2YXIgbnVsbFJlY3QgPSB7bGVmdDogMCwgcmlnaHQ6IDAsIHRvcDogMCwgYm90dG9tOiAwfTtcblxuICBmdW5jdGlvbiBub2RlQW5kT2Zmc2V0SW5MaW5lTWFwKG1hcCwgY2gsIGJpYXMpIHtcbiAgICB2YXIgbm9kZSwgc3RhcnQsIGVuZCwgY29sbGFwc2U7XG4gICAgLy8gRmlyc3QsIHNlYXJjaCB0aGUgbGluZSBtYXAgZm9yIHRoZSB0ZXh0IG5vZGUgY29ycmVzcG9uZGluZyB0byxcbiAgICAvLyBvciBjbG9zZXN0IHRvLCB0aGUgdGFyZ2V0IGNoYXJhY3Rlci5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1hcC5sZW5ndGg7IGkgKz0gMykge1xuICAgICAgdmFyIG1TdGFydCA9IG1hcFtpXSwgbUVuZCA9IG1hcFtpICsgMV07XG4gICAgICBpZiAoY2ggPCBtU3RhcnQpIHtcbiAgICAgICAgc3RhcnQgPSAwOyBlbmQgPSAxO1xuICAgICAgICBjb2xsYXBzZSA9IFwibGVmdFwiO1xuICAgICAgfSBlbHNlIGlmIChjaCA8IG1FbmQpIHtcbiAgICAgICAgc3RhcnQgPSBjaCAtIG1TdGFydDtcbiAgICAgICAgZW5kID0gc3RhcnQgKyAxO1xuICAgICAgfSBlbHNlIGlmIChpID09IG1hcC5sZW5ndGggLSAzIHx8IGNoID09IG1FbmQgJiYgbWFwW2kgKyAzXSA+IGNoKSB7XG4gICAgICAgIGVuZCA9IG1FbmQgLSBtU3RhcnQ7XG4gICAgICAgIHN0YXJ0ID0gZW5kIC0gMTtcbiAgICAgICAgaWYgKGNoID49IG1FbmQpIGNvbGxhcHNlID0gXCJyaWdodFwiO1xuICAgICAgfVxuICAgICAgaWYgKHN0YXJ0ICE9IG51bGwpIHtcbiAgICAgICAgbm9kZSA9IG1hcFtpICsgMl07XG4gICAgICAgIGlmIChtU3RhcnQgPT0gbUVuZCAmJiBiaWFzID09IChub2RlLmluc2VydExlZnQgPyBcImxlZnRcIiA6IFwicmlnaHRcIikpXG4gICAgICAgICAgY29sbGFwc2UgPSBiaWFzO1xuICAgICAgICBpZiAoYmlhcyA9PSBcImxlZnRcIiAmJiBzdGFydCA9PSAwKVxuICAgICAgICAgIHdoaWxlIChpICYmIG1hcFtpIC0gMl0gPT0gbWFwW2kgLSAzXSAmJiBtYXBbaSAtIDFdLmluc2VydExlZnQpIHtcbiAgICAgICAgICAgIG5vZGUgPSBtYXBbKGkgLT0gMykgKyAyXTtcbiAgICAgICAgICAgIGNvbGxhcHNlID0gXCJsZWZ0XCI7XG4gICAgICAgICAgfVxuICAgICAgICBpZiAoYmlhcyA9PSBcInJpZ2h0XCIgJiYgc3RhcnQgPT0gbUVuZCAtIG1TdGFydClcbiAgICAgICAgICB3aGlsZSAoaSA8IG1hcC5sZW5ndGggLSAzICYmIG1hcFtpICsgM10gPT0gbWFwW2kgKyA0XSAmJiAhbWFwW2kgKyA1XS5pbnNlcnRMZWZ0KSB7XG4gICAgICAgICAgICBub2RlID0gbWFwWyhpICs9IDMpICsgMl07XG4gICAgICAgICAgICBjb2xsYXBzZSA9IFwicmlnaHRcIjtcbiAgICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge25vZGU6IG5vZGUsIHN0YXJ0OiBzdGFydCwgZW5kOiBlbmQsIGNvbGxhcHNlOiBjb2xsYXBzZSwgY292ZXJTdGFydDogbVN0YXJ0LCBjb3ZlckVuZDogbUVuZH07XG4gIH1cblxuICBmdW5jdGlvbiBtZWFzdXJlQ2hhcklubmVyKGNtLCBwcmVwYXJlZCwgY2gsIGJpYXMpIHtcbiAgICB2YXIgcGxhY2UgPSBub2RlQW5kT2Zmc2V0SW5MaW5lTWFwKHByZXBhcmVkLm1hcCwgY2gsIGJpYXMpO1xuICAgIHZhciBub2RlID0gcGxhY2Uubm9kZSwgc3RhcnQgPSBwbGFjZS5zdGFydCwgZW5kID0gcGxhY2UuZW5kLCBjb2xsYXBzZSA9IHBsYWNlLmNvbGxhcHNlO1xuXG4gICAgdmFyIHJlY3Q7XG4gICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMykgeyAvLyBJZiBpdCBpcyBhIHRleHQgbm9kZSwgdXNlIGEgcmFuZ2UgdG8gcmV0cmlldmUgdGhlIGNvb3JkaW5hdGVzLlxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHsgLy8gUmV0cnkgYSBtYXhpbXVtIG9mIDQgdGltZXMgd2hlbiBub25zZW5zZSByZWN0YW5nbGVzIGFyZSByZXR1cm5lZFxuICAgICAgICB3aGlsZSAoc3RhcnQgJiYgaXNFeHRlbmRpbmdDaGFyKHByZXBhcmVkLmxpbmUudGV4dC5jaGFyQXQocGxhY2UuY292ZXJTdGFydCArIHN0YXJ0KSkpIC0tc3RhcnQ7XG4gICAgICAgIHdoaWxlIChwbGFjZS5jb3ZlclN0YXJ0ICsgZW5kIDwgcGxhY2UuY292ZXJFbmQgJiYgaXNFeHRlbmRpbmdDaGFyKHByZXBhcmVkLmxpbmUudGV4dC5jaGFyQXQocGxhY2UuY292ZXJTdGFydCArIGVuZCkpKSArK2VuZDtcbiAgICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPCA5ICYmIHN0YXJ0ID09IDAgJiYgZW5kID09IHBsYWNlLmNvdmVyRW5kIC0gcGxhY2UuY292ZXJTdGFydCkge1xuICAgICAgICAgI
23459HJlY3QgPSBub2RlLnBhcmVudE5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIH0gZWxzZSBpZiAoaWUgJiYgY20ub3B0aW9ucy5saW5lV3JhcHBpbmcpIHtcbiAgICAgICAgICB2YXIgcmVjdHMgPSByYW5nZShub2RlLCBzdGFydCwgZW5kKS5nZXRDbGllbnRSZWN0cygpO1xuICAgICAgICAgIGlmIChyZWN0cy5sZW5ndGgpXG4gICAgICAgICAgICByZWN0ID0gcmVjdHNbYmlhcyA9PSBcInJpZ2h0XCIgPyByZWN0cy5sZW5ndGggLSAxIDogMF07XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmVjdCA9IG51bGxSZWN0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlY3QgPSByYW5nZShub2RlLCBzdGFydCwgZW5kKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSB8fCBudWxsUmVjdDtcbiAgICAgICAgf
vendor: 13,208 bytes, line 23459
23459VxuICAgICAgICBpZiAocmVjdC5sZWZ0IHx8IHJlY3QucmlnaHQgfHwgc3RhcnQgPT0gMCkgYnJlYWs7XG4gICAgICAgIGVuZCA9IHN0YXJ0O1xuICAgICAgICBzdGFydCA9IHN0YXJ0IC0gMTtcbiAgICAgICAgY29sbGFwc2UgPSBcInJpZ2h0XCI7XG4gICAgICB9XG4gICAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8IDExKSByZWN0ID0gbWF5YmVVcGRhdGVSZWN0Rm9yWm9vbWluZyhjbS5kaXNwbGF5Lm1lYXN1cmUsIHJlY3QpO1xuICAgIH0gZWxzZSB7IC8vIElmIGl0IGlzIGEgd2lkZ2V0LCBzaW1wbHkgZ2V0IHRoZSBib3ggZm9yIHRoZSB3aG9sZSB3aWRnZXQuXG4gICAgICBpZiAoc3RhcnQgPiAwKSBjb2xsYXBzZSA9IGJpYXMgPSBcInJpZ2h0XCI7XG4gICAgICB2YXIgcmVjdHM7XG4gICAgICBpZiAoY20ub3B0aW9ucy5saW5lV3JhcHBpbmcgJiYgKHJlY3RzID0gbm9kZS5nZXRDbGllbnRSZWN0cygpKS5sZW5ndGggPiAxKVxuICAgICAgICByZWN0ID0gcmVjdHNbYmlhcyA9PSBcInJpZ2h0XCIgPyByZWN0cy5sZW5ndGggLSAxIDogMF07XG4gICAgICBlbHNlXG4gICAgICAgIHJlY3QgPSBub2RlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIH1cbiAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8IDkgJiYgIXN0YXJ0ICYmICghcmVjdCB8fCAhcmVjdC5sZWZ0ICYmICFyZWN0LnJpZ2h0KSkge1xuICAgICAgdmFyIHJTcGFuID0gbm9kZS5wYXJlbnROb2RlLmdldENsaWVudFJlY3RzKClbMF07XG4gICAgICBpZiAoclNwYW4pXG4gICAgICAgIHJlY3QgPSB7bGVmdDogclNwYW4ubGVmdCwgcmlnaHQ6IHJTcGFuLmxlZnQgKyBjaGFyV2lkdGgoY20uZGlzcGxheSksIHRvcDogclNwYW4udG9wLCBib3R0b206IHJTcGFuLmJvdHRvbX07XG4gICAgICBlbHNlXG4gICAgICAgIHJlY3QgPSBudWxsUmVjdDtcbiAgICB9XG5cbiAgICB2YXIgcnRvcCA9IHJlY3QudG9wIC0gcHJlcGFyZWQucmVjdC50b3AsIHJib3QgPSByZWN0LmJvdHRvbSAtIHByZXBhcmVkLnJlY3QudG9wO1xuICAgIHZhciBtaWQgPSAocnRvcCArIHJib3QpIC8gMjtcbiAgICB2YXIgaGVpZ2h0cyA9IHByZXBhcmVkLnZpZXcubWVhc3VyZS5oZWlnaHRzO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGVpZ2h0cy5sZW5ndGggLSAxOyBpKyspXG4gICAgICBpZiAobWlkIDwgaGVpZ2h0c1tpXSkgYnJlYWs7XG4gICAgdmFyIHRvcCA9IGkgPyBoZWlnaHRzW2kgLSAxXSA6IDAsIGJvdCA9IGhlaWdodHNbaV07XG4gICAgdmFyIHJlc3VsdCA9IHtsZWZ0OiAoY29sbGFwc2UgPT0gXCJyaWdodFwiID8gcmVjdC5yaWdodCA6IHJlY3QubGVmdCkgLSBwcmVwYXJlZC5yZWN0LmxlZnQsXG4gICAgICAgICAgICAgICAgICByaWdodDogKGNvbGxhcHNlID09IFwibGVmdFwiID8gcmVjdC5sZWZ0IDogcmVjdC5yaWdodCkgLSBwcmVwYXJlZC5yZWN0LmxlZnQsXG4gICAgICAgICAgICAgICAgICB0b3A6IHRvcCwgYm90dG9tOiBib3R9O1xuICAgIGlmICghcmVjdC5sZWZ0ICYmICFyZWN0LnJpZ2h0KSByZXN1bHQuYm9ndXMgPSB0cnVlO1xuICAgIGlmICghY20ub3B0aW9ucy5zaW5nbGVDdXJzb3JIZWlnaHRQZXJMaW5lKSB7IHJlc3VsdC5ydG9wID0gcnRvcDsgcmVzdWx0LnJib3R0b20gPSByYm90OyB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gV29yayBhcm91bmQgcHJvYmxlbSB3aXRoIGJvdW5kaW5nIGNsaWVudCByZWN0cyBvbiByYW5nZXMgYmVpbmdcbiAgLy8gcmV0dXJuZWQgaW5jb3JyZWN0bHkgd2hlbiB6b29tZWQgb24gSUUxMCBhbmQgYmVsb3cuXG4gIGZ1bmN0aW9uIG1heWJlVXBkYXRlUmVjdEZvclpvb21pbmcobWVhc3VyZSwgcmVjdCkge1xuICAgIGlmICghd2luZG93LnNjcmVlbiB8fCBzY3JlZW4ubG9naWNhbFhEUEkgPT0gbnVsbCB8fFxuICAgICAgICBzY3JlZW4ubG9naWNhbFhEUEkgPT0gc2NyZWVuLmRldmljZVhEUEkgfHwgIWhhc0JhZFpvb21lZFJlY3RzKG1lYXN1cmUpKVxuICAgICAgcmV0dXJuIHJlY3Q7XG4gICAgdmFyIHNjYWxlWCA9IHNjcmVlbi5sb2dpY2FsWERQSSAvIHNjcmVlbi5kZXZpY2VYRFBJO1xuICAgIHZhciBzY2FsZVkgPSBzY3JlZW4ubG9naWNhbFlEUEkgLyBzY3JlZW4uZGV2aWNlWURQSTtcbiAgICByZXR1cm4ge2xlZnQ6IHJlY3QubGVmdCAqIHNjYWxlWCwgcmlnaHQ6IHJlY3QucmlnaHQgKiBzY2FsZVgsXG4gICAgICAgICAgICB0b3A6IHJlY3QudG9wICogc2NhbGVZLCBib3R0b206IHJlY3QuYm90dG9tICogc2NhbGVZfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsZWFyTGluZU1lYXN1cmVtZW50Q2FjaGVGb3IobGluZVZpZXcpIHtcbiAgICBpZiAobGluZVZpZXcubWVhc3VyZSkge1xuICAgICAgbGluZVZpZXcubWVhc3VyZS5jYWNoZSA9IHt9O1xuICAgICAgbGluZVZpZXcubWVhc3VyZS5oZWlnaHRzID0gbnVsbDtcbiAgICAgIGlmIChsaW5lVmlldy5yZXN0KSBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVWaWV3LnJlc3QubGVuZ3RoOyBpKyspXG4gICAgICAgIGxpbmVWaWV3Lm1lYXN1cmUuY2FjaGVzW2ldID0ge307XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY2xlYXJMaW5lTWVhc3VyZW1lbnRDYWNoZShjbSkge1xuICAgIGNtLmRpc3BsYXkuZXh0ZXJuYWxNZWFzdXJlID0gbnVsbDtcbiAgICByZW1vdmVDaGlsZHJlbihjbS5kaXNwbGF5LmxpbmVNZWFzdXJlKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNtLmRpc3BsYXkudmlldy5sZW5ndGg7IGkrKylcbiAgICAgIGNsZWFyTGluZU1lYXN1cmVtZW50Q2FjaGVGb3IoY20uZGlzcGxheS52aWV3W2ldKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsZWFyQ2FjaGVzKGNtKSB7XG4gICAgY2xlYXJMaW5lTWVhc3VyZW1lbnRDYWNoZShjbSk7XG4gICAgY20uZGlzcGxheS5jYWNoZWRDaGFyV2lkdGggPSBjbS5kaXNwbGF5LmNhY2hlZFRleHRIZWlnaHQgPSBjbS5kaXNwbGF5LmNhY2hlZFBhZGRpbmdIID0gbnVsbDtcbiAgICBpZiAoIWNtLm9wdGlvbnMubGluZVdyYXBwaW5nKSBjbS5kaXNwbGF5Lm1heExpbmVDaGFuZ2VkID0gdHJ1ZTtcbiAgICBjbS5kaXNwbGF5LmxpbmVOdW1DaGFycyA9IG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiBwYWdlU2Nyb2xsWCgpIHsgcmV0dXJuIHdpbmRvdy5wYWdlWE9mZnNldCB8fCAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IHx8IGRvY3VtZW50LmJvZHkpLnNjcm9sbExlZnQ7IH1cbiAgZnVuY3Rpb24gcGFnZVNjcm9sbFkoKSB7IHJldHVybiB3aW5kb3cucGFnZVlPZmZzZXQgfHwgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCB8fCBkb2N1bWVudC5ib2R5KS5zY3JvbGxUb3A7IH1cblxuICAvLyBDb252ZXJ0cyBhIHt0b3AsIGJvdHRvbSwgbGVmdCwgcmlnaHR9IGJveCBmcm9tIGxpbmUtbG9jYWxcbiAgLy8gY29vcmRpbmF0ZXMgaW50byBhbm90aGVyIGNvb3JkaW5hdGUgc3lzdGVtLiBDb250ZXh0IG1heSBiZSBvbmUgb2ZcbiAgLy8gXCJsaW5lXCIsIFwiZGl2XCIgKGRpc3BsYXkubGluZURpdiksIFwibG9jYWxcIi9udWxsIChlZGl0b3IpLCBcIndpbmRvd1wiLFxuICAvLyBvciBcInBhZ2VcIi5cbiAgZnVuY3Rpb24gaW50b0Nvb3JkU3lzdGVtKGNtLCBsaW5lT2JqLCByZWN0LCBjb250ZXh0KSB7XG4gICAgaWYgKGxpbmVPYmoud2lkZ2V0cykgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lT2JqLndpZGdldHMubGVuZ3RoOyArK2kpIGlmIChsaW5lT2JqLndpZGdldHNbaV0uYWJvdmUpIHtcbiAgICAgIHZhciBzaXplID0gd2lkZ2V0SGVpZ2h0KGxpbmVPYmoud2lkZ2V0c1tpXSk7XG4gICAgICByZWN0LnRvcCArPSBzaXplOyByZWN0LmJvdHRvbSArPSBzaXplO1xuICAgIH1cbiAgICBpZiAoY29udGV4dCA9PSBcImxpbmVcIikgcmV0dXJuIHJlY3Q7XG4gICAgaWYgKCFjb250ZXh0KSBjb250ZXh0ID0gXCJsb2NhbFwiO1xuICAgIHZhciB5T2ZmID0gaGVpZ2h0QXRMaW5lKGxpbmVPYmopO1xuICAgIGlmIChjb250ZXh0ID09IFwibG9jYWxcIikgeU9mZiArPSBwYWRkaW5nVG9wKGNtLmRpc3BsYXkpO1xuICAgIGVsc2UgeU9mZiAtPSBjbS5kaXNwbGF5LnZpZXdPZmZzZXQ7XG4gICAgaWYgKGNvbnRleHQgPT0gXCJwYWdlXCIgfHwgY29udGV4dCA9PSBcIndpbmRvd1wiKSB7XG4gICAgICB2YXIgbE9mZiA9IGNtLmRpc3BsYXkubGluZVNwYWNlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgeU9mZiArPSBsT2ZmLnRvcCArIChjb250ZXh0ID09IFwid2luZG93XCIgPyAwIDogcGFnZVNjcm9sbFkoKSk7XG4gICAgICB2YXIgeE9mZiA9IGxPZmYubGVmdCArIChjb250ZXh0ID09IFwid2luZG93XCIgPyAwIDogcGFnZVNjcm9sbFgoKSk7XG4gICAgICByZWN0LmxlZnQgKz0geE9mZjsgcmVjdC5yaWdodCArPSB4T2ZmO1xuICAgIH1cbiAgICByZWN0LnRvcCArPSB5T2ZmOyByZWN0LmJvdHRvbSArPSB5T2ZmO1xuICAgIHJldHVybiByZWN0O1xuICB9XG5cbiAgLy8gQ292ZXJ0cyBhIGJveCBmcm9tIFwiZGl2XCIgY29vcmRzIHRvIGFub3RoZXIgY29vcmRpbmF0ZSBzeXN0ZW0uXG4gIC8vIENvbnRleHQgbWF5IGJlIFwid2luZG93XCIsIFwicGFnZVwiLCBcImRpdlwiLCBvciBcImxvY2FsXCIvbnVsbC5cbiAgZnVuY3Rpb24gZnJvbUNvb3JkU3lzdGVtKGNtLCBjb29yZHMsIGNvbnRleHQpIHtcbiAgICBpZiAoY29udGV4dCA9PSBcImRpdlwiKSByZXR1cm4gY29vcmRzO1xuICAgIHZhciBsZWZ0ID0gY29vcmRzLmxlZnQsIHRvcCA9IGNvb3Jkcy50b3A7XG4gICAgLy8gRmlyc3QgbW92ZSBpbnRvIFwicGFnZVwiIGNvb3JkaW5hdGUgc3lzdGVtXG4gICAgaWYgKGNvbnRleHQgPT0gXCJwYWdlXCIpIHtcbiAgICAgIGxlZnQgLT0gcGFnZVNjcm9sbFgoKTtcbiAgICAgIHRvcCAtPSBwYWdlU2Nyb2xsWSgpO1xuICAgIH0gZWxzZSBpZiAoY29udGV4dCA9PSBcImxvY2FsXCIgfHwgIWNvbnRleHQpIHtcbiAgICAgIHZhciBsb2NhbEJveCA9IGNtLmRpc3BsYXkuc2l6ZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBsZWZ0ICs9IGxvY2FsQm94LmxlZnQ7XG4gICAgICB0b3AgKz0gbG9jYWxCb3gudG9wO1xuICAgIH1cblxuICAgIHZhciBsaW5lU3BhY2VCb3ggPSBjbS5kaXNwbGF5LmxpbmVTcGFjZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICByZXR1cm4ge2xlZnQ6IGxlZnQgLSBsaW5lU3BhY2VCb3gubGVmdCwgdG9wOiB0b3AgLSBsaW5lU3BhY2VCb3gudG9wfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNoYXJDb29yZHMoY20sIHBvcywgY29udGV4dCwgbGluZU9iaiwgYmlhcykge1xuICAgIGlmICghbGluZU9iaikgbGluZU9iaiA9IGdldExpbmUoY20uZG9jLCBwb3MubGluZSk7XG4gICAgcmV0dXJuIGludG9Db29yZFN5c3RlbShjbSwgbGluZU9iaiwgbWVhc3VyZUNoYXIoY20sIGxpbmVPYmosIHBvcy5jaCwgYmlhcyksIGNvbnRleHQpO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIGJveCBmb3IgYSBnaXZlbiBjdXJzb3IgcG9zaXRpb24sIHdoaWNoIG1heSBoYXZlIGFuXG4gIC8vICdvdGhlcicgcHJvcGVydHkgY29udGFpbmluZyB0aGUgcG9zaXRpb24gb2YgdGhlIHNlY29uZGFyeSBjdXJzb3JcbiAgLy8gb24gYSBiaWRpIGJvdW5kYXJ5LlxuICBmdW5jdGlvbiBjdXJzb3JDb29yZHMoY20sIHBvcywgY29udGV4dCwgbGluZU9iaiwgcHJlcGFyZWRNZWFzdXJlLCB2YXJIZWlnaHQpIHtcbiAgICBsaW5lT2JqID0gbGluZU9iaiB8fCBnZXRMaW5lKGNtLmRvYywgcG9zLmxpbmUpO1xuICAgIGlmICghcHJlcGFyZWRNZWFzdXJlKSBwcmVwYXJlZE1lYXN1cmUgPSBwcmVwYXJlTWVhc3VyZUZvckxpbmUoY20sIGxpbmVPYmopO1xuICAgIGZ1bmN0aW9uIGdldChjaCwgcmlnaHQpIHtcbiAgICAgIHZhciBtID0gbWVhc3VyZUNoYXJQcmVwYXJlZChjbSwgcHJlcGFyZWRNZWFzdXJlLCBjaCwgcmlnaHQgPyBcInJpZ2h0XCIgOiBcImxlZnRcIiwgdmFySGVpZ2h0KTtcbiAgICAgIGlmIChyaWdodCkgbS5sZWZ0ID0gbS5yaWdodDsgZWxzZSBtLnJpZ2h0ID0gbS5sZWZ0O1xuICAgICAgcmV0dXJuIGludG9Db29yZFN5c3RlbShjbSwgbGluZU9iaiwgbSwgY29udGV4dCk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGdldEJpZGkoY2gsIHBhcnRQb3MpIHtcbiAgICAgIHZhciBwYXJ0ID0gb3JkZXJbcGFydFBvc10sIHJpZ2h0ID0gcGFydC5sZXZlbCAlIDI7XG4gICAgICBpZiAoY2ggPT0gYmlkaUxlZnQocGFydCkgJiYgcGFydFBvcyAmJiBwYXJ0LmxldmVsIDwgb3JkZXJbcGFydFBvcyAtIDFdLmxldmVsKSB7XG4gICAgICAgIHBhcnQgPSBvcmRlclstLXBhcnRQb3NdO1xuICAgICAgICBjaCA9IGJpZGlSaWdodChwYXJ0KSAtIChwYXJ0LmxldmVsICUgMiA/IDAgOiAxKTtcbiAgICAgICAgcmlnaHQgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmIChjaCA9PSBiaWRpUmlnaHQocGFydCkgJiYgcGFydFBvcyA8IG9yZGVyLmxlbmd0aCAtIDEgJiYgcGFydC5sZXZlbCA8IG9yZGVyW3BhcnRQb3MgKyAxXS5sZXZlbCkge1xuICAgICAgICBwYXJ0ID0gb3JkZXJbKytwYXJ0UG9zXTtcbiAgICAgICAgY2ggPSBiaWRpTGVmdChwYXJ0KSAtIHBhcnQubGV2ZWwgJSAyO1xuICAgICAgICByaWdodCA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKHJpZ2h0ICYmIGNoID09IHBhcnQudG8gJiYgY2ggPiBwYXJ0LmZyb20pIHJldHVybiBnZXQoY2ggLSAxKTtcbiAgICAgIHJldHVybiBnZXQoY2gsIHJpZ2h0KTtcbiAgICB9XG4gICAgdmFyIG9yZGVyID0gZ2V0T3JkZXIobGluZU9iaiksIGNoID0gcG9zLmNoO1xuICAgIGlmICghb3JkZXIpIHJldHVybiBnZXQoY2gpO1xuICAgIHZhciBwYXJ0UG9zID0gZ2V0QmlkaVBhcnRBdChvcmRlciwgY2gpO1xuICAgIHZhciB2YWwgPSBnZXRCaWRpKGNoLCBwYXJ0UG9zKTtcbiAgICBpZiAoYmlkaU90aGVyICE9IG51bGwpIHZhbC5vdGhlciA9IGdldEJpZGkoY2gsIGJpZGlPdGhlcik7XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxuXG4gIC8vIFVzZWQgdG8gY2hlYXBseSBlc3RpbWF0ZSB0aGUgY29vcmRpbmF0ZXMgZm9yIGEgcG9zaXRpb24uIFVzZWQgZm9yXG4gIC8vIGludGVybWVkaWF0ZSBzY3JvbGwgdXBkYXRlcy5cbiAgZnVuY3Rpb24gZXN0aW1hdGVDb29yZHMoY20sIHBvcykge1xuICAgIHZhciBsZWZ0ID0gMCwgcG9zID0gY2xpcFBvcyhjbS5kb2MsIHBvcyk7XG4gICAgaWYgKCFjbS5vcHRpb25zLmxpbmVXcmFwcGluZykgbGVmdCA9IGNoYXJXaWR0aChjbS5kaXNwbGF5KSAqIHBvcy5jaDtcbiAgICB2YXIgbGluZU9iaiA9IGdldExpbmUoY20uZG9jLCBwb3MubGluZSk7XG4gICAgdmFyIHRvcCA9IGhlaWdodEF0TGluZShsaW5lT2JqKSArIHBhZGRpbmdUb3AoY20uZGlzcGxheSk7XG4gICAgcmV0dXJuIHtsZWZ0OiBsZWZ0LCByaWdodDogbGVmdCwgdG9wOiB0b3AsIGJvdHRvbTogdG9wICsgbGluZU9iai5oZWlnaHR9O1xuICB9XG5cbiAgLy8gUG9zaXRpb25zIHJldHVybmVkIGJ5IGNvb3Jkc0NoYXIgY29udGFpbiBzb21lIGV4dHJhIGluZm9ybWF0aW9uLlxuICAvLyB4UmVsIGlzIHRoZSByZWxhdGl2ZSB4IHBvc2l0aW9uIG9mIHRoZSBpbnB1dCBjb29yZGluYXRlcyBjb21wYXJlZFxuICAvLyB0byB0aGUgZm91bmQgcG9zaXRpb24gKHNvIHhSZWwgPiAwIG1lYW5zIHRoZSBjb29yZGluYXRlcyBhcmUgdG9cbiAgLy8gdGhlIHJpZ2h0IG9mIHRoZSBjaGFyYWN0ZXIgcG9zaXRpb24sIGZvciBleGFtcGxlKS4gV2hlbiBvdXRzaWRlXG4gIC8vIGlzIHRydWUsIHRoYXQgbWVhbnMgdGhlIGNvb3JkaW5hdGVzIGxpZSBvdXRzaWRlIHRoZSBsaW5lJ3NcbiAgLy8gdmVydGljYWwgcmFuZ2UuXG4gIGZ1bmN0aW9uIFBvc1dpdGhJbmZvKGxpbmUsIGNoLCBvdXRzaWRlLCB4UmVsKSB7XG4gICAgdmFyIHBvcyA9IFBvcyhsaW5lLCBjaCk7XG4gICAgcG9zLnhSZWwgPSB4UmVsO1xuICAgIGlmIChvdXRzaWRlKSBwb3Mub3V0c2lkZSA9IHRydWU7XG4gICAgcmV0dXJuIHBvcztcbiAgfVxuXG4gIC8vIENvbXB1dGUgdGhlIGNoYXJhY3RlciBwb3NpdGlvbiBjbG9zZXN0IHRvIHRoZSBnaXZlbiBjb29yZGluYXRlcy5cbiAgLy8gSW5wdXQgbXVzdCBiZSBsaW5lU3BhY2UtbG9jYWwgKFwiZGl2XCIgY29vcmRpbmF0ZSBzeXN0ZW0pLlxuICBmdW5jdGlvbiBjb29yZHNDaGFyKGNtLCB4LCB5KSB7XG4gICAgdmFyIGRvYyA9IGNtLmRvYztcbiAgICB5ICs9IGNtLmRpc3BsYXkudmlld09mZnNldDtcbiAgICBpZiAoeSA8IDApIHJldHVybiBQb3NXaXRoSW5mbyhkb2MuZmlyc3QsIDAsIHRydWUsIC0xKTtcbiAgICB2YXIgbGluZU4gPSBsaW5lQXRIZWlnaHQoZG9jLCB5KSwgbGFzdCA9IGRvYy5maXJzdCArIGRvYy5zaXplIC0gMTtcbiAgICBpZiAobGluZU4gPiBsYXN0KVxuICAgICAgcmV0dXJuIFBvc1dpdGhJbmZvKGRvYy5maXJzdCArIGRvYy5zaXplIC0gMSwgZ2V0TGluZShkb2MsIGxhc3QpLnRleHQubGVuZ3RoLCB0cnVlLCAxKTtcbiAgICBpZiAoeCA8IDApIHggPSAwO1xuXG4gICAgdmFyIGxpbmVPYmogPSBnZXRMaW5lKGRvYywgbGluZU4pO1xuICAgIGZvciAoOzspIHtcbiAgICAgIHZhciBmb3VuZCA9IGNvb3Jkc0NoYXJJbm5lcihjbSwgbGluZU9iaiwgbGluZU4sIHgsIHkpO1xuICAgICAgdmFyIG1lcmdlZCA9IGNvbGxhcHNlZFNwYW5BdEVuZChsaW5lT2JqKTtcbiAgICAgIHZhciBtZXJnZWRQb3MgPSBtZXJnZWQgJiYgbWVyZ2VkLmZpbmQoMCwgdHJ1ZSk7XG4gICAgICBpZiAobWVyZ2VkICYmIChmb3VuZC5jaCA+IG1lcmdlZFBvcy5mcm9tLmNoIHx8IGZvdW5kLmNoID09IG1lcmdlZFBvcy5mcm9tLmNoICYmIGZvdW5kLnhSZWwgPiAwKSlcbiAgICAgICAgbGluZU4gPSBsaW5lTm8obGluZU9iaiA9IG1lcmdlZFBvcy50by5saW5lKTtcbiAgICAgIGVsc2VcbiAgICAgICAgcmV0dXJuIGZvdW5kO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNvb3Jkc0NoYXJJbm5lcihjbSwgbGluZU9iaiwgbGluZU5vLCB4LCB5KSB7XG4gICAgdmFyIGlubmVyT2ZmID0geSAtIGhlaWdodEF0TGluZShsaW5lT2JqKTtcbiAgICB2YXIgd3JvbmdMaW5lID0gZmFsc2UsIGFkanVzdCA9IDIgKiBjbS5kaXNwbGF5LndyYXBwZXIuY2xpZW50V2lkdGg7XG4gICAgdmFyIHByZXBhcmVkTWVhc3VyZSA9IHByZXBhcmVNZWFzdXJlRm9yTGluZShjbSwgbGluZU9iaik7XG5cbiAgICBmdW5jdGlvbiBnZXRYKGNoKSB7XG4gICAgICB2YXIgc3AgPSBjdXJzb3JDb29yZHMoY20sIFBvcyhsaW5lTm8sIGNoKSwgXCJsaW5lXCIsIGxpbmVPYmosIHByZXBhcmVkTWVhc3VyZSk7XG4gICAgICB3cm9uZ0xpbmUgPSB0cnVlO1xuICAgICAgaWYgKGlubmVyT2ZmID4gc3AuYm90dG9tKSByZXR1cm4gc3AubGVmdCAtIGFkanVzdDtcbiAgICAgIGVsc2UgaWYgKGlubmVyT2ZmIDwgc3AudG9wKSByZXR1cm4gc3AubGVmdCArIGFkanVzdDtcbiAgICAgIGVsc2Ugd3JvbmdMaW5lID0gZmFsc2U7XG4gICAgICByZXR1cm4gc3AubGVmdDtcbiAgICB9XG5cbiAgICB2YXIgYmlkaSA9IGdldE9yZGVyKGxpbmVPYmopLCBkaXN0ID0gbGluZU9iai50ZXh0Lmxlbmd0aDtcbiAgICB2YXIgZnJvbSA9IGxpbmVMZWZ0KGxpbmVPYmopLCB0byA9IGxpbmVSaWdodChsaW5lT2JqKTtcbiAgICB2YXIgZnJvbVggPSBnZXRYKGZyb20pLCBmcm9tT3V0c2lkZSA9IHdyb25nTGluZSwgdG9YID0gZ2V0WCh0byksIHRvT3V0c2lkZSA9IHdyb25nTGluZTtcblxuICAgIGlmICh4ID4gdG9YKSByZXR1cm4gUG9zV2l0aEluZm8obGluZU5vLCB0bywgdG9PdXRzaWRlLCAxKTtcbiAgICAvLyBEbyBhIGJpbmFyeSBzZWFyY2ggYmV0d2VlbiB0aGVzZSBib3VuZHMuXG4gICAgZm9yICg7Oykge1xuICAgICAgaWYgKGJpZGkgPyB0byA9PSBmcm9tIHx8IHRvID09IG1vdmVWaXN1YWxseShsaW5lT2JqLCBmcm9tLCAxKSA6IHRvIC0gZnJvbSA8PSAxKSB7XG4gICAgICAgIHZhciBjaCA9IHggPCBmcm9tWCB8fCB4IC0gZnJvbVggPD0gdG9YIC0geCA/IGZyb20gOiB0bztcbiAgICAgICAgdmFyI
23459HhEaWZmID0geCAtIChjaCA9PSBmcm9tID8gZnJvbVggOiB0b1gpO1xuICAgICAgICB3aGlsZSAoaXNFeHRlbmRpbmdDaGFyKGxpbmVPYmoudGV4dC5jaGFyQXQoY2gpKSkgKytjaDtcbiAgICAgICAgdmFyIHBvcyA9IFBvc1dpdGhJbmZvKGxpbmVObywgY2gsIGNoID09IGZyb20gPyBmcm9tT3V0c2lkZSA6IHRvT3V0c2lkZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhEaWZmIDwgLTEgPyAtMSA6IHhEaWZmID4gMSA/IDEgOiAwKTtcbiAgICAgICAgcmV0dXJuIHBvcztcbiAgICAgIH1cbiAgICAgIHZhciBzdGVwID0gTWF0aC5jZWlsKGRpc3QgLyAyKSwgbWlkZGxlID0gZnJvbSArIHN0ZXA7XG4gICAgICBpZiAoYmlkaSkge1xuICAgICAgICBtaWRkbGUgPSBmcm9tO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ZXA7ICsraSkgbWlkZGxlID0gbW92ZVZpc3VhbGx5KGxpbmVPYmosIG1pZGRsZSwgMSk7XG4gICAgICB9XG4gICAgICB2YXIgbWlkZGxlWCA9IGdldFgobWlkZGxlKTtcbiAgICAgIGlmIChtaWRkbGVYID4geCkge3RvID0gbWlkZGxlOyB0b1ggPSBtaWRkbGVYOyBpZiAodG9PdXRzaWRlID0gd3JvbmdMaW5lKSB0b1ggKz0gMTAwMDsgZGlzdCA9IHN0ZXA7fVxuICAgICAgZWxzZSB7ZnJvbSA9IG1pZGRsZTsgZnJvbVggPSBtaWRkbGVYOyBmcm9tT3V0c2lkZSA9IHdyb25nTGluZTsgZGlzdCAtPSBzdGVwO31cbiAgICB9XG4gIH1cblxuICB2YXIgbWVhc3VyZVRleHQ7XG4gIC8vIENvbXB1dGUgdGhlIGRlZmF1bHQgdGV4dCBoZWlnaHQuXG4gIGZ1bmN0aW9uIHRleHRIZWlnaHQoZGlzcGxheSkge1xuICAgIGlmIChkaXNwbGF5LmNhY2hlZFRleHRIZWlnaHQgIT0gbnVsbCkgcmV0dXJuIGRpc3BsYXkuY2FjaGVkVGV4dEhlaWdodDtcbiAgICBpZiAobWVhc3VyZVRleHQgPT0gbnVsbCkge1xuICAgICAgbWVhc3VyZVRleHQgPSBlbHQoXCJwcmVcIik7XG4gICAgICAvLyBNZWFzdXJlIGEgYnVuY2ggb2YgbGluZXMsIGZvciBicm93c2VycyB0aGF0IGNvbXB1dGVcbiAgICAgIC8vIGZyYWN0aW9uYWwgaGVpZ2h0cy5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDk7ICsraSkge1xuICAgICAgICBtZWFzdXJlVGV4dC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcInhcIikpO1xuICAgICAgICBtZWFzdXJlVGV4dC5hcHBlbmRDaGlsZChlbHQoXCJiclwiKSk7XG4gICAgICB9XG4gICAgICBtZWFzdXJlVGV4dC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcInhcIikpO1xuICAgIH1cbiAgICByZW1vdmVDaGlsZHJlbkFuZEFkZChkaXNwbGF5Lm1lYXN1cmUsIG1lYXN1cmVUZXh0KTtcbiAgICB2YXIgaGVpZ2h0ID0gbWVhc3VyZVRleHQub2Zmc2V0SGVpZ2h0IC8gNTA7XG4gICAgaWYgKGhlaWdodCA+IDMpIGRpc3BsYXkuY2FjaGVkVGV4dEhlaWdodCA9IGhlaWdodDtcbiAgICByZW1vdmVDaGlsZHJlbihkaXNwbGF5Lm1lYXN1cmUpO1xuICAgIHJldHVybiBoZWlnaHQgfHwgMTtcbiAgfVxuXG4gIC8vIENvbXB1dGUgdGhlIGRlZmF1bHQgY2hhcmFjdGVyIHdpZHRoLlxuICBmdW5jdGlvbiBjaGFyV2lkdGgoZGlzcGxheSkge1xuICAgIGlmIChkaXNwbGF5LmNhY2hlZENoYXJXaWR0aCAhPSBudWxsKSByZXR1cm4gZGlzcGxheS5jYWNoZWRDaGFyV2lkdGg7XG4gICAgdmFyIGFuY2hvciA9IGVsdChcInNwYW5cIiwgXCJ4eHh4eHh4eHh4XCIpO1xuICAgIHZhciBwcmUgPSBlbHQoXCJwcmVcIiwgW2FuY2hvcl0pO1xuICAgIHJlbW92ZUNoaWxkcmVuQW5kQWRkKGRpc3BsYXkubWVhc3VyZSwgcHJlKTtcbiAgICB2YXIgcmVjdCA9IGFuY2hvci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgd2lkdGggPSAocmVjdC5yaWdodCAtIHJlY3QubGVmdCkgLyAxMDtcbiAgICBpZiAod2lkdGggPiAyKSBkaXNwbGF5LmNhY2hlZENoYXJXaWR0aCA9IHdpZHRoO1xuICAgIHJldHVybiB3aWR0aCB8fCAxMDtcbiAgfVxuXG4gIC8vIE9QRVJBVElPTlNcblxuICAvLyBPcGVyYXRpb25zIGFyZSB1c2VkIHRvIHdyYXAgYSBzZXJpZXMgb2YgY2hhbmdlcyB0byB0aGUgZWRpdG9yXG4gIC8vIHN0YXRlIGluIHN1Y2ggYSB3YXkgdGhhdCBlYWNoIGNoYW5nZSB3b24ndCBoYXZlIHRvIHVwZGF0ZSB0aGVcbiAgLy8gY3Vyc29yIGFuZCBkaXNwbGF5ICh3aGljaCB3b3VsZCBiZSBhd2t3YXJkLCBzbG93LCBhbmRcbiAgLy8gZXJyb3ItcHJvbmUpLiBJbnN0ZWFkLCBkaXNwbGF5IHVwZGF0ZXMgYXJlIGJhdGNoZWQgYW5kIHR
23459oZW4gYWxsXG4gIC8vIGNvbWJpbmVkIGFuZCBleGVjdXRlZCBhdCBvbmNlLlxuXG4gIHZhciBvcGVyYXRpb25Hcm91cCA9IG51bGw7XG5cbiAgdmFyIG5leHRPcElkID0gMDtcbiAgLy8gU3RhcnQgYSBuZXcgb3BlcmF0aW9uLlxuICBmdW5jdGlvbiBzdGFydE9wZXJhdGlvbihjbSkge1xuICAgIGNtLmN1ck9wID0ge1xuICAgICAgY206IGNtLFxuICAgICAgdmlld0NoYW5nZWQ6IGZhbHNlLCAgICAgIC8vIEZsYWcgdGhhdCBpbmRpY2F0ZXMgdGhhdCBsaW5lcyBtaWdodCBuZWVkIHRvIGJlIHJlZHJhd25cbiAgICAgIHN0YXJ0SGVpZ2h0OiBjbS5kb2MuaGVpZ2h0LCAvLyBVc2VkIHRvIGRldGVjdCBuZWVkIHRvIHVwZGF0ZSBzY3JvbGxiYXJcbiAgICAgIGZvcmNlVXBkYXRlOiBmYWxzZSwgICAgICAvLyBVc2VkIHRvIGZvcmNlIGEgcmVkcmF3XG4gICAgICB1cGRhdGVJbnB1dDogbnVsbCwgICAgICAgLy8gV2hldGhlciB0byByZXNldCB0aGUgaW5wdXQgdGV4dGFyZWFcbiAgICAgIHR5cGluZzogZmFsc2UsICAgICAgICAgICAvLyBXaGV0aGVyIHRoaXMgcmVzZXQgc2hvdWxkIGJlIGNhcmVmdWwgdG8gbGVhdmUgZXhpc3RpbmcgdGV4dCAoZm9yIGNvbXBvc2l0aW5nKVxuICAgICAgY2hhbmdlT2JqczogbnVsbCwgICAgICAgIC8vIEFjY3VtdWxhdGVkIGNoYW5nZXMsIGZvciBmaXJpbmcgY2hhbmdlIGV2ZW50c1xuICAgICAgY3Vyc29yQWN0aXZpdHlIYW5kbGVyczogbnVsbCwgLy8gU2V0IG9mIGhhbmRsZXJzIHRvIGZpcmUgY3Vyc29yQWN0aXZpdHkgb25cbiAgICAgIGN1cnNvckFjdGl2aXR5Q2FsbGVkOiAwLCAvLyBUcmFja3Mgd2hpY2ggY3Vyc29yQWN0aXZpdHkgaGFuZGxlcnMgaGF2ZSBiZWVuIGNhbGxlZCBhbHJlYWR5XG4gICAgICBzZWxlY3Rpb25DaGFuZ2VkOiBmYWxzZSwgLy8gV2hldGhlciB0aGUgc2VsZWN0aW9uIG5lZWRzIHRvIGJlIHJlZHJhd25cbiAgICAgIHVwZGF0ZU1heExpbmU6IGZhbHNlLCAgICAvLyBTZXQgd2hlbiB0aGUgd2lkZXN0IGxpbmUgbmVlZHMgdG8gYmUgZGV0ZXJtaW5lZCBhbmV3XG4gICAgICBzY3JvbGxMZWZ0OiBudWxsLCBzY3JvbGxUb3A6IG51bGwsIC8vIEludGVybWVkaWF0ZSBzY3JvbGwgcG9zaXRpb24sIG5vdCBwdXNoZWQgdG8gRE9NIHlldFxuICAgICAgc2Nyb2xsVG9Qb3M6IG51bGwsICAgICAgIC8vIFVzZWQgdG8gc2Nyb2xsIHRvIGEgc3BlY2lmaWMgcG9zaXRpb25cbiAgICAgIGZvY3VzOiBmYWxzZSxcbiAgICAgIGlkOiArK25leHRPcElkICAgICAgICAgICAvLyBVbmlxdWUgSURcbiAgICB9O1xuICAgIGlmIChvcGVyYXRpb25Hcm91cCkge1xuICAgICAgb3BlcmF0aW9uR3JvdXAub3BzLnB1c2goY20uY3VyT3ApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjbS5jdXJPcC5vd25zR3JvdXAgPSBvcGVyYXRpb25Hcm91cCA9IHtcbiAgICAgICAgb3BzOiBbY20uY3VyT3BdLFxuICAgICAgICBkZWxheWVkQ2FsbGJhY2tzOiBbXVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBmaXJlQ2FsbGJhY2tzRm9yT3BzKGdyb3VwKSB7XG4gICAgLy8gQ2FsbHMgZGVsYXllZCBjYWxsYmFja3MgYW5kIGN1cnNvckFjdGl2aXR5IGhhbmRsZXJzIHVudGlsIG5vXG4gICAgLy8gbmV3IG9uZXMgYXBwZWFyXG4gICAgdmFyIGNhbGxiYWNrcyA9IGdyb3VwLmRlbGF5ZWRDYWxsYmFja3MsIGkgPSAwO1xuICAgIGRvIHtcbiAgICAgIGZvciAoOyBpIDwgY2FsbGJhY2tzLmxlbmd0aDsgaSsrKVxuICAgICAgICBjYWxsYmFja3NbaV0uY2FsbChudWxsKTtcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgZ3JvdXAub3BzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIHZhciBvcCA9IGdyb3VwLm9wc1tqXTtcbiAgICAgICAgaWYgKG9wLmN1cnNvckFjdGl2aXR5SGFuZGxlcnMpXG4gICAgICAgICAgd2hpbGUgKG9wLmN1cnNvckFjdGl2aXR5Q2FsbGVkIDwgb3AuY3Vyc29yQWN0aXZpdHlIYW5kbGVycy5sZW5ndGgpXG4gICAgICAgICAgICBvcC5jdXJzb3JBY3Rpdml0eUhhbmRsZXJzW29wLmN1cnNvckFjdGl2aXR5Q2FsbGVkKytdLmNhbGwobnVsbCwgb3AuY20pO1xuICAgICAgfVxuICAgIH0gd2hpbGUgKGkgPCBjYWxsYmFja3MubGVuZ3RoKTtcbiAgfVxuXG4gIC8vIEZpbmlzaCBhbiBvcGVyYXRpb24sIHVwZGF0aW5nIHRoZSBkaXNwbGF5IGFuZCBzaWduYWxsaW5nIGRlbGF5ZWQgZXZlbnRzXG4gIGZ1bmN0aW9uIGVuZE9wZXJhdGlvbihjbSkge1xuICAgIHZhciBvcCA9IGNtLmN1ck9wLCBncm91cCA9IG9wLm93bnNHcm91cDtcbiAgICBpZiAoIWdyb3VwKSByZXR1cm47XG5cbiAgICB0cnkgeyBmaXJlQ2FsbGJhY2tzRm9yT3BzKGdyb3VwKTsgfVxuICAgIGZpbmFsbHkge1xuICAgICAgb3BlcmF0aW9uR3JvdXAgPSBudWxsO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBncm91cC5vcHMubGVuZ3RoOyBpKyspXG4gICAgICAgIGdyb3VwLm9wc1tpXS5jbS5jdXJPcCA9IG51bGw7XG4gICAgICBlbmRPcGVyYXRpb25zKGdyb3VwKTtcbiAgICB9XG4gIH1cblxuICAvLyBUaGUgRE9NIHVwZGF0ZXMgZG9uZSB3aGVuIGFuIG9wZXJhdGlvbiBmaW5pc2hlcyBhcmUgYmF0Y2hlZCBzb1xuICAvLyB0aGF0IHRoZSBtaW5pbXVtIG51bWJlciBvZiByZWxheW91dHMgYXJlIHJlcXVpcmVkLlxuICBmdW5jdGlvbiBlbmRPcGVyYXRpb25zKGdyb3VwKSB7XG4gICAgdmFyIG9wcyA9IGdyb3VwLm9wcztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wcy5sZW5ndGg7IGkrKykgLy8gUmVhZCBET01cbiAgICAgIGVuZE9wZXJhdGlvbl9SMShvcHNbaV0pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3BzLmxlbmd0aDsgaSsrKSAvLyBXcml0ZSBET00gKG1heWJlKVxuICAgICAgZW5kT3BlcmF0aW9uX1cxKG9wc1tpXSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvcHMubGVuZ3RoOyBpKyspIC8vIFJlYWQgRE9NXG4gICAgICBlbmRPcGVyYXRpb25fUjIob3BzW2ldKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wcy5sZW5ndGg7IGkrKykgLy8gV3JpdGUgRE9NIChtYXliZSlcbiAgICAgIGVuZE9wZXJhdGlvbl9XMihvcHNbaV0pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3BzLmxlbmd0aDsgaSsrKSAvLyBSZWFkIERPTVxuICAgICAgZW5kT3BlcmF0aW9uX2ZpbmlzaChvcHNbaV0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5kT3BlcmF0aW9uX1IxKG9wKSB7XG4gICAgdmFyIGNtID0gb3AuY20sIGRpc3BsYXkgPSBjbS5kaXNwbGF5O1xuICAgIG1heWJlQ2xpcFNjcm9sbGJhcnMoY20pO1xuICAgIGlmIChvcC51cGRhdGVNYXhMaW5lKSBmaW5kTWF4TGluZShjbSk7XG5cbiAgICBvcC5tdXN0VXBkYXRlID0gb3Audmlld0NoYW5nZWQgfHwgb3AuZm9yY2VVcGRhdGUgfHwgb3Auc2Nyb2xsVG9wICE9IG51bGwgfHxcbiAgICAgIG9wLnNjcm9sbFRvUG9zICYmIChvcC5zY3JvbGxUb1Bvcy5mcm9tLmxpbmUgPCBkaXNwbGF5LnZpZXdGcm9tIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgb3Auc2Nyb2xsVG9Qb3MudG8ubGluZSA+PSBkaXNwbGF5LnZpZXdUbykgfHxcbiAgICAgIGRpc3BsYXkubWF4TGluZUNoYW5nZWQgJiYgY20ub3B0aW9ucy5saW5lV3JhcHBpbmc7XG4gICAgb3AudXBkYXRlID0gb3AubXVzdFVwZGF0ZSAmJlxuICAgICAgbmV3IERpc3BsYXlVcGRhdGUoY20sIG9wLm11c3RVcGRhdGUgJiYge3RvcDogb3Auc2Nyb2xsVG9wLCBlbnN1cmU6IG9wLnNjcm9sbFRvUG9zfSwgb3AuZm9yY2VVcGRhdGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5kT3BlcmF0aW9uX1cxKG9wKSB7XG4gICAgb3AudXBkYXRlZERpc3BsYXkgPSBvcC5tdXN0VXBkYXRlICYmIHVwZGF0ZURpc3BsYXlJZk5lZWRlZChvcC5jbSwgb3AudXBkYXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuZE9wZXJhdGlvbl9SMihvcCkge1xuICAgIHZhciBjbSA9IG9wLmNtLCBkaXNwbGF5ID0gY20uZGlzcGxheTtcbiAgICBpZiAob3AudXBkYXRlZERpc3BsYXkpIHVwZGF0ZUhlaWdodHNJblZpZXdwb3J0KGNtKTtcblxuICAgIG9wLmJhck1lYXN1cmUgPSBtZWFzdXJlRm9yU2Nyb2xsYmFycyhjbSk7XG5cbiAgICAvLyBJZiB0aGUgbWF4IGxpbmUgY2hhbmdlZCBzaW5jZSBpdCB3YXMgbGFzdCBtZWFzdXJlZCwgbWVhc3VyZSBpdCxcbiAgICAvLyBhbmQgZW5zdXJlIHRoZSBkb2N1bWVudCdzIHdpZHRoIG1hdGNoZXMgaXQuXG4gICAgLy8gdXBkYXRlRGlzcGxheV9XMiB3aWxsIHVzZSB0aGVzZSBwcm9wZXJ0aWVzIHRvIGRvIHRoZSBhY3R1YWwgcmVzaXppbmdcbiAgICBpZiAoZGlzcGxheS5tYXhMaW5lQ2hhbmdlZCAmJiAhY20ub3B0aW9ucy5saW5lV3JhcHBpbmcpIHtcbiAgICAgIG9wLmFkanVzdFdpZHRoVG8gPSBtZWFzdXJlQ2hhcihjbSwgZGlzcGxheS5tYXhMaW5lLCBkaXNwbGF5Lm1heExpbmUudGV4dC5sZW5ndGgpLmxlZnQgKyAzO1xuICAgICAgY20uZGlzcGxheS5zaXplcldpZHRoID0gb3AuYWRqdXN0V2lkdGhUbztcbiAgICAgIG9wLmJhck1lYXN1cmUuc2Nyb2xsV2lkdGggPVxuICAgICAgICBNYXRoLm1heChkaXNwbGF5LnNjcm9sbGVyLmNsaWVudFdpZHRoLCBkaXNwbGF5LnNpemVyLm9mZnNldExlZnQgKyBvcC5hZGp1c3RXaWR0aFRvICsgc2Nyb2xsR2FwKGNtKSArIGNtLmRpc3BsYXkuYmFyV2lkdGgpO1xuICAgICAgb3AubWF4U2Nyb2xsTGVmdCA9IE1hdGgubWF4KDAsIGRpc3BsYXkuc2l6ZXIub2Zmc2V0TGVmdCArIG9wLmFkanVzdFdpZHRoVG8gLSBkaXNwbGF5V2lkdGgoY20pKTtcbiAgICB9XG5cbiAgICBpZiAob3AudXBkYXRlZERpc3BsYXkgfHwgb3Auc2VsZWN0aW9uQ2hhbmdlZClcbiAgICAgIG9wLnByZXBhcmVkU2VsZWN0aW9uID0gZGlzcGxheS5pbnB1dC5wcmVwYXJlU2VsZWN0aW9uKCk7XG4gIH1cblxuICBmdW5jdGlvbiBlbmRPcGVyYXRpb25fVzIob3ApIHtcbiAgICB2YXIgY20gPSBvcC5jbTtcblxuICAgIGlmIChvcC5hZGp1c3RXaWR0aFRvICE9IG51bGwpIHtcbiAgICAgIGNtLmRpc3BsYXkuc2l6ZXIuc3R5bGUubWluV2lk
23459dGggPSBvcC5hZGp1c3RXaWR0aFRvICsgXCJweFwiO1xuICAgICAgaWYgKG9wLm1heFNjcm9sbExlZnQgPCBjbS5kb2Muc2Nyb2xsTGVmdClcbiAgICAgICAgc2V0U2Nyb2xsTGVmdChjbSwgTWF0aC5taW4oY20uZGlzcGxheS5zY3JvbGxlci5zY3JvbGxMZWZ0LCBvcC5tYXhTY3JvbGxMZWZ0KSwgdHJ1ZSk7XG4gICAgICBjbS5kaXNwbGF5Lm1heExpbmVDaGFuZ2VkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKG9wLnByZXBhcmVkU2VsZWN0aW9uKVxuICAgICAgY20uZGlzcGxheS5pbnB1dC5zaG93U2VsZWN0aW9uKG9wLnByZXBhcmVkU2VsZWN0aW9uKTtcbiAgICBpZiAob3AudXBkYXRlZERpc3BsYXkpXG4gICAgICBzZXREb2N1bWVudEhlaWdodChjbSwgb3AuYmFyTWVhc3VyZSk7XG4gICAgaWYgKG9wLnVwZGF0ZWREaXNwbGF5IHx8IG9wLnN0YXJ0SGVpZ2h0ICE9IGNtLmRvYy5oZWlnaHQpXG4gICAgICB1cGRhdGVTY3JvbGxiYXJzKGNtLCBvcC5iYXJNZWFzdXJlKTtcblxuICAgIGlmIChvcC5zZWxlY3Rpb25DaGFuZ2VkKSByZXN0YXJ0QmxpbmsoY20pO1xuXG4gICAgaWYgKGNtLnN0YXRlLmZvY3VzZWQgJiYgb3AudXBkYXRlSW5wdXQpXG4gICAgICBjbS5kaXNwbGF5LmlucHV0LnJlc2V0KG9wLnR5cGluZyk7XG4gICAgaWYgKG9wLmZvY3VzICYmIG9wLmZvY3VzID09IGFjdGl2ZUVsdCgpKSBlbnN1cmVGb2N1cyhvcC5jbSk7XG4gIH1cblxuICBmdW5jdGlvbiBlbmRPcGVyYXRpb25fZmluaXNoKG9wKSB7XG4gICAgdmFyIGNtID0gb3AuY20sIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCBkb2MgPSBjbS5kb2M7XG5cbiAgICBpZiAob3AudXBkYXRlZERpc3BsYXkpIHBvc3RVcGRhdGVEaXNwbGF5KGNtLCBvcC51cGRhdGUpO1xuXG4gICAgLy8gQWJvcnQgbW91c2Ugd2hlZWwgZGVsdGEgbWVhc3VyZW1lbnQsIHdoZW4gc2Nyb2xsaW5nIGV4cGxpY2l0bHlcbiAgICBpZiAoZGlzcGxheS53aGVlbFN0YXJ0WCAhPSBudWxsICYmIChvcC5zY3JvbGxUb3AgIT0gbnVsbCB8fCBvcC5zY3JvbGxMZWZ0ICE9IG51bGwgfHwgb3Auc2Nyb2xsVG9Qb3MpKVxuICAgICAgZGlzcGxheS53aGVlbFN0YXJ0WCA9IGRpc3BsYXkud2hlZWxTdGFydFkgPSBudWxsO1xuXG4gICAgLy8gUHJvcGFnYXRlIHRoZSBzY3JvbGwgcG9zaXRpb24gdG8gdGhlIGFjdHVhbCBET00gc2Nyb2xsZXJcbiAgICBpZiAob3Auc2Nyb2xsVG9wICE9IG51bGwgJiYgKGRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsVG9wICE9IG9wLnNjcm9sbFRvcCB8fCBvcC5mb3JjZVNjcm9sbCkpIHtcbiAgICAgIGRvYy5zY3JvbGxUb3AgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbEhlaWdodCAtIGRpc3BsYXkuc2Nyb2xsZXIuY2xpZW50SGVpZ2h0LCBvcC5zY3JvbGxUb3ApKTtcbiAgICAgIGRpc3BsYXkuc2Nyb2xsYmFycy5zZXRTY3JvbGxUb3AoZG9jLnNjcm9sbFRvcCk7XG4gICAgICBkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbFRvcCA9IGRvYy5zY3JvbGxUb3A7XG4gICAgfVxuICAgIGlmIChvcC5zY3JvbGxMZWZ0ICE9IG51bGwgJiYgKGRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsTGVmdCAhPSBvcC5zY3JvbGxMZWZ0IHx8IG9wLmZvcmNlU2Nyb2xsKSkge1xuICAgICAgZG9jLnNjcm9sbExlZnQgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbFdpZHR
23459oIC0gZGlzcGxheVdpZHRoKGNtKSwgb3Auc2Nyb2xsTGVmdCkpO1xuICAgICAgZGlzcGxheS5zY3JvbGxiYXJzLnNldFNjcm9sbExlZnQoZG9jLnNjcm9sbExlZnQpO1xuICAgICAgZGlzcGxheS5zY3JvbGxlci5zY3JvbGxMZWZ0ID0gZG9jLnNjcm9sbExlZnQ7XG4gICAgICBhbGlnbkhvcml6b250YWxseShjbSk7XG4gICAgfVxuICAgIC8vIElmIHdlIG5lZWQgdG8gc2Nyb2xsIGEgc3BlY2lmaWMgcG9zaXRpb24gaW50byB2aWV3LCBkbyBzby5cbiAgICBpZiAob3Auc2Nyb2xsVG9Qb3MpIHtcbiAgICAgIHZhciBjb29yZHMgPSBzY3JvbGxQb3NJbnRvVmlldyhjbSwgY2xpcFBvcyhkb2MsIG9wLnNjcm9sbFRvUG9zLmZyb20pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaXBQb3MoZG9jLCBvcC5zY3JvbGxUb1Bvcy50byksIG9wLnNjcm9sbFRvUG9zLm1hcmdpbik7XG4gICAgICBpZiAob3Auc2Nyb2xsVG9Qb3MuaXNDdXJzb3IgJiYgY20uc3RhdGUuZm9jdXNlZCkgbWF5YmVTY3JvbGxXaW5kb3coY20sIGNvb3Jkcyk7XG4gICAgfVxuXG4gICAgLy8gRmlyZSBldmVudHMgZm9yIG1hcmtlcnMgdGhhdCBhcmUgaGlkZGVuL3VuaWRkZW4gYnkgZWRpdGluZyBvclxuICAgIC8vIHVuZG9pbmdcbiAgICB2YXIgaGlkZGVuID0gb3AubWF5YmVIaWRkZW5NYXJrZXJzLCB1bmhpZGRlbiA9IG9wLm1heWJlVW5oaWRkZW5NYXJrZXJzO1xuICAgIGlmIChoaWRkZW4pIGZvciAodmFyIGkgPSAwOyBpIDwgaGlkZGVuLmxlbmd0aDsgKytpKVxuICAgICAgaWYgKCFoaWRkZW5baV0ubGluZXMubGVuZ3RoKSBzaWduYWwoaGlkZGVuW2ldLCBcImhpZGVcIik7XG4gICAgaWYgKHVuaGlkZGVuKSBmb3IgKHZhciBpID0gMDsgaSA8IHVuaGlkZGVuLmxlbmd0aDsgKytpKVxuICAgICAgaWYgKHVuaGlkZGVuW2ldLmxpbmVzLmxlbmd0aCkgc2lnbmFsKHVuaGlkZGVuW2ldLCBcInVuaGlkZVwiKTtcblxuICAgIGlmIChkaXNwbGF5LndyYXBwZXIub2Zmc2V0SGVpZ2h0KVxuICAgICAgZG9jLnNjcm9sbFRvcCA9IGNtLmRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsVG9wO1xuXG4gICAgLy8gRmlyZSBjaGFuZ2UgZXZlbnRzLCBhbmQgZGVsYXllZCBldmVudCBoYW5kbGVyc1xuICAgIGlmIChvcC5jaGFuZ2VPYmpzKVxuICAgICAgc2lnbmFsKGNtLCBcImNoYW5nZXNcIiwgY20sIG9wLmNoYW5nZU9ianMpO1xuICAgIGlmIChvcC51cGRhdGUpXG4gICAgICBvcC51cGRhdGUuZmluaXNoKCk7XG4gIH1cblxuICAvLyBSdW4gdGhlIGdpdmVuIGZ1bmN0aW9uIGluIGFuIG9wZXJhdGlvblxuICBmdW5jdGlvbiBydW5Jbk9wKGNtLCBmKSB7XG4gICAgaWYgKGNtLmN1ck9wKSByZXR1cm4gZigpO1xuICAgIHN0YXJ0T3BlcmF0aW9uKGNtKTtcbiAgICB0cnkgeyByZXR1cm4gZigpOyB9XG4gICAgZmluYWxseSB7IGVuZE9wZXJhdGlvbihjbSk7IH1cbiAgfVxuICAvLyBXcmFwcyBhIGZ1bmN0aW9uIGluIGFuIG9wZXJhdGlvbi4gUmV0dXJucyB0aGUgd3JhcHBlZCBmdW5jdGlvbi5cbiAgZnVuY3Rpb24gb3BlcmF0aW9uKGNtLCBmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGNtLmN1ck9wKSByZXR1cm4gZi5hcHBseShjbSwgYXJndW1lbnRzKTtcbiAgICAgIHN0YXJ0T3BlcmF0aW9uKGNtKTtcbiAgICAgIHRyeSB7IHJldHVybiBmLmFwcGx5KGNtLCBhcmd1bWVudHMpOyB9XG4gICAgICBmaW5hbGx5IHsgZW5kT3BlcmF0aW9uKGNtKTsgfVxuICAgIH07XG4gIH1cbiAgLy8gVXNlZCB0byBhZGQgbWV0aG9kcyB0byBlZGl0b3IgYW5kIGRvYyBpbnN0YW5jZXMsIHdyYXBwaW5nIHRoZW0gaW5cbiAgLy8gb3BlcmF0aW9ucy5cbiAgZnVuY3Rpb24gbWV0aG9kT3AoZikge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmN1ck9wKSByZXR1cm4gZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgc3RhcnRPcGVyYXRpb24odGhpcyk7XG4gICAgICB0cnkgeyByZXR1cm4gZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9XG4gICAgICBmaW5hbGx5IHsgZW5kT3BlcmF0aW9uKHRoaXMpOyB9XG4gICAgfTtcbiAgfVxuICBmdW5jdGlvbiBkb2NNZXRob2RPcChmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGNtID0gdGhpcy5jbTtcbiAgICAgIGlmICghY20gfHwgY20uY3VyT3ApIHJldHVybiBmLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICBzdGFydE9wZXJhdGlvbihjbSk7XG4gICAgICB0cnkgeyByZXR1cm4gZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9XG4gICAgICBmaW5hbGx5IHsgZW5kT3BlcmF0aW9uKGNtKTsgfVxuICAgIH07XG4gIH1cblxuICAvLyBWSUVXIFRSQUNLSU5HXG5cbiAgLy8gVGhlc2Ugb2JqZWN0cyBhcmUgdXNlZCB0byByZXByZXNlbnQgdGhlIHZpc2libGUgKGN1cnJlbnRseSBkcmF3bilcbiAgLy8gcGFydCBvZiB0aGUgZG9jdW1lbnQuIEEgTGluZVZpZXcgbWF5IGNvcnJlc3BvbmQgdG8gbXVsdGlwbGVcbiAgLy8gbG9naWNhbCBsaW5lcywgaWYgdGhvc2UgYXJlIGNvbm5lY3RlZCBieSBjb2xsYXBzZWQgcmFuZ2VzLlxuICBmdW5jdGlvbiBMaW5lVmlldyhkb2MsIGxpbmUsIGxpbmVOKSB7XG4gICAgLy8gVGhlIHN0YXJ0aW5nIGxpbmVcbiAgICB0aGlzLmxpbmUgPSBsaW5lO1xuICAgIC8vIENvbnRpbnVpbmcgbGluZXMsIGlmIGFueVxuICAgIHRoaXMucmVzdCA9IHZpc3VhbExpbmVDb250aW51ZWQobGluZSk7XG4gICAgLy8gTnVtYmVyIG9mIGxvZ2ljYWwgbGluZXMgaW4gdGhpcyB2aXN1YWwgbGluZVxuICAgIHRoaXMuc2l6ZSA9IHRoaXMucmVzdCA/IGxpbmVObyhsc3QodGhpcy5yZXN0KSkgLSBsaW5lTiArIDEgOiAxO1xuICAgIHRoaXMubm9kZSA9IHRoaXMudGV4dCA9IG51bGw7XG4gICAgdGhpcy5oaWRkZW4gPSBsaW5lSXNIaWRkZW4oZG9jLCBsaW5lKTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBhIHJhbmdlIG9mIExpbmVWaWV3IG9iamVjdHMgZm9yIHRoZSBnaXZlbiBsaW5lcy5cbiAgZnVuY3Rpb24gYnVpbGRWaWV3QXJyYXkoY20sIGZyb20sIHRvKSB7XG4gICAgdmFyIGFycmF5ID0gW10sIG5leHRQb3M7XG4gICAgZm9yICh2YXIgcG9zID0gZnJvbTsgcG9zIDwgdG87IHBvcyA9IG5leHRQb3MpIHtcbiAgICAgIHZhciB2aWV3ID0gbmV3IExpbmVWaWV3KGNtLmRvYywgZ2V0TGluZShjbS5kb2MsIHBvcyksIHBvcyk7XG4gICAgICBuZXh0UG9zID0gcG9zICsgdmlldy5zaXplO1xuICAgICAgYXJyYXkucHVzaCh2aWV3KTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cbiAgLy8gVXBkYXRlcyB0aGUgZGlzcGxheS52aWV3IGRhdGEgc3RydWN0dXJlIGZvciBhIGdpdmVuIGNoYW5nZSB0byB0aG
23459VcbiAgLy8gZG9jdW1lbnQuIEZyb20gYW5kIHRvIGFyZSBpbiBwcmUtY2hhbmdlIGNvb3JkaW5hdGVzLiBMZW5kaWZmIGlzXG4gIC8vIHRoZSBhbW91bnQgb2YgbGluZXMgYWRkZWQgb3Igc3VidHJhY3RlZCBieSB0aGUgY2hhbmdlLiBUaGlzIGlzXG4gIC8vIHVzZWQgZm9yIGNoYW5nZXMgdGhhdCBzcGFuIG11bHRpcGxlIGxpbmVzLCBvciBjaGFuZ2UgdGhlIHdheVxuICAvLyBsaW5lcyBhcmUgZGl2aWRlZCBpbnRvIHZpc3VhbCBsaW5lcy4gcmVnTGluZUNoYW5nZSAoYmVsb3cpXG4gIC8vIHJlZ2lzdGVycyBzaW5nbGUtbGluZSBjaGFuZ2VzLlxuICBmdW5jdGlvbiByZWdDaGFuZ2UoY20sIGZyb20sIHRvLCBsZW5kaWZmKSB7XG4gICAgaWYgKGZyb20gPT0gbnVsbCkgZnJvbSA9IGNtLmRvYy5maXJzdDtcbiAgICBpZiAodG8gPT0gbnVsbCkgdG8gPSBjbS5kb2MuZmlyc3QgKyBjbS5kb2Muc2l6ZTtcbiAgICBpZiAoIWxlbmRpZmYpIGxlbmRpZmYgPSAwO1xuXG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5O1xuICAgIGlmIChsZW5kaWZmICYmIHRvIDwgZGlzcGxheS52aWV3VG8gJiZcbiAgICAgICAgKGRpc3BsYXkudXBkYXRlTGluZU51bWJlcnMgPT0gbnVsbCB8fCBkaXNwbGF5LnVwZGF0ZUxpbmVOdW1iZXJzID4gZnJvbSkpXG4gICAgICBkaXNwbGF5LnVwZGF0ZUxpbmVOdW1iZXJzID0gZnJvbTtcblxuICAgIGNtLmN1ck9wLnZpZXdDaGFuZ2VkID0gdHJ1ZTtcblxuICAgIGlmIChmcm9tID49IGRpc3BsYXkudmlld1RvKSB7IC8vIENoYW5nZSBhZnRlclxuICAgICAgaWYgKHNhd0NvbGxhcHNlZFNwYW5zICYmIHZpc3VhbExpbmVObyhjbS5kb2MsIGZyb20pIDwgZGlzcGxheS52aWV3VG8pXG4gICAgICAgIHJlc2V0VmlldyhjbSk7XG4gICAgfSBlbHNlIGlmICh0byA8PSBkaXNwbGF5LnZpZXdGcm9tKSB7IC8vIENoYW5nZSBiZWZvcmVcbiAgICAgIGlmIChzYXdDb2xsYXBzZWRTcGFucyAmJiB2aXN1YWxMaW5lRW5kTm8oY20uZG9jLCB0byArIGxlbmRpZmYpID4gZGlzcGxheS52aWV3RnJvbSkge1xuICAgICAgICByZXNldFZpZXcoY20pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGlzcGxheS52aWV3RnJvbSArPSBsZW5kaWZmO1xuICAgICAgICBkaXNwbGF5LnZpZXdUbyArPSBsZW5kaWZmO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZnJvbSA8PSBkaXNwbGF5LnZpZXdGcm9tICYmIHRvID49IGRpc3BsYXkudmlld1RvKSB7IC8vIEZ1bGwgb3ZlcmxhcFxuICAgICAgcmVzZXRWaWV3KGNtKTtcbiAgICB9IGVsc2UgaWYgKGZyb20gPD0gZGlzcGxheS52aWV3RnJvbSkgeyAvLyBUb3Agb3ZlcmxhcFxuICAgICAgdmFyIGN1dCA9IHZpZXdDdXR0aW5nUG9pbnQoY20sIHRvLCB0byArIGxlbmRpZmYsIDEpO1xuICAgICAgaWYgKGN1dCkge1xuICAgICAgICBkaXNwbGF5LnZpZXcgPSBkaXNwbGF5LnZpZXcuc2xpY2UoY3V0LmluZGV4KTtcbiAgICAgICAgZGlzcGxheS52aWV3RnJvbSA9IGN1dC5saW5lTjtcbiAgICAgICAgZGlzcGxheS52aWV3VG8gKz0gbGVuZGlmZjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc2V0VmlldyhjbSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0byA+PSBkaXNwbGF5LnZpZXdUbykgeyAvLyBCb3R0b20gb3ZlcmxhcFxuICAgICAgdmFyIGN1dCA9IHZpZXdDdXR0aW5nUG9pbnQoY20sIGZyb20sIGZyb20sIC0xKTtcbiAgICAgIGlmIChjdXQpIHtcbiAgICAgICAgZGlzcGxheS52aWV3ID0gZGlzcGxheS52aWV3LnNsaWNlKDAsIGN1dC5pbmRleCk7XG4gICAgICAgIGRpc3BsYXkudmlld1RvID0gY3V0LmxpbmVOO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzZXRWaWV3KGNtKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgeyAvLyBHYXAgaW4gdGhlIG1pZGRsZVxuICAgICAgdmFyIGN1dFRvcCA9IHZpZXdDdXR0aW5nUG9pbnQoY20sIGZyb20sIGZyb20sIC0xKTtcbiAgICAgIHZhciBjdXRCb3QgPSB2aWV3Q3V0dGluZ1BvaW50KGNtLCB0bywgdG8gKyBsZW5kaWZmLCAxKTtcbiAgICAgIGlmIChjdXRUb3AgJiYgY3V0Qm90KSB7XG4gICAgICAgIGRpc3BsYXkudmlldyA9IGRpc3BsYXkudmlldy5zbGljZSgwLCBjdXRUb3AuaW5kZXgpXG4gICAgICAgICAgLmNvbmNhdChidWlsZFZpZXdBcnJheShjbSwgY3V0VG9wLmxpbmVOLCBjdXRCb3QubGluZU4pKVxuICAgICAgICAgIC5jb25jYXQoZGlzcGxheS52aWV3LnNsaWNlKGN1dEJvdC5pbmRleCkpO1xuICAgICAgICBkaXNwbGF5LnZpZXdUbyArPSBsZW5kaWZmO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzZXRWaWV3KGNtKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZXh0ID0gZGlzcGxheS5leHRlcm5hbE1lYXN1cmVkO1xuICAgIGlmIChleHQpIHtcbiAgICAgIGlmICh0byA8IGV4dC5saW5lTilcbiAgICAgICAgZXh0LmxpbmVOICs9IGxlbmRpZmY7XG4gICAgICBlbHNlIGlmIChmcm9tIDwgZXh0LmxpbmVOICsgZXh0LnNpemUpXG4gICAgICAgIGRpc3BsYXkuZXh0ZXJuYWxNZWFzdXJlZCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLy8gUmVnaXN0ZXIgYSBjaGFuZ2UgdG8gYSBzaW5nbGUgbGluZS4gVHlwZSBtdXN0IGJlIG9uZSBvZiBcInRleHRcIixcbiAgLy8gXCJndXR0ZXJcIiwgXCJjbGFzc1wiLCBcIndpZGdldFwiXG4gIGZ1bmN0aW9uIHJlZ0xpbmVDaGFuZ2UoY20sIGxpbmUsIHR5cGUpIHtcbiAgICBjbS5jdXJPcC52aWV3Q2hhbmdlZCA9IHRydWU7XG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCBleHQgPSBjbS5kaXNwbGF5LmV4dGVybmFsTWVhc3VyZWQ7XG4gICAgaWYgKGV4dCAmJiBsaW5lID49IGV4dC5saW5lTiAmJiBsaW5lIDwgZXh0LmxpbmVOICsgZXh0LnNpemUpXG4gICAgICBkaXNwbGF5LmV4dGVybmFsTWVhc3VyZWQgPSBudWxsO1xuXG4gICAgaWYgKGxpbmUgPCBkaXNwbGF5LnZpZXdGcm9tIHx8IGxpbmUgPj0gZGlzcGxheS52aWV3VG8pIHJldHVybjtcbiAgICB2YXIgbGluZVZpZXcgPSBkaXNwbGF5LnZpZXdbZmluZFZpZXdJbmRleChjbSwgbGluZSldO1xuICAgIGlmIChsaW5lVmlldy5ub2RlID09IG51bGwpIHJldHVybjtcbiAgICB2YXIgYXJyID0gbGluZVZpZXcuY2hhbmdlcyB8fCAobGluZVZpZXcuY2hhbmdlcyA9IFtdKTtcbiAgICBpZiAoaW5kZX
23459hPZihhcnIsIHR5cGUpID09IC0xKSBhcnIucHVzaCh0eXBlKTtcbiAgfVxuXG4gIC8vIENsZWFyIHRoZSB2aWV3LlxuICBmdW5jdGlvbiByZXNldFZpZXcoY20pIHtcbiAgICBjbS5kaXNwbGF5LnZpZXdGcm9tID0gY20uZGlzcGxheS52aWV3VG8gPSBjbS5kb2MuZmlyc3Q7XG4gICAgY20uZGlzcGxheS52aWV3ID0gW107XG4gICAgY20uZGlzcGxheS52aWV3T2Zmc2V0ID0gMDtcbiAgfVxuXG4gIC8vIEZpbmQgdGhlIHZpZXcgZWxlbWVudCBjb3JyZXNwb25kaW5nIHRvIGEgZ2l2ZW4gbGluZS4gUmV0dXJuIG51bGxcbiAgLy8gd2hlbiB0aGUgbGluZSBpc24ndCB2aXNpYmxlLlxuICBmdW5jdGlvbiBmaW5kVmlld0luZGV4KGNtLCBuKSB7XG4gICAgaWYgKG4gPj0gY20uZGlzcGxheS52aWV3VG8pIHJldHVybiBudWxsO1xuICAgIG4gLT0gY20uZGlzcGxheS52aWV3RnJvbTtcbiAgICBpZiAobiA8IDApIHJldHVybiBudWxsO1xuICAgIHZhciB2aWV3ID0gY20uZGlzcGxheS52aWV3O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgbiAtPSB2aWV3W2ldLnNpemU7XG4gICAgICBpZiAobiA8IDApIHJldHVybiBpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHZpZXdDdXR0aW5nUG9pbnQoY20sIG9sZE4sIG5ld04sIGRpcikge1xuICAgIHZhciBpbmRleCA9IGZpbmRWaWV3SW5kZXgoY20sIG9sZE4pLCBkaWZmLCB2aWV3ID0gY20uZGlzcGxheS52aWV3O1xuICAgIGlmICghc2F3Q29sbGFwc2VkU3BhbnMgfHwgbmV3TiA9PSBjbS5kb2MuZmlyc3QgKyBjbS5kb2Muc2l6ZSlcbiAgICAgIHJldHVybiB7aW5kZXg6IGluZGV4LCBsaW5lTjogbmV3Tn07XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBjbS5kaXNwbGF5LnZpZXdGcm9tOyBpIDwgaW5kZXg7IGkrKylcbiAgICAgIG4gKz0gdmlld1tpXS5zaXplO1xuICAgIGlmIChuICE9IG9sZE4pIHtcbiAgICAgIGlmIChkaXIgPiAwKSB7XG4gICAgICAgIGlmIChpbmRleCA9PSB2aWV3Lmxlbmd0aCAtIDEpIHJldHVybiBudWxsO1xuICAgICAgICBkaWZmID0gKG4gKyB2aWV3W2luZGV4XS5zaXplKSAtIG9sZE47XG4gICAgICAgIGluZGV4Kys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaWZmID0gbiAtIG9sZE47XG4gICAgICB9XG4gICAgICBvbGROICs9IGRpZmY7IG5ld04gKz0gZGlmZjtcbiAgICB9XG4gICAgd2hpbGUgKHZpc3VhbExpbmVObyhjbS5kb2MsIG5ld04pICE9IG5ld04pIHtcbiAgICAgIGlmIChpbmRleCA9PSAoZGlyIDwgMCA/IDAgOiB2aWV3Lmxlbmd0aCAtIDEpKSByZXR1cm4gbnVsbDtcbiAgICAgIG5ld04gKz0gZGlyICogdmlld1tpbmRleCAtIChkaXIgPCAwID8gMSA6IDApXS5zaXplO1xuICAgICAgaW5kZXggKz0gZGlyO1xuICAgIH1cbiAgICByZXR1cm4ge2luZGV4OiBpbmRleCwgbGluZU46IG5ld059O1xuICB9XG5cbiAgLy8gRm9yY2UgdGhlIHZpZXcgdG8gY292ZXIgYSBnaXZlbiByYW5nZSwgYWRkaW5nIGVtcHR5IHZpZXcgZWxlbWVudFxuICAvLyBvciBjbGlwcGluZyBvZmYgZXhpc3Rpbmcgb25lcyBhcyBuZWVkZWQuXG4gIGZ1bmN0aW9uIGFkanVzdFZpZXcoY20sIGZyb20sIHRvKSB7XG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCB2aWV3ID0gZGlzcGxheS52aWV3O1xuICAgIGlmICh2aWV3Lmxlbmd0aCA9PSAwIHx8IGZyb20gPj0gZGlzcGxheS52aWV3VG8gfHwgdG8gPD0gZGlzcGxheS52aWV3RnJvbSkge1xuICAgICAgZGlzcGxheS52aWV3ID0gYnVpbGRWaWV3QXJyYXkoY20sIGZyb20sIHRvKTtcbiAgICAgIGRpc3BsYXkudmlld0Zyb20gPSBmcm9tO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoZGlzcGxheS52aWV3RnJvbSA+IGZyb20pXG4gICAgICAgIGRpc3BsYXkudmlldyA9IGJ1aWxkVmlld0FycmF5KGNtLCBmcm9tLCBkaXNwbGF5LnZpZXdGcm9tKS5jb25jYXQoZGlzcGxheS52aWV3KTtcbiAgICAgIGVsc2UgaWYgKGRpc3BsYXkudmlld0Zyb20gPCBmcm9tKVxuICAgICAgICBkaXNwbGF5LnZpZXcgPSBkaXNwbGF5LnZpZXcuc2xpY2UoZmluZFZpZXdJbmRleChjbSwgZnJvbSkpO1xuICAgICAgZGlzcGxheS52aWV3RnJvbSA9IGZyb207XG4gICAgICBpZiAoZGlzcGxheS52aWV3VG8gPCB0bylcbiAgICAgICAgZGlzcGxheS52aWV3ID0gZGlzcGxheS52aWV3LmNvbmNhdChidWlsZFZpZXdBcnJheShjbSwgZGlzcGxheS52aWV3VG8sIHRvKSk7XG4gICAgICBlbHNlIGlmIChkaXNwbGF5LnZpZXdUbyA+IHRvKVxuICAgICAgICBkaXNwbGF5LnZpZXcgPSBkaXNwbGF5LnZpZXcuc2xpY2UoMCwgZmluZFZpZXdJbmRleChjbSwgdG8pKTtcbiAgICB9XG4gICAgZGlzcGxheS52aWV3VG8gPSB0bztcbiAgfVxuXG4gIC8vIENvdW50IHRoZSBudW1iZXIgb2YgbGluZXMgaW4gdGhlIHZpZXcgd2hvc2UgRE9NIHJlcHJlc2VudGF0aW9uIGlzXG4gIC8vIG91dCBvZiBkYXRlIChvciBub25leGlzdGVudCkuXG4gIGZ1bmN0aW9uIGNvdW50RGlydHlWaWV3KGNtKSB7XG4gICAgdmFyIHZpZXcgPSBjbS5kaXNwbGF5LnZpZXcsIGRpcnR5ID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZpZXcubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBsaW5lVmlldyA9IHZpZXdbaV07XG4gICAgICBpZiAoIWxpbmVWaWV3LmhpZGRlbiAmJiAoIWxpbmVWaWV3Lm5vZGUgfHwgbGluZVZpZXcuY2hhbmdlcykpICsrZGlydHk7XG4gICAgfVxuICAgIHJldHVybiBkaXJ0eTtcbiAgfVxuXG4gIC8vIEVWRU5UIEhBTkRMRVJTXG5cbiAgLy8gQXR0YWNoIHRoZSBuZWNlc3NhcnkgZXZlbnQgaGFuZGxlcnMgd2hlbiBpbml0aWFsaXppbmcgdGhlIGVkaXRvclxuICBmdW5jdGlvbiByZWdpc3RlckV2ZW50SGFuZGxlcnMoY20pIHtcbiAgICB2YXIgZCA9IGNtLmRpc3BsYXk7XG4gICAgb24oZC5zY3JvbGxlciwgXCJtb3VzZWRvd25cIiwgb3BlcmF0aW9uKGNtLCBvbk1vdXNlRG93bikpO1xuICAgIC8vIE9sZGVyIElFJ3Mgd2lsbCBub3QgZmlyZSBhIHNlY29uZCBtb3VzZWRvd24gZm9yIGEgZG91YmxlIGNsaWNrXG4gICAgaWYgKGllICYmIGllX3ZlcnNpb24gPCAxMSlcbiAgICAgIG9uKGQuc2Nyb2xsZXIsIFwiZGJsY2xpY2tcIiwgb3BlcmF0aW9uKGNtLCBmdW5jdGlvbihlKSB7XG4gICAgICAgIGlmIChzaWduYWxET01FdmVudChjbSwgZSkpIHJldHVybjtcbiAgICAgICAgdmFyIHBvcyA9IHBvc0Zyb21Nb3VzZShjbSwgZSk7XG4gICAgICAgIGlmICghcG9zIHx8IGNsaWNrSW5HdXR0ZXIoY20sIGUpIHx8IGV2ZW50SW5XaWRnZXQ
23459oY20uZGlzcGxheSwgZSkpIHJldHVybjtcbiAgICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgICAgdmFyIHdvcmQgPSBjbS5maW5kV29yZEF0KHBvcyk7XG4gICAgICAgIGV4dGVuZFNlbGVjdGlvbihjbS5kb2MsIHdvcmQuYW5jaG9yLCB3b3JkLmhlYWQpO1xuICAgICAgfSkpO1xuICAgIGVsc2VcbiAgICAgIG9uKGQuc2Nyb2xsZXIsIFwiZGJsY2xpY2tcIiwgZnVuY3Rpb24oZSkgeyBzaWduYWxET01FdmVudChjbSwgZSkgfHwgZV9wcmV2ZW50RGVmYXVsdChlKTsgfSk7XG4gICAgLy8gU29tZSBicm93c2VycyBmaXJlIGNvbnRleHRtZW51ICphZnRlciogb3BlbmluZyB0aGUgbWVudSwgYXRcbiAgICAvLyB3aGljaCBwb2ludCB3ZSBjYW4ndCBtZXNzIHdpdGggaXQgYW55bW9yZS4gQ29udGV4dCBtZW51IGlzXG4gICAgLy8gaGFuZGxlZCBpbiBvbk1vdXNlRG93biBmb3IgdGhlc2UgYnJvd3NlcnMuXG4gICAgaWYgKCFjYXB0dXJlUmlnaHRDbGljaykgb24oZC5zY3JvbGxlciwgXCJjb250ZXh0bWVudVwiLCBmdW5jdGlvbihlKSB7b25Db250ZXh0TWVudShjbSwgZSk7fSk7XG5cbiAgICAvLyBVc2VkIHRvIHN1cHByZXNzIG1vdXNlIGV2ZW50IGhhbmRsaW5nIHdoZW4gYSB0b3VjaCBoYXBwZW5zXG4gICAgdmFyIHRvdWNoRmluaXNoZWQsIHByZXZUb3VjaCA9IHtlbmQ6IDB9O1xuICAgIGZ1bmN0aW9uIGZpbmlzaFRvdWNoKCkge1xuICAgICAgaWYgKGQuYWN0aXZlVG91Y2gpIHtcbiAgICAgICAgdG91Y2hGaW5pc2hlZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7ZC5hY3RpdmVUb3VjaCA9IG51bGw7fSwgMTAwMCk7XG4gICAgICAgIHByZXZUb3VjaCA9IGQuYWN0aXZlVG91Y2g7XG4gICAgICAgIHByZXZUb3VjaC5lbmQgPSArbmV3IERhdGU7XG4gICAgICB9XG4gICAgfTtcbiAgICBmdW5jdGlvbiBpc01vdXNlTGlrZVRvdWNoRXZlbnQoZSkge1xuICAgICAgaWYgKGUudG91Y2hlcy5sZW5ndGggIT0gMSkgcmV0dXJuIGZhbHNlO1xuICAgICAgdmFyIHRvdWNoID0gZS50b3VjaGVzWzBdO1xuICAgICAgcmV0dXJuIHRvdWNoLnJhZGl1c1ggPD0gMSAmJiB0b3VjaC5yYWRpdXNZIDw9IDE7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGZ
23459hckF3YXkodG91Y2gsIG90aGVyKSB7XG4gICAgICBpZiAob3RoZXIubGVmdCA9PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgICAgIHZhciBkeCA9IG90aGVyLmxlZnQgLSB0b3VjaC5sZWZ0LCBkeSA9IG90aGVyLnRvcCAtIHRvdWNoLnRvcDtcbiAgICAgIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeSA+IDIwICogMjA7XG4gICAgfVxuICAgIG9uKGQuc2Nyb2xsZXIsIFwidG91Y2hzdGFydFwiLCBmdW5jdGlvbihlKSB7XG4gICAgICBpZiAoIWlzTW91c2VMaWtlVG91Y2hFdmVudChlKSkge1xuICAgICAgICBjbGVhclRpbWVvdXQodG91Y2hGaW5pc2hlZCk7XG4gICAgICAgIHZhciBub3cgPSArbmV3IERhdGU7XG4gICAgICAgIGQuYWN0aXZlVG91Y2ggPSB7c3RhcnQ6IG5vdywgbW92ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgIHByZXY6IG5vdyAtIHByZXZUb3VjaC5lbmQgPD0gMzAwID8gcHJldlRvdWNoIDogbnVsbH07XG4gICAgICAgIGlmIChlLnRvdWNoZXMubGVuZ3RoID09IDEpIHtcbiAgICAgICAgICBkLmFjdGl2ZVRvdWNoLmxlZnQgPSBlLnRvdWNoZXNbMF0ucGFnZVg7XG4gICAgICAgICAgZC5hY3RpdmVUb3VjaC50b3AgPSBlLnRvdWNoZXNbMF0ucGFnZVk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBvbihkLnNjcm9sbGVyLCBcInRvdWNobW92ZVwiLCBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChkLmFjdGl2ZVRvdWNoKSBkLmFjdGl2ZVRvdWNoLm1vdmVkID0gdHJ1ZTtcbiAgICB9KTtcbiAgICBvbihkLnNjcm9sbGVyLCBcInRvdWNoZW5kXCIsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIHZhciB0b3VjaCA9IGQuYWN0aXZlVG91Y2g7XG4gICAgICBpZiAodG91Y2ggJiYgIWV2ZW50SW5XaWRnZXQoZCwgZSkgJiYgdG91Y2gubGVmdCAhPSBudWxsICYmXG4gICAgICAgICAgIXRvdWNoLm1vdmVkICYmIG5ldyBEYXRlIC0gdG91Y2guc3RhcnQgPCAzMDApIHtcbiAgICAgICAgdmFyIHBvcyA9IGNtLmNvb3Jkc0NoYX
23459IoZC5hY3RpdmVUb3VjaCwgXCJwYWdlXCIpLCByYW5nZTtcbiAgICAgICAgaWYgKCF0b3VjaC5wcmV2IHx8IGZhckF3YXkodG91Y2gsIHRvdWNoLnByZXYpKSAvLyBTaW5nbGUgdGFwXG4gICAgICAgICAgcmFuZ2UgPSBuZXcgUmFuZ2UocG9zLCBwb3MpO1xuICAgICAgICBlbHNlIGlmICghdG91Y2gucHJldi5wcmV2IHx8IGZhckF3YXkodG91Y2gsIHRvdWNoLnByZXYucHJldikpIC8vIERvdWJsZSB0YXBcbiAgICAgICAgICByYW5nZSA9IGNtLmZpbmRXb3JkQXQocG9zKTtcbiAgICAgICAgZWxzZSAvLyBUcmlwbGUgdGFwXG4gICAgICAgICAgcmFuZ2UgPSBuZXcgUmFuZ2UoUG9zKHBvcy5saW5lLCAwKSwgY2xpcFBvcyhjbS5kb2MsIFBvcyhwb3MubGluZSArIDEsIDApKSk7XG4gICAgICAgIGNtLnNldFNlbGVjdGlvbihyYW5nZS5hbmNob3IsIHJhbmdlLmhlYWQpO1xuICAgICAgICBjbS5mb2N1cygpO1xuICAgICAgICBlX3ByZXZlbnREZWZhdWx0KGUpO1xuICAgICAgfVxuICAgICAgZmluaXNoVG91Y2goKTtcbiAgICB9KTtcbiAgICBvbihkLnNjcm9sbGVyLCBcInRvdWNoY2FuY2VsXCIsIGZpbmlzaFRvdWNoKTtcblxuICAgIC8vIFN5bmMgc2Nyb2xsaW5nIGJldHdlZW4gZmFrZSBzY3JvbGxiYXJzIGFuZCByZWFsIHNjcm9sbGFibGVcbiAgICAvLyBhcmVhLCBlbnN1cmUgdmlld3BvcnQgaXMgdXBkYXRlZCB3aGVuIHNjcm9sbGluZy5cbiAgICBvbihkLnNjcm9sbGVyLCBcInNjcm9sbFwiLCBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChkLnNjcm9sbGVyLmNsaWVudEhlaWdodCkge1xuICAgICAgICBzZXRTY3JvbGxUb3AoY20sIGQuc2Nyb2xsZXIuc2Nyb2xsVG9wKTtcbiAgICAgICAgc2V0U2Nyb2xsTGVmdChjbSwgZC5zY3JvbGxlci5zY3JvbGxMZWZ0LCB0cnVlKTtcbiAgICAgICAgc2lnbmFsKGNtLCBcInNjcm9sbFwiLCBjbSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBMaXN0ZW4gdG8gd2hlZWwgZXZlbnRzIGluIG9yZGVyIHRvIHRyeSBhbmQgdXBkYXRlIHRoZSB2aWV3cG9ydCBvbiB0aW1lLlxuICAgIG9uKGQuc2Nyb2xsZXIsIFwibW91c2V3aGVlbFwiLCBmdW5jdGlvbihlKXtvblNjcm9sbFdoZWVsKGNtLCBlKTt9KTtcbiAgICBvbihkLnNjcm9sbGVyLCBcIkRPTU1vdXNlU2Nyb2xsXCIsIGZ1bmN0aW9uKGUpe29uU2Nyb2xsV2hlZWwoY20sIGUpO30pO1xuXG4gICAgLy8gUHJldmVudCB3cmFwcGVyIGZyb20gZXZlciBzY3JvbGxpbmdcbiAgICBvbihkLndyYXBwZXIsIFwic2Nyb2xsXCIsIGZ1bmN0aW9uKCkgeyBkLndyYXBwZXIuc2Nyb2xsVG9wID0gZC53cmFwcGVyLnNjcm9sbExlZnQgPSAwOyB9KTtcblxuICAgIGQuZHJhZ0Z1bmN0aW9ucyA9IHtcbiAgICAgIGVudGVyOiBmdW5jdGlvbihlKSB7aWYgKCFzaWduYWxET01FdmVudChjbSwgZSkpIGVfc3RvcChlKTt9LFxuICAgICAgb3ZlcjogZnVuY3Rpb24oZSkge2lmICghc2lnbmFsRE9NRXZlbnQoY20sIGUpKSB7IG9uRHJhZ092ZXIoY20sIGUpOyBlX3N0b3AoZSk7IH19LFxuICAgICAgc3RhcnQ6IGZ1bmN0aW9uKGUpe29uRHJhZ1N0YXJ0KGNtLCBlKTt9LFxuICAgICAgZHJvcDogb3BlcmF0aW9uKGNtLCBvbkRyb3ApLFxuICAgICAgbGVhdmU6IGZ1bmN0aW9uKCkge2NsZWFyRHJhZ0N1cnNvcihjbSk7fVxuICAgIH07XG5cbiAgICB2YXIgaW5wID0gZC5pbnB1dC5nZXRGaWVsZCgpO1xuICAgIG9uKGlucCwgXCJrZXl1cFwiLCBmdW5jdGlvbihlKSB7IG9uS2V5VXAuY2FsbChjbSwgZSk7IH0pO1xuICAgIG9uKGlucCwgXCJrZXlkb3duXCIsIG9wZXJhdGlvbihjbSwgb25LZXlEb3duKSk7XG4gICAgb24oaW5wLCBcImtleXByZXNzXCIsIG9wZXJhdGlvbihjbSwgb25LZXlQcmVzcykpO1xuICAgIG9uKGlucCwgXCJmb2N1c1wiLCBiaW5kKG9uRm9jdXMsIGNtKSk7XG4gICAgb24oaW5wLCBcImJsdXJcIiwgYmluZChvbkJsdXIsIGNtKSk7XG4gIH1cblxuICBmdW5jdGlvbiBkcmFnRHJvcENoYW5nZWQoY20sIHZhbHVlLCBvbGQpIHtcbiAgICB2YXIgd2FzT24gPSBvbGQgJiYgb2xkICE9IENvZGVNaXJyb3IuSW5pdDtcbiAgICBpZiAoIXZhbHVlICE9ICF3YXNPbikge1xuICAgICAgdmFyIGZ1bmNzID0gY20uZGlzcGxheS5kcmFnRnVuY3Rpb25zO1xuICAgICAgdmFyIHRvZ2dsZSA9IHZhbHVlID8gb24gOiBvZmY7XG4gICAgICB0b2dnbGUoY20uZGlzcGxheS5zY3JvbGxlciwgXCJkcmFnc3RhcnRcIiwgZnVuY3Muc3RhcnQpO1xuICAgICAgdG9nZ2xlKGNtLmRpc3BsYXkuc2Nyb2xsZXIsIFwiZHJhZ2VudGVyXCIsIGZ1bmNzLmVudGVyKTtcbiAgICAgIHRvZ2dsZShjbS5kaXNwbGF5LnNjcm9sbGVyLCBcImRyYWdvdmVyXCIsIGZ1bmNzLm92ZXIpO1xuICAgICAgdG9nZ2xlKGNtLmRpc3BsYXkuc2Nyb2xsZXIsIFwiZHJhZ2xlYXZlXCIsIGZ1bmNzLmxlYXZlKTtcbiAgICAgIHRvZ2dsZShjbS5kaXNwbGF5LnNjcm9sbGVyLCBcImRyb3BcIiwgZnVuY3MuZHJvcCk7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2FsbGVkIHdoZW4gdGhlIHdpbmRvdyByZXNpemVzXG4gIGZ1bmN0aW9uIG9uUmVzaXplKGNtKSB7XG4gICAgdmFyIGQgPSBjbS5kaXNwbGF5O1xuICAgIGlmIChkLmxhc3RXcmFwSGVpZ2h0ID09IGQud3JhcHBlci5jbGllbnRIZWlnaHQgJiYgZC5sYXN0V3JhcFdpZHRoID09IGQud3JhcHBlci5jbGllbnRXaWR0aClcbiAgICAgIHJldHVybjtcbiAgICAvLyBNaWdodCBiZSBhIHRleHQgc2NhbGluZyBvcGVyYXRpb24sIGNsZWFyIHNpemUgY2FjaGVzLlxuICAgIGQuY2FjaGVkQ2hhcldpZHRoID0gZC5jYWNoZWRUZXh0SGVpZ2h0ID0gZC5jYWNoZWRQYWRkaW5nSCA9IG51bGw7XG4gICAgZC5zY3JvbGxiYXJzQ2xpcHBlZCA9IGZhbHNlO1xuICAgIGNtLnNldFNpemUoKTtcbiAgfVxuXG4gIC8vIE1PVVNFIEVWRU5UU1xuXG4gIC8vIFJldHVybiB0cnVlIHdoZW4gdGhlIGdpdmVuIG1vdXNlIGV2ZW50IGhhcHBlbmVkIGluIGEgd2lkZ2V0XG4gIGZ1bmN0aW9uIGV2ZW50SW5XaWRnZXQoZGlzcGxheSwgZSkge1xuICAgIGZvciAodmFyIG4gPSBlX3RhcmdldChlKTsgbiAhPSBkaXNwbGF5LndyYXBwZXI7IG4gPSBuLnBhcmVudE5vZGUpIHtcbiAgICAgIGlmICghbiB8fCAobi5ub2RlVHlwZSA9PSAxICYmIG4uZ2V0QXR0cmlidXRlKFwiY20taWdub3JlLWV2ZW50c1wiKSA9PSBcInRydWVcIikgfHxcbiAgICAgICAgICAobi5wYXJlbnROb2RlID09IGRpc3BsYXkuc2l6ZXIgJiYgbiAhPSBkaXNwbGF5Lm1vdmVyKSlcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gR2l2ZW4gYSBtb3VzZSBldmVudCwgZmluZCB0aGUgY29ycmVzcG9uZGluZyBwb3NpdGlvbi4gSWYgbGliZXJhbFxuICAvLyBpcyBmYWxzZSwgaXQgY2hlY2tzIHdoZXRoZXIgYSBndXR0ZXIgb3Igc2Nyb2xsYmFyIHdhcyBjbGlja2VkLFxuICAvLyBhbmQgcmV0dXJucyBudWxsIGlmIGl0IHdhcy4gZm9yUmVjdCBpcyB1c2VkIGJ5IHJlY3Rhbmd1bGFyXG4gIC8vIHNlbGVjdGlvbnMsIGFuZCB0cmllcyB0byBlc3RpbWF0ZSBhIGNoYXJhY3RlciBwb3NpdGlvbiBldmVuIGZvclxuICAvLyBjb29yZGluYX
23459RlcyBiZXlvbmQgdGhlIHJpZ2h0IG9mIHRoZSB0ZXh0LlxuICBmdW5jdGlvbiBwb3NGcm9tTW91c2UoY20sIGUsIGxpYmVyYWwsIGZvclJlY3QpIHtcbiAgICB2YXIgZGlzcGxheSA9IGNtLmRpc3BsYXk7XG4gICAgaWYgKCFsaWJlcmFsICYmIGVfdGFyZ2V0KGUpLmdldEF0dHJpYnV0ZShcImNtLW5vdC1jb250ZW50XCIpID09IFwidHJ1ZVwiKSByZXR1cm4gbnVsbDtcblxuICAgIHZhciB4LCB5LCBzcGFjZSA9IGRpc3BsYXkubGluZVNwYWNlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIC8vIEZhaWxzIHVucHJlZGljdGFibHkgb24gSUVbNjddIHdoZW4gbW91c2UgaXMgZHJhZ2dlZCBhcm91bmQgcXVpY2tseS5cbiAgICB0cnkgeyB4ID0gZS5jbGllbnRYIC0gc3BhY2UubGVmdDsgeSA9IGUuY2xpZW50WSAtIHNwYWNlLnRvcDsgfVxuICAgIGNhdGNoIChlKSB7IHJldHVybiBudWxsOyB9XG4gICAgdmFyIGNvb3JkcyA9IGNvb3Jkc0NoYXIoY20sIHgsIHkpLCBsaW5lO1xuICAgIGlmIChmb3JSZWN0ICYmIGNvb3Jkcy54UmVsID09IDEgJiYgKGxpbmUgPSBnZXRMaW5lKGNtLmRvYywgY29vcmRzLmxpbmUpLnRleHQpLmxlbmd0aCA9PSBjb29yZHMuY2gpIHtcbiAgICAgIHZhciBjb2xEaWZmID0gY291bnRDb2x1bW4obGluZSwgbGluZS5sZW5ndGgsIGNtLm9wdGlvbnMudGFiU2l6ZSkgLSBsaW5lLmxlbmd0aDtcbiAgICAgIGNvb3JkcyA9IFBvcyhjb29yZHMubGluZSwgTWF0aC5tYXgoMCwgTWF0aC5yb3VuZCgoeCAtIHBhZGRpbmdIKGNtLmRpc3BsYXkpLmxlZnQpIC8gY2hhcldpZHRoKGNtLmRpc3BsYXkpKSAtIGNvbERpZmYpKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvb3JkcztcbiAgfVxuXG4gIC8vIEEgbW91c2UgZG93biBjYW4gYmUgYSBzaW5nbGUgY2xpY2ssIGRvdWJsZSBjbGljaywgdHJpcGxlIGNsaWNrLFxuICAvLyBzdGFydCBvZiBzZWxlY3Rpb24gZHJhZywgc3RhcnQgb2YgdGV4dCBkcmFnLCBuZXcgY3Vyc29yXG4gIC8vIChjdHJsLWNsaWNrKSwgcmVjdGFuZ2xlIGRyYWcgKGFsdC1kcmFnKSwgb3IgeHdpblxuICAvLyBtaWRkbGUtY2xpY2stcGFzdGUuIE9yIGl0IG1pZ2h0IGJlIGEgY2xpY2sgb24gc29tZXRoaW5nIHdlIHNob3VsZFxuICAvLyBub3QgaW50ZXJmZXJlIHdpdGgsIHN1Y2ggYXMgYSBzY3JvbGxiYXIgb3Igd2lkZ2V0LlxuICBmdW5jdGlvbiBvbk1vdXNlRG93bihlKSB7XG4gICAgdmFyIGNtID0gdGhpcywgZGlzcGxheSA9IGNtLmRpc3BsYXk7XG4gICAgaWYgKGRpc3BsYXkuYWN0aXZlVG91Y2ggJiYgZGlzcGxheS5pbnB1dC5zdXBwb3J0c1RvdWNoKCkgfHwgc2lnbmFsRE9NRXZlbnQoY20sIGUpKSByZXR1cm47XG4gICAgZGlzcGxheS5zaGlmdCA9IGUuc2hpZnRLZXk7XG5cbiAgICBpZiAoZXZlbnRJbldpZGdldChkaXNwbGF5LCBlKSkge1xuICAgICAgaWYgKCF3ZWJraXQpIHtcbiAgICAgICAgLy8gQnJpZWZseSB0dXJuIG9mZiBkcmFnZ2FiaWxpdHksIHRvIGFsbG93IHdpZGdldHMgdG8gZG9cbiAgICAgICAgLy8gbm9ybWFsIGRyYWdnaW5nIHRoaW5ncy5cbiAgICAgICAgZGlzcGxheS5zY3JvbGxlci5kcmFnZ2FibGUgPSBmYWxzZTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpe2Rpc3BsYXkuc2Nyb2xsZXIuZHJhZ2dhYmxlID0gdHJ1ZTt9LCAxMDApO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY2xpY2tJbkd1dHRlcihjbSwgZSkpIHJldHVybjtcbiAgICB2YXIgc3RhcnQgPSBwb3NGcm9tTW91c2UoY20sIGUpO1xuICAgIHdpbmRvdy5mb2N1cygpO1xuXG4gICAgc3dpdGNoIChlX2J1dHRvbihlKSkge1xuICAgIGNhc2UgMTpcbiAgICAgIC8vICMzMjYxOiBtYWtlIHN1cmUsIHRoYXQgd2UncmUgbm90IHN0YXJ0aW5nIGEgc2Vjb25kIHNlbGVjdGlvblxuICAgICAgaWYgKGNtLnN0YXRlLnNlbGVjdGluZ1RleHQpXG4gICAgICAgIGNtLnN0YXRlLnNlbGVjdGluZ1RleHQoZSk7XG4gICAgICBlbHNlIGlmIChzdGFydClcbiAgICAgICAgbGVmdEJ1dHRvbkRvd24oY20sIGUsIHN0YXJ0KTtcbiAgICAgIGVsc2UgaWYgKGVfdGFyZ2V0KGUpID09IGRpc3BsYXkuc2Nyb2xsZXIpXG4gICAgICAgIGVfcHJldmVudERlZmF1bHQoZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDI6XG4gICAgICBpZiAod2Via2l0KSBjbS5zdGF0ZS5sYXN0TWlkZGxlRG93biA9ICtuZXcgRGF0ZTtcbiAgICAgIGlmIChzdGFydCkgZXh0ZW5kU2VsZWN0aW9uKGNtLmRvYywgc3RhcnQpO1xuICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtkaXNwbGF5LmlucHV0LmZvY3VzKCk7fSwgMjApO1xuICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIGlmIChjYXB0dXJlUmlnaHRDbGljaykgb25Db250ZXh0TWVudShjbSwgZSk7XG4gICAgICBlbHNlIGRlbGF5Qmx1ckV2ZW50KGNtKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHZhciBsYXN0Q2xpY2ssIGxhc3REb3VibGVDbGljaztcbiAgZnVuY3Rpb24gbGVmdEJ1dHRvbkRvd24oY20sIGUsIHN0YXJ0KSB7XG4gICAgaWYgKGllKSBzZXRUaW1lb3V0KGJpbmQoZW5zdXJlRm9jdXMsIGNtKSwgMCk7XG4gICAgZWxzZSBjbS5jdXJPcC5mb2N1cyA9IGFjdGl2ZUVsdCgpO1xuXG4gICAgdmFyIG5vdyA9ICtuZXcgRGF0ZSwgdHlwZTtcbiAgICBpZiAobGFzdERvdWJsZUNsaWNrICYmIGxhc3REb3VibGVDbGljay50aW1lID4gbm93IC0gNDAwICYmIGNtcChsYXN0RG91YmxlQ2xpY2sucG9zLCBzdGFydCkgPT0gMCkge1xuICAgICAgdHlwZSA9IFwidHJpcGxlXCI7XG4gICAgfSBlbHNlIGlmIChsYXN0Q2xpY2sgJiYgbGFzdENsaWNrLnRpbWUgPiBub3cgLSA0MDAgJiYgY21wKGxhc3RDbGljay5wb3MsIHN0YXJ0KSA9PSAwKSB7XG4gICAgICB0eXBlID0gXCJkb3VibGVcIjtcbiAgICAgIGxhc3REb3VibGVDbGljayA9IHt0aW1lOiBub3csIHBvczogc3RhcnR9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0eXBlID0gXCJzaW5nbGVcIjtcbiAgICAgIGxhc3RDbGljayA9IHt0aW1lOiBub3csIHBvczogc3RhcnR9O1xuICAgIH1cblxuICAgIHZhciBzZWwgPSBjbS5kb2Muc2VsLCBtb2RpZmllciA9IG1hYyA/IGUubWV0YUtleSA6IGUuY3RybEtleSwgY29udGFpbmVkO1xuICAgIGlmIChjbS5vcHRpb25zLmRyYWdEcm9wICYmIGRyYWdBbmREcm9wICYmICFpc1JlYWRPbmx5KGNtKSAmJlxuICAgICAgICB0eX
23459BlID09IFwic2luZ2xlXCIgJiYgKGNvbnRhaW5lZCA9IHNlbC5jb250YWlucyhzdGFydCkpID4gLTEgJiZcbiAgICAgICAgKGNtcCgoY29udGFpbmVkID0gc2VsLnJhbmdlc1tjb250YWluZWRdKS5mcm9tKCksIHN0YXJ0KSA8IDAgfHwgc3RhcnQueFJlbCA+IDApICYmXG4gICAgICAgIChjbXAoY29udGFpbmVkLnRvKCksIHN0YXJ0KSA+IDAgfHwgc3RhcnQueFJlbCA8IDApKVxuICAgICAgbGVmdEJ1dHRvblN0YXJ0RHJhZyhjbSwgZSwgc3RhcnQsIG1vZGlmaWVyKTtcbiAgICBlbHNlXG4gICAgICBsZWZ0QnV0dG9uU2VsZWN0KGNtLCBlLCBzdGFydCwgdHlwZSwgbW9kaWZpZXIpO1xuICB9XG5cbiAgLy8gU3RhcnQgYSB0ZXh0IGRyYWcuIFdoZW4gaXQgZW5kcywgc2VlIGlmIGFueSBkcmFnZ2luZyBhY3R1YWxseVxuICAvLyBoYXBwZW4sIGFuZCB0cmVhdCBhcyBhIGNsaWNrIGlmIGl0IGRpZG4ndC5cbiAgZnVuY3Rpb24gbGVmdEJ1dHRvblN0YXJ0RHJhZyhjbSwgZSwgc3RhcnQsIG1vZGlmaWVyKSB7XG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCBzdGFydFRpbWUgPSArbmV3IERhdGU7XG4gICAgdmFyIGRyYWdFbmQgPSBvcGVyYXRpb24oY20sIGZ1bmN0aW9uKGUyKSB7XG4gICAgICBpZiAod2Via2l0KSBkaXNwbGF5LnNjcm9sbGVyLmRyYWdnYWJsZSA9IGZhbHNlO1xuICAgICAgY20uc3RhdGUuZHJhZ2dpbmdUZXh0ID0gZmFsc2U7XG4gICAgICBvZmYoZG9jdW1lbnQsIFwibW91c2V1cFwiLCBkcmFnRW5kKTtcbiAgICAgIG9mZihkaXNwbGF5LnNjcm9sbGVyLCBcImRyb3BcIiwgZHJhZ0VuZCk7XG4gICAgICBpZiAoTWF0aC5hYnMoZS5jbGllbnRYIC0gZTIuY2xpZW50WCkgKyBNYXRoLmFicyhlLmNsaWVudFkgLSBlMi5jbGllbnRZKSA8IDEwKSB7XG4gICAgICAgIGVfcHJldmVudERlZmF1bHQoZTIpO1xuICAgICAgICBpZiAoIW1vZGlmaWVyICYmICtuZXcgRGF0ZSAtIDIwMCA8IHN0YXJ0VGltZSlcbiAgICAgICAgICBleHRlbmRTZWxlY3Rpb24oY20uZG9jLCBzdGFydCk7XG4gICAgICAgIC8vIFdvcmsgYXJvdW5kIHVuZXhwbGFpbmFibGUgZm9jdXMgcHJvYmxlbSBpbiBJRTkgKCMyMTI3KSBhbmQgQ2hyb21lICgjMzA4MSlcbiAgICAgICAgaWYgKHdlYmtpdCB8fCBpZSAmJiBpZV92ZXJzaW9uID09IDkpXG4gICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtkb2N1bWVudC5ib2R5LmZvY3VzKCk7IGRpc3BsYXkuaW5wdXQuZm9jdXMoKTt9LCAyMCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBkaXNwbGF5LmlucHV0LmZvY3VzKCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gTGV0IHRoZSBkcmFnIGhhbmRsZXIgaGFuZGxlIHRoaXMuXG4gICAgaWYgKHdlYmtpdCkgZGlzcGxheS5zY3JvbGxlci5kcmFnZ2FibGUgPSB0cnVlO1xuICAgIGNtLnN0YXRlLmRyYWdnaW5nVGV4dCA9IGRyYWdFbmQ7XG4gICAgLy8gSUUncyBhcHByb2FjaCB0byBkcmFnZ2FibGVcbiAgICBpZiAoZGlzcGxheS5zY3JvbGxlci5kcmFnRHJvcCkgZGlzcGxheS5zY3JvbGxlci5kcmFnRHJvcCgpO1xuICAgIG9uKGRvY3VtZW50LCBcIm1vdXNldXBcIiwgZHJhZ0VuZCk7XG4gICAgb24oZGlzcGxheS5zY3JvbGxlciwgXCJkcm9wXCIsIGRyYWdFbmQpO1xuICB9XG5cbiAgLy8gTm9ybWFsIHNlbGVjdGlvbiwgYXMgb3Bwb3NlZCB0byB0ZXh0IGRyYWdnaW5nLlxuICBmdW5jdGlvbiBsZWZ0QnV0dG9uU2VsZWN0KGNtLCBlLCBzdGFydCwgdHlwZSwgYWRkTmV3KSB7XG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCBkb2MgPSBjbS5kb2M7XG4gICAgZV9wcmV2ZW50RGVmYXVsdChlKTtcblxuICAgIHZhciBvdXJSYW5nZSwgb3VySW5kZXgsIHN0YXJ0U2VsID0gZG9jLnNlbCwgcmFuZ2VzID0gc3RhcnRTZWwucmFuZ2VzO1xuICAgIGlmIChhZGROZXcgJiYgIWUuc2hpZnRLZXkpIHtcbiAgICAgIG91ckluZGV4ID0gZG9jLnNlbC5jb250YWlucyhzdGFydCk7XG4gICAgICBpZiAob3VySW5kZXggPiAtMSlcbiAgICAgICAgb3VyUmFuZ2UgPSByYW5nZXNbb3VySW5kZXhdO1xuICAgICAgZWxzZVxuICAgICAgICBvdXJSYW5nZSA9IG5ldyBSYW5nZShzdGFydCwgc3RhcnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXJSYW5nZSA9IGRvYy5zZWwucHJpbWFyeSgpO1xuICAgICAgb3VySW5kZXggPSBkb2Muc2VsLnByaW1JbmRleDtcbiAgICB9XG5cbiAgICBpZiAoZS5hbHRLZXkpIHtcbiAgICAgIHR5cGUgPSBcInJlY3RcIjtcbiAgICAgIGlmICghYWRkTmV3KSBvdXJSYW5nZSA9IG5ldyBSYW5nZShzdGFydCwgc3RhcnQpO1xuICAgICAgc3RhcnQgPSBwb3NGcm9tTW91c2UoY20sIGUsIHRydWUsIHRydWUpO1xuICAgICAgb3VySW5kZXggPSAtMTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT0gXCJkb3VibGVcIikge1xuICAgICAgdmFyIHdvcmQgPSBjbS5maW5kV29yZEF0KHN0YXJ0KTtcbiAgICAgIGlmIChjbS5kaXNwbGF5LnNoaWZ0IHx8IGRvYy5leHRlbmQpXG4gICAgICAgIG91clJhbmdlID0gZXh0ZW5kUmFuZ2UoZG9jLCBvdXJSYW5nZSwgd29yZC5hbmNob3IsIHdvcmQuaGVhZCk7XG4gICAgICBlbHNlXG4gICAgICAgIG91clJhbmdlID0gd29yZDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT0gXCJ0cmlwbGVcIikge1xuICAgICAgdmFyIGxpbmUgPSBuZXcgUmFuZ2UoUG9zKHN0YXJ0LmxpbmUsIDApLCBjbGlwUG9zKGRvYywgUG9zKHN0YXJ0LmxpbmUgKyAxLCAwKSkpO1xuICAgICAgaWYgKGNtLmRpc3BsYXkuc2hpZnQgfHwgZG9jLmV4dGVuZClcbiAgICAgICAgb3VyUmFuZ2UgPSBleHRlbmRSYW5nZShkb2MsIG91clJhbmdlLCBsaW5lLmFuY2hvciwgbGluZS5oZWFkKTtcbiAgICAgIGVsc2VcbiAgICAgICAgb3VyUmFuZ2UgPSBsaW5lO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXJSYW5nZSA9IGV4dGVuZFJhbmdlKGRvYywgb3VyUmFuZ2UsIHN0YXJ0KTtcbiAgICB9XG5cbiAgICBpZiAoIWFkZE5ldykge1xuICAgICAgb3VySW5kZXggPSAwO1xuICAgICAgc2V0U2VsZWN0aW9uKGRvYywgbmV3IFNlbGVjdGlvbihbb3VyUmFuZ2VdLCAwKSwgc2VsX21vdXNlKTtcbiAgICAgIHN0YXJ0U2VsID0gZG9jLnNlbDtcbiAgICB9IGVsc2UgaWYgKG91ckluZGV4ID09IC0xKSB7XG4gICAgICBvdXJJbmRleCA9IHJhbmdlcy5sZW5ndGg7XG4gICAgICBzZXRTZWxlY3Rpb24oZG9jLCBub3JtYWxpem
23459VTZWxlY3Rpb24ocmFuZ2VzLmNvbmNhdChbb3VyUmFuZ2VdKSwgb3VySW5kZXgpLFxuICAgICAgICAgICAgICAgICAgIHtzY3JvbGw6IGZhbHNlLCBvcmlnaW46IFwiKm1vdXNlXCJ9KTtcbiAgICB9IGVsc2UgaWYgKHJhbmdlcy5sZW5ndGggPiAxICYmIHJhbmdlc1tvdXJJbmRleF0uZW1wdHkoKSAmJiB0eXBlID09IFwic2luZ2xlXCIgJiYgIWUuc2hpZnRLZXkpIHtcbiAgICAgIHNldFNlbGVjdGlvbihkb2MsIG5vcm1hbGl6ZVNlbGVjdGlvbihyYW5nZXMuc2xpY2UoMCwgb3VySW5kZXgpLmNvbmNhdChyYW5nZXMuc2xpY2Uob3VySW5kZXggKyAxKSksIDApLFxuICAgICAgICAgICAgICAgICAgIHtzY3JvbGw6IGZhbHNlLCBvcmlnaW46IFwiKm1vdXNlXCJ9KTtcbiAgICAgIHN0YXJ0U2VsID0gZG9jLnNlbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVwbGFjZU9uZVNlbGVjdGlvbihkb2MsIG91ckluZGV4LCBvdXJSYW5nZSwgc2VsX21vdXNlKTtcbiAgICB9XG5cbiAgICB2YXIgbGFzdFBvcyA9IHN0YXJ0O1xuICAgIGZ1bmN0aW9uIGV4dGVuZFRvKHBvcykge1xuICAgICAgaWYgKGNtcChsYXN0UG9zLCBwb3MpID09IDApIHJldHVybjtcbiAgICAgIGxhc3RQb3MgPSBwb3M7XG5cbiAgICAgIGlmICh0eXBlID09IFwicmVjdFwiKSB7XG4gICAgICAgIHZhciByYW5nZXMgPSBbXSwgdGFiU2l6ZSA9IGNtLm9wdGlvbnMudGFiU2l6ZTtcbiAgICAgICAgdmFyIHN0YXJ0Q29sID0gY291bnRDb2x1bW4oZ2V0TGluZShkb2MsIHN0YXJ0LmxpbmUpLnRleHQsIHN0YXJ0LmNoLCB0YWJTaXplKTtcbiAgICAgICAgdmFyIHBvc0NvbCA9IGNvdW50Q29sdW1uKGdldExpbmUoZG9jLCBwb3MubGluZSkudGV4dCwgcG9zLmNoLCB0YWJTaXplKTtcbiAgICAgICAgdmFyIGxlZnQgPSBNYXRoLm1pbihzdGFydENvbCwgcG9zQ29sKSwgcmlnaHQgPSBNYXRoLm1heChzdGFydENvbCwgcG9zQ29sKTtcbiAgICAgICAgZm9yICh2YXIgbGluZSA9IE1hdGgubWluKHN0YXJ0LmxpbmUsIHBvcy5saW5lKSwgZW5kID0gTWF0aC5taW4oY20ubGFzdExpbmUoKSwgTWF0aC5tYXgoc3RhcnQubGluZSwgcG9zLmxpbmUpKTtcbiAgICAgICAgICAgICBsaW5lIDw9IGVuZDsgbGluZSsrKSB7XG4gICAgICAgICAgdmFyIHRleHQgPSBnZXRMaW5lKGRvYywgbGluZSkudGV4dCwgbGVmdFBvcyA9IGZpbmRDb2x1bW4odGV4dCwgbGVmdCwgdGFiU2l6ZSk7XG4gICAgICAgICAgaWYgKGxlZnQgPT0gcmlnaHQpXG4gICAgICAgICAgICByYW5nZXMucHVzaChuZXcgUmFuZ2UoUG9zKGxpbmUsIGxlZnRQb3MpLCBQb3MobGluZSwgbGVmdFBvcykpKTtcbiAgICAgICAgICBlbHNlIGlmICh0ZXh0Lmxlbmd0aCA+IGxlZnRQb3MpXG4gICAgICAgICAgICByYW5nZXMucHVzaChuZXcgUmFuZ2UoUG9zKGxpbmUsIGxlZnRQb3MpLCBQb3MobGluZSwgZmluZENvbHVtbih0ZXh0LCByaWdodCwgdGFiU2l6ZSkpKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFyYW5nZXMubGVuZ3RoKSByYW5nZXMucHVzaChuZXcgUmFuZ2Uoc3RhcnQsIHN0YXJ0KSk7XG4gICAgICAgIHNldFNlbGVjdGlvbihkb2MsIG5vcm1hbGl6ZVNlbGVjdGlvbihzdGFydFNlbC5yYW5nZXMuc2xpY2UoMCwgb3VySW5kZXgpLmNvbmNhdChyYW5nZXMpLCBvdXJJbmRleCksXG4gICAgICAgICAgICAgICAgICAgICB7b3JpZ2luOiBcIiptb3VzZVwiLCBzY3JvbGw6IGZhbHNlfSk7XG4gICAgICAgIGNtLnNjcm9sbEludG9WaWV3KHBvcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2Y
23459XIgb2xkUmFuZ2UgPSBvdXJSYW5nZTtcbiAgICAgICAgdmFyIGFuY2hvciA9IG9sZFJhbmdlLmFuY2hvciwgaGVhZCA9IHBvcztcbiAgICAgICAgaWYgKHR5cGUgIT0gXCJzaW5nbGVcIikge1xuICAgICAgICAgIGlmICh0eXBlID09IFwiZG91YmxlXCIpXG4gICAgICAgICAgICB2YXIgcmFuZ2UgPSBjbS5maW5kV29yZEF0KHBvcyk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgdmFyIHJhbmdlID0gbmV3IFJhbmdlKFBvcyhwb3MubGluZSwgMCksIGNsaXBQb3MoZG9jLCBQb3MocG9zLmxpbmUgKyAxLCAwKSkpO1xuICAgICAgICAgIGlmIChjbXAocmFuZ2UuYW5jaG9yLCBhbmNob3IpID4gMCkge1xuICAgICAgICAgICAgaGVhZCA9IHJhbmdlLmhlYWQ7XG4gICAgICAgICAgICBhbmNob3IgPSBtaW5Qb3Mob2xkUmFuZ2UuZnJvbSgpLCByYW5nZS5hbmNob3IpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBoZWFkID0gcmFuZ2UuYW5jaG9yO1xuICAgICAgICAgICAgYW5jaG9yID0gbWF4UG9zKG9sZFJhbmdlLnRvKCksIHJhbmdlLmhlYWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgcmFuZ2VzID0gc3RhcnRTZWwucmFuZ2VzLnNsaWNlKDApO1xuICAgICAgICByYW5nZXNbb3VySW5kZXhdID0gbmV3IFJhbmdlKGNsaXBQb3MoZG9jLCBhbmNob3IpLCBoZWFkKTtcbiAgICAgICAgc2V0U2VsZWN0aW9uKGRvYywgbm9ybWFsaXplU2VsZWN0aW9uKHJhbmdlcywgb3VySW5kZXgpLCBzZWxfbW91c2UpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBlZGl0b3JTaXplID0gZGlzcGxheS53cmFwcGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIC8vIFVzZWQgdG8gZW5zdXJlIHRpbWVvdXQgcmUtdHJpZXMgZG9uJ3QgZmlyZSB3aGVuIGFub3RoZXIgZXh0ZW5kXG4gICAgLy8gaGFwcGVuZWQgaW4gdGhlIG1lYW50aW1lIChjbGVhclRpbWVvdXQgaXNuJ3QgcmVsaWFibGUgLS0gYXRcbiAgICAvLyBsZWFzdCBvbiBDaHJvbWUsIHRoZSB0aW1lb3V0cyBzdGlsbCBoYXBwZW4gZXZlbiB3aGVuIGNsZWFyZWQsXG4gICAgLy8gaWYgdGhlIGNsZWFyIGhhcHBlbnMgYWZ0ZXIgdGhlaXIgc2NoZWR1bGVkIGZpcmluZyB0aW1lKS5cbiAgICB2YXIgY291bnRlciA9IDA7XG5cbiAgICBmdW5jdGlvbiBleHRlbmQoZSkge1xuICAgICAgdmFyIGN1ckNvdW50ID0gKytjb3VudGVyO1xuICAgICAgdmFyIGN1ciA9IHBvc0Zyb21Nb3VzZShjbSwgZSwgdHJ1ZSwgdHlwZSA9PSBcInJlY3RcIik7XG4gICAgICBpZiAoIWN1cikgcmV0dXJuO1xuICAgICAgaWYgKGNtcChjdXIsIGxhc3RQb3MpICE9IDApIHtcbiAgICAgICAgY20uY3VyT3AuZm9jdXMgPSBhY3RpdmVFbHQoKTtcbiAgICAgICAgZXh0ZW5kVG8oY3VyKTtcbiAgICAgICAgdmFyIHZpc2libGUgPSB2aXNpYmxlTGluZXMoZGlzcGxheSwgZG9jKTtcbiAgICAgICAgaWYgKGN1ci5saW5lID49IHZpc2libGUudG8gfHwgY3VyLmxpbmUgPCB2aXNpYmxlLmZyb20pXG4gICAgICAgICAgc2V0VGltZW91dChvcGVyYXRpb24oY20sIGZ1bmN0aW9uKCl7aWYgKGNvdW50ZXIgPT0gY3VyQ291bnQpIGV4dGVuZChlKTt9KSwgMTUwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBvdXRzaWRlID0gZS5jbGllbnRZIDwgZWRpdG9yU2l6ZS50b3AgPyAtMjAgOiBlLmNsaWVudFkgPiBlZGl0b3JTaXplLmJvdHRvbSA/IDIwIDogMDtcbiAgICAgICAgaWYgKG91dHNpZGUpIHNldFRpbWVvdXQob3BlcmF0aW9uKGNtLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAoY291bnRlciAhPSBjdXJDb3VudCkgcmV0dXJuO1xuICAgICAgICAgIGRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsVG9wICs9IG91dHNpZGU7XG4gICAgICAgICAgZXh0ZW5kKGUpO1xuICAgICAgICB9KSwgNTApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRvbmUoZSkge1xuICAgICAgY20uc3RhdGUuc2VsZWN0aW5nVGV4dCA9IGZhbHNlO1xuICAgICAgY291bnRlciA9IEluZmluaXR5O1xuICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgIGRpc3BsYXkuaW5wdXQuZm9jdXMoKTtcbiAgICAgIG9mZihkb2N1bWVudCwgXCJtb3VzZW1vdmVcIiwgbW92ZSk7XG4gICAgICBvZmYoZG9jdW1lbnQsIFwibW91c2V1cFwiLCB1cCk7XG4gICAgICBkb2MuaGlzdG9yeS5sYXN0U2VsT3JpZ2luID0gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgbW92ZSA9IG9wZXJhdGlvbihjbSwgZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKCFlX2J1dHRvbihlKSkgZG9uZShlKTtcbiAgICAgIGVsc2UgZXh0ZW5kKGUpO1xuICAgIH0pO1xuICAgIHZhciB1cCA9IG9wZXJhdGlvbihjbSwgZG9uZSk7XG4gICAgY20uc3RhdGUuc2VsZWN0aW5nVGV4dCA9IHVwO1xuICAgIG9uKGRvY3VtZW50LCBcIm1vdXNlbW92ZVwiLCBtb3ZlKTtcbiAgICBvbihkb2N1bWVudCwgXCJtb3VzZXVwXCIsIHVwKTtcbiAgfVxuXG4gIC8vIERldGVybWluZXMgd2hldGhlciBhbiBldmVudCBoYXBwZW5lZCBpbiB0aGUgZ3V0dGVyLCBhbmQgZmlyZXMgdGhlXG4gIC8vIGhhbmRsZXJzIGZvciB0aGUgY29ycmVzcG9uZGluZyBldmVudC5cbiAgZnVuY3Rpb24gZ3V0dGVyRXZlbnQoY20sIGUsIHR5cGUsIHByZXZlbnQsIHNpZ25hbGZuKSB7XG4gICAgdHJ5IHsgdmFyIG1YID0gZS5jbGllbnRYLCBtWSA9IGUuY2xpZW50WTsgfVxuICAgIGNhdGNoKGUpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgaWYgKG1YID49IE1hdGguZmxvb3IoY20uZGlzcGxheS5ndXR0ZXJzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnJpZ2h0KSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChwcmV2ZW50KSBlX3ByZXZlbnREZWZhdWx0KGUpO1xuXG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5O1xuICAgIHZhciBsaW5lQm94ID0gZGlzcGxheS5saW5lRGl2LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgaWYgKG1ZID4gbGluZUJveC5ib3R0b20gfHwgIWhhc0hhbmRsZXIoY20sIHR5cGUpKSByZXR1cm4gZV9kZWZhdWx0UHJldmVudGVkKGUpO1xuICAgIG1ZIC09IGxpbmVCb3gudG9wIC0gZGlzcGxheS52aWV3T2Zmc2V0O1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjbS5vcHRpb25zLmd1dHRlcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBnID0gZGlzcGxheS5ndXR0ZXJzLmNoaWxkTm9kZXNbaV07XG4gICAgICBpZiAoZyAmJiBnLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnJpZ2h0ID49IG1YKSB7XG4gICAgICAgI
23459HZhciBsaW5lID0gbGluZUF0SGVpZ2h0KGNtLmRvYywgbVkpO1xuICAgICAgICB2YXIgZ3V0dGVyID0gY20ub3B0aW9ucy5ndXR0ZXJzW2ldO1xuICAgICAgICBzaWduYWxmbihjbSwgdHlwZSwgY20sIGxpbmUsIGd1dHRlciwgZSk7XG4gICAgICAgIHJldHVybiBlX2RlZmF1bHRQcmV2ZW50ZWQoZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY2xpY2tJbkd1dHRlcihjbSwgZSkge1xuICAgIHJldHVybiBndXR0ZXJFdmVudChjbSwgZSwgXCJndXR0ZXJDbGlja1wiLCB0cnVlLCBzaWduYWxMYXRlcik7XG4gIH1cblxuICAvLyBLbHVkZ2UgdG8gd29yayBhcm91bmQgc3RyYW5nZSBJRSBiZWhhdmlvciB3aGVyZSBpdCdsbCBzb21ldGltZXNcbiAgLy8gcmUtZmlyZSBhIHNlcmllcyBvZiBkcmFnLXJlbGF0ZWQgZXZlbnRzIHJpZ2h0IGFmdGVyIHRoZSBkcm9wICgjMTU1MSlcbiAgdmFyIGxhc3REcm9wID0gMDtcblxuICBmdW5jdGlvbiBvbkRyb3AoZSkge1xuICAgIHZhciBjbSA9IHRoaXM7XG4gICAgY2xlYXJEcmFnQ3Vyc29yKGNtKTtcbiAgICBpZiAoc2lnbmFsRE9NRXZlbnQoY20sIGUpIHx8IGV2ZW50SW5XaWRnZXQoY20uZGlzcGxheSwgZSkpXG4gICAgICByZXR1cm47XG4gICAgZV9wcmV2ZW50RGVmYXVsdChlKTtcbiAgICBpZiAoaWUpIGxhc3REcm9wID0gK25ldyBEYXRlO1xuICAgIHZhciBwb3MgPSBwb3NGcm9tTW91c2UoY20sIGUsIHRydWUpLCBmaWxlcyA9IGUuZGF0YVRyYW5zZmVyLmZpbGVzO1xuICAgIGlmICghcG9zIHx8IGlzUmVhZE9ubHkoY20pKSByZXR1cm47XG4gICAgLy8gTWlnaHQgYmUgYSBmaWxlIGRyb3AsIGluIHdoaWNoIGNhc2Ugd2Ugc2ltcGx5IGV4dHJhY3QgdGhlIHRleHRcbiAgICAvLyBhbmQgaW5zZXJ0IGl0LlxuICAgIGlmIChmaWxlcyAmJiBmaWxlcy5sZW5ndGggJiYgd2luZG93LkZpbGVSZWFkZXIgJiYgd2luZG93LkZpbGUpIHtcbiAgICAgIHZhciBuID0gZmlsZXMubGVuZ3RoLCB0ZXh0ID0gQXJyYXkobiksIHJlYWQgPSAwO1xuICAgICAgdmFyIGxvYWRGaWxlID0gZnVuY3Rpb24oZmlsZSwgaSkge1xuICAgICAgICBpZiAoY20ub3B0aW9ucy5hbGxvd0Ryb3BGaWxlVHlwZXMgJiZcbiAgICAgICAgICAgIGluZGV4T2YoY20ub3B0aW9ucy5hbGxvd0Ryb3BGaWxlVHlwZXMsIGZpbGUudHlwZSkgPT0gLTEpXG4gICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcjtcbiAgICAgICAgcmVhZGVyLm9ubG9hZCA9IG9wZXJhdGlvbihjbSwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdmFyIGNvbnRlbnQgPSByZWFkZXIucmVzdWx0O1xuICAgICAgICAgIGlmICgvW1xceDAwLVxceDA4XFx4MGUtXFx4MWZdezJ9Ly50ZXN0KGNvbnRlbnQpKSBjb250ZW50ID0gXCJcIjtcbiAgICAgICAgICB0ZXh0W2ldID0gY29udGVudDtcbiAgICAgICAgICBpZiAoKytyZWFkID09IG4pIHtcbiAgICAgICAgICAgIHBvcyA9IGNsaXBQb3MoY20uZG9jLCBwb3MpO1xuICAgICAgICAgICAgdmFyIGNoYW5nZSA9IHtmcm9tOiBwb3MsIHRvOiBwb3MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IGNtLmRvYy5zcGxpdExpbmVzKHRleHQuam9pbihjbS5kb2MubGluZVNlcGFyYXRvcigpKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbjogXCJwYXN0ZVwifTtcbiAgICAgICAgICAgIG1ha2VDaGFuZ2UoY20uZG9jLCBjaGFuZ2UpO1xuICAgICAgICAgICAgc2V0U2VsZWN0aW9uUmVwbGFjZUhpc3RvcnkoY20uZG9jLCBzaW1wbGVTZWxlY3Rpb24ocG9zLCBjaGFuZ2VFbmQoY2hhbmdlKSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRlci5yZWFkQXNUZXh0KGZpbGUpO1xuICAgICAgfTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKSBsb2FkRmlsZShmaWxlc1tpXSwgaSk7XG4gICAgfSBlbHNlIHsgLy8gTm9ybWFsIGRyb3BcbiAgICAgIC8vIERvbid0IGRvIGEgcmVwbGFjZSBpZiB0aGUgZHJvcCBoYXBwZW5lZCBpbnNpZGUgb2YgdGhlIHNlbGVjdGVkIHRleHQuXG4gICAgICBpZiAoY20uc3RhdGUuZHJhZ2dpbmdUZXh0ICYmIGNtLmRvYy5zZWwuY29udGFpbnMocG9zKSA+IC0xKSB7XG4gICAgICAgIGNtLnN0YXRlLmRyYWdnaW5nVGV4dChlKTtcbiAgICAgICAgLy8gRW5zdXJlIHRoZSBlZGl0b3IgaXMgcmUtZm9jdXNlZFxuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge2NtLmRpc3BsYXkuaW5wdXQuZm9jdXMoKTt9LCAyMCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciB0ZXh0ID0gZS5kYXRhVHJhbnNmZXIuZ2V0RGF0YShcIlRleHRcIik7XG4gICAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgICAgaWYgKGNtLnN0YXRlLmRyYWdnaW5nVGV4dCAmJiAhKG1hYyA/IGUuYWx0S2V5IDogZS5jdHJsS2V5KSlcbiAgICAgICAgICAgIHZhciBzZWxlY3RlZCA9IGNtLmxpc3RTZWxlY3Rpb25zKCk7XG4gICAgICAgICAgc2V0U2VsZWN0aW9uTm9VbmRvKGNtLmRvYywgc2ltcGxlU2VsZWN0aW9uKHBvcywgcG9zKSk7XG4gICAgICAgICAgaWYgKHNlbGVjdGVkKSBmb3IgKHZhciBpID0gMDsgaSA8IHNlbGVjdGVkLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgcmVwbGFjZVJhbmdlKGNtLmRvYywgXCJcIiwgc2VsZWN0ZWRbaV0uYW5jaG9yLCBzZWxlY3RlZFtpXS5oZWFkLCBcImRyYWdcIik7XG4gICAgICAgICAgY20ucmVwbGFjZVNlbGVjdGlvbih0ZXh0LCBcImFyb3VuZFwiLCBcInBhc3RlXCIpO1xuICAgICAgICAgIGNtLmRpc3BsYXkuaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2F0Y2goZSl7fVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG9uRHJhZ1N0YXJ0KGNtLCBlKSB7XG4gICAgaWYgKGllICYmICghY20uc3RhdGUuZHJhZ2dpbmdUZXh0IHx8ICtuZXcgRGF0ZSAtIGxhc3REcm9wIDwgMTAwKSkgeyBlX3N0b3AoZSk7IHJldHVybjsgfVxuICAgIGlmIChzaWduYWxET01FdmVudChjbSwgZSkgfHwgZXZlbnRJbldpZGdldChjbS5kaXNwbGF5LCBlKSkgcmV0dXJuO1xuXG4gICAgZS5kYXRhV
23459HJhbnNmZXIuc2V0RGF0YShcIlRleHRcIiwgY20uZ2V0U2VsZWN0aW9uKCkpO1
vendor: 10,548 bytes, line 23459
23459xuXG4gICAgLy8gVXNlIGR1bW15IGltYWdlIGluc3RlYWQgb2YgZGVmYXVsdCBicm93c2VycyBpbWFnZS5cbiAgICAvLyBSZWNlbnQgU2FmYXJpICh+Ni4wLjIpIGhhdmUgYSB0ZW5kZW5jeSB0byBzZWdmYXVsdCB3aGVuIHRoaXMgaGFwcGVucywgc28gd2UgZG9uJ3QgZG8gaXQgdGhlcmUuXG4gICAgaWYgKGUuZGF0YVRyYW5zZmVyLnNldERyYWdJbWFnZSAmJiAhc2FmYXJpKSB7XG4gICAgICB2YXIgaW1nID0gZWx0KFwiaW1nXCIsIG51bGwsIG51bGwsIFwicG9zaXRpb246IGZpeGVkOyBsZWZ0OiAwOyB0b3A6IDA7XCIpO1xuICAgICAgaW1nLnNyYyA9IFwiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoQVFBQkFBQUFBQ0g1QkFFS0FBRUFMQUFBQUFBQkFBRUFBQUlDVEFFQU93PT1cIjtcbiAgICAgIGlmIChwcmVzdG8pIHtcbiAgICAgICAgaW1nLndpZHRoID0gaW1nLmhlaWdodCA9IDE7XG4gICAgICAgIGNtLmRpc3BsYXkud3JhcHBlci5hcHBlbmRDaGlsZChpbWcpO1xuICAgICAgICAvLyBGb3JjZSBhIHJlbGF5b3V0LCBvciBPcGVyYSB3b24ndCB1c2Ugb3VyIGltYWdlIGZvciBzb21lIG9ic2N1cmUgcmVhc29uXG4gICAgICAgIGltZy5fdG9wID0gaW1nLm9mZnNldFRvcDtcbiAgICAgIH1cbiAgICAgIGUuZGF0YVRyYW5zZmVyLnNldERyYWdJbWFnZShpbWcsIDAsIDApO1xuICAgICAgaWYgKHByZXN0bykgaW1nLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoaW1nKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbkRyYWdPdmVyKGNtLCBlKSB7XG4gICAgdmFyIHBvcyA9IHBvc0Zyb21Nb3VzZShjbSwgZSk7XG4gICAgaWYgKCFwb3MpIHJldHVybjtcbiAgICB2YXIgZnJhZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICBkcmF3U2VsZWN0aW9uQ3Vyc29yKGNtLCBwb3MsIGZyYWcpO1xuICAgIGlmICghY20uZGlzcGxheS5kcmFnQ3Vyc29yKSB7XG4gICAgICBjbS5kaXNwbGF5LmRyYWdDdXJzb3IgPSBlbHQoXCJkaXZcIiwgbnVsbCwgXCJDb2RlTWlycm9yLWN1cnNvcnMgQ29kZU1pcnJvci1kcmFnY3Vyc29yc1wiKTtcbiAgICAgIGNtLmRpc3BsYXkubGluZVNwYWNlLmluc2VydEJlZm9yZShjbS5kaXNwbGF5LmRyYWdDdXJzb3IsIGNtLmRpc3BsYXkuY3Vyc29yRGl2KTtcbiAgICB9XG4gICAgcmVtb3ZlQ2hpbGRyZW5BbmRBZGQoY20uZGlzcGxheS5kcmFnQ3Vyc29yLCBmcmFnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsZWFyRHJhZ0N1cnNvcihjbSkge1xuICAgIGlmIChjbS5kaXNwbGF5LmRyYWdDdXJzb3IpIHtcbiAgICAgIGNtLmRpc3BsYXkubGluZVNwYWNlLnJlbW92ZUNoaWxkKGNtLmRpc3BsYXkuZHJhZ0N1cnNvcik7XG4gICAgICBjbS5kaXNwbGF5LmRyYWdDdXJzb3IgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8vIFNDUk9MTCBFVkVOVFNcblxuICAvLyBTeW5jIHRoZSBzY3JvbGxhYmxlIGFyZWEgYW5kIHNjcm9sbGJhcnMsIGVuc3VyZSB0aGUgdmlld3BvcnRcbiAgLy8gY292ZXJzIHRoZSB2aXNpYmxlIGFyZWEuXG4gIGZ1bmN0aW9uIHNldFNjcm9sbFRvcChjbSwgdmFsKSB7XG4gICAgaWYgKE1hdGguYWJzKGNtLmRvYy5zY3JvbGxUb3AgLSB2YWwpIDwgMikgcmV0dXJuO1xuICAgIGNtLmRvYy5zY3JvbGxUb3AgPSB2YWw7XG4gICAgaWYgKCFnZWNrbykgdXBkYXRlRGlzcGxheVNpbXBsZShjbSwge3RvcDogdmFsfSk7XG4gICAgaWYgKGNtLmRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsVG9wICE9IHZhbCkgY20uZGlzcGxheS5zY3JvbGxlci5zY3JvbGxUb3AgPSB2YWw7XG4gICAgY20uZGlzcGxheS5zY3JvbGxiYXJzLnNldFNjcm9sbFRvcCh2YWwpO1xuICAgIGlmIChnZWNrbykgdXBkYXRlRGlzcGxheVNpbXBsZShjbSk7XG4gICAgc3RhcnRXb3JrZXIoY20sIDEwMCk7XG4gIH1cbiAgLy8gU3luYyBzY3JvbGxlciBhbmQgc2Nyb2xsYmFyLCBlbnN1cmUgdGhlIGd1dHRlciBlbGVtZW50cyBhcmVcbiAgLy8gYWxpZ25lZC5cbiAgZnVuY3Rpb24gc2V0U2Nyb2xsTGVmdChjbSwgdmFsLCBpc1Njcm9sbGVyKSB7XG4gICAgaWYgKGlzU2Nyb2xsZXIgPyB2YWwgPT0gY20uZG9jLnNjcm9sbExlZnQgOiBNYXRoLmFicyhjbS5kb2Muc2Nyb2xsTGVmdCAtIHZhbCkgPCAyKSByZXR1cm47XG4gICAgdmFsID0gTWF0aC5taW4odmFsLCBjbS5kaXNwbGF5LnNjcm9sbGVyLnNjcm9sbFdpZHRoIC0gY20uZGlzcGxheS5zY3JvbGxlci5jbGllbnRXaWR0aCk7XG4gICAgY20uZG9jLnNjcm9sbExlZnQgPSB2YWw7XG4gICAgYWxpZ25Ib3Jpem9udGFsbHkoY20pO1xuICAgIGlmIChjbS5kaXNwbGF5LnNjcm9sbGVyLnNjcm9sbExlZnQgIT0gdmFsKSBjbS5kaXNwbGF5LnNjcm9sbGVyLnNjcm9sbExlZnQgPSB2YWw7XG4gICAgY20uZGlzcGxheS5zY3JvbGxiYXJzLnNldFNjcm9sbExlZnQodmFsKTtcbiAgfVxuXG4gIC8vIFNpbmNlIHRoZSBkZWx0YSB2YWx1ZXMgcmVwb3J0ZWQgb24gbW91c2Ugd2hlZWwgZXZlbnRzIGFyZVxuICAvLyB1bnN0YW5kYXJkaXplZCBiZXR3ZWVuIGJyb3dzZXJzIGFuZCBldmVuIGJyb3dzZXIgdmVyc2lvbnMsIGFuZFxuICAvLyBnZW5lcmFsbHkgaG9ycmlibHkgdW5wcmVkaWN0YWJsZSwgdGhpcyBjb2RlIHN0YXJ0cyBieSBtZWFzdXJpbmdcbiAgLy8gdGhlIHNjcm9sbCBlZmZlY3QgdGhhdCB0aGUgZmlyc3QgZmV3IG1vdXNlIHdoZWVsIGV2ZW50cyBoYXZlLFxuICAvLyBhbmQsIGZyb20gdGhhdCwgZGV0ZWN0cyB0aGUgd2F5IGl0IGNhbiBjb252ZXJ0IGRlbHRhcyB0byBwaXhlbFxuICAvLyBvZmZzZXRzIGFmdGVyd2FyZHMuXG4gIC8vXG4gIC8vIFRoZSByZWFzb24gd2Ugd2FudCB0byBrbm93IHRoZSBhbW91bnQgYSB3aGVlbCBldmVudCB3aWxsIHNjcm9sbFxuICAvLyBpcyB0aGF0IGl0IGdpdmVzIHVzIGEgY2hhbmNlIHRvIHVwZGF0ZSB0aGUgZGlzcGxheSBiZWZvcmUgdGhlXG4gIC8vIGFjdHVhbCBzY3JvbGxpbmcgaGFwcGVucywgcmVkdWNpbmcgZmxpY2tlcmluZy5cblxuICB2YXIgd2hlZWxTYW1wbGVzID0gMCwgd2hlZWxQaXhlbHNQZXJVbml0ID0gbnVsbDtcbiAgLy8gRmlsbCBpbiBhIGJyb3dzZXItZGV0ZWN0ZWQgc3RhcnRpbmcgdmFsdWUgb24gYnJvd3NlcnMgd2hlcmUgd2VcbiAgLy8ga25vdyBvbmUuIFRoZXNlIGRvbid0IGhhdmUgdG8gYmUgYWNjdXJhdGUgLS0gdGhlIHJlc3VsdCBvZiB0aGVtXG4gIC8vIGJlaW5nIHdyb25nIHdvdWxkIGp1c3QgYmUgYSBzbGlnaHQgZmxpY2tlciBvbiB0aGUgZmlyc3Qgd2hlZWxcbiAgLy8gc2Nyb2xsIChpZiBpdCBpcyBsYXJnZSBlbm91Z2gpLlxuICBpZiAoaWUpIHdoZWVsUGl4ZWxzUGVyVW5pdCA9IC0uNTM7XG4gIGVsc2UgaWYgKGdlY2tvKSB3aGVlbFBpeGVsc1BlclVuaXQgPSAxNTtcbiAgZWxzZSBpZiAoY2hyb21lKSB3aGVlbFBpeGVsc1BlclVuaXQgPSAtLjc7XG4gIGVsc2UgaWYgKHNhZmFyaSkgd2hlZWxQaXhlbHNQZXJVbml0ID0gLTEvMztcblxuICB2YXIgd2hlZWxFdmVudERlbHRhID0gZnVuY3Rpb24oZSkge1xuICAgIHZhciBkeCA9IGUud2hlZWxEZWx0YVgsIGR5ID0gZS53aGVlbERlbHRhWTtcbiAgICBpZiAoZHggPT0gbnVsbCAmJiBlLmRldGFpbCAmJiBlLmF4aXMgPT0gZS5IT1JJWk9OVEFMX0FYSVMpIGR4ID0gZS5kZXRhaWw7XG4gICAgaWYgKGR5ID09IG51bGwgJiYgZS5kZXRhaWwgJiYgZS5heGlzID09IGUuVkVSVElDQUxfQVhJUykgZHkgPSBlLmRldGFpbDtcbiAgICBlbHNlIGlmIChkeSA9PSBudWxsKSBkeSA9IGUud2hlZWxEZWx0YTtcbiAgICByZXR1cm4ge3g6IGR4LCB5OiBkeX07XG4gIH07XG4gIENvZGVNaXJyb3Iud2hlZWxFdmVudFBpeGVscyA9IGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZGVsdGEgPSB3aGVlbEV2ZW50RGVsdGEoZSk7XG4gICAgZGVsdGEueCAqPSB3aGVlbFBpeGVsc1BlclVuaXQ7XG4gICAgZGVsdGEueSAqPSB3aGVlbFBpeGVsc1BlclVuaXQ7XG4gICAgcmV0dXJuIGRlbHRhO1xuICB9O1xuXG4gIGZ1bmN0aW9uIG9uU2Nyb2xsV2hlZWwoY20sIGUpIHtcbiAgICB2YXIgZGVsdGEgPSB3aGVlbEV2ZW50RGVsdGEoZSksIGR4ID0gZGVsdGEueCwgZHkgPSBkZWx0YS55O1xuXG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCBzY3JvbGwgPSBkaXNwbGF5LnNjcm9sbGVyO1xuICAgIC8vIFF1aXQgaWYgdGhlcmUncyBub3RoaW5nIHRvIHNjcm9sbCBoZXJlXG4gICAgdmFyIGNhblNjcm9sbFggPSBzY3JvbGwuc2Nyb2xsV2lkdGggPiBzY3JvbGwuY2xpZW50V2lkdGg7XG4gICAgdmFyIGNhblNjcm9sbFkgPSBzY3JvbGwuc2Nyb2xsSGVpZ2h0ID4gc2Nyb2xsLmNsaWVudEhlaWdodDtcbiAgICBpZiAoIShkeCAmJiBjYW5TY3JvbGxYIHx8IGR5ICYmIGNhblNjcm9sbFkpKSByZXR1cm47XG5cbiAgICAvLyBXZWJraXQgYnJvd3NlcnMgb24gT1MgWCBhYm9ydCBtb21lbnR1bSBzY3JvbGxzIHdoZW4gdGhlIHRhcmdldFxuICAgIC8vIG9mIHRoZSBzY3JvbGwgZXZlbnQgaXMgcmVtb3ZlZCBmcm9tIHRoZSBzY3JvbGxhYmxlIGVsZW1lbnQuXG4gICAgLy8gVGhpcyBoYWNrIChzZWUgcmVsYXRlZCBjb2RlIGluIHBhdGNoRGlzcGxheSkgbWFrZXMgc3VyZSB0aGVcbiAgICAvLyBlbGVtZW50IGlzIGtlcHQgYXJvdW5kLlxuICAgIGlmIChkeSAmJiBtYWMgJiYgd2Via2l0KSB7XG4gICAgICBvdXRlcjogZm9yICh2YXIgY3VyID0gZS50YXJnZXQsIHZpZXcgPSBkaXNwbGF5LnZpZXc7IGN1ciAhPSBzY3JvbGw7IGN1ciA9IGN1ci5wYXJlbnROb2RlKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmICh2aWV3W2ldLm5vZGUgPT0gY3VyKSB7XG4gICAgICAgICAgICBjbS5kaXNwbGF5LmN1cnJlbnRXaGVlbFRhcmdldCA9IGN1cjtcbiAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE9uIHNvbWUgYnJvd3NlcnMsIGhvcml6b250YWwgc2Nyb2xsaW5nIHdpbGwgY2F1c2UgcmVkcmF3cyB0b1xuICAgIC8vIGhhcHBlbiBiZWZvcmUgdGhlIGd1dHRlciBoYXMgYmVlbiByZWFsaWduZWQsIGNhdXNpbmcgaXQgdG9cbiAgICAvLyB3cmlnZ2xlIGFyb3VuZCBpbiBhIG1vc3QgdW5zZWVtbHkgd2F5LiBXaGVuIHdlIGhhdmUgYW5cbiAgICAvLyBlc3RpbWF0ZWQgcGl4ZWxzL2RlbHRhIHZhbHVlLCB3ZSBqdXN0IGhhbmRsZSBob3Jpem9udGFsXG4gICAgLy8gc2Nyb2xsaW5nIGVudGlyZWx5IGhlcmUuIEl0J2xsIGJlIHNsaWdodGx5IG9mZiBmcm9tIG5hdGl2ZSwgYnV0XG4gICAgLy8gYmV0dGVyIHRoYW4gZ2xpdGNoaW5nIG91dC5cbiAgICBpZiAoZHggJiYgIWdlY2tvICYmICFwcmVzdG8gJiYgd2hlZWxQaXhlbHNQZXJVbml0ICE9IG51bGwpIHtcbiAgICAgIGlmIChkeSAmJiBjYW5TY3JvbGxZKVxuICAgICAgICBzZXRTY3JvbGxUb3AoY20sIE1hdGgubWF4KDAsIE1hdGgubWluKHNjcm9sbC5zY3JvbGxUb3AgKyBkeSAqIHdoZWVsUGl4ZWxzUGVyVW5pdCwgc2Nyb2xsLnNjcm9sbEhlaWdodCAtIHNjcm9sbC5jbGllbnRIZWlnaHQpKSk7XG4gICAgICBzZXRTY3JvbGxMZWZ0KGNtLCBNYXRoLm1heCgwLCBNYXRoLm1pbihzY3JvbGwuc2Nyb2xsTGVmdCArIGR4ICogd2hlZWxQaXhlbHNQZXJVbml0LCBzY3JvbGwuc2Nyb2xsV2lkdGggLSBzY3JvbGwuY2xpZW50V2lkdGgpKSk7XG4gICAgICAvLyBPbmx5IHByZXZlbnQgZGVmYXVsdCBzY3JvbGxpbmcgaWYgdmVydGljYWwgc2Nyb2xsaW5nIGlzXG4gICAgICAvLyBhY3R1YWxseSBwb3NzaWJsZS4gT3RoZXJ3aXNlLCBpdCBjYXVzZXMgdmVydGljYWwgc2Nyb2xsXG4gICAgICAvLyBqaXR0ZXIgb24gT1NYIHRyYWNrcGFkcyB3aGVuIGRlbHRhWCBpcyBzbWFsbCBhbmQgZGVsdGFZXG4gICAgICAvLyBpcyBsYXJnZSAoaXNzdWUgIzM1NzkpXG4gICAgICBpZiAoIWR5IHx8IChkeSAmJiBjYW5TY3JvbGxZKSlcbiAgICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgIGRpc3BsYXkud2hlZWxTdGFydFggPSBudWxsOyAvLyBBYm9ydCBtZWFzdXJlbWVudCwgaWYgaW4gcHJvZ3Jlc3NcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyAnUHJvamVjdCcgdGhlIHZpc2libGUgdmlld3BvcnQgdG8gY292ZXIgdGhlIGFyZWEgdGhhdCBpcyBiZWluZ1xuICAgIC8vIHNjcm9sbGVkIGludG8gdmlldyAoaWYgd2Uga25vdyBlbm91Z2ggdG8gZXN0aW1hdGUgaXQpLlxuICAgIGlmIChkeSAmJiB3aGVlbFBpeGVsc1BlclVuaXQgIT0gbnVsbCkge1xuICAgICAgdmFyIHBpeGVscyA9IGR5ICogd2hlZWxQaXhlbHNQZXJVbml0O1xuICAgICAgdmFyIHRvcCA9IGNtLmRvYy5zY3JvbGxUb3AsIGJvdCA9IHRvcCArIGRpc3BsYXkud3JhcHBlci5jbGllbnRIZWlnaHQ7XG4gICAgICBpZiAocGl4ZWxzIDwgMCkgdG9wID0gTWF0aC5tYXgoMCwgdG9wICsgcGl4ZWxzIC0gNTApO1xuICAgICAgZWxzZSBib3QgPSBNYXRoLm1pbihjbS5kb2MuaGVpZ2h0LCBib3QgKyBwaXhlbHMgKyA1MCk7XG4gICAgICB1cGRhdGVEaXNwbGF5U2ltcGxlKGNtLCB7dG9wOiB0b3AsIGJvdHRvbTogYm90fSk7XG4gICAgfVxuXG4gICAgaWYgKHdoZWVsU2FtcGxlcyA8IDIwKSB7XG4gICAgICBpZiAoZGlzcGxheS53aGVlbFN0YXJ0WCA9PSBudWxsKSB7XG4gICAgICAgIGRpc3BsYXkud2hlZWxTdGFydFggPSBzY3JvbGwuc2Nyb2xsTGVmdDsgZGlzcGxheS53aGVlbFN0YXJ0WSA9IHNjcm9sbC5zY3JvbGxUb3A7XG4gICAgICAgIGRpc3BsYXkud2hlZWxEWCA9IGR4OyBkaXNwbGF5LndoZWVsRFkgPSBkeTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAoZGlzcGxheS53aGVlbFN0YXJ0WCA9PSBudWxsKSByZXR1cm47XG4gICAgICAgICAgdmFyIG1vdmVkWCA9IHNjcm9sbC5zY3JvbGxMZWZ0IC0gZGlzcGxheS53aGVlbFN0YXJ0WDtcbiAgICAgICAgICB2YXIgbW92ZWRZID0gc2Nyb2xsLnNjcm9sbFRvcCAtIGRpc3BsYXkud2hlZWxTdGFydFk7XG4gICAgICAgICAgdmFyIHNhbXBsZSA9IChtb3ZlZFkgJiYgZGlzcGxheS53aGVlbERZICYmIG1vdmVkWSAvIGRpc3BsYXkud2hlZWxEWSkgfHxcbiAgICAgICAgICAgIChtb3ZlZFggJiYgZGlzcGxheS53aGVlbERYICYmIG1vdmVkWCAvIGRpc3BsYXkud2hlZWxEWCk7XG4gICAgICAgICAgZGlzcGxheS53aGVlbFN0YXJ0WCA9IGRpc3BsYXkud2hlZWxTdGFydFkgPSBudWxsO1xuICAgICAgICAgIGlmICghc2FtcGxlKSByZXR1cm47XG4gICAgICAgICAgd2hlZWxQaXhlbHNQZXJVbml0ID0gKHdoZWVsUGl4ZWxzUGVyVW5pdCAqIHdoZWVsU2FtcGxlcyArIHNhbXBsZSkgLyAod2hlZWxTYW1wbGVzICsgMSk7XG4gICAgICAgICAgKyt3aGVlbFNhbXBsZXM7XG4gICAgICAgIH0sIDIwMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaXNwbGF5LndoZWVsRFggKz0gZHg7IGRpc3BsYXkud2hlZWxEWSArPSBkeTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBLRVkgRVZFTlRTXG5cbiAgLy8gUnVuIGEgaGFuZGxlciB0aGF0IHdhcyBib3VuZCB0byBhIGtleS5cbiAgZnVuY3Rpb24gZG9IYW5kbGVCaW5kaW5nKGNtLCBib3VuZCwgZHJvcFNoaWZ0KSB7XG4gICAgaWYgKHR5cGVvZiBib3VuZCA9PSBcInN0cmluZ1wiKSB7XG4gICAgICBib3VuZCA9IGNvbW1hbmRzW2JvdW5kXTtcbiAgICAgIGlmICghYm91bmQpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gRW5zdXJlIHByZXZpb3VzIGlucHV0IGhhcyBiZWVuIHJlYWQsIHNvIHRoYXQgdGhlIGhhbmRsZXIgc2VlcyBhXG4gICAgLy8gY29uc2lzdGVudCB2aWV3IG9mIHRoZSBkb2N1bWVudFxuICAgIGNtLmRpc3BsYXkuaW5wdXQuZW5zdXJlUG9sbGVkKCk7XG4gICAgdmFyIHByZXZTaGlmdCA9IGNtLmRpc3BsYXkuc2hpZnQsIGRvbmUgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgaWYgKG
23459lzUmVhZE9ubHkoY20pKSBjbS5zdGF0ZS5zdXBwcmVzc0VkaXRzID0gdHJ1ZTtcbiAgICAgIGlmIChkcm9wU2hpZnQpIGNtLmRpc3BsYXkuc2hpZnQgPSBmYWxzZTtcbiAgICAgIGRvbmUgPSBib3VuZChjbSkgIT0gUGFzcztcbiAgICB9IGZpbmFsbHkge1xuICAgICAgY20uZGlzcGxheS5zaGlmdCA9IHByZXZTaGlmdDtcbiAgICAgIGNtLnN0YXRlLnN1cHByZXNzRWRpdHMgPSBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGRvbmU7XG4gIH1cblxuICBmdW5jdGlvbiBsb29rdXBLZXlGb3JFZGl0b3IoY20sIG5hbWUsIGhhbmRsZSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY20uc3RhdGUua2V5TWFwcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHJlc3VsdCA9IGxvb2t1cEtleShuYW1lLCBjbS5zdGF0ZS5rZXlNYXBzW2ldLCBoYW5kbGUsIGNtKTtcbiAgICAgIGlmIChyZXN1bHQpIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIHJldHVybiAoY20ub3B0aW9ucy5leHRyYUtleXMgJiYgbG9va3VwS2V5KG5hbWUsIGNtLm9wdGlvbnMuZXh0cmFLZXlzLCBoYW5kbGUsIGNtKSlcbiAgICAgIHx8IGxvb2t1cEtleShuYW1lLCBjbS5vcHRpb25zLmtleU1hcCwgaGFuZGxlLCBjbSk7XG4gIH1cblxuICB2YXIgc3RvcFNlcSA9IG5ldyBEZWxheWVkO1xuICBmdW5jdGlvbiBkaXNwYXRjaEtleShjbSwgbmFtZSwgZSwgaGFuZGxlKSB7XG4gICAgdmFyIHNlcSA9IGNtLnN0YXRlLmtleVNlcTtcbiAgICBpZiAoc2VxKSB7XG4gICAgICBpZiAoaXNNb2RpZmllcktleShuYW1lKSkgcmV0dXJuIFwiaGFuZGxlZFwiO1xuICAgICAgc3RvcFNlcS5zZXQoNTAsIGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoY20uc3RhdGUua2V5U2VxID09IHNlcSkge1xuICAgICAgICAgIGNtLnN0YXRlLmtleVNlcSA9IG51bGw7XG4gICAgICAgICAgY20uZGlzcGxheS5pbnB1dC5yZXNldCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIG5hbWUgPSBzZXEgKyBcIiBcIiArIG5hbWU7XG4gICAgfVxuICAgIHZhciByZXN1bHQgPSBsb29rdXBLZXlGb3JFZGl0b3IoY20sIG5hbWUsIGhhbmRsZSk7XG5cbiAgICBpZiAocmVzdWx0ID09IFwibXVsdGlcIilcbiAgICAgIGNtLnN0YXRlLmtleVNlcSA9IG5hbWU7XG4gICAgaWYgKHJlc3VsdCA9PSBcImhhbmRsZWRcIilcbiAgICAgIHNpZ25hbExhdGVyKGNtLCBcImtleUhhbmRsZWRcIiwgY20sIG5hbW
23459UsIGUpO1xuXG4gICAgaWYgKHJlc3VsdCA9PSBcImhhbmRsZWRcIiB8fCByZXN1bHQgPT0gXCJtdWx0aVwiKSB7XG4gICAgICBlX3ByZXZlbnREZWZhdWx0KGUpO1xuICAgICAgcmVzdGFydEJsaW5rKGNtKTtcbiAgICB9XG5cbiAgICBpZiAoc2VxICYmICFyZXN1bHQgJiYgL1xcJyQvLnRlc3QobmFtZSkpIHtcbiAgICAgIGVfcHJldmVudERlZmF1bHQoZSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuICEhcmVzdWx0O1xuICB9XG5cbiAgLy8gSGFuZGxlIGEga2V5IGZyb20gdGhlIGtleWRvd24gZXZlbnQuXG4gIGZ1bmN0aW9uIGhhbmRsZUtleUJpbmRpbmcoY20sIGUpIHtcbiAgICB2YXIgbmFtZSA9IGtleU5hbWUoZSwgdHJ1ZSk7XG4gICAgaWYgKCFuYW1lKSByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAoZS5zaGlmdEtleSAmJiAhY20uc3RhdGUua2V5U2VxKSB7XG4gICAgICAvLyBGaXJzdCB0cnkgdG8gcmVzb2x2ZSBmdWxsIG5hbWUgKGluY2x1ZGluZyAnU2hpZnQtJykuIEZhaWxpbmdcbiAgICAgIC8vIHRoYXQsIHNlZSBpZiB0aGVyZSBpcyBhIGN1cnNvci1tb3Rpb24gY29tbWFuZCAoc3RhcnRpbmcgd2l0aFxuICAgICAgLy8gJ2dvJykgYm91bmQgdG8gdGhlIGtleW5hbWUgd2l0aG91dCAnU2hpZnQtJy5cbiAgICAgIHJldHVybiBkaXNwYXRjaEtleShjbSwgXCJTaGlmdC1cIiArIG5hbWUsIGUsIGZ1bmN0aW9uKGIpIHtyZXR1cm4gZG9IYW5kbGVCaW5kaW5nKGNtLCBiLCB0cnVlKTt9KVxuICAgICAgICAgIHx8IGRpc3BhdGNoS2V5KGNtLCBuYW1lLCBlLCBmdW5jdGlvbihiKSB7XG4gICAgICAgICAgICAgICBpZiAodHlwZW9mIGIgPT0gXCJzdHJpbmdcIiA/IC9eZ29bQS1aXS8udGVzdChiKSA6IGIubW90aW9uKVxuICAgICAgICAgICAgICAgICByZXR1cm4gZG9IYW5kbGVCaW5kaW5nKGNtLCBiKTtcbiAgICAgICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGRpc3BhdGNoS2V5KGNtLCBuYW1lLCBlLCBmdW5jdGlvbihiKSB7IHJldHVybiBkb0hhbmRsZUJpbmRpbmcoY20sIGIpOyB9KTtcbiAgICB9XG4gIH1cblxuICAvLyBIYW5kbGUgYSBrZXkgZnJvbSB0aGUga2V5cHJlc3MgZXZlbnRcbiAgZnVuY3Rpb24gaGFuZGxlQ2hhckJpbmRpbmcoY20sIGUsIGNoKSB7XG4gICAgcmV0dXJuIGRpc3BhdGNoS2V5KGNtLCBcIidcIiArIGNoICsgXCInXCIsIGUsXG4gICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKGIpIHsgcmV0dXJuIGRvSGFuZGxlQmluZGluZyhjbSwgYiwgdHJ1ZSk7IH0pO1xuICB9XG5cbiAgdmFyIGxhc3RTdG9wcGVkS2V5ID0gbnVsbDtcbiAgZnVuY3Rpb24gb25LZXlEb3duKGUpIHtcbiAgICB2YXIgY20gPSB0aGlzO1xuICAgIGNtLmN1ck9wLmZvY3VzID0gYWN0aXZlRWx0KCk7XG4gICAgaWYgKHNpZ25hbERPTUV2ZW50KGNtLCBlKSkgcmV0dXJuO1xuICAgIC8vIElFIGRvZXMgc3RyYW5nZSB0aGluZ3Mgd2l0aCBlc2NhcGUuXG4gICAgaWYgKGllICYmIGllX3ZlcnNpb24gPCAxMSAmJiBlLmtleUNvZGUgPT0gMjcpIGUucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICB2YXIgY29kZSA9IGUua2V5Q29kZTtcbiAgICBjbS5kaXNwbGF5LnNoaWZ0ID0gY29kZSA9PSAxNiB8fCBlLnNoaWZ0S2V5O1xuICAgIHZhciBoYW5kbGVkID0gaGFuZGxlS2V5QmluZGluZyhjbSwgZSk7XG4gICAgaWYgKHByZXN0bykge1xuICAgICAgbGFzdFN0b3BwZWRLZXkgPSBoYW5kbGVkID8gY29kZSA6IG51bGw7XG4gICAgICAvLyBPcGVyYSBoYXMgbm8gY3V0IGV2ZW50Li4uIHdlIHRyeSB0byBhdCBsZWFzdCBjYXRjaCB0aGUga2V5IGNvbWJvXG4gICAgICBpZiAoIWhhbmRsZWQgJiYgY29kZSA9PSA4OCAmJiAhaGFzQ29weUV2ZW50ICYmIChtYWMgPyBlLm1ldGFLZXkgOiBlLmN0cmxLZXkpKVxuICAgICAgICBjbS5yZXBsYWNlU2VsZWN0aW9uKFwiXCIsIG51bGwsIFwiY3V0XCIpO1xuICAgIH1cblxuICAgIC8vIFR1cm4gbW91c2UgaW50byBjcm9zc2hhaXIgd2hlbiBBbHQgaXMgaGVsZCBvbiBNYWMuXG4gICAgaWYgKGNvZGUgPT0gMTggJiYgIS9cXGJDb2RlTWlycm9yLWNyb3NzaGFpclxcYi8udGVzdChjbS5kaXNwbGF5LmxpbmVEaXYuY2xhc3NOYW1lKSlcbiAgICAgIHNob3dDcm9zc0hhaXIoY20pO1xuICB9XG5cbiAgZnVuY3Rpb24gc2hvd0Nyb3NzSGFpcihjbSkge1xuICAgIHZhciBsaW5lRGl2ID0gY20uZGlzcGxheS5saW5lRGl2O1xuICAgIGFkZENsYXNzKGxpbmVEaXYsIFwiQ29kZU1pcnJvci1jcm9zc2hhaXJcIik7XG5cbiAgICBmdW5jdGlvbiB1cChlKSB7XG4gICAgICBpZiAoZS5rZXlDb2RlID09IDE4IHx8ICFlLmFsdEtleSkge1xuICAgICAgICBybUNsYXNzKGxpbmVEaXYsIFwiQ29kZU1pcnJvci1jcm9zc2hhaXJcIik7XG4gICAgICAgIG9mZihkb2N1bWVudCwgXCJrZXl1cFwiLCB1cCk7XG4gICAgICAgIG9mZihkb2N1bWVudCwgXCJtb3VzZW92ZXJcIiwgdXApO1xuICAgICAgfVxuICAgIH1cbiAgICBvbihkb2N1bWVudCwgXCJrZXl1cFwiLCB1cCk7XG4gICAgb24oZG9jdW1lbnQsIFwibW91c2VvdmVyXCIsIHVwKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uS2V5VXAoZSkge1xuICAgIGlmIChlLmtleUNvZGUgPT0gMTYpIHRoaXMuZG9jLnNlbC5zaGlmdCA9IGZhbHNlO1xuICAgIHNpZ25hbERPTUV2ZW50KHRoaXMsIGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gb25LZXlQcmVzcyhlKSB7XG4gICAgdmFyIGNtID0gdGhpcztcbiAgICBpZiAoZXZlbnRJbldpZGdldChjbS5kaXNwbGF5LCBlKSB8fCBzaWduYWxET01FdmVudChjbSwgZSkgfHwgZS5jdHJsS2V5ICYmICFlLmFsdEtleSB8fCBtYWMgJiYgZS5tZXRhS2V5KSByZXR1cm47XG4gICAgdmFyIGtleUNvZGUgPSBlLmtleUNvZGUsIGNoYXJDb2RlID0gZS5jaGFyQ29kZTtcbiAgICBpZiAocHJlc3RvICYmIGtleUNvZGUgPT0gbGFzdFN0b3BwZWRLZXkpIHtsYXN0U3RvcHBlZEtleSA9IG51bGw7IGVfcHJldmVudERlZmF1bHQoZSk7IHJldHVybjt9XG4gICAgaWYgKChwcmVzdG8gJiYgKCFlLndoaWNoIHx8IGUud2hpY2ggPCAxMCkpICYmIGhhbmRsZUtleUJpbmRpbmcoY20sIGUpKSByZXR1cm47XG4gICAgdmFyIGNoID0gU3RyaW5nLmZyb21DaGFyQ29kZShjaGFyQ29kZSA9PSBudWxsID8ga2V5Q29kZSA6IGNoYXJDb2RlKTtcbiAgICBpZiAoaGFuZGxlQ2hhckJpbmRpbmcoY20sIGUsIGNoKSkgcmV0dXJuO1xuICAgIGNtLmRpc3BsYXkuaW5wdXQub25LZXlQcmVzcyhlKTtcbiAgfVxuXG4gIC8vIEZPQ1VTL0JMVVIgRVZFTlRTXG5cbiAgZnVuY3Rpb24gZGVsYXlCbHVyRXZlbnQoY20pIHtcbiAgICBjbS5zdGF0ZS5kZWxheWluZ0JsdXJFdmVudCA9IHRydWU7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIGlmIChjbS5zdGF0ZS5kZWxheWluZ0JsdXJFdmVudCkge1xuICAgICAgICBjbS5zdGF0ZS5kZWxheWluZ0JsdXJFdmVudCA9IGZhbHNlO1xuICAgICAgICBvbkJsdXIoY20pO1xuICAgICAgfVxuICAgIH0sIDEwMCk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkZvY3VzKGNtKSB7XG4gICAgaWYgKGNtLnN0YXRlLmRlbGF5aW5nQmx1ckV2ZW50KSBjbS5zdGF0ZS5kZWxheWluZ0JsdXJFdmVudCA9IGZhbHNlO1xuXG4gICAgaWYgKGNtLm9wdGlvbnMucmVhZE9ubHkgPT0gXCJub2N1cnNvclwiKSByZXR1cm47XG4gICAgaWYgKCFjbS5zdGF0ZS5mb2N1c2VkKSB7XG4gICAgICBzaWduYWwoY20sIFwiZm9jdXNcIiwgY20pO1xuICAgICAgY20uc3RhdGUuZm9jdXNlZCA9IHRydWU7XG4gICAgICBhZGRDbGFzcyhjbS5kaXNwbGF5LndyYXBwZXIsIFwiQ29kZU1pcnJvci1mb2N1c2VkXCIpO1xuICAgICAgLy8gVGhpcyB0ZXN0IH
23459ByZXZlbnRzIHRoaXMgZnJvbSBmaXJpbmcgd2hlbiBhIGNvbnRleHRcbiAgICAgIC8vIG1lbnUgaXMgY2xvc2VkIChzaW5jZSB0aGUgaW5wdXQgcmVzZXQgd291bGQga2lsbCB0aGVcbiAgICAgIC8vIHNlbGVjdC1hbGwgZGV0ZWN0aW9uIGhhY2spXG4gICAgICBpZiAoIWNtLmN1ck9wICYmIGNtLmRpc3BsYXkuc2VsRm9yQ29udGV4dE1lbnUgIT0gY20uZG9jLnNlbCkge1xuICAgICAgICBjbS5kaXNwbGF5LmlucHV0LnJlc2V0KCk7XG4gICAgICAgIGlmICh3ZWJraXQpIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNtLmRpc3BsYXkuaW5wdXQucmVzZXQodHJ1ZSk7IH0sIDIwKTsgLy8gSXNzdWUgIzE3MzBcbiAgICAgIH1cbiAgICAgIGNtLmRpc3BsYXkuaW5wdXQucmVjZWl2ZWRGb2N1cygpO1xuICAgIH1cbiAgICByZXN0YXJ0QmxpbmsoY20pO1xuICB9XG4gIGZ1bmN0aW9uIG9uQmx1cihjbSkge1xuICAgIGlmIChjbS5zdGF0ZS5kZWxheWluZ0JsdXJFdmVudCkgcmV0dXJuO1xuXG4gICAgaWYgKGNtLnN0YXRlLmZvY3VzZWQpIHtcbiAgICAgIHNpZ25hbChjbSwgXCJibHVyXCIsIGNtKTtcbiAgICAgIGNtLnN0YXRlLmZvY3VzZWQgPSBmYWxzZTtcbiAgICAgIHJtQ2xhc3MoY20uZGlzcGxheS53cmFwcGVyLCBcIkNvZGVNaXJyb3ItZm9jdXNlZFwiKTtcbiAgICB9XG4gICAgY2xlYXJJbnRlcnZhbChjbS5kaXNwbGF5LmJsaW5rZXIpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7aWYgKCFjbS5zdGF0ZS5mb2N1c2VkKSBjbS5kaXNwbGF5LnNoaWZ0ID0gZmFsc2U7fSwgMTUwKTtcbiAgfVxuXG4gIC8vIENPTlRFWFQgTUVOVSBIQU5ETElOR1xuXG4gIC8vIFRvIG1ha2UgdGhlIGNvbnRleHQgbWVudSB3b3JrLCB3ZSBuZWVkIHRvIGJyaWVmbHkgdW5oaWRlIHRoZVxuICAvLyB0ZXh0YXJlYSAobWFraW5nIGl0IGFzIHVub2J0cnVzaXZlIGFzIHBvc3NpYmxlKSB0byBsZXQgdGhlXG4gIC8vIHJpZ2h0LWNsaWNrIHRha2UgZWZmZWN0IG9uIGl0LlxuICBmdW5jdGlvbiBvbkNvbnRleHRNZW51KGNtLCBlKSB7XG4gICAgaWYgKGV2ZW50SW5XaWRnZXQoY20uZGlzcGxheSwgZSkgfHwgY29udGV4dE1lbnVJbkd1dHRlcihjbSwgZSkpIHJldHVybjtcbiAgICBpZiAoc2lnbmFsRE9NRXZlbnQoY20sIGUsIFwiY29udGV4dG1lbnVcIikpIHJldHVybjtcbiAgICBjbS5kaXNwbGF5LmlucHV0Lm9uQ29udGV4dE1lbnUoZSk7XG4gIH1cblxuICBmdW5jdGlvbiBjb250ZXh0TWVudUluR3V0dGVyKGNtLCBlKSB7XG4gICAgaWYgKCFoYXNIYW5kbGVyKGNtLCBcImd1dHRlckNvbnRleHRNZW51XCIpKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIGd1dHRlckV2ZW50KGNtLCBlLCBcImd1dHRlckNvbnRleHRNZW51XCIsIGZhbHNlLCBzaWduYWwpO1xuICB9XG5cbiAgLy8gVVBEQVRJTkdcblxuICAvLyBDb21wdXRlIHRoZSBwb3NpdGlvbiBvZiB0aGUgZW5kIG9mIGEgY2hhbmdlIChpdHMgJ3RvJyBwcm9wZXJ0eVxuICAvLyByZWZlcnMgdG8gdGhlIHByZS1jaGFuZ2UgZW5kKS5cbiAgdmFyIGNoYW5nZUVuZCA9IENvZGVNaXJyb3IuY2hhbmdlRW5kID0gZnVuY3Rpb24oY2hhbmdlKSB7XG4gICAgaWYgKCFjaGFuZ2UudGV4dCkgcmV0dXJuIGNoYW5nZS50bztcbiAgICByZXR1cm4gUG9zKGNoYW5nZS5mcm9tLmxpbmUgKyBjaGFuZ2UudGV4dC5sZW5ndGggLSAxLFxuICAgICAgICAgICAgICAgbHN0KGNoYW5nZS50ZXh0KS5sZW5ndGggKyAoY2hhbmdlLnRleHQubGVuZ3RoID09IDEgPyBjaGFuZ2UuZnJvbS5jaCA6IDApKTtcbiAgfTtcblxuICAvLyBBZGp1c3QgYSBwb3NpdGlvbiB0byByZWZlciB0byB0aGUgcG9zdC1jaGFuZ2UgcG9zaXRpb24gb2YgdGhlXG4gIC8vIHNhbWUgdGV4dCwgb3IgdGhlIGVuZCBvZiB0aGUgY2hhbmdlIGlmIHRoZSBjaGFuZ2UgY292ZXJzIGl0LlxuICBmdW5jdGlvbiBhZGp1c3RGb3JDaGFuZ2UocG9zLCBjaGFuZ2UpIHtcbiAgICBpZiAoY21wKHBvcywgY2hhbmdlLmZyb20pIDwgMCkgcmV0dXJuIHBvcztcbiAgICBpZiAoY21wKHBvcywgY2hhbmdlLnRvKSA8PSAwKSByZXR1cm4gY2hhbmdlRW5kKGNoYW5nZSk7XG5cbiAgICB2YXIgbGluZSA9IHBvcy5saW5lICsgY2hhbmdlLnRleHQubGVuZ3RoIC0gKGNoYW5nZS50by5saW5lIC0gY2hhbmdlLmZyb20ubGluZSkgLSAxLCBjaCA9IHBvcy5jaDtcbiAgICBpZiAocG9zLmxpbmUgPT0gY2hhbmdlLnRvLmxpbmUpIGNoICs9IGNoYW5nZUVuZChjaGFuZ2UpLmNoIC0gY2hhbmdlLnRvLmNoO1xuICAgIHJldHVybiBQb3MobGluZSwgY2gpO1xuICB9XG5cbiAgZnVuY3Rpb24gY29tcHV0ZVNlbEFmdGVyQ2hhbmdlKGRvYywgY2hhbmdlKSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZG9jLnNlbC5yYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciByYW5nZSA9IGRvYy5zZWwucmFuZ2VzW2ldO1xuICAgICAgb3V0LnB1c2gobmV3IFJhbmdlKGFkanVzdEZvckNoYW5nZShyYW5nZS5hbmNob3IsIGNoYW5nZSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgYWRqdXN0Rm9yQ2hhbmdlKHJhbmdlLmhlYWQsIGNoYW5nZSkpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5vcm1hbGl6ZVNlbGVjdGlvbihvdXQsIGRvYy5zZWwucHJpbUluZGV4KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9mZnNldFBvcyhwb3MsIG9sZCwgbncpIHtcbiAgICBpZiAocG9zLmxpbmUgPT0gb2xkLmxpbmUpXG4gICAgICByZXR1cm4gUG9zKG53LmxpbmUsIHBvcy5jaCAtIG9sZC5jaCArIG53LmNoKTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gUG9zKG53LmxpbmUgKyAocG9zLmxpbmUgLSBvbGQubGluZSksIHBvcy5jaCk7XG4gIH1cblxuICAvLyBVc2VkIGJ5IHJlcGxhY2VTZWxlY3Rpb25zIHRvIGFsbG93IG1vdmluZyB0aGUgc2VsZWN0aW9uIHRvIHRoZVxuICAvLyBzdGFydCBvciBhcm91bmQgdGhlIHJlcGxhY2VkIHRlc3QuIEhpbnQgbWF5IGJlIFwic3RhcnRcIiBvciBcImFyb3VuZFwiLlxuICBmdW5jdGlvbiBjb21wdXRlUmVwbGFjZWRTZWwoZG9jLCBjaGFuZ2VzLCBoaW50KSB7XG4gICAgdmFyIG91dCA9IFtdO1xuICAgIHZhciBvbGRQcmV2ID0gUG9zKGRvYy5maXJzdCwgMCksIG5ld1ByZXYgPSBvbGRQcmV2O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGNoYW5nZSA9IGNoYW5nZXNbaV07XG4gICAgICB2Y
23459XIgZnJvbSA9IG9mZnNldFBvcyhjaGFuZ2UuZnJvbSwgb2xkUHJldiwgbmV3UHJldik7XG4gICAgICB2YXIgdG8gPSBvZmZzZXRQb3MoY2hhbmdlRW5kKGNoYW5nZSksIG9sZFByZXYsIG5ld1ByZXYpO1xuICAgICAgb2xkUHJldiA9IGNoYW5nZS50bztcbiAgICAgIG5ld1ByZXYgPSB0bztcbiAgICAgIGlmIChoaW50ID09IFwiYXJvdW5kXCIpIHtcbiAgICAgICAgdmFyIHJhbmdlID0gZG9jLnNlbC5yYW5nZXNbaV0sIGludiA9IGNtcChyYW5nZS5oZWFkLCByYW5nZS5hbmNob3IpIDwgMDtcbiAgICAgICAgb3V0W2ldID0gbmV3IFJhbmdlKGludiA/IHRvIDogZnJvbSwgaW52ID8gZnJvbSA6IHRvKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG91dFtpXSA9IG5ldyBSYW5nZShmcm9tLCBmcm9tKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBTZWxlY3Rpb24ob3V0LCBkb2Muc2VsLnByaW1JbmRleCk7XG4gIH1cblxuICAvLyBBbGxvdyBcImJlZm9yZUNoYW5nZVwiIGV2ZW50IGhhbmRsZXJzIHRvIGluZmx1ZW5jZSBhIGNoYW5nZVxuICBmdW5jdGlvbiBmaWx0ZXJDaGFuZ2UoZG9jLCBjaGFuZ2UsIHVwZGF0ZSkge1xuICAgIHZhciBvYmogPSB7XG4gICAgICBjYW5jZWxlZDogZmFsc2UsXG4gICAgICBmcm9tOiBjaGFuZ2UuZnJvbSxcbiAgICAgIHRvOiBjaGFuZ2UudG8sXG4gICAgICB0ZXh0OiBjaGFuZ2UudGV4dCxcbiAgICAgIG9yaWdpbjogY2hhbmdlLm9yaWdpbixcbiAgICAgIGNhbmNlbDogZnVuY3Rpb24oKSB7IHRoaXMuY2FuY2VsZWQgPSB0cnVlOyB9XG4gICAgfTtcbiAgICBpZiAodXBkYXRlKSBvYmoudXBkYXRlID0gZnVuY3Rpb24oZnJvbSwgdG8sIHRleHQsIG9yaWdpbikge1xuICAgICAgaWYgKGZyb20pIHRoaXMuZnJvbSA9IGNsaXBQb3MoZG9jLCBmcm9tKTtcbiAgICAgIGlmICh0bykgdGhpcy50byA9IGNsaXBQb3MoZG9jLCB0byk7XG4gICAgICBpZiAodGV4dCkgdGhpcy50ZXh0ID0gdGV4dDtcbiAgICAgIGlmIChvcmlnaW4gIT09IHVuZGVmaW5lZCkgdGhpcy5vcmlnaW4gPSBvcmlnaW47XG4gICAgfTtcbiAgICBzaWduYWwoZG9jLCBcImJlZm9yZUNoYW5nZVwiLCBkb2MsIG9iaik7XG4gICAgaWYgKGRvYy5jbSkgc2lnbmFsKGRvYy5jbSwgXCJiZWZvcmVDaGFuZ2VcIiwgZG9jLmNtLCBvYmopO1xuXG4gICAgaWYgKG9iai5jYW5jZWxlZCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHtmcm9tOiBvYmouZnJvbSwgdG86IG9iai50bywgdGV4dDogb2JqLnRleHQsIG9yaWdpbjogb2JqLm9yaWdpbn07XG4gIH1cblxuICAvLyBBcHBseSBhIGNoYW5nZSB0byBhIGRvY3VtZW50LCBhbmQgYWRkIGl0IHRvIHRoZSBkb2N1bWVudCdzXG4gIC8vIGhpc3RvcnksIGFuZCBwcm9wYWdhdGluZyBpdCB0byBhbGwgbGlua2VkIGRvY3VtZW50cy5cbiAgZnVuY3Rpb24gbWFrZUNoYW5nZShkb2MsIGNoYW5nZSwgaWdub3JlUmVhZE9ubHkpIHtcbiAgICBpZiAoZG9jLmNtKSB7XG4gICAgICBpZiAoIWRvYy5jbS5jdXJPcCkgcmV0dXJuIG9wZXJhdGlvbihkb2MuY20sIG1ha2VDaGFuZ2UpKGRvYywgY2hhbmdlLCBpZ25vcmVSZWFkT25seSk7XG4gICAgICBpZiAoZG9jLmNtLnN0YXRlLnN1cHByZXNzRWRpdHMpIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoaGFzSGFuZGxlcihkb2MsIFwiYmVmb3JlQ2hhbmdlXCIpIHx8IGRvYy5jbSAmJiBoYXNIYW5kbGVyKGRvYy5jbSwgXCJiZWZvcmVDaGFuZ2VcIikpIHtcbiAgICAgIGNoYW5nZSA9IGZpbHRlckNoYW5nZShkb2MsIGNoYW5nZSwgdHJ1ZSk7XG4gICAgICBpZiAoIWNoYW5nZSkgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFBvc3NpYmx5IHNwbGl0IG9yIHN1cHByZXNzIHRoZSB1cGRhdGUgYmFzZWQgb24gdGhlIHByZXNlbmNlXG4gICAgLy8gb2YgcmVhZC1vbmx5IHNwYW5zIGluIGl0cyByYW5nZS5cbiAgICB2YXIgc3BsaXQgPSBzYXdSZWFkT25seVNwYW5zICYmICFpZ25vcmVSZWFkT25seSAmJiByZW1vdmVSZWFkT25seVJhbmdlcyhkb2MsIGNoYW5nZS5mcm9tLCBjaGFuZ2UudG8pO1xuICAgIGlmIChzcGxpdCkge1xuICAgICAgZm9yICh2YXIgaSA9IHNwbGl0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKVxuICAgICAgICBtYWtlQ2hhbmdlSW5uZXIoZG9jLCB7ZnJvbTogc3BsaXRbaV0uZnJvbSwgdG86IHNwbGl0W2ldLnRvLCB0ZXh0OiBpID8gW1wiXCJdIDogY2hhbmdlLnRleHR9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWFrZUNoYW5nZUlubmVyKGRvYywgY2hhbmdlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBtYWtlQ2hhbmdlSW5uZXIoZG9jLCBjaGFuZ2UpIHtcbiAgICBpZiAoY2hhbmdlLnRleHQubGVuZ3RoID09IDEgJiYgY2hhbmdlLnRleHRbMF0gPT0gXCJcIiAmJiBjbXAoY2hhbmdlLmZyb20sIGNoYW5nZS50bykgPT0gMCkgcmV0dXJuO1xuICAgIHZhciBzZWxBZnRlciA9IGNvbXB1dGVTZWxBZnRlckNoYW5nZShkb2MsIGNoYW5nZSk7XG4gICAgYWRkQ2hhbmdlVG9IaXN0b3J5KGRvYywgY2hhbmdlLCBzZWxBZnRlciwgZG9jLmNtID8gZG9jLmNtLmN1ck9wLmlkIDogTmFOKTtcblxuICAgIG1ha2VDaGFuZ2VTaW5nbGVEb2MoZG9jLCBjaGFuZ2UsIHNlbEFmdGVyLCBzdHJldGNoU3BhbnNPdmVyQ2hhbmdlKGRvYywgY2hhbmdlKSk7XG4gICAgdmFyIHJlYmFzZWQgPSBbXTtcblxuICAgIGxpbmtlZERvY3MoZG9jLCBmdW5jdGlvbihkb2MsIHNoYXJlZEhpc3QpIHtcbiAgICAgIGlmICghc2hhcmVkSGlzdCAmJiBpbmRleE9mKHJlYmFzZWQsIGRvYy5oaXN0b3J5KSA9PSAtMSkge1xuICAgICAgICByZWJhc2VIaXN0KGRvYy5oaXN0b3J5LCBjaGFuZ2UpO1xuICAgICAgICByZWJhc2VkLnB1c2goZG9jLmhpc3RvcnkpO1xuICAgICAgfVxuICAgICAgbWFrZUNoYW5nZVNpbmdsZURvYyhkb2MsIGNoYW5nZSwgbnVsbCwgc3RyZXRjaFNwYW5zT3ZlckNoYW5nZShkb2MsIGNoYW5nZSkpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gUmV2ZXJ0IGEgY2hhbmdlIHN0b3JlZCBpbiBhIGRvY3VtZW50J3MgaGlzdG9yeS5cbiAgZnVuY3Rpb24gbWFrZUNoYW5nZUZyb21IaXN0b3J5KGRvYywgdHlwZSwgYWxsb3dTZWxlY3Rpb25Pbmx5KSB7XG4gICAgaWYgKGRvYy5jbSAmJiBkb2MuY20uc3RhdGUuc3VwcHJlc3NFZGl0cykgcmV0dXJuO1xuXG4gICAgdmFyIGhpc3QgPSBkb2MuaGlzdG9yeSwgZXZlbnQsIHNlbEFmdGVyID0gZG9jLnNlbDtcbiAgICB2YXIgc291cmNlID0gdHlwZSA9PSBcInVuZG9cIiA/IGhpc3QuZG9uZSA6IGhpc3QudW5kb25lLCBkZXN0ID0gdHlwZSA9PSBcInVuZG9cIiA/IGhpc3QudW5kb25lIDogaGlzdC5kb25lO1xuXG4gICAgLy8gVmVyaWZ5IHRoYXQgdGhlcmUgaXMgYSB1c2VhYmxlIGV2ZW50IChzbyB0aGF0IGN0cmwteiB3b24ndFxuICAgIC8vIG5lZWRsZXNzbHkgY2xlYXIgc2VsZWN0aW9uIGV2ZW50cylcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNvdXJjZS5sZW5ndGg7IGkrKykge1xuICAgICAgZXZlbnQgPSBzb3VyY2VbaV07XG4gICAgICBpZiAoYWxsb3dTZWxlY3Rpb25Pbmx5ID8gZXZlbnQucmFuZ2VzICYmICFldmVudC5lcXVhbHMoZG9jLnNlbCkgOiAhZXZlbnQucmFuZ2VzKVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgaWYgKGkgPT0gc291cmNlLmxlbmd0aCkgcmV0dXJuO1xuICAgIGhpc3QubGFzdE9yaWdpbiA9IGhpc3QubGFzdFNlbE9yaWdpbiA9IG51bGw7XG5cbiAgICBmb3IgKDs7KSB7XG4gICAgICBldmVudCA9IHNvdXJjZS5wb3AoKTtcbiAgICAgIGlmIChldmVudC5yYW5nZXMpIHtcbiAgICAgICAgcHVzaFNlbGVjdGlvblRvSGlzdG9yeShldmVudCwgZGVzdCk7XG4gICAgICAgIGlmIChhbGxvd1NlbGVjdGlvbk9ubHkgJiYgIWV2ZW50LmVxdWFscyhkb2Muc2VsKSkge1xuICAgICAgICAgI
23459HNldFNlbGVjdGlvbihkb2MsIGV2ZW50LCB7Y2xlYXJSZWRvOiBmYWxzZX0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzZWxBZnRlciA9IGV2ZW50O1xuICAgICAgfVxuICAgICAgZWxzZSBicmVhaztcbiAgICB9XG5cbiAgICAvLyBCdWlsZCB1cCBhIHJldmVyc2UgY2hhbmdlIG9iamVjdCB0byBhZGQgdG8gdGhlIG9wcG9zaXRlIGhpc3RvcnlcbiAgICAvLyBzdGFjayAocmVkbyB3aGVuIHVuZG9pbmcsIGFuZCB2aWNlIHZlcnNhKS5cbiAgICB2YXIgYW50aUNoYW5nZXMgPSBbXTtcbiAgICBwdXNoU2VsZWN0aW9uVG9IaXN0b3J5KHNlbEFmdGVyLCBkZXN0KTtcbiAgICBkZXN0LnB1c2goe2NoYW5nZXM6IGFudGlDaGFuZ2VzLCBnZW5lcmF0aW9uOiBoaXN0LmdlbmVyYXRpb259KTtcbiAgICBoaXN0LmdlbmVyYXRpb24gPSBldmVudC5nZW5lcmF0aW9uIHx8ICsraGlzdC5tYXhHZW5lcmF0aW9uO1xuXG4gICAgdmFyIGZpbHRlciA9IGhhc0hhbmRsZXIoZG9jLCBcImJlZm9yZUNoYW5nZVwiKSB8fCBkb2MuY20gJiYgaGFzSGFuZGxlcihkb2MuY20sIFwiYmVmb3JlQ2hhbmdlXCIpO1xuXG4gICAgZm9yICh2YXIgaSA9IGV2ZW50LmNoYW5nZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHZhciBjaGFuZ2UgPSBldmVudC5jaGFuZ2VzW2ldO1xuICAgICAgY2hhbmdlLm9yaWdpbiA9IHR5cGU7XG4gICAgICBpZiAoZmlsdGVyICYmICFmaWx0ZXJDaGFuZ2UoZG9jLCBjaGFuZ2UsIGZhbHNlKSkge1xuICAgICAgICBzb3VyY2UubGVuZ3RoID0gMDtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBhbnRpQ2hhbmdlcy5wdXNoKGhpc3RvcnlDaGFuZ2VGcm9tQ2hhbmdlKGRvYywgY2hhbmdlKSk7XG5cbiAgICAgIHZhciBhZnRlciA9IGkgPyBjb21wdXRlU2VsQWZ0ZXJDaGFuZ2UoZG9jLCBjaGFuZ2UpIDogbHN0KHNvdXJjZSk7XG4gICAgICBtYWtlQ2hhbmdlU2luZ2xlRG9jKGRvYywgY2hhbmdlLCBhZnRlciwgbWVyZ2VPbGRTcGFucyhkb2MsIGNoYW5nZSkpO1xuICAgICAgaWYgKCFpICYmIGRvYy5jbSkgZG9jLmNtLnNjcm9sbEludG9WaWV3KHtmcm9tOiBjaGFuZ2UuZnJvbSwgdG86IGNoYW5nZUVuZChjaGFuZ2UpfSk7XG4gICAgICB2Y
23459XIgcmViYXNlZCA9IFtdO1xuXG4gICAgICAvLyBQcm9wYWdhdGUgdG8gdGhlIGxpbmtlZCBkb2N1bWVudHNcbiAgICAgIGxpbmtlZERvY3MoZG9jLCBmdW5jdGlvbihkb2MsIHNoYXJlZEhpc3QpIHtcbiAgICAgICAgaWYgKCFzaGFyZWRIaXN0ICYmIGluZGV4T2YocmViYXNlZCwgZG9jLmhpc3RvcnkpID09IC0xKSB7XG4gICAgICAgICAgcmViYXNlSGlzdChkb2MuaGlzdG9yeSwgY2hhbmdlKTtcbiAgICAgICAgICByZWJhc2VkLnB1c2goZG9jLmhpc3RvcnkpO1xuICAgICAgICB9XG4gICAgICAgIG1ha2VDaGFuZ2VTaW5nbGVEb2MoZG9jLCBjaGFuZ2UsIG51bGwsIG1lcmdlT2xkU3BhbnMoZG9jLCBjaGFuZ2UpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN1Yi12aWV3cyBuZWVkIHRoZWlyIGxpbmUgbnVtYmVycyBzaGlmdGVkIHdoZW4gdGV4dCBpcyBhZGRlZFxuICAvLyBhYm92ZSBvciBiZWxvdyB0aGVtIGluIHRoZSBwYXJlbnQgZG9jdW1lbnQuXG4gIGZ1bmN0aW9uIHNoaWZ0RG9jKGRvYywgZGlzdGFuY2UpIHtcbiAgICBpZiAoZGlzdGFuY2UgPT0gMCkgcmV0dXJuO1xuICAgIGRvYy5maXJzdCArPSBkaXN0YW5jZTtcbiAgICBkb2Muc2VsID0gbmV3IFNlbGVjdGlvbihtYXAoZG9jLnNlbC5yYW5nZXMsIGZ1bmN0aW9uKHJhbmdlKSB7XG4gICAgICByZXR1cm4gbmV3IFJhbmdlKFBvcyhyYW5nZS5hbmNob3IubGluZSArIGRpc3RhbmNlLCByYW5nZS5hbmNob3IuY2gpLFxuICAgICAgICAgICAgICAgICAgICAgICBQb3MocmFuZ2UuaGVhZC5saW5lICsgZGlzdGFuY2UsIHJhbmdlLmhlYWQuY2gpKTtcbiAgICB9KSwgZG9jLnNlbC5wcmltSW5kZXgpO1xuICAgIGlmIChkb2MuY20pIHtcbiAgICAgIHJlZ0NoYW5nZShkb2MuY20sIGRvYy5maXJzdCwgZG9jLmZpcnN0IC0gZGlzdGFuY2UsIGRpc3RhbmNlKTtcbiAgICAgIGZvciAodmFyIGQgPSBkb2MuY20uZGlzcGxheSwgbCA9IGQudmlld0Zyb207IGwgPCBkLnZpZXdUbzsgbCsrKVxuICAgICAgICByZWdMaW5lQ2hhbmdlKGRvYy5jbSwgbCwgXCJndXR0ZXJcIik7XG4gICAgfVxuICB9XG5cbiAgLy8gTW9yZSBsb3dlci1sZXZlbCBjaGFuZ2UgZnVuY3Rpb24sIGhhbmRsaW5nIG9ubHkgYSBzaW5nbGUgZG9jdW1lbnRcbiAgLy8gKG5vdCBsaW5rZWQgb25lcykuXG4gIGZ1bmN0aW9uIG1ha2VDaGFuZ2VTaW5nbGVEb2MoZG9jLCBjaGFuZ2UsIHNlbEFmdGVyLCBzcGFucykge1xuICAgIGlmIChkb2MuY20gJiYgIWRvYy5jbS5jdXJPcClcbiAgICAgIHJldHVybiBvcGVyYXRpb24oZG9jLmNtLCBtYWtlQ2hhbmdlU2luZ2xlRG9jKShkb2MsIGNoYW5nZSwgc2VsQWZ0ZXIsIHNwYW5zKTtcblxuICAgIGlmIChjaGFuZ2UudG8ubGluZSA8IGRvYy5maXJzdCkge1xuICAgICAgc2hpZnREb2MoZG9jLCBjaGFuZ2UudGV4dC5sZW5ndGggLSAxIC0gKGNoYW5nZS50by5saW5lIC0gY2hhbmdlLmZyb20ubGluZSkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlLmZyb20ubGluZSA+IGRvYy5sYXN0TGluZSgpKSByZXR1cm47XG5cbiAgICAvLyBDbGlwIHRoZSBjaGFuZ2UgdG8gdGhlIHNpemUgb2YgdGhpcyBkb2NcbiAgICBpZiAoY2hhbmdlLmZyb20ubGluZSA8IGRvYy5maXJzdCkge1xuICAgICAgdmFyIHNoaWZ0ID0gY2hhbmdlLnRleHQubGVuZ3RoIC0gMSAtIChkb2MuZmlyc3QgLSBjaGFuZ2UuZnJvbS5saW5lKTtcbiAgICAgIHNoaWZ0RG9jKGRvYywgc2hpZnQpO1xuICAgICAgY2hhbmdlID0ge2Zyb206IFBvcyhkb2MuZmlyc3QsIDApLCB0bzogUG9zKGNoYW5nZS50by5saW5lICsgc2hpZnQsIGNoYW5nZS50by5jaCksXG4gICAgICAgICAgICAgICAgdGV4dDogW2xzdChjaGFuZ2UudGV4dCldLCBvcmlnaW46IGNoYW5nZS5vcmlnaW59O1xuICAgIH1cbiAgICB2YXIgbGFzdCA9IGRvYy5sYXN0TGluZSgpO1xuICAgIGlmIChjaGFuZ2UudG8ubGluZSA+IGxhc3QpIHtcbiAgICAgIGNoYW5nZSA9IHtmcm9tOiBjaGFuZ2UuZnJvbSwgdG86IFBvcyhsYXN0LCBnZXRMaW5lKGRvYywgbGFzdCkudGV4dC5sZW5ndGgpLFxuICAgICAgICAgICAgICAgIHRleHQ6IFtjaGFuZ2UudGV4dFswXV0sIG9yaWdpbjogY2hhbmdlLm9yaWdpbn07XG4gICAgfVxuXG4gICAgY2hhbmdlLnJlbW92ZWQgPSBnZXRCZXR3ZWVuKGRvYywgY2hhbmdlLmZyb20sIGNoYW5nZS50byk7XG5cbiAgICBpZiAoIXNlbEFmdGVyKSBzZWxBZnRlciA9IGNvbXB1dGVTZWxBZnRlckNoYW5nZShkb2MsIGNoYW5nZSk7XG4gICAgaWYgKGRvYy5jbSkgbWFrZUNoYW5nZVNpbmdsZURvY0luRWRpdG9yKGRvYy5jbSwgY2hhbmdlLCBzcGFucyk7XG4gICAgZWxzZSB1cGRhdGVEb2MoZG9jLCBjaGFuZ2UsIHNwYW5zKTtcbiAgICBzZXRTZWxlY3Rpb25Ob1VuZG8oZG9jLCBzZWxBZnRlciwgc2VsX2RvbnRTY3JvbGwpO1xuICB9XG5cbiAgLy8gSGFuZGxlIHRoZSBpbnRlcmFjdGlvbiBvZiBhIGNoYW5nZSB0byBhIGRvY3VtZW50IHdpdGggdGhlIGVkaXRvclxuICAvLyB0aGF0IHRoaXMgZG9jdW1lbnQgaXMgcGFydCBvZi5cbiAgZnVuY3Rpb24gbWFrZUNoYW5nZVNpbmdsZURvY0luRWRpdG9yKGNtLCBjaGFuZ2UsIHNwYW5zKSB7XG4gICAgdmFyIGRvYyA9IGNtLmRvYywgZGlzcGxheSA9IGNtLmRpc3BsYXksIGZyb20gPSBjaGFuZ2UuZnJvbSwgdG8gPSBjaGFuZ2UudG87XG5cbiAgICB2YXIgcmVjb21wdXRlTWF4TGVuZ3RoID0gZmFsc2UsIGNoZWNrV2lkdGhTdGFydCA9IGZyb20ubGluZTtcbiAgICBpZiAoIWNtLm9wdGlvbnMubGluZVdyYXBwaW5nKSB7XG4gICAgICBjaGVja1dpZHRoU3RhcnQgPSBsaW5lTm8odmlzdWFsTGluZShnZXRMaW5lKGRvYywgZnJvbS5saW5lKSkpO1xuICAgICAgZG9jLml0ZXIoY2hlY2tXaWR0aFN0YXJ0LCB0by5saW5lICsgMSwgZnVuY3Rpb24obGluZSkge1xuICAgICAgICBpZiAobGluZSA9PSBkaXNwbGF5Lm1heExpbmUpIHtcbiAgICAgICAgICByZWNvbXB1dGVNYXhMZW5ndGggPSB0cnVlO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoZG9jLnNlbC5jb250YWlucyhjaGFuZ2UuZnJvbSwgY2hhbmdlLnRvKSA+IC0xKVxuICAgICAgc2lnbmFsQ3Vyc29yQWN0aXZpdHkoY20pO1xuXG4gICAgdXBkYXRlRG9jKGRvYywgY2hhbmdlLCBzcGFucywgZXN0aW1hdGVIZWlnaHQoY20pKTtcblxuICAgIGlmICghY20ub3B0aW9ucy5saW5lV3JhcHBpbmcpIHtcbiAgICAgIGRvYy5pdGVyKGNoZWNrV2lk
23459dGhTdGFydCwgZnJvbS5saW5lICsgY2hhbmdlLnRleHQubGVuZ3RoLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgIHZhciBsZW4gPSBsaW5lTGVuZ3RoKGxpbmUpO1xuICAgICAgICBpZiAobGVuID4gZGlzcGxheS5tYXhMaW5lTGVuZ3RoKSB7XG4gICAgICAgICAgZGlzcGxheS5tYXhMaW5lID0gbGluZTtcbiAgICAgICAgICBkaXNwbGF5Lm1heExpbmVMZW5ndGggPSBsZW47XG4gICAgICAgICAgZGlzcGxheS5tYXhMaW5lQ2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgcmVjb21wdXRlTWF4TGVuZ3RoID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKHJlY29tcHV0ZU1heExlbmd0aCkgY20uY3VyT3AudXBkYXRlTWF4TGluZSA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gQWRqdXN0IGZyb250aWVyLCBzY2hlZHVsZSB3b3JrZXJcbiAgICBkb2MuZnJvbnRpZXIgPSBNYXRoLm1pbihkb2MuZnJvbnRpZXIsIGZyb20ubGluZSk7XG4gICAgc3RhcnRXb3JrZXIoY20sIDQwMCk7XG5cbiAgICB2YXIgbGVuZGlmZiA9IGNoYW5nZS50ZXh0Lmxlbmd0aCAtICh0by5saW5lIC0gZnJvbS5saW5lKSAtIDE7XG4gICAgLy8gUmVtZW1iZXIgdGhhdCB0aGVzZSBsaW5lcyBjaGFuZ2VkLCBmb3IgdXBkYXRpbmcgdGhlIGRpc3BsYXlcbiAgICBpZiAoY2hhbmdlLmZ1bGwpXG4gICAgICByZWdDaGFuZ2UoY20pO1xuICAgIGVsc2UgaWYgKGZyb20ubGluZSA9PSB0by5saW5lICYmIGNoYW5nZS50ZXh0Lmxlbmd0aCA9PSAxICYmICFpc1dob2xlTGluZVVwZGF0ZShjbS5kb2MsIGNoYW5nZSkpXG4gICAgICByZWdMaW5lQ2hhbmdlKGNtLCBmcm9tLmxpbmUsIFwidGV4dFwiKTtcbiAgICBlbHNlXG4gICAgICByZWdDaGFuZ2UoY20sIGZyb20ubGluZSwgdG8ubGluZSArIDEsIGxlbmRpZmYpO1xuXG4gICAgdmFyIGNoYW5nZXNIYW5kbGVyID0gaGFzSGFuZGxlcihjbSwgXCJjaGFuZ2VzXCIpLCBjaGFuZ2VIYW5kbGVyID0gaGFzSGFuZGxlcihjbSwgXCJjaGFuZ2VcIik7XG4gICAgaWYgKGNoYW5nZUhhbmRsZXIgfHwgY2hhbmdlc0hhbmRsZXIpIHtcbiAgICAgIHZhciBvYmogPSB7XG4gICAgICAgIGZyb206IGZyb20sIHRvOiB0byxcbiAgICAgICAgdGV4dDogY2hhbmdlLnRleHQsXG4gICAgICAgIHJlbW92ZWQ6IGNoYW5nZS5yZW1vdmVkLFxuICAgICAgICBvcmlnaW46IGNoYW5nZS5vcmlnaW5cbiAgICAgIH07XG4gICAgICBpZiAoY2hhbmdlSGFuZGxlcikgc2lnbmFsTGF0ZXIoY20sIFwiY2hhbmdlXCIsIGNtLCBvYmopO1xuICAgICAgaWYgKGNoYW5nZXNIYW5kbGVyKSAoY20uY3VyT3AuY2hhbmdlT2JqcyB8fCAoY20uY3VyT3AuY2hhbmdlT2JqcyA9IFtdKSkucHVzaChvYmopO1xuICAgIH1cbiAgICBjbS5kaXNwbGF5LnNlbEZvckNvbnRleHRNZW51ID0gbnVsbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlcGxhY2VSYW5nZShkb2MsIGNvZGUsIGZyb20sIHRvLCBvcmlnaW4pIHtcbiAgICBpZiAoIXRvKSB0byA9IGZyb207XG4gICAgaWYgKGNtcCh0bywgZnJvbSkgPCAwKSB7IHZhciB0bXAgPSB0bzsgdG8gPSBmcm9tOyBmcm9tID0gdG1wOyB9XG4gICAgaWYgKHR5cGVvZiBjb2RlID09IFwic3RyaW5nXCIpIGNvZGUgPSBkb2Muc3BsaXRMaW5lcyhjb2RlKTtcbiAgICBtYWtlQ2hhbmdlKGRvYywge2Zyb206IGZyb20sIHRvOiB0bywgdGV4dDogY29kZSwgb3JpZ2luOiBvcmlnaW59KTtcbiAgfVxuXG4gIC8vIFNDUk9MTElORyBUSElOR1MgSU5UTyBWSUVXXG5cbiAgLy8gSWYgYW4gZWRpdG9yIHNpdHMgb24gdGhlIHRvcCBvciBib3R0b20gb2YgdGhlIHdpbmRvdywgcGFydGlhbGx5XG4gIC8vIHNjcm9sbGVkIG91dCBvZiB2aWV3LCB0aGlzIGVuc3VyZXMgdGhhdCB0aGUgY3Vyc29yIGlzIHZpc2libGUuXG4gIGZ1bmN0aW9uIG1heWJlU2Nyb2xsV2luZG93KGNtLCBjb29yZHMpIHtcbiAgICBpZiAoc2lnbmFsRE9NRXZlbnQoY20sIFwic2Nyb2xsQ3Vyc29ySW50b1ZpZXdcIikpIHJldHVybjtcblxuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheSwgYm94ID0gZGlzcGxheS5zaXplci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgZG9TY3JvbGwgPSBudWxsO1xuICAgIGlmIChjb29yZHMudG9wICsgYm94LnRvcCA8IDApIGRvU2Nyb2xsID0gdHJ1ZTtcbiAgICBlbHNlIGlmIChjb29yZHMuYm90dG9tICsgYm94LnRvcCA+ICh3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCkpIGRvU2Nyb2xsID0gZmFsc2U7XG4gICAgaWYgKGRvU2Nyb2xsICE9IG51bGwgJiYgIXBoYW50b20pIHtcbiAgICAgIHZhciBzY3JvbGxOb2RlID0gZWx0KFwiZGl2XCIsIFwiXFx1MjAwYlwiLCBudWxsLCBcInBvc2l0aW9uOiBhYnNvbHV0ZTsgdG9wOiBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAoY29vcmRzLnRvcCAtIGRpc3BsYXkudmlld09mZnNldCAtIHBhZGRpbmdUb3AoY20uZGlzcGxheSkpICsgXCJweDsgaGVpZ2h0OiBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAoY29vcmRzLmJvdHRvbSAtIGNvb3Jkcy50b3AgKyBzY3JvbGxHYXAoY20pICsgZGlzcGxheS5iYXJIZWlnaHQpICsgXCJweDsgbGVmdDogXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRzLmxlZnQgKyBcInB4OyB3aWR0aDogMnB4O1wiKTtcbiAgICAgIGNtLmRpc3BsYXkubGluZVNwYWNlLmFwcGVuZENoaWxkKHNjcm9sbE5vZGUpO1xuICAgICAgc2Nyb2xsTm9kZS5zY3JvbGxJbnRvVmlldyhkb1Njcm9sbCk7XG4gICAgICBjbS5kaXNwbGF5LmxpbmVTcGFjZS5yZW1vdmVDaGlsZChzY3JvbGxOb2RlKTtcbiAgICB9XG4gIH1cblxuICAvLyBTY3JvbGwgYSBnaXZlbiBwb3NpdGlvbiBpbnRvIHZpZXcgKGltbWVkaWF0ZWx5KSwgdmVyaWZ5aW5nIHRoYXRcbiAgLy8gaXQgYWN0dWFsbHkgYmVjYW1lIHZpc2libGUgKGFzIGxpbmUgaGVpZ2h0cyBhcmUgYWNjdXJhdGVseVxuICAvLyBtZWFzdXJlZCwgdGhlIHBvc2l0aW9uIG9mIHNvbWV0aGluZyBtYXkgJ2RyaWZ0JyBkdXJpbmcgZHJhd2luZykuXG4gIGZ1bmN0aW9uIHNjcm9sbFBvc0ludG9WaWV3KGNtLCBwb3MsIGVuZCwgbWFyZ2luKSB7XG4gICAgaWYgKG1hcmdpbiA9PSBudWxsKSBtY
23459XJnaW4gPSAwO1xuICAgIGZvciAodmFyIGxpbWl0ID0gMDsgbGltaXQgPCA1OyBsaW1pdCsrKSB7XG4gICAgICB2YXIgY2hhbmdlZCA9IGZhbHNlLCBjb29yZHMgPSBjdXJzb3JDb29yZHMoY20sIHBvcyk7XG4gICAgICB2YXIgZW5kQ29vcmRzID0gIWVuZCB8fCBlbmQgPT0gcG9zID8gY29vcmRzIDogY3Vyc29yQ29vcmRzKGNtLCBlbmQpO1xuICAgICAgdmFyIHNjcm9sbFBvcyA9IGNhbGN1bGF0ZVNjcm9sbFBvcyhjbSwgTWF0aC5taW4oY29vcmRzLmxlZnQsIGVuZENvb3Jkcy5sZWZ0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5taW4oY29vcmRzLnRvcCwgZW5kQ29vcmRzLnRvcCkgLSBtYXJnaW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGgubWF4KGNvb3Jkcy5sZWZ0LCBlbmRDb29yZHMubGVmdCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGgubWF4KGNvb3Jkcy5ib3R0b20sIGVuZENvb3Jkcy5ib3R0b20pICsgbWFyZ2luKTtcbiAgICAgIHZhciBzdGFydFRvcCA9IGNtLmRvYy5zY3JvbGxUb3AsIHN0YXJ0TGVmdCA9IGNtLmRvYy5zY3JvbGxMZWZ0O1xuICAgICAgaWYgKHNjcm9sbFBvcy5zY3JvbGxUb3AgIT0gbnVsbCkge1xuICAgICAgICBzZXRTY3JvbGxUb3AoY20sIHNjcm9sbFBvcy5zY3JvbGxUb3ApO1xuICAgICAgICBpZiAoTWF0aC5hYnMoY20uZG9jLnNjcm9sbFRvcCAtIHN0YXJ0VG9wKSA+IDEpIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHNjcm9sbFBvcy5zY3JvbGxMZWZ0ICE9IG51bGwpIHtcbiAgICAgICAgc2V0U2Nyb2xsTGVmdChjbSwgc2Nyb2xsUG9zLnNjcm9sbExlZnQpO1xuICAgICAgICBpZiAoTWF0aC5hYnMoY20uZG9jLnNjcm9sbExlZnQgLSBzdGFydExlZnQpID4gMSkgY2hhbmdlZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAoIWNoYW5nZWQpIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gY29vcmRzO1xuICB9XG5cbiAgLy8gU2Nyb2xsIGEgZ2l2ZW4gc2V0IG9mIGNvb3JkaW5hdGVzIGludG8gdmlldyAoaW1tZWRpYXRlbHkpLlxuICBmdW5jdGlvbiBzY3JvbGxJbnRvVmlldyhjbSwgeDEsIHkxLCB4MiwgeTIpIHtcbiAgICB2YXIgc2Nyb2xsUG9zID0gY2FsY3VsYXRlU2Nyb2xsUG9zKGNtLCB4MSwgeTEsIHgyLCB5Mik7XG4gICAgaWYgKHNjcm9sbFBvcy5zY3JvbGxUb3AgIT0gbnVsbCkgc2V0U2Nyb2xsVG9wKGNtLCBzY3JvbGxQb3Muc2Nyb2xsVG9wKTtcbiAgICBpZiAoc2Nyb2xsUG9zLnNjcm9sbExlZnQgIT0gbnVsbCkgc2V0U2Nyb2xsTGVmdChjbSwgc2Nyb2xsUG9zLnNjcm9sbExlZnQpO1xuICB9XG5cbiAgLy8gQ2FsY3VsYXRlIGEgbmV3IHNjcm9sbCBwb3NpdGlvbiBuZWVkZWQgdG8gc2Nyb2xsIHRoZSBnaXZlblxuICAvLyByZWN0YW5nbGUgaW50byB2aWV3LiBSZXR1cm5zIGFuIG9iamVjdCB3aXRoIHNjcm9sbFRvcCBhbmRcbiAgLy8gc2Nyb2xsTGVmdCBwcm9wZXJ0aWVzLiBXaGVuIHRoZXNlIGFyZSB1bmRlZmluZWQsIHRoZVxuICAvLyB2ZXJ0aWNhbC9ob3Jpem9udGFsIHBvc2l0aW9uIGRvZXMgbm90IG5lZWQgdG8gYmUgYWRqdXN0ZWQuXG4gIGZ1bmN0aW9uIGNhbGN1bGF0ZVNjcm9sbFBvcyhjbSwgeDEsIHkxLCB4MiwgeTIpIHtcbiAgICB2YXIgZGlzcGxheSA9IGNtLmRpc3BsYXksIHNuYXBNYXJnaW4gPSB0ZXh0SGVpZ2h0KGNtLmRpc3BsYXkpO1xuICAgIGlmICh5MSA8IDApIHkxID0gMDtcbiAgICB2YXIgc2NyZWVudG9wID0gY20uY3VyT3AgJiYgY20uY3VyT3Auc2Nyb2xsVG9wICE9IG51bGwgPyBjbS5jdXJPcC5zY3JvbGxUb3AgOiBkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbFRvcDtcbiAgICB2YXIgc2NyZWVuID0gZGlzcGxheUhlaWdodChjbSksIHJlc3VsdCA9IHt9O1xuICAgIGlmICh5MiAtIHkxID4gc2NyZWVuKSB5MiA9IHkxICsgc2NyZWVuO1xuICAgIHZhciBkb2NCb3R0b20gPSBjbS5kb2MuaGVpZ2h0ICsgcGFkZGluZ1ZlcnQoZGlzcGxheSk7XG4gICAgdmFyIGF0VG9wID0geTEgPCBzbmFwTWFyZ2luLCBhdEJvdHRvbSA9IHkyID4gZG9jQm90dG9tIC0gc25hcE1hcmdpbjtcbiAgICBpZiAoeTEgPCBzY3JlZW50b3ApIHtcbiAgICAgIHJlc3VsdC5zY3JvbGxUb3AgPSBhdFRvcCA/IDAgOiB5MTtcbiAgICB9IGVsc2UgaWYgKHkyID4gc2NyZWVudG9wICsgc2NyZWVuKSB7XG4gICAgICB2Y
23459XIgbmV3VG9wID0gTWF0aC5taW4oeTEsIChhdEJvdHRvbSA/IGRvY0JvdHRvbSA6IHkyKSAtIHNjcmVlbik7XG4gICAgICBpZiAobmV3VG9wICE9IHNjcmVlbnRvcCkgcmVzdWx0LnNjcm9sbFRvcCA9IG5ld1RvcDtcbiAgICB9XG5cbiAgICB2YXIgc2NyZWVubGVmdCA9IGNtLmN1ck9wICYmIGNtLmN1ck9wLnNjcm9sbExlZnQgIT0gbnVsbCA/IGNtLmN1ck9wLnNjcm9sbExlZnQgOiBkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbExlZnQ7XG4gICAgdmFyIHNjcmVlbncgPSBkaXNwbGF5V2lkdGgoY20pIC0gKGNtLm9wdGlvbnMuZml4ZWRHdXR0ZXIgPyBkaXNwbGF5Lmd1dHRlcnMub2Zmc2V0V2lkdGggOiAwKTtcbiAgICB2YXIgdG9vV2lkZSA9IHgyIC0geDEgPiBzY3JlZW53O1xuICAgIGlmICh0b29XaWRlKSB4MiA9IHgxICsgc2NyZWVudztcbiAgICBpZiAoeDEgPCAxMClcbiAgICAgIHJlc3VsdC5zY3JvbGxMZWZ0ID0gMDtcbiAgICBlbHNlIGlmICh4MSA8IHNjcmVlbmxlZnQpXG4gICAgICByZXN1bHQuc2Nyb2xsTGVmdCA9IE1hdGgubWF4KDAsIHgxIC0gKHRvb1dpZGUgPyAwIDogMTApKTtcbiAgICBlbHNlIGlmICh4MiA+IHNjcmVlbncgKyBzY3JlZW5sZWZ0IC0gMylcbiAgICAgIHJlc3VsdC5zY3JvbGxMZWZ0ID0geDIgKyAodG9vV2lkZSA/IDAgOiAxMCkgLSBzY3JlZW53O1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBTdG9yZSBhIHJlbGF0aXZlIGFkanVzdG1lbnQgdG8gdGhlIHNjcm9sbCBwb3NpdGlvbiBpbiB0aGUgY3VycmVudFxuICAvLyBvcGVyYXRpb24gKHRvIGJlIGFwcGxpZWQgd2hlbiB0aGUgb3BlcmF0aW9uIGZpbmlzaGVzKS5cbiAgZnVuY3Rpb24gYWRkVG9TY3JvbGxQb3MoY20sIGxlZnQsIHRvcCkge1xuICAgIGlmIChsZWZ0ICE9IG51bGwgfHwgdG9wICE9IG51bGwpIHJlc29sdmVTY3JvbGxUb1BvcyhjbSk7XG4gICAgaWYgKGxlZnQgIT0gbnVsbClcbiAgICAgIGNtLmN1ck9wLnNjcm9sbExlZnQgPSAoY20uY3VyT3Auc2Nyb2xsTGVmdCA9PSBudWxsID8gY20uZG9jLnNjcm9sbExlZnQgOiBjbS5jdXJPcC5zY3JvbGxMZWZ0KSArIGxlZnQ7XG4gICAgaWYgKHRvcCAhPSBudWxsKVxuICAgICAgY20uY3VyT3Auc2Nyb2xsVG9wID0gKGNtLmN1ck9wLnNjcm9sbFRvcCA9PSBudWxsID8gY20uZG9jLnNjcm9sbFRvcCA6IGNtLmN1ck9wLnNjcm9sbFRvcCkgKyB0b3A7XG4gIH1cblxuICAvLyBNYWtlIHN1cmUgdGhhdCBhdCB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb24gdGhlIGN1cnJlbnQgY3Vyc29yIGlzXG4gIC8vIHNob3duLlxuICBmdW5jdGlvbiBlbnN1cmVDdXJzb3JWaXNpYmxlKGNtKSB7XG4gICAgcmVzb2x2ZVNjcm9sbFRvUG9zKGNtKTtcbiAgICB2YXIgY3VyID0gY20uZ2V0Q3Vyc29yKCksIGZyb20gPSBjdXIsIHRvID0gY3VyO1xuICAgIGlmICghY20ub3B0aW9ucy5saW5lV3JhcHBpbmcpIHtcbiAgICAgIGZyb20gPSBjdXIuY2ggPyBQb3MoY3VyLmxpbmUsIGN1ci5jaCAtIDEpIDogY3VyO1xuICAgICAgdG8gPSBQb3MoY3VyLmxpbmUsIGN1ci5jaCArIDEpO1xuICAgIH1cbiAgICBjbS5jdXJPcC5zY3JvbGxUb1BvcyA9IHtmcm9tOiBmcm9tLCB0bzogdG8sIG1hcmdpbjogY20ub3B0aW9ucy5jdXJzb3JTY3JvbGxNYXJnaW4sIGlzQ3Vyc29yOiB0cnVlfTtcbiAgfVxuXG4gIC8vIFdoZW4gYW4gb3BlcmF0aW9uIGhhcyBpdHMgc2Nyb2xsVG9Qb3MgcHJvcGVydHkgc2V0LCBhbmQgYW5vdGhlclxuICAvLyBzY3JvbGwgYWN0aW9uIGlzIGFwcGxpZWQgYmVmb3JlIHRoZSBlbmQgb2YgdGhlIG9wZXJhdGlvbiwgdGhpc1xuICAvLyAnc2ltdWxhdGVzJyBzY3JvbGxpbmcgdGhhdCBwb3NpdGlvbiBpbnRvIHZpZXcgaW4gYSBjaGVhcCB3YXksIHNvXG4gIC8vIHRoYXQgdGhlIGVmZmVjdCBvZiBpbnRlcm1lZGlhdGUgc2Nyb2xsIGNvbW1hbmRzIGlzIG5vdCBpZ25vcmVkLlxuICBmdW5jdGlvbiByZXNvbHZlU2Nyb2xsVG9Qb3MoY20pIHtcbiAgICB2YXIgcmFuZ2UgPSBjbS5jdXJPcC5zY3JvbGxUb1BvcztcbiAgICBpZiAocmFuZ2UpIHtcbiAgICAgIGNtLmN1ck9wLnNjcm9sbFRvUG9zID0gbnVsbDtcbiAgICAgIHZhciBmcm9tID0gZXN0aW1hdGVDb29yZHMoY20sIHJhbmdlLmZyb20pLCB0byA9IGVzdGltYXRlQ29vcmRzKGNtLCByYW5nZS50byk7XG4gICAgICB2Y
23459XIgc1BvcyA9IGNhbGN1bGF0ZVNjcm9sbFBvcyhjbSwgTWF0aC5taW4oZnJvbS5sZWZ0LCB0by5sZWZ0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGgubWluKGZyb20udG9wLCB0by50b3ApIC0gcmFuZ2UubWFyZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5tYXgoZnJvbS5yaWdodCwgdG8ucmlnaHQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5tYXgoZnJvbS5ib3R0b20sIHRvLmJvdHRvbSkgKyByYW5nZS5tYXJnaW4pO1xuICAgICAgY20uc2Nyb2xsVG8oc1Bvcy5zY3JvbGxMZWZ0LCBzUG9zLnNjcm9sbFRvcCk7XG4gICAgfVxuICB9XG5cbiAgLy8gQVBJIFVUSUxJVElFU1xuXG4gIC8vIEluZGVudCB0aGUgZ2l2ZW4gbGluZS4gVGhlIGhvdyBwYXJhbWV0ZXIgY2FuIGJlIFwic21hcnRcIixcbiAgLy8gXCJhZGRcIi9udWxsLCBcInN1YnRyYWN0XCIsIG9yIFwicHJldlwiLiBXaGVuIGFnZ3Jlc3NpdmUgaXMgZmFsc2VcbiAgLy8gKHR5cGljYWxseSBzZXQgdG8gdHJ1ZSBmb3IgZm9yY2VkIHNpbmdsZS1saW5lIGluZGVudHMpLCBlbXB0eVxuICAvLyBsaW5lcyBhcmUgbm90IGluZGVudGVkLCBhbmQgcGxhY2VzIHdoZXJlIHRoZSBtb2RlIHJldHVybnMgUGFzc1xuICAvLyBhcmUgbGVmdCBhbG9uZS5cbiAgZnVuY3Rpb24gaW5kZW50TGluZShjbSwgbiwgaG93LCBhZ2dyZXNzaXZlKSB7XG4gICAgdmFyIGRvYyA9IGNtLmRvYywgc3RhdGU7XG4gICAgaWYgKGhvdyA9PSBudWxsKSBob3cgPSBcImFkZFwiO1xuICAgIGlmIChob3cgPT0gXCJzbWFydFwiKSB7XG4gICAgICAvLyBGYWxsIGJhY2sgdG8gXCJwcmV2XCIgd2hlbiB0aGUgbW9kZSBkb2Vzbid0IGhhdmUgYW4gaW5kZW50YXRpb25cbiAgICAgIC8vIG1ldGhvZC5cbiAgICAgIGlmICghZG9jLm1vZGUuaW5kZW50KSBob3cgPSBcInByZXZcIjtcbiAgICAgIGVsc2Ugc3RhdGUgPSBnZXRTdGF0ZUJlZm9yZShjbSwgbik7XG4gICAgfVxuXG4gICAgdmFyIHRhYlNpemUgPSBjbS5vcHRpb25zLnRhYlNpemU7XG4gICAgdmFyIGxpbmUgPSBnZXRMaW5lKGRvYywgbiksIGN1clNwYWNlID0gY291bnRDb2x1bW4obGluZS50ZXh0LCBudWxsLCB0YWJTaXplKTtcbiAgICBpZiAobGluZS5zdGF0ZUFmdGVyKSBsaW5lLnN0YXRlQWZ0ZXIgPSBudWxsO1xuICAgIHZhciBjdXJTcGFjZVN0cmluZyA9IGxpbmUudGV4dC5tYXRjaCgvXlxccyovKVswXSwgaW5kZW50YXRpb247XG4gICAgaWYgKCFhZ2dyZXNzaXZlICYmICEvXFxTLy50ZXN0KGxpbmUudGV4dCkpIHtcbiAgICAgIGluZGVudGF0aW9uID0gMDtcbiAgICAgIGhvdyA9IFwibm90XCI7XG4gICAgfSBlbHNlIGlmIChob3cgPT0gXCJzbWFydFwiKSB7XG4gICAgICBpbmRlbnRhdGlvbiA9IGRvYy5tb2RlLmluZGVudChzdGF0ZSwgbGluZS50ZXh0LnNsaWNlKGN1clNwYWNlU3RyaW5nLmxlbmd0aCksIGxpbmUudGV4dCk7XG4gICAgICBpZiAoaW5kZW50YXRpb24gPT0gUGFzcyB8fCBpbmRlbnRhdGlvbiA+IDE1MCkge1xuICAgICAgICBpZiAoIWFnZ3Jlc3NpdmUpIHJldHVybjtcbiAgICAgICAgaG93ID0gXCJwcmV2XCI7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChob3cgPT0gXCJwcmV2XCIpIHtcbiAgICAgIGlmIChuID4gZG9jLmZpcnN0KSBpbmRlbnRhdGlvbiA9IGNvdW50Q29sdW1uKGdldExpbmUoZG9jLCBuLTEpLnRleHQsIG51bGwsIHRhYlNpemUpO1xuICAgICAgZWxzZSBpbmRlbnRhdGlvbiA9IDA7XG4gICAgfSBlbHNlIGlmIChob3cgPT0gXCJhZGRcIikge1xuICAgICAgaW5kZW50YXRpb24gPSBjdXJTcGFjZSArIGNtLm9wdGlvbnMuaW5kZW50VW5pdDtcbiAgICB9IGVsc2UgaWYgKGhvdyA9PSBcInN1YnRyYWN0XCIpIHtcbiAgICAgIGluZGVudGF0aW9uID0gY3VyU3BhY2UgLSBjbS5vcHRpb25zLmluZGVudFVuaXQ7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgaG93ID09IFwibnVtYmVyXCIpIHtcbiAgICAgIGluZGVudGF0aW9uID0gY3VyU3BhY2UgKyBob3c7XG4gICAgfVxuICAgIGluZGVudGF0aW9uID0gTWF0aC5tYXgoMCwgaW5kZW50YXRpb24pO1xuXG4gICAgdmFyIGluZGVudFN0cmluZyA9IFwiXCIsIHBvcyA9IDA7XG4gICAgaWYgKGNtLm9wdGlvbnMuaW5kZW50V2l0aFRhYnMpXG4gICAgICBmb3IgKHZhciBpID0gTWF0aC5mbG9vcihpbmRlbnRhdGlvbiAvIHRhYlNpemUpOyBpOyAtLWkpIHtwb3MgKz0gdGFiU2l6ZTsgaW5kZW50U3RyaW5nICs9IFwiXFx0XCI7fVxuICAgIGlmIChwb3MgPCBpbmRlbnRhdGlvbikgaW5kZW50U3RyaW5nICs9IHNwYWNlU3RyKGluZGVudGF0aW9uIC0gcG9zKTtcblxuICAgIGlmIChpbmRlbnRTdHJpbmcgIT0gY3VyU3BhY2VTdHJpbmcpIHtcbiAgICAgIHJlcGxhY2VSYW5nZShkb2MsIGluZGVudFN0cmluZywgUG9zKG4sIDApLCBQb3MobiwgY3VyU3BhY2VTdHJpbmcubGVuZ3RoKSwgXCIraW5wdXRcIik7XG4gICAgICBsaW5lLnN0YXRlQWZ0ZXIgPSBudWxsO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEVuc3VyZSB0aGF0LCBpZiB0aGUgY3Vyc29yIHdhcyBpbiB0aGUgd2hpdGVzcGFjZSBhdCB0aGUgc3RhcnRcbiAgICAgIC8vIG9mIHRoZSBsaW5lLCBpdCBpcyBtb3ZlZCB0byB0aGUgZW5kIG9mIHRoYXQgc3BhY2UuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRvYy5zZWwucmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciByYW5nZSA9IGRvYy5zZWwucmFuZ2VzW2ldO1xuICAgICAgICBpZiAocmFuZ2UuaGVhZC5saW5lID09IG4gJiYgcmFuZ2UuaGVhZC5jaCA8IGN1clNwYWNlU3RyaW5nLmxlbmd0aCkge1xuICAgICAgICAgIHZhciBwb3MgPSBQb3MobiwgY3VyU3BhY2VTdHJpbmcubGVuZ3RoKTtcbiAgICAgICAgICByZXBsYWNlT25lU2VsZWN0aW9uKGRvYywgaSwgbmV3IFJhbmdlKHBvcywgcG9zKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBVdGlsaXR5IGZvciBhcHBseWluZyBhIGNoYW5nZSB0byBhIGxpbmUgYnkgaGFuZGxlIG9yIG51bWJlcixcbiAgLy8gcmV0dXJuaW5nIHRoZSBudW1iZXIgYW5kIG9wdGlvbmFsbHkgcmVnaXN0ZXJpbmcgdGhlIGxpbmUgYXNcbiAgLy8gY2hhbmdlZC5cbiAgZnVuY3Rpb24gY2hhbmdlTGluZShkb2MsIGhhbmRsZSwgY2hhbmdlVHlwZSwgb3ApIHtcbiAgICB2YXIgbm8gPSBoYW5kbGUsIGxpbmUgPSBoYW5kbGU7XG4gICAgaWYgKHR5cGVvZiBoYW5kbGUgPT0gXCJudW1iZXJcIikgbGluZSA9IGdldExpbmUoZG9jLCBjbGlwTGluZShkb2MsIGhhbmRsZSkpO1xuICAgIGVsc2Ugbm8gPSBsaW5lTm8oaGFuZGxlKTtcbiAgICBpZiAobm8gPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgaWYgKG9wKGxpbmUsIG5vKSAmJiBkb2MuY20pIHJlZ0xpbmVDaGFuZ2UoZG9jLmNtLCBubywgY2hhbmdlVHlwZSk7XG4gICAgcmV0dXJuIGxpbmU7XG4gIH1cblxuICAvLyBIZWxwZXIgZm9yIGRlbGV0aW5nIHRleHQgbmVhciB0aGUgc2VsZWN0aW9uKHMpLCB1c2VkIHRvIGltcGxlbWVudFxuICAvLyBiYWNrc3BhY2UsIGRlbGV0ZSwgYW5kIHNpbWlsYXIgZnVuY3Rpb25hbGl0eS5cbiAgZnVuY3Rpb24gZGVsZXRlTmVhclNlbGVjdGlvbihjbSwgY29tcHV0ZSkge1xuICAgIHZhciByYW5nZXMgPSBjbS5kb2Muc2VsLnJhbmdlcywga2lsbCA9I
23459FtdO1xuICAgIC8vIEJ1aWxkIHVwIGEgc2V0IG9mIHJhbmdlcyB0byBraWxsIGZpcnN0LCBtZXJnaW5nIG92ZXJsYXBwaW5nXG4gICAgLy8gcmFuZ2VzLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdG9LaWxsID0gY29tcHV0ZShyYW5nZXNbaV0pO1xuICAgICAgd2hpbGUgKGtpbGwubGVuZ3RoICYmIGNtcCh0b0tpbGwuZnJvbSwgbHN0KGtpbGwpLnRvKSA8PSAwKSB7XG4gICAgICAgIHZhciByZXBsYWNlZCA9IGtpbGwucG9wKCk7XG4gICAgICAgIGlmIChjbXAocmVwbGFjZWQuZnJvbSwgdG9LaWxsLmZyb20pIDwgMCkge1xuICAgICAgICAgIHRvS2lsbC5mcm9tID0gcmVwbGFjZWQuZnJvbTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAga2lsbC5wdXNoKHRvS2lsbCk7XG4gICAgfVxuICAgIC8vIE5leHQsIHJlbW92ZSB0aG9zZSBhY3R1YWwgcmFuZ2VzLlxuICAgIHJ1bkluT3AoY20sIGZ1bmN0aW9uKCkge1xuICAgICAgZm9yICh2YXIgaSA9IGtpbGwubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgIHJlcGxhY2VSYW5nZShjbS5kb2MsIFwiXCIsIGtpbGxbaV0uZnJvbSwga2lsbFtpXS50bywgXCIrZGVsZXRlXCIpO1xuICAgICAgZW5zdXJlQ3Vyc29yVmlzaWJsZShjbSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBVc2VkIGZvciBob3Jpem9udGFsIHJlbGF0aXZlIG1vdGlvbi4gRGlyIGlzIC0xIG9yIDEgKGxlZnQgb3JcbiAgLy8gcmlnaHQpLCB1bml0IGNhbiBiZSBcImNoYXJcIiwgXCJjb2x1bW5cIiAobGlrZSBjaGFyLCBidXQgZG9lc24ndFxuICAvLyBjcm9zcyBsaW5lIGJvdW5kYXJpZXMpLCBcIndvcmRcIiAoYWNyb3NzIG5leHQgd29yZCksIG9yIFwiZ3JvdXBcIiAodG9cbiAgLy8gdGhlIHN0YXJ0IG9mIG5leHQgZ3JvdXAgb2Ygd29yZCBvciBub24td29yZC1ub24td2hpdGVzcGFjZVxuICAvLyBjaGFycykuIFRoZSB2aXN1YWxseSBwYXJhbSBjb250cm9scyB3aGV0aGVyLCBpbiByaWdodC10by1sZWZ0XG4gIC8vIHRleHQsIGRpcmVjdGlvbiAxIG1lYW5zIHRvIG1vdmUgdG93YXJkcyB0aGUgbmV4dCBpbmRleCBpbiB0aGVcbiAgLy8gc3RyaW5nLCBvciB0b3dhcmRzIHRoZSBjaGFyYWN0ZXIgdG8gdGhlIHJpZ2h0IG9mIHRoZSBjdXJyZW50XG4gIC8vIHBvc2l0aW9uLiBUaGUgcmVzdWx0aW5nIHBvc2l0aW9uIHdpbGwgaGF2ZSBhIGhpdFNpZGU9dHJ1ZVxuICAvLyBwcm9wZXJ0eSBpZiBpdCByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LlxuICBmdW5jdGlvbiBmaW5kUG9zSChkb2MsIHBvcywgZGlyLCB1bml0LCB2aXN1YWxseSkge1xuICAgIHZhciBsaW5lID0gcG9zLmxpbmUsIGNoID0gcG9zLmNoLCBvcmlnRGlyID0gZGlyO1xuICAgIHZhciBsaW5lT2JqID0gZ2V0TGluZShkb2MsIGxpbmUpO1xuICAgIHZhciBwb3NzaWJsZSA9IHRydWU7XG4gICAgZnVuY3Rpb24gZmluZE5leHRMaW5lKCkge1xuICAgICAgdmFyIGwgPSBsaW5lICsgZGlyO1xuICAgICAgaWYgKGwgPCBkb2MuZmlyc3QgfHwgbCA+PSBkb2MuZmlyc3QgKyBkb2Muc2l6ZSkgcmV0dXJuIChwb3NzaWJsZSA9IGZhbHNlKTtcbiAgICAgIGxpbmUgPSBsO1xuICAgICAgcmV0dXJuIGxpbmVPYmogPSBnZXRMaW5lKGRvYywgbCk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIG1vdmVPbmNlKGJvdW5kVG9MaW5lKSB7XG4gICAgICB2Y
23459XIgbmV4dCA9ICh2aXN1YWxseSA/IG1vdmVWaXN1YWxseSA6IG1vdmVMb2dpY2FsbHkpKGxpbmVPYmosIGNoLCBkaXIsIHRydWUpO1xuICAgICAgaWYgKG5leHQgPT0gbnVsbCkge1xuICAgICAgICBpZiAoIWJvdW5kVG9MaW5lICYmIGZpbmROZXh0TGluZSgpKSB7XG4gICAgICAgICAgaWYgKHZpc3VhbGx5KSBjaCA9IChkaXIgPCAwID8gbGluZVJpZ2h0IDogbGluZUxlZnQpKGxpbmVPYmopO1xuICAgICAgICAgIGVsc2UgY2ggPSBkaXIgPCAwID8gbGluZU9iai50ZXh0Lmxlbmd0aCA6IDA7XG4gICAgICAgIH0gZWxzZSByZXR1cm4gKHBvc3NpYmxlID0gZmFsc2UpO1xuICAgICAgfSBlbHNlIGNoID0gbmV4dDtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmICh1bml0ID09IFwiY2hhclwiKSBtb3ZlT25jZSgpO1xuICAgIGVsc2UgaWYgKHVuaXQgPT0gXCJjb2x1bW5cIikgbW92ZU9uY2UodHJ1ZSk7XG4gICAgZWxzZSBpZiAodW5pdCA9PSBcIndvcmRcIiB8fCB1bml0ID09IFwiZ3JvdXBcIikge1xuICAgICAgdmFyIHNhd1R5cGUgPSBudWxsLCBncm91cCA9IHVuaXQgPT0gXCJncm91cFwiO1xuICAgICAgdmFyIGhlbHBlciA9IGRvYy5jbSAmJiBkb2MuY20uZ2V0SGVscGVyKHBvcywgXCJ3b3JkQ2hhcnNcIik7XG4gICAgICBmb3IgKHZhciBmaXJzdCA9IHRydWU7OyBmaXJzdCA9IGZhbHNlKSB7XG4gICAgICAgIGlmIChkaXIgPCAwICYmICFtb3ZlT25jZSghZmlyc3QpKSBicmVhaztcbiAgICAgICAgdmFyIGN1ciA9IGxpbmVPYmoudGV4dC5jaGFyQXQoY2gpIHx8IFwiXFxuXCI7XG4gICAgICAgIHZhciB0eXBlID0gaXNXb3JkQ2hhcihjdXIsIGhlbHBlcikgPyBcIndcIlxuICAgICAgICAgIDogZ3JvdXAgJiYgY3VyID09IFwiXFxuXCIgPyBcIm5cIlxuICAgICAgICAgIDogIWdyb3VwIHx8IC9cXHMvLnRlc3QoY3VyKSA/IG51bGxcbiAgICAgICAgICA6IFwicFwiO1xuICAgICAgICBpZiAoZ3JvdXAgJiYgIWZpcnN0ICYmICF0eXBlKSB0eXBlID0gXCJzXCI7XG4gICAgICAgIGlmIChzYXdUeXBlICYmIHNhd1R5cGUgIT0gdHlwZSkge1xuICAgICAgICAgIGlmIChkaXIgPCAwKSB7ZGlyID0gMTsgbW92ZU9uY2UoKTt9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSkgc2F3VHlwZSA9IHR5cGU7XG4gICAgICAgIGlmIChkaXIgPiAwICYmICFtb3ZlT25jZSghZmlyc3QpKSBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIHJlc3VsdCA9IHNraXBBdG9taWMoZG9jLCBQb3MobGluZSwgY2gpLCBvcmlnRGlyLCB0cnVlKTtcbiAgICBpZiAoIXBvc3NpYmxlKSByZXN1bHQuaGl0U2lkZSA9IHRydWU7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIEZvciByZWxhdGl2ZSB2ZXJ0aWNhbCBtb3ZlbWVudC4gRGlyIG1heSBiZSAtMSBvciAxLiBVbml0IGNhbiBiZVxuICAvLyBcInBhZ2VcIiBvciBcImxpbmVcIi4gVGhlIHJlc3VsdGluZyBwb3NpdGlvbiB3aWxsIGhhdmUgYSBoaXRTaWRlPXRydWVcbiAgLy8gcHJvcGVydHkgaWYgaXQgcmVhY2hlZCB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudC5cbiAgZnVuY3Rpb24gZmluZFBvc1YoY20sIHBvcywgZGlyLCB1bml0KSB7XG4gICAgdmFyIGRvYyA9IGNtLmRvYywgeCA9IHBvcy5sZWZ0LCB5O1xuICAgIGlmICh1bml0ID09IFwicGFnZVwiKSB7XG4gICAgICB2Y
23459XIgcGFnZVNpemUgPSBNYXRoLm1pbihjbS5kaXNwbGF5LndyYXBwZXIuY2xpZW50SGVpZ2h0LCB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCk7XG4gICAgICB5ID0gcG9zLnRvcCArIGRpciAqIChwYWdlU2l6ZSAtIChkaXIgPCAwID8gMS41IDogLjUpICogdGV4dEhlaWdodChjbS5kaXNwbGF5KSk7XG4gICAgfSBlbHNlIGlmICh1bml0ID09IFwibGluZVwiKSB7XG4gICAgICB5ID0gZGlyID4gMCA/IHBvcy5ib3R0b20gKyAzIDogcG9zLnRvcCAtIDM7XG4gICAgfVxuICAgIGZvciAoOzspIHtcbiAgICAgIHZhciB0YXJnZXQgPSBjb29yZHNDaGFyKGNtLCB4LCB5KTtcbiAgICAgIGlmICghdGFyZ2V0Lm91dHNpZGUpIGJyZWFrO1xuICAgICAgaWYgKGRpciA8IDAgPyB5IDw9IDAgOiB5ID49IGRvYy5oZWlnaHQpIHsgdGFyZ2V0LmhpdFNpZGUgPSB0cnVlOyBicmVhazsgfVxuICAgICAgeSArPSBkaXIgKiA1O1xuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG5cbiAgLy8gRURJVE9SIE1FVEhPRFNcblxuICAvLyBUaGUgcHVibGljbHkgdmlzaWJsZSBBUEkuIE5vdGUgdGhhdCBtZXRob2RPcChmKSBtZWFuc1xuICAvLyAnd3JhcCBmIGluIGFuIG9wZXJhdGlvbiwgcGVyZm9ybWVkIG9uIGl0cyBgdGhpc2AgcGFyYW1ldGVyJy5cblxuICAvLyBUaGlzIGlzIG5vdCB0aGUgY29tcGxldGUgc2V0IG9mIGVkaXRvciBtZXRob2RzLiBNb3N0IG9mIHRoZVxuICAvLyBtZXRob2RzIGRlZmluZWQgb24gdGhlIERvYyB0eXBlIGFyZSBhbHNvIGluamVjdGVkIGludG9cbiAgLy8gQ29kZU1pcnJvci5wcm90b3R5cGUsIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBhbmRcbiAgLy8gY29udmVuaWVuY2UuXG5cbiAgQ29kZU1pcnJvci5wcm90b3R5cGUgPSB7XG4gICAgY29uc3RydWN0b3I6IENvZGVNaXJyb3IsXG4gICAgZm9jdXM6IGZ1bmN0aW9uKCl7d2luZG93LmZvY3VzKCk7IHRoaXMuZGlzcGxheS5pbnB1dC5mb2N1cygpO30sXG5cbiAgICBzZXRPcHRpb246IGZ1bmN0aW9uKG9wdGlvbiwgdmFsdWUpIHtcbiAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zLCBvbGQgPSBvcHRpb25zW29wdGlvbl07XG4gICAgICBpZiAob3B0aW9uc1tvcHRpb25dID09IHZhbHVlICYmIG9wdGlvbiAhPSBcIm1vZGVcIikgcmV0dXJuO1xuICAgICAgb3B0aW9uc1tvcHRpb25dID0gdmFsdWU7XG4gICAgICBpZiAob3B0aW9uSGFuZGxlcnMuaGFzT3duUHJvcGVydHkob3B0aW9uKSlcbiAgICAgICAgb3BlcmF0aW9uKHRoaXMsIG9wdGlvbkhhbmRsZXJzW29wdGlvbl0pKHRoaXMsIHZhbHVlLCBvbGQpO1xuICAgIH0sXG5cbiAgICBnZXRPcHRpb246IGZ1bmN0aW9uKG9wdGlvbikge3JldHVybiB0aGlzLm9wdGlvbnNbb3B0aW9uXTt9LFxuICAgIGdldERvYzogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMuZG9jO30sXG5cbiAgICBhZGRLZXlNYXA6IGZ1bmN0aW9uKG1hcCwgYm90dG9tKSB7XG4gICAgICB0aGlzLnN0YXRlLmtleU1hcHNbYm90dG9tID8gXCJwdXNoXCIgOiBcInVuc2hpZnRcIl0oZ2V0S2V5TWFwKG1hcCkpO1xuICAgIH0sXG4gICAgcmVtb3ZlS2V5TWFwOiBmdW5jdGlvbihtYXApIHtcbiAgICAgIHZhciBtYXBzID0gdGhpcy5zdGF0ZS5rZXlNYXBzO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXBzLmxlbmd0aDsgKytpKVxuICAgICAgICBpZiAobWFwc1tpXSA9PSBtYXAgfHwgbWFwc1tpXS5uYW1lID09IG1hcCkge1xuICAgICAgICAgIG1hcHMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGFkZE92ZXJsYXk6IG1ldGhvZE9wKGZ1bmN0aW9uKHNwZWMsIG9wdGlvbnMpIHtcbiAgICAgIHZhciBtb2RlID0gc3BlYy50b2tlbiA/IHNwZWMgOiBDb2RlTWlycm9yLmdldE1vZGUodGhpcy5vcHRpb25zLCBzcGVjKTtcbiAgICAgIGlmIChtb2RlLnN0YXJ0U3RhdGUpIHRocm93IG5ldyBFcnJvcihcIk92ZXJsYXlzIG1heSBub3QgYmUgc3RhdGVmdWwuXCIpO1xuICAgICAgdGhpcy5zdGF0ZS5vdmVybGF5cy5wdXNoKHttb2RlOiBtb2RlLCBtb2RlU3BlYzogc3BlYywgb3BhcXVlOiBvcHRpb25zICYmIG9wdGlvbnMub3BhcXVlfSk7XG4gICAgICB0aGlzLnN0YXRlLm1vZGVHZW4rKztcbiAgICAgIHJlZ0NoYW5nZSh0aGlzKTtcbiAgICB9KSxcbiAgICByZW1vdmVPdmVybGF5OiBtZXRob2RPcChmdW5jdGlvbihzcGVjKSB7XG4gICAgICB2Y
23459XIgb3ZlcmxheXMgPSB0aGlzLnN0YXRlLm92ZXJsYXlzO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdmVybGF5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgY3VyID0gb3ZlcmxheXNbaV0ubW9kZVNwZWM7XG4gICAgICAgIGlmIChjdXIgPT0gc3BlYyB8fCB0eXBlb2Ygc3BlYyA9PSBcInN0cmluZ1wiICYmIGN1ci5uYW1lID09IHNwZWMpIHtcbiAgICAgICAgICBvdmVybGF5cy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgdGhpcy5zdGF0ZS5tb2RlR2VuKys7XG4gICAgICAgICAgcmVnQ2hhbmdlKHRoaXMpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pLFxuXG4gICAgaW5kZW50TGluZTogbWV0aG9kT3AoZnVuY3Rpb24obiwgZGlyLCBhZ2dyZXNzaXZlKSB7XG4gICAgICBpZiAodHlwZW9mIGRpciAhPSBcInN0cmluZ1wiICYmIHR5cGVvZiBkaXIgIT0gXCJudW1iZXJcIikge1xuICAgICAgICBpZiAoZGlyID09IG51bGwpIGRpciA9IHRoaXMub3B0aW9ucy5zbWFydEluZGVudCA/IFwic21hcnRcIiA6IFwicHJldlwiO1xuICAgICAgICBlbHNlIGRpciA9IGRpciA/IFwiYWRkXCIgOiBcInN1YnRyYWN0XCI7XG4gICAgICB9XG4gICAgICBpZiAoaXNMaW5lKHRoaXMuZG9jLCBuKSkgaW5kZW50TGluZSh0aGlzLCBuLCBkaXIsIGFnZ3Jlc3NpdmUpO1xuICAgIH0pLFxuICAgIGluZGVudFNlbGVjdGlvbjogbWV0aG9kT3AoZnVuY3Rpb24oaG93KSB7XG4gICAgICB2YXIgcmFuZ2VzID0gdGhpcy5kb2Muc2VsLnJhbmdlcywgZW5kID0gLTE7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2Y
23459XIgcmFuZ2UgPSByYW5nZXNbaV07XG4gICAgICAgIGlmICghcmFuZ2UuZW1wdHkoKSkge1xuICAgICAgICAgIHZhciBmcm9tID0gcmFuZ2UuZnJvbSgpLCB0byA9IHJhbmdlLnRvKCk7XG4gICAgICAgICAgdmFyIHN0YXJ0ID0gTWF0aC5tYXgoZW5kLCBmcm9tLmxpbmUpO1xuICAgICAgICAgIGVuZCA9IE1hdGgubWluKHRoaXMubGFzdExpbmUoKSwgdG8ubGluZSAtICh0by5jaCA/IDAgOiAxKSkgKyAxO1xuICAgICAgICAgIGZvciAodmFyIGogPSBzdGFydDsgaiA8IGVuZDsgKytqKVxuICAgICAgICAgICAgaW5kZW50TGluZSh0aGlzLCBqLCBob3cpO1xuICAgICAgICAgIHZhciBuZXdSYW5nZXMgPSB0aGlzLmRvYy5zZWwucmFuZ2VzO1xuICAgICAgICAgIGlmIChmcm9tLmNoID09IDAgJiYgcmFuZ2VzLmxlbmd0aCA9PSBuZXdSYW5nZXMubGVuZ3RoICYmIG5ld1Jhbmdlc1tpXS5mcm9tKCkuY2ggPiAwKVxuICAgICAgICAgICAgcmVwbGFjZU9uZVNlbGVjdGlvbih0aGlzLmRvYywgaSwgbmV3IFJhbmdlKGZyb20sIG5ld1Jhbmdlc1tpXS50bygpKSwgc2VsX2RvbnRTY3JvbGwpO1xuICAgICAgICB9IGVsc2UgaWYgKHJhbmdlLmhlYWQubGluZSA+IGVuZCkge1xuICAgICAgICAgIGluZGVudExpbmUodGhpcywgcmFuZ2UuaGVhZC5saW5lLCBob3csIHRydWUpO1xuICAgICAgICAgIGVuZCA9IHJhbmdlLmhlYWQubGluZTtcbiAgICAgICAgICBpZiAoaSA9PSB0aGlzLmRvYy5zZWwucHJpbUluZGV4KSBlbnN1cmVDdXJzb3JWaXNpYmxlKHRoaXMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSksXG5cbiAgICAvLyBGZXRjaCB0aGUgcGFyc2VyIHRva2VuIGZvciBhIGdpdmVuIGNoYXJhY3Rlci4gVXNlZnVsIGZvciBoYWNrc1xuICAgIC8vIHRoYXQgd2FudCB0byBpbnNwZWN0IHRoZSBtb2RlIHN0YXRlIChzYXksIGZvciBjb21wbGV0aW9uKS5cbiAgICBnZXRUb2tlbkF0OiBmdW5jdGlvbihwb3MsIHByZWNpc2UpIHtcbiAgICAgIHJldHVybiB0YWtlVG9rZW4odGhpcywgcG9zLCBwcmVjaXNlKTtcbiAgICB9LFxuXG4gICAgZ2V0TGluZVRva2VuczogZnVuY3Rpb24obGluZSwgcHJlY2lzZSkge1xuICAgICAgcmV0dXJuIHRha2VUb2tlbih0aGlzLCBQb3MobGluZSksIHByZWNpc2UsIHRydWUpO1xuICAgIH0sXG5cbiAgICBnZXRUb2tlblR5cGVBdDogZnVuY3Rpb24ocG9zKSB7XG4gICAgICBwb3MgPSBjbGlwUG9zKHRoaXMuZG9jLCBwb3MpO1xuICAgICAgdmFyIHN0eWxlcyA9IGdldExpbmVTdHlsZXModGhpcywgZ2V0TGluZSh0aGlzLmRvYywgcG9zLmxpbmUpKTtcbiAgICAgIHZhciBiZWZvcmUgPSAwLCBhZnRlciA9IChzdHlsZXMubGVuZ3RoIC0gMSkgLyAyLCBjaCA9IHBvcy5jaDtcbiAgICAgIHZhciB0eXBlO1xuICAgICAgaWYgKGNoID09IDApIHR5cGUgPSBzdHlsZXNbMl07XG4gICAgICBlbHNlIGZvciAoOzspIHtcbiAgICAgICAgdmFyIG1pZCA9IChiZWZvcmUgKyBhZnRlcikgPj4gMTtcbiAgICAgICAgaWYgKChtaWQgPyBzdHlsZXNbbWlkICogMiAtIDFdIDogMCkgPj0gY2gpIGFmdGVyID0gbWlkO1xuICAgICAgICBlbHNlIGlmIChzdHlsZXNbbWlkICogMiArIDFdIDwgY2gpIGJlZm9yZSA9IG1pZCArIDE7XG4gICAgICAgIGVsc2UgeyB0eXBlID0gc3R5bGVzW21pZCAqIDIgKyAyXTsgYnJlYWs7IH1cbiAgICAgIH1cbiAgICAgIHZhciBjdXQgPSB0eXBlID8gdHlwZS5pbmRleE9mKFwiY20tb3ZlcmxheSBcIikgOiAtMTtcbiAgICAgIHJldHVybiBjdXQgPCAwID8gdHlwZSA6IGN1dCA9PSAwID8gbnVsbCA6IHR5cGUuc2xpY2UoMCwgY3V0IC0gMSk7XG4gICAgfSxcblxuICAgIGdldE1vZGVBdDogZnVuY3Rpb24ocG9zKSB7XG4gICAgICB2Y
23459XIgbW9kZSA9IHRoaXMuZG9jLm1vZGU7XG4gICAgICBpZiAoIW1vZGUuaW5uZXJNb2RlKSByZXR1cm4gbW9kZTtcbiAgICAgIHJldHVybiBDb2RlTWlycm9yLmlubmVyTW9kZShtb2RlLCB0aGlzLmdldFRva2VuQXQocG9zKS5zdGF0ZSkubW9kZTtcbiAgICB9LFxuXG4gICAgZ2V0SGVscGVyOiBmdW5jdGlvbihwb3MsIHR5cGUpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEhlbHBlcnMocG9zLCB0eXBlKVswXTtcbiAgICB9LFxuXG4gICAgZ2V0SGVscGVyczogZnVuY3Rpb24ocG9zLCB0eXBlKSB7XG4gICAgICB2YXIgZm91bmQgPSBbXTtcbiAgICAgIGlmICghaGVscGVycy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkgcmV0dXJuIGZvdW5kO1xuICAgICAgdmFyIGhlbHAgPSBoZWxwZXJzW3R5cGVdLCBtb2RlID0gdGhpcy5nZXRNb2RlQXQocG9zKTtcbiAgICAgIGlmICh0eXBlb2YgbW9kZVt0eXBlXSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGlmIChoZWxwW21vZGVbdHlwZV1dKSBmb3VuZC5wdXNoKGhlbHBbbW9kZVt0eXBlXV0pO1xuICAgICAgfSBlbHNlIGlmIChtb2RlW3R5cGVdKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbW9kZVt0eXBlXS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciB2YWwgPSBoZWxwW21vZGVbdHlwZV1baV1dO1xuICAgICAgICAgIGlmICh2YWwpIGZvdW5kLnB1c2godmFsKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChtb2RlLmhlbHBlclR5cGUgJiYgaGVscFttb2RlLmhlbHBlclR5cGVdKSB7XG4gICAgICAgIGZvdW5kLnB1c2goaGVscFttb2RlLmhlbHBlclR5cGVdKTtcbiAgICAgIH0gZWxzZSBpZiAoaGVscFttb2RlLm5hbWVdKSB7XG4gICAgICAgIGZvdW5kLnB1c2goaGVscFttb2RlLm5hbWVdKTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGVscC5fZ2xvYmFsLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjdXIgPSBoZWxwLl9nbG9iYWxbaV07XG4gICAgICAgIGlmIChjdXIucHJlZChtb2RlLCB0aGlzKSAmJiBpbmRleE9mKGZvdW5kLCBjdXIudmFsKSA9PSAtMSlcbiAgICAgICAgICBmb3VuZC5wdXNoKGN1ci52YWwpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZvdW5kO1xuICAgIH0sXG5cbiAgICBnZXRTdGF0ZUFmdGVyOiBmdW5jdGlvbihsaW5lLCBwcmVjaXNlKSB7XG4gICAgICB2Y
23459XIgZG9jID0gdGhpcy5kb2M7XG4gICAgICBsaW5lID0gY2xpcExpbmUoZG9jLCBsaW5lID09IG51bGwgPyBkb2MuZmlyc3QgKyBkb2Muc2l6ZSAtIDE6IGxpbmUpO1xuICAgICAgcmV0dXJuIGdldFN0YXRlQmVmb3JlKHRoaXMsIGxpbmUgKyAxLCBwcmVjaXNlKTtcbiAgICB9LFxuXG4gICAgY3Vyc29yQ29vcmRzOiBmdW5jdGlvbihzdGFydCwgbW9kZSkge1xuICAgICAgdmFyIHBvcywgcmFuZ2UgPSB0aGlzLmRvYy5zZWwucHJpbWFyeSgpO1xuICAgICAgaWYgKHN0YXJ0ID09IG51bGwpIHBvcyA9IHJhbmdlLmhlYWQ7XG4gICAgICBlbHNlIGlmICh0eXBlb2Ygc3RhcnQgPT0gXCJvYmplY3RcIikgcG9zID0gY2xpcFBvcyh0aGlzLmRvYywgc3RhcnQpO1xuICAgICAgZWxzZSBwb3MgPSBzdGFydCA/IHJhbmdlLmZyb20oKSA6IHJhbmdlLnRvKCk7XG4gICAgICByZXR1cm4gY3Vyc29yQ29vcmRzKHRoaXMsIHBvcywgbW9kZSB8fCBcInBhZ2VcIik7XG4gICAgfSxcblxuICAgIGNoYXJDb29yZHM6IGZ1bmN0aW9uKHBvcywgbW9kZSkge1xuICAgICAgcmV0dXJuIGNoYXJDb29yZHModGhpcywgY2xpcFBvcyh0aGlzLmRvYywgcG9zKSwgbW9kZSB8fCBcInBhZ2VcIik7XG4gICAgfSxcblxuICAgIGNvb3Jkc0NoYXI6IGZ1bmN0aW9uKGNvb3JkcywgbW9kZSkge1xuICAgICAgY29vcmRzID0gZnJvbUNvb3JkU3lzdGVtKHRoaXMsIGNvb3JkcywgbW9kZSB8fCBcInBhZ2VcIik7XG4gICAgICByZXR1cm4gY29vcmRzQ2hhcih0aGlzLCBjb29yZHMubGVmdCwgY29vcmRzLnRvcCk7XG4gICAgfSxcblxuICAgIGxpbmVBdEhlaWdodDogZnVuY3Rpb24oaGVpZ2h0LCBtb2RlKSB7XG4gICAgICBoZWlnaHQgPSBmcm9tQ29vcmRTeXN0ZW0odGhpcywge3RvcDogaGVpZ2h0LCBsZWZ0OiAwfSwgbW9kZSB8fCBcInBhZ2VcIikudG9wO1xuICAgICAgcmV0dXJuIGxpbmVBdEhlaWdodCh0aGlzLmRvYywgaGVpZ2h0ICsgdGh
23459pcy5kaXNwbGF5LnZpZXdPZmZzZXQpO1xuICAgIH0sXG4gICAgaGVpZ2h0QXRMaW5lOiBmdW5jdGlvbihsaW5lLCBtb2RlKSB7XG4gICAgICB2YXIgZW5kID0gZmFsc2UsIGxpbmVPYmo7XG4gICAgICBpZiAodHlwZW9mIGxpbmUgPT0gXCJudW1iZXJcIikge1xuICAgICAgICB2YXIgbGFzdCA9IHRoaXMuZG9jLmZpcnN0ICsgdGhpcy5kb2Muc2l6ZSAtIDE7XG4gICAgICAgIGlmIChsaW5lIDwgdGhpcy5kb2MuZmlyc3QpIGxpbmUgPSB0aGlzLmRvYy5maXJzdDtcbiAgICAgICAgZWxzZSBpZiAobGluZSA+IGxhc3QpIHsgbGluZSA9IGxhc3Q7IGVuZCA9IHRydWU7IH1cbiAgICAgICAgbGluZU9iaiA9IGdldExpbmUodGhpcy5kb2MsIGxpbmUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGluZU9iaiA9IGxpbmU7XG4gICAgICB9XG4gICAgICByZXR1cm4gaW50b0Nvb3JkU3lzdGVtKHRoaXMsIGxpbmVPYmosIHt0b3A6IDAsIGxlZnQ6IDB9LCBtb2RlIHx8IFwicGFnZVwiKS50b3AgK1xuICAgICAgICAoZW5kID8gdGhpcy5kb2MuaGVpZ2h0IC0gaGVpZ2h0QXRMaW5lKGxpbmVPYmopIDogMCk7XG4gICAgfSxcblxuICAgIGRlZmF1bHRUZXh0SGVpZ2h0OiBmdW5jdGlvbigpIHsgcmV0dXJuIHRleHRIZWlnaHQodGhpcy5kaXNwbGF5KTsgfSxcbiAgICBkZWZhdWx0Q2hhcldpZHRoOiBmdW5jdGlvbigpIHsgcmV0dXJuIGNoYXJXaWR0aCh0aGlzLmRpc3BsYXkpOyB9LFxuXG4gICAgc2V0R3V0dGVyTWFya2VyOiBtZXRob2RPcChmdW5jdGlvbihsaW5lLCBndXR0ZXJJRCwgdmFsdWUpIHtcbiAgICAgIHJldHVybiBjaGFuZ2VMaW5lKHRoaXMuZG9jLCBsaW5lLCBcImd1dHRlclwiLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgIHZhciBtYXJrZXJzID0gbGluZS5ndXR0ZXJNYXJrZXJzIHx8IChsaW5lLmd1dHRlck1hcmtlcnMgPSB7fSk7XG4gICAgICAgIG1hcmtlcnNbZ3V0dGVySURdID0gdmFsdWU7XG4gICAgICAgIGlmICghdmFsdWUgJiYgaXNFbXB0eShtY
23459XJrZXJzKSkgbGluZS5ndXR0ZXJNYXJrZXJzID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9KTtcbiAgICB9KSxcblxuICAgIGNsZWFyR3V0dGVyOiBtZXRob2RPcChmdW5jdGlvbihndXR0ZXJJRCkge1xuICAgICAgdmFyIGNtID0gdGhpcywgZG9jID0gY20uZG9jLCBpID0gZG9jLmZpcnN0O1xuICAgICAgZG9jLml0ZXIoZnVuY3Rpb24obGluZSkge1xuICAgICAgICBpZiAobGluZS5ndXR0ZXJNYXJrZXJzICYmIGxpbmUuZ3V0dGVyTWFya2Vyc1tndXR0ZXJJRF0pIHtcbiAgICAgICAgICBsaW5lLmd1dHRlck1hcmtlcnNbZ3V0dGVySURdID0gbnVsbDtcbiAgICAgICAgICByZWdMaW5lQ2hhbmdlKGNtLCBpLCBcImd1dHRlclwiKTtcbiAgICAgICAgICBpZiAoaXNFbXB0eShsaW5lLmd1dHRlck1hcmtlcnMpKSBsaW5lLmd1dHRlck1hcmtlcnMgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgICsraTtcbiAgICAgIH0pO1xuICAgIH0pLFxuXG4gICAgbGluZUluZm86IGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgIGlmICh0eXBlb2YgbGluZSA9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIGlmICghaXNMaW5lKHRoaXMuZG9jLCBsaW5lKSkgcmV0dXJuIG51bGw7XG4gICAgICAgIHZhciBuID0gbGluZTtcbiAgICAgICAgbGluZSA9IGdldExpbmUodGhpcy5kb2MsIGxpbmUpO1xuICAgICAgICBpZiAoIWxpbmUpIHJldHVybiBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIG4gPSBsaW5lTm8obGluZSk7XG4gICAgICAgIGlmIChuID09IG51bGwpIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtsaW5lOiBuLCBoYW5kbGU6IGxpbmUsIHRleHQ6IGxpbmUudGV4dCwgZ3V0dGVyTWFya2VyczogbGluZS5ndXR0ZXJNYXJrZXJzLFxuICAgICAgICAgICAgICB0ZXh0Q2xhc3M6IGxpbmUudGV4dENsYXNzLCBiZ0NsYXNzOiBsaW5lLmJnQ2xhc3MsIHdyYXBDbGFzczogbGluZS53cmFwQ2xhc3MsXG4gICAgICAgICAgICAgIHdpZGdldHM6IGxpbmUud2lkZ2V0c307XG4gICAgfSxcblxuICAgIGdldFZpZXdwb3J0OiBmdW5jdGlvbigpIHsgcmV0dXJuIHtmcm9tOiB0aGlzLmRpc3BsYXkudmlld0Zyb20sIHRvOiB0aGlzLmRpc3BsYXkudmlld1RvfTt9LFxuXG4gICAgYWRkV2lkZ2V0OiBmdW5jdGlvbihwb3MsIG5vZGUsIHNjcm9sbCwgdmVydCwgaG9yaXopIHtcbiAgICAgIHZhciBkaXNwbGF5ID0gdGhpcy5kaXNwbGF5O1xuICAgICAgcG9zID0gY3Vyc29yQ29vcmRzKHRoaXMsIGNsaXBQb3ModGhpcy5kb2MsIHBvcykpO1xuICAgICAgdmFyIHRvcCA9IHBvcy5ib3R0b20sIGxlZnQgPSBwb3MubGVmdDtcbiAgICAgIG5vZGUuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7XG4gICAgICBub2RlLnNldEF0dHJpYnV0ZShcImNtLWlnbm9yZS1ldmVud
23459HNcIiwgXCJ0cnVlXCIpO1xuICAgICAgdGhpcy5kaXNwbGF5LmlucHV0LnNldFVuZWRpdGFibGUobm9kZSk7XG4gICAgICBkaXNwbGF5LnNpemVyLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgaWYgKHZlcnQgPT0gXCJvdmVyXCIpIHtcbiAgICAgICAgdG9wID0gcG9zLnRvcDtcbiAgICAgIH0gZWxzZSBpZiAodmVydCA9PSBcImFib3ZlXCIgfHwgdmVydCA9PSBcIm5lYXJcIikge1xuICAgICAgICB2YXIgdnNwYWNlID0gTWF0aC5tYXgoZGlzcGxheS53cmFwcGVyLmNsaWVudEhlaWdodCwgdGhpcy5kb2MuaGVpZ2h0KSxcbiAgICAgICAgaHNwYWNlID0gTWF0aC5tYXgoZGlzcGxheS5zaXplci5jbGllbnRXaWR0aCwgZGlzcGxheS5saW5lU3BhY2UuY2xpZW50V2lkdGgpO1xuICAgICAgICAvLyBEZWZhdWx0IHRvIHBvc2l0aW9uaW5nIGFib3ZlIChpZiBzcGVjaWZpZWQgYW5kIHBvc3NpYmxlKTsgb3RoZXJ3aXNlIGRlZmF1bHQgdG8gcG9zaXRpb25pbmcgYmVsb3dcbiAgICAgICAgaWYgKCh2ZXJ0ID09ICdhYm92ZScgfHwgcG9zLmJvdHRvbSArIG5vZGUub2Zmc2V0SGVpZ2h0ID4gdnNwYWNlKSAmJiBwb3MudG9wID4gbm9kZS5vZmZzZXRIZWlnaHQpXG4gICAgICAgICAgdG9wID0gcG9zLnRvcCAtIG5vZGUub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBlbHNlIGlmIChwb3MuYm90dG9tICsgbm9kZS5vZmZzZXRIZWlnaHQgPD0gdnNwYWNlKVxuICAgICAgICAgIHRvcCA9IHBvcy5ib3R0b207XG4gICAgICAgIGlmIChsZWZ0ICsgbm9kZS5vZmZzZXRXaWR0aCA+IGhzcGFjZSlcbiAgICAgICAgICBsZWZ0ID0gaHNwYWNlIC0gbm9kZS5vZmZzZXRXaWR0aDtcbiAgICAgIH1cbiAgICAgIG5vZGUuc3R5bGUudG9wID0gdG9wICsgXCJweFwiO1xuICAgICAgbm9kZS5zdHlsZS5sZWZ0ID0gbm9kZS5zdHlsZS5yaWdodCA9IFwiXCI7XG4gICAgICBpZiAoaG9yaXogPT0gXCJyaWdodFwiKSB7XG4gICAgICAgIGxlZnQgPSBkaXNwbGF5LnNpemVyLmNsaWVudFdpZHRoIC0gbm9kZS5vZmZzZXRXaWR0aDtcbiAgICAgICAgbm9kZS5zdHlsZS5yaWdodCA9IFwiMHB4XCI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaG9yaXogPT0gXCJsZWZ0XCIpIGxlZnQgPSAwO1xuICAgICAgICBlbHNlIGlmIChob3JpeiA9PSBcIm1pZGRsZVwiKSBsZWZ0ID0gKGRpc3BsYXkuc2l6ZXIuY2xpZW50V2lkdGggLSBub2RlLm9mZnNldFdpZHRoKSAvIDI7XG4gICAgICAgIG5vZGUuc3R5bGUubGVmdCA9IGxlZnQgKyBcInB4XCI7XG4gICAgICB9XG4gICAgICBpZiAoc2Nyb2xsKVxuICAgICAgICBzY3JvbGxJbnRvVmlldyh0aGlzLCBsZWZ0LCB0b3AsIGxlZnQgKyBub2RlLm9mZnNldFdpZHRoLCB0b3AgKyBub2RlLm9mZnNldEhlaWdodCk7XG4gICAgfSxcblxuICAgIHRyaWdnZXJPbktleURvd246IG1ldGhvZE9wKG9uS2V5RG93biksXG4gICAgdHJpZ2dlck9uS2V5UHJlc3M6IG1ldGhvZE9wKG9uS2V5UHJlc3MpLFxuICAgIHRyaWdnZXJPbktleVVwOiBvbktleVVwLFxuXG4gICAgZXhlY0NvbW1hbmQ6IGZ1bmN0aW9uKGNtZCkge1xuICAgICAgaWYgKGNvbW1hbmRzLmhhc093blByb3BlcnR5KGNtZCkpXG4gICAgICAgIHJldHVybiBjb21tYW5kc1tjbWRdLmNhbGwobnVsbCwgdGhpcyk7XG4gICAgfSxcblxuICAgIHRyaWdnZXJFbGVjdHJpYzogbWV0aG9kT3AoZnVuY3Rpb24odGV4dCkgeyB0cmlnZ2VyRWxlY3RyaWModGhpcywgdGV4dCk7IH0pLFxuXG4gICAgZmluZFBvc0g6IGZ1bmN0aW9uKGZyb20sIGFtb3VudCwgdW5pdCwgdmlzdWFsbHkpIHtcbiAgICAgIHZhciBkaXIgPSAxO1xuICAgICAgaWYgKGFtb3VudCA8IDApIHsgZGlyID0gLTE7IGFtb3VudCA9IC1hbW91bnQ7IH1cbiAgICAgIGZvciAodmFyIGkgPSAwLCBjdXIgPSBjbGlwUG9zKHRoaXMuZG9jLCBmcm9tKTsgaSA8IGFtb3VudDsgKytpKSB7XG4gICAgICAgIGN1ciA9IGZpbmRQb3NIKHRoaXMuZG9jLCBjdXIsIGRpciwgdW5pdCwgdmlzdWFsbHkpO1xuICAgICAgICBpZiAoY3VyLmhpdFNpZGUpIGJyZWFrO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGN1cjtcbiAgICB9LFxuXG4gICAgbW92ZUg6IG1ldGhvZE9wKGZ1bmN0aW9uKGRpciwgdW5pdCkge1xuICAgICAgdmFyIGNtID0gdGhpcztcbiAgICAgIGNtLmV4dGVuZFNlbGVjdGlvbnNCeShmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICBpZiAoY20uZGlzcGxheS5zaGlmdCB8fCBjbS5kb2MuZXh0ZW5kIHx8IHJhbmdlLmVtcHR5KCkpXG4gICAgICAgICAgcmV0dXJuIGZpbmRQb3NIKGNtLmRvYywgcmFuZ2UuaGVhZCwgZGlyLCB1bml0LCBjbS5vcHRpb25zLnJ0bE1vdmVWaXN1YWxseSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICByZXR1cm4gZGlyIDwgMCA/IHJhbmdlLmZyb20oKSA6IHJhbmdlLnRvKCk7XG4gICAgICB9LCBzZWxfbW92ZSk7XG4gICAgfSksXG5cbiAgICBkZWxldGVIOiBtZXRob2RPcChmdW5jdGlvbihkaXIsIHVuaXQpIHtcbiAgICAgIHZhciBzZWwgPSB0aGlzLmRvYy5zZWwsIGRvYyA9IHRoaXMuZG9jO1xuICAgICAgaWYgKHNlbC5zb21ldGhpbmdTZWxlY3RlZCgpKVxuICAgICAgICBkb2MucmVwbGFjZVNlbGVjdGlvbihcIlwiLCBudWxsLCBcIitkZWxldGVcIik7XG4gICAgICBlbHNlXG4gICAgICAgIGRlbGV0ZU5lYXJTZWxlY3Rpb24odGhpcywgZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgICAgICB2Y
23459XIgb3RoZXIgPSBmaW5kUG9zSChkb2MsIHJhbmdlLmhlYWQsIGRpciwgdW5pdCwgZmFsc2UpO1xuICAgICAgICAgIHJldHVybiBkaXIgPCAwID8ge2Zyb206IG90aGVyLCB0bzogcmFuZ2UuaGVhZH0gOiB7ZnJvbTogcmFuZ2UuaGVhZCwgdG86IG90aGVyfTtcbiAgICAgICAgfSk7XG4gICAgfSksXG5cbiAgICBmaW5kUG9zVjogZnVuY3Rpb24oZnJvbSwgYW1vdW50LCB1bml0LCBnb2FsQ29sdW1uKSB7XG4gICAgICB2YXIgZGlyID0gMSwgeCA9IGdvYWxDb2x1bW47XG4gICAgICBpZiAoYW1vdW50IDwgMCkgeyBkaXIgPSAtMTsgYW1vdW50ID0gLWFtb3VudDsgfVxuICAgICAgZm9yICh2YXIgaSA9IDAsIGN1ciA9IGNsaXBQb3ModGhpcy5kb2MsIGZyb20pOyBpIDwgYW1vdW50OyArK2kpIHtcbiAgICAgICAgdmFyIGNvb3JkcyA9IGN1cnNvckNvb3Jkcyh0aGlzLCBjdXIsIFwiZGl2XCIpO1xuICAgICAgICBpZiAoeCA9PSBudWxsKSB4ID0gY29vcmRzLmxlZnQ7XG4gICAgICAgIGVsc2UgY29vcmRzLmxlZnQgPSB4O1xuICAgICAgICBjdXIgPSBmaW5kUG9zVih0aGlzLCBjb29yZHMsIGRpciwgdW5pdCk7XG4gICAgICAgIGlmIChjdXIuaGl0U2lkZSkgYnJlYWs7XG4gICAgICB9XG4gICAgICByZXR1cm4gY3VyO1xuICAgIH0sXG5cbiAgICBtb3ZlVjogbWV0aG9kT3AoZnVuY3Rpb24oZGlyLCB1bml0KSB7XG4gICAgICB2YXIgY20gPSB0aGlzLCBkb2MgPSB0aGlzLmRvYywgZ29hbHMgPSBbXTtcbiAgICAgIHZhciBjb2xsYXBzZSA9ICFjbS5kaXNwbGF5LnNoaWZ0ICYmICFkb2MuZXh0ZW5kICYmIGRvYy5zZWwuc29tZXRoaW5nU2VsZWN0ZWQoKTtcbiAgICAgIGRvYy5leHRlbmRTZWxlY3Rpb25zQnkoZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgICAgaWYgKGNvbGxhcHNlKVxuICAgICAgICAgIHJldHVybiBkaXIgPCAwID8gcmFuZ2UuZnJvbSgpIDogcmFuZ2UudG8oKTtcbiAgICAgICAgdmFyIGhlYWRQb3MgPSBjdXJzb3JDb29yZHMoY20sIHJhbmdlLmhlYWQsIFwiZGl2XCIpO1xuICAgICAgICBpZiAocmFuZ2UuZ29hbENvbHVtbiAhPSBudWxsKSBoZWFkUG9zLmxlZnQgPSByYW5nZS5nb2FsQ29sdW1uO1xuICAgICAgICBnb2Fscy5wdXNoKGhlYWRQb3MubGVmdCk7XG4gICAgICAgIHZhciBwb3MgPSBmaW5kUG9zVihjbSwgaGVhZFBvcywgZGlyLCB1bml0KTtcbiAgICAgICAgaWYgKHVuaXQgPT0gXCJwYWdlXCIgJiYgcmFuZ2UgPT0gZG9jLnNlbC5wcmltYXJ5KCkpXG4gICAgICAgICAgYWRkVG9TY3JvbGxQb3MoY20sIG51bGwsIGNoYXJDb29yZHMoY20sIHBvcywgXCJkaXZcIikudG9wIC0gaGVhZFBvcy50b3ApO1xuICAgICAgICByZXR1cm4gcG9zO1xuICAgICAgfSwgc2VsX21vdmUpO1xuICAgICAgaWYgKGdvYWxzLmxlbmd0aCkgZm9yICh2YXIgaSA9IDA7IGkgPCBkb2Muc2VsLnJhbmdlcy5sZW5ndGg7IGkrKylcbiAgICAgICAgZG9jLnNlbC5yYW5nZXNbaV0uZ29hbENvbHVtbiA9IGdvYWxzW2ldO1xuICAgIH0pLFxuXG4gICAgLy8gRmluZCB0aGUgd29yZCBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24gKGFzIHJldHVybmVkIGJ5IGNvb3Jkc0NoYX
23459IpLlxuICAgIGZpbmRXb3JkQXQ6IGZ1bmN0aW9uKHBvcykge1xuICAgICAgdmFyIGRvYyA9IHRoaXMuZG9jLCBsaW5lID0gZ2V0TGluZShkb2MsIHBvcy5saW5lKS50ZXh0O1xuICAgICAgdmFyIHN0YXJ0ID0gcG9zLmNoLCBlbmQgPSBwb3MuY2g7XG4gICAgICBpZiAobGluZSkge1xuICAgICAgICB2YXIgaGVscGVyID0gdGhpcy5nZXRIZWxwZXIocG9zLCBcIndvcmRDaGFyc1wiKTtcbiAgICAgICAgaWYgKChwb3MueFJlbCA8IDAgfHwgZW5kID09IGxpbmUubGVuZ3RoKSAmJiBzdGFydCkgLS1zdGFydDsgZWxzZSArK2VuZDtcbiAgICAgICAgdmFyIHN0YXJ0Q2hhciA9IGxpbmUuY2hhckF0KHN0YXJ0KTtcbiAgICAgICAgdmFyIGNoZWNrID0gaXNXb3JkQ2hhcihzdGFydENoYXIsIGhlbHBlcilcbiAgICAgICAgICA/IGZ1bmN0aW9uKGNoKSB7IHJldHVybiBpc1dvcmRDaGFyKGNoLCBoZWxwZXIpOyB9XG4gICAgICAgICAgOiAvXFxzLy50ZXN0KHN0YXJ0Q2hhcikgPyBmdW5jdGlvbihjaCkge3JldHVybiAvXFxzLy50ZXN0KGNoKTt9XG4gICAgICAgICAgOiBmdW5jdGlvbihjaCkge3JldHVybiAhL1xccy8udGVzdChjaCkgJiYgIWlzV29yZENoYXIoY2gpO307XG4gICAgICAgIHdoaWxlIChzdGFydCA+IDAgJiYgY2hlY2sobGluZS5jaGFyQXQoc3RhcnQgLSAxKSkpIC0tc3RhcnQ7XG4gICAgICAgIHdoaWxlIChlbmQgPCBsaW5lLmxlbmd0aCAmJiBjaGVjayhsaW5lLmNoYXJBdChlbmQpKSkgKytlbmQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFJhbmdlKFBvcyhwb3MubGluZSwgc3RhcnQpLCBQb3MocG9zLmxpbmUsIGVuZCkpO1xuICAgIH0sXG5cbiAgICB0b2dnbGVPdmVyd3JpdGU6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiB2YWx1ZSA9PSB0aGlzLnN0YXRlLm92ZXJ3cml0ZSkgcmV0dXJuO1xuICAgICAgaWYgKHRoaXMuc3RhdGUub3ZlcndyaXRlID0gIXRoaXMuc3RhdGUub3ZlcndyaXRlKVxuICAgICAgICBhZGRDbGFzcyh0aGlzLmRpc3BsYXkuY3Vyc29yRGl2LCBcIkNvZGVNaXJyb3Itb3ZlcndyaXRlXCIpO1xuICAgICAgZWxzZVxuICAgICAgICBybUNsYXNzKHRoaXMuZGlzcGxheS5jdXJzb3JEaXYsIFwiQ29kZU1pcnJvci1vdmVyd3JpdGVcIik7XG5cbiAgICAgIHNpZ25hbCh0aGlzLCBcIm92ZXJ3cml0ZVRvZ2dsZVwiLCB0aGlzLCB0aGlzLnN0YXRlLm92ZXJ3cml0ZSk7XG4gICAgfSxcbiAgICBoYXNGb2N1czogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLmRpc3BsYXkuaW5wdXQuZ2V0RmllbGQoKSA9PSBhY3RpdmVFbHQoKTsgfSxcblxuICAgIHNjcm9sbFRvOiBtZXRob2RPcChmdW5jdGlvbih4LCB5KSB7XG4gICAgICBpZiAoeCAhPSBudWxsIHx8IHkgIT0gbnVsbCkgcmVzb2x2ZVNjcm9sbFRvUG9zKHRoaXMpO1xuICAgICAgaWYgKHggIT0gbnVsbCkgdGhpcy5jdXJPcC5zY3JvbGxMZWZ0ID0geDtcbiAgICAgIGlmICh5ICE9IG51bGwpIHRoaXMuY3VyT3Auc2Nyb2xsVG9wID0geTtcbiAgICB9KSxcbiAgICBnZXRTY3JvbGxJbmZvOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBzY3JvbGxlciA9IHRoaXMuZGlzcGxheS5zY3JvbGxlcjtcbiAgICAgIHJldHVybiB7bGVmdDogc2Nyb2xsZXIuc2Nyb2xsTGVmdCwgdG9wOiBzY3JvbGxlci5zY3JvbGxUb3AsXG4gICAgICAgICAgICAgIGhlaWdodDogc2Nyb2xsZXIuc2Nyb2xsSGVpZ2h0IC0gc2Nyb2xsR2FwKHRoaXMpIC0gdGhpcy5kaXNwbGF5LmJhckhlaWdodCxcbiAgICAgICAgICAgICAgd2lkdGg6IHNjcm9sbGVyLnNjcm9sbFdpZHR
23459oIC0gc2Nyb2xsR2FwKHRoaXMpIC0gdGhpcy5kaXNwbGF5LmJhcldpZHRoLFxuICAgICAgICAgICAgICBjbGllbnRIZWlnaHQ6IGRpc3BsYXlIZWlnaHQodGhpcyksIGNsaWVudFdpZHRoOiBkaXNwbGF5V2lkdGgodGhpcyl9O1xuICAgIH0sXG5cbiAgICBzY3JvbGxJbnRvVmlldzogbWV0aG9kT3AoZnVuY3Rpb24ocmFuZ2UsIG1hcmdpbikge1xuICAgICAgaWYgKHJhbmdlID09IG51bGwpIHtcbiAgICAgICAgcmFuZ2UgPSB7ZnJvbTogdGhpcy5kb2Muc2VsLnByaW1hcnkoKS5oZWFkLCB0bzogbnVsbH07XG4gICAgICAgIGlmIChtYXJnaW4gPT0gbnVsbCkgbWFyZ2luID0gdGhpcy5vcHRpb25zLmN1cnNvclNjcm9sbE1hcmdpbjtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHJhbmdlID09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgcmFuZ2UgPSB7ZnJvbTogUG9zKHJhbmdlLCAwKSwgdG86IG51bGx9O1xuICAgICAgfSBlbHNlIGlmIChyYW5nZS5mcm9tID09IG51bGwpIHtcbiAgICAgICAgcmFuZ2UgPSB7ZnJvbTogcmFuZ2UsIHRvOiBudWxsfTtcbiAgICAgIH1cbiAgICAgIGlmICghcmFuZ2UudG8pIHJhbmdlLnRvID0gcmFuZ2UuZnJvbTtcbiAgICAgIHJhbmdlLm1hcmdpbiA9IG1hcmdpbiB8fCAwO1xuXG4gICAgICBpZiAocmFuZ2UuZnJvbS5saW5lICE9IG51bGwpIHtcbiAgICAgICAgcmVzb2x2ZVNjcm9sbFRvUG9zKHRoaXMpO1xuICAgICAgICB0aGlzLmN1ck9wLnNjcm9sbFRvUG9zID0gcmFuZ2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgc1BvcyA9IGNhbGN1bGF0ZVNjcm9sbFBvcyh0aGlzLCBNYXRoLm1pbihyYW5nZS5mcm9tLmxlZnQsIHJhbmdlLnRvLmxlZnQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRoLm1pbihyYW5nZS5mcm9tLnRvcCwgcmFuZ2UudG8udG9wKSAtIHJhbmdlLm1hcmdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5tYXgocmFuZ2UuZnJvbS5yaWdodCwgcmFuZ2UudG8ucmlnaHQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRoLm1heChyYW5nZS5mcm9tLmJvdHRvbSwgcmFuZ2UudG8uYm90dG9tKSArIHJhbmdlLm1hcmdpbik7XG4gICAgICAgIHRoaXMuc2Nyb2xsVG8oc1Bvcy5zY3JvbGxMZWZ0LCBzUG9zLnNjcm9sbFRvcCk7XG4gICAgICB9XG4gICAgfSksXG5cbiAgICBzZXRTaXplOiBtZXRob2RPcChmdW5jdGlvbih3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICB2Y
23459XIgY20gPSB0aGlzO1xuICAgICAgZnVuY3Rpb24gaW50ZXJwcmV0KHZhbCkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbCA9PSBcIm51bWJlclwiIHx8IC9eXFxkKyQvLnRlc3QoU3RyaW5nKHZhbCkpID8gdmFsICsgXCJweFwiIDogdmFsO1xuICAgICAgfVxuICAgICAgaWYgKHdpZHRoICE9IG51bGwpIGNtLmRpc3BsYXkud3JhcHBlci5zdHlsZS53aWR0aCA9IGludGVycHJldCh3aWR0aCk7XG4gICAgICBpZiAoaGVpZ2h0ICE9IG51bGwpIGNtLmRpc3BsYXkud3JhcHBlci5zdHlsZS5oZWlnaHQgPSBpbnRlcnByZXQoaGVpZ2h0KTtcbiAgICAgIGlmIChjbS5vcHRpb25zLmxpbmVXcmFwcGluZykgY2xlYXJMaW5lTWVhc3VyZW1lbnRDYWNoZSh0aGlzKTtcbiAgICAgIHZhciBsaW5lTm8gPSBjbS5kaXNwbGF5LnZpZXdGcm9tO1xuICAgICAgY20uZG9jLml0ZXIobGluZU5vLCBjbS5kaXNwbGF5LnZpZXdUbywgZnVuY3Rpb24obGluZSkge1xuICAgICAgICBpZiAobGluZS53aWRnZXRzKSBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmUud2lkZ2V0cy5sZW5ndGg7IGkrKylcbiAgICAgICAgICBpZiAobGluZS53aWRnZXRzW2ldLm5vSFNjcm9sbCkgeyByZWdMaW5lQ2hhbmdlKGNtLCBsaW5lTm8sIFwid2lkZ2V0XCIpOyBicmVhazsgfVxuICAgICAgICArK2xpbmVObztcbiAgICAgIH0pO1xuICAgICAgY20uY3VyT3AuZm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgc2lnbmFsKGNtLCBcInJlZnJlc2hcIiwgdGhpcyk7XG4gICAgfSksXG5cbiAgICBvcGVyYXRpb246IGZ1bmN0aW9uKGYpe3JldHVybiBydW5Jbk9wKHRoaXMsIGYpO30sXG5cbiAgICByZWZyZXNoOiBtZXRob2RPcChmdW5jdGlvbigpIHtcbiAgICAgIHZhciBvbGRIZWlnaHQgPSB0aGlzLmRpc3BsYXkuY2FjaGVkVGV4dEhlaWdodDtcbiAgICAgIHJlZ0NoYW5nZSh0aGlzKTtcbiAgICAgIHRoaXMuY3VyT3AuZm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgY2xlYXJDYWNoZXModGhpcyk7XG4gICAgICB0aGlzLnNjcm9sbFRvKHRoaXMuZG9jLnNjcm9sbExlZnQsIHRoaXMuZG9jLnNjcm9sbFRvcCk7XG4gICAgICB1cGRhdGVHdXR0ZXJTcGFjZSh0aGlzKTtcbiAgICAgIGlmIChvbGRIZWlnaHQgPT0gbnVsbCB8fCBNYXRoLmFicyhvbGRIZWlnaHQgLSB0ZXh0SGVpZ2h0KHRoaXMuZGlzcGxheSkpID4gLjUpXG4gICAgICAgIGVzdGltYXRlTGluZUhlaWdodHModGhpcyk7XG4gICAgICBzaWduYWwodGhpcywgXCJyZWZyZXNoXCIsIHRoaXMpO1xuICAgIH0pLFxuXG4gICAgc3dhcERvYzogbWV0aG9kT3AoZnVuY3Rpb24oZG9jKSB7XG4gICAgICB2Y
23459XIgb2xkID0gdGhpcy5kb2M7XG4gICAgICBvbGQuY20gPSBudWxsO1xuICAgICAgYXR0YWNoRG9jKHRoaXMsIGRvYyk7XG4gICAgICBjbGVhckNhY2hlcyh0aGlzKTtcbiAgICAgIHRoaXMuZGlzcGxheS5pbnB1dC5yZXNldCgpO1xuICAgICAgdGhpcy5zY3JvbGxUbyhkb2Muc2Nyb2xsTGVmdCwgZG9jLnNjcm9sbFRvcCk7XG4gICAgICB0aGlzLmN1ck9wLmZvcmNlU2Nyb2xsID0gdHJ1ZTtcbiAgICAgIHNpZ25hbExhdGVyKHRoaXMsIFwic3dhcERvY1wiLCB0aGlzLCBvbGQpO1xuICAgICAgcmV0dXJuIG9sZDtcbiAgICB9KSxcblxuICAgIGdldElucHV0RmllbGQ6IGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZGlzcGxheS5pbnB1dC5nZXRGaWVsZCgpO30sXG4gICAgZ2V0V3JhcHBlckVsZW1lbnQ6IGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZGlzcGxheS53cmFwcGVyO30sXG4gICAgZ2V0U2Nyb2xsZXJFbGVtZW50OiBmdW5jdGlvbigpe3JldHVybiB0aGlzLmRpc3BsYXkuc2Nyb2xsZXI7fSxcbiAgICBnZXRHdXR0ZXJFbGVtZW50OiBmdW5jdGlvbigpe3JldHVybiB0aGlzLmRpc3BsYXkuZ3V0dGVyczt9XG4gIH07XG4gIGV2ZW50TWl4aW4oQ29kZU1pcnJvcik7XG5cbiAgLy8gT1BUSU9OIERFRkFVTFRTXG5cbiAgLy8gVGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbiBvcHRpb25zLlxuICB2YXIgZGVmYXVsdHMgPSBDb2RlTWlycm9yLmRlZmF1bHRzID0ge307XG4gIC8vIEZ1bmN0aW9ucyB0byBydW4gd2hlbiBvcHRpb25zIGFyZSBjaGFuZ2VkLlxuICB2YXIgb3B0aW9uSGFuZGxlcnMgPSBDb2RlTWlycm9yLm9wdGlvbkhhbmRsZXJzID0ge307XG5cbiAgZnVuY3Rpb24gb3B0aW9uKG5hbWUsIGRlZmx0LCBoYW5kbGUsIG5vdE9uSW5pdCkge1xuICAgIENvZGVNaXJyb3IuZGVmYXVsdHNbbmFtZV0gPSBkZWZsdDtcbiAgICBpZiAoaGFuZGxlKSBvcHRpb25IYW5kbGVyc1tuYW1lXSA9XG4gICAgICBub3RPbkluaXQgPyBmdW5jdGlvbihjbSwgdmFsLCBvbGQpIHtpZiAob2xkICE9IEluaXQpIGhhbmRsZShjbSwgdmFsLCBvbGQpO30gOiBoYW5kbGU7XG4gIH1cblxuICAvLyBQYXNzZWQgdG8gb3B0aW9uIGhhbmRsZXJzIHdoZW4gdGhlcmUgaXMgbm8gb2xkIHZhbHVlLlxuICB2YXIgSW5pdCA9IENvZGVNaXJyb3IuSW5pdCA9IHt0b1N0cmluZzogZnVuY3Rpb24oKXtyZXR1cm4gXCJDb2RlTWlycm9yLkluaXRcIjt9fTtcblxuICAvLyBUaGVzZSB0d28gYXJlLCBvbiBpbml0LCBjYWxsZWQgZnJvbSB0aGUgY29uc3RydWN0b3IgYmVjYXVzZSB0aGV5XG4gIC8vIGhhdmUgdG8gYmUgaW5pdGlhbGl6ZWQgYmVmb3JlIHRoZSBlZGl0b3IgY2FuIHN0YXJ0IGF0IGFsbC5cbiAgb3B0aW9uKFwidmFsdWVcIiwgXCJcIiwgZnVuY3Rpb24oY20sIHZhbCkge1xuICAgIGNtLnNldFZhbHVlKHZhbCk7XG4gIH0sIHRydWUpO1xuICBvcHRpb24oXCJtb2RlXCIsIG51bGwsIGZ1bmN0aW9uKGNtLCB2YWwpIHtcbiAgICBjbS5kb2MubW9kZU9wdGlvbiA9IHZhbDtcbiAgICBsb2FkTW9kZShjbSk7XG4gIH0sIHRydWUpO1xuXG4gIG9wdGlvbihcImluZGVudFVuaXRcIiwgMiwgbG9hZE1vZGUsIHRydWUpO1xuICBvcHRpb24oXCJpbmRlbnRXaXRoVGFic1wiLCBmYWxzZSk7XG4gIG9wdGlvbihcInNtYXJ0SW5kZW50XCIsIHRydWUpO1xuICBvcHRpb24oXCJ0YWJTaXplXCIsIDQsIGZ1bmN0aW9uKGNtKSB7XG4gICAgcmVzZXRNb2RlU3RhdGUoY20pO1xuICAgIGNsZWFyQ2FjaGVzKGNtKTtcbiAgICByZWdDaGFuZ2UoY20pO1xuICB9LCB0cnVlKTtcbiAgb3B0aW9uKFwibGluZVNlcGFyYXRvclwiLCBudWxsLCBmdW5jdGlvbihjbSwgdmFsKSB7XG4gICAgY20uZG9jLmxpbmVTZXAgPSB2YWw7XG4gICAgaWYgKCF2YWwpIHJldHVybjtcbiAgICB2YXIgbmV3QnJlYWtzID0gW10sIGxpbmVObyA9IGNtLmRvYy5maXJzdDtcbiAgICBjbS5kb2MuaXRlcihmdW5jdGlvbihsaW5lKSB7XG4gICAgICBmb3IgKHZhciBwb3MgPSAwOzspIHtcbiAgICAgICAgdmFyIGZvdW5kID0gbGluZS50ZXh0LmluZGV4T2YodmFsLCBwb3MpO1xuICAgICAgICBpZiAoZm91bmQgPT0gLTEpIGJyZWFrO1xuICAgICAgICBwb3MgPSBmb3VuZCArIHZhbC5sZW5ndGg7XG4gICAgICAgIG5ld0JyZWFrcy5wdXNoKFBvcyhsaW5lTm8sIGZvdW5kKSk7XG4gICAgICB9XG4gICAgICBsaW5lTm8rKztcbiAgICB9KTtcbiAgICBmb3IgKHZhciBpID0gbmV3QnJlYWtzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKVxuICAgICAgcmVwbGFjZVJhbmdlKGNtLmRvYywgdmFsLCBuZXdCcmVha3NbaV0sIFBvcyhuZXdCcmVha3NbaV0ubGluZSwgbmV3QnJlYWtzW2ldLmNoICsgdmFsLmxlbmd0aCkpXG4gIH0pO1xuICBvcHRpb24oXCJzcGVjaWFsQ2hhcnNcIiwgL1tcXHRcXHUwMDAwLVxcdTAwMTl
vendor: 18,294 bytes, line 23459
23459cXHUwMGFkXFx1MjAwYi1cXHUyMDBmXFx1MjAyOFxcdTIwMjlcXHVmZWZmXS9nLCBmdW5jdGlvbihjbSwgdmFsLCBvbGQpIHtcbiAgICBjbS5zdGF0ZS5zcGVjaWFsQ2hhcnMgPSBuZXcgUmVnRXhwKHZhbC5zb3VyY2UgKyAodmFsLnRlc3QoXCJcXHRcIikgPyBcIlwiIDogXCJ8XFx0XCIpLCBcImdcIik7XG4gICAgaWYgKG9sZCAhPSBDb2RlTWlycm9yLkluaXQpIGNtLnJlZnJlc2goKTtcbiAgfSk7XG4gIG9wdGlvbihcInNwZWNpYWxDaGFyUGxhY2Vob2xkZXJcIiwgZGVmYXVsdFNwZWNpYWxDaGFyUGxhY2Vob2xkZXIsIGZ1bmN0aW9uKGNtKSB7Y20ucmVmcmVzaCgpO30sIHRydWUpO1xuICBvcHRpb24oXCJlbGVjdHJpY0NoYXJzXCIsIHRydWUpO1xuICBvcHRpb24oXCJpbnB1dFN0eWxlXCIsIG1vYmlsZSA/IFwiY29udGVudGVkaXRhYmxlXCIgOiBcInRleHRhcmVhXCIsIGZ1bmN0aW9uKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcImlucHV0U3R5bGUgY2FuIG5vdCAoeWV0KSBiZSBjaGFuZ2VkIGluIGEgcnVubmluZyBlZGl0b3JcIik7IC8vIEZJWE1FXG4gIH0sIHRydWUpO1xuICBvcHRpb24oXCJydGxNb3ZlVmlzdWFsbHlcIiwgIXdpbmRvd3MpO1xuICBvcHRpb24oXCJ3aG9sZUxpbmVVcGRhdGVCZWZvcmVcIiwgdHJ1ZSk7XG5cbiAgb3B0aW9uKFwidGhlbWVcIiwgXCJkZWZhdWx0XCIsIGZ1bmN0aW9uKGNtKSB7XG4gICAgdGhlbWVDaGFuZ2VkKGNtKTtcbiAgICBndXR0ZXJzQ2hhbmdlZChjbSk7XG4gIH0sIHRydWUpO1xuICBvcHRpb24oXCJrZXlNYXBcIiwgXCJkZWZhdWx0XCIsIGZ1bmN0aW9uKGNtLCB2YWwsIG9sZCkge1xuICAgIHZhciBuZXh0ID0gZ2V0S2V5TWFwKHZhbCk7XG4gICAgdmFyIHByZXYgPSBvbGQgIT0gQ29kZU1pcnJvci5Jbml0ICYmIGdldEtleU1hcChvbGQpO1xuICAgIGlmIChwcmV2ICYmIHByZXYuZGV0YWNoKSBwcmV2LmRldGFjaChjbSwgbmV4dCk7XG4gICAgaWYgKG5leHQuYXR0YWNoKSBuZXh0LmF0dGFjaChjbSwgcHJldiB8fCBudWxsKTtcbiAgfSk7XG4gIG9wdGlvbihcImV4dHJhS2V5c1wiLCBudWxsKTtcblxuICBvcHRpb24oXCJsaW5lV3JhcHBpbmdcIiwgZmFsc2UsIHdyYXBwaW5nQ2hhbmdlZCwgdHJ1ZSk7XG4gIG9wdGlvbihcImd1dHRlcnNcIiwgW10sIGZ1bmN0aW9uKGNtKSB7XG4gICAgc2V0R3V0dGVyc0ZvckxpbmVOdW1iZXJzKGNtLm9wdGlvbnMpO1xuICAgIGd1dHRlcnNDaGFuZ2VkKGNtKTtcbiAgfSwgdHJ1ZSk7XG4gIG9wdGlvbihcImZpeGVkR3V0dGVyXCIsIHRydWUsIGZ1bmN0aW9uKGNtLCB2YWwpIHtcbiAgICBjbS5kaXNwbGF5Lmd1dHRlcnMuc3R5bGUubGVmdCA9IHZhbCA/IGNvbXBlbnNhdGVGb3JIU2Nyb2xsKGNtLmRpc3BsYXkpICsgXCJweFwiIDogXCIwXCI7XG4gICAgY20ucmVmcmVzaCgpO1xuICB9LCB0cnVlKTtcbiAgb3B0aW9uKFwiY292ZXJHdXR0ZXJOZXh0VG9TY3JvbGxiYXJcIiwgZmFsc2UsIGZ1bmN0aW9uKGNtKSB7dXBkYXRlU2Nyb2xsYmFycyhjbSk7fSwgdHJ1ZSk7XG4gIG9wdGlvbihcInNjcm9sbGJhclN0eWxlXCIsIFwibmF0aXZlXCIsIGZ1bmN0aW9uKGNtKSB7XG4gICAgaW5pdFNjcm9sbGJhcnMoY20pO1xuICAgIHVwZGF0ZVNjcm9sbGJhcnMoY20pO1xuICAgIGNtLmRpc3BsYXkuc2Nyb2xsYmFycy5zZXRTY3JvbGxUb3AoY20uZG9jLnNjcm9sbFRvcCk7XG4gICAgY20uZGlzcGxheS5zY3JvbGxiYXJzLnNldFNjcm9sbExlZnQoY20uZG9jLnNjcm9sbExlZnQpO1xuICB9LCB0cnVlKTtcbiAgb3B0aW9uKFwibGluZU51bWJlcnNcIiwgZmFsc2UsIGZ1bmN0aW9uKGNtKSB7XG4gICAgc2V0R3V0dGVyc0ZvckxpbmVOdW1iZXJzKGNtLm9wdGlvbnMpO1xuICAgIGd1dHRlcnNDaGFuZ2VkKGNtKTtcbiAgfSwgdHJ1ZSk7XG4gIG9wdGlvbihcImZpcnN0TGluZU51bWJlclwiLCAxLCBndXR0ZXJzQ2hhbmdlZCwgdHJ1ZSk7XG4gIG9wdGlvbihcImxpbmVOdW1iZXJGb3JtYXR0ZXJcIiwgZnVuY3Rpb24oaW50ZWdlcikge3JldHVybiBpbnRlZ2VyO30sIGd1dHRlcnNDaGFuZ2VkLCB0cnVlKTtcbiAgb3B0aW9uKFwic2hvd0N1cnNvcldoZW5TZWxlY3RpbmdcIiwgZmFsc2UsIHVwZGF0ZVNlbGVjdGlvbiwgdHJ1ZSk7XG5cbiAgb3B0aW9uKFwicmVzZXRTZWxlY3Rpb25PbkNvbnRleHRNZW51XCIsIHRydWUpO1xuICBvcHRpb24oXCJsaW5lV2lzZUNvcHlDdXRcIiwgdHJ1ZSk7XG5cbiAgb3B0aW9uKFwicmVhZE9ubHlcIiwgZmFsc2UsIGZ1bmN0aW9uKGNtLCB2YWwpIHtcbiAgICBpZiAodmFsID09IFwibm9jdXJzb3JcIikge1xuICAgICAgb25CbHVyKGNtKTtcbiAgICAgIGNtLmRpc3BsYXkuaW5wdXQuYmx1cigpO1xuICAgICAgY20uZGlzcGxheS5kaXNhYmxlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNtLmRpc3BsYXkuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgY20uZGlzcGxheS5pbnB1dC5yZWFkT25seUNoYW5nZWQodmFsKVxuICB9KTtcbiAgb3B0aW9uKFwiZGlzYWJsZUlucHV0XCIsIGZhbHNlLCBmdW5jdGlvbihjbSwgdmFsKSB7aWYgKCF2YWwpIGNtLmRpc3BsYXkuaW5wdXQucmVzZXQoKTt9LCB0cnVlKTtcbiAgb3B0aW9uKFwiZHJhZ0Ryb3BcIiwgdHJ1ZSwgZHJhZ0Ryb3BDaGFuZ2VkKTtcbiAgb3B0aW9uKFwiYWxsb3dEcm9wRmlsZVR5cGVzXCIsIG51bGwpO1xuXG4gIG9wdGlvbihcImN1cnNvckJsaW5rUmF0ZVwiLCA1MzApO1xuICBvcHRpb24oXCJjdXJzb3JTY3JvbGxNYXJnaW5cIiwgMCk7XG4gIG9wdGlvbihcImN1cnNvckhlaWdodFwiLCAxLCB1cGRhdGVTZWxlY3Rpb24sIHRydWUpO1xuICBvcHRpb24oXCJzaW5nbGVDdXJzb3JIZWlnaHRQZXJMaW5lXCIsIHRydWUsIHVwZGF0ZVNlbGVjdGlvbiwgdHJ1ZSk7XG4gIG9wdGlvbihcIndvcmtUaW1lXCIsIDEwMCk7XG4gIG9wdGlvbihcIndvcmtEZWxheVwiLCAxMDApO1xuICBvcHRpb24oXCJmbGF0dGVuU3BhbnNcIiwgdHJ1ZSwgcmVzZXRNb2RlU3RhdGUsIHRydWUpO1xuICBvcHRpb24oXCJhZGRNb2RlQ2xhc3NcIiwgZmFsc2UsIHJlc2V0TW9kZVN0YXRlLCB0cnVlKTtcbiAgb3B0aW9uKFwicG9sbEludGVydmFsXCIsIDEwMCk7XG4gIG9wdGlvbihcInVuZG9EZXB0aFwiLCAyMDAsIGZ1bmN0aW9uKGNtLCB2YWwpe2NtLmRvYy5oaXN0b3J5LnVuZG9EZXB0aCA9IHZhbDt9KTtcbiAgb3B0aW9uKFwiaGlzdG9yeUV2ZW50RGVsYXlcIiwgMTI1MCk7XG4gIG9wdGlvbihcInZpZXdwb3J0TWFyZ2luXCIsIDEwLCBmdW5jdGlvbihjbSl7Y20ucmVmcmVzaCgpO30sIHRydWUpO1xuICBvcHRpb24oXCJtYXhIaWdobGlnaHRMZW5ndGhcIiwgMTAwMDAsIHJlc2V0TW9kZVN0YXRlLCB0cnVlKTtcbiAgb3B0aW9uKFwibW92ZUlucHV0V2l0aEN1cnNvclwiLCB0cnVlLCBmdW5jdGlvbihjbSwgdmFsKSB7XG4gICAgaWYgKCF2YWwpIGNtLmRpc3BsYXkuaW5wdXQucmVzZXRQb3NpdGlvbigpO1xuICB9KTtcblxuICBvcHRpb24oXCJ0YWJpbmRleFwiLCBudWxsLCBmdW5jdGlvbihjbSwgdmFsKSB7XG4gICAgY20uZGlzcGxheS5pbnB1dC5nZXRGaWVsZCgpLnRhYkluZGV4ID0gdmFsIHx8IFwiXCI7XG4gIH0pO1xuICBvcHRpb24oXCJhdXRvZm9jdXNcIiwgbnVsbCk7XG5cbiAgLy8gTU9ERSBERUZJTklUSU9OIEFORCBRVUVSWUlOR1xuXG4gIC8vIEtub3duIG1vZGVzLCBieSBuYW1lIGFuZCBieSBNSU1FXG4gIHZhciBtb2RlcyA9IENvZGVNaXJyb3IubW9kZXMgPSB7fSwgbWltZU1vZGVzID0gQ29kZU1pcnJvci5taW1lTW9kZXMgPSB7fTtcblxuICAvLyBFeHRyYSBhcmd1bWVudHMgYXJlIHN0b3JlZCBhcyB0aGUgbW9kZSdzIGRlcGVuZGVuY2llcywgd2hpY2ggaXNcbiAgLy8gdXNlZCBieSAobGVnYWN5KSBtZWNoYW5pc21zIGxpa2UgbG9hZG1vZGUuanMgdG8gYXV0b21hdGljYWxseVxuICAvLyBsb2FkIGEgbW9kZS4gKFByZWZlcnJlZCBtZWNoYW5pc20gaXMgdGhlIHJlcXVpcmUvZGVmaW5lIGNhbGxzLilcbiAgQ29kZU1pcnJvci5kZWZpbmVNb2RlID0gZnVuY3Rpb24obmFtZSwgbW9kZSkge1xuICAgIGlmICghQ29kZU1pcnJvci5kZWZhdWx0cy5tb2RlICYmIG5hbWUgIT0gXCJudWxsXCIpIENvZGVNaXJyb3IuZGVmYXVsdHMubW9kZSA9IG5hbWU7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKVxuICAgICAgbW9kZS5kZXBlbmRlbmNpZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpO1xuICAgIG1vZGVzW25hbWVdID0gbW9kZTtcbiAgfTtcblxuICBDb2RlTWlycm9yLmRlZmluZU1JTUUgPSBmdW5jdGlvbihtaW1lLCBzcGVjKSB7XG4gICAgbWltZU1vZGVzW21pbWVdID0gc3BlYztcbiAgfTtcblxuICAvLyBHaXZlbiBhIE1JTUUgdHlwZSwgYSB7bmFtZSwgLi4ub3B0aW9uc30gY29uZmlnIG9iamVjdCwgb3IgYSBuYW1lXG4gIC8vIHN0cmluZywgcmV0dXJuIGEgbW9kZSBjb25maWcgb2JqZWN0LlxuICBDb2RlTWlycm9yLnJlc29sdmVNb2RlID0gZnVuY3Rpb24oc3BlYykge1xuICAgIGlmICh0eXBlb2Ygc3BlYyA9PSBcInN0cmluZ1wiICYmIG1pbWVNb2Rlcy5oYXNPd25Qcm9wZXJ0eShzcGVjKSkge1xuICAgICAgc3BlYyA9IG1pbWVNb2Rlc1tzcGVjXTtcbiAgICB9IGVsc2UgaWYgKHNwZWMgJiYgdHlwZW9mIHNwZWMubmFtZSA9PSBcInN0cmluZ1wiICYmIG1pbWVNb2Rlcy5oYXNPd25Qcm9wZXJ0eShzcGVjLm5hbWUpKSB7XG4gICAgICB2YXIgZm91bmQgPSBtaW1lTW9kZXNbc3BlYy5uYW1lXTtcbiAgICAgIGlmICh0eXBlb2YgZm91bmQgPT0gXCJzdHJpbmdcIikgZm91bmQgPSB7bmFtZTogZm91bmR9O1xuICAgICAgc3BlYyA9IGNyZWF0ZU9iaihmb3VuZCwgc3BlYyk7XG4gICAgICBzcGVjLm5hbWUgPSBmb3VuZC5uYW1lO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNwZWMgPT0gXCJzdHJpbmdcIiAmJiAvXltcXHdcXC1dK1xcL1tcXHdcXC1dK1xcK3htbCQvLnRlc3Qoc3BlYykpIHtcbiAgICAgIHJldHVybiBDb2RlTWlycm9yLnJlc29sdmVNb2RlKFwiYXBwbGljYXRpb24veG1sXCIpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHNwZWMgPT0gXCJzdHJpbmdcIikgcmV0dXJuIHtuYW1lOiBzcGVjfTtcbiAgICBlbHNlIHJldHVybiBzcGVjIHx8IHtuYW1lOiBcIm51bGxcIn07XG4gIH07XG5cbiAgLy8gR2l2ZW4gYSBtb2RlIHNwZWMgKGFueXRoaW5nIHRoYXQgcmVzb2x2ZU1vZGUgYWNjZXB0cyksIGZpbmQgYW5kXG4gIC8vIGluaXRpYWxpemUgYW4gYWN0dWFsIG1vZGUgb2JqZWN0LlxuICBDb2RlTWlycm9yLmdldE1vZGUgPSBmdW5jdGlvbihvcHRpb25zLCBzcGVjKSB7XG4gICAgdmFyIHNwZWMgPSBDb2RlTWlycm9yLnJlc29sdmVNb2RlKHNwZWMpO1xuICAgIHZhciBtZmFjdG9yeSA9IG1vZGVzW3NwZWMubmFtZV07XG4gICAgaWYgKCFtZmFjdG9yeSkgcmV0dXJuIENvZGVNaXJyb3IuZ2V0TW9kZShvcHRpb25zLCBcInRleHQvcGxhaW5cIik7XG4gICAgdmFyIG1vZGVPYmogPSBtZmFjdG9yeShvcHRpb25zLCBzcGVjKTtcbiAgICBpZiAobW9kZUV4dGVuc2lvbnMuaGFzT3duUHJvcGVydHkoc3BlYy5uYW1lKSkge1xuICAgICAgdmFyIGV4dHMgPSBtb2RlRXh0ZW5zaW9uc1tzcGVjLm5hbWVdO1xuICAgICAgZm9yICh2YXIgcHJvcCBpbiBleHRzKSB7XG4gICAgICAgIGlmICghZXh0cy5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgY29udGludWU7XG4gICAgICAgIGlmIChtb2RlT2JqLmhhc093blByb3BlcnR5KHByb3ApKSBtb2RlT2JqW1wiX1wiICsgcHJvcF0gPSBtb2RlT2JqW3Byb3BdO1xuICAgICAgICBtb2RlT2JqW3Byb3BdID0gZXh0c1twcm9wXTtcbiAgICAgIH1cbiAgICB9XG4gICAgbW9kZU9iai5uYW1lID0gc3BlYy5uYW1lO1xuICAgIGlmIChzcGVjLmhlbHBlclR5cGUpIG1vZGVPYmouaGVscGVyVHlwZSA9IHNwZWMuaGVscGVyVHlwZTtcbiAgICBpZiAoc3BlYy5tb2RlUHJvcHMpIGZvciAodmFyIHByb3AgaW4gc3BlYy5tb2RlUHJvcHMpXG4gICAgICBtb2RlT2JqW3Byb3BdID0gc3BlYy5tb2RlUHJvcHNbcHJvcF07XG5cbiAgICByZXR1cm4gbW9kZU9iajtcbiAgfTtcblxuICAvLyBNaW5pbWFsIGRlZmF1bHQgbW9kZS5cbiAgQ29kZU1pcnJvci5kZWZpbmVNb2RlKFwibnVsbFwiLCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge3Rva2VuOiBmdW5jdGlvbihzdHJlYW0pIHtzdHJlYW0uc2tpcFRvRW5kKCk7fX07XG4gIH0pO1xuICBDb2RlTWlycm9yLmRlZmluZU1JTUUoXCJ0ZXh0L3BsYWluXCIsIFwibnVsbFwiKTtcblxuICAvLyBUaGlzIGNhbiBiZSB1c2VkIHRvIGF0dGFjaCBwcm9wZXJ0aWVzIHRvIG1vZGUgb2JqZWN0cyBmcm9tXG4gIC8vIG91dHNpZGUgdGhlIGFjdHVhbCBtb2RlIGRlZmluaXRpb24uXG4gIHZhciBtb2RlRXh0ZW5zaW9ucyA9IENvZGVNaXJyb3IubW9kZUV4dGVuc2lvbnMgPSB7fTtcbiAgQ29kZU1pcnJvci5leHRlbmRNb2RlID0gZnVuY3Rpb24obW9kZSwgcHJvcGVydGllcykge1xuICAgIHZhciBleHRzID0gbW9kZUV4dGVuc2lvbnMuaGFzT3duUHJvcGVydHkobW9kZSkgPyBtb2RlRXh0ZW5zaW9uc1ttb2RlXSA6IChtb2RlRXh0ZW5zaW9uc1ttb2RlXSA9IHt9KTtcbiAgICBjb3B5T2JqKHByb3BlcnRpZXMsIGV4dHMpO1xuICB9O1xuXG4gIC8vIEVYVEVOU0lPTlNcblxuICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbiA9IGZ1bmN0aW9uKG5hbWUsIGZ1bmMpIHtcbiAgICBDb2RlTWlycm9yLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmM7XG4gIH07XG4gIENvZGVNaXJyb3IuZGVmaW5lRG9jRXh0ZW5zaW9uID0gZnVuY3Rpb24obmFtZSwgZnVuYykge1xuICAgIERvYy5wcm90b3R5cGVbbmFtZV0gPSBmdW5jO1xuICB9O1xuICBDb2RlTWlycm9yLmRlZmluZU9wdGlvbiA9IG9wdGlvbjtcblxuICB2YXIgaW5pdEhvb2tzID0gW107XG4gIENvZGVNaXJyb3IuZGVmaW5lSW5pdEhvb2sgPSBmdW5jdGlvbihmKSB7aW5pdEhvb2tzLnB1c2goZik7fTtcblxuICB2YXIgaGVscGVycyA9IENvZGVNaXJyb3IuaGVscGVycyA9IHt9O1xuICBDb2RlTWlycm9yLnJlZ2lzdGVySGVscGVyID0gZnVuY3Rpb24odHlwZSwgbmFtZSwgdmFsdWUpIHtcbiAgICBpZiAoIWhlbHBlcnMuaGFzT3duUHJvcGVydHkodHlwZSkpIGhlbHBlcnNbdHlwZV0gPSBDb2RlTWlycm9yW3R5cGVdID0ge19nbG9iYWw6IFtdfTtcbiAgICBoZWxwZXJzW3R5cGVdW25hbWVdID0gdmFsdWU7XG4gIH07XG4gIENvZGVNaXJyb3IucmVnaXN0ZXJHbG9iYWxIZWxwZXIgPSBmdW5jdGlvbih0eXBlLCBuYW1lLCBwcmVkaWNhdGUsIHZhbHVlKSB7XG4gICAgQ29kZU1pcnJvci5yZWdpc3RlckhlbHBlcih0eXBlLCBuYW1lLCB2YWx1ZSk7XG4gICAgaGVscGVyc1t0eXBlXS5fZ2xvYmFsLnB1c2goe3ByZWQ6IHByZWRpY2F0ZSwgdmFsOiB2YWx1ZX0pO1xuICB9O1xuXG4gIC8vIE1PREUgU1RBVEUgSEFORExJTkdcblxuICAvLyBVdGlsaXR5IGZ1bmN0aW9ucyBmb3Igd29ya2luZyB3aXRoIHN0YXRlLiBFeHBvcnRlZCBiZWNhdXNlIG5lc3RlZFxuICAvLyBtb2RlcyBuZWVkIHRvIGRvIHRoaXMgZm9yIHRoZWlyIGlubmVyIG1vZGVzLlxuXG4gIHZhciBjb3B5U3RhdGUgPSBDb2RlTWlycm9yLmNvcHlTdGF0ZSA9IGZ1bmN0aW9uKG1vZGUsIHN0YXRlKSB7XG4gICAgaWYgKHN0YXRlID09PSB0cnVlKSByZXR1cm4gc3RhdGU7XG4gICAgaWYgKG1vZGUuY29weVN0YXRlKSByZXR1cm4gbW9kZS5jb3B5U3RhdGUoc3RhdGUpO1xuICAgIHZhciBuc3RhdGUgPSB7fTtcbiAgICBmb3IgKHZhciBuIGluIHN0YXRlKSB7XG4gICAgICB2YXIgdmFsID0gc3RhdGVbbl07XG4gICAgICBpZiAodmFsIGluc3RhbmNlb2YgQXJyYXkpIHZhbCA9IHZhbC5jb25jYXQoW10pO1xuICAgICAgbnN0YXRlW25dID0gdmFsO1xuICAgIH1cbiAgICByZXR1cm4gbnN0YXRlO1xuICB9O1xuXG4gIHZhciBzdGFydFN0YXRlID0gQ29kZU1pcnJvci5zdGFydFN0YXRlID0gZnVuY3Rpb24obW9kZSwgYTEsIGEyKSB7XG4gICAgcmV0dXJuIG1vZGUuc3RhcnRTdGF0ZSA/IG1vZGUuc3RhcnRTdGF0ZShhMSwgYTIpIDogdHJ1ZTtcbiAgfTtcblxuICAvLyBHaXZlbiBhIG1vZGUgYW5kIGEgc3RhdGUgKGZvciB0aGF0IG1vZGUpLCBmaW5kIHRoZSBpbm5lciBtb2RlIGFuZFxuICAvLyBzdGF0ZSBhdCB0aGUgcG9zaXRpb24gdGhhdCB0aGUgc3RhdGUgcmVmZXJzIHRvLlxuICBDb2RlTWlycm9yLmlubmVyTW9kZSA9IGZ1bmN0aW9uKG1vZGUsIHN0YXRlKSB7XG4gICAgd2hpbGUgKG1vZGUuaW5uZXJNb2RlKSB7XG4gICAgICB2YXIgaW5mbyA9IG1vZGUuaW5uZXJNb2RlKHN0YXRlKTtcbiAgICAgIGlmICghaW5mbyB8fCBpbmZvLm1vZGUgPT0gbW9kZSkgYnJlYWs7XG4gICAgICBzdGF0ZSA9IGluZm8uc3RhdGU7XG4gICAgICBtb2RlID0gaW5mby5tb2RlO1xuICAgIH1cbiAgICByZXR1cm4gaW5mbyB8fCB7bW9kZTogbW9kZSwgc3RhdGU6IHN0YXRlfTtcbiAgfTtcblxuICAvLyBTVEFOREFSRCBDT01NQU5EU1xuXG4gIC8vIENvbW1hbmRzIGFyZSBwYXJhbWV0ZXItbGVzcyBhY3Rpb25zIHRoYXQgY2FuIGJlIHBlcmZvcm1lZCBvbiBhblxuICAvLyBlZGl0b3IsIG1vc3RseSB1c2VkIGZvciBrZXliaW5kaW5ncy5cbiAgdmFyIGNvbW1hbmRzID0gQ29kZU1pcnJvci5jb21tYW5kcyA9IHtcbiAgICBzZWxlY3RBbGw6IGZ1bmN0aW9uKGNtKSB7Y20uc2V0U2VsZWN0aW9uKFBvcyhjbS5maXJzdExpbmUoKSwgMCksIFBvcyhjbS5sYXN0TGluZSgpKSwgc2VsX2RvbnRTY3JvbGwpO30sXG4gICAgc2luZ2xlU2VsZWN0aW9uOiBmdW5jdGlvbihjbSkge1xuICAgICAgY20uc2V0U2VsZWN0aW9uKGNtLmdldEN1cnNvcihcImFuY2hvclwiKSwgY20uZ2V0Q3Vyc29yKFwiaGVhZFwiKSwgc2VsX2RvbnRTY3JvbGwpO1xuICAgIH0sXG4gICAga2lsbExpbmU6IGZ1bmN0aW9uKGNtKSB7XG4gICAgICBkZWxldGVOZWFyU2VsZWN0aW9uKGNtLCBmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICBpZiAocmFuZ2UuZW1wdHkoKSkge1xuICAgICAgICAgIHZhciBsZW4gPSBnZXRMaW5lKGNtLmRvYywgcmFuZ2UuaGVhZC5saW5lKS50ZXh0Lmxlbmd0aDtcbiAgICAgICAgICBpZiAocmFuZ2UuaGVhZC5jaCA9PSBsZW4gJiYgcmFuZ2UuaGVhZC5saW5lIDwgY20ubGFzdExpbmUoKSlcbiAgICAgICAgICAgIHJldHVybiB7ZnJvbTogcmFuZ2UuaGVhZCwgdG86IFBvcyhyYW5nZS5oZWFkLmxpbmUgKyAxLCAwKX07XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIHtmcm9tOiByYW5nZS5oZWFkLCB0bzogUG9zKHJhbmdlLmhlYWQubGluZSwgbGVuKX07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHtmcm9tOiByYW5nZS5mcm9tKCksIHRvOiByYW5nZS50bygpfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBkZWxldGVMaW5lOiBmdW5jdGlvbihjbSkge1xuICAgICAgZGVsZXRlTmVhclNlbGVjdGlvbihjbSwgZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgICAgcmV0dXJuIHtmcm9tOiBQb3MocmFuZ2UuZnJvbSgpLmxpbmUsIDApLFxuICAgICAgICAgICAgICAgIHRvOiBjbGlwUG9zKGNtLmRvYywgUG9zKHJhbmdlLnRvKCkubGluZSArIDEsIDApKX07XG4gICAgICB9KTtcbiAgICB9LFxuICAgIGRlbExpbmVMZWZ0OiBmdW5jdGlvbihjbSkge1xuICAgICAgZGVsZXRlTmVhclNlbGVjdGlvbihjbSwgZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgICAgcmV0dXJuIHtmcm9tOiBQb3MocmFuZ2UuZnJvbSgpLmxpbmUsIDApLCB0bzogcmFuZ2UuZnJvbSgpfTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgZGVsV3JhcHBlZExpbmVMZWZ0OiBmdW5jdGlvbihjbSkge1xuICAgICAgZGVsZXRlTmVhclNlbGVjdGlvbihjbSwgZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgICAgdmFyIHRvcCA9IGNtLmNoYXJDb29yZHMocmFuZ2UuaGVhZCwgXCJkaXZcIikudG9wICsgNTtcbiAgICAgICAgdmFyIGxlZnRQb3MgPSBjbS5jb29yZHNDaGFyKHtsZWZ0OiAwLCB0b3A6IHRvcH0sIFwiZGl2XCIpO1xuICAgICAgICByZXR1cm4ge2Zyb206IGxlZnRQb3MsIHRvOiByYW5nZS5mcm9tKCl9O1xuICAgICAgfSk7XG4gICAgfSxcbiAgICBkZWxXcmFwcGVkTGluZVJpZ2h0OiBmdW5jdGlvbihjbSkge1xuICAgICAgZGVsZXRlTmVhclNlbGVjdGlvbihjbSwgZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgICAgdmFyIHRvcCA9IGNtLmNoYXJDb29yZHMocmFuZ2UuaGVhZCwgXCJkaXZcIikudG9wICsgNTtcbiAgICAgICAgdmFyIHJpZ2h0UG9zID0gY20uY29vcmRzQ2hhcih7bGVmdDogY20uZGlzcGxheS5saW5lRGl2Lm9mZnNldFdpZHRoICsgMTAwLCB0b3A6IHRvcH0sIFwiZGl2XCIpO1xuICAgICAgICByZXR1cm4ge2Zyb206IHJhbmdlLmZyb20oKSwgdG86IHJpZ2h0UG9zIH07XG4gICAgICB9KTtcbiAgICB9LFxuICAgIHVuZG86IGZ1bmN0aW9uKGNtKSB7Y20udW5kbygpO30sXG4gICAgcmVkbzogZnVuY3Rpb24oY20pIHtjbS5yZWRvKCk7fSxcbiAgICB1bmRvU2VsZWN0aW9uOiBmdW5jdGlvbihjbSkge2NtLnVuZG9TZWxlY3Rpb24oKTt9LFxuICAgIHJlZG9TZWxlY3Rpb246IGZ1bmN0aW9uKGNtKSB7Y20ucmVkb1NlbGVjdGlvbigpO30sXG4gICAgZ29Eb2NTdGFydDogZnVuY3Rpb24oY20pIHtjbS5leHRlbmRTZWxlY3Rpb24oUG9zKGNtLmZpcnN0TGluZSgpLCAwKSk7fSxcbiAgICBnb0RvY0VuZDogZnVuY3Rpb24oY20pIHtjbS5leHRlbmRTZWxlY3Rpb24oUG9zKGNtLmxhc3RMaW5lKCkpKTt9LFxuICAgIGdvTGluZVN0YXJ0OiBmdW5jdGlvbihjbSkge1xuICAgICAgY20uZXh0ZW5kU2VsZWN0aW9uc0J5KGZ1bmN0aW9uKHJhbmdlKSB7IHJldHVybiBsaW5lU3RhcnQoY20sIHJhbmdlLmhlYWQubGluZSk7IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge29yaWdpbjogXCIrbW92ZVwiLCBiaWFzOiAxfSk7XG4gICAgfSxcbiAgICBnb0xpbmVTdGFydFNtYXJ0OiBmdW5jdGlvbihjbSkge1xuICAgICAgY20uZXh0ZW5kU2VsZWN0aW9uc0J5KGZ1bmN0aW9uKHJhbmdlKSB7XG4gICAgICAgIHJldHVybiBsaW5lU3RhcnRTbWFydChjbSwgcmFuZ2UuaGVhZCk7XG4gICAgICB9LCB7b3JpZ2luOiBcIittb3ZlXCIsIGJpYXM6IDF9KTtcbiAgICB9LFxuICAgIGdvTGluZUVuZDogZnVuY3Rpb24oY20pIHtcbiAgICAgIGNtLmV4dGVuZFNlbGVjdGlvbnNCeShmdW5jdGlvbihyYW5nZSkgeyByZXR1cm4gbGluZUVuZChjbSwgcmFuZ2UuaGVhZC5saW5lKTsgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7b3JpZ2luOiBcIittb3ZlXCIsIGJpYXM6IC0xfSk7XG4gICAgfSxcbiAgICBnb0xpbmVSaWdodDogZnVuY3Rpb24oY20pIHtcbiAgICAgIGNtLmV4dGVuZFNlbGVjdGlvbnNCeShmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICB2YXIgdG9wID0gY20uY2hhckNvb3JkcyhyYW5nZS5oZWFkLCBcImRpdlwiKS50b3AgKyA1O1xuICAgICAgICByZXR1cm4gY20uY29vcmRzQ2hhcih7bGVmdDogY20uZGlzcGxheS5saW5lRGl2Lm9mZnNldFdpZHRoICsgMTAwLCB0b3A6IHRvcH0sIFwiZGl2XCIpO1xuICAgICAgfSwgc2VsX21vdmUpO1xuICAgIH0sXG4gICAgZ29MaW5lTGVmdDogZnVuY3Rpb24oY20pIHtcbiAgICAgIGNtLmV4dGVuZFNlbGVjdGlvbnNCeShmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICB2YXIgdG9wID0gY20uY2hhckNvb3JkcyhyYW5nZS5oZWFkLCBcImRpdlwiKS50b3AgKyA1O1xuICAgICAgICByZXR1cm4gY20uY29vcmRzQ2hhcih7bGVmdDogMCwgdG9wOiB0b3B9LCBcImRpdlwiKTtcbiAgICAgIH0sIHNlbF9tb3ZlKTtcbiAgICB9LFxuICAgIGdvTGluZUxlZnRTbWFydDogZnVuY3Rpb24oY20pIHtcbiAgICAgIGNtLmV4dGVuZFNlbGVjdGlvbnNCeShmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICB2YXIgdG9wID0gY20uY2hhckNvb3JkcyhyYW5nZS5oZWFkLCBcImRpdlwiKS50b3AgKyA1O1xuICAgICAgICB2YXIgcG9zID0gY20uY29vcmRzQ2hhcih7bGVmdDogMCwgdG9wOiB0b3B9LCBcImRpdlwiKTtcbiAgICAgICAgaWYgKHBvcy5jaCA8IGNtLmdldExpbmUocG9zLmxpbmUpLnNlYXJjaCgvXFxTLykpIHJldHVybiBsaW5lU3RhcnRTbWFydChjbSwgcmFuZ2UuaGVhZCk7XG4gICAgICAgIHJldHVybiBwb3M7XG4gICAgICB9LCBzZWxfbW92ZSk7XG4gICAgfSxcbiAgICBnb0xpbmVVcDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlVigtMSwgXCJsaW5lXCIpO30sXG4gICAgZ29MaW5lRG93bjogZnVuY3Rpb24oY20pIHtjbS5tb3ZlVigxLCBcImxpbmVcIik7fSxcbiAgICBnb1BhZ2VVcDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlVigtMSwgXCJwYWdlXCIpO30sXG4gICAgZ29QYWdlRG93bjogZnVuY3Rpb24oY20pIHtjbS5tb3ZlVigxLCBcInBhZ2VcIik7fSxcbiAgICBnb0NoYXJMZWZ0OiBmdW5jdGlvbihjbSkge2NtLm1vdmVIKC0xLCBcImNoYXJcIik7fSxcbiAgICBnb0NoYXJSaWdodDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgxLCBcImNoYXJcIik7fSxcbiAgICBnb0NvbHVtbkxlZnQ6IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZUgoLTEsIFwiY29sdW1uXCIpO30sXG4gICAgZ29Db2x1bW5SaWdodDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgxLCBcImNvbHVtblwiKTt9LFxuICAgIGdvV29yZExlZnQ6IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZUgoLTEsIFwid29yZFwiKTt9LFxuICAgIGdvR3JvdXBSaWdodDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgxLCBcImdyb3VwXCIpO30sXG4gICAgZ29Hcm91cExlZnQ6IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZUgoLTEsIFwiZ3JvdXBcIik7fSxcbiAgICBnb1dvcmRSaWdodDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgxLCBcIndvcmRcIik7fSxcbiAgICBkZWxDaGFyQmVmb3JlOiBmdW5jdGlvbihjbSkge2NtLmRlbGV0ZUgoLTEsIFwiY2hhclwiKTt9LFxuICAgIGRlbENoYXJBZnRlcjogZnVuY3Rpb24oY20pIHtjbS5kZWxldGVIKDEsIFwiY2hhclwiKTt9LFxuICAgIGRlbFdvcmRCZWZvcmU6IGZ1bmN0aW9uKGNtKSB7Y20uZGVsZXRlSCgtMSwgXCJ3b3JkXCIpO30sXG4gICAgZGVsV29yZEFmdGVyOiBmdW5jdGlvbihjbSkge2NtLmRlbGV0ZUgoMSwgXCJ3b3JkXCIpO30sXG4gICAgZGVsR3JvdXBCZWZvcmU6IGZ1bmN0aW9uKGNtKSB7Y20uZGVsZXRlSCgtMSwgXCJncm91cFwiKTt9LFxuICAgIGRlbEdyb3VwQWZ0ZXI6IGZ1bmN0aW9uKGNtKSB7Y20uZGVsZXRlSCgxLCBcImdyb3VwXCIpO30sXG4gICAgaW5kZW50QXV0bzogZnVuY3Rpb24oY20pIHtjbS5pbmRlbnRTZWxlY3Rpb24oXCJzbWFydFwiKTt9LFxuICAgIGluZGVudE1vcmU6IGZ1bmN0aW9uKGNtKSB7Y20uaW5kZW50U2VsZWN0aW9uKFwiYWRkXCIpO30sXG4gICAgaW5kZW50TGVzczogZnVuY3Rpb24oY20pIHtjbS5pbmRlbnRTZWxlY3Rpb24oXCJzdWJ0cmFjdFwiKTt9LFxuICAgIGluc2VydFRhYjogZnVuY3Rpb24oY20pIHtjbS5yZXBsYWNlU2VsZWN0aW9uKFwiXFx0XCIpO30sXG4gICAgaW5zZXJ0U29mdFRhYjogZnVuY3Rpb24oY20pIHtcbiAgICAgIHZhciBzcGFjZXMgPSBbXSwgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKSwgdGFiU2l6ZSA9IGNtLm9wdGlvbnMudGFiU2l6ZTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBwb3MgPSByYW5nZXNbaV0uZnJvbSgpO1xuICAgICAgICB2YXIgY29sID0gY291bnRDb2x1bW4oY20uZ2V0TGluZShwb3MubGluZSksIHBvcy5jaCwgdGFiU2l6ZSk7XG4gICAgICAgIHNwYWNlcy5wdXNoK
23459G5ldyBBcnJheSh0YWJTaXplIC0gY29sICUgdGFiU2l6ZSArIDEpLmpvaW4oXCIgXCIpKTtcbiAgICAgIH1cbiAgICAgIGNtLnJlcGxhY2VTZWxlY3Rpb25zKHNwYWNlcyk7XG4gICAgfSxcbiAgICBkZWZhdWx0VGFiOiBmdW5jdGlvbihjbSkge1xuICAgICAgaWYgKGNtLnNvbWV0aGluZ1NlbGVjdGVkKCkpIGNtLmluZGVudFNlbGVjdGlvbihcImFkZFwiKTtcbiAgICAgIGVsc2UgY20uZXhlY0NvbW1hbmQoXCJpbnNlcnRUYWJcIik7XG4gICAgfSxcbiAgICB0cmFuc3Bvc2VDaGFyczogZnVuY3Rpb24oY20pIHtcbiAgICAgIHJ1bkluT3AoY20sIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKSwgbmV3U2VsID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIGN1ciA9IHJhbmdlc1tpXS5oZWFkLCBsaW5lID0gZ2V0TGluZShjbS5kb2MsIGN1ci5saW5lKS50ZXh0O1xuICAgICAgICAgIGlmIChsaW5lKSB7XG4gICAgICAgICAgICBpZiAoY3VyLmNoID09IGxpbmUubGVuZ3RoKSBjdXIgPSBuZXcgUG9zKGN1ci5saW5lLCBjdXIuY2ggLSAxKTtcbiAgICAgICAgICAgIGlmIChjdXIuY2ggPiAwKSB7XG4gICAgICAgICAgICAgIGN1ciA9IG5ldyBQb3MoY3VyLmxpbmUsIGN1ci5jaCArIDEpO1xuICAgICAgICAgICAgICBjbS5yZXBsYWNlUmFuZ2UobGluZS5jaGFyQXQoY3VyLmNoIC0gMSkgKyBsaW5lLmNoYXJBdChjdXIuY2ggLSAyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvcyhjdXIubGluZSwgY3VyLmNoIC0gMiksIGN1ciwgXCIrdHJhbnNwb3NlXCIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjdXIubGluZSA+IGNtLmRvYy5maXJzdCkge1xuICAgICAgICAgICAgICB2Y
23459XIgcHJldiA9IGdldExpbmUoY20uZG9jLCBjdXIubGluZSAtIDEpLnRleHQ7XG4gICAgICAgICAgICAgIGlmIChwcmV2KVxuICAgICAgICAgICAgICAgIGNtLnJlcGxhY2VSYW5nZShsaW5lLmNoYXJBdCgwKSArIGNtLmRvYy5saW5lU2VwYXJhdG9yKCkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmV2LmNoYXJBdChwcmV2Lmxlbmd0aCAtIDEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3MoY3VyLmxpbmUgLSAxLCBwcmV2Lmxlbmd0aCAtIDEpLCBQb3MoY3VyLmxpbmUsIDEpLCBcIit0cmFuc3Bvc2VcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIG5ld1NlbC5wdXNoKG5ldyBSYW5nZShjdXIsIGN1cikpO1xuICAgICAgICB9XG4gICAgICAgIGNtLnNldFNlbGVjdGlvbnMobmV3U2VsKTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgbmV3bGluZUFuZEluZGVudDogZnVuY3Rpb24oY20pIHtcbiAgICAgIHJ1bkluT3AoY20sIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbGVuID0gY20ubGlzdFNlbGVjdGlvbnMoKS5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICB2YXIgcmFuZ2UgPSBjbS5saXN0U2VsZWN0aW9ucygpW2ldO1xuICAgICAgICAgIGNtLnJlcGxhY2VSYW5nZShjbS5kb2MubGluZVNlcGFyYXRvcigpLCByYW5nZS5hbmNob3IsIHJhbmdlLmhlYWQsIFwiK2lucHV0XCIpO1xuICAgICAgICAgIGNtLmluZGVudExpbmUocmFuZ2UuZnJvbSgpLmxpbmUgKyAxLCBudWxsLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbnN1cmVDdXJzb3JWaXNpYmxlKGNtKTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgdG9nZ2xlT3ZlcndyaXRlOiBmdW5jdGlvbihjbSkge2NtLnRvZ2dsZU92ZXJ3cml0ZSgpO31cbiAgfTtcblxuXG4gIC8vIFNUQU5EQVJEIEtFWU1BUFNcblxuICB2YXIga2V5TWFwID0gQ29kZU1pcnJvci5rZXlNYXAgPSB7fTtcblxuICBrZXlNYXAuYmFzaWMgPSB7XG4gICAgXCJMZWZ0XCI6IFwiZ29DaGFyTGVmdFwiLCBcIlJpZ2h0XCI6IFwiZ29DaGFyUmlnaHRcIiwgXCJVcFwiOiBcImdvTGluZVVwXCIsIFwiRG93blwiOiBcImdvTGluZURvd25cIixcbiAgICBcIkVuZFwiOiBcImdvTGluZUVuZFwiLCBcIkhvbWVcIjogXCJnb0xpbmVTdGFydFNtYXJ0XCIsIFwiUGFnZVVwXCI6IFwiZ29QYWdlVXBcIiwgXCJQYWdlRG93blwiOiBcImdvUGFnZURvd25cIixcbiAgICBcIkRlbGV0ZVwiOiBcImRlbENoYXJBZnRlclwiLCBcIkJhY2tzcGFjZVwiOiBcImRlbENoYXJCZWZvcmVcIiwgXCJTaGlmdC1CYWNrc3BhY2VcIjogXCJkZWxDaGFyQmVmb3JlXCIsXG4gICAgXCJUYWJcIjogXCJkZWZhdWx0VGFiXCIsIFwiU2hpZnQtVGFiXCI6IFwiaW5kZW50QXV0b1wiLFxuICAgIFwiRW50ZXJcIjogXCJuZXdsaW5lQW5kSW5kZW50XCIsIFwiSW5zZXJ0XCI6IFwidG9nZ2xlT3ZlcndyaXRlXCIsXG4gICAgXCJFc2NcIjogXCJzaW5nbGVTZWxlY3Rpb25cIlxuICB9O1xuICAvLyBOb3RlIHRoYXQgdGhlIHNhdmUgYW5kIGZpbmQtcmVsYXRlZCBjb21tYW5kcyBhcmVuJ3QgZGVmaW5lZCBieVxuICAvLyBkZWZhdWx0LiBVc2VyIGNvZGUgb3IgYWRkb25zIGNhbiBkZWZpbmUgdGhlbS4gVW5rbm93biBjb21tYW5kc1xuICAvLyBhcmUgc2ltcGx5IGlnbm9yZWQuXG4gIGtleU1hcC5wY0RlZmF1bHQgPSB7XG4gICAgXCJDdHJsLUFcIjogXCJzZWxlY3RBbGxcIiwgXCJDdHJsLURcIjogXCJkZWxldGVMaW5lXCIsIFwiQ3RybC1aXCI6IFwidW5kb1wiLCBcIlNoaWZ0LUN0cmwtWlwiOiBcInJlZG9cIiwgXCJDdHJsLVlcIjogXCJyZWRvXCIsXG4gICAgXCJDdHJsLUhvbWVcIjogXCJnb0RvY1N0YXJ0XCIsIFwiQ3RybC1FbmRcIjogXCJnb0RvY0VuZFwiLCBcIkN0cmwtVXBcIjogXCJnb0xpbmVVcFwiLCBcIkN0cmwtRG93blwiOiBcImdvTGluZURvd25cIixcbiAgICBcIkN0cmwtTGVmdFwiOiBcImdvR3JvdXBMZWZ0XCIsIFwiQ3RybC1SaWdodFwiOiBcImdvR3JvdXBSaWdodFwiLCBcIkFsdC1MZWZ0XCI6IFwiZ29MaW5lU3RhcnRcIiwgXCJBbHQtUmlnaHRcIjogXCJnb0xpbmVFbmRcIixcbiAgICBcIkN0cmwtQmFja3NwYWNlXCI6IFwiZGVsR3JvdXBCZWZvcmVcIiwgXCJDdHJsLURlbGV0ZVwiOiBcImRlbEdyb3VwQWZ0ZXJcIiwgXCJDdHJsLVNcIjogXCJzYXZlXCIsIFwiQ3RybC1GXCI6IFwiZmluZFwiLFxuICAgIFwiQ3RybC1HXCI6IFwiZmluZE5leHRcIiwgXCJTaGlmdC1DdHJsLUdcIjogXCJmaW5kUHJldlwiLCBcIlNoaWZ0LUN0cmwtRlwiOiBcInJlcGxhY2VcIiwgXCJTaGlmdC1DdHJsLVJcIjogXCJyZXBsYWNlQWxsXCIsXG4gICAgXCJDdHJsLVtcIjogXCJpbmRlbnRMZXNzXCIsIFwiQ3RybC1dXCI6IFwiaW5kZW50TW9yZVwiLFxuICAgIFwiQ3RybC1VXCI6IFwidW5kb1NlbGVjdGlvblwiLCBcIlNoaWZ0LUN0cmwtVVwiOiBcInJlZG9TZWxlY3Rpb25cIiwgXCJBbHQtVVwiOiBcInJlZG9TZWxlY3Rpb25cIixcbiAgICBmYWxsdGhyb3VnaDogXCJiYXNpY1wiXG4gIH07XG4gIC8vIFZlcnkgYmFzaWMgcmVhZGxpbmUvZW1hY3Mtc3R5bGUgYmluZGluZ3MsIHdoaWNoIGFyZSBzdGFuZGFyZCBvbiBNYWMuXG4gIGtleU1hcC5lbWFjc3kgPSB7XG4gICAgXCJDdHJsLUZcIjogXCJnb0NoYXJSaWdodFwiLCBcIkN0cmwtQlwiOiBcImdvQ2hhckxlZnRcIiwgXCJDdHJsLVBcIjogXCJnb0xpbmVVcFwiLCBcIkN0cmwtTlwiOiBcImdvTGluZURvd25cIixcbiAgICBcIkFsdC1GXCI6IFwiZ29Xb3JkUmlnaHRcIiwgXCJBbHQtQlwiOiBcImdvV29yZExlZnRcIiwgXCJDdHJsLUFcIjogXCJnb0xpbmVTdGFydFwiLCBcIkN0cmwtRVwiOiBcImdvTGluZUVuZFwiLFxuICAgIFwiQ3RybC1WXCI6IFwiZ29QYWdlRG93blwiLCBcIlNoaWZ0LUN0cmwtVlwiOiBcImdvUGFnZVVwXCIsIFwiQ3RybC1EXCI6IFwiZGVsQ2hhckFmdGVyXCIsIFwiQ3RybC1IXCI6IFwiZGVsQ2hhckJlZm9yZVwiLFxuICAgIFwiQWx0LURcIjogXCJkZWxXb3JkQWZ0ZXJcIiwgXCJBbHQtQmFja3NwYWNlXCI6IFwiZGVsV29yZEJlZm9yZVwiLCBcIkN0cmwtS1wiOiBcImtpbGxMaW5lXCIsIFwiQ3RybC1UXCI6IFwidHJhbnNwb3NlQ2hhcnNcIlxuICB9O1xuICBrZXlNYXAubWFjRGVmYXVsdCA9IHtcbiAgICBcIkNtZC1BXCI6IFwic2VsZWN0QWxsXCIsIFwiQ21kLURcIjogXCJkZWxldGVMaW5lXCIsIFwiQ21kLVpcIjogXCJ1bmRvXCIsIFwiU2hpZnQtQ21kLVpcIjogXCJyZWRvXCIsIFwiQ21kLVlcIjogXCJyZWRvXCIsXG4gICAgXCJDbWQtSG9tZVwiOiBcImdvRG9jU3RhcnRcIiwgXCJDbWQtVXBcIjogXCJnb0RvY1N0YXJ0XCIsIFwiQ21kLUVuZFwiOiBcImdvRG9jRW5kXCIsIFwiQ21kLURvd25cIjogXCJnb0RvY0VuZFwiLCBcIkFsdC1MZWZ0XCI6IFwiZ29Hcm91cExlZnRcIixcbiAgICBcIkFsdC1SaWdodFwiOiBcImdvR3JvdXBSaWdodFwiLCBcIkNtZC1MZWZ0XCI6IFwiZ29MaW5lTGVmdFwiLCBcIkNtZC1SaWdodFwiOiBcImdvTGluZVJpZ2h0XCIsIFwiQWx0LUJhY2tzcGFjZVwiOiBcImRlbEdyb3VwQmVmb3JlXCIsXG4gICAgXCJDdHJsLUFsdC1CYWNrc3BhY2VcIjogXCJkZWxHcm91cEFmdGVyXCIsIFwiQWx0LURlbGV0ZVwiOiBcImRlbEdyb3VwQWZ0ZXJcIiwgXCJDbWQtU1wiOiBcInNhdmVcIiwgXCJDbWQtRlwiOiBcImZpbmRcIixcbiAgICBcIkNtZC1HXCI6IFwiZmluZE5leHRcIiwgXCJTaGlmdC1DbWQtR1wiOiBcImZpbmRQcmV2XCIsIFwiQ21kLUFsdC1GXCI6IFwicmVwbGFjZVwiLCBcIlNoaWZ0LUNtZC1BbHQtRlwiOiBcInJlcGxhY2VBbGxcIixcbiAgICBcIkNtZC1bXCI6IFwiaW5kZW50TGVzc1wiLCBcIkNtZC1dXCI6IFwiaW5kZW50TW9yZVwiLCBcIkNtZC1CYWNrc3BhY2VcIjogXCJkZWxXcmFwcGVkTGluZUxlZnRcIiwgXCJDbWQtRGVsZXRlXCI6IFwiZGVsV3JhcHBlZExpbmVSaWdodFwiLFxuICAgIFwiQ21kLVVcIjogXCJ1bmRvU2VsZWN0aW9uXCIsIFwiU2hpZnQtQ21kLVVcIjogXCJyZWRvU2VsZWN0aW9uXCIsIFwiQ3RybC1VcFwiOiBcImdvRG9jU3RhcnRcIiwgXCJDdHJsLURvd25cIjogXCJnb0RvY0VuZFwiLFxuICAgIGZhbGx0aHJvdWdoOiBbXCJiYXNpY1wiLCBcImVtYWNzeVwiXVxuICB9O1xuICBrZXlNYXBbXCJkZWZhdWx0XCJdID0gbWFjID8ga2V5TWFwLm1hY0RlZmF1bHQgOiBrZXlNYXAucGNEZWZhdWx0O
234591xuXG4gIC8vIEtFWU1BUCBESVNQQVRDSFxuXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZUtleU5hbWUobmFtZSkge1xuICAgIHZhciBwYXJ0cyA9IG5hbWUuc3BsaXQoLy0oPyEkKS8pLCBuYW1lID0gcGFydHNbcGFydHMubGVuZ3RoIC0gMV07XG4gICAgdmFyIGFsdCwgY3RybCwgc2hpZnQsIGNtZDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgdmFyIG1vZCA9IHBhcnRzW2ldO1xuICAgICAgaWYgKC9eKGNtZHxtZXRhfG0pJC9pLnRlc3QobW9kKSkgY21kID0gdHJ1ZTtcbiAgICAgIGVsc2UgaWYgKC9eYShsdCk/JC9pLnRlc3QobW9kKSkgYWx0ID0gdHJ1ZTtcbiAgICAgIGVsc2UgaWYgKC9eKGN8Y3RybHxjb250cm9sKSQvaS50ZXN0KG1vZCkpIGN0cmwgPSB0cnVlO1xuICAgICAgZWxzZSBpZiAoL15zKGhpZnQpJC9pLnRlc3QobW9kKSkgc2hpZnQgPSB0cnVlO1xuICAgICAgZWxzZSB0aHJvdyBuZXcgRXJyb3IoXCJVbnJlY29nbml6ZWQgbW9kaWZpZXIgbmFtZTogXCIgKyBtb2QpO1xuICAgIH1cbiAgICBpZiAoYWx0KSBuYW1lID0gXCJBbHQtXCIgKyBuYW1lO1xuICAgIGlmIChjdHJsKSBuYW1lID0gXCJDdHJsLVwiICsgbmFtZTtcbiAgICBpZiAoY21kKSBuYW1lID0gXCJDbWQtXCIgKyBuYW1lO1xuICAgIGlmIChzaGlmdCkgbmFtZSA9IFwiU2hpZnQtXCIgKyBuYW1lO1xuICAgIHJldHVybiBuYW1lO1xuICB9XG5cbiAgLy8gVGhpcyBpcyBhIGtsdWRnZSB0byBrZWVwIGtleW1hcHMgbW9zdGx5IHdvcmtpbmcgYXMgcmF3IG9iamVjdHNcbiAgLy8gKGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5KSB3aGlsZSBhdCB0aGUgc2FtZSB0aW1lIHN1cHBvcnQgZmVhdHVyZXNcbiAgLy8gbGlrZSBub3JtYWxpemF0aW9uIGFuZCBtdWx0aS1zdHJva2Uga2V5IGJpbmRpbmdzLiBJdCBjb21waWxlcyBhXG4gIC8vIG5ldyBub3JtYWxpemVkIGtleW1hcCwgYW5kIHRoZW4gdXBkYXRlcyB0aGUgb2xkIG9iamVjdCB0byByZWZsZWN0XG4gIC8vIHRoaXMuXG4gIENvZGVNaXJyb3Iubm9ybWFsaXplS2V5TWFwID0gZnVuY3Rpb24oa2V5bWFwKSB7XG4gICAgdmFyIGNvcHkgPSB7fTtcbiAgICBmb3IgKHZhciBrZXluYW1lIGluIGtleW1hcCkgaWYgKGtleW1hcC5oYXNPd25Qcm9wZXJ0eShrZXluYW1lKSkge1xuICAgICAgdmFyIHZhbHVlID0ga2V5bWFwW2tleW5hbWVdO1xuICAgICAgaWYgKC9eKG5hbWV8ZmFsbHRocm91Z2h8KGRlfGF0KXRhY2gpJC8udGVzdChrZXluYW1lKSkgY29udGludWU7XG4gICAgICBpZiAodmFsdWUgPT0gXCIuLi5cIikgeyBkZWxldGUga2V5bWFwW2tleW5hbWVdOyBjb250aW51ZTsgfVxuXG4gICAgICB2Y
23459XIga2V5cyA9IG1hcChrZXluYW1lLnNwbGl0KFwiIFwiKSwgbm9ybWFsaXplS2V5TmFtZSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHZhbCwgbmFtZTtcbiAgICAgICAgaWYgKGkgPT0ga2V5cy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgbmFtZSA9IGtleXMuam9pbihcIiBcIik7XG4gICAgICAgICAgdmFsID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmFtZSA9IGtleXMuc2xpY2UoMCwgaSArIDEpLmpvaW4oXCIgXCIpO1xuICAgICAgICAgIHZhbCA9IFwiLi4uXCI7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHByZXYgPSBjb3B5W25hbWVdO1xuICAgICAgICBpZiAoIXByZXYpIGNvcHlbbmFtZV0gPSB2YWw7XG4gICAgICAgIGVsc2UgaWYgKHByZXYgIT0gdmFsKSB0aHJvdyBuZXcgRXJyb3IoXCJJbmNvbnNpc3RlbnQgYmluZGluZ3MgZm9yIFwiICsgbmFtZSk7XG4gICAgICB9XG4gICAgICBkZWxldGUga2V5bWFwW2tleW5hbWVdO1xuICAgIH1cbiAgICBmb3IgKHZhciBwcm9wIGluIGNvcHkpIGtleW1hcFtwcm9wXSA9IGNvcHlbcHJvcF07XG4gICAgcmV0dXJuIGtleW1hcDtcbiAgfTtcblxuICB2YXIgbG9va3VwS2V5ID0gQ29kZU1pcnJvci5sb29rdXBLZXkgPSBmdW5jdGlvbihrZXksIG1hcCwgaGFuZGxlLCBjb250ZXh0KSB7XG4gICAgbWFwID0gZ2V0S2V5TWFwKG1hcCk7XG4gICAgdmFyIGZvdW5kID0gbWFwLmNhbGwgPyBtYXAuY2FsbChrZXksIGNvbnRleHQpIDogbWFwW2tleV07XG4gICAgaWYgKGZvdW5kID09PSBmYWxzZSkgcmV0dXJuIFwibm90aGluZ1wiO1xuICAgIGlmIChmb3VuZCA9PT0gXCIuLi5cIikgcmV0dXJuIFwibXVsdGlcIjtcbiAgICBpZiAoZm91bmQgIT0gbnVsbCAmJiBoYW5kbGUoZm91bmQpKSByZXR1cm4gXCJoYW5kbGVkXCI7XG5cbiAgICBpZiAobWFwLmZhbGx0aHJvdWdoKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1hcC5mYWxsdGhyb3VnaCkgIT0gXCJbb2JqZWN0IEFycmF5XVwiKVxuICAgICAgICByZXR1cm4gbG9va3VwS2V5KGtleSwgbWFwLmZhbGx0aHJvdWdoLCBoYW5kbGUsIGNvbnRleHQpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXAuZmFsbHRocm91Z2gubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGxvb2t1cEtleShrZXksIG1hcC5mYWxsdGhyb3VnaFtpXSwgaGFuZGxlLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKHJlc3VsdCkgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLy8gTW9kaWZpZXIga2V5IHByZXNzZXMgZG9uJ3QgY291bnQgYXMgJ3JlYWwnIGtleSBwcmVzc2VzIGZvciB0aGVcbiAgLy8gcHVycG9zZSBvZiBrZXltYXAgZmFsbHRocm91Z2guXG4gIHZhciBpc01vZGlmaWVyS2V5ID0gQ29kZU1pcnJvci5pc01vZGlmaWVyS2V5ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICB2YXIgbmFtZSA9IHR5cGVvZiB2YWx1ZSA9PSBcInN0cmluZ1wiID8gdmFsdWUgOiBrZXlOYW1lc1t2YWx1ZS5rZXlDb2RlXTtcbiAgICByZXR1cm4gbmFtZSA9PSBcIkN0cmxcIiB8fCBuYW1lID09IFwiQWx0XCIgfHwgbmFtZSA9PSBcIlNoaWZ0XCIgfHwgbmFtZSA9PSBcIk1vZFwiO1xuICB9O1xuXG4gIC8vIExvb2sgdXAgdGhlIG5hbWUgb2YgYSBrZXkgYXMgaW5kaWNhdGVkIGJ5IGFuIGV2ZW50IG9iamVjdC5cbiAgdmFyIGtleU5hbWUgPSBDb2RlTWlycm9yLmtleU5hbWUgPSBmdW5jdGlvbihldmVudCwgbm9TaGlmdCkge1xuICAgIGlmIChwcmVzdG8gJiYgZXZlbnQua2V5Q29kZSA9PSAzNCAmJiBldmVudFtcImNoYXJcIl0pIHJldHVybiBmYWxzZTtcbiAgICB2YXIgYmFzZSA9IGtleU5hbWVzW2V2ZW50LmtleUNvZGVdLCBuYW1lID0gYmFzZTtcbiAgICBpZiAobmFtZSA9PSBudWxsIHx8IGV2ZW50LmFsdEdyYXBoS2V5KSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGV2ZW50LmFsdEtleSAmJiBiYXNlICE9IFwiQWx0XCIpIG5hbWUgPSBcIkFsdC1cIiArIG5hbWU7XG4gICAgaWYgKChmbGlwQ3RybENtZCA/IGV2ZW50Lm1ldGFLZXkgOiBldmVudC5jdHJsS2V5KSAmJiBiYXNlICE9IFwiQ3RybFwiKSBuYW1lID0gXCJDdHJsLVwiICsgbmFtZTtcbiAgICBpZiAoKGZsaXBDdHJsQ21kID8gZXZlbnQuY3RybEtleSA6IGV2ZW50Lm1ldGFLZXkpICYmIGJhc2UgIT0gXCJDbWRcIikgbmFtZSA9IFwiQ21kLVwiICsgbmFtZTtcbiAgICBpZiAoIW5vU2hpZnQgJiYgZXZlbnQuc2hpZnRLZXkgJiYgYmFzZSAhPSBcIlNoaWZ0XCIpIG5hbWUgPSBcIlNoaWZ0LVwiICsgbmFtZTtcbiAgICByZXR1cm4gbmFtZTtcbiAgfTtcblxuICBmdW5jdGlvbiBnZXRLZXlNYXAodmFsKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWwgPT0gXCJzdHJpbmdcIiA/IGtleU1hcFt2YWxdIDogdmFsO1xuICB9XG5cbiAgLy8gRlJPTVRFWFRBUkVBXG5cbiAgQ29kZU1pcnJvci5mcm9tVGV4dEFyZWEgPSBmdW5jdGlvbih0ZXh0YXJlYSwgb3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zID8gY29weU9iaihvcHRpb25zKSA6IHt9O1xuICAgIG9wdGlvbnMudmFsdWUgPSB0ZXh0YXJlYS52YWx1ZTtcbiAgICBpZiAoIW9wdGlvbnMudGFiaW5kZXggJiYgdGV4dGFyZWEudGFiSW5kZXgpXG4gICAgICBvcHRpb25zLnRhYmluZGV4ID0gdGV4dGFyZWEudGFiSW5kZXg7XG4gICAgaWYgKCFvcHRpb25zLnBsYWNlaG9sZGVyICYmIHRleHRhcmVhLnBsYWNlaG9sZGVyKVxuICAgICAgb3B0aW9ucy5wbGFjZWhvbGRlciA9IHRleHRhcmVhLnBsYWNlaG9sZGVyO1xuICAgIC8vIFNldCBhdXRvZm9jdXMgdG8gdHJ1ZSBpZiB0aGlzIHRleHRhcmVhIGlzIGZvY3VzZWQsIG9yIGlmIGl0IGhhc1xuICAgIC8vIGF1dG9mb2N1cyBhbmQgbm8gb3RoZXIgZWxlbWVudCBpcyBmb2N1c2VkLlxuICAgIGlmIChvcHRpb25zLmF1dG9mb2N1cyA9PSBudWxsKSB7XG4gICAgICB2Y
23459XIgaGFzRm9jdXMgPSBhY3RpdmVFbHQoKTtcbiAgICAgIG9wdGlvbnMuYXV0b2ZvY3VzID0gaGFzRm9jdXMgPT0gdGV4dGFyZWEgfHxcbiAgICAgICAgdGV4dGFyZWEuZ2V0QXR0cmlidXRlKFwiYXV0b2ZvY3VzXCIpICE9IG51bGwgJiYgaGFzRm9jdXMgPT0gZG9jdW1lbnQuYm9keTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzYXZlKCkge3RleHRhcmVhLnZhbHVlID0gY20uZ2V0VmFsdWUoKTt9XG4gICAgaWYgKHRleHRhcmVhLmZvcm0pIHtcbiAgICAgIG9uKHRleHRhcmVhLmZvcm0sIFwic3VibWl0XCIsIHNhdmUpO1xuICAgICAgLy8gRGVwbG9yYWJsZSBoYWNrIHRvIG1ha2UgdGhlIHN1Ym1pdCBtZXRob2QgZG8gdGhlIHJpZ2h0IHRoaW5nLlxuICAgICAgaWYgKCFvcHRpb25zLmxlYXZlU3VibWl0TWV0aG9kQWxvbmUpIHtcbiAgICAgICAgdmFyIGZvcm0gPSB0ZXh0YXJlYS5mb3JtLCByZWFsU3VibWl0ID0gZm9ybS5zdWJtaXQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdmFyIHdyYXBwZWRTdWJtaXQgPSBmb3JtLnN1Ym1pdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgc2F2ZSgpO1xuICAgICAgICAgICAgZm9ybS5zdWJtaXQgPSByZWFsU3VibWl0O1xuICAgICAgICAgICAgZm9ybS5zdWJtaXQoKTtcbiAgICAgICAgICAgIGZvcm0uc3VibWl0ID0gd3JhcHBlZFN1Ym1pdDtcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoKGUpIHt9XG4gICAgICB9XG4gICAgfVxuXG4gICAgb3B0aW9ucy5maW5pc2hJbml0ID0gZnVuY3Rpb24oY20pIHtcbiAgICAgIGNtLnNhdmUgPSBzYXZlO1xuICAgICAgY20uZ2V0VGV4dEFyZWEgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRleHRhcmVhOyB9O1xuICAgICAgY20udG9UZXh0QXJlYSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBjbS50b1RleHRBcmVhID0gaXNOYU47IC8vIFByZXZlbnQgdGhpcyBmcm9tIGJlaW5nIHJhbiB0d2ljZVxuICAgICAgICBzYXZlKCk7XG4gICAgICAgIHRleHRhcmVhLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY20uZ2V0V3JhcHBlckVsZW1lbnQoKSk7XG4gICAgICAgIHRleHRhcmVhLnN0eWxlLmRpc3BsYXkgPSBcIlwiO1xuICAgICAgICBpZiAodGV4dGFyZWEuZm9ybSkge1xuICAgICAgICAgIG9mZih0ZXh0YXJlYS5mb3JtLCBcInN1Ym1pdFwiLCBzYXZlKTtcbiAgICAgICAgICBpZiAodHlwZW9mIHRleHRhcmVhLmZvcm0uc3VibWl0ID09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgICAgIHRleHRhcmVhLmZvcm0uc3VibWl0ID0gcmVhbFN1Ym1pdDtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdGV4dGFyZWEuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgIHZhciBjbSA9IENvZGVNaXJyb3IoZnVuY3Rpb24obm9kZSkge1xuICAgICAgdGV4dGFyZWEucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobm9kZSwgdGV4dGFyZWEubmV4dFNpYmxpbmcpO1xuICAgIH0sIG9wdGlvbnMpO1xuICAgIHJldHVybiBjbTtcbiAgfTtcblxuICAvLyBTVFJJTkcgU1RSRUFNXG5cbiAgLy8gRmVkIHRvIHRoZSBtb2RlIHBhcnNlcnMsIHByb3ZpZGVzIGhlbHBlciBmdW5jdGlvbnMgdG8gbWFrZVxuICAvLyBwYXJzZXJzIG1vcmUgc3VjY2luY3QuXG5cbiAgdmFyIFN0cmluZ1N0cmVhbSA9IENvZGVNaXJyb3IuU3RyaW5nU3RyZWFtID0gZnVuY3Rpb24oc3RyaW5nLCB0YWJTaXplKSB7XG4gICAgdGhpcy5wb3MgPSB0aGlzLnN0YXJ0ID0gMDtcbiAgICB0aGlzLnN0cmluZyA9IHN0cmluZztcbiAgICB0aGlzLnRhYlNpemUgPSB0YWJTaXplIHx8IDg7XG4gICAgdGhpcy5sYXN0Q29sdW1uUG9zID0gdGhpcy5sYXN0Q29sdW1uVmFsdWUgPSAwO1xuICAgIHRoaXMubGluZVN0YXJ0ID0gMDtcbiAgfTtcblxuICBTdHJpbmdTdHJlYW0ucHJvdG90eXBlID0ge1xuICAgIGVvbDogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMucG9zID49IHRoaXMuc3RyaW5nLmxlbmd0aDt9LFxuICAgIHNvbDogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMucG9zID09IHRoaXMubGluZVN0YXJ0O30sXG4gICAgcGVlazogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMuc3RyaW5nLmNoYXJBdCh0aGlzLnBvcykgfHwgdW5kZWZpbmVkO30sXG4gICAgbmV4dDogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5wb3MgPCB0aGlzLnN0cmluZy5sZW5ndGgpXG4gICAgICAgIHJldHVybiB0aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MrKyk7XG4gICAgfSxcbiAgICBlYXQ6IGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICB2Y
23459XIgY2ggPSB0aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MpO1xuICAgICAgaWYgKHR5cGVvZiBtYXRjaCA9PSBcInN0cmluZ1wiKSB2YXIgb2sgPSBjaCA9PSBtYXRjaDtcbiAgICAgIGVsc2UgdmFyIG9rID0gY2ggJiYgKG1hdGNoLnRlc3QgPyBtYXRjaC50ZXN0KGNoKSA6IG1hdGNoKGNoKSk7XG4gICAgICBpZiAob2spIHsrK3RoaXMucG9zOyByZXR1cm4gY2g7fVxuICAgIH0sXG4gICAgZWF0V2hpbGU6IGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICB2YXIgc3RhcnQgPSB0aGlzLnBvcztcbiAgICAgIHdoaWxlICh0aGlzLmVhdChtYXRjaCkpe31cbiAgICAgIHJldHVybiB0aGlzLnBvcyA+IHN0YXJ0O1xuICAgIH0sXG4gICAgZWF0U3BhY2U6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5wb3M7XG4gICAgICB3aGlsZSAoL1tcXHNcXHUwMGEwXS8udGVzdCh0aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MpKSkgKyt0aGlzLnBvcztcbiAgICAgIHJldHVybiB0aGlzLnBvcyA+IHN0YXJ0O1xuICAgIH0sXG4gICAgc2tpcFRvRW5kOiBmdW5jdGlvbigpIHt0aGlzLnBvcyA9IHRoaXMuc3RyaW5nLmxlbmd0aDt9LFxuICAgIHNraXBUbzogZnVuY3Rpb24oY2gpIHtcbiAgICAgIHZhciBmb3VuZCA9IHRoaXMuc3RyaW5nLmluZGV4T2YoY2gsIHRoaXMucG9zKTtcbiAgICAgIGlmIChmb3VuZCA+IC0xKSB7dGhpcy5wb3MgPSBmb3VuZDsgcmV0dXJuIHRydWU7fVxuICAgIH0sXG4gICAgYmFja1VwOiBmdW5jdGlvbihuKSB7dGhpcy5wb3MgLT0gbjt9LFxuICAgIGNvbHVtbjogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5sYXN0Q29sdW1uUG9zIDwgdGhpcy5zdGFydCkge1xuICAgICAgICB0aGlzLmxhc3RDb2x1bW5WYWx1ZSA9IGNvdW50Q29sdW1uKHRoaXMuc3RyaW5nLCB0aGlzLnN0YXJ0LCB0aGlzLnRhYlNpemUsIHRoaXMubGFzdENvbHVtblBvcywgdGhpcy5sYXN0Q29sdW1uVmFsdWUpO1xuICAgICAgICB0aGlzLmxhc3RDb2x1bW5Qb3MgPSB0aGlzLnN0YXJ0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMubGFzdENvbHVtblZhbHVlIC0gKHRoaXMubGluZVN0YXJ0ID8gY291bnRDb2x1bW4odGhpcy5zdHJpbmcsIHRoaXMubGluZVN0YXJ0LCB0aGlzLnRhYlNpemUpIDogMCk7XG4gICAgfSxcbiAgICBpbmRlbnRhdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gY291bnRDb2x1bW4odGhpcy5zdHJpbmcsIG51bGwsIHRoaXMudGFiU2l6ZSkgLVxuICAgICAgICAodGhpcy5saW5lU3RhcnQgPyBjb3VudENvbHVtbih0aGlzLnN0cmluZywgdGhpcy5saW5lU3RhcnQsIHRoaXMudGFiU2l6ZSkgOiAwKTtcbiAgICB9LFxuICAgIG1hdGNoOiBmdW5jdGlvbihwYXR0ZXJuLCBjb25zdW1lLCBjYXNlSW5zZW5zaXRpdmUpIHtcbiAgICAgIGlmICh0eXBlb2YgcGF0dGVybiA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHZhciBjYXNlZCA9IGZ1bmN0aW9uKHN0cikge3JldHVybiBjYXNlSW5zZW5zaXRpdmUgPyBzdHIudG9Mb3dlckNhc2UoKSA6IHN0cjt9O1xuICAgICAgICB2Y
23459XIgc3Vic3RyID0gdGhpcy5zdHJpbmcuc3Vic3RyKHRoaXMucG9zLCBwYXR0ZXJuLmxlbmd0aCk7XG4gICAgICAgIGlmIChjYXNlZChzdWJzdHIpID09IGNhc2VkKHBhdHRlcm4pKSB7XG4gICAgICAgICAgaWYgKGNvbnN1bWUgIT09IGZhbHNlKSB0aGlzLnBvcyArPSBwYXR0ZXJuLmxlbmd0aDtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIG1hdGNoID0gdGhpcy5zdHJpbmcuc2xpY2UodGhpcy5wb3MpLm1hdGNoKHBhdHRlcm4pO1xuICAgICAgICBpZiAobWF0Y2ggJiYgbWF0Y2guaW5kZXggPiAwKSByZXR1cm4gbnVsbDtcbiAgICAgICAgaWYgKG1hdGNoICYmIGNvbnN1bWUgIT09IGZhbHNlKSB0aGlzLnBvcyArPSBtYXRjaFswXS5sZW5ndGg7XG4gICAgICAgIHJldHVybiBtYXRjaDtcbiAgICAgIH1cbiAgICB9LFxuICAgIGN1cnJlbnQ6IGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuc3RyaW5nLnNsaWNlKHRoaXMuc3RhcnQsIHRoaXMucG9zKTt9LFxuICAgIGhpZGVGaXJzdENoYXJzOiBmdW5jdGlvbihuLCBpbm5lcikge1xuICAgICAgdGhpcy5saW5lU3RhcnQgKz0gbjtcbiAgICAgIHRyeSB7IHJldHVybiBpbm5lcigpOyB9XG4gICAgICBmaW5hbGx5IHsgdGhpcy5saW5lU3RhcnQgLT0gbjsgfVxuICAgIH1cbiAgfTtcblxuICAvLyBURVhUTUFSS0VSU1xuXG4gIC8vIENyZWF0ZWQgd2l0aCBtYXJrVGV4dCBhbmQgc2V0Qm9va21hcmsgbWV0aG9kcy4gQSBUZXh0TWFya2VyIGlzIGFcbiAgLy8gaGFuZGxlIHRoYXQgY2FuIGJlIHVzZWQgdG8gY2xlYXIgb3IgZmluZCBhIG1hcmtlZCBwb3NpdGlvbiBpbiB0aGVcbiAgLy8gZG9jdW1lbnQuIExpbmUgb2JqZWN0cyBob2xkIGFycmF5cyAobWFya2VkU3BhbnMpIGNvbnRhaW5pbmdcbiAgLy8ge2Zyb20sIHRvLCBtYXJrZXJ9IG9iamVjdCBwb2ludGluZyB0byBzdWNoIG1hcmtlciBvYmplY3RzLCBhbmRcbiAgLy8gaW5kaWNhdGluZyB0aGF0IHN1Y2ggYSBtYXJrZXIgaXMgcHJlc2VudCBvbiB0aGF0IGxpbmUuIE11bHRpcGxlXG4gIC8vIGxpbmVzIG1heSBwb2ludCB0byB0aGUgc2FtZSBtYXJrZXIgd2hlbiBpdCBzcGFucyBhY3Jvc3MgbGluZXMuXG4gIC8vIFRoZSBzcGFucyB3aWxsIGhhdmUgbnVsbCBmb3IgdGhlaXIgZnJvbS90byBwcm9wZXJ0aWVzIHdoZW4gdGhlXG4gIC8vIG1hcmtlciBjb250aW51ZXMgYmV5b25kIHRoZSBzdGFydC9lbmQgb2YgdGhlIGxpbmUuIE1hcmtlcnMgaGF2ZVxuICAvLyBsaW5rcyBiYWNrIHRvIHRoZSBsaW5lcyB0aGV5IGN1cnJlbnRseSB0b3VjaC5cblxuICB2YXIgbmV4dE1hcmtlcklkID0gMDtcblxuICB2YXIgVGV4dE1hcmtlciA9IENvZGVNaXJyb3IuVGV4dE1hcmtlciA9IGZ1bmN0aW9uKGRvYywgdHlwZSkge1xuICAgIHRoaXMubGluZXMgPSBbXTtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMuZG9jID0gZG9jO1xuICAgIHRoaXMuaWQgPSArK25leHRNYXJrZXJJZDtcbiAgfTtcbiAgZXZlbnRNaXhpbihUZXh0TWFya2VyKTtcblxuICAvLyBDbGVhciB0aGUgbWFya2VyLlxuICBUZXh0TWFya2VyLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLmV4cGxpY2l0bHlDbGVhcmVkKSByZXR1cm47XG4gICAgdmFyIGNtID0gdGhpcy5kb2MuY20sIHdpdGhPcCA9IGNtICYmICFjbS5jdXJPcDtcbiAgICBpZiAod2l0aE9wKSBzdGFydE9wZXJhdGlvbihjbSk7XG4gICAgaWYgKGhhc0hhbmRsZXIodGhpcywgXCJjbGVhclwiKSkge1xuICAgICAgdmFyIGZvdW5kID0gdGhpcy5maW5kKCk7XG4gICAgICBpZiAoZm91bmQpIHNpZ25hbExhdGVyKHRoaXMsIFwiY2xlYXJcIiwgZm91bmQuZnJvbSwgZm91bmQudG8pO1xuICAgIH1cbiAgICB2YXIgbWluID0gbnVsbCwgbWF4ID0gbnVsbDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGluZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBsaW5lID0gdGhpcy5saW5lc1tpXTtcbiAgICAgIHZhciBzcGFuID0gZ2V0TWFya2VkU3BhbkZvcihsaW5lLm1hcmtlZFNwYW5zLCB0aGlzKTtcbiAgICAgIGlmIChjbSAmJiAhdGhpcy5jb2xsYXBzZWQpIHJlZ0xpbmVDaGFuZ2UoY20sIGxpbmVObyhsaW5lKSwgXCJ0ZXh0XCIpO1xuICAgICAgZWxzZSBpZiAoY20pIHtcbiAgICAgICAgaWYgKHNwYW4udG8gIT0gbnVsbCkgbWF4ID0gbGluZU5vKGxpbmUpO1xuICAgICAgICBpZiAoc3Bhbi5mcm9tICE9IG51bGwpIG1pbiA9IGxpbmVObyhsaW5lKTtcbiAgICAgIH1cbiAgICAgIGxpbmUubWFya2VkU3BhbnMgPSByZW1vdmVNYXJrZWRTcGFuKGxpbmUubWFya2VkU3BhbnMsIHNwYW4pO1xuICAgICAgaWYgKHNwYW4uZnJvbSA9PSBudWxsICYmIHRoaXMuY29sbGFwc2VkICYmICFsaW5lSXNIaWRkZW4odGhpcy5kb2MsIGxpbmUpICYmIGNtKVxuICAgICAgICB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIHRleHRIZWlnaHQoY20uZGlzcGxheSkpO1xuICAgIH1cbiAgICBpZiAoY20gJiYgdGhpcy5jb2xsYXBzZWQgJiYgIWNtLm9wdGlvbnMubGluZVdyYXBwaW5nKSBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGluZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciB2aXN1YWwgPSB2aXN1YWxMaW5lKHRoaXMubGluZXNbaV0pLCBsZW4gPSBsaW5lTGVuZ3RoKHZpc3VhbCk7XG4gICAgICBpZiAobGVuID4gY20uZGlzcGxheS5tYXhMaW5lTGVuZ3RoKSB7XG4gICAgICAgIGNtLmRpc3BsYXkubWF4TGluZSA9IHZpc3VhbDtcbiAgICAgICAgY20uZGlzcGxheS5tYXhMaW5lTGVuZ3RoID0gbGVuO1xuICAgICAgICBjbS5kaXNwbGF5Lm1heExpbmVDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobWluICE9IG51bGwgJiYgY20gJiYgdGhpcy5jb2xsYXBzZWQpIHJlZ0NoYW5nZShjbSwgbWluLCBtYXggKyAxKTtcbiAgICB0aGlzLmxpbmVzLmxlbmd0aCA9IDA7XG4gICAgdGhpcy5leHBsaWNpdGx5Q2xlYXJlZCA9IHRydWU7XG4gICAgaWYgKHRoaXMuYXRvbWljICYmIHRoaXMuZG9jLmNhbnRFZGl0KSB7XG4gICAgICB0aGlzLmRvYy5jYW50RWRpdCA9IGZhbHNlO1xuICAgICAgaWYgKGNtKSByZUNoZWNrU2VsZWN0aW9uKGNtLmRvYyk7XG4gICAgfVxuICAgIGlmIChjbSkgc2lnbmFsTGF0ZXIoY20sIFwibWFya2VyQ2xlYXJlZFwiLCBjbSwgdGhpcyk7XG4gICAgaWYgKHdpdGhPcCkgZW5kT3BlcmF0aW9uKGNtKTtcbiAgICBpZiAodGhpcy5wYXJlbnQpIHRoaXMucGFyZW50LmNsZWFyKCk7XG4gIH07XG5cbiAgLy8gRmluZCB0aGUgcG9zaXRpb24gb2YgdGhlIG1hcmtlciBpbiB0aGUgZG9jdW1lbnQuIFJldHVybnMgYSB7ZnJvbSxcbiAgLy8gdG99IG9iamVjdCBieSBkZWZh
23459dWx0LiBTaWRlIGNhbiBiZSBwYXNzZWQgdG8gZ2V0IGEgc3BlY2lmaWMgc2lkZVxuICAvLyAtLSAwIChib3RoKSwgLTEgKGxlZnQpLCBvciAxIChyaWdodCkuIFdoZW4gbGluZU9iaiBpcyB0cnVlLCB0aGVcbiAgLy8gUG9zIG9iamVjdHMgcmV0dXJuZWQgY29udGFpbiBhIGxpbmUgb2JqZWN0LCByYXRoZXIgdGhhbiBhIGxpbmVcbiAgLy8gbnVtYmVyICh1c2VkIHRvIHByZXZlbnQgbG9va2luZyB1cCB0aGUgc2FtZSBsaW5lIHR3aWNlKS5cbiAgVGV4dE1hcmtlci5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uKHNpZGUsIGxpbmVPYmopIHtcbiAgICBpZiAoc2lkZSA9PSBudWxsICYmIHRoaXMudHlwZSA9PSBcImJvb2ttYXJrXCIpIHNpZGUgPSAxO1xuICAgIHZhciBmcm9tLCB0bztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGluZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBsaW5lID0gdGhpcy5saW5lc1tpXTtcbiAgICAgIHZhciBzcGFuID0gZ2V0TWFya2VkU3BhbkZvcihsaW5lLm1hcmtlZFNwYW5zLCB0aGlzKTtcbiAgICAgIGlmIChzcGFuLmZyb20gIT0gbnVsbCkge1xuICAgICAgICBmcm9tID0gUG9zKGxpbmVPYmogPyBsaW5lIDogbGluZU5vKGxpbmUpLCBzcGFuLmZyb20pO1xuICAgICAgICBpZiAoc2lkZSA9PSAtMSkgcmV0dXJuIGZyb207XG4gICAgICB9XG4gICAgICBpZiAoc3Bhbi50byAhPSBudWxsKSB7XG4gICAgICAgIHRvID0gUG9zKGxpbmVPYmogPyBsaW5lIDogbGluZU5vKGxpbmUpLCBzcGFuLnRvKTtcbiAgICAgICAgaWYgKHNpZGUgPT0gMSkgcmV0dXJuIHRvO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZnJvbSAmJiB7ZnJvbTogZnJvbSwgdG86IHRvfTtcbiAgfTtcblxuICAvLyBTaWduYWxzIHRoYXQgdGhlIG1hcmtlcidzIHdpZGdldCBjaGFuZ2VkLCBhbmQgc3Vycm91bmRpbmcgbGF5b3V0XG4gIC8vIHNob3VsZCBiZSByZWNvbXB1dGVkLlxuICBUZXh0TWFya2VyLnByb3RvdHlwZS5jaGFuZ2VkI
23459D0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHBvcyA9IHRoaXMuZmluZCgtMSwgdHJ1ZSksIHdpZGdldCA9IHRoaXMsIGNtID0gdGhpcy5kb2MuY207XG4gICAgaWYgKCFwb3MgfHwgIWNtKSByZXR1cm47XG4gICAgcnVuSW5PcChjbSwgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgbGluZSA9IHBvcy5saW5lLCBsaW5lTiA9IGxpbmVObyhwb3MubGluZSk7XG4gICAgICB2YXIgdmlldyA9IGZpbmRWaWV3Rm9yTGluZShjbSwgbGluZU4pO1xuICAgICAgaWYgKHZpZXcpIHtcbiAgICAgICAgY2xlYXJMaW5lTWVhc3VyZW1lbnRDYWNoZUZvcih2aWV3KTtcbiAgICAgICAgY20uY3VyT3Auc2VsZWN0aW9uQ2hhbmdlZCA9IGNtLmN1ck9wLmZvcmNlVXBkYXRlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGNtLmN1ck9wLnVwZGF0ZU1heExpbmUgPSB0cnVlO1xuICAgICAgaWYgKCFsaW5lSXNIaWRkZW4od2lkZ2V0LmRvYywgbGluZSkgJiYgd2lkZ2V0LmhlaWdodCAhPSBudWxsKSB7XG4gICAgICAgIHZhciBvbGRIZWlnaHQgPSB3aWRnZXQuaGVpZ2h0O1xuICAgICAgICB3aWRnZXQuaGVpZ2h0ID0gbnVsbDtcbiAgICAgICAgdmFyIGRIZWlnaHQgPSB3aWRnZXRIZWlnaHQod2lkZ2V0KSAtIG9sZEhlaWdodDtcbiAgICAgICAgaWYgKGRIZWlnaHQpXG4gICAgICAgICAgdXBkYXRlTGluZUhlaWdodChsaW5lLCBsaW5lLmhlaWdodCArIGRIZWlnaHQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIFRleHRNYXJrZXIucHJvdG90eXBlLmF0dGFjaExpbmUgPSBmdW5jdGlvbihsaW5lKSB7XG4gICAgaWYgKCF0aGlzLmxpbmVzLmxlbmd0aCAmJiB0aGlzLmRvYy5jbSkge1xuICAgICAgdmFyIG9wID0gdGhpcy5kb2MuY20uY3VyT3A7XG4gICAgICBpZiAoIW9wLm1heWJlSGlkZGVuTWFya2VycyB8fCBpbmRleE9mKG9wLm1heWJlSGlkZGVuTWFya2VycywgdGhpcykgPT0gLTEpXG4gICAgICAgIChvcC5tYXliZVVuaGlkZGVuTWFya2VycyB8fCAob3AubWF5YmVVbmhpZGRlbk1hcmtlcnMgPSBbXSkpLnB1c2godGhpcyk7XG4gICAgfVxuICAgIHRoaXMubGluZXMucHVzaChsaW5lKTtcbiAgfTtcbiAgVGV4dE1hcmtlci5wcm90b3R5cGUuZGV0YWNoTGluZSA9IGZ1bmN0aW9uKGxpbmUpIHtcbiAgICB0aGlzLmxpbmVzLnNwbGljZShpbmRleE9mKHRoaXMubGluZXMsIGxpbmUpLCAxKTtcbiAgICBpZiAoIXRoaXMubGluZXMubGVuZ3RoICYmIHRoaXMuZG9jLmNtKSB7XG4gICAgICB2Y
23459XIgb3AgPSB0aGlzLmRvYy5jbS5jdXJPcDtcbiAgICAgIChvcC5tYXliZUhpZGRlbk1hcmtlcnMgfHwgKG9wLm1heWJlSGlkZGVuTWFya2VycyA9IFtdKSkucHVzaCh0aGlzKTtcbiAgICB9XG4gIH07XG5cbiAgLy8gQ29sbGFwc2VkIG1hcmtlcnMgaGF2ZSB1bmlxdWUgaWRzLCBpbiBvcmRlciB0byBiZSBhYmxlIHRvIG9yZGVyXG4gIC8vIHRoZW0sIHdoaWNoIGlzIG5lZWRlZCBmb3IgdW5pcXVlbHkgZGV0ZXJtaW5pbmcgYW4gb3V0ZXIgbWFya2VyXG4gIC8vIHdoZW4gdGhleSBvdmVybGFwICh0aGV5IG1heSBuZXN0LCBidXQgbm90IHBhcnRpYWxseSBvdmVybGFwKS5cbiAgdmFyIG5leHRNYXJrZXJJZCA9IDA7XG5cbiAgLy8gQ3JlYXRlIGEgbWFya2VyLCB3aXJlIGl0IHVwIHRvIHRoZSByaWdodCBsaW5lcywgYW5kXG4gIGZ1bmN0aW9uIG1hcmtUZXh0KGRvYywgZnJvbSwgdG8sIG9wdGlvbnMsIHR5cGUpIHtcbiAgICAvLyBTaGFyZWQgbWFya2VycyAoYWNyb3NzIGxpbmtlZCBkb2N1bWVudHMpIGFyZSBoYW5kbGVkIHNlcGFyYXRlbHlcbiAgICAvLyAobWFya1RleHRTaGFyZWQgd2lsbCBjYWxsIG91dCB0byB0aGlzIGFnYWluLCBvbmNlIHBlclxuICAgIC8vIGRvY3VtZW50KS5cbiAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnNoYXJlZCkgcmV0dXJuIG1hcmtUZXh0U2hhcmVkKGRvYywgZnJvbSwgdG8sIG9wdGlvbnMsIHR5cGUpO1xuICAgIC8vIEVuc3VyZSB3ZSBhcmUgaW4gYW4gb3BlcmF0aW9uLlxuICAgIGlmIChkb2MuY20gJiYgIWRvYy5jbS5jdXJPcCkgcmV0dXJuIG9wZXJhdGlvbihkb2MuY20sIG1hcmtUZXh0KShkb2MsIGZyb20sIHRvLCBvcHRpb25zLCB0eXBlKTtcblxuICAgIHZhciBtYXJrZXIgPSBuZXcgVGV4dE1hcmtlcihkb2MsIHR5cGUpLCBkaWZmID0gY21wKGZyb20sIHRvKTtcbiAgICBpZiAob3B0aW9ucykgY29weU9iaihvcHRpb25zLCBtYXJrZXIsIGZhbHNlKTtcbiAgICAvLyBEb24ndCBjb25uZWN0IGVtcHR5IG1hcmtlcnMgdW5sZXNzIGNsZWFyV2hlbkVtcHR5IGlzIGZhbHNlXG4gICAgaWYgKGRpZmYgPiAwIHx8IGRpZmYgPT0gMCAmJiBtYXJrZXIuY2xlYXJXaGVuRW1wdHkgIT09IGZhbHNlKVxuICAgICAgcmV0dXJuIG1hcmtlcjtcbiAgICBpZiAobWFya2VyLnJlcGxhY2VkV2l0aCkge1xuICAgICAgLy8gU2hvd2luZyB1cCBhcyBhIHdpZGdldCBpbXBsaWVzIGNvbGxhcHNlZCAod2lkZ2V0IHJlcGxhY2VzIHRleHQpXG4gICAgICBtYXJrZXIuY29sbGFwc2VkID0gdHJ1ZTtcbiAgICAgIG1hcmtlci53aWRnZXROb2RlID0gZWx0KFwic3BhblwiLCBbbWFya2VyLnJlcGxhY2VkV2l0aF0sIFwiQ29kZU1pcnJvci13aWRnZXRcIik7XG4gICAgICBpZiAoIW9wdGlvbnMuaGFuZGxlTW91c2VFdmVudHMpIG1hcmtlci53aWRnZXROb2RlLnNldEF0dHJpYnV0ZShcImNtLWlnbm9yZS1ldmVud
23459HNcIiwgXCJ0cnVlXCIpO1xuICAgICAgaWYgKG9wdGlvbnMuaW5zZXJ0TGVmdCkgbWFya2VyLndpZGdldE5vZGUuaW5zZXJ0TGVmdCA9IHRydWU7XG4gICAgfVxuICAgIGlmIChtYXJrZXIuY29sbGFwc2VkKSB7XG4gICAgICBpZiAoY29uZmxpY3RpbmdDb2xsYXBzZWRSYW5nZShkb2MsIGZyb20ubGluZSwgZnJvbSwgdG8sIG1hcmtlcikgfHxcbiAgICAgICAgICBmcm9tLmxpbmUgIT0gdG8ubGluZSAmJiBjb25mbGljdGluZ0NvbGxhcHNlZFJhbmdlKGRvYywgdG8ubGluZSwgZnJvbSwgdG8sIG1hcmtlcikpXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkluc2VydGluZyBjb2xsYXBzZWQgbWFya2VyIHBhcnRpYWxseSBvdmVybGFwcGluZyBhbiBleGlzdGluZyBvbmVcIik7XG4gICAgICBzYXdDb2xsYXBzZWRTcGFucyA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKG1hcmtlci5hZGRUb0hpc3RvcnkpXG4gICAgICBhZGRDaGFuZ2VUb0hpc3RvcnkoZG9jLCB7ZnJvbTogZnJvbSwgdG86IHRvLCBvcmlnaW46IFwibWFya1RleHRcIn0sIGRvYy5zZWwsIE5hTik7XG5cbiAgICB2YXIgY3VyTGluZSA9IGZyb20ubGluZSwgY20gPSBkb2MuY20sIHVwZGF0ZU1heExpbmU7XG4gICAgZG9jLml0ZXIoY3VyTGluZSwgdG8ubGluZSArIDEsIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgIGlmIChjbSAmJiBtYXJrZXIuY29sbGFwc2VkICYmICFjbS5vcHRpb25zLmxpbmVXcmFwcGluZyAmJiB2aXN1YWxMaW5lKGxpbmUpID09IGNtLmRpc3BsYXkubWF4TGluZSlcbiAgICAgICAgdXBkYXRlTWF4TGluZSA9IHRydWU7XG4gICAgICBpZiAobWFya2VyLmNvbGxhcHNlZCAmJiBjdXJMaW5lICE9IGZyb20ubGluZSkgdXBkYXRlTGluZUhlaWdodChsaW5lLCAwKTtcbiAgICAgIGFkZE1hcmtlZFNwYW4obGluZSwgbmV3IE1hcmtlZFNwYW4obWFya2VyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJMaW5lID09IGZyb20ubGluZSA/IGZyb20uY2ggOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJMaW5lID09IHRvLmxpbmUgPyB0by5jaCA6IG51bGwpKTtcbiAgICAgICsrY3VyTGluZTtcbiAgICB9KTtcbiAgICAvLyBsaW5lSXNIaWRkZW4gZGVwZW5kcyBvbiB0aGUgcHJlc2VuY2Ugb2YgdGhlIHNwYW5zLCBzbyBuZWVkcyBhIHNlY29uZCBwYXNzXG4gICAgaWYgKG1hcmtlci5jb2xsYXBzZWQpIGRvYy5pdGVyKGZyb20ubGluZSwgdG8ubGluZSArIDEsIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgIGlmIChsaW5lSXNIaWRkZW4oZG9jLCBsaW5lKSkgdXBkYXRlTGluZUhlaWdodChsaW5lLCAwKTtcbiAgICB9KTtcblxuICAgIGlmIChtYXJrZXIuY2xlYXJPbkVudGVyKSBvbihtYXJrZXIsIFwiYmVmb3JlQ3Vyc29yRW50ZXJcIiwgZnVuY3Rpb24oKSB7IG1hcmtlci5jbGVhcigpOyB9KTtcblxuICAgIGlmIChtYXJrZXIucmVhZE9ubHkpIHtcbiAgICAgIHNhd1JlYWRPbmx5U3BhbnMgPSB0cnVlO1xuICAgICAgaWYgKGRvYy5oaXN0b3J5LmRvbmUubGVuZ3RoIHx8IGRvYy5oaXN0b3J5LnVuZG9uZS5sZW5ndGgpXG4gICAgICAgIGRvYy5jbGVhckhpc3RvcnkoKTtcbiAgICB9XG4gICAgaWYgKG1hcmtlci5jb2xsYXBzZWQpIHtcbiAgICAgIG1hcmtlci5pZCA9ICsrbmV4dE1hcmtlcklkO1xuICAgICAgbWFya2VyLmF0b21pYyA9IHRydWU7XG4gICAgfVxuICAgIGlmIChjbSkge1xuICAgICAgLy8gU3luYyBlZGl0b3Igc3RhdGVcbiAgICAgIGlmICh1cGRhdGVNYXhMaW5lKSBjbS5jdXJPcC51cGRhdGVNYXhMaW5lID0gdHJ1ZTtcbiAgICAgIGlmIChtYXJrZXIuY29sbGFwc2VkKVxuICAgICAgICByZWdDaGFuZ2UoY20sIGZyb20ubGluZSwgdG8ubGluZSArIDEpO1xuICAgICAgZWxzZSBpZiAobWFya2VyLmNsYXNzTmFtZSB8fCBtYXJrZXIudGl0bGUgfHwgbWFya2VyLnN0YXJ0U3R5bGUgfHwgbWFya2VyLmVuZFN0eWxlIHx8IG1hcmtlci5jc3MpXG4gICAgICAgIGZvciAodmFyIGkgPSBmcm9tLmxpbmU7IGkgPD0gdG8ubGluZTsgaSsrKSByZWdMaW5lQ2hhbmdlKGNtLCBpLCBcInRleHRcIik7XG4gICAgICBpZiAobWFya2VyLmF0b21pYykgcmVDaGVja1NlbGVjdGlvbihjbS5kb2MpO1xuICAgICAgc2lnbmFsTGF0ZXIoY20sIFwibWFya2VyQWRkZWRcIiwgY20sIG1hcmtlcik7XG4gICAgfVxuICAgIHJldHVybiBtYXJrZXI7XG4gIH1cblxuICAvLyBTSEFSRUQgVEVYVE1BUktFUlNcblxuICAvLyBBIHNoYXJlZCBtYXJrZXIgc3BhbnMgbXVsdGlwbGUgbGlua2VkIGRvY3VtZW50cy4gSXQgaXNcbiAgLy8gaW1wbGVtZW50ZWQgYXMgYSBtZXRhLW1hcmtlci1vYmplY3QgY29udHJvbGxpbmcgbXVsdGlwbGUgbm9ybWFsXG4gIC8vIG1hcmtlcnMuXG4gIHZhciBTaGFyZWRUZXh0TWFya2VyID0gQ29kZU1pcnJvci5TaGFyZWRUZXh0TWFya2VyID0gZnVuY3Rpb24obWFya2VycywgcHJpbWFyeSkge1xuICAgIHRoaXMubWFya2VycyA9IG1hcmtlcnM7XG4gICAgdGhpcy5wcmltYXJ5ID0gcHJpbWFyeTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1hcmtlcnMubGVuZ3RoOyArK2kpXG4gICAgICBtYXJrZXJzW2ldLnBhcmVudCA9IHRoaXM7XG4gIH07XG4gIGV2ZW50TWl4aW4oU2hhcmVkVGV4dE1hcmtlcik7XG5cbiAgU2hhcmVkVGV4dE1hcmtlci5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5leHBsaWNpdGx5Q2xlYXJlZCkgcmV0dXJuO1xuICAgIHRoaXMuZXhwbGljaXRseUNsZWFyZWQgPSB0cnVlO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tYXJrZXJzLmxlbmd0aDsgKytpKVxuICAgICAgdGhpcy5tYXJrZXJzW2ldLmNsZWFyKCk7XG4gICAgc2lnbmFsTGF0ZXIodGhpcywgXCJjbGVhclwiKTtcbiAgfTtcbiAgU2hhcmVkVGV4dE1hcmtlci5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uKHNpZGUsIGxpbmVPYmopIHtcbiAgICByZXR1cm4gdGhpcy5wcmltYXJ5LmZpbmQoc2lkZSwgbGluZU9iaik7XG4gIH07XG5cbiAgZnVuY3Rpb24gbWFya1RleHRTaGFyZWQoZG9jLCBmcm9tLCB0bywgb3B0aW9ucywgdHlwZSkge1xuICAgIG9wdGlvbnMgPSBjb3B5T2JqKG9wdGlvbnMpO1xuICAgIG9wdGlvbnMuc2hhcmVkID0gZmFsc2U7XG4gICAgdmFyIG1hcmtlcnMgPSBbbWFya1RleHQoZG9jLCBmcm9tLCB0bywgb3B0aW9ucywgdHlwZSldLCBwcmltYXJ5ID0gbWFya2Vyc1swXTtcbiAgICB2YXIgd2lkZ2V0ID0gb3B0aW9ucy53aWRnZXROb2RlO1xuICAgIGxpbmtlZERvY3MoZG9jLCBmdW5jdGlvbihkb2MpIHtcbiAgICAgIGlmICh3aWRnZXQpIG9wdGlvbnMud2lkZ2V0Tm9kZSA9IHdpZGdldC5jbG9uZU5vZGUodHJ1ZSk7XG4gICAgICBtYXJrZXJzLnB1c2gobWFya1RleHQoZG9jLCBjbGlwUG9zKGRvYywgZnJvbSksIGNsaXBQb3MoZG9jLCB0byksIG9wdGlvbnMsIHR5cGUpKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZG9jLmxpbmtlZC5sZW5ndGg7ICsraSlcbiAgICAgICAgaWYgKGRvYy5saW5rZWRbaV0uaXNQYXJlbnQpIHJldHVybjtcbiAgICAgIHByaW1hcnkgPSBsc3QobWFya2Vycyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ldyBTaGFyZWRUZXh0TWFya2VyKG1hcmtlcnMsIHByaW1hcnkpO1xuICB9XG5cbiAgZnVuY3Rpb24gZmluZFNoYXJlZE1hcmtlcnMoZG9jKSB7XG4gICAgcmV0dXJuIGRvYy5maW5kTWFya3MoUG9zKGRvYy5maXJzdCwgMCksIGRvYy5jbGlwUG9zKFBvcyhkb2MubGFzdExpbmUoKSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKG0pIHsgcmV0dXJuIG0ucGFyZW50OyB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvcHlTaGFyZWRNYXJrZXJzKGRvYywgbWFya2Vycykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWFya2Vycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIG1hcmtlciA9IG1hcmtlcnNbaV0sIHBvcyA9IG1hcmtlci5maW5kKCk7XG4gICAgICB2Y
23459XIgbUZyb20gPSBkb2MuY2xpcFBvcyhwb3MuZnJvbSksIG1UbyA9IGRvYy5jbGlwUG9zKHBvcy50byk7XG4gICAgICBpZiAoY21wKG1Gcm9tLCBtVG8pKSB7XG4gICAgICAgIHZhciBzdWJNYXJrID0gbWFya1RleHQoZG9jLCBtRnJvbSwgbVRvLCBtYXJrZXIucHJpbWFyeSwgbWFya2VyLnByaW1hcnkudHlwZSk7XG4gICAgICAgIG1hcmtlci5tYXJrZXJzLnB1c2goc3ViTWFyayk7XG4gICAgICAgIHN1Yk1hcmsucGFyZW50ID0gbWFya2VyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRldGFjaFNoYXJlZE1hcmtlcnMobWFya2Vycykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWFya2Vycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIG1hcmtlciA9IG1hcmtlcnNbaV0sIGxpbmtlZCA9IFttYXJrZXIucHJpbWFyeS5kb2NdOztcbiAgICAgIGxpbmtlZERvY3MobWFya2VyLnByaW1hcnkuZG9jLCBmdW5jdGlvbihkKSB7IGxpbmtlZC5wdXNoKGQpOyB9KTtcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWFya2VyLm1hcmtlcnMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgdmFyIHN1Yk1hcmtlciA9IG1hcmtlci5tYXJrZXJzW2pdO1xuICAgICAgICBpZiAoaW5kZXhPZihsaW5rZWQsIHN1Yk1hcmtlci5kb2MpID09IC0xKSB7XG4gICAgICAgICAgc3ViTWFya2VyLnBhcmVudCA9IG51bGw7XG4gICAgICAgICAgbWFya2VyLm1hcmtlcnMuc3BsaWNlKGotLSwgMSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBURVhUTUFSS0VSIFNQQU5TXG5cbiAgZnVuY3Rpb24gTWFya2VkU3BhbihtYXJrZXIsIGZyb20sIHRvKSB7XG4gICAgdGhpcy5tYXJrZXIgPSBtYXJrZXI7XG4gICAgdGhpcy5mcm9tID0gZnJvbTsgdGhpcy50byA9IHRvO1xuICB9XG5cbiAgLy8gU2VhcmNoIGFuIGFycmF5IG9mIHNwYW5zIGZvciBhIHNwYW4gbWF0Y2hpbmcgdGhlIGdpdmVuIG1hcmtlci5cbiAgZnVuY3Rpb24gZ2V0TWFya2VkU3BhbkZvcihzcGFucywgbWFya2VyKSB7XG4gICAgaWYgKHNwYW5zKSBmb3IgKHZhciBpID0gMDsgaSA8IHNwYW5zLmxlbmd0aDsgKytpKSB7XG4gICAgICB2Y
23459XIgc3BhbiA9IHNwYW5zW2ldO1xuICAgICAgaWYgKHNwYW4ubWFya2VyID09IG1hcmtlcikgcmV0dXJuIHNwYW47XG4gICAgfVxuICB9XG4gIC8vIFJlbW92ZSBhIHNwYW4gZnJvbSBhbiBhcnJheSwgcmV0dXJuaW5nIHVuZGVmaW5lZCBpZiBubyBzcGFucyBhcmVcbiAgLy8gbGVmdCAod2UgZG9uJ3Qgc3RvcmUgYXJyYXlzIGZvciBsaW5lcyB3aXRob3V0IHNwYW5zKS5cbiAgZnVuY3Rpb24gcmVtb3ZlTWFya2VkU3BhbihzcGFucywgc3Bhbikge1xuICAgIGZvciAodmFyIHIsIGkgPSAwOyBpIDwgc3BhbnMubGVuZ3RoOyArK2kpXG4gICAgICBpZiAoc3BhbnNbaV0gIT0gc3BhbikgKHIgfHwgKHIgPSBbXSkpLnB1c2goc3BhbnNbaV0pO1xuICAgIHJldHVybiByO1xuICB9XG4gIC8vIEFkZCBhIHNwYW4gdG8gYSBsaW5lLlxuICBmdW5jdGlvbiBhZGRNYXJrZWRTcGFuKGxpbmUsIHNwYW4pIHtcbiAgICBsaW5lLm1hcmtlZFNwYW5zID0gbGluZS5tYXJrZWRTcGFucyA/IGxpbmUubWFya2VkU3BhbnMuY29uY2F0KFtzcGFuXSkgOiBbc3Bhbl07XG4gICAgc3Bhbi5tYXJrZXIuYXR0YWNoTGluZShsaW5lKTtcbiAgfVxuXG4gIC8vIFVzZWQgZm9yIHRoZSBhbGdvcml0aG0gdGhhdCBhZGp1c3RzIG1hcmtlcnMgZm9yIGEgY2hhbmdlIGluIHRoZVxuICAvLyBkb2N1bWVudC4gVGhlc2UgZnVuY3Rpb25zIGN1dCBhbiBhcnJheSBvZiBzcGFucyBhdCBhIGdpdmVuXG4gIC8vIGNoYXJhY3RlciBwb3NpdGlvbiwgcmV0dXJuaW5nIGFuIGFycmF5IG9mIHJlbWFpbmluZyBjaHVua3MgKG9yXG4gIC8vIHVuZGVmaW5lZCBpZiBub3RoaW5nIHJlbWFpbnMpLlxuICBmdW5jdGlvbiBtYXJrZWRTcGFuc0JlZm9yZShvbGQsIHN0YXJ0Q2gsIGlzSW5zZXJ0KSB7XG4gICAgaWYgKG9sZCkgZm9yICh2YXIgaSA9IDAsIG53OyBpIDwgb2xkLmxlbmd0aDsgKytpKSB7XG4gICAgICB2Y
23459XIgc3BhbiA9IG9sZFtpXSwgbWFya2VyID0gc3Bhbi5tYXJrZXI7XG4gICAgICB2YXIgc3RhcnRzQmVmb3JlID0gc3Bhbi5mcm9tID09IG51bGwgfHwgKG1hcmtlci5pbmNsdXNpdmVMZWZ0ID8gc3Bhbi5mcm9tIDw9IHN0YXJ0Q2ggOiBzcGFuLmZyb20gPCBzdGFydENoKTtcbiAgICAgIGlmIChzdGFydHNCZWZvcmUgfHwgc3Bhbi5mcm9tID09IHN0YXJ0Q2ggJiYgbWFya2VyLnR5cGUgPT0gXCJib29rbWFya1wiICYmICghaXNJbnNlcnQgfHwgIXNwYW4ubWFya2VyLmluc2VydExlZnQpKSB7XG4gICAgICAgIHZhciBlbmRzQWZ0ZXIgPSBzcGFuLnRvID09IG51bGwgfHwgKG1hcmtlci5pbmNsdXNpdmVSaWdodCA/IHNwYW4udG8gPj0gc3RhcnRDaCA6IHNwYW4udG8gPiBzdGFydENoKTtcbiAgICAgICAgKG53IHx8IChudyA9IFtdKSkucHVzaChuZXcgTWFya2VkU3BhbihtYXJrZXIsIHNwYW4uZnJvbSwgZW5kc0FmdGVyID8gbnVsbCA6IHNwYW4udG8pKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG53O1xuICB9XG4gIGZ1bmN0aW9uIG1hcmtlZFNwYW5zQWZ0ZXIob2xkLCBlbmRDaCwgaXNJbnNlcnQpIHtcbiAgICBpZiAob2xkKSBmb3IgKHZhciBpID0gMCwgbnc7IGkgPCBvbGQubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBzcGFuID0gb2xkW2ldLCBtYXJrZXIgPSBzcGFuLm1hcmtlcjtcbiAgICAgIHZhciBlbmRzQWZ0ZXIgPSBzcGFuLnRvID09IG51bGwgfHwgKG1hcmtlci5pbmNsdXNpdmVSaWdodCA/IHNwYW4udG8gPj0gZW5kQ2ggOiBzcGFuLnRvID4gZW5kQ2gpO1xuICAgICAgaWYgKGVuZHNBZnRlciB8fCBzcGFuLmZyb20gPT0gZW5kQ2ggJiYgbWFya2VyLnR5cGUgPT0gXCJib29rbWFya1wiICYmICghaXNJbnNlcnQgfHwgc3Bhbi5tYXJrZXIuaW5zZXJ0TGVmdCkpIHtcbiAgICAgICAgdmFyIHN0YXJ0c0JlZm9yZSA9IHNwYW4uZnJvbSA9PSBudWxsIHx8IChtYXJrZXIuaW5jbHVzaXZlTGVmdCA/IHNwYW4uZnJvbSA8PSBlbmRDaCA6IHNwYW4uZnJvbSA8IGVuZENoKTtcbiAgICAgICAgKG53IHx8IChudyA9IFtdKSkucHVzaChuZXcgTWFya2VkU3BhbihtYXJrZXIsIHN0YXJ0c0JlZm9yZSA/IG51bGwgOiBzcGFuLmZyb20gLSBlbmRDaCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFuLnRvID09IG51bGwgPyBudWxsIDogc3Bhbi50byAtIGVuZENoKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudztcbiAgfVxuXG4gIC8vIEdpdmVuIGEgY2hhbmdlIG9iamVjdCwgY29tcHV0ZSB0aGUgbmV3IHNldCBvZiBtYXJrZXIgc3BhbnMgdGhhdFxuICAvLyBjb3ZlciB0aGUgbGluZSBpbiB3aGljaCB0aGUgY2hhbmdlIHRvb2sgcGxhY2UuIFJlbW92ZXMgc3BhbnNcbiAgLy8gZW50aXJlbHkgd2l0aGluIHRoZSBjaGFuZ2UsIHJlY29ubmVjdHMgc3BhbnMgYmVsb25naW5nIHRvIHRoZVxuICAvLyBzYW1lIG1hcmtlciB0aGF0IGFwcGVhciBvbiBib3RoIHNpZGVzIG9mIHRoZSBjaGFuZ2UsIGFuZCBjdXRzIG9mZlxuICAvLyBzcGFucyBwYXJ0aWFsbHkgd2l0aGluIHRoZSBjaGFuZ2UuIFJldHVybnMgYW4gYXJyYXkgb2Ygc3BhblxuICAvLyBhcnJheXMgd2l0aCBvbmUgZWxlbWVudCBmb3IgZWFjaCBsaW5lIGluIChhZnRlcikgdGhlIGNoYW5nZS5cbiAgZnVuY3Rpb24gc3RyZXRjaFNwYW5zT3ZlckNoYW5nZShkb2MsIGNoYW5nZSkge1xuICAgIGlmIChjaGFuZ2UuZnVsbCkgcmV0dXJuIG51bGw7XG4gICAgdmFyIG9sZEZpcnN0ID0gaXNMaW5lKGRvYywgY2hhbmdlLmZyb20ubGluZSkgJiYgZ2V0TGluZShkb2MsIGNoYW5nZS5mcm9tLmxpbmUpLm1hcmtlZFNwYW5zO1xuICAgIHZhciBvbGRMYXN0ID0gaXNMaW5lKGRvYywgY2hhbmdlLnRvLmxpbmUpICYmIGdldExpbmUoZG9jLCBjaGFuZ2UudG8ubGluZSkubWFya2VkU3BhbnM7XG4gICAgaWYgKCFvbGRGaXJzdCAmJiAhb2xkTGFzdCkgcmV0dXJuIG51bGw7XG5cbiAgICB2YXIgc3RhcnRDaCA9IGNoYW5nZS5mcm9tLmNoLCBlbmRDaCA9IGNoYW5nZS50by5jaCwgaXNJbnNlcnQgPSBjbXAoY2hhbmdlLmZyb20sIGNoYW5nZS50bykgPT0gMDtcbiAgICAvLyBHZXQgdGhlIHNwYW5zIHRoYXQgJ3N0aWNrIG91dCcgb24gYm90aCBzaWRlc1xuICAgIHZhciBmaXJzdCA9IG1hcmtlZFNwYW5zQmVmb3JlKG9sZEZpcnN0LCBzdGFydENoLCBpc0luc2VydCk7XG4gICAgdmFyIGxhc3QgPSBtYXJrZWRTcGFuc0FmdGVyKG9sZExhc3QsIGVuZENoLCBpc0luc2VydCk7XG5cbiAgICAvLyBOZXh0LCBtZXJnZSB0aG9zZSB0d28gZW5kc1xuICAgIHZhciBzYW1lTGluZSA9IGNoYW5nZS50ZXh0Lmxlbmd0aCA9PSAxLCBvZmZzZXQgPSBsc3QoY2hhbmdlLnRleHQpLmxlbmd0aCArIChzYW1lTGluZSA/IHN0YXJ0Q2ggOiAwKTtcbiAgICBpZiAoZmlyc3QpIHtcbiAgICAgIC8vIEZpeCB1cCAudG8gcHJvcGVydGllcyBvZiBmaXJzdFxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaXJzdC5sZW5ndGg7ICsraSkge1xuICAgICAgICB2Y
23459XIgc3BhbiA9IGZpcnN0W2ldO1xuICAgICAgICBpZiAoc3Bhbi50byA9PSBudWxsKSB7XG4gICAgICAgICAgdmFyIGZvdW5kID0gZ2V0TWFya2VkU3BhbkZvcihsYXN0LCBzcGFuLm1hcmtlcik7XG4gICAgICAgICAgaWYgKCFmb3VuZCkgc3Bhbi50byA9IHN0YXJ0Q2g7XG4gICAgICAgICAgZWxzZSBpZiAoc2FtZUxpbmUpIHNwYW4udG8gPSBmb3VuZC50byA9PSBudWxsID8gbnVsbCA6IGZvdW5kLnRvICsgb2Zmc2V0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChsYXN0KSB7XG4gICAgICAvLyBGaXggdXAgLmZyb20gaW4gbGFzdCAob3IgbW92ZSB0aGVtIGludG8gZmlyc3QgaW4gY2FzZSBvZiBzYW1lTGluZSlcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGFzdC5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgc3BhbiA9IGxhc3RbaV07XG4gICAgICAgIGlmIChzcGFuLnRvICE9IG51bGwpIHNwYW4udG8gKz0gb2Zmc2V0O1xuICAgICAgICBpZiAoc3Bhbi5mcm9tID09IG51bGwpIHtcbiAgICAgICAgICB2YXIgZm91bmQgPSBnZXRNYXJrZWRTcGFuRm9yKGZpcnN0LCBzcGFuLm1hcmtlcik7XG4gICAgICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICAgICAgc3Bhbi5mcm9tID0gb2Zmc2V0O1xuICAgICAgICAgICAgaWYgKHNhbWVMaW5lKSAoZmlyc3QgfHwgKGZpcnN0ID0gW10pKS5wdXNoKHNwYW4pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzcGFuLmZyb20gKz0gb2Zmc2V0O1xuICAgICAgICAgIGlmIChzYW1lTGluZSkgKGZpcnN0IHx8IChmaXJzdCA9IFtdKSkucHVzaChzcGFuKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBNYWtlIHN1cmUgd2UgZGlkbid0IGNyZWF0ZSBhbnkgemVyby1sZW5ndGggc3BhbnNcbiAgICBpZiAoZmlyc3QpIGZpcnN0ID0gY2xlYXJFbXB0eVNwYW5zKGZpcnN0KTtcbiAgICBpZiAobGFzdCAmJiBsYXN0ICE9IGZpcnN0KSBsYXN0ID0gY2xlYXJFbXB0eVNwYW5zKGxhc3QpO1xuXG4gICAgdmFyIG5ld01hcmtlcnMgPSBbZmlyc3RdO1xuICAgIGlmICghc2FtZUxpbmUpIHtcbiAgICAgIC8vIEZpbGwgZ2FwIHdpdGggd2hvbGUtbGluZS1zcGFuc1xuICAgICAgdmFyIGdhcCA9IGNoYW5nZS50ZXh0Lmxlbmd0aCAtIDIsIGdhcE1hcmtlcnM7XG4gICAgICBpZiAoZ2FwID4gMCAmJiBmaXJzdClcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmaXJzdC5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoZmlyc3RbaV0udG8gPT0gbnVsbClcbiAgICAgICAgICAgIChnYXBNYXJrZXJzIHx8IChnYXBNYXJrZXJzID0gW10pKS5wdXNoKG5ldyBNYXJrZWRTcGFuKGZpcnN0W2ldLm1hcmtlciwgbnVsbCwgbnVsbCkpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBnYXA7ICsraSlcbiAgICAgICAgbmV3TWFya2Vycy5wdXNoKGdhcE1hcmtlcnMpO1xuICAgICAgbmV3TWFya2Vycy5wdXNoKGxhc3QpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3TWFya2VycztcbiAgfVxuXG4gIC8vIFJlbW92ZSBzcGFucyB0aGF0IGFyZSBlbXB0eSBhbmQgZG9uJ3QgaGF2ZSBhIGNsZWFyV2hlbkVtcHR5XG4gIC8vIG9wdGlvbiBvZiBmYWxzZS5cbiAgZnVuY3Rpb24gY2xlYXJFbXB0eVNwYW5zKHNwYW5zKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzcGFucy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIHNwYW4gPSBzcGFuc1tpXTtcbiAgICAgIGlmIChzcGFuLmZyb20gIT0gbnVsbCAmJiBzcGFuLmZyb20gPT0gc3Bhbi50byAmJiBzcGFuLm1hcmtlci5jbGVhcldoZW5FbXB0eSAhPT0gZmFsc2UpXG4gICAgICAgIHNwYW5zLnNwbGljZShpLS0sIDEpO1xuICAgIH1cbiAgICBpZiAoIXNwYW5zLmxlbmd0aCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHNwYW5zO1xuICB9XG5cbiAgLy8gVXNlZCBmb3IgdW4vcmUtZG9pbmcgY2hhbmdlcyBmcm9tIHRoZSBoaXN0b3J5LiBDb21iaW5lcyB0aGVcbiAgLy8gcmVzdWx0IG9mIGNvbXB1dGluZyB0aGUgZXhpc3Rpbmcgc3BhbnMgd2l0aCB0aGUgc2V0IG9mIHNwYW5zIHRoYXRcbiAgLy8gZXhpc3RlZCBpbiB0aGUgaGlzdG9yeSAoc28gdGhhdCBkZWxldGluZyBhcm91bmQgYSBzcGFuIGFuZCB0aGVuXG4gIC8vIHVuZG9pbmcgYnJpbmdzIGJhY2sgdGhlIHNwYW4pLlxuICBmdW5jdGlvbiBtZXJnZU9sZFNwYW5zKGRvYywgY2hhbmdlKSB7XG4gICAgdmFyIG9sZCA9IGdldE9sZFNwYW5zKGRvYywgY2hhbmdlKTtcbiAgICB2YXIgc3RyZXRjaGVkID0gc3RyZXRjaFNwYW5zT3ZlckNoYW5nZShkb2MsIGNoYW5nZSk7XG4gICAgaWYgKCFvbGQpIHJldHVybiBzdHJldGNoZWQ7XG4gICAgaWYgKCFzdHJldGNoZWQpIHJldHVybiBvbGQ7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9sZC5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIG9sZEN1ciA9IG9sZFtpXSwgc3RyZXRjaEN1ciA9IHN0cmV0Y2hlZFtpXTtcbiAgICAgIGlmIChvbGRDdXIgJiYgc3RyZXRjaEN1cikge1xuICAgICAgICBzcGFuczogZm9yICh2YXIgaiA9IDA7IGogPCBzdHJldGNoQ3VyLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgdmFyIHNwYW4gPSBzdHJldGNoQ3VyW2pdO1xuICAgICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgb2xkQ3VyLmxlbmd0aDsgKytrKVxuICAgICAgICAgICAgaWYgKG9sZEN1cltrXS5tYXJrZXIgPT0gc3Bhbi5tYXJrZXIpIGNvbnRpbnVlIHNwYW5zO1xuICAgICAgICAgIG9sZEN1ci5wdXNoKHNwYW4pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHN0cmV0Y2hDdXIpIHtcbiAgICAgICAgb2xkW2ldID0gc3RyZXRjaEN1cjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9sZDtcbiAgfVxuXG4gIC8vIFVzZWQgdG8gJ2NsaXAnIG91dCByZWFkT25seSByYW5nZXMgd2hlbiBtYWtpbmcgYSBjaGFuZ2UuXG4gIGZ1bmN0aW9uIHJlbW92ZVJlYWRPbmx5UmFuZ2VzKGRvYywgZnJvbSwgdG8pIHtcbiAgICB2YXIgbWFya2VycyA9IG51bGw7XG4gICAgZG9jLml0ZXIoZnJvbS5saW5lLCB0by5saW5lICsgMSwgZnVuY3Rpb24obGluZSkge1xuICAgICAgaWYgKGxpbmUubWFya2VkU3BhbnMpIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZS5tYXJrZWRTcGFucy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2Y
23459XIgbWFyayA9IGxpbmUubWFya2VkU3BhbnNbaV0ubWFya2VyO1xuICAgICAgICBpZiAobWFyay5yZWFkT25seSAmJiAoIW1hcmtlcnMgfHwgaW5kZXhPZihtYXJrZXJzLCBtYXJrKSA9PSAtMSkpXG4gICAgICAgICAgKG1hcmtlcnMgfHwgKG1hcmtlcnMgPSBbXSkpLnB1c2gobWFyayk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKCFtYXJrZXJzKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgcGFydHMgPSBbe2Zyb206IGZyb20sIHRvOiB0b31dO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWFya2Vycy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIG1rID0gbWFya2Vyc1tpXSwgbSA9IG1rLmZpbmQoMCk7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHBhcnRzLmxlbmd0aDsgKytqKSB7XG4gICAgICAgIHZhciBwID0gcGFydHNbal07XG4gICAgICAgIGlmIChjbXAocC50bywgbS5mcm9tKSA8IDAgfHwgY21wKHAuZnJvbSwgbS50bykgPiAwKSBjb250aW51ZTtcbiAgICAgICAgdmFyIG5ld1BhcnRzID0gW2osIDFdLCBkZnJvbSA9IGNtcChwLmZyb20sIG0uZnJvbSksIGR0byA9IGNtcChwLnRvLCBtLnRvKTtcbiAgICAgICAgaWYgKGRmcm9tIDwgMCB8fCAhbWsuaW5jbHVzaXZlTGVmdCAmJiAhZGZyb20pXG4gICAgICAgICAgbmV3UGFydHMucHVzaCh7ZnJvbTogcC5mcm9tLCB0bzogbS5mcm9tfSk7XG4gICAgICAgIGlmIChkdG8gPiAwIHx8ICFtay5pbmNsdXNpdmVSaWdodCAmJiAhZHRvKVxuICAgICAgICAgIG5ld1BhcnRzLnB1c2goe2Zyb206IG0udG8sIHRvOiBwLnRvfSk7XG4gICAgICAgIHBhcnRzLnNwbGljZS5hcHBseShwYXJ0cywgbmV3UGFydHMpO1xuICAgICAgICBqICs9IG5ld1BhcnRzLmxlbmd0aCAtIDE7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwYXJ0cztcbiAgfVxuXG4gIC8vIENvbm5lY3Qgb3IgZGlzY29ubmVjdCBzcGFucyBmcm9tIGEgbGluZS5cbiAgZnVuY3Rpb24gZGV0YWNoTWFya2VkU3BhbnMobGluZSkge1xuICAgIHZhciBzcGFucyA9IGxpbmUubWFya2VkU3BhbnM7XG4gICAgaWYgKCFzcGFucykgcmV0dXJuO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3BhbnMubGVuZ3RoOyArK2kpXG4gICAgICBzcGFuc1tpXS5tYXJrZXIuZGV0YWNoTGluZShsaW5lKTtcbiAgICBsaW5lLm1hcmtlZFNwYW5zID0gbnVsbDtcbiAgfVxuICBmdW5jdGlvbiBhdHRhY2hNYXJrZWRTcGFucyhsaW5lLCBzcGFucykge1xuICAgIGlmICghc3BhbnMpIHJldHVybjtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNwYW5zLmxlbmd0aDsgKytpKVxuICAgICAgc3BhbnNbaV0ubWFya2VyLmF0dGFjaExpbmUobGluZSk7XG4gICAgbGluZS5tYXJrZWRTcGFucyA9IHNwYW5zO1xuICB9XG5cbiAgLy8gSGVscGVycyB1c2VkIHdoZW4gY29tcHV0aW5nIHdoaWNoIG92ZXJsYXBwaW5nIGNvbGxhcHNlZCBzcGFuXG4gIC8vIGNvdW50cyBhcyB0aGUgbGFyZ2VyIG9uZS5cbiAgZnVuY3Rpb24gZXh0cmFMZWZ0KG1hcmtlcikgeyByZXR1cm4gbWFya2VyLmluY2x1c2l2ZUxlZnQgPyAtMSA6IDA7IH1cbiAgZnVuY3Rpb24gZXh0cmFSaWdodChtYXJrZXIpIHsgcmV0dXJuIG1hcmtlci5pbmNsdXNpdmVSaWdodCA/IDEgOiAwOyB9XG5cbiAgLy8gUmV0dXJucyBhIG51bWJlciBpbmRpY2F0aW5nIHdoaWNoIG9mIHR3byBvdmVybGFwcGluZyBjb2xsYXBzZWRcbiAgLy8gc3BhbnMgaXMgbGFyZ2VyIChhbmQgdGh1cyBpbmNsdWRlcyB0aGUgb3RoZXIpLiBGYWxscyBiYWNrIHRvXG4gIC8vIGNvbXBhcmluZyBpZHMgd2hlbiB0aGUgc3BhbnMgY292ZXIgZXhhY3RseSB0aGUgc2FtZSByYW5nZS5cbiAgZnVuY3Rpb24gY29tcGFyZUNvbGxhcHNlZE1hcmtlcnMoYSwgYikge1xuICAgIHZhciBsZW5EaWZmID0gYS5saW5lcy5sZW5ndGggLSBiLmxpbmVzLmxlbmd0aDtcbiAgICBpZiAobGVuRGlmZiAhPSAwKSByZXR1cm4gbGVuRGlmZjtcbiAgICB2YXIgYVBvcyA9IGEuZmluZCgpLCBiUG9zID0gYi5maW5kKCk7XG4gICAgdmFyIGZyb21DbXAgPSBjbXAoYVBvcy5mcm9tLCBiUG9zLmZyb20pIHx8IGV4dHJhTGVmdChhKSAtIGV4dHJhTGVmdChiKTtcbiAgICBpZiAoZnJvbUNtcCkgcmV0dXJuIC1mcm9tQ21wO1xuICAgIHZhciB0b0NtcCA9IGNtcChhUG9zLnRvLCBiUG9zLnRvKSB8fCBleHRyYVJpZ2h0KGEpIC0gZXh0cmFSaWdodChiKTtcbiAgICBpZiAodG9DbXApIHJldHVybiB0b0NtcDtcbiAgICByZXR1cm4gYi5pZCAtIGEuaWQ7XG4gIH1cblxuICAvLyBGaW5kIG91dCB3aGV0aGVyIGEgbGluZSBlbmRzIG9yIHN0YXJ0cyBpbiBhIGNvbGxhcHNlZCBzcGFuLiBJZlxuICAvLyBzbywgcmV0dXJuIHRoZSBtYXJrZXIgZm9yIHRoYXQgc3Bhbi5cbiAgZnVuY3Rpb24gY29sbGFwc2VkU3BhbkF0U2lkZShsaW5lLCBzdGFydCkge1xuICAgIHZhciBzcHMgP
23459SBzYXdDb2xsYXBzZWRTcGFucyAmJiBsaW5lLm1hcmtlZFNwYW5zLCBmb3VuZDtcbiAgICBpZiAoc3BzKSBmb3IgKHZhciBzcCwgaSA9IDA7IGkgPCBzcHMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHNwID0gc3BzW2ldO1xuICAgICAgaWYgKHNwLm1hcmtlci5jb2xsYXBzZWQgJiYgKHN0YXJ0ID8gc3AuZnJvbSA6IHNwLnRvKSA9PSBudWxsICYmXG4gICAgICAgICAgKCFmb3VuZCB8fCBjb21wYXJlQ29sbGFwc2VkTWFya2Vycyhmb3VuZCwgc3AubWFya2VyKSA8IDApKVxuICAgICAgICBmb3VuZCA9IHNwLm1hcmtlcjtcbiAgICB9XG4gICAgcmV0dXJuIGZvdW5kO1xuICB9XG4gIGZ1bmN0aW9uIGNvbGxhcHNlZFNwYW5BdFN0YXJ0KGxpbmUpIHsgcmV0dXJuIGNvbGxhcHNlZFNwYW5BdFNpZGUobGluZSwgdHJ1ZSk7IH1cbiAgZnVuY3Rpb24gY29sbGFwc2VkU3BhbkF0RW5kKGxpbmUpIHsgcmV0dXJuIGNvbGxhcHNlZFNwYW5BdFNpZGUobGluZSwgZmFsc2UpOyB9XG5cbiAgLy8gVGVzdCB3aGV0aGVyIHRoZXJlIGV4aXN0cyBhIGNvbGxhcHNlZCBzcGFuIHRoYXQgcGFydGlhbGx5XG4gIC8vIG92ZXJsYXBzIChjb3ZlcnMgdGhlIHN0YXJ0IG9yIGVuZCwgYnV0IG5vdCBib3RoKSBvZiBhIG5ldyBzcGFuLlxuICAvLyBTdWNoIG92ZXJsYXAgaXMgbm90IGFsbG93ZWQuXG4gIGZ1bmN0aW9uIGNvbmZsaWN0aW5nQ29sbGFwc2VkUmFuZ2UoZG9jLCBsaW5lTm8sIGZyb20sIHRvLCBtYXJrZXIpIHtcbiAgICB2YXIgbGluZSA9IGdldExpbmUoZG9jLCBsaW5lTm8pO1xuICAgIHZhciBzcHMgP
23459SBzYXdDb2xsYXBzZWRTcGFucyAmJiBsaW5lLm1hcmtlZFNwYW5zO1xuICAgIGlmIChzcHMpIGZvciAodmFyIGkgPSAwOyBpIDwgc3BzLmxlbmd0aDsgKytpKSB7XG4gICAgICB2YXIgc3AgPSBzcHNbaV07XG4gICAgICBpZiAoIXNwLm1hcmtlci5jb2xsYXBzZWQpIGNvbnRpbnVlO1xuICAgICAgdmFyIGZvdW5kID0gc3AubWFya2VyLmZpbmQoMCk7XG4gICAgICB2YXIgZnJvbUNtcCA9IGNtcChmb3VuZC5mcm9tLCBmcm9tKSB8fCBleHRyYUxlZnQoc3AubWFya2VyKSAtIGV4dHJhTGVmdChtYXJrZXIpO1xuICAgICAgdmFyIHRvQ21wID0gY21wKGZvdW5kLnRvLCB0bykgfHwgZXh0cmFSaWdodChzcC5tYXJrZXIpIC0gZXh0cmFSaWdodChtYXJrZXIpO1xuICAgICAgaWYgKGZyb21DbXAgPj0gMCAmJiB0b0NtcCA8PSAwIHx8IGZyb21DbXAgPD0gMCAmJiB0b0NtcCA+PSAwKSBjb250aW51ZTtcbiAgICAgIGlmIChmcm9tQ21wIDw9IDAgJiYgKGNtcChmb3VuZC50bywgZnJvbSkgPiAwIHx8IChzcC5tYXJrZXIuaW5jbHVzaXZlUmlnaHQgJiYgbWFya2VyLmluY2x1c2l2ZUxlZnQpKSB8fFxuICAgICAgICAgIGZyb21DbXAgPj0gMCAmJiAoY21wKGZvdW5kLmZyb20sIHRvKSA8IDAgfHwgKHNwLm1hcmtlci5pbmNsdXNpdmVMZWZ0ICYmIG1hcmtlci5pbmNsdXNpdmVSaWdodCkpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvLyBBIHZpc3VhbCBsaW5lIGlzIGEgbGluZSBhcyBkcmF3biBvbiB0aGUgc2NyZWVuLiBGb2xkaW5nLCBmb3JcbiAgLy8gZXhhbXBsZSwgY2FuIGNhdXNlIG11bHRpcGxlIGxvZ2ljYWwgbGluZXMgdG8gYXBwZWFyIG9uIHRoZSBzYW1lXG4gIC8vIHZpc3VhbCBsaW5lLiBUaGlzIGZpbmRzIHRoZSBzdGFydCBvZiB0aGUgdmlzdWFsIGxpbmUgdGhhdCB0aGVcbiAgLy8gZ2l2ZW4gbGluZSBpcyBwYXJ0IG9mICh1c3VhbGx5IHRoYXQgaXMgdGhlIGxpbmUgaXRzZWxmKS5cbiAgZnVuY3Rpb24gdmlzdWFsTGluZShsaW5lKSB7XG4gICAgdmFyIG1lcmdlZDtcbiAgICB3aGlsZSAobWVyZ2VkID0gY29sbGFwc2VkU3BhbkF0U3RhcnQobGluZSkpXG4gICAgICBsaW5lID0gbWVyZ2VkLmZpbmQoLTEsIHRydWUpLmxpbmU7XG4gICAgcmV0dXJuIGxpbmU7XG4gIH1cblxuICAvLyBSZXR1cm5zIGFuIGFycmF5IG9mIGxvZ2ljYWwgbGluZXMgdGhhdCBjb250aW51ZSB0aGUgdmlzdWFsIGxpbmVcbiAgLy8gc3RhcnRlZCBieSB0aGUgYXJndW1lbnQsIG9yIHVuZGVmaW5lZCBpZiB0aGVyZSBhcmUgbm8gc3VjaCBsaW5lcy5cbiAgZnVuY3Rpb24gdmlzdWFsTGluZUNvbnRpbnVlZChsaW5lKSB7XG4gICAgdmFyIG1lcmdlZCwgbGluZXM7XG4gICAgd2hpbGUgKG1lcmdlZCA9IGNvbGxhcHNlZFNwYW5BdEVuZChsaW5lKSkge1xuICAgICAgbGluZSA9IG1lcmdlZC5maW5kKDEsIHRydWUpLmxpbmU7XG4gICAgICAobGluZXMgfHwgKGxpbmVzID0gW10pKS5wdXNoKGxpbmUpO1xuICAgIH1cbiAgICByZXR1cm4gbGluZXM7XG4gIH1cblxuICAvLyBHZXQgdGhlIGxpbmUgbnVtYmVyIG9mIHRoZSBzdGFydCBvZiB0aGUgdmlzdWFsIGxpbmUgdGhhdCB0aGVcbiAgLy8gZ2l2ZW4gbGluZSBudW1iZXIgaXMgcGFydCBvZi5cbiAgZnVuY3Rpb24gdmlzdWFsTGluZU5vKGRvYywgbGluZU4pIHtcbiAgICB2YXIgbGluZSA9IGdldExpbmUoZG9jLCBsaW5lTiksIHZpcyA9IHZpc3VhbExpbmUobGluZSk7XG4gICAgaWYgKGxpbmUgPT0gdmlzKSByZXR1cm4gbGluZU47XG4gICAgcmV0dXJuIGxpbmVObyh2aXMpO1xuICB9XG4gIC8vIEdldCB0aGUgbGluZSBudW1iZXIgb2YgdGhlIHN0YXJ0IG9mIHRoZSBuZXh0IHZpc3VhbCBsaW5lIGFmdGVyXG4gIC8vIHRoZSBnaXZlbiBsaW5lLlxuICBmdW5jdGlvbiB2aXN1YWxMaW5lRW5kTm8oZG9jLCBsaW5lTikge1xuICAgIGlmIChsaW5lTiA+IGRvYy5sYXN0TGluZSgpKSByZXR1cm4gbGluZU47XG4gICAgdmFyIGxpbmUgPSBnZXRMaW5lKGRvYywgbGluZU4pLCBtZXJnZWQ7XG4gICAgaWYgKCFsaW5lSXNIaWRkZW4oZG9jLCBsaW5lKSkgcmV0dXJuIGxpbmVOO1xuICAgIHdoaWxlIChtZXJnZWQgPSBjb2xsYXBzZWRTcGFuQXRFbmQobGluZSkpXG4gICAgICBsaW5lID0gbWVyZ2VkLmZpbmQoMSwgdHJ1ZSkubGluZTtcbiAgICByZXR1cm4gbGluZU5vKGxpbmUpICsgMTtcbiAgfVxuXG4gIC8vIENvbXB1dGUgd2hldGhlciBhIGxpbmUgaXMgaGlkZGVuLiBMaW5lcyBjb3VudCBhcyBoaWRkZW4gd2hlbiB0aGV5XG4gIC8vIGFyZSBwYXJ0IG9mIGEgdmlzdWFsIGxpbmUgdGhhdCBzdGFydHMgd2l0aCBhbm90aGVyIGxpbmUsIG9yIHdoZW5cbiAgLy8gdGhleSBhcmUgZW50aXJlbHkgY292ZXJlZCBieSBjb2xsYXBzZWQsIG5vbi13aWRnZXQgc3Bhbi5cbiAgZnVuY3Rpb24gbGluZUlzSGlkZGVuKGRvYywgbGluZSkge1xuICAgIHZhciBzcHMgP
23459SBzYXdDb2xsYXBzZWRTcGFucyAmJiBsaW5lLm1hcmtlZFNwYW5zO1xuICAgIGlmIChzcHMpIGZvciAodmFyIHNwLCBpID0gMDsgaSA8IHNwcy5sZW5ndGg7ICsraSkge1xuICAgICAgc3AgPSBzcHNbaV07XG4gICAgICBpZiAoIXNwLm1hcmtlci5jb2xsYXBzZWQpIGNvbnRpbnVlO1xuICAgICAgaWYgKHNwLmZyb20gPT0gbnVsbCkgcmV0dXJuIHRydWU7XG4gICAgICBpZiAoc3AubWFya2VyLndpZGdldE5vZGUpIGNvbnRpbnVlO1xuICAgICAgaWYgKHNwLmZyb20gPT0gMCAmJiBzcC5tYXJrZXIuaW5jbHVzaXZlTGVmdCAmJiBsaW5lSXNIaWRkZW5Jbm5lcihkb2MsIGxpbmUsIHNwKSlcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIGxpbmVJc0hpZGRlbklubmVyKGRvYywgbGluZSwgc3Bhbikge1xuICAgIGlmIChzcGFuLnRvID09IG51bGwpIHtcbiAgICAgIHZhciBlbmQgPSBzcGFuLm1hcmtlci5maW5kKDEsIHRydWUpO1xuICAgICAgcmV0dXJuIGxpbmVJc0hpZGRlbklubmVyKGRvYywgZW5kLmxpbmUsIGdldE1hcmtlZFNwYW5Gb3IoZW5kLmxpbmUubWFya2VkU3BhbnMsIHNwYW4ubWFya2VyKSk7XG4gICAgfVxuICAgIGlmIChzcGFuLm1hcmtlci5pbmNsdXNpdmVSaWdodCAmJiBzcGFuLnRvID09IGxpbmUudGV4dC5sZW5ndGgpXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICBmb3IgKHZhciBzcCwgaSA9IDA7IGkgPCBsaW5lLm1hcmtlZFNwYW5zLmxlbmd0aDsgKytpKSB7XG4gICAgICBzcCA9IGxpbmUubWFya2VkU3BhbnNbaV07XG4gICAgICBpZiAoc3AubWFya2VyLmNvbGxhcHNlZCAmJiAhc3AubWFya2VyLndpZGdldE5vZGUgJiYgc3AuZnJvbSA9PSBzcGFuLnRvICYmXG4gICAgICAgICAgKHNwLnRvID09IG51bGwgfHwgc3AudG8gIT0gc3Bhbi5mcm9tKSAmJlxuICAgICAgICAgIChzcC5tYXJrZXIuaW5jbHVzaXZlTGVmdCB8fCBzcGFuLm1hcmtlci5pbmNsdXNpdmVSaWdodCkgJiZcbiAgICAgICAgICBsaW5lSXNIaWRkZW5Jbm5lcihkb2MsIGxpbmUsIHNwKSkgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gTElORSBXSURHRVRTXG5cbiAgLy8gTGluZSB3aWRnZXRzIGFyZSBibG9jayBlbGVtZW50cyBkaXNwbGF5ZWQgYWJvdmUgb3IgYmVsb3cgYSBsaW5lLlxuXG4gIHZhciBMaW5lV2lkZ2V0ID0gQ29kZU1pcnJvci5MaW5lV2lkZ2V0ID0gZnVuY3Rpb24oZG9jLCBub2RlLCBvcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbnMpIGZvciAodmFyIG9wdCBpbiBvcHRpb25zKSBpZiAob3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShvcHQpKVxuICAgICAgdGhpc1tvcHRdID0gb3B0aW9uc1tvcHRdO1xuICAgIHRoaXMuZG9jID0gZG9jO1xuICAgIHRoaXMubm9kZSA9IG5vZGU7XG4gIH07XG4gIGV2ZW50TWl4aW4oTGluZVdpZGdldCk7XG5cbiAgZnVuY3Rpb24gYWRqdXN0U2Nyb2xsV2hlbkFib3ZlVmlzaWJsZShjbSwgbGluZSwgZGlmZikge1xuICAgIGlmIChoZWlnaHRBdExpbmUobGluZSkgPCAoKGNtLmN1ck9wICYmIGNtLmN1ck9wLnNjcm9sbFRvcCkgfHwgY20uZG9jLnNjcm9sbFRvcCkpXG4gICAgICBhZGRUb1Njcm9sbFBvcyhjbSwgbnVsbCwgZGlmZik7XG4gIH1cblxuICBMaW5lV2lkZ2V0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBjbSA9IHRoaXMuZG9jLmNtLCB3cyA9IHRoaXMubGluZS53aWRnZXRzLCBsaW5lID0gdGhpcy5saW5lLCBubyA9IGxpbmVObyhsaW5lKTtcbiAgICBpZiAobm8gPT0gbnVsbCB8fCAhd3MpIHJldHVybjtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHdzLmxlbmd0aDsgKytpKSBpZiAod3NbaV0gPT0gdGhpcykgd3Muc3BsaWNlKGktLSwgMSk7XG4gICAgaWYgKCF3cy5sZW5ndGgpIGxpbmUud2lkZ2V0cyA9IG51bGw7XG4gICAgdmFyIGhlaWdodCA9IHdpZGdldEhlaWdodCh0aGlzKTtcbiAgICB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIE1hdGgubWF4KDAsIGxpbmUuaGVpZ2h0IC0gaGVpZ2h0KSk7XG4gICAgaWYgKGNtKSBydW5Jbk9wKGNtLCBmdW5jdGlvbigpIHtcbiAgICAgIGFkanVzdFNjcm9sbFdoZW5BYm92ZVZpc2libGUoY20sIGxpbmUsIC1oZWlnaHQpO1xuICAgICAgcmVnTGluZUNoYW5nZShjbSwgbm8sIFwid2lkZ2V0XCIpO1xuICAgIH0pO1xuICB9O1xuICBMaW5lV2lkZ2V0LnByb3RvdHlwZS5jaGFuZ2VkI
23459D0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIG9sZEggPSB0aGlzLmhlaWdodCwgY20gPSB0aGlzLmRvYy5jbSwgbGluZSA9IHRoaXMubGluZTtcbiAgICB0aGlzLmhlaWdodCA9IG51bGw7XG4gICAgdmFyIGRpZmYgPSB3aWRnZXRIZWlnaHQodGhpcykgLSBvbGRIO1xuICAgIGlmICghZGlmZikgcmV0dXJuO1xuICAgIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgbGluZS5oZWlnaHQgKyBkaWZmKTtcbiAgICBpZiAoY20pIHJ1bkluT3AoY20sIGZ1bmN0aW9uKCkge1xuICAgICAgY20uY3VyT3AuZm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgYWRqdXN0U2Nyb2xsV2hlbkFib3ZlVmlzaWJsZShjbSwgbGluZSwgZGlmZik7XG4gICAgfSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gd2lkZ2V0SGVpZ2h0KHdpZGdldCkge1xuICAgIGlmICh3aWRnZXQuaGVpZ2h0ICE9IG51bGwpIHJldHVybiB3aWRnZXQuaGVpZ2h0O1xuICAgIHZhciBjbSA9IHdpZGdldC5kb2MuY207XG4gICAgaWYgKCFjbSkgcmV0dXJuIDA7XG4gICAgaWYgKCFjb250YWlucyhkb2N1bWVudC5ib2R5LCB3aWRnZXQubm9kZSkpIHtcbiAgICAgIHZhciBwYXJlbnRTdHlsZSA9IFwicG9zaXRpb246IHJlbGF0aXZlO1wiO1xuICAgICAgaWYgKHdpZGdldC5jb3Zlckd1dHRlcilcbiAgICAgICAgcGFyZW50U3R5bGUgKz0gXCJtYXJnaW4tbGVmdDogLVwiICsgY20uZGlzcGxheS5ndXR0ZXJzLm9mZnNldFdpZHRoICsgXCJweDtcIjtcbiAgICAgIGlmICh3aWRnZXQubm9IU2Nyb2xsKVxuICAgICAgICBwYXJlbnRTdHlsZSArPSBcIndpZHRoOiBcIiArIGNtLmRpc3BsYXkud3JhcHBlci5jbGllbnRXaWR0aCArIFwicHg7XCI7XG4gICAgICByZW1vdmVDaGlsZHJlbkFuZEFkZChjbS5kaXNwbGF5Lm1lYXN1cmUsIGVsdChcImRpdlwiLCBbd2lkZ2V0Lm5vZGVdLCBudWxsLCBwYXJlbnRTdHlsZSkpO1xuICAgIH1cbiAgICByZXR1cm4gd2lkZ2V0LmhlaWdodCA9IHdpZGdldC5u
vendor: 13,023 bytes, line 23459
23459b2RlLm9mZnNldEhlaWdodDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZExpbmVXaWRnZXQoZG9jLCBoYW5kbGUsIG5vZGUsIG9wdGlvbnMpIHtcbiAgICB2YXIgd2lkZ2V0ID0gbmV3IExpbmVXaWRnZXQoZG9jLCBub2RlLCBvcHRpb25zKTtcbiAgICB2YXIgY20gPSBkb2MuY207XG4gICAgaWYgKGNtICYmIHdpZGdldC5ub0hTY3JvbGwpIGNtLmRpc3BsYXkuYWxpZ25XaWRnZXRzID0gdHJ1ZTtcbiAgICBjaGFuZ2VMaW5lKGRvYywgaGFuZGxlLCBcIndpZGdldFwiLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICB2YXIgd2lkZ2V0cyA9IGxpbmUud2lkZ2V0cyB8fCAobGluZS53aWRnZXRzID0gW10pO1xuICAgICAgaWYgKHdpZGdldC5pbnNlcnRBdCA9PSBudWxsKSB3aWRnZXRzLnB1c2god2lkZ2V0KTtcbiAgICAgIGVsc2Ugd2lkZ2V0cy5zcGxpY2UoTWF0aC5taW4od2lkZ2V0cy5sZW5ndGggLSAxLCBNYXRoLm1heCgwLCB3aWRnZXQuaW5zZXJ0QXQpKSwgMCwgd2lkZ2V0KTtcbiAgICAgIHdpZGdldC5saW5lID0gbGluZTtcbiAgICAgIGlmIChjbSAmJiAhbGluZUlzSGlkZGVuKGRvYywgbGluZSkpIHtcbiAgICAgICAgdmFyIGFib3ZlVmlzaWJsZSA9IGhlaWdodEF0TGluZShsaW5lKSA8IGRvYy5zY3JvbGxUb3A7XG4gICAgICAgIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgbGluZS5oZWlnaHQgKyB3aWRnZXRIZWlnaHQod2lkZ2V0KSk7XG4gICAgICAgIGlmIChhYm92ZVZpc2libGUpIGFkZFRvU2Nyb2xsUG9zKGNtLCBudWxsLCB3aWRnZXQuaGVpZ2h0KTtcbiAgICAgICAgY20uY3VyT3AuZm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIHdpZGdldDtcbiAgfVxuXG4gIC8vIExJTkUgREFUQSBTVFJVQ1RVUkVcblxuICAvLyBMaW5lIG9iamVjdHMuIFRoZXNlIGhvbGQgc3RhdGUgcmVsYXRlZCB0byBhIGxpbmUsIGluY2x1ZGluZ1xuICAvLyBoaWdobGlnaHRpbmcgaW5mbyAodGhlIHN0eWxlcyBhcnJheSkuXG4gIHZhciBMaW5lID0gQ29kZU1pcnJvci5MaW5lID0gZnVuY3Rpb24odGV4dCwgbWFya2VkU3BhbnMsIGVzdGltYXRlSGVpZ2h0KSB7XG4gICAgdGhpcy50ZXh0ID0gdGV4dDtcbiAgICBhdHRhY2hNYXJrZWRTcGFucyh0aGlzLCBtYXJrZWRTcGFucyk7XG4gICAgdGhpcy5oZWlnaHQgPSBlc3RpbWF0ZUhlaWdodCA/IGVzdGltYXRlSGVpZ2h0KHRoaXMpIDogMTtcbiAgfTtcbiAgZXZlbnRNaXhpbihMaW5lKTtcbiAgTGluZS5wcm90b3R5cGUubGluZU5vID0gZnVuY3Rpb24oKSB7IHJldHVybiBsaW5lTm8odGhpcyk7IH07XG5cbiAgLy8gQ2hhbmdlIHRoZSBjb250ZW50ICh0ZXh0LCBtYXJrZXJzKSBvZiBhIGxpbmUuIEF1dG9tYXRpY2FsbHlcbiAgLy8gaW52YWxpZGF0ZXMgY2FjaGVkIGluZm9ybWF0aW9uIGFuZCB0cmllcyB0byByZS1lc3RpbWF0ZSB0aGVcbiAgLy8gbGluZSdzIGhlaWdodC5cbiAgZnVuY3Rpb24gdXBkYXRlTGluZShsaW5lLCB0ZXh0LCBtYXJrZWRTcGFucywgZXN0aW1hdGVIZWlnaHQpIHtcbiAgICBsaW5lLnRleHQgPSB0ZXh0O1xuICAgIGlmIChsaW5lLnN0YXRlQWZ0ZXIpIGxpbmUuc3RhdGVBZnRlciA9IG51bGw7XG4gICAgaWYgKGxpbmUuc3R5bGVzKSBsaW5lLnN0eWxlcyA9IG51bGw7XG4gICAgaWYgKGxpbmUub3JkZXIgIT0gbnVsbCkgbGluZS5vcmRlciA9IG51bGw7XG4gICAgZGV0YWNoTWFya2VkU3BhbnMobGluZSk7XG4gICAgYXR0YWNoTWFya2VkU3BhbnMobGluZSwgbWFya2VkU3BhbnMpO1xuICAgIHZhciBlc3RIZWlnaHQgPSBlc3RpbWF0ZUhlaWdodCA/IGVzdGltYXRlSGVpZ2h0KGxpbmUpIDogMTtcbiAgICBpZiAoZXN0SGVpZ2h0ICE9IGxpbmUuaGVpZ2h0KSB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIGVzdEhlaWdodCk7XG4gIH1cblxuICAvLyBEZXRhY2ggYSBsaW5lIGZyb20gdGhlIGRvY3VtZW50IHRyZWUgYW5kIGl0cyBtYXJrZXJzLlxuICBmdW5jdGlvbiBjbGVhblVwTGluZShsaW5lKSB7XG4gICAgbGluZS5wYXJlbnQgPSBudWxsO1xuICAgIGRldGFjaE1hcmtlZFNwYW5zKGxpbmUpO1xuICB9XG5cbiAgZnVuY3Rpb24gZXh0cmFjdExpbmVDbGFzc2VzKHR5cGUsIG91dHB1dCkge1xuICAgIGlmICh0eXBlKSBmb3IgKDs7KSB7XG4gICAgICB2YXIgbGluZUNsYXNzID0gdHlwZS5tYXRjaCgvKD86XnxcXHMrKWxpbmUtKGJhY2tncm91bmQtKT8oXFxTKykvKTtcbiAgICAgIGlmICghbGluZUNsYXNzKSBicmVhaztcbiAgICAgIHR5cGUgPSB0eXBlLnNsaWNlKDAsIGxpbmVDbGFzcy5pbmRleCkgKyB0eXBlLnNsaWNlKGxpbmVDbGFzcy5pbmRleCArIGxpbmVDbGFzc1swXS5sZW5ndGgpO1xuICAgICAgdmFyIHByb3AgPSBsaW5lQ2xhc3NbMV0gPyBcImJnQ2xhc3NcIiA6IFwidGV4dENsYXNzXCI7XG4gICAgICBpZiAob3V0cHV0W3Byb3BdID09IG51bGwpXG4gICAgICAgIG91dHB1dFtwcm9wXSA9IGxpbmVDbGFzc1syXTtcbiAgICAgIGVsc2UgaWYgKCEobmV3IFJlZ0V4cChcIig/Ol58XFxzKVwiICsgbGluZUNsYXNzWzJdICsgXCIoPzokfFxccylcIikpLnRlc3Qob3V0cHV0W3Byb3BdKSlcbiAgICAgICAgb3V0cHV0W3Byb3BdICs9IFwiIFwiICsgbGluZUNsYXNzWzJdO1xuICAgIH1cbiAgICByZXR1cm4gdHlwZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbGxCbGFua0xpbmUobW9kZSwgc3RhdGUpIHtcbiAgICBpZiAobW9kZS5ibGFua0xpbmUpIHJldHVybiBtb2RlLmJsYW5rTGluZShzdGF0ZSk7XG4gICAgaWYgKCFtb2RlLmlubmVyTW9kZSkgcmV0dXJuO1xuICAgIHZhciBpbm5lciA9IENvZGVNaXJyb3IuaW5uZXJNb2RlKG1vZGUsIHN0YXRlKTtcbiAgICBpZiAoaW5uZXIubW9kZS5ibGFua0xpbmUpIHJldHVybiBpbm5lci5tb2RlLmJsYW5rTGluZShpbm5lci5zdGF0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiByZWFkVG9rZW4obW9kZSwgc3RyZWFtLCBzdGF0ZSwgaW5uZXIpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDEwOyBpKyspIHtcbiAgICAgIGlmIChpbm5lcikgaW5uZXJbMF0gPSBDb2RlTWlycm9yLmlubmVyTW9kZShtb2RlLCBzdGF0ZSkubW9kZTtcbiAgICAgIHZhciBzdHlsZSA9IG1vZGUudG9rZW4oc3RyZWFtLCBzdGF0ZSk7XG4gICAgICBpZiAoc3RyZWFtLnBvcyA+IHN0cmVhbS5zdGFydCkgcmV0dXJuIHN0eWxlO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJNb2RlIFwiICsgbW9kZS5uYW1lICsgXCIgZmFpbGVkIHRvIGFkdmFuY2Ugc3RyZWFtLlwiKTtcbiAgfVxuXG4gIC8vIFV0aWxpdHkgZm9yIGdldFRva2VuQXQgYW5kIGdldExpbmVUb2tlbnNcbiAgZnVuY3Rpb24gdGFrZVRva2VuKGNtLCBwb3MsIHByZWNpc2UsIGFzQXJyYXkpIHtcbiAgICBmdW5jdGlvbiBnZXRPYmooY29weSkge1xuICAgICAgcmV0dXJuIHtzdGFydDogc3RyZWFtLnN0YXJ0LCBlbmQ6IHN0cmVhbS5wb3MsXG4gICAgICAgICAgICAgIHN0cmluZzogc3RyZWFtLmN1cnJlbnQoKSxcbiAgICAgICAgICAgICAgdHlwZTogc3R5bGUgfHwgbnVsbCxcbiAgICAgICAgICAgICAgc3RhdGU6IGNvcHkgPyBjb3B5U3RhdGUoZG9jLm1vZGUsIHN0YXRlKSA6IHN0YXRlfTtcbiAgICB9XG5cbiAgICB2YXIgZG9jID0gY20uZG9jLCBtb2RlID0gZG9jLm1vZGUsIHN0eWxlO1xuICAgIHBvcyA9IGNsaXBQb3MoZG9jLCBwb3MpO1xuICAgIHZhciBsaW5lID0gZ2V0TGluZShkb2MsIHBvcy5saW5lKSwgc3RhdGUgPSBnZXRTdGF0ZUJlZm9yZShjbSwgcG9zLmxpbmUsIHByZWNpc2UpO1xuICAgIHZhciBzdHJlYW0gPSBuZXcgU3RyaW5nU3RyZWFtKGxpbmUudGV4dCwgY20ub3B0aW9ucy50YWJTaXplKSwgdG9rZW5zO1xuICAgIGlmIChhc0FycmF5KSB0b2tlbnMgPSBbXTtcbiAgICB3aGlsZSAoKGFzQXJyYXkgfHwgc3RyZWFtLnBvcyA8IHBvcy5jaCkgJiYgIXN0cmVhbS5lb2woKSkge1xuICAgICAgc3RyZWFtLnN0YXJ0ID0gc3RyZWFtLnBvcztcbiAgICAgIHN0eWxlID0gcmVhZFRva2VuKG1vZGUsIHN0cmVhbSwgc3RhdGUpO1xuICAgICAgaWYgKGFzQXJyYXkpIHRva2Vucy5wdXNoKGdldE9iaih0cnVlKSk7XG4gICAgfVxuICAgIHJldHVybiBhc0FycmF5ID8gdG9rZW5zIDogZ2V0T2JqKCk7XG4gIH1cblxuICAvLyBSdW4gdGhlIGdpdmVuIG1vZGUncyBwYXJzZXIgb3ZlciBhIGxpbmUsIGNhbGxpbmcgZiBmb3IgZWFjaCB0b2tlbi5cbiAgZnVuY3Rpb24gcnVuTW9kZShjbSwgdGV4dCwgbW9kZSwgc3RhdGUsIGYsIGxpbmVDbGFzc2VzLCBmb3JjZVRvRW5kKSB7XG4gICAgdmFyIGZsYXR0ZW5TcGFucyA9IG1vZGUuZmxhdHRlblNwYW5zO1xuICAgIGlmIChmbGF0dGVuU3BhbnMgPT0gbnVsbCkgZmxhdHRlblNwYW5zID0gY20ub3B0aW9ucy5mbGF0dGVuU3BhbnM7XG4gICAgdmFyIGN1clN0YXJ0ID0gMCwgY3VyU3R5bGUgPSBudWxsO1xuICAgIHZhciBzdHJlYW0gPSBuZXcgU3RyaW5nU3RyZWFtKHRleHQsIGNtLm9wdGlvbnMudGFiU2l6ZSksIHN0eWxlO1xuICAgIHZhciBpbm5lciA9IGNtLm9wdGlvbnMuYWRkTW9kZUNsYXNzICYmIFtudWxsXTtcbiAgICBpZiAodGV4dCA9PSBcIlwiKSBleHRyYWN0TGluZUNsYXNzZXMoY2FsbEJsYW5rTGluZShtb2RlLCBzdGF0ZSksIGxpbmVDbGFzc2VzKTtcbiAgICB3aGlsZSAoIXN0cmVhbS5lb2woKSkge1xuICAgICAgaWYgKHN0cmVhbS5wb3MgPiBjbS5vcHRpb25zLm1heEhpZ2hsaWdodExlbmd0aCkge1xuICAgICAgICBmbGF0dGVuU3BhbnMgPSBmYWxzZTtcbiAgICAgICAgaWYgKGZvcmNlVG9FbmQpIHByb2Nlc3NMaW5lKGNtLCB0ZXh0LCBzdGF0ZSwgc3RyZWFtLnBvcyk7XG4gICAgICAgIHN0cmVhbS5wb3MgPSB0ZXh0Lmxlbmd0aDtcbiAgICAgICAgc3R5bGUgPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3R5bGUgPSBleHRyYWN0TGluZUNsYXNzZXMocmVhZFRva2VuKG1vZGUsIHN0cmVhbSwgc3RhdGUsIGlubmVyKSwgbGluZUNsYXNzZXMpO1xuICAgICAgfVxuICAgICAgaWYgKGlubmVyKSB7XG4gICAgICAgIHZhciBtTmFtZSA9IGlubmVyWzBdLm5hbWU7XG4gICAgICAgIGlmIChtTmFtZSkgc3R5bGUgPSBcIm0tXCIgKyAoc3R5bGUgPyBtTmFtZSArIFwiIFwiICsgc3R5bGUgOiBtTmFtZSk7XG4gICAgICB9XG4gICAgICBpZiAoIWZsYXR0ZW5TcGFucyB8fCBjdXJTdHlsZSAhPSBzdHlsZSkge1xuICAgICAgICB3aGlsZSAoY3VyU3RhcnQgPCBzdHJlYW0uc3RhcnQpIHtcbiAgICAgICAgICBjdXJTdGFydCA9IE1hdGgubWluKHN0cmVhbS5zdGFydCwgY3VyU3RhcnQgKyA1MDAwMCk7XG4gICAgICAgICAgZihjdXJTdGFydCwgY3VyU3R5bGUpO1xuICAgICAgICB9XG4gICAgICAgIGN1clN0eWxlID0gc3R5bGU7XG4gICAgICB9XG4gICAgICBzdHJlYW0uc3RhcnQgPSBzdHJlYW0ucG9zO1xuICAgIH1cbiAgICB3aGlsZSAoY3VyU3RhcnQgPCBzdHJlYW0ucG9zKSB7XG4gICAgICAvLyBXZWJraXQgc2VlbXMgdG8gcmVmdXNlIHRvIHJlbmRlciB0ZXh0IG5vZGVzIGxvbmdlciB0aGFuIDU3NDQ0IGNoYXJhY3RlcnNcbiAgICAgIHZhciBwb3MgPSBNYXRoLm1pbihzdHJlYW0ucG9zLCBjdXJTdGFydCArIDUwMDAwKTtcbiAgICAgIGYocG9zLCBjdXJTdHlsZSk7XG4gICAgICBjdXJTdGFydCA9IHBvcztcbiAgICB9XG4gIH1cblxuICAvLyBDb21wdXRlIGEgc3R5bGUgYXJyYXkgKGFuIGFycmF5IHN0YXJ0aW5nIHdpdGggYSBtb2RlIGdlbmVyYXRpb25cbiAgLy8gLS0gZm9yIGludmFsaWRhdGlvbiAtLSBmb2xsb3dlZCBieSBwYWlycyBvZiBlbmQgcG9zaXRpb25zIGFuZFxuICAvLyBzdHlsZSBzdHJpbmdzKSwgd2hpY2ggaXMgdXNlZCB0byBoaWdobGlnaHQgdGhlIHRva2VucyBvbiB0aGVcbiAgLy8gbGluZS5cbiAgZnVuY3Rpb24gaGlnaGxpZ2h0TGluZShjbSwgbGluZSwgc3RhdGUsIGZvcmNlVG9FbmQpIHtcbiAgICAvLyBBIHN0eWxlcyBhcnJheSBhbHdheXMgc3RhcnRzIHdpdGggYSBudW1iZXIgaWRlbnRpZnlpbmcgdGhlXG4gICAgLy8gbW9kZS9vdmVybGF5cyB0aGF0IGl0IGlzIGJhc2VkIG9uIChmb3IgZWFzeSBpbnZhbGlkYXRpb24pLlxuICAgIHZhciBzdCA9IFtjbS5zdGF0ZS5tb2RlR2VuXSwgbGluZUNsYXNzZXMgPSB7fTtcbiAgICAvLyBDb21wdXRlIHRoZSBiYXNlIGFycmF5IG9mIHN0eWxlc1xuICAgIHJ1bk1vZGUoY20sIGxpbmUudGV4dCwgY20uZG9jLm1vZGUsIHN0YXRlLCBmdW5jdGlvbihlbmQsIHN0eWxlKSB7XG4gICAgICBzdC5wdXNoKGVuZCwgc3R5bGUpO1xuICAgIH0sIGxpbmVDbGFzc2VzLCBmb3JjZVRvRW5kKTtcblxuICAgIC8vIFJ1biBvdmVybGF5cywgYWRqdXN0IHN0eWxlIGFycmF5LlxuICAgIGZvciAodmFyIG8gPSAwOyBvIDwgY20uc3RhdGUub3ZlcmxheXMubGVuZ3RoOyArK28pIHtcbiAgICAgIHZhciBvdmVybGF5ID0gY20uc3RhdGUub3ZlcmxheXNbb10sIGkgPSAxLCBhdCA9IDA7XG4gICAgICBydW5Nb2RlKGNtLCBsaW5lLnRleHQsIG92ZXJsYXkubW9kZSwgdHJ1ZSwgZnVuY3Rpb24oZW5kLCBzdHlsZSkge1xuICAgICAgICB2YXIgc3RhcnQgPSBpO1xuICAgICAgICAvLyBFbnN1cmUgdGhlcmUncyBhIHRva2VuIGVuZCBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiwgYW5kIHRoYXQgaSBwb2ludHMgYXQgaXRcbiAgICAgICAgd2hpbGUgKGF0IDwgZW5kKSB7XG4gICAgICAgICAgdmFyIGlfZW5kID0gc3RbaV07XG4gICAgICAgICAgaWYgKGlfZW5kID4gZW5kKVxuICAgICAgICAgICAgc3Quc3BsaWNlKGksIDEsIGVuZCwgc3RbaSsxXSwgaV9lbmQpO1xuICAgICAgICAgIGkgKz0gMjtcbiAgICAgICAgICBhdCA9IE1hdGgubWluKGVuZCwgaV9lbmQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghc3R5bGUpIHJldHVybjtcbiAgICAgICAgaWYgKG92ZXJsYXkub3BhcXVlKSB7XG4gICAgICAgICAgc3Quc3BsaWNlKHN0YXJ0LCBpIC0gc3RhcnQsIGVuZCwgXCJjbS1vdmVybGF5IFwiICsgc3R5bGUpO1xuICAgICAgICAgIGkgPSBzdGFydCArIDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZm9yICg7IHN0YXJ0IDwgaTsgc3RhcnQgKz0gMikge1xuICAgICAgICAgICAgdmFyIGN1ciA9IHN0W3N0YXJ0KzFdO1xuICAgICAgICAgICAgc3Rbc3RhcnQrMV0gPSAoY3VyID8gY3VyICsgXCIgXCIgOiBcIlwiKSArIFwiY20tb3ZlcmxheSBcIiArIHN0eWxlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSwgbGluZUNsYXNzZXMpO1xuICAgIH1cblxuICAgIHJldHVybiB7c3R5bGVzOiBzdCwgY2xhc3NlczogbGluZUNsYXNzZXMuYmdDbGFzcyB8fCBsaW5lQ2xhc3Nlcy50ZXh0Q2xhc3MgPyBsaW5lQ2xhc3NlcyA6IG51bGx9O1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0TGluZVN0eWxlcyhjbSwgbGluZSwgdXBkYXRlRnJvbnRpZXIpIHtcbiAgICBpZiAoIWxpbmUuc3R5bGVzIHx8IGxpbmUuc3R5bGVzWzBdICE9IGNtLnN0YXRlLm1vZGVHZW4pIHtcbiAgICAgIHZhciBzdGF0ZSA9IGdldFN0YXRlQmVmb3JlKGNtLCBsaW5lTm8obGluZSkpO1xuICAgICAgdmFyIHJlc3VsdCA9IGhpZ2hsaWdodExpbmUoY20sIGxpbmUsIGxpbmUudGV4dC5sZW5ndGggPiBjbS5vcHRpb25zLm1heEhpZ2hsaWdodExlbmd0aCA/IGNvcHlTdGF0ZShjbS5kb2MubW9kZSwgc3RhdGUpIDogc3RhdGUpO1xuICAgICAgbGluZS5zdGF0ZUFmdGVyID0gc3RhdGU7XG4gICAgICBsaW5lLnN0eWxlcyA9IHJlc3VsdC5zdHlsZXM7XG4gICAgICBpZiAocmVzdWx0LmNsYXNzZXMpIGxpbmUuc3R5bGVDbGFzc2VzID0gcmVzdWx0LmNsYXNzZXM7XG4gICAgICBlbHNlIGlmIChsaW5lLnN0eWxlQ2xhc3NlcykgbGluZS5zdHlsZUNsYXNzZXMgPSBudWxsO1xuICAgICAgaWYgKHVwZGF0ZUZyb250aWVyID09PSBjbS5kb2MuZnJvbnRpZXIpIGNtLmRvYy5mcm9udGllcisrO1xuICAgIH1cbiAgICByZXR1cm4gbGluZS5zdHlsZXM7XG4gIH1cblxuICAvLyBMaWdodHdlaWdodCBmb3JtIG9mIGhpZ2hsaWdodCAtLSBwcm9jZWVkIG92ZXIgdGhpcyBsaW5lIGFuZFxuICAvLyB1cGRhdGUgc3RhdGUsIGJ1dCBkb24ndCBzYXZlIGEgc3R5bGUgYXJyYXkuIFVzZWQgZm9yIGxpbmVzIHRoYXRcbiAgLy8gYXJlbid0IGN1cnJlbnRseSB2aXNpYmxlLlxuICBmdW5jdGlvbiBwcm9jZXNzTGluZShjbSwgdGV4dCwgc3RhdGUsIHN0YXJ0QXQpIHtcbiAgICB2YXIgbW9kZSA9IGNtLmRvYy5tb2RlO1xuICAgIHZhciBzdHJlYW0gPSBuZXcgU3RyaW5nU3RyZWFtKHRleHQsIGNtLm9wdGlvbnMudGFiU2l6ZSk7XG4gICAgc3RyZWFtLnN0YXJ0ID0gc3RyZWFtLnBvcyA9IHN0YXJ0QXQgfHwgMDtcbiAgICBpZiAodGV4dCA9PSBcIlwiKSBjYWxsQmxhbmtMaW5lKG1vZGUsIHN0YXRlKTtcbiAgICB3aGlsZSAoIXN0cmVhbS5lb2woKSkge1xuICAgICAgcmVhZFRva2VuKG1vZGUsIHN0cmVhbSwgc3RhdGUpO1xuICAgICAgc3RyZWFtLnN0YXJ0ID0gc3RyZWFtLnBvcztcbiAgICB9XG4gIH1cblxuICAvLyBDb252ZXJ0IGEgc3R5bGUgYXMgcmV0dXJuZWQgYnkgYSBtb2RlIChlaXRoZXIgbnVsbCwgb3IgYSBzdHJpbmdcbiAgLy8gY29udGFpbmluZyBvbmUgb3IgbW9yZSBzdHlsZXMpIHRvIGEgQ1NTIHN0eWxlLiBUaGlzIGlzIGNhY2hlZCxcbiAgLy8gYW5kIGFsc28gbG9va3MgZm9yIGxpbmUtd2lkZSBzdHlsZXMuXG4gIHZhciBzdHlsZVRvQ2xhc3NDYWNoZSA9IHt9LCBzdHlsZVRvQ2xhc3NDYWNoZVdpdGhNb2RlID0ge307XG4gIGZ1bmN0aW9uIGludGVycHJldFRva2VuU3R5bGUoc3R5bGUsIG9wdGlvbnMpIHtcbiAgICBpZiAoIXN0eWxlIHx8IC9eXFxzKiQvLnRlc3Qoc3R5bGUpKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgY2FjaGUgPSBvcHRpb25zLmFkZE1vZGVDbGFzcyA/IHN0eWxlVG9DbGFzc0NhY2hlV2l0aE1vZGUgOiBzdHlsZVRvQ2xhc3NDYWNoZTtcbiAgICByZXR1cm4gY2FjaGVbc3R5bGVdIHx8XG4gICAgICAoY2FjaGVbc3R5bGVdID0gc3R5bGUucmVwbGFjZSgvXFxTKy9nLCBcImNtLSQmXCIpKTtcbiAgfVxuXG4gIC8vIFJlbmRlciB0aGUgRE9NIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0ZXh0IG9mIGEgbGluZS4gQWxzbyBidWlsZHNcbiAgLy8gdXAgYSAnbGluZSBtYXAnLCB3aGljaCBwb2ludHMgYXQgdGhlIERPTSBub2RlcyB0aGF0IHJlcHJlc2VudFxuICAvLyBzcGVjaWZpYyBzdHJldGNoZXMgb2YgdGV4dCwgYW5kIGlzIHVzZWQgYnkgdGhlIG1lYXN1cmluZyBjb2RlLlxuICAvLyBUaGUgcmV0dXJuZWQgb2JqZWN0IGNvbnRhaW5zIHRoZSBET00gbm9kZSwgdGhpcyBtYXAsIGFuZFxuICAvLyBpbmZvcm1hdGlvbiBhYm91dCBsaW5lLXdpZGUgc3R5bGVzIHRoYXQgd2VyZSBzZXQgYnkgdGhlIG1vZGUuXG4gIGZ1bmN0aW9uIGJ1aWxkTGluZUNvbnRlbnQoY20sIGxpbmVWaWV3KSB7XG4gICAgLy8gVGhlIHBhZGRpbmctcmlnaHQgZm9yY2VzIHRoZSBlbGVtZW50IHRvIGhhdmUgYSAnYm9yZGVyJywgd2hpY2hcbiAgICAvLyBpcyBuZWVkZWQgb24gV2Via2l0IHRvIGJlIGFibGUgdG8gZ2V0IGxpbmUtbGV2ZWwgYm91bmRpbmdcbiAgICAvLyByZWN0YW5nbGVzIGZvciBpdCAoaW4gbWVhc3VyZUNoYXIpLlxuICAgIHZhciBjb250ZW50ID0gZWx0KFwic3BhblwiLCBudWxsLCBudWxsLCB3ZWJraXQgPyBcInBhZGRpbmctcmlnaHQ6IC4xcHhcIiA6IG51bGwpO1xuICAgIHZhciBidWlsZGVyID0ge3ByZTogZWx0KFwicHJlXCIsIFtjb250ZW50XSwgXCJDb2RlTWlycm9yLWxpbmVcIiksIGNvbnRlbnQ6IGNvbnRlbnQsXG4gICAgICAgICAgICAgICAgICAgY29sOiAwLCBwb3M6IDAsIGNtOiBjbSxcbiAgICAgICAgICAgICAgICAgICB
23459zcGxpdFNwYWNlczogKGllIHx8IHdlYmtpdCkgJiYgY20uZ2V0T3B0aW9uKFwibGluZVdyYXBwaW5nXCIpfTtcbiAgICBsaW5lVmlldy5tZWFzdXJlID0ge307XG5cbiAgICAvLyBJdGVyYXRlIG92ZXIgdGhlIGxvZ2ljYWwgbGluZXMgdGhhdCBtYWtlIHVwIHRoaXMgdmlzdWFsIGxpbmUuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPD0gKGxpbmVWaWV3LnJlc3QgPyBsaW5lVmlldy5yZXN0Lmxlbmd0aCA6IDApOyBpKyspIHtcbiAgICAgIHZhciBsaW5lID0gaSA/IGxpbmVWaWV3LnJlc3RbaSAtIDFdIDogbGluZVZpZXcubGluZSwgb3JkZXI7XG4gICAgICBidWlsZGVyLnBvcyA9IDA7XG4gICAgICBidWlsZGVyLmFkZFRva2VuID0gYnVpbGRUb2tlbjtcbiAgICAgIC8vIE9wdGlvbmFsbHkgd2lyZSBpbiBzb21lIGhhY2tzIGludG8gdGhlIHRva2VuLXJlbmRlcmluZ1xuICAgICAgLy8gYWxnb3JpdGhtLCB0byBkZWFsIHdpdGggYnJvd3NlciBxdWlya3MuXG4gICAgICBpZiAoaGFzQmFkQmlkaVJlY3RzKGNtLmRpc3BsYXkubWVhc3VyZSkgJiYgKG9yZGVyID0gZ2V0T3JkZXIobGluZSkpKVxuICAgICAgICBidWlsZGVyLmFkZFRva2VuID0gYnVpbGRUb2tlbkJhZEJpZGkoYnVpbGRlci5hZGRUb2tlbiwgb3JkZXIpO1xuICAgICAgYnVpbGRlci5tYXAgPSBbXTtcbiAgICAgIHZhciBhbGxvd0Zyb250aWVyVXBkYXRlID0gbGluZVZpZXcgIT0gY20uZGlzcGxheS5leHRlcm5hbE1lYXN1cmVkICYmIGxpbmVObyhsaW5lKTtcbiAgICAgIGluc2VydExpbmVDb250ZW50KGxpbmUsIGJ1aWxkZXIsIGdldExpbmVTdHlsZXMoY20sIGxpbmUsIGFsbG93RnJvbnRpZXJVcGRhdGUpKTtcbiAgICAgIGlmIChsaW5lLnN0eWxlQ2xhc3Nlcykge1xuICAgICAgICBpZiAobGluZS5zdHlsZUNsYXNzZXMuYmdDbGFzcylcbiAgICAgICAgICBidWlsZGVyLmJnQ2xhc3MgPSBqb2luQ2xhc3NlcyhsaW5lLnN0eWxlQ2xhc3Nlcy5iZ0NsYXNzLCBidWlsZGVyLmJnQ2xhc3MgfHwgXCJcIik7XG4gICAgICAgIGlmIChsaW5lLnN0eWxlQ2xhc3Nlcy50ZXh0Q2xhc3MpXG4gICAgICAgICAgYnVpbGRlci50ZXh0Q2xhc3MgPSBqb2luQ2xhc3NlcyhsaW5lLnN0eWxlQ2xhc3Nlcy50ZXh0Q2xhc3MsIGJ1aWxkZXIudGV4dENsYXNzIHx8IFwiXCIpO1xuICAgICAgfVxuXG4gICAgICAvLyBFbnN1cmUgYXQgbGVhc3QgYSBzaW5nbGUgbm9kZSBpcyBwcmVzZW50LCBmb3IgbWVhc3VyaW5nLlxuICAgICAgaWYgKGJ1aWxkZXIubWFwLmxlbmd0aCA9PSAwKVxuICAgICAgICBidWlsZGVyLm1hcC5wdXNoKDAsIDAsIGJ1aWxkZXIuY29udGVudC5hcHBlbmRDaGlsZCh6ZXJvV2lkdGhFbGVtZW50KGNtLmRpc3BsYXkubWVhc3VyZSkpKTtcblxuICAgICAgLy8gU3RvcmUgdGhlIG1hcCBhbmQgYSBjYWNoZSBvYmplY3QgZm9yIHRoZSBjdXJyZW50IGxvZ2ljYWwgbGluZVxuICAgICAgaWYgKGkgPT0gMCkge1xuICAgICAgICBsaW5lVmlldy5tZWFzdXJlLm1hcCA9IGJ1aWxkZXIubWFwO1xuICAgICAgICBsaW5lVmlldy5tZWFzdXJlLmNhY2hlID0ge307XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAobGluZVZpZXcubWVhc3VyZS5tYXBzIHx8IChsaW5lVmlldy5tZWFzdXJlLm1hcHMgPSBbXSkpLnB1c2goYnVpbGRlci5tYXApO1xuICAgICAgICAobGluZVZpZXcubWVhc3VyZS5jYWNoZXMgfHwgKGxpbmVWaWV3Lm1lYXN1cmUuY2FjaGVzID0gW10pKS5wdXNoKHt9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTZWUgaXNzdWUgIzI5MDFcbiAgICBpZiAod2Via2l0ICYmIC9cXGJjbS10YWJcXGIvLnRlc3QoYnVpbGRlci5jb250ZW50Lmxhc3RDaGlsZC5jbGFzc05hbWUpKVxuICAgICAgYnVpbGRlci5jb250ZW50LmNsYXNzTmFtZSA9IFwiY20tdGFiLXdyYXAtaGFja1wiO1xuXG4gICAgc2lnbmFsKGNtLCBcInJlbmRlckxpbmVcIiwgY20sIGxpbmVWaWV3LmxpbmUsIGJ1aWxkZXIucHJlKTtcbiAgICBpZiAoYnVpbGRlci5wcmUuY2xhc3NOYW1lKVxuICAgICAgYnVpbGRlci50ZXh0Q2xhc3MgPSBqb2luQ2xhc3NlcyhidWlsZGVyLnByZS5jbGFzc05hbWUsIGJ1aWxkZXIudGV4dENsYXNzIHx8IFwiXCIpO1xuXG4gICAgcmV0dXJuIGJ1aWxkZXI7XG4gIH1cblxuICBmdW5jdGlvbiBkZWZhdWx0U3BlY2lhbENoYXJQbGFjZWhvbGRlcihjaCkge1xuICAgIHZhciB0b2tlbiA9IGVsdChcInNwYW5cIiwgXCJcXHUyMDIyXCIsIFwiY20taW52YWxpZGNoYXJcIik7XG4gICAgdG9rZW4udGl0bGUgPSBcIlxcXFx1XCIgKyBjaC5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KTtcbiAgICB0b2tlbi5zZXRBdHRyaWJ1dGUoXCJhcmlhLWxhYmVsXCIsIHRva2VuLnRpdGxlKTtcbiAgICByZXR1cm4gdG9rZW47XG4gIH1cblxuICAvLyBCdWlsZCB1cCB0aGUgRE9NIHJlcHJlc2VudGF0aW9uIGZvciBhIHNpbmdsZSB0b2tlbiwgYW5kIGFkZCBpdCB0b1xuICAvLyB0aGUgbGluZSBtYXAuIFRha2VzIGNhcmUgdG8gcmVuZGVyIHNwZWNpYWwgY2hhcmFjdGVycyBzZXBhcmF0ZWx5LlxuICBmdW5jdGlvbiBidWlsZFRva2VuKGJ1aWxkZXIsIHRleHQsIHN0eWxlLCBzdGFydFN0eWxlLCBlbmRTdHlsZSwgdGl0bGUsIGNzcykge1xuICAgIGlmICghdGV4dCkgcmV0dXJuO1xuICAgIHZhciBkaXNwbGF5VGV4dCA9IGJ1aWxkZXIuc3BsaXRTcGFjZXMgPyB0ZXh0LnJlcGxhY2UoLyB7Myx9L2csIHNwbGl0U3BhY2VzKSA6IHRleHQ7XG4gICAgdmFyIHNwZWNpYWwgPSBidWlsZGVyLmNtLnN0YXRlLnNwZWNpYWxDaGFycywgbXVzdFdyYXAgPSBmYWxzZTtcbiAgICBpZiAoIXNwZWNpYWwudGVzdCh0ZXh0KSkge1xuICAgICAgYnVpbGRlci5jb2wgKz0gdGV4dC5sZW5ndGg7XG4gICAgICB2Y
23459XIgY29udGVudCA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGRpc3BsYXlUZXh0KTtcbiAgICAgIGJ1aWxkZXIubWFwLnB1c2goYnVpbGRlci5wb3MsIGJ1aWxkZXIucG9zICsgdGV4dC5sZW5ndGgsIGNvbnRlbnQpO1xuICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPCA5KSBtdXN0V3JhcCA9IHRydWU7XG4gICAgICBidWlsZGVyLnBvcyArPSB0ZXh0Lmxlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGNvbnRlbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksIHBvcyA9IDA7XG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBzcGVjaWFsLmxhc3RJbmRleCA9IHBvcztcbiAgICAgICAgdmFyIG0gPSBzcGVjaWFsLmV4ZWModGV4dCk7XG4gICAgICAgIHZhciBza2lwcGVkID0gbSA/IG0uaW5kZXggLSBwb3MgOiB0ZXh0Lmxlbmd0aCAtIHBvcztcbiAgICAgICAgaWYgKHNraXBwZWQpIHtcbiAgICAgICAgICB2YXIgdHh0ID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoZGlzcGxheVRleHQuc2xpY2UocG9zLCBwb3MgKyBza2lwcGVkKSk7XG4gICAgICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPCA5KSBjb250ZW50LmFwcGVuZENoaWxkKGVsdChcInNwYW5cIiwgW3R4dF0pKTtcbiAgICAgICAgICBlbHNlIGNvbnRlbnQuYXBwZW5kQ2hpbGQodHh0KTtcbiAgICAgICAgICBidWlsZGVyLm1hcC5wdXNoKGJ1aWxkZXIucG9zLCBidWlsZGVyLnBvcyArIHNraXBwZWQsIHR4dCk7XG4gICAgICAgICAgYnVpbGRlci5jb2wgKz0gc2tpcHBlZDtcbiAgICAgICAgICBidWlsZGVyLnBvcyArPSBza2lwcGVkO1xuICAgICAgICB9XG4gICAgICAgIGlmICghbSkgYnJlYWs7XG4gICAgICAgIHBvcyArPSBza2lwcGVkICsgMTtcbiAgICAgICAgaWYgKG1bMF0gPT0gXCJcXHRcIikge1xuICAgICAgICAgIHZhciB0YWJTaXplID0gYnVpbGRlci5jbS5vcHRpb25zLnRhYlNpemUsIHRhYldpZHRoID0gdGFiU2l6ZSAtIGJ1aWxkZXIuY29sICUgdGFiU2l6ZTtcbiAgICAgICAgICB2Y
23459XIgdHh0ID0gY29udGVudC5hcHBlbmRDaGlsZChlbHQoXCJzcGFuXCIsIHNwYWNlU3RyKHRhYldpZHRoKSwgXCJjbS10YWJcIikpO1xuICAgICAgICAgIHR4dC5zZXRBdHRyaWJ1dGUoXCJyb2xlXCIsIFwicHJlc2VudGF0aW9uXCIpO1xuICAgICAgICAgIHR4dC5zZXRBdHRyaWJ1dGUoXCJjbS10ZXh0XCIsIFwiXFx0XCIpO1xuICAgICAgICAgIGJ1aWxkZXIuY29sICs9IHRhYldpZHRoO1xuICAgICAgICB9IGVsc2UgaWYgKG1bMF0gPT0gXCJcXHJcIiB8fCBtWzBdID09IFwiXFxuXCIpIHtcbiAgICAgICAgICB2YXIgdHh0ID0gY29udGVudC5hcHBlbmRDaGlsZChlbHQoXCJzcGFuXCIsIG1bMF0gPT0gXCJcXHJcIiA/IFwiXFx1MjQwZFwiIDogXCJcXHUyNDI0XCIsIFwiY20taW52YWxpZGNoYXJcIikpO1xuICAgICAgICAgIHR4dC5zZXRBdHRyaWJ1dGUoXCJjbS10ZXh0XCIsIG1bMF0pO1xuICAgICAgICAgIGJ1aWxkZXIuY29sICs9IDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHR4dCA9IGJ1aWxkZXIuY20ub3B0aW9ucy5zcGVjaWFsQ2hhclBsYWNlaG9sZGVyKG1bMF0pO1xuICAgICAgICAgIHR4dC5zZXRBdHRyaWJ1dGUoXCJjbS10ZXh0XCIsIG1bMF0pO1xuICAgICAgICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uIDwgOSkgY29udGVudC5hcHBlbmRDaGlsZChlbHQoXCJzcGFuXCIsIFt0eHRdKSk7XG4gICAgICAgICAgZWxzZSBjb250ZW50LmFwcGVuZENoaWxkKHR4dCk7XG4gICAgICAgICAgYnVpbGRlci5jb2wgKz0gMTtcbiAgICAgICAgfVxuICAgICAgICBidWlsZGVyLm1hcC5wdXNoKGJ1aWxkZXIucG9zLCBidWlsZGVyLnBvcyArIDEsIHR4dCk7XG4gICAgICAgIGJ1aWxkZXIucG9zKys7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzdHlsZSB8fCBzdGFydFN0eWxlIHx8IGVuZFN0eWxlIHx8IG11c3RXcmFwIHx8IGNzcykge1xuICAgICAgdmFyIGZ1bGxTdHlsZSA9IHN0eWxlIHx8IFwiXCI7XG4gICAgICBpZiAoc3RhcnRTdHlsZSkgZnVsbFN0eWxlICs9IHN0YXJ0U3R5bGU7XG4gICAgICBpZiAoZW5kU3R5bGUpIGZ1bGxTdHlsZSArPSBlbmRTdHlsZTtcbiAgICAgIHZhciB0b2tlbiA9IGVsdChcInNwYW5cIiwgW2NvbnRlbnRdLCBmdWxsU3R5bGUsIGNzcyk7XG4gICAgICBpZiAodGl0bGUpIHRva2VuLnRpdGxlID0gdGl0bGU7XG4gICAgICByZXR1cm4gYnVpbGRlci5jb250ZW50LmFwcGVuZENoaWxkKHRva2VuKTtcbiAgICB9XG4gICAgYnVpbGRlci5jb250ZW50LmFwcGVuZENoaWxkKGNvbnRlbnQpO1xuICB9XG5cbiAgZnVuY3Rpb24gc3BsaXRTcGFjZXMob2xkKSB7XG4gICAgdmFyIG91dCA9IFwiIFwiO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2xkLmxlbmd0aCAtIDI7ICsraSkgb3V0ICs9IGkgJSAyID8gXCIgXCIgOiBcIlxcdTAwYTBcIjtcbiAgICBvdXQgKz0gXCIgXCI7XG4gICAgcmV0dXJuIG91dDtcbiAgfVxuXG4gIC8vIFdvcmsgYXJvdW5kIG5vbnNlbnNlIGRpbWVuc2lvbnMgYmVpbmcgcmVwb3J0ZWQgZm9yIHN0cmV0Y2hlcyBvZlxuICAvLyByaWdodC10by1sZWZ0IHRleHQuXG4gIGZ1bmN0aW9uIGJ1aWxkVG9rZW5CYWRCaWRpKGlubmVyLCBvcmRlcikge1xuICAgIHJldHVybiBmdW5jdGlvbihidWlsZGVyLCB0ZXh0LCBzdHlsZSwgc3RhcnRTdHlsZSwgZW5kU3R5bGUsIHRpdGxlLCBjc3MpIHtcbiAgICAgIHN0eWxlID0gc3R5bGUgPyBzdHlsZSArIFwiIGNtLWZvcmNlLWJvcmRlclwiIDogXCJjbS1mb3JjZS1ib3JkZXJcIjtcbiAgICAgIHZhciBzdGFydCA9IGJ1aWxkZXIucG9zLCBlbmQgPSBzdGFydCArIHRleHQubGVuZ3RoO1xuICAgICAgZm9yICg7Oykge1xuICAgICAgICAvLyBGaW5kIHRoZSBwYXJ0IHRoYXQgb3ZlcmxhcHMgd2l0aCB0aGUgc3RhcnQgb2YgdGhpcyB0ZXh0XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3JkZXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB2Y
23459XIgcGFydCA9IG9yZGVyW2ldO1xuICAgICAgICAgIGlmIChwYXJ0LnRvID4gc3RhcnQgJiYgcGFydC5mcm9tIDw9IHN0YXJ0KSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFydC50byA+PSBlbmQpIHJldHVybiBpbm5lcihidWlsZGVyLCB0ZXh0LCBzdHlsZSwgc3RhcnRTdHlsZSwgZW5kU3R5bGUsIHRpdGxlLCBjc3MpO1xuICAgICAgICBpbm5lcihidWlsZGVyLCB0ZXh0LnNsaWNlKDAsIHBhcnQudG8gLSBzdGFydCksIHN0eWxlLCBzdGFydFN0eWxlLCBudWxsLCB0aXRsZSwgY3NzKTtcbiAgICAgICAgc3RhcnRTdHlsZSA9IG51bGw7XG4gICAgICAgIHRleHQgPSB0ZXh0LnNsaWNlKHBhcnQudG8gLSBzdGFydCk7XG4gICAgICAgIHN0YXJ0ID0gcGFydC50bztcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRDb2xsYXBzZWRTcGFuKGJ1aWxkZXIsIHNpemUsIG1hcmtlciwgaWdub3JlV2lkZ2V0KSB7XG4gICAgdmFyIHdpZGdldCA9ICFpZ25vcmVXaWRnZXQgJiYgbWFya2VyLndpZGdldE5vZGU7XG4gICAgaWYgKHdpZGdldCkgYnVpbGRlci5tYXAucHVzaChidWlsZGVyLnBvcywgYnVpbGRlci5wb3MgKyBzaXplLCB3aWRnZXQpO1xuICAgIGlmICghaWdub3JlV2lkZ2V0ICYmIGJ1aWxkZXIuY20uZGlzcGxheS5pbnB1dC5uZWVkc0NvbnRlbnRBdHRyaWJ1dGUpIHtcbiAgICAgIGlmICghd2lkZ2V0KVxuICAgICAgICB3aWRnZXQgPSBidWlsZGVyLmNvbnRlbnQuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNwYW5cIikpO1xuICAgICAgd2lkZ2V0LnNldEF0dHJpYnV0ZShcImNtLW1hcmtlclwiLCBtYXJrZXIuaWQpO1xuICAgIH1cbiAgICBpZiAod2lkZ2V0KSB7XG4gICAgICBidWlsZGVyLmNtLmRpc3BsYXkuaW5wdXQuc2V0VW5lZGl0YWJsZSh3aWRnZXQpO1xuICAgICAgYnVpbGRlci5jb250ZW50LmFwcGVuZENoaWxkKHdpZGdldCk7XG4gICAgfVxuICAgIGJ1aWxkZXIucG9zICs9IHNpemU7XG4gIH1cblxuICAvLyBPdXRwdXRzIGEgbnVtYmVyIG9mIHNwYW5zIHRvIG1ha2UgdXAgYSBsaW5lLCB0YWtpbmcgaGlnaGxpZ2h0aW5nXG4gIC8vIGFuZCBtYXJrZWQgdGV4dCBpbnRvIGFjY291bnQuXG4gIGZ1bmN0aW9uIGluc2VydExpbmVDb250ZW50KGxpbmUsIGJ1aWxkZXIsIHN0eWxlcykge1xuICAgIHZhciBzcGFucyA9IGxpbmUubWFya2VkU3BhbnMsIGFsbFRleHQgPSBsaW5lLnRleHQsIGF0ID0gMDtcbiAgICBpZiAoIXNwYW5zKSB7XG4gICAgICBmb3IgKHZhciBpID0gMTsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrPTIpXG4gICAgICAgIGJ1aWxkZXIuYWRkVG9rZW4oYnVpbGRlciwgYWxsVGV4dC5zbGljZShhdCwgYXQgPSBzdHlsZXNbaV0pLCBpbnRlcnByZXRUb2tlblN0eWxlKHN0eWxlc1tpKzFdLCBidWlsZGVyLmNtLm9wdGlvbnMpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbGVuID0gYWxsVGV4dC5sZW5ndGgsIHBvcyA9IDAsIGkgPSAxLCB0ZXh0ID0gXCJcIiwgc3R5bGUsIGNzcztcbiAgICB2YXIgbmV4dENoYW5nZSA9IDAsIHNwYW5TdHlsZSwgc3BhbkVuZFN0eWxlLCBzcGFuU3RhcnRTdHlsZSwgdGl0bGUsIGNvbGxhcHNlZDtcbiAgICBmb3IgKDs7KSB7XG4gICAgICBpZiAobmV4dENoYW5nZSA9PSBwb3MpIHsgLy8gVXBkYXRlIGN1cnJlbnQgbWFya2VyIHNldFxuICAgICAgICBzcGFuU3R5bGUgPSBzcGFuRW5kU3R5bGUgPSBzcGFuU3RhcnRTdHlsZSA9IHRpdGxlID0gY3NzID0gXCJcIjtcbiAgICAgICAgY29sbGFwc2VkID0gbnVsbDsgbmV4dENoYW5nZSA9IEluZmluaXR5O1xuICAgICAgICB2Y
23459XIgZm91bmRCb29rbWFya3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBzcGFucy5sZW5ndGg7ICsraikge1xuICAgICAgICAgIHZhciBzcCA9IHNwYW5zW2pdLCBtID0gc3AubWFya2VyO1xuICAgICAgICAgIGlmIChtLnR5cGUgPT0gXCJib29rbWFya1wiICYmIHNwLmZyb20gPT0gcG9zICYmIG0ud2lkZ2V0Tm9kZSkge1xuICAgICAgICAgICAgZm91bmRCb29rbWFya3MucHVzaChtKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHNwLmZyb20gPD0gcG9zICYmIChzcC50byA9PSBudWxsIHx8IHNwLnRvID4gcG9zIHx8IG0uY29sbGFwc2VkICYmIHNwLnRvID09IHBvcyAmJiBzcC5mcm9tID09IHBvcykpIHtcbiAgICAgICAgICAgIGlmIChzcC50byAhPSBudWxsICYmIHNwLnRvICE9IHBvcyAmJiBuZXh0Q2hhbmdlID4gc3AudG8pIHtcbiAgICAgICAgICAgICAgbmV4dENoYW5nZSA9IHNwLnRvO1xuICAgICAgICAgICAgICBzcGFuRW5kU3R5bGUgPSBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG0uY2xhc3NOYW1lKSBzcGFuU3R5bGUgKz0gXCIgXCIgKyBtLmNsYXNzTmFtZTtcbiAgICAgICAgICAgIGlmIChtLmNzcykgY3NzID0gbS5jc3M7XG4gICAgICAgICAgICBpZiAobS5zdGFydFN0eWxlICYmIHNwLmZyb20gPT0gcG9zKSBzcGFuU3RhcnRTdHlsZSArPSBcIiBcIiArIG0uc3RhcnRTdHlsZTtcbiAgICAgICAgICAgIGlmIChtLmVuZFN0eWxlICYmIHNwLnRvID09IG5leHRDaGFuZ2UpIHNwYW5FbmRTdHlsZSArPSBcIiBcIiArIG0uZW5kU3R5bGU7XG4gICAgICAgICAgICBpZiAobS50aXRsZSAmJiAhdGl0bGUpIHRpdGxlID0gbS50aXRsZTtcbiAgICAgICAgICAgIGlmIChtLmNvbGxhcHNlZCAmJiAoIWNvbGxhcHNlZCB8fCBjb21wYXJlQ29sbGFwc2VkTWFya2Vycyhjb2xsYXBzZWQubWFya2VyLCBtKSA8IDApKVxuICAgICAgICAgICAgICBjb2xsYXBzZWQgPSBzcDtcbiAgICAgICAgICB9IGVsc2UgaWYgKHNwLmZyb20gPiBwb3MgJiYgbmV4dENoYW5nZSA+IHNwLmZyb20pIHtcbiAgICAgICAgICAgIG5leHRDaGFuZ2UgPSBzcC5mcm9tO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoY29sbGFwc2VkICYmIChjb2xsYXBzZWQuZnJvbSB8fCAwKSA9PSBwb3MpIHtcbiAgICAgICAgICBidWlsZENvbGxhcHNlZFNwYW4oYnVpbGRlciwgKGNvbGxhcHNlZC50byA9PSBudWxsID8gbGVuICsgMSA6IGNvbGxhcHNlZC50bykgLSBwb3MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxhcHNlZC5tYXJrZXIsIGNvbGxhcHNlZC5mcm9tID09IG51bGwpO1xuICAgICAgICAgIGlmIChjb2xsYXBzZWQudG8gPT0gbnVsbCkgcmV0dXJuO1xuICAgICAgICAgIGlmIChjb2xsYXBzZWQudG8gPT0gcG9zKSBjb2xsYXBzZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNvbGxhcHNlZCAmJiBmb3VuZEJvb2ttYXJrcy5sZW5ndGgpIGZvciAodmFyIGogPSAwOyBqIDwgZm91bmRCb29rbWFya3MubGVuZ3RoOyArK2opXG4gICAgICAgICAgYnVpbGRDb2xsYXBzZWRTcGFuKGJ1aWxkZXIsIDAsIGZvdW5kQm9va21hcmtzW2pdKTtcbiAgICAgIH1cbiAgICAgIGlmIChwb3MgPj0gbGVuKSBicmVhaztcblxuICAgICAgdmFyIHVwdG8gPSBNYXRoLm1pbihsZW4sIG5leHRDaGFuZ2UpO1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaWYgKHRleHQpIHtcbiAgICAgICAgICB2Y
23459XIgZW5kID0gcG9zICsgdGV4dC5sZW5ndGg7XG4gICAgICAgICAgaWYgKCFjb2xsYXBzZWQpIHtcbiAgICAgICAgICAgIHZhciB0b2tlblRleHQgPSBlbmQgPiB1cHRvID8gdGV4dC5zbGljZSgwLCB1cHRvIC0gcG9zKSA6IHRleHQ7XG4gICAgICAgICAgICBidWlsZGVyLmFkZFRva2VuKGJ1aWxkZXIsIHRva2VuVGV4dCwgc3R5bGUgPyBzdHlsZSArIHNwYW5TdHlsZSA6IHNwYW5TdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhblN0YXJ0U3R5bGUsIHBvcyArIHRva2VuVGV4dC5sZW5ndGggPT0gbmV4dENoYW5nZSA/IHNwYW5FbmRTdHlsZSA6IFwiXCIsIHRpdGxlLCBjc3MpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZW5kID49IHVwdG8pIHt0ZXh0ID0gdGV4dC5zbGljZSh1cHRvIC0gcG9zKTsgcG9zID0gdXB0bzsgYnJlYWs7fVxuICAgICAgICAgIHBvcyA9IGVuZDtcbiAgICAgICAgICBzcGFuU3RhcnRTdHlsZSA9IFwiXCI7XG4gICAgICAgIH1cbiAgICAgICAgdGV4dCA9IGFsbFRleHQuc2xpY2UoYXQsIGF0ID0gc3R5bGVzW2krK10pO1xuICAgICAgICBzdHlsZSA9IGludGVycHJldFRva2VuU3R5bGUoc3R5bGVzW2krK10sIGJ1aWxkZXIuY20ub3B0aW9ucyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gRE9DVU1FTlQgREFUQSBTVFJVQ1RVUkVcblxuICAvLyBCeSBkZWZhdWx0LCB1cGRhdGVzIHRoYXQgc3RhcnQgYW5kIGVuZCBhdCB0aGUgYmVnaW5uaW5nIG9mIGEgbGluZVxuICAvLyBhcmUgdHJlYXRlZCBzcGVjaWFsbHksIGluIG9yZGVyIHRvIG1ha2UgdGhlIGFzc29jaWF0aW9uIG9mIGxpbmVcbiAgLy8gd2lkZ2V0cyBhbmQgbWFya2VyIGVsZW1lbnRzIHdpdGggdGhlIHRleHQgYmVoYXZlIG1vcmUgaW50dWl0aXZlLlxuICBmdW5jdGlvbiBpc1dob2xlTGluZVVwZGF0ZShkb2MsIGNoYW5nZSkge1xuICAgIHJldHVybiBjaGFuZ2UuZnJvbS5jaCA9PSAwICYmIGNoYW5nZS50by5jaCA9PSAwICYmIGxzdChjaGFuZ2UudGV4dCkgPT0gXCJcIiAmJlxuICAgICAgKCFkb2MuY20gfHwgZG9jLmNtLm9wdGlvbnMud2hvbGVMaW5lVXBkYXRlQmVmb3JlKTtcbiAgfVxuXG4gIC8vIFBlcmZvcm0gYSBjaGFuZ2Ugb24gdGhlIGRvY3VtZW50IGRhdGEgc3RydWN0dXJlLlxuICBmdW5jdGlvbiB1cGRhdGVEb2MoZG9jLCBjaGFuZ2UsIG1hcmtlZFNwYW5zLCBlc3RpbWF0ZUhlaWdodCkge1xuICAgIGZ1bmN0aW9uIHNwYW5zRm9yKG4pIHtyZXR1cm4gbWFya2VkU3BhbnMgPyBtYXJrZWRTcGFuc1tuXSA6IG51bGw7fVxuICAgIGZ1bmN0aW9uIHVwZGF0ZShsaW5lLCB0ZXh0LCBzcGFucykge1xuICAgICAgdXBkYXRlTGluZShsaW5lLCB0ZXh0LCBzcGFucywgZXN0aW1hdGVIZWlnaHQpO1xuICAgICAgc2lnbmFsTGF0ZXIobGluZSwgXCJjaGFuZ2VcIiwgbGluZSwgY2hhbmdlKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gbGluZXNGb3Ioc3RhcnQsIGVuZCkge1xuICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0LCByZXN1bHQgPSBbXTsgaSA8IGVuZDsgKytpKVxuICAgICAgICByZXN1bHQucHVzaChuZXcgTGluZSh0ZXh0W2ldLCBzcGFuc0ZvcihpKSwgZXN0aW1hdGVIZWlnaHQpKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgdmFyIGZyb20gPSBjaGFuZ2UuZnJvbSwgdG8gPSBjaGFuZ2UudG8sIHRleHQgPSBjaGFuZ2UudGV4dDtcbiAgICB2YXIgZmlyc3RMaW5lID0gZ2V0TGluZShkb2MsIGZyb20ubGluZSksIGxhc3RMaW5lID0gZ2V0TGluZShkb2MsIHRvLmxpbmUpO1xuICAgIHZhciBsYXN0VGV4dCA9IGxzdCh0ZXh0KSwgbGFzdFNwYW5zID0gc3BhbnNGb3IodGV4dC5sZW5ndGggLSAxKSwgbmxpbmVzID0gdG8ubGluZSAtIGZyb20ubGluZTtcblxuICAgIC8vIEFkanVzdCB0aGUgbGluZSBzdHJ1Y3R1cmVcbiAgICBpZiAoY2hhbmdlLmZ1bGwpIHtcbiAgICAgIGRvYy5pbnNlcnQoMCwgbGluZXNGb3IoMCwgdGV4dC5sZW5ndGgpKTtcbiAgICAgIGRvYy5yZW1vdmUodGV4dC5sZW5ndGgsIGRvYy5zaXplIC0gdGV4dC5sZW5ndGgpO1xuICAgIH0gZWxzZSBpZiAoaXNXaG9sZUxpbmVVcGRhdGUoZG9jLCBjaGFuZ2UpKSB7XG4gICAgICAvLyBUaGlzIGlzIGEgd2hvbGUtbGluZSByZXBsYWNlLiBUcmVhdGVkIHNwZWNpYWxseSB0byBtYWtlXG4gICAgICAvLyBzdXJlIGxpbmUgb2JqZWN0cyBtb3ZlIHRoZSB3YXkgdGhleSBhcmUgc3VwcG9zZWQgdG8uXG4gICAgICB2Y
23459XIgYWRkZWQgPSBsaW5lc0ZvcigwLCB0ZXh0Lmxlbmd0aCAtIDEpO1xuICAgICAgdXBkYXRlKGxhc3RMaW5lLCBsYXN0TGluZS50ZXh0LCBsYXN0U3BhbnMpO1xuICAgICAgaWYgKG5saW5lcykgZG9jLnJlbW92ZShmcm9tLmxpbmUsIG5saW5lcyk7XG4gICAgICBpZiAoYWRkZWQubGVuZ3RoKSBkb2MuaW5zZXJ0KGZyb20ubGluZSwgYWRkZWQpO1xuICAgIH0gZWxzZSBpZiAoZmlyc3RMaW5lID09IGxhc3RMaW5lKSB7XG4gICAgICBpZiAodGV4dC5sZW5ndGggPT0gMSkge1xuICAgICAgICB1cGRhdGUoZmlyc3RMaW5lLCBmaXJzdExpbmUudGV4dC5zbGljZSgwLCBmcm9tLmNoKSArIGxhc3RUZXh0ICsgZmlyc3RMaW5lLnRleHQuc2xpY2UodG8uY2gpLCBsYXN0U3BhbnMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGFkZGVkID0gbGluZXNGb3IoMSwgdGV4dC5sZW5ndGggLSAxKTtcbiAgICAgICAgYWRkZWQucHVzaChuZXcgTGluZShsYXN0VGV4dCArIGZpcnN0TGluZS50ZXh0LnNsaWNlKHRvLmNoKSwgbGFzdFNwYW5zLCBlc3RpbWF0ZUhlaWdodCkpO1xuICAgICAgICB1cGRhdGUoZmlyc3RMaW5lLCBmaXJzdExpbmUudGV4dC5zbGljZSgwLCBmcm9tLmNoKSArIHRleHRbMF0sIHNwYW5zRm9yKDApKTtcbiAgICAgICAgZG9jLmluc2VydChmcm9tLmxpbmUgKyAxLCBhZGRlZCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0ZXh0Lmxlbmd0aCA9PSAxKSB7XG4gICAgICB1cGRhdGUoZmlyc3RMaW5lLCBmaXJzdExpbmUudGV4dC5zbGljZSgwLCBmcm9tLmNoKSArIHRleHRbMF0gKyBsYXN0TGluZS50ZXh0LnNsaWNlKHRvLmNoKSwgc3BhbnNGb3IoMCkpO1xuICAgICAgZG9jLnJlbW92ZShmcm9tLmxpbmUgKyAxLCBubGluZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB1cGRhdGUoZmlyc3RMaW5lLCBmaXJzdExpbmUudGV4dC5zbGljZSgwLCBmcm9tLmNoKSArIHRleHRbMF0sIHNwYW5zRm9yKDApKTtcbiAgICAgIHVwZGF0ZShsYXN0TGluZSwgbGFzdFRleHQgKyBsYXN0TGluZS50ZXh0LnNsaWNlKHRvLmNoKSwgbGFzdFNwYW5zKTtcbiAgICAgIHZhciBhZGRlZCA9IGxpbmVzRm9yKDEsIHRleHQubGVuZ3RoIC0gMSk7XG4gICAgICBpZiAobmxpbmVzID4gMSkgZG9jLnJlbW92ZShmcm9tLmxpbmUgKyAxLCBubGluZXMgLSAxKTtcbiAgICAgIGRvYy5pbnNlcnQoZnJvbS5saW5lICsgMSwgYWRkZWQpO1xuICAgIH1cblxuICAgIHNpZ25hbExhdGVyKGRvYywgXCJjaGFuZ2VcIiwgZG9jLCBjaGFuZ2UpO1xuICB9XG5cbiAgLy8gVGhlIGRvY3VtZW50IGlzIHJlcHJlc2VudGVkIGFzIGEgQlRyZWUgY29uc2lzdGluZyBvZiBsZWF2ZXMsIHdpdGhcbiAgLy8gY2h1bmsgb2YgbGluZXMgaW4gdGhlbSwgYW5kIGJyYW5jaGVzLCB3aXRoIHVwIHRvIHRlbiBsZWF2ZXMgb3JcbiAgLy8gb3RoZXIgYnJhbmNoIG5vZGVzIGJlbG93IHRoZW0uIFRoZSB0b3Agbm9kZSBpcyBhbHdheXMgYSBicmFuY2hcbiAgLy8gbm9kZSwgYW5kIGlzIHRoZSBkb2N1bWVudCBvYmplY3QgaXRzZWxmIChtZWFuaW5nIGl0IGhhc1xuICAvLyBhZGRpdGlvbmFsIG1ldGhvZHMgYW5kIHByb3BlcnRpZXMpLlxuICAvL1xuICAvLyBBbGwgbm9kZXMgaGF2ZSBwYXJlbnQgbGlua3MuIFRoZSB0cmVlIGlzIHVzZWQgYm90aCB0byBnbyBmcm9tXG4gIC8vIGxpbmUgbnVtYmVycyB0byBsaW5lIG9iamVjdHMsIGFuZCB0byBnbyBmcm9tIG9iamVjdHMgdG8gbnVtYmVycy5cbiAgLy8gSXQgYWxzbyBpbmRleGVzIGJ5IGhlaWdodCwgYW5kIGlzIHVzZWQgdG8gY29udmVydCBiZXR3ZWVuIGhlaWdodFxuICAvLyBhbmQgbGluZSBvYmplY3QsIGFuZCB0byBmaW5kIHRoZSB0b3RhbCBoZWlnaHQgb2YgdGhlIGRvY3VtZW50LlxuICAvL1xuICAvLyBTZWUgYWxzbyBodHRwOi8vbWFyaWpuaGF2ZXJiZWtlLm5sL2Jsb2cvY29kZW1pcnJvci1saW5lLXRyZWUuaHRtbFxuXG4gIGZ1bmN0aW9uIExlYWZDaHVuayhsaW5lcykge1xuICAgIHRoaXMubGluZXMgPSBsaW5lcztcbiAgICB0aGlzLnBhcmVudCA9IG51bGw7XG4gICAgZm9yICh2YXIgaSA9IDAsIGhlaWdodCA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgbGluZXNbaV0ucGFyZW50ID0gdGhpcztcbiAgICAgIGhlaWdodCArPSBsaW5lc1tpXS5oZWlnaHQ7XG4gICAgfVxuICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICB9XG5cbiAgTGVhZkNodW5rLnByb3RvdHlwZSA9IHtcbiAgICBjaHVua1NpemU6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5saW5lcy5sZW5ndGg7IH0sXG4gICAgLy8gUmVtb3ZlIHRoZSBuIGxpbmVzIGF0IG9mZnNldCAnYXQnLlxuICAgIHJlbW92ZUlubmVyOiBmdW5jdGlvbihhdCwgbikge1xuICAgICAgZm9yICh2YXIgaSA9IGF0LCBlID0gYXQgKyBuOyBpIDwgZTsgKytpKSB7XG4gICAgICAgIHZhciBsaW5lID0gdGhpcy5saW5lc1tpXTtcbiAgICAgICAgdGhpcy5oZWlnaHQgLT0gbGluZS5oZWlnaHQ7XG4gICAgICAgIGNsZWFuVXBMaW5lKGxpbmUpO1xuICAgICAgICBzaWduYWxMYXRlcihsaW5lLCBcImRlbGV0ZVwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubGluZXMuc3BsaWNlKGF0LCBuKTtcbiAgICB9LFxuICAgIC8vIEhlbHBlciB1c2VkIHRvIGNvbGxhcHNlIGEgc21hbGwgYnJhbmNoIGludG8gYSBzaW5nbGUgbGVhZi5cbiAgICBjb2xsYXBzZTogZnVuY3Rpb24obGluZXMpIHtcbiAgICAgIGxpbmVzLnB1c2guYXBwbHkobGluZXMsIHRoaXMubGluZXMpO1xuICAgIH0sXG4gICAgLy8gSW5zZXJ0IHRoZSBnaXZlbiBhcnJheSBvZiBsaW5lcyBhdCBvZmZzZXQgJ2F0JywgY291bnQgdGhlbSBhc1xuICAgIC8vIGhhdmluZyB0aGUgZ2l2ZW4gaGVpZ2h0LlxuICAgIGluc2VydElubmVyOiBmdW5jdGlvbihhdCwgbGluZXMsIGhlaWdodCkge1xuICAgICAgdGhpcy5oZWlnaHQgKz0gaGVpZ2h0O1xuICAgICAgdGhpcy5saW5lcyA9IHRoaXMubGluZXMuc2xpY2UoMCwgYXQpLmNvbmNhdChsaW5lcykuY29uY2F0KHRoaXMubGluZXMuc2xpY2UoYXQpKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyArK2kpIGxpbmVzW2ldLnBhcmVudCA9IHRoaXM7XG4gICAgfSxcbiAgICAvLyBVc2VkIHRvIGl0ZXJhdGUgb3ZlciBhIHBhcnQgb2YgdGhlIHRyZWUuXG4gICAgaXRlck46IGZ1bmN0aW9uKGF0LCBuLCBvcCkge1xuICAgICAgZm9yICh2YXIgZSA9IGF0ICsgbjsgYXQgPCBlOyArK2F0KVxuICAgICAgICBpZiAob3AodGhpcy5saW5lc1thdF0pKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gI
23459H07XG5cbiAgZnVuY3Rpb24gQnJhbmNoQ2h1bmsoY2hpbGRyZW4pIHtcbiAgICB0aGlzLmNoaWxkcmVuID0gY2hpbGRyZW47XG4gICAgdmFyIHNpemUgPSAwLCBoZWlnaHQgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBjaCA9IGNoaWxkcmVuW2ldO1xuICAgICAgc2l6ZSArPSBjaC5jaHVua1NpemUoKTsgaGVpZ2h0ICs9IGNoLmhlaWdodDtcbiAgICAgIGNoLnBhcmVudCA9IHRoaXM7XG4gICAgfVxuICAgIHRoaXMuc2l6ZSA9IHNpemU7XG4gICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgdGhpcy5wYXJlbnQgPSBudWxsO1xuICB9XG5cbiAgQnJhbmNoQ2h1bmsucHJvdG90eXBlID0ge1xuICAgIGNodW5rU2l6ZTogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLnNpemU7IH0sXG4gICAgcmVtb3ZlSW5uZXI6IGZ1bmN0aW9uKGF0LCBuKSB7XG4gICAgICB0aGlzLnNpemUgLT0gbjtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgY2hpbGQgPSB0aGlzLmNoaWxkcmVuW2ldLCBzeiA9IGNoaWxkLmNodW5rU2l6ZSgpO1xuICAgICAgICBpZiAoYXQgPCBzeikge1xuICAgICAgICAgIHZhciBybSA9IE1hdGgubWluKG4sIHN6IC0gYXQpLCBvbGRIZWlnaHQgPSBjaGlsZC5oZWlnaHQ7XG4gICAgICAgICAgY2hpbGQucmVtb3ZlSW5uZXIoYXQsIHJtKTtcbiAgICAgICAgICB0aGlzLmhlaWdodCAtPSBvbGRIZWlnaHQgLSBjaGlsZC5oZWlnaHQ7XG4gICAgICAgICAgaWYgKHN6ID09IHJtKSB7IHRoaXMuY2hpbGRyZW4uc3BsaWNlKGktLSwgMSk7IGNoaWxkLnBhcmVudCA9IG51bGw7IH1cbiAgICAgICAgICBpZiAoKG4gLT0gcm0pID09IDApIGJyZWFrO1xuICAgICAgICAgIGF0ID0gMDtcbiAgICAgICAgfSBlbHNlIGF0IC09IHN6O1xuICAgICAgfVxuICAgICAgLy8gSWYgdGhlIHJlc3VsdCBpcyBzbWFsbGVyIHRoYW4gMjUgbGluZXMsIGVuc3VyZSB0aGF0IGl0IGlzIGFcbiAgICAgIC8vIHNpbmdsZSBsZWFmIG5vZGUuXG4gICAgICBpZiAodGhpcy5zaXplIC0gbiA8IDI1ICYmXG4gICAgICAgICAgKHRoaXMuY2hpbGRyZW4ubGVuZ3RoID4gMSB8fCAhKHRoaXMuY2hpbGRyZW5bMF0gaW5zdGFuY2VvZiBMZWFmQ2h1bmspKSkge1xuICAgICAgICB2Y
23459XIgbGluZXMgPSBbXTtcbiAgICAgICAgdGhpcy5jb2xsYXBzZShsaW5lcyk7XG4gICAgICAgIHRoaXMuY2hpbGRyZW4gPSBbbmV3IExlYWZDaHVuayhsaW5lcyldO1xuICAgICAgICB0aGlzLmNoaWxkcmVuWzBdLnBhcmVudCA9IHRoaXM7XG4gICAgICB9XG4gICAgfSxcbiAgICBjb2xsYXBzZTogZnVuY3Rpb24obGluZXMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7ICsraSkgdGhpcy5jaGlsZHJlbltpXS5jb2xsYXBzZShsaW5lcyk7XG4gICAgfSxcbiAgICBpbnNlcnRJbm5lcjogZnVuY3Rpb24oYXQsIGxpbmVzLCBoZWlnaHQpIHtcbiAgICAgIHRoaXMuc2l6ZSArPSBsaW5lcy5sZW5ndGg7XG4gICAgICB0aGlzLmhlaWdodCArPSBoZWlnaHQ7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5jaGlsZHJlbltpXSwgc3ogPSBjaGlsZC5jaHVua1NpemUoKTtcbiAgICAgICAgaWYgKGF0IDw9IHN6KSB7XG4gICAgICAgICAgY2hpbGQuaW5zZXJ0SW5uZXIoYXQsIGxpbmVzLCBoZWlnaHQpO1xuICAgICAgICAgIGlmIChjaGlsZC5saW5lcyAmJiBjaGlsZC5saW5lcy5sZW5ndGggPiA1MCkge1xuICAgICAgICAgICAgd2hpbGUgKGNoaWxkLmxpbmVzLmxlbmd0aCA+IDUwKSB7XG4gICAgICAgICAgICAgIHZhciBzcGlsbGVkID0gY2hpbGQubGluZXMuc3BsaWNlKGNoaWxkLmxpbmVzLmxlbmd0aCAtIDI1LCAyNSk7XG4gICAgICAgICAgICAgIHZhciBuZXdsZWFmID0gbmV3IExlYWZDaHVuayhzcGlsbGVkKTtcbiAgICAgICAgICAgICAgY2hpbGQuaGVpZ2h0IC09IG5ld2xlYWYuaGVpZ2h0O1xuICAgICAgICAgICAgICB0aGlzLmNoaWxkcmVuLnNwbGljZShpICsgMSwgMCwgbmV3bGVhZik7XG4gICAgICAgICAgICAgIG5ld2xlYWYucGFyZW50ID0gdGhpcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubWF5YmVTcGlsbCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBhdCAtPSBzejtcbiAgICAgIH1cbiAgICB9LFxuICAgIC8vIFdoZW4gYSBub2RlIGhhcyBncm93biwgY2hlY2sgd2hldGhlciBpdCBzaG91bGQgYmUgc3BsaXQuXG4gICAgbWF5YmVTcGlsbDogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGggPD0gMTApIHJldHVybjtcbiAgICAgIHZhciBtZSA9IHRoaXM7XG4gICAgICBkbyB7XG4gICAgICAgIHZhciBzcGlsbGVkID0gbWUuY2hpbGRyZW4uc3BsaWNlKG1lLmNoaWxkcmVuLmxlbmd0aCAtIDUsIDUpO1xuICAgICAgICB2Y
23459XIgc2libGluZyA9IG5ldyBCcmFuY2hDaHVuayhzcGlsbGVkKTtcbiAgICAgICAgaWYgKCFtZS5wYXJlbnQpIHsgLy8gQmVjb21lIHRoZSBwYXJlbnQgbm9kZVxuICAgICAgICAgIHZhciBjb3B5ID0gbmV3IEJyYW5jaENodW5rKG1lLmNoaWxkcmVuKTtcbiAgICAgICAgICBjb3B5LnBhcmVudCA9IG1lO1xuICAgICAgICAgIG1lLmNoaWxkcmVuID0gW2NvcHksIHNpYmxpbmddO1xuICAgICAgICAgIG1lID0gY29weTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtZS5zaXplIC09IHNpYmxpbmcuc2l6ZTtcbiAgICAgICAgICBtZS5oZWlnaHQgLT0gc2libGluZy5oZWlnaHQ7XG4gICAgICAgICAgdmFyIG15SW5kZXggPSBpbmRleE9mKG1lLnBhcmVudC5jaGlsZHJlbiwgbWUpO1xuICAgICAgICAgIG1lLnBhcmVudC5jaGlsZHJlbi5zcGxpY2UobXlJbmRleCArIDEsIDAsIHNpYmxpbmcpO1xuICAgICAgICB9XG4gICAgICAgIHNpYmxpbmcucGFyZW50ID0gbWUucGFyZW50O1xuICAgICAgfSB3aGlsZSAobWUuY2hpbGRyZW4ubGVuZ3RoID4gMTApO1xuICAgICAgbWUucGFyZW50Lm1heWJlU3BpbGwoKTtcbiAgICB9LFxuICAgIGl0ZXJOOiBmdW5jdGlvbihhdCwgbiwgb3ApIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgY2hpbGQgPSB0aGlzLmNoaWxkcmVuW2ldLCBzeiA9IGNoaWxkLmNodW5rU2l6ZSgpO1xuICAgICAgICBpZiAoYXQgPCBzeikge1xuICAgICAgICAgIHZhciB1c2VkID0gTWF0aC5taW4obiwgc3ogLSBhdCk7XG4gICAgICAgICAgaWYgKGNoaWxkLml0ZXJOKGF0LCB1c2VkLCBvcCkpIHJldHVybiB0cnVlO1xuICAgICAgICAgIGlmICgobiAtPSB1c2VkKSA9PSAwKSBicmVhaztcbiAgICAgICAgICBhdCA9IDA7XG4gICAgICAgIH0gZWxzZSBhdCAtPSBzejtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdmFyIG5leHREb2NJZCA9IDA7XG4gIHZhciBEb2MgPSBDb2RlTWlycm9yLkRvYyA9IGZ1bmN0aW9uKHRleHQsIG1vZGUsIGZpcnN0TGluZSwgbGluZVNlcCkge1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEb2MpKSByZXR1cm4gbmV3IERvYyh0ZXh0LCBtb2RlLCBmaXJzdExpbmUsIGxpbmVTZXApO
234591xuICAgIGlmIChmaXJzdExpbmUgPT0gbnVsbCkgZmlyc3RMaW5lID0gMDtcblxuICAgIEJyYW5jaENodW5rLmNhbGwodGhpcywgW25ldyBMZWFmQ2h1bmsoW25ldyBMaW5lKFwiXCIsIG51bGwpXSldKTtcbiAgICB0aGlzLmZpcnN0ID0gZmlyc3RMaW5lO1xuICAgIHRoaXMuc2Nyb2xsVG9wID0gdGhpcy5zY3JvbGxMZWZ0ID0gMDtcbiAgICB0aGlzLmNhbnRFZGl0ID0gZmFsc2U7XG4gICAgdGhpcy5jbGVhbkdlbmVyYXRpb24gPSAxO1xuICAgIHRoaXMuZnJvbnRpZXIgPSBmaXJzdExpbmU7XG4gICAgdmFyIHN0YXJ0ID0gUG9zKGZpcnN0TGluZSwgMCk7XG4gICAgdGhpcy5zZWwgPSBzaW1wbGVTZWxlY3Rpb24oc3RhcnQpO1xuICAgIHRoaXMuaGlzdG9yeSA9IG5ldyBIaXN0b3J5KG51bGwpO1xuICAgIHRoaXMuaWQgPSArK25leHREb2NJZDtcbiAgICB0aGlzLm1vZGVPcHRpb24gPSBtb2RlO1xuICAgIHRoaXMubGluZVNlcCA9IGxpbmVTZXA7XG5cbiAgICBpZiAodHlwZW9mIHRleHQgPT0gXCJzdHJpbmdcIikgdGV4dCA9IHRoaXMuc3BsaXRMaW5lcyh0ZXh0KTtcbiAgICB1cGRhdGVEb2ModGhpcywge2Zyb206IHN0YXJ0LCB0bzogc3RhcnQsIHRleHQ6IHRleHR9KTtcbiAgICBzZXRTZWxlY3Rpb24odGhpcywgc2ltcGxlU2VsZWN0aW9uKHN0YXJ0KSwgc2VsX2RvbnRTY3JvbGwpO1xuICB9O1xuXG4gIERvYy5wcm90b3R5cGUgPSBjcmVhdGVPYmooQnJhbmNoQ2h1bmsucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IERvYyxcbiAgICAvLyBJdGVyYXRlIG92ZXIgdGhlIGRvY3VtZW50LiBTdXBwb3J0cyB0d28gZm9ybXMgLS0gd2l0aCBvbmx5IG9uZVxuICAgIC8vIGFyZ3VtZW50LCBpdCBjYWxscyB0aGF0IGZvciBlYWNoIGxpbmUgaW4gdGhlIGRvY3VtZW50LiBXaXRoXG4gICAgLy8gdGhyZWUsIGl0IGl0ZXJhdGVzIG92ZXIgdGhlIHJhbmdlIGdpdmVuIGJ5IHRoZSBmaXJzdCB0d28gKHdpdGhcbiAgICAvLyB0aGUgc2Vjb25kIGJlaW5nIG5vbi1pbmNsdXNpdmUpLlxuICAgIGl0ZXI6IGZ1bmN0aW9uKGZyb20sIHRvLCBvcCkge1xuICAgICAgaWYgKG9wKSB0aGlzLml0ZXJOKGZyb20gLSB0aGlzLmZpcnN0LCB0byAtIGZyb20sIG9wKTtcbiAgICAgIGVsc2UgdGhpcy5pdGVyTih0aGlzLmZpcnN0LCB0aGlzLmZpcnN0ICsgdGhpcy5zaXplLCBmcm9tKTtcbiAgICB9LFxuXG4gICAgLy8gTm9uLXB1YmxpYyBpbnRlcmZhY2UgZm9yIGFkZGluZyBhbmQgcmVtb3ZpbmcgbGluZXMuXG4gICAgaW5zZXJ0OiBmdW5jdGlvbihhdCwgbGluZXMpIHtcbiAgICAgIHZhciBoZWlnaHQgPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkgaGVpZ2h0ICs9IGxpbmVzW2ldLmhlaWdodDtcbiAgICAgIHRoaXMuaW5zZXJ0SW5uZXIoYXQgLSB0aGlzLmZpcnN0LCBsaW5lcywgaGVpZ2h0KTtcbiAgICB9LFxuICAgIHJlbW92ZTogZnVuY3Rpb24oYXQsIG4pIHsgdGhpcy5yZW1vdmVJbm5lcihhdCAtIHRoaXMuZmlyc3QsIG4pOyB9LFxuXG4gICAgLy8gRnJvbSBoZXJlLCB0aGUgbWV0aG9kcyBhcmUgcGFydCBvZiB0aGUgcHVibGljIGludGVyZmFjZS4gTW9zdFxuICAgIC8vIGFyZSBhbHNvIGF2YWlsYWJsZSBmcm9tIENvZGVNaXJyb3IgKGVkaXRvcikgaW5zdGFuY2VzLlxuXG4gICAgZ2V0VmFsdWU6IGZ1bmN0aW9uKGxpbmVTZXApIHtcbiAgICAgIHZhciBsaW5lcyA9IGdldExpbmVzKHR
23459oaXMsIHRoaXMuZmlyc3QsIHRoaXMuZmlyc3QgKyB0aGlzLnNpemUpO1xuICAgICAgaWYgKGxpbmVTZXAgPT09IGZhbHNlKSByZXR1cm4gbGluZXM7XG4gICAgICByZXR1cm4gbGluZXMuam9pbihsaW5lU2VwIHx8IHRoaXMubGluZVNlcGFyYXRvcigpKTtcbiAgICB9LFxuICAgIHNldFZhbHVlOiBkb2NNZXRob2RPcChmdW5jdGlvbihjb2RlKSB7XG4gICAgICB2YXIgdG9wID0gUG9zKHRoaXMuZmlyc3QsIDApLCBsYXN0ID0gdGhpcy5maXJzdCArIHRoaXMuc2l6ZSAtIDE7XG4gICAgICBtYWtlQ2hhbmdlKHRoaXMsIHtmcm9tOiB0b3AsIHRvOiBQb3MobGFzdCwgZ2V0TGluZSh0aGlzLCBsYXN0KS50ZXh0Lmxlbmd0aCksXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiB0aGlzLnNwbGl0TGluZXMoY29kZSksIG9yaWdpbjogXCJzZXRWYWx1ZVwiLCBmdWxsOiB0cnVlfSwgdHJ1ZSk7XG4gICAgICBzZXRTZWxlY3Rpb24odGhpcywgc2ltcGxlU2VsZWN0aW9uKHRvcCkpO1xuICAgIH0pLFxuICAgIHJlcGxhY2VSYW5nZTogZnVuY3Rpb24oY29kZSwgZnJvbSwgdG8sIG9yaWdpbikge1xuICAgICAgZnJvbSA9IGNsaXBQb3ModGhpcywgZnJvbSk7XG4gICAgICB0byA9IHRvID8gY2xpcFBvcyh0aGlzLCB0bykgOiBmcm9tO1xuICAgICAgcmVwbGFjZVJhbmdlKHRoaXMsIGNvZGUsIGZyb20sIHRvLCBvcmlnaW4pO1xuICAgIH0sXG4gICAgZ2V0UmFuZ2U6IGZ1bmN0aW9uKGZyb20sIHRvLCBsaW5lU2VwKSB7XG4gICAgICB2YXIgbGluZXMgPSBnZXRCZXR3ZWVuKHRoaXMsIGNsaXBQb3ModGhpcywgZnJvbSksIGNsaXBQb3ModGhpcywgdG8pKTtcbiAgICAgIGlmIChsaW5lU2VwID09PSBmYWxzZSkgcmV0dXJuIGxpbmVzO1xuICAgICAgcmV0dXJuIGxpbmVzLmpvaW4obGluZVNlcCB8fCB0aGlzLmxpbmVTZXBhcmF0b3IoKSk7XG4gICAgfSxcblxuICAgIGdldExpbmU6IGZ1bmN0aW9uKGxpbmUpIHt2YXIgbCA9IHRoaXMuZ2V0TGluZUhhbmRsZShsaW5lKTsgcmV0dXJuIGwgJiYgbC50ZXh0O30sXG5cbiAgICBnZXRMaW5lSGFuZGxlOiBmdW5jdGlvbihsaW5lKSB7aWYgKGlzTGluZSh0aGlzLCBsaW5lKSkgcmV0dXJuIGdldExpbmUodGhpcywgbGluZSk7fSxcbiAgICBnZXRMaW5lTnVtYmVyOiBmdW5jdGlvbihsaW5lKSB7cmV0dXJuIGxpbmVObyhsaW5lKTt9LFxuXG4gICAgZ2V0TGluZUhhbmRsZVZpc3VhbFN0YXJ0OiBmdW5jdGlvbihsaW5lKSB7XG4gICAgICBpZiAodHlwZW9mIGxpbmUgPT0gXCJudW1iZXJcIikgbGluZSA9IGdldExpbmUodGhpcywgbGluZSk7XG4gICAgICByZXR1cm4gdmlzdWFsTGluZShsaW5lKTtcbiAgICB9LFxuXG4gICAgbGluZUNvdW50OiBmdW5jdGlvbigpIHtyZXR1cm4gdGhpcy5zaXplO30sXG4gICAgZmlyc3RMaW5lOiBmdW5jdGlvbigpIHtyZXR1cm4gdGhpcy5maXJzdDt9LFxuICAgIGxhc3RMaW5lOiBmdW5jdGlvbigpIHtyZXR1cm4gdGhpcy5maXJzdCArIHRoaXMuc2l6ZSAtIDE7fSxcblxuICAgIGNsaXBQb3M6IGZ1bmN0aW9uKHBvcykge3JldHVybiBjbGlwUG9zKHRoaXMsIHBvcyk7fSxcblxuICAgIGdldEN1cnNvcjogZnVuY3Rpb24oc3RhcnQpIHtcbiAgICAgIHZhciByYW5nZSA9IHRoaXMuc2VsLnByaW1hcnkoKSwgcG9zO1xuICAgICAgaWYgKHN0YXJ0ID09IG51bGwgfHwgc3RhcnQgPT0gXCJoZWFkXCIpIHBvcyA9IHJhbmdlLmhlYWQ7XG4gICAgICBlbHNlIGlmIChzdGFydCA9PSBcImFuY2hvclwiKSBwb3MgPSByYW5nZS5hbmNob3I7XG4gICAgICBlbHNlIGlmIChzdGFydCA9PSBcImVuZFwiIHx8IHN0YXJ0ID09IFwidG9cIiB8fCBzdGFydCA9PT0gZmFsc2UpIHBvcyA9IHJhbmdlLnRvKCk7XG4gICAgICBlbHNlIHBvcyA9IHJhbmdlLmZyb20oKTtcbiAgICAgIHJldHVybiBwb3M7XG4gICAgfSxcbiAgICBsaXN0U2VsZWN0aW9uczogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLnNlbC5yYW5nZXM7IH0sXG4gICAgc29tZXRoaW5nU2VsZWN0ZWQ6IGZ1bmN0aW9uKCkge3JldHVybiB0aGlzLnNlbC5zb21ldGhpbmdTZWxlY3RlZCgpO30sXG5cbiAgICBzZXRDdXJzb3I6IGRvY01ldGhvZE9wKGZ1bmN0aW9uKGxpbmUsIGNoLCBvcHRpb25zKSB7XG4gICAgICBzZXRTaW1wbGVTZWxlY3Rpb24odGhpcywgY2xpcFBvcyh0aGlzLCB0eXBlb2YgbGluZSA9PSBcIm51bWJlclwiID8gUG9zKGxpbmUsIGNoIHx8IDApIDogbGluZSksIG51bGwsIG9wdGlvbnMpO1xuICAgIH0pLFxuICAgIHNldFNlbGVjdGlvbjogZG9jTWV0aG9kT3AoZnVuY3Rpb24oYW5jaG9yLCBoZWFkLCBvcHRpb25zKSB7XG4gICAgICBzZXRTaW1wbGVTZWxlY3Rpb24odGhpcywgY2xpcFBvcyh0aGlzLCBhbmNob3IpLCBjbGlwUG9zKHRoaXMsIGhlYWQgfHwgYW5jaG9yKSwgb3B0aW9ucyk7XG4gICAgfSksXG4gICAgZXh0ZW5kU2VsZWN0aW9uOiBkb2NNZXRob2RPcChmdW5jdGlvbihoZWFkLCBvdGhlciwgb3B0aW9ucykge1xuICAgICAgZXh0ZW5kU2VsZWN0aW9uKHRoaXMsIGNsaXBQb3ModGhpcywgaGVhZCksIG90aGVyICYmIGNsaXBQb3ModGhpcywgb3RoZXIpLCBvcHRpb25zKTtcbiAgICB9KSxcbiAgICBleHRlbmRTZWxlY3Rpb25zOiBkb2NNZXRob2RPcChmdW5jdGlvbihoZWFkcywgb3B0aW9ucykge1xuICAgICAgZXh0ZW5kU2VsZWN0aW9ucyh0aGlzLCBjbGlwUG9zQXJyYXkodGhpcywgaGVhZHMsIG9wdGlvbnMpKTtcbiAgICB9KSxcbiAgICBleHRlbmRTZWxlY3Rpb25zQnk6IGRvY01ldGhvZE9wKGZ1bmN0aW9uKGYsIG9wdGlvbnMpIHtcbiAgICAgIGV4dGVuZFNlbGVjdGlvbnModGhpcywgbWFwKHRoaXMuc2VsLnJhbmdlcywgZi
vendor: 9,389 bytes, line 23459
23459ksIG9wdGlvbnMpO1xuICAgIH0pLFxuICAgIHNldFNlbGVjdGlvbnM6IGRvY01ldGhvZE9wKGZ1bmN0aW9uKHJhbmdlcywgcHJpbWFyeSwgb3B0aW9ucykge1xuICAgICAgaWYgKCFyYW5nZXMubGVuZ3RoKSByZXR1cm47XG4gICAgICBmb3IgKHZhciBpID0gMCwgb3V0ID0gW107IGkgPCByYW5nZXMubGVuZ3RoOyBpKyspXG4gICAgICAgIG91dFtpXSA9IG5ldyBSYW5nZShjbGlwUG9zKHRoaXMsIHJhbmdlc1tpXS5hbmNob3IpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcFBvcyh0aGlzLCByYW5nZXNbaV0uaGVhZCkpO1xuICAgICAgaWYgKHByaW1hcnkgPT0gbnVsbCkgcHJpbWFyeSA9IE1hdGgubWluKHJhbmdlcy5sZW5ndGggLSAxLCB0aGlzLnNlbC5wcmltSW5kZXgpO1xuICAgICAgc2V0U2VsZWN0aW9uKHRoaXMsIG5vcm1hbGl6ZVNlbGVjdGlvbihvdXQsIHByaW1hcnkpLCBvcHRpb25zKTtcbiAgICB9KSxcbiAgICBhZGRTZWxlY3Rpb246IGRvY01ldGhvZE9wKGZ1bmN0aW9uKGFuY2hvciwgaGVhZCwgb3B0aW9ucykge1xuICAgICAgdmFyIHJhbmdlcyA9IHRoaXMuc2VsLnJhbmdlcy5zbGljZSgwKTtcbiAgICAgIHJhbmdlcy5wdXNoKG5ldyBSYW5nZShjbGlwUG9zKHRoaXMsIGFuY2hvciksIGNsaXBQb3ModGhpcywgaGVhZCB8fCBhbmNob3IpKSk7XG4gICAgICBzZXRTZWxlY3Rpb24odGhpcywgbm9ybWFsaXplU2VsZWN0aW9uKHJhbmdlcywgcmFuZ2VzLmxlbmd0aCAtIDEpLCBvcHRpb25zKTtcbiAgICB9KSxcblxuICAgIGdldFNlbGVjdGlvbjogZnVuY3Rpb24obGluZVNlcCkge1xuICAgICAgdmFyIHJhbmdlcyA9IHRoaXMuc2VsLnJhbmdlcywgbGluZXM7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc2VsID0gZ2V0QmV0d2Vlbih0aGlzLCByYW5nZXNbaV0uZnJvbSgpLCByYW5nZXNbaV0udG8oKSk7XG4gICAgICAgIGxpbmVzID0gbGluZXMgPyBsaW5lcy5jb25jYXQoc2VsKSA6IHNlbDtcbiAgICAgIH1cbiAgICAgIGlmIChsaW5lU2VwID09PSBmYWxzZSkgcmV0dXJuIGxpbmVzO1xuICAgICAgZWxzZSByZXR1cm4gbGluZXMuam9pbihsaW5lU2VwIHx8IHRoaXMubGluZVNlcGFyYXRvcigpKTtcbiAgICB9LFxuICAgIGdldFNlbGVjdGlvbnM6IGZ1bmN0aW9uKGxpbmVTZXApIHtcbiAgICAgIHZhciBwYXJ0cyA9IFtdLCByYW5nZXMgPSB0aGlzLnNlbC5yYW5nZXM7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc2VsID0gZ2V0QmV0d2Vlbih0aGlzLCByYW5nZXNbaV0uZnJvbSgpLCByYW5nZXNbaV0udG8oKSk7XG4gICAgICAgIGlmIChsaW5lU2VwICE9PSBmYWxzZSkgc2VsID0gc2VsLmpvaW4obGluZVNlcCB8fCB0aGlzLmxpbmVTZXBhcmF0b3IoKSk7XG4gICAgICAgIHBhcnRzW2ldID0gc2VsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHBhcnRzO1xuICAgIH0sXG4gICAgcmVwbGFjZVNlbGVjdGlvbjogZnVuY3Rpb24oY29kZSwgY29sbGFwc2UsIG9yaWdpbikge1xuICAgICAgdmFyIGR1cCA9IFtdO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnNlbC5yYW5nZXMubGVuZ3RoOyBpKyspXG4gICAgICAgIGR1cFtpXSA9IGNvZGU7XG4gICAgICB0aGlzLnJlcGxhY2VTZWxlY3Rpb25zKGR1cCwgY29sbGFwc2UsIG9yaWdpbiB8fCBcIitpbnB1dFwiKTtcbiAgICB9LFxuICAgIHJlcGxhY2VTZWxlY3Rpb25zOiBkb2NNZXRob2RPcChmdW5jdGlvbihjb2RlLCBjb2xsYXBzZSwgb3JpZ2luKSB7XG4gICAgICB2YXIgY2hhbmdlcyA9IFtdLCBzZWwgPSB0aGlzLnNlbDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsLnJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgcmFuZ2UgPSBzZWwucmFuZ2VzW2ldO1xuICAgICAgICBjaGFuZ2VzW2ldID0ge2Zyb206IHJhbmdlLmZyb20oKSwgdG86IHJhbmdlLnRvKCksIHRleHQ6IHRoaXMuc3BsaXRMaW5lcyhjb2RlW2ldKSwgb3JpZ2luOiBvcmlnaW59O1xuICAgICAgfVxuICAgICAgdmFyIG5ld1NlbCA9IGNvbGxhcHNlICYmIGNvbGxhcHNlICE9IFwiZW5kXCIgJiYgY29tcHV0ZVJlcGxhY2VkU2VsKHRoaXMsIGNoYW5nZXMsIGNvbGxhcHNlKTtcbiAgICAgIGZvciAodmFyIGkgPSBjaGFuZ2VzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKVxuICAgICAgICBtYWtlQ2hhbmdlKHRoaXMsIGNoYW5nZXNbaV0pO1xuICAgICAgaWYgKG5ld1NlbCkgc2V0U2VsZWN0aW9uUmVwbGFjZUhpc3RvcnkodGhpcywgbmV3U2VsKTtcbiAgICAgIGVsc2UgaWYgKHRoaXMuY20pIGVuc3VyZUN1cnNvclZpc2libGUodGhpcy5jbSk7XG4gICAgfSksXG4gICAgdW5kbzogZG9jTWV0aG9kT3AoZnVuY3Rpb24oKSB7bWFrZUNoYW5nZUZyb21IaXN0b3J5KHRoaXMsIFwidW5kb1wiKTt9KSxcbiAgICByZWRvOiBkb2NNZXRob2RPcChmdW5jdGlvbigpIHttYWtlQ2hhbmdlRnJvbUhpc3RvcnkodGhpcywgXCJyZWRvXCIpO30pLFxuICAgIHVuZG9TZWxlY3Rpb246IGRvY01ldGhvZE9wKGZ1bmN0aW9uKCkge21ha2VDaGFuZ2VGcm9tSGlzdG9yeSh0aGlzLCBcInVuZG9cIiwgdHJ1ZSk7fSksXG4gICAgcmVkb1NlbGVjdGlvbjogZG9jTWV0aG9kT3AoZnVuY3Rpb24oKSB7bWFrZUNoYW5nZUZyb21IaXN0b3J5KHRoaXMsIFwicmVkb1wiLCB0cnVlKTt9KSxcblxuICAgIHNldEV4dGVuZGluZzogZnVuY3Rpb24odmFsKSB7dGhpcy5leHRlbmQgPSB2YWw7fSxcbiAgICBnZXRFeHRlbmRpbmc6IGZ1bmN0aW9uKCkge3JldHVybiB0aGlzLmV4dGVuZDt9LFxuXG4gICAgaGlzdG9yeVNpemU6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGhpc3QgPSB0aGlzLmhpc3RvcnksIGRvbmUgPSAwLCB1bmRvbmUgPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoaXN0LmRvbmUubGVuZ3RoOyBpKyspIGlmICghaGlzdC5kb25lW2ldLnJhbmdlcykgKytkb25lO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoaXN0LnVuZG9uZS5sZW5ndGg7IGkrKykgaWYgKCFoaXN0LnVuZG9uZVtpXS5yYW5nZXMpICsrdW5kb25lO1xuICAgICAgcmV0dXJuIHt1bmRvOiBkb25lLCByZWRvOiB1bmRvbmV9O1xuICAgIH0sXG4gICAgY2xlYXJIaXN0b3J5OiBmdW5jdGlvbigpIHt0aGlzLmhpc3RvcnkgPSBuZXcgSGlzdG9yeSh0aGlzLmhpc3RvcnkubWF4R2VuZXJhdGlvbik7fSxcblxuICAgIG1hcmtDbGVhbjogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmNsZWFuR2VuZXJhdGlvbiA9IHRoaXMuY2hhbmdlR2VuZXJhdGlvbih0cnVlKTtcbiAgICB9LFxuICAgIGNoYW5nZUdlbmVyYXRpb246IGZ1bmN0aW9uKGZvcmNlU3BsaXQpIHtcbiAgICAgIGlmIChmb3JjZVNwbGl0KVxuICAgICAgICB0aGlzLmhpc3RvcnkubGFzdE9wID0gdGhpcy5oaXN0b3J5Lmxhc3RTZWxPcCA9IHRoaXMuaGlzdG9yeS5sYXN0T3JpZ2luID0gbnVsbDtcbiAgICAgIHJldHVybiB0aGlzLmhpc3RvcnkuZ2VuZXJhdGlvbjtcbiAgICB9LFxuICAgIGlzQ2xlYW46IGZ1bmN0aW9uIChnZW4pIHtcbiAgICAgIHJldHVybiB0aGlzLmhpc3RvcnkuZ2VuZXJhdGlvbiA9PSAoZ2VuIHx8IHRoaXMuY2xlYW5HZW5lcmF0aW9uKTtcbiAgICB9LFxuXG4gICAgZ2V0SGlzdG9yeTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4ge2RvbmU6IGNvcHlIaXN0b3J5QXJyYXkodGhpcy5oaXN0b3J5LmRvbmUpLFxuICAgICAgICAgICAgICB1bmRvbmU6IGNvcHlIaXN0b3J5QXJyYXkodGhpcy5oaXN0b3J5LnVuZG9uZSl9O1xuICAgIH0sXG4gICAgc2V0SGlzdG9yeTogZnVuY3Rpb24oaGlzdERhdGEpIHtcbiAgICAgIHZhciBoaXN0ID0gdGhpcy5oaXN0b3J5ID0gbmV3IEhpc3RvcnkodGhpcy5oaXN0b3J5Lm1heEdlbmVyYXRpb24pO1xuICAgICAgaGlzdC5kb25lID0gY29weUhpc3RvcnlBcnJheShoaXN0RGF0YS5kb25lLnNsaWNlKDApLCBudWxsLCB0cnVlKTtcbiAgICAgIGhpc3QudW5kb25lID0gY29weUhpc3RvcnlBcnJheShoaXN0RGF0YS51bmRvbmUuc2xpY2UoMCksIG51bGwsIHRydWUpO1xuICAgIH0sXG5cbiAgICBhZGRMaW5lQ2xhc3M6IGRvY01ldGhvZE9wKGZ1bmN0aW9uKGhhbmRsZSwgd2hlcmUsIGNscykge1xuICAgICAgcmV0dXJuIGNoYW5nZUxpbmUodGhpcywgaGFuZGxlLCB3aGVyZSA9PSBcImd1dHRlclwiID8gXCJndXR0ZXJcIiA6IFwiY2xhc3NcIiwgZnVuY3Rpb24obGluZSkge1xuICAgICAgICB2YXIgcHJvcCA9IHdoZXJlID09IFwidGV4dFwiID8gXCJ0ZXh0Q2xhc3NcIlxuICAgICAgICAgICAgICAgICA6IHdoZXJlID09IFwiYmFja2dyb3VuZFwiID8gXCJiZ0NsYXNzXCJcbiAgICAgICAgICAgICAgICAgOiB3aGVyZSA9PSBcImd1dHRlclwiID8gXCJndXR0ZXJDbGFzc1wiIDogXCJ3cmFwQ2xhc3NcIjtcbiAgICAgICAgaWYgKCFsaW5lW3Byb3BdKSBsaW5lW3Byb3BdID0gY2xzO1xuICAgICAgICBlbHNlIGlmIChjbGFzc1Rlc3QoY2xzKS50ZXN0KGxpbmVbcHJvcF0pKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGVsc2UgbGluZVtwcm9wXSArPSBcIiBcIiArIGNscztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9KTtcbiAgICB9KSxcbiAgICByZW1vdmVMaW5lQ2xhc3M6IGRvY01ldGhvZE9wKGZ1bmN0aW9uKGhhbmRsZSwgd2hlcmUsIGNscykge1xuICAgICAgcmV0dXJuIGNoYW5nZUxpbmUodGhpcywgaGFuZGxlLCB3aGVyZSA9PSBcImd1dHRlclwiID8gXCJndXR0ZXJcIiA6IFwiY2xhc3NcIiwgZnVuY3Rpb24obGluZSkge1xuICAgICAgICB2YXIgcHJvcCA9IHdoZXJlID09IFwidGV4dFwiID8gXCJ0ZXh0Q2xhc3NcIlxuICAgICAgICAgICAgICAgICA6IHdoZXJlID09IFwiYmFja2dyb3VuZFwiID8gXCJiZ0NsYXNzXCJcbiAgICAgICAgICAgICAgICAgOiB3aGVyZSA9PSBcImd1dHRlclwiID8gXCJndXR0ZXJDbGFzc1wiIDogXCJ3cmFwQ2xhc3NcIjtcbiAgICAgICAgdmFyIGN1ciA9IGxpbmVbcHJvcF07XG4gICAgICAgIGlmICghY3VyKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGVsc2UgaWYgKGNscyA9PSBudWxsKSBsaW5lW3Byb3BdID0gbnVsbDtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdmFyIGZvdW5kID0gY3VyLm1hdGNoKGNsYXNzVGVzdChjbHMpKTtcbiAgICAgICAgICBpZiAoIWZvdW5kKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgdmFyIGVuZCA9IGZvdW5kLmluZGV4ICsgZm91bmRbMF0ubGVuZ3RoO1xuICAgICAgICAgIGxpbmVbcHJvcF0gPSBjdXIuc2xpY2UoMCwgZm91bmQuaW5kZXgpICsgKCFmb3VuZC5pbmRleCB8fCBlbmQgPT0gY3VyLmxlbmd0aCA/IFwiXCIgOiBcIiBcIikgKyBjdXIuc2xpY2UoZW5kKSB8fCBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSk7XG4gICAgfSksXG5cbiAgICBhZGRMaW5lV2lkZ2V0OiBkb2NNZXRob2RPcChmdW5jdGlvbihoYW5kbGUsIG5vZGUsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhZGRMaW5lV2lkZ2V0KHRoaXMsIGhhbmRsZSwgbm9kZSwgb3B0aW9ucyk7XG4gICAgfSksXG4gICAgcmVtb3ZlTGluZVdpZGdldDogZnVuY3Rpb24od2lkZ2V0KSB7IHdpZGdldC5jbGVhcigpOyB9LFxuXG4gICAgbWFya1RleHQ6IGZ1bmN0aW9uKGZyb20sIHRvLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gbWFya1RleHQodGhpcywgY2xpcFBvcyh0aGlzLCBmcm9tKSwgY2xpcFBvcyh0aGlzLCB0byksIG9wdGlvbnMsIG9wdGlvbnMgJiYgb3B0aW9ucy50eXBlIHx8IFwicmFuZ2VcIik7XG4gICAgfSxcbiAgICBzZXRCb29rbWFyazogZnVuY3Rpb24ocG9zLCBvcHRpb25zKSB7XG4gICAgICB2YXIgcmVhbE9wdHMgPSB7cmVwbGFjZWRXaXRoOiBvcHRpb25zICYmIChvcHRpb25zLm5vZGVUeXBlID09IG51bGwgPyBvcHRpb25zLndpZGdldCA6IG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgICAgIGluc2VydExlZnQ6IG9wdGlvbnMgJiYgb3B0aW9ucy5pbnNlcnRMZWZ0LFxuICAgICAgICAgICAgICAgICAgICAgIGNsZWFyV2hlbkVtcHR5OiBmYWxzZSwgc2hhcmVkOiBvcHRpb25zICYmIG9wdGlvbnMuc2hhcmVkLFxuICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZU1vdXNlRXZlbnRzOiBvcHRpb25zICYmIG9wdGlvbnMuaGFuZGxlTW91c2VFdmVudHN9O1xuICAgICAgcG9zID0gY2xpcFBvcyh0aGlzLCBwb3MpO1xuICAgICAgcmV0dXJuIG1hcmtUZXh0KHRoaXMsIHBvcywgcG9zLCByZWFsT3B0cywgXCJib29rbWFya1wiKTtcbiAgICB9LFxuICAgIGZpbmRNYXJrc0F0OiBmdW5jdGlvbihwb3MpIHtcbiAgICAgIHBvcyA9IGNsaXBQb3ModGhpcywgcG9zKTtcbiAgICAgIHZhciBtYXJrZXJzID0gW10sIHNwYW5zID0gZ2V0TGluZSh0aGlzLCBwb3MubGluZSkubWFya2VkU3BhbnM7XG4gICAgICBpZiAoc3BhbnMpIGZvciAodmFyIGkgPSAwOyBpIDwgc3BhbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHNwYW4gPSBzcGFuc1tpXTtcbiAgICAgICAgaWYgKChzcGFuLmZyb20gPT0gbnVsbCB8fCBzcGFuLmZyb20gPD0gcG9zLmNoKSAmJlxuICAgICAgICAgICAgKHNwYW4udG8gPT0gbnVsbCB8fCBzcGFuLnRvID49IHBvcy5jaCkpXG4gICAgICAgICAgbWFya2Vycy5wdXNoKHNwYW4ubWFya2VyLnBhcmVudCB8fCBzcGFuLm1hcmtlcik7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFya2VycztcbiAgICB9LFxuICAgIGZpbmRNYXJrczogZnVuY3Rpb24oZnJvbSwgdG8sIGZpbHRlcikge1xuICAgICAgZnJvbSA9IGNsaXBQb3ModGhpcywgZnJvbSk7IHRvID0gY2xpcFBvcyh0aGlzLCB0byk7XG4gICAgICB2YXIgZm91bmQgPSBbXSwgbGluZU5vID0gZnJvbS5saW5lO1xuICAgICAgdGhpcy5pdGVyKGZyb20ubGluZSwgdG8ubGluZSArIDEsIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgdmFyIHNwYW5zID0gbGluZS5tYXJrZWRTcGFucztcbiAgICAgICAgaWYgKHNwYW5zKSBmb3IgKHZhciBpID0gMDsgaSA8IHNwYW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIHNwYW4gPSBzcGFuc1tpXTtcbiAgICAgICAgICBpZiAoISh
23459saW5lTm8gPT0gZnJvbS5saW5lICYmIGZyb20uY2ggPiBzcGFuLnRvIHx8XG4gICAgICAgICAgICAgICAgc3Bhbi5mcm9tID09IG51bGwgJiYgbGluZU5vICE9IGZyb20ubGluZXx8XG4gICAgICAgICAgICAgICAgbGluZU5vID09IHRvLmxpbmUgJiYgc3Bhbi5mcm9tID4gdG8uY2gpICYmXG4gICAgICAgICAgICAgICghZmlsdGVyIHx8IGZpbHRlcihzcGFuLm1hcmtlcikpKVxuICAgICAgICAgICAgZm91bmQucHVzaChzcGFuLm1hcmtlci5wYXJlbnQgfHwgc3Bhbi5tYXJrZXIpO1xuICAgICAgICB9XG4gICAgICAgICsrbGluZU5vO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gZm91bmQ7XG4gICAgfSxcbiAgICBnZXRBbGxNYXJrczogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgbWFya2VycyA9IFtdO1xuICAgICAgdGhpcy5pdGVyKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgdmFyIHNwcyA9IGxpbmUubWFya2VkU3BhbnM7XG4gICAgICAgIGlmIChzcHMpIGZvciAodmFyIGkgPSAwOyBpIDwgc3BzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChzcHNbaV0uZnJvbSAhPSBudWxsKSBtYXJrZXJzLnB1c2goc3BzW2ldLm1hcmtlcik7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBtYXJrZXJzO1xuICAgIH0sXG5cbiAgICBwb3NGcm9tSW5kZXg6IGZ1bmN0aW9uKG9mZikge1xuICAgICAgdmFyIGNoLCBsaW5lTm8gPSB0aGlzLmZpcnN0O1xuICAgICAgdGhpcy5pdGVyKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgdmFyIHN6ID0gbGluZS50ZXh0Lmxlbmd0aCArIDE7XG4gICAgICAgIGlmIChzeiA+IG9mZikgeyBjaCA9IG9mZjsgcmV0dXJuIHRydWU7IH1cbiAgICAgICAgb2ZmIC09IHN6O1xuICAgICAgICArK2xpbmVObztcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGNsaXBQb3ModGhpcywgUG9zKGxpbmVObywgY2gpKTtcbiAgICB9LFxuICAgIGluZGV4RnJvbVBvczogZnVuY3Rpb24gKGNvb3Jkcykge1xuICAgICAgY29vcmRzID0gY2xpcFBvcyh0aGlzLCBjb29yZHMpO1xuICAgICAgdmFyIGluZGV4ID0gY29vcmRzLmNoO1xuICAgICAgaWYgKGNvb3Jkcy5saW5lIDwgdGhpcy5maXJzdCB8fCBjb29yZHMuY2ggPCAwKSByZXR1cm4gMDtcbiAgICAgIHRoaXMuaXRlcih0aGlzLmZpcnN0LCBjb29yZHMubGluZSwgZnVuY3Rpb24gKGxpbmUpIHtcbiAgICAgICAgaW5kZXggKz0gbGluZS50ZXh0Lmxlbmd0aCArIDE
vendor: 45,029 bytes, line 23459
234597XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9LFxuXG4gICAgY29weTogZnVuY3Rpb24oY29weUhpc3RvcnkpIHtcbiAgICAgIHZhciBkb2MgPSBuZXcgRG9jKGdldExpbmVzKHRoaXMsIHRoaXMuZmlyc3QsIHRoaXMuZmlyc3QgKyB0aGlzLnNpemUpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlT3B0aW9uLCB0aGlzLmZpcnN0LCB0aGlzLmxpbmVTZXApO1xuICAgICAgZG9jLnNjcm9sbFRvcCA9IHRoaXMuc2Nyb2xsVG9wOyBkb2Muc2Nyb2xsTGVmdCA9IHRoaXMuc2Nyb2xsTGVmdDtcbiAgICAgIGRvYy5zZWwgPSB0aGlzLnNlbDtcbiAgICAgIGRvYy5leHRlbmQgPSBmYWxzZTtcbiAgICAgIGlmIChjb3B5SGlzdG9yeSkge1xuICAgICAgICBkb2MuaGlzdG9yeS51bmRvRGVwdGggPSB0aGlzLmhpc3RvcnkudW5kb0RlcHRoO1xuICAgICAgICBkb2Muc2V0SGlzdG9yeSh0aGlzLmdldEhpc3RvcnkoKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZG9jO1xuICAgIH0sXG5cbiAgICBsaW5rZWREb2M6IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgIGlmICghb3B0aW9ucykgb3B0aW9ucyA9IHt9O1xuICAgICAgdmFyIGZyb20gPSB0aGlzLmZpcnN0LCB0byA9IHRoaXMuZmlyc3QgKyB0aGlzLnNpemU7XG4gICAgICBpZiAob3B0aW9ucy5mcm9tICE9IG51bGwgJiYgb3B0aW9ucy5mcm9tID4gZnJvbSkgZnJvbSA9IG9wdGlvbnMuZnJvbTtcbiAgICAgIGlmIChvcHRpb25zLnRvICE9IG51bGwgJiYgb3B0aW9ucy50byA8IHRvKSB0byA9IG9wdGlvbnMudG87XG4gICAgICB2YXIgY29weSA9IG5ldyBEb2MoZ2V0TGluZXModGhpcywgZnJvbSwgdG8pLCBvcHRpb25zLm1vZGUgfHwgdGhpcy5tb2RlT3B0aW9uLCBmcm9tLCB0aGlzLmxpbmVTZXApO1xuICAgICAgaWYgKG9wdGlvbnMuc2hhcmVkSGlzdCkgY29weS5oaXN0b3J5ID0gdGhpcy5oaXN0b3J5O1xuICAgICAgKHRoaXMubGlua2VkIHx8ICh0aGlzLmxpbmtlZCA9IFtdKSkucHVzaCh7ZG9jOiBjb3B5LCBzaGFyZWRIaXN0OiBvcHRpb25zLnNoYXJlZEhpc3R9KTtcbiAgICAgIGNvcHkubGlua2VkID0gW3tkb2M6IHRoaXMsIGlzUGFyZW50OiB0cnVlLCBzaGFyZWRIaXN0OiBvcHRpb25zLnNoYXJlZEhpc3R9XTtcbiAgICAgIGNvcHlTaGFyZWRNYXJrZXJzKGNvcHksIGZpbmRTaGFyZWRNYXJrZXJzKHRoaXMpKTtcbiAgICAgIHJldHVybiBjb3B5O1xuICAgIH0sXG4gICAgdW5saW5rRG9jOiBmdW5jdGlvbihvdGhlcikge1xuICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgQ29kZU1pcnJvcikgb3RoZXIgPSBvdGhlci5kb2M7XG4gICAgICBpZiAodGhpcy5saW5rZWQpIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5saW5rZWQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGxpbmsgPSB0aGlzLmxpbmtlZFtpXTtcbiAgICAgICAgaWYgKGxpbmsuZG9jICE9IG90aGVyKSBjb250aW51ZTtcbiAgICAgICAgdGhpcy5saW5rZWQuc3BsaWNlKGksIDEpO1xuICAgICAgICBvdGhlci51bmxpbmtEb2ModGhpcyk7XG4gICAgICAgIGRldGFjaFNoYXJlZE1hcmtlcnMoZmluZFNoYXJlZE1hcmtlcnModGhpcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIC8vIElmIHRoZSBoaXN0b3JpZXMgd2VyZSBzaGFyZWQsIHNwbGl0IHRoZW0gYWdhaW5cbiAgICAgIGlmIChvdGhlci5oaXN0b3J5ID09IHRoaXMuaGlzdG9yeSkge1xuICAgICAgICB2YXIgc3BsaXRJZHMgPSBbb3RoZXIuaWRdO1xuICAgICAgICBsaW5rZWREb2NzKG90aGVyLCBmdW5jdGlvbihkb2MpIHtzcGxpdElkcy5wdXNoKGRvYy5pZCk7fSwgdHJ1ZSk7XG4gICAgICAgIG90aGVyLmhpc3RvcnkgPSBuZXcgSGlzdG9yeShudWxsKTtcbiAgICAgICAgb3RoZXIuaGlzdG9yeS5kb25lID0gY29weUhpc3RvcnlBcnJheSh0aGlzLmhpc3RvcnkuZG9uZSwgc3BsaXRJZHMpO1xuICAgICAgICBvdGhlci5oaXN0b3J5LnVuZG9uZSA9IGNvcHlIaXN0b3J5QXJyYXkodGhpcy5oaXN0b3J5LnVuZG9uZSwgc3BsaXRJZHMpO1xuICAgICAgfVxuICAgIH0sXG4gICAgaXRlckxpbmtlZERvY3M6IGZ1bmN0aW9uKGYpIHtsaW5rZWREb2NzKHRoaXMsIGYpO30sXG5cbiAgICBnZXRNb2RlOiBmdW5jdGlvbigpIHtyZXR1cm4gdGhpcy5tb2RlO30sXG4gICAgZ2V0RWRpdG9yOiBmdW5jdGlvbigpIHtyZXR1cm4gdGhpcy5jbTt9LFxuXG4gICAgc3BsaXRMaW5lczogZnVuY3Rpb24oc3RyKSB7XG4gICAgICBpZiAodGhpcy5saW5lU2VwKSByZXR1cm4gc3RyLnNwbGl0KHRoaXMubGluZVNlcCk7XG4gICAgICByZXR1cm4gc3BsaXRMaW5lc0F1dG8oc3RyKTtcbiAgICB9LFxuICAgIGxpbmVTZXBhcmF0b3I6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5saW5lU2VwIHx8IFwiXFxuXCI7IH1cbiAgfSk7XG5cbiAgLy8gUHVibGljIGFsaWFzLlxuICBEb2MucHJvdG90eXBlLmVhY2hMaW5lID0gRG9jLnByb3RvdHlwZS5pdGVyO1xuXG4gIC8vIFNldCB1cCBtZXRob2RzIG9uIENvZGVNaXJyb3IncyBwcm90b3R5cGUgdG8gcmVkaXJlY3QgdG8gdGhlIGVkaXRvcidzIGRvY3VtZW50LlxuICB2YXIgZG9udERlbGVnYXRlID0gXCJpdGVyIGluc2VydCByZW1vdmUgY29weSBnZXRFZGl0b3IgY29uc3RydWN0b3JcIi5zcGxpdChcIiBcIik7XG4gIGZvciAodmFyIHByb3AgaW4gRG9jLnByb3RvdHlwZSkgaWYgKERvYy5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkocHJvcCkgJiYgaW5kZXhPZihkb250RGVsZWdhdGUsIHByb3ApIDwgMClcbiAgICBDb2RlTWlycm9yLnByb3RvdHlwZVtwcm9wXSA9IChmdW5jdGlvbihtZXRob2QpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtyZXR1cm4gbWV0aG9kLmFwcGx5KHRoaXMuZG9jLCBhcmd1bWVudHMpO307XG4gICAgfSkoRG9jLnByb3RvdHlwZVtwcm9wXSk7XG5cbiAgZXZlbnRNaXhpbihEb2MpO1xuXG4gIC8vIENhbGwgZiBmb3IgYWxsIGxpbmtlZCBkb2N1bWVudHMuXG4gIGZ1bmN0aW9uIGxpbmtlZERvY3MoZG9jLCBmLCBzaGFyZWRIaXN0T25seSkge1xuICAgIGZ1bmN0aW9uIHByb3BhZ2F0ZShkb2MsIHNraXAsIHNoYXJlZEhpc3QpIHtcbiAgICAgIGlmIChkb2MubGlua2VkKSBmb3IgKHZhciBpID0gMDsgaSA8IGRvYy5saW5rZWQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHJlbCA9IGRvYy5saW5rZWRbaV07XG4gICAgICAgIGlmIChyZWwuZG9jID09IHNraXApIGNvbnRpbnVlO1xuICAgICAgICB2YXIgc2hhcmVkID0gc2hhcmVkSGlzdCAmJiByZWwuc2hhcmVkSGlzdDtcbiAgICAgICAgaWYgKHNoYXJlZEhpc3RPbmx5ICYmICFzaGFyZWQpIGNvbnRpbnVlO1xuICAgICAgICBmKHJlbC5kb2MsIHNoYXJlZCk7XG4gICAgICAgIHByb3BhZ2F0ZShyZWwuZG9jLCBkb2MsIHNoYXJlZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHByb3BhZ2F0ZShkb2MsIG51bGwsIHRydWUpO1xuICB9XG5cbiAgLy8gQXR0YWNoIGEgZG9jdW1lbnQgdG8gYW4gZWRpdG9yLlxuICBmdW5jdGlvbiBhdHRhY2hEb2MoY20sIGRvYykge1xuICAgIGlmIChkb2MuY20pIHRocm93IG5ldyBFcnJvcihcIlRoaXMgZG9jdW1lbnQgaXMgYWxyZWFkeSBpbiB1c2UuXCIpO1xuICAgIGNtLmRvYyA9IGRvYztcbiAgICBkb2MuY20gPSBjbTtcbiAgICBlc3RpbWF0ZUxpbmVIZWlnaHRzKGNtKTtcbiAgICBsb2FkTW9kZShjbSk7XG4gICAgaWYgKCFjbS5vcHRpb25zLmxpbmVXcmFwcGluZykgZmluZE1heExpbmUoY20pO1xuICAgIGNtLm9wdGlvbnMubW9kZSA9IGRvYy5tb2RlT3B0aW9uO1xuICAgIHJlZ0NoYW5nZShjbSk7XG4gIH1cblxuICAvLyBMSU5FIFVUSUxJVElFU1xuXG4gIC8vIEZpbmQgdGhlIGxpbmUgb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGxpbmUgbnVtYmVyLlxuICBmdW5jdGlvbiBnZXRMaW5lKGRvYywgbikge1xuICAgIG4gLT0gZG9jLmZpcnN0O1xuICAgIGlmIChuIDwgMCB8fCBuID49IGRvYy5zaXplKSB0aHJvdyBuZXcgRXJyb3IoXCJUaGVyZSBpcyBubyBsaW5lIFwiICsgKG4gKyBkb2MuZmlyc3QpICsgXCIgaW4gdGhlIGRvY3VtZW50LlwiKTtcbiAgICBmb3IgKHZhciBjaHVuayA9IGRvYzsgIWNodW5rLmxpbmVzOykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7OyArK2kpIHtcbiAgICAgICAgdmFyIGNoaWxkID0gY2h1bmsuY2hpbGRyZW5baV0sIHN6ID0gY2hpbGQuY2h1bmtTaXplKCk7XG4gICAgICAgIGlmIChuIDwgc3opIHsgY2h1bmsgPSBjaGlsZDsgYnJlYWs7IH1cbiAgICAgICAgbiAtPSBzejtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNodW5rLmxpbmVzW25dO1xuICB9XG5cbiAgLy8gR2V0IHRoZSBwYXJ0IG9mIGEgZG9jdW1lbnQgYmV0d2VlbiB0d28gcG9zaXRpb25zLCBhcyBhbiBhcnJheSBvZlxuICAvLyBzdHJpbmdzLlxuICBmdW5jdGlvbiBnZXRCZXR3ZWVuKGRvYywgc3RhcnQsIGVuZCkge1xuICAgIHZhciBvdXQgPSBbXSwgbiA9IHN0YXJ0LmxpbmU7XG4gICAgZG9jLml0ZXIoc3RhcnQubGluZSwgZW5kLmxpbmUgKyAxLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICB2YXIgdGV4dCA9IGxpbmUudGV4dDtcbiAgICAgIGlmIChuID09IGVuZC5saW5lKSB0ZXh0ID0gdGV4dC5zbGljZSgwLCBlbmQuY2gpO1xuICAgICAgaWYgKG4gPT0gc3RhcnQubGluZSkgdGV4dCA9IHRleHQuc2xpY2Uoc3RhcnQuY2gpO1xuICAgICAgb3V0LnB1c2godGV4dCk7XG4gICAgICArK247XG4gICAgfSk7XG4gICAgcmV0dXJuIG91dDtcbiAgfVxuICAvLyBHZXQgdGhlIGxpbmVzIGJldHdlZW4gZnJvbSBhbmQgdG8sIGFzIGFycmF5IG9mIHN0cmluZ3MuXG4gIGZ1bmN0aW9uIGdldExpbmVzKGRvYywgZnJvbSwgdG8pIHtcbiAgICB2YXIgb3V0ID0gW107XG4gICAgZG9jLml0ZXIoZnJvbSwgdG8sIGZ1bmN0aW9uKGxpbmUpIHsgb3V0LnB1c2gobGluZS50ZXh0KTsgfSk7XG4gICAgcmV0dXJuIG91dDtcbiAgfVxuXG4gIC8vIFVwZGF0ZSB0aGUgaGVpZ2h0IG9mIGEgbGluZSwgcHJvcGFnYXRpbmcgdGhlIGhlaWdodCBjaGFuZ2VcbiAgLy8gdXB3YXJkcyB0byBwYXJlbnQgbm9kZXMuXG4gIGZ1bmN0aW9uIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgaGVpZ2h0KSB7XG4gICAgdmFyIGRpZmYgPSBoZWlnaHQgLSBsaW5lLmhlaWdodDtcbiAgICBpZiAoZGlmZikgZm9yICh2YXIgbiA9IGxpbmU7IG47IG4gPSBuLnBhcmVudCkgbi5oZWlnaHQgKz0gZGlmZjtcbiAgfVxuXG4gIC8vIEdpdmVuIGEgbGluZSBvYmplY3QsIGZpbmQgaXRzIGxpbmUgbnVtYmVyIGJ5IHdhbGtpbmcgdXAgdGhyb3VnaFxuICAvLyBpdHMgcGFyZW50IGxpbmtzLlxuICBmdW5jdGlvbiBsaW5lTm8obGluZSkge1xuICAgIGlmIChsaW5lLnBhcmVudCA9PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgY3VyID0gbGluZS5wYXJlbnQsIG5vID0gaW5kZXhPZihjdXIubGluZXMsIGxpbmUpO1xuICAgIGZvciAodmFyIGNodW5rID0gY3VyLnBhcmVudDsgY2h1bms7IGN1ciA9IGNodW5rLCBjaHVuayA9IGNodW5rLnBhcmVudCkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7OyArK2kpIHtcbiAgICAgICAgaWYgKGNodW5rLmNoaWxkcmVuW2ldID09IGN1cikgYnJlYWs7XG4gICAgICAgIG5vICs9IGNodW5rLmNoaWxkcmVuW2ldLmNodW5rU2l6ZSgpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbm8gKyBjdXIuZmlyc3Q7XG4gIH1cblxuICAvLyBGaW5kIHRoZSBsaW5lIGF0IHRoZSBnaXZlbiB2ZXJ0aWNhbCBwb3NpdGlvbiwgdXNpbmcgdGhlIGhlaWdodFxuICAvLyBpbmZvcm1hdGlvbiBpbiB0aGUgZG9jdW1lbnQgdHJlZS5cbiAgZnVuY3Rpb24gbGluZUF0SGVpZ2h0KGNodW5rLCBoKSB7XG4gICAgdmFyIG4gPSBjaHVuay5maXJzdDtcbiAgICBvdXRlcjogZG8ge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaHVuay5jaGlsZHJlbi5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgY2hpbGQgPSBjaHVuay5jaGlsZHJlbltpXSwgY2ggPSBjaGlsZC5oZWlnaHQ7XG4gICAgICAgIGlmIChoIDwgY2gpIHsgY2h1bmsgPSBjaGlsZDsgY29udGludWUgb3V0ZXI7IH1cbiAgICAgICAgaCAtPSBjaDtcbiAgICAgICAgbiArPSBjaGlsZC5jaHVua1NpemUoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuO1xuICAgIH0gd2hpbGUgKCFjaHVuay5saW5lcyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaHVuay5saW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIGxpbmUgPSBjaHVuay5saW5lc1tpXSwgbGggPSBsaW5lLmhlaWdodDtcbiAgICAgIGlmIChoIDwgbGgpIGJyZWFrO1xuICAgICAgaCAtPSBsaDtcbiAgICB9XG4gICAgcmV0dXJuIG4gKyBpO1xuICB9XG5cblxuICAvLyBGaW5kIHRoZSBoZWlnaHQgYWJvdmUgdGhlIGdpdmVuIGxpbmUuXG4gIGZ1bmN0aW9uIGhlaWdodEF0TGluZShsaW5lT2JqKSB7XG4gICAgbGluZU9iaiA9IHZpc3VhbExpbmUobGluZU9iaik7XG5cbiAgICB2YXIgaCA9IDAsIGNodW5rID0gbGluZU9iai5wYXJlbnQ7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaHVuay5saW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIGxpbmUgPSBjaHVuay5saW5lc1tpXTtcbiAgICAgIGlmIChsaW5lID09IGxpbmVPYmopIGJyZWFrO1xuICAgICAgZWxzZSBoICs9IGxpbmUuaGVpZ2h0O1xuICAgIH1cbiAgICBmb3IgKHZhciBwID0gY2h1bmsucGFyZW50OyBwOyBjaHVuayA9IHAsIHAgPSBjaHVuay5wYXJlbnQpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5jaGlsZHJlbi5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgY3VyID0gcC5jaGlsZHJlbltpXTtcbiAgICAgICAgaWYgKGN1ciA9PSBjaHVuaykgYnJlYWs7XG4gICAgICAgIGVsc2UgaCArPSBjdXIuaGVpZ2h0O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaDtcbiAgfVxuXG4gIC8vIEdldCB0aGUgYmlkaSBvcmRlcmluZyBmb3IgdGhlIGdpdmVuIGxpbmUgKGFuZCBjYWNoZSBpdCkuIFJldHVybnNcbiAgLy8gZmFsc2UgZm9yIGxpbmVzIHRoYXQgYXJlIGZ1bGx5IGxlZnQtdG8tcmlnaHQsIGFuZCBhbiBhcnJheSBvZlxuICAvLyBCaWRpU3BhbiBvYmplY3RzIG90aGVyd2lzZS5cbiAgZnVuY3Rpb24gZ2V0T3JkZXIobGluZSkge1xuICAgIHZhciBvcmRlciA9IGxpbmUub3JkZXI7XG4gICAgaWYgKG9yZGVyID09IG51bGwpIG9yZGVyID0gbGluZS5vcmRlciA9IGJpZGlPcmRlcmluZyhsaW5lLnRleHQpO1xuICAgIHJldHVybiBvcmRlcjtcbiAgfVxuXG4gIC8vIEhJU1RPUllcblxuICBmdW5jdGlvbiBIaXN0b3J5KHN0YXJ0R2VuKSB7XG4gICAgLy8gQXJyYXlzIG9mIGNoYW5nZSBldmVudHMgYW5kIHNlbGVjdGlvbnMuIERvaW5nIHNvbWV0aGluZyBhZGRzIGFuXG4gICAgLy8gZXZlbnQgdG8gZG9uZSBhbmQgY2xlYXJzIHVuZG8uIFVuZG9pbmcgbW92ZXMgZXZlbnRzIGZyb20gZG9uZVxuICAgIC8vIHRvIHVuZG9uZSwgcmVkb2luZyBtb3ZlcyB0aGVtIGluIHRoZSBvdGhlciBkaXJlY3Rpb24uXG4gICAgdGhpcy5kb25lID0gW107IHRoaXMudW5kb25lID0gW107XG4gICAgdGhpcy51bmRvRGVwdGggPSBJbmZpbml0eTtcbiAgICAvLyBVc2VkIHRvIHRyYWNrIHdoZW4gY2hhbmdlcyBjYW4gYmUgbWVyZ2VkIGludG8gYSBzaW5nbGUgdW5kb1xuICAgIC8vIGV2ZW50XG4gICAgdGhpcy5sYXN0TW9kVGltZSA9IHRoaXMubGFzdFNlbFRpbWUgPSAwO1xuICAgIHRoaXMubGFzdE9wID0gdGhpcy5sYXN0U2VsT3AgPSBudWxsO1xuICAgIHRoaXMubGFzdE9yaWdpbiA9IHRoaXMubGFzdFNlbE9yaWdpbiA9IG51bGw7XG4gICAgLy8gVXNlZCBieSB0aGUgaXNDbGVhbigpIG1ldGhvZFxuICAgIHRoaXMuZ2VuZXJhdGlvbiA9IHRoaXMubWF4R2VuZXJhdGlvbiA9IHN0YXJ0R2VuIHx8IDE7XG4gIH1cblxuICAvLyBDcmVhdGUgYSBoaXN0b3J5IGNoYW5nZSBldmVudCBmcm9tIGFuIHVwZGF0ZURvYy1zdHlsZSBjaGFuZ2VcbiAgLy8gb2JqZWN0LlxuICBmdW5jdGlvbiBoaXN0b3J5Q2hhbmdlRnJvbUNoYW5nZShkb2MsIGNoYW5nZSkge1xuICAgIHZhciBoaXN0Q2hhbmdlID0ge2Zyb206IGNvcHlQb3MoY2hhbmdlLmZyb20pLCB0bzogY2hhbmdlRW5kKGNoYW5nZSksIHRleHQ6IGdldEJldHdlZW4oZG9jLCBjaGFuZ2UuZnJvbSwgY2hhbmdlLnRvKX07XG4gICAgYXR0YWNoTG9jYWxTcGFucyhkb2MsIGhpc3RDaGFuZ2UsIGNoYW5nZS5mcm9tLmxpbmUsIGNoYW5nZS50by5saW5lICsgMSk7XG4gICAgbGlua2VkRG9jcyhkb2MsIGZ1bmN0aW9uKGRvYykge2F0dGFjaExvY2FsU3BhbnMoZG9jLCBoaXN0Q2hhbmdlLCBjaGFuZ2UuZnJvbS5saW5lLCBjaGFuZ2UudG8ubGluZSArIDEpO30sIHRydWUpO1xuICAgIHJldHVybiBoaXN0Q2hhbmdlO1xuICB9XG5cbiAgLy8gUG9wIGFsbCBzZWxlY3Rpb24gZXZlbnRzIG9mZiB0aGUgZW5kIG9mIGEgaGlzdG9yeSBhcnJheS4gU3RvcCBhdFxuICAvLyBhIGNoYW5nZSBldmVudC5cbiAgZnVuY3Rpb24gY2xlYXJTZWxlY3Rpb25FdmVudHMoYXJyYXkpIHtcbiAgICB3aGlsZSAoYXJyYXkubGVuZ3RoKSB7XG4gICAgICB2YXIgbGFzdCA9IGxzdChhcnJheSk7XG4gICAgICBpZiAobGFzdC5yYW5nZXMpIGFycmF5LnBvcCgpO1xuICAgICAgZWxzZSBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyBGaW5kIHRoZSB0b3AgY2hhbmdlIGV2ZW50IGluIHRoZSBoaXN0b3J5LiBQb3Agb2ZmIHNlbGVjdGlvblxuICAvLyBldmVudHMgdGhhdCBhcmUgaW4gdGhlIHdheS5cbiAgZnVuY3Rpb24gbGFzdENoYW5nZUV2ZW50KGhpc3QsIGZvcmNlKSB7XG4gICAgaWYgKGZvcmNlKSB7XG4gICAgICBjbGVhclNlbGVjdGlvbkV2ZW50cyhoaXN0LmRvbmUpO1xuICAgICAgcmV0dXJuIGxzdChoaXN0LmRvbmUpO1xuICAgIH0gZWxzZSBpZiAoaGlzdC5kb25lLmxlbmd0aCAmJiAhbHN0KGhpc3QuZG9uZSkucmFuZ2VzKSB7XG4gICAgICByZXR1cm4gbHN0KGhpc3QuZG9uZSk7XG4gICAgfSBlbHNlIGlmIChoaXN0LmRvbmUubGVuZ3RoID4gMSAmJiAhaGlzdC5kb25lW2hpc3QuZG9uZS5sZW5ndGggLSAyXS5yYW5nZXMpIHtcbiAgICAgIGhpc3QuZG9uZS5wb3AoKTtcbiAgICAgIHJldHVybiBsc3QoaGlzdC5kb25lKTtcbiAgICB9XG4gIH1cblxuICAvLyBSZWdpc3RlciBhIGNoYW5nZSBpbiB0aGUgaGlzdG9yeS4gTWVyZ2VzIGNoYW5nZXMgdGhhdCBhcmUgd2l0aGluXG4gIC8vIGEgc2luZ2xlIG9wZXJhdGlvbiwgb3JlIGFyZSBjbG9zZSB0b2dldGhlciB3aXRoIGFuIG9yaWdpbiB0aGF0XG4gIC8vIGFsbG93cyBtZXJnaW5nIChzdGFydGluZyB3aXRoIFwiK1wiKSBpbnRvIGEgc2luZ2xlIGV2ZW50LlxuICBmdW5jdGlvbiBhZGRDaGFuZ2VUb0hpc3RvcnkoZG9jLCBjaGFuZ2UsIHNlbEFmdGVyLCBvcElkKSB7XG4gICAgdmFyIGhpc3QgPSBkb2MuaGlzdG9yeTtcbiAgICBoaXN0LnVuZG9uZS5sZW5ndGggPSAwO1xuICAgIHZhciB0aW1lID0gK25ldyBEYXRlLCBjdXI7XG5cbiAgICBpZiAoKGhpc3QubGFzdE9wID09IG9wSWQgfHxcbiAgICAgICAgIGhpc3QubGFzdE9yaWdpbiA9PSBjaGFuZ2Uub3JpZ2luICYmIGNoYW5nZS5vcmlnaW4gJiZcbiAgICAgICAgICgoY2hhbmdlLm9yaWdpbi5jaGFyQXQoMCkgPT0gXCIrXCIgJiYgZG9jLmNtICYmIGhpc3QubGFzdE1vZFRpbWUgPiB0aW1lIC0gZG9jLmNtLm9wdGlvbnMuaGlzdG9yeUV2ZW50RGVsYXkpIHx8XG4gICAgICAgICAgY2hhbmdlLm9yaWdpbi5jaGFyQXQoMCkgPT0gXCIqXCIpKSAmJlxuICAgICAgICAoY3VyID0gbGFzdENoYW5nZUV2ZW50KGhpc3QsIGhpc3QubGFzdE9wID09IG9wSWQpKSkge1xuICAgICAgLy8gTWVyZ2UgdGhpcyBjaGFuZ2UgaW50byB0aGUgbGFzdCBldmVudFxuICAgICAgdmFyIGxhc3QgPSBsc3QoY3VyLmNoYW5nZXMpO1xuICAgICAgaWYgKGNtcChjaGFuZ2UuZnJvbSwgY2hhbmdlLnRvKSA9PSAwICYmIGNtcChjaGFuZ2UuZnJvbSwgbGFzdC50bykgPT0gMCkge1xuICAgICAgICAvLyBPcHRpbWl6ZWQgY2FzZSBmb3Igc2ltcGxlIGluc2VydGlvbiAtLSBkb24ndCB3YW50IHRvIGFkZFxuICAgICAgICAvLyBuZXcgY2hhbmdlc2V0cyBmb3IgZXZlcnkgY2hhcmFjdGVyIHR5cGVkXG4gICAgICAgIGxhc3QudG8gPSBjaGFuZ2VFbmQoY2hhbmdlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEFkZCBuZXcgc3ViLWV2ZW50XG4gICAgICAgIGN1ci5jaGFuZ2VzLnB1c2goaGlzdG9yeUNoYW5nZUZyb21DaGFuZ2UoZG9jLCBjaGFuZ2UpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQ2FuIG5vdCBiZSBtZXJnZWQsIHN0YXJ0IGEgbmV3IGV2ZW50LlxuICAgICAgdmFyIGJlZm9yZSA9IGxzdChoaXN0LmRvbmUpO1xuICAgICAgaWYgKCFiZWZvcmUgfHwgIWJlZm9yZS5yYW5nZXMpXG4gICAgICAgIHB1c2hTZWxlY3Rpb25Ub0hpc3RvcnkoZG9jLnNlbCwgaGlzdC5kb25lKTtcbiAgICAgIGN1ciA9IHtjaGFuZ2VzOiBbaGlzdG9yeUNoYW5nZUZyb21DaGFuZ2UoZG9jLCBjaGFuZ2UpXSxcbiAgICAgICAgICAgICBnZW5lcmF0aW9uOiBoaXN0LmdlbmVyYXRpb259O1xuICAgICAgaGlzdC5kb25lLnB1c2goY3VyKTtcbiAgICAgIHdoaWxlIChoaXN0LmRvbmUubGVuZ3RoID4gaGlzdC51bmRvRGVwdGgpIHtcbiAgICAgICAgaGlzdC5kb25lLnNoaWZ0KCk7XG4gICAgICAgIGlmICghaGlzdC5kb25lWzBdLnJhbmdlcykgaGlzdC5kb25lLnNoaWZ0KCk7XG4gICAgICB9XG4gICAgfVxuICAgIGhpc3QuZG9uZS5wdXNoKHNlbEFmdGVyKTtcbiAgICBoaXN0LmdlbmVyYXRpb24gPSArK2hpc3QubWF4R2VuZXJhdGlvbjtcbiAgICBoaXN0Lmxhc3RNb2RUaW1lID0gaGlzdC5sYXN0U2VsVGltZSA9IHRpbWU7XG4gICAgaGlzdC5sYXN0T3AgPSBoaXN0Lmxhc3RTZWxPcCA9IG9wSWQ7XG4gICAgaGlzdC5sYXN0T3JpZ2luID0gaGlzdC5sYXN0U2VsT3JpZ2luID0gY2hhbmdlLm9yaWdpbjtcblxuICAgIGlmICghbGFzdCkgc2lnbmFsKGRvYywgXCJoaXN0b3J5QWRkZWRcIik7XG4gIH1cblxuICBmdW5jdGlvbiBzZWxlY3Rpb25FdmVudENhbkJlTWVyZ2VkKGRvYywgb3JpZ2luLCBwcmV2LCBzZWwpIHtcbiAgICB2YXIgY2ggPSBvcmlnaW4uY2hhckF0KDApO1xuICAgIHJldHVybiBjaCA9PSBcIipcIiB8fFxuICAgICAgY2ggPT0gXCIrXCIgJiZcbiAgICAgIHByZXYucmFuZ2VzLmxlbmd0aCA9PSBzZWwucmFuZ2VzLmxlbmd0aCAmJlxuICAgICAgcHJldi5zb21ldGhpbmdTZWxlY3RlZCgpID09IHNlbC5zb21ldGhpbmdTZWxlY3RlZCgpICYmXG4gICAgICBuZXcgRGF0ZSAtIGRvYy5oaXN0b3J5Lmxhc3RTZWxUaW1lIDw9IChkb2MuY20gPyBkb2MuY20ub3B0aW9ucy5oaXN0b3J5RXZlbnREZWxheSA6IDUwMCk7XG4gIH1cblxuICAvLyBDYWxsZWQgd2hlbmV2ZXIgdGhlIHNlbGVjdGlvbiBjaGFuZ2VzLCBzZXRzIHRoZSBuZXcgc2VsZWN0aW9uIGFzXG4gIC8vIHRoZSBwZW5kaW5nIHNlbGVjdGlvbiBpbiB0aGUgaGlzdG9yeSwgYW5kIHB1c2hlcyB0aGUgb2xkIHBlbmRpbmdcbiAgLy8gc2VsZWN0aW9uIGludG8gdGhlICdkb25lJyBhcnJheSB3aGVuIGl0IHdhcyBzaWduaWZpY2FudGx5XG4gIC8vIGRpZmZlcmVudCAoaW4gbnVtYmVyIG9mIHNlbGVjdGVkIHJhbmdlcywgZW1wdGluZXNzLCBvciB0aW1lKS5cbiAgZnVuY3Rpb24gYWRkU2VsZWN0aW9uVG9IaXN0b3J5KGRvYywgc2VsLCBvcElkLCBvcHRpb25zKSB7XG4gICAgdmFyIGhpc3QgPSBkb2MuaGlzdG9yeSwgb3JpZ2luID0gb3B0aW9ucyAmJiBvcHRpb25zLm9yaWdpbjtcblxuICAgIC8vIEEgbmV3IGV2ZW50IGlzIHN0YXJ0ZWQgd2hlbiB0aGUgcHJldmlvdXMgb3JpZ2luIGRvZXMgbm90IG1hdGNoXG4gICAgLy8gdGhlIGN1cnJlbnQsIG9yIHRoZSBvcmlnaW5zIGRvbid0IGFsbG93IG1hdGNoaW5nLiBPcmlnaW5zXG4gICAgLy8gc3RhcnRpbmcgd2l0aCAqIGFyZSBhbHdheXMgbWVyZ2VkLCB0aG9zZSBzdGFydGluZyB3aXRoICsgYXJlXG4gICAgLy8gbWVyZ2VkIHdoZW4gc2ltaWxhciBhbmQgY2xvc2UgdG9nZXRoZXIgaW4gdGltZS5cbiAgICBpZiAob3BJZCA9PSBoaXN0Lmxhc3RTZWxPcCB8fFxuICAgICAgICAob3JpZ2luICYmIGhpc3QubGFzdFNlbE9yaWdpbiA9PSBvcmlnaW4gJiZcbiAgICAgICAgIChoaXN0Lmxhc3RNb2RUaW1lID09IGhpc3QubGFzdFNlbFRpbWUgJiYgaGlzdC5sYXN0T3JpZ2luID09IG9yaWdpbiB8fFxuICAgICAgICAgIHNlbGVjdGlvbkV2ZW50Q2FuQmVNZXJnZWQoZG9jLCBvcmlnaW4sIGxzdChoaXN0LmRvbmUpLCBzZWwpKSkpXG4gICAgICBoaXN0LmRvbmVbaGlzdC5kb25lLmxlbmd0aCAtIDFdID0gc2VsO1xuICAgIGVsc2VcbiAgICAgIHB1c2hTZWxlY3Rpb25Ub0hpc3Rvcnkoc2VsLCBoaXN0LmRvbmUpO1xuXG4gICAgaGlzdC5sYXN0U2VsVGltZSA9ICtuZXcgRGF0ZTtcbiAgICBoaXN0Lmxhc3RTZWxPcmlnaW4gPSBvcmlnaW47XG4gICAgaGlzdC5sYXN0U2VsT3AgPSBvcElkO1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuY2xlYXJSZWRvICE9PSBmYWxzZSlcbiAgICAgIGNsZWFyU2VsZWN0aW9uRXZlbnRzKGhpc3QudW5kb25lKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHB1c2hTZWxlY3Rpb25Ub0hpc3Rvcnkoc2VsLCBkZXN0KSB7XG4gICAgdmFyIHRvcCA9IGxzdChkZXN0KTtcbiAgICBpZiAoISh0b3AgJiYgdG9wLnJhbmdlcyAmJiB0b3AuZXF1YWxzKHNlbCkpKVxuICAgICAgZGVzdC5wdXNoKHNlbCk7XG4gIH1cblxuICAvLyBVc2VkIHRvIHN0b3JlIG1hcmtlZCBzcGFuIGluZm9ybWF0aW9uIGluIHRoZSBoaXN0b3J5LlxuICBmdW5jdGlvbiBhdHRhY2hMb2NhbFNwYW5zKGRvYywgY2hhbmdlLCBmcm9tLCB0bykge1xuICAgIHZhciBleGlzdGluZyA9IGNoYW5nZVtcInNwYW5zX1wiICsgZG9jLmlkXSwgbiA9IDA7XG4gICAgZG9jLml0ZXIoTWF0aC5tYXgoZG9jLmZpcnN0LCBmcm9tKSwgTWF0aC5taW4oZG9jLmZpcnN0ICsgZG9jLnNpemUsIHRvKSwgZnVuY3Rpb24obGluZSkge1xuICAgICAgaWYgKGxpbmUubWFya2VkU3BhbnMpXG4gICAgICAgIChleGlzdGluZyB8fCAoZXhpc3RpbmcgPSBjaGFuZ2VbXCJzcGFuc19cIiArIGRvYy5pZF0gPSB7fSkpW25dID0gbGluZS5tYXJrZWRTcGFucztcbiAgICAgICsrbjtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFdoZW4gdW4vcmUtZG9pbmcgcmVzdG9yZXMgdGV4dCBjb250YWluaW5nIG1hcmtlZCBzcGFucywgdGhvc2VcbiAgLy8gdGhhdCBoYXZlIGJlZW4gZXhwbGljaXRseSBjbGVhcmVkIHNob3VsZCBub3QgYmUgcmVzdG9yZWQuXG4gIGZ1bmN0aW9uIHJlbW92ZUNsZWFyZWRTcGFucyhzcGFucykge1xuICAgIGlmICghc3BhbnMpIHJldHVybiBudWxsO1xuICAgIGZvciAodmFyIGkgPSAwLCBvdXQ7IGkgPCBzcGFucy5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKHNwYW5zW2ldLm1hcmtlci5leHBsaWNpdGx5Q2xlYXJlZCkgeyBpZiAoIW91dCkgb3V0ID0gc3BhbnMuc2xpY2UoMCwgaSk7IH1cbiAgICAgIGVsc2UgaWYgKG91dCkgb3V0LnB1c2goc3BhbnNbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gIW91dCA/IHNwYW5zIDogb3V0Lmxlbmd0aCA/IG91dCA6IG51bGw7XG4gIH1cblxuICAvLyBSZXRyaWV2ZSBhbmQgZmlsdGVyIHRoZSBvbGQgbWFya2VkIHNwYW5zIHN0b3JlZCBpbiBhIGNoYW5nZSBldmVudC5cbiAgZnVuY3Rpb24gZ2V0T2xkU3BhbnMoZG9jLCBjaGFuZ2UpIHtcbiAgICB2YXIgZm91bmQgPSBjaGFuZ2VbXCJzcGFuc19cIiArIGRvYy5pZF07XG4gICAgaWYgKCFmb3VuZCkgcmV0dXJuIG51bGw7XG4gICAgZm9yICh2YXIgaSA9IDAsIG53ID0gW107IGkgPCBjaGFuZ2UudGV4dC5sZW5ndGg7ICsraSlcbiAgICAgIG53LnB1c2gocmVtb3ZlQ2xlYXJlZFNwYW5zKGZvdW5kW2ldKSk7XG4gICAgcmV0dXJuIG53O1xuICB9XG5cbiAgLy8gVXNlZCBib3RoIHRvIHByb3ZpZGUgYSBKU09OLXNhZmUgb2JqZWN0IGluIC5nZXRIaXN0b3J5LCBhbmQsIHdoZW5cbiAgLy8gZGV0YWNoaW5nIGEgZG9jdW1lbnQsIHRvIHNwbGl0IHRoZSBoaXN0b3J5IGluIHR3b1xuICBmdW5jdGlvbiBjb3B5SGlzdG9yeUFycmF5KGV2ZW50cywgbmV3R3JvdXAsIGluc3RhbnRpYXRlU2VsKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGNvcHkgPSBbXTsgaSA8IGV2ZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIGV2ZW50ID0gZXZlbnRzW2ldO1xuICAgICAgaWYgKGV2ZW50LnJhbmdlcykge1xuICAgICAgICBjb3B5LnB1c2goaW5zdGFudGlhdGVTZWwgPyBTZWxlY3Rpb24ucHJvdG90eXBlLmRlZXBDb3B5LmNhbGwoZXZlbnQpIDogZXZlbnQpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHZhciBjaGFuZ2VzID0gZXZlbnQuY2hhbmdlcywgbmV3Q2hhbmdlcyA9IFtdO1xuICAgICAgY29weS5wdXNoKHtjaGFuZ2VzOiBuZXdDaGFuZ2VzfSk7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGNoYW5nZXMubGVuZ3RoOyArK2opIHtcbiAgICAgICAgdmFyIGNoYW5nZSA9IGNoYW5nZXNbal0sIG07XG4gICAgICAgIG5ld0NoYW5nZXMucHVzaCh7ZnJvbTogY2hhbmdlLmZyb20sIHRvOiBjaGFuZ2UudG8sIHRleHQ6IGNoYW5nZS50ZXh0fSk7XG4gICAgICAgIGlmIChuZXdHcm91cCkgZm9yICh2YXIgcHJvcCBpbiBjaGFuZ2UpIGlmIChtID0gcHJvcC5tYXRjaCgvXnNwYW5zXyhcXGQrKSQvKSkge1xuICAgICAgICAgIGlmIChpbmRleE9mKG5ld0dyb3VwLCBOdW1iZXIobVsxXSkpID4gLTEpIHtcbiAgICAgICAgICAgIGxzdChuZXdDaGFuZ2VzKVtwcm9wXSA9IGNoYW5nZVtwcm9wXTtcbiAgICAgICAgICAgIGRlbGV0ZSBjaGFuZ2VbcHJvcF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb3B5O1xuICB9XG5cbiAgLy8gUmViYXNpbmcvcmVzZXR0aW5nIGhpc3RvcnkgdG8gZGVhbCB3aXRoIGV4dGVybmFsbHktc291cmNlZCBjaGFuZ2VzXG5cbiAgZnVuY3Rpb24gcmViYXNlSGlzdFNlbFNpbmdsZShwb3MsIGZyb20sIHRvLCBkaWZmKSB7XG4gICAgaWYgKHRvIDwgcG9zLmxpbmUpIHtcbiAgICAgIHBvcy5saW5lICs9IGRpZmY7XG4gICAgfSBlbHNlIGlmIChmcm9tIDwgcG9zLmxpbmUpIHtcbiAgICAgIHBvcy5saW5lID0gZnJvbTtcbiAgICAgIHBvcy5jaCA9IDA7XG4gICAgfVxuICB9XG5cbiAgLy8gVHJpZXMgdG8gcmViYXNlIGFuIGFycmF5IG9mIGhpc3RvcnkgZXZlbnRzIGdpdmVuIGEgY2hhbmdlIGluIHRoZVxuICAvLyBkb2N1bWVudC4gSWYgdGhlIGNoYW5nZSB0b3VjaGVzIHRoZSBzYW1lIGxpbmVzIGFzIHRoZSBldmVudCwgdGhlXG4gIC8vIGV2ZW50LCBhbmQgZXZlcnl0aGluZyAnYmVoaW5kJyBpdCwgaXMgZGlzY2FyZGVkLiBJZiB0aGUgY2hhbmdlIGlzXG4gIC8vIGJlZm9yZSB0aGUgZXZlbnQsIHRoZSBldmVudCdzIHBvc2l0aW9ucyBhcmUgdXBkYXRlZC4gVXNlcyBhXG4gIC8vIGNvcHktb24td3JpdGUgc2NoZW1lIGZvciB0aGUgcG9zaXRpb25zLCB0byBhdm9pZCBoYXZpbmcgdG9cbiAgLy8gcmVhbGxvY2F0ZSB0aGVtIGFsbCBvbiBldmVyeSByZWJhc2UsIGJ1dCBhbHNvIGF2b2lkIHByb2JsZW1zIHdpdGhcbiAgLy8gc2hhcmVkIHBvc2l0aW9uIG9iamVjdHMgYmVpbmcgdW5zYWZlbHkgdXBkYXRlZC5cbiAgZnVuY3Rpb24gcmViYXNlSGlzdEFycmF5KGFycmF5LCBmcm9tLCB0bywgZGlmZikge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBzdWIgPSBhcnJheVtpXSwgb2sgPSB0cnVlO1xuICAgICAgaWYgKHN1Yi5yYW5nZXMpIHtcbiAgICAgICAgaWYgKCFzdWIuY29waWVkKSB7IHN1YiA9IGFycmF5W2ldID0gc3ViLmRlZXBDb3B5KCk7IHN1Yi5jb3BpZWQgPSB0cnVlOyB9XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3ViLnJhbmdlcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgIHJlYmFzZUhpc3RTZWxTaW5nbGUoc3ViLnJhbmdlc1tqXS5hbmNob3IsIGZyb20sIHRvLCBkaWZmKTtcbiAgICAgICAgICByZWJhc2VIaXN0U2VsU2luZ2xlKHN1Yi5yYW5nZXNbal0uaGVhZCwgZnJvbSwgdG8sIGRpZmYpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBzdWIuY2hhbmdlcy5sZW5ndGg7ICsraikge1xuICAgICAgICB2YXIgY3VyID0gc3ViLmNoYW5nZXNbal07XG4gICAgICAgIGlmICh0byA8IGN1ci5mcm9tLmxpbmUpIHtcbiAgICAgICAgICBjdXIuZnJvbSA9IFBvcyhjdXIuZnJvbS5saW5lICsgZGlmZiwgY3VyLmZyb20uY2gpO1xuICAgICAgICAgIGN1ci50byA9IFBvcyhjdXIudG8ubGluZSArIGRpZmYsIGN1ci50by5jaCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZnJvbSA8PSBjdXIudG8ubGluZSkge1xuICAgICAgICAgIG9rID0gZmFsc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghb2spIHtcbiAgICAgICAgYXJyYXkuc3BsaWNlKDAsIGkgKyAxKTtcbiAgICAgICAgaSA9IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmViYXNlSGlzdChoaXN0LCBjaGFuZ2UpIHtcbiAgICB2YXIgZnJvbSA9IGNoYW5nZS5mcm9tLmxpbmUsIHRvID0gY2hhbmdlLnRvLmxpbmUsIGRpZmYgPSBjaGFuZ2UudGV4dC5sZW5ndGggLSAodG8gLSBmcm9tKSAtIDE7XG4gICAgcmViYXNlSGlzdEFycmF5KGhpc3QuZG9uZSwgZnJvbSwgdG8sIGRpZmYpO1xuICAgIHJlYmFzZUhpc3RBcnJheShoaXN0LnVuZG9uZSwgZnJvbSwgdG8sIGRpZmYpO1xuICB9XG5cbiAgLy8gRVZFTlQgVVRJTElUSUVTXG5cbiAgLy8gRHVlIHRvIHRoZSBmYWN0IHRoYXQgd2Ugc3RpbGwgc3VwcG9ydCBqdXJhc3NpYyBJRSB2ZXJzaW9ucywgc29tZVxuICAvLyBjb21wYXRpYmlsaXR5IHdyYXBwZXJzIGFyZSBuZWVkZWQuXG5cbiAgdmFyIGVfcHJldmVudERlZmF1bHQgPSBDb2RlTWlycm9yLmVfcHJldmVudERlZmF1bHQgPSBmdW5jdGlvbihlKSB7XG4gICAgaWYgKGUucHJldmVudERlZmF1bHQpIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlbHNlIGUucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgfTtcbiAgdmFyIGVfc3RvcFByb3BhZ2F0aW9uID0gQ29kZU1pcnJvci5lX3N0b3BQcm9wYWdhdGlvbiA9IGZ1bmN0aW9uKGUpIHtcbiAgICBpZiAoZS5zdG9wUHJvcGFnYXRpb24pIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgZWxzZSBlLmNhbmNlbEJ1YmJsZSA9IHRydWU7XG4gIH07XG4gIGZ1bmN0aW9uIGVfZGVmYXVsdFByZXZlbnRlZChlKSB7XG4gICAgcmV0dXJuIGUuZGVmYXVsdFByZXZlbnRlZCAhPSBudWxsID8gZS5kZWZhdWx0UHJldmVudGVkIDogZS5yZXR1cm5WYWx1ZSA9PSBmYWxzZTtcbiAgfVxuICB2YXIgZV9zdG9wID0gQ29kZU1pcnJvci5lX3N0b3AgPSBmdW5jdGlvbihlKSB7ZV9wcmV2ZW50RGVmYXVsdChlKTsgZV9zdG9wUHJvcGFnYXRpb24oZSk7fTtcblxuICBmdW5jdGlvbiBlX3RhcmdldChlKSB7cmV0dXJuIGUudGFyZ2V0IHx8IGUuc3JjRWxlbWVudDt9XG4gIGZ1bmN0aW9uIGVfYnV0dG9uKGUpIHtcbiAgICB2YXIgYiA9IGUud2hpY2g7XG4gICAgaWYgKGIgPT0gbnVsbCkge1xuICAgICAgaWYgKGUuYnV0dG9uICYgMSkgYiA9IDE7XG4gICAgICBlbHNlIGlmIChlLmJ1dHRvbiAmIDIpIGIgPSAzO1xuICAgICAgZWxzZSBpZiAoZS5idXR0b24gJiA0KSBiID0gMjtcbiAgICB9XG4gICAgaWYgKG1hYyAmJiBlLmN0cmxLZXkgJiYgYiA9PSAxKSBiID0gMztcbiAgICByZXR1cm4gYjtcbiAgfVxuXG4gIC8vIEVWRU5UIEhBTkRMSU5HXG5cbiAgLy8gTGlnaHR3ZWlnaHQgZXZlbnQgZnJhbWV3b3JrLiBvbi9vZmYgYWxzbyB3b3JrIG9uIERPTSBub2RlcyxcbiAgLy8gcmVnaXN0ZXJpbmcgbmF0aXZlIERPTSBoYW5kbGVycy5cblxuICB2YXIgb24gPSBDb2RlTWlycm9yLm9uID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSwgZikge1xuICAgIGlmIChlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIpXG4gICAgICBlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgZiwgZmFsc2UpO1xuICAgIGVsc2UgaWYgKGVtaXR0ZXIuYXR0YWNoRXZlbnQpXG4gICAgICBlbWl0dGVyLmF0dGFjaEV2ZW50KFwib25cIiArIHR5cGUsIGYpO1xuICAgIGVsc2Uge1xuICAgICAgdmFyIG1hcCA9IGVtaXR0ZXIuX2hhbmRsZXJzIHx8IChlbWl0dGVyLl9oYW5kbGVycyA9IHt9KTtcbiAgICAgIHZhciBhcnIgPSBtYXBbdHlwZV0gfHwgKG1hcFt0eXBlXSA9IFtdKTtcbiAgICAgIGFyci5wdXNoKGYpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgbm9IYW5kbGVycyA9IFtdXG4gIGZ1bmN0aW9uIGdldEhhbmRsZXJzKGVtaXR0ZXIsIHR5cGUsIGNvcHkpIHtcbiAgICB2YXIgYXJyID0gZW1pdHRlci5faGFuZGxlcnMgJiYgZW1pdHRlci5faGFuZGxlcnNbdHlwZV1cbiAgICBpZiAoY29weSkgcmV0dXJuIGFyciAmJiBhcnIubGVuZ3RoID4gMCA/IGFyci5zbGljZSgpIDogbm9IYW5kbGVyc1xuICAgIGVsc2UgcmV0dXJuIGFyciB8fCBub0hhbmRsZXJzXG4gIH1cblxuICB2YXIgb2ZmID0gQ29kZU1pcnJvci5vZmYgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlLCBmKSB7XG4gICAgaWYgKGVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcilcbiAgICAgIGVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBmLCBmYWxzZSk7XG4gICAgZWxzZSBpZiAoZW1pdHRlci5kZXRhY2hFdmVudClcbiAgICAgIGVtaXR0ZXIuZGV0YWNoRXZlbnQoXCJvblwiICsgdHlwZSwgZik7XG4gICAgZWxzZSB7XG4gICAgICB2YXIgaGFuZGxlcnMgPSBnZXRIYW5kbGVycyhlbWl0dGVyLCB0eXBlLCBmYWxzZSlcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGFuZGxlcnMubGVuZ3RoOyArK2kpXG4gICAgICAgIGlmIChoYW5kbGVyc1tpXSA9PSBmKSB7IGhhbmRsZXJzLnNwbGljZShpLCAxKTsgYnJlYWs7IH1cbiAgICB9XG4gIH07XG5cbiAgdmFyIHNpZ25hbCA9IENvZGVNaXJyb3Iuc2lnbmFsID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSAvKiwgdmFsdWVzLi4uKi8pIHtcbiAgICB2YXIgaGFuZGxlcnMgPSBnZXRIYW5kbGVycyhlbWl0dGVyLCB0eXBlLCB0cnVlKVxuICAgIGlmICghaGFuZGxlcnMubGVuZ3RoKSByZXR1cm47XG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGFuZGxlcnMubGVuZ3RoOyArK2kpIGhhbmRsZXJzW2ldLmFwcGx5KG51bGwsIGFyZ3MpO1xuICB9O1xuXG4gIHZhciBvcnBoYW5EZWxheWVkQ2FsbGJhY2tzID0gbnVsbDtcblxuICAvLyBPZnRlbiwgd2Ugd2FudCB0byBzaWduYWwgZXZlbnRzIGF0IGEgcG9pbnQgd2hlcmUgd2UgYXJlIGluIHRoZVxuICAvLyBtaWRkbGUgb2Ygc29tZSB3b3JrLCBidXQgZG9uJ3Qgd2FudCB0aGUgaGFuZGxlciB0byBzdGFydCBjYWxsaW5nXG4gIC8vIG90aGVyIG1ldGhvZHMgb24gdGhlIGVkaXRvciwgd2hpY2ggbWlnaHQgYmUgaW4gYW4gaW5jb25zaXN0ZW50XG4gIC8vIHN0YXRlIG9yIHNpbXBseSBub3QgZXhwZWN0IGFueSBvdGhlciBldmVudHMgdG8gaGFwcGVuLlxuICAvLyBzaWduYWxMYXRlciBsb29rcyB3aGV0aGVyIHRoZXJlIGFyZSBhbnkgaGFuZGxlcnMsIGFuZCBzY2hlZHVsZXNcbiAgLy8gdGhlbSB0byBiZSBleGVjdXRlZCB3aGVuIHRoZSBsYXN0IG9wZXJhdGlvbiBlbmRzLCBvciwgaWYgbm9cbiAgLy8gb3BlcmF0aW9uIGlzIGFjdGl2ZSwgd2hlbiBhIHRpbWVvdXQgZmlyZXMuXG4gIGZ1bmN0aW9uIHNpZ25hbExhdGVyKGVtaXR0ZXIsIHR5cGUgLyosIHZhbHVlcy4uLiovKSB7XG4gICAgdmFyIGFyciA9IGdldEhhbmRsZXJzKGVtaXR0ZXIsIHR5cGUsIGZhbHNlKVxuICAgIGlmICghYXJyLmxlbmd0aCkgcmV0dXJuO1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKSwgbGlzdDtcbiAgICBpZiAob3BlcmF0aW9uR3JvdXApIHtcbiAgICAgIGxpc3QgPSBvcGVyYXRpb25Hcm91cC5kZWxheWVkQ2FsbGJhY2tzO1xuICAgIH0gZWxzZSBpZiAob3JwaGFuRGVsYXllZENhbGxiYWNrcykge1xuICAgICAgbGlzdCA9IG9ycGhhbkRlbGF5ZWRDYWxsYmFja3M7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3QgPSBvcnBoYW5EZWxheWVkQ2FsbGJhY2tzID0gW107XG4gICAgICBzZXRUaW1lb3V0KGZpcmVPcnBoYW5EZWxheWVkLCAwKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYm5kKGYpIHtyZXR1cm4gZnVuY3Rpb24oKXtmLmFwcGx5KG51bGwsIGFyZ3MpO307fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7ICsraSlcbiAgICAgIGxpc3QucHVzaChibmQoYXJyW2ldKSk7XG4gIH1cblxuICBmdW5jdGlvbiBmaXJlT3JwaGFuRGVsYXllZCgpIHtcbiAgICB2YXIgZGVsYXllZCA9IG9ycGhhbkRlbGF5ZWRDYWxsYmFja3M7XG4gICAgb3JwaGFuRGVsYXllZENhbGxiYWNrcyA9IG51bGw7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkZWxheWVkLmxlbmd0aDsgKytpKSBkZWxheWVkW2ldKCk7XG4gIH1cblxuICAvLyBUaGUgRE9NIGV2ZW50cyB0aGF0IENvZGVNaXJyb3IgaGFuZGxlcyBjYW4gYmUgb3ZlcnJpZGRlbiBieVxuICAvLyByZWdpc3RlcmluZyBhIChub24tRE9NKSBoYW5kbGVyIG9uIHRoZSBlZGl0b3IgZm9yIHRoZSBldmVudCBuYW1lLFxuICAvLyBhbmQgcHJldmVudERlZmF1bHQtaW5nIHRoZSBldmVudCBpbiB0aGF0IGhhbmRsZXIuXG4gIGZ1bmN0aW9uIHNpZ25hbERPTUV2ZW50KGNtLCBlLCBvdmVycmlkZSkge1xuICAgIGlmICh0eXBlb2YgZSA9PSBcInN0cmluZ1wiKVxuICAgICAgZSA9IHt0eXBlOiBlLCBwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7IHRoaXMuZGVmYXVsdFByZXZlbnRlZCA9IHRydWU7IH19O1xuICAgIHNpZ25hbChjbSwgb3ZlcnJpZGUgfHwgZS50eXBlLCBjbSwgZSk7XG4gICAgcmV0dXJuIGVfZGVmYXVsdFByZXZlbnRlZChlKSB8fCBlLmNvZGVtaXJyb3JJZ25vcmU7XG4gIH1cblxuICBmdW5jdGlvbiBzaWduYWxDdXJzb3JBY3Rpdml0eShjbSkge1xuICAgIHZhciBhcnIgPSBjbS5faGFuZGxlcnMgJiYgY20uX2hhbmRsZXJzLmN1cnNvckFjdGl2aXR5O1xuICAgIGlmICghYXJyKSByZXR1cm47XG4gICAgdmFyIHNldCA9IGNtLmN1ck9wLmN1cnNvckFjdGl2aXR5SGFuZGxlcnMgfHwgKGNtLmN1ck9wLmN1cnNvckFjdGl2aXR5SGFuZGxlcnMgPSBbXSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIGlmIChpbmRleE9mKHNldCwgYXJyW2ldKSA9PSAtMSlcbiAgICAgIHNldC5wdXNoKGFycltpXSk7XG4gIH1cblxuICBmdW5jdGlvbiBoYXNIYW5kbGVyKGVtaXR0ZXIsIHR5cGUpIHtcbiAgICByZXR1cm4gZ2V0SGFuZGxlcnMoZW1pdHRlciwgdHlwZSkubGVuZ3RoID4gMFxuICB9XG5cbiAgLy8gQWRkIG9uIGFuZCBvZmYgbWV0aG9kcyB0byBhIGNvbnN0cnVjdG9yJ3MgcHJvdG90eXBlLCB0byBtYWtlXG4gIC8vIHJlZ2lzdGVyaW5nIGV2ZW50cyBvbiBzdWNoIG9iamVjdHMgbW9yZSBjb252ZW5pZW50LlxuICBmdW5jdGlvbiBldmVudE1peGluKGN0b3IpIHtcbiAgICBjdG9yLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uKHR5cGUsIGYpIHtvbih0aGlzLCB0eXBlLCBmKTt9O1xuICAgIGN0b3IucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uKHR5cGUsIGYpIHtvZmYodGhpcywgdHlwZSwgZik7fTtcbiAgfVxuXG4gIC8vIE1JU0MgVVRJTElUSUVTXG5cbiAgLy8gTnVtYmVyIG9mIHBpeGVscyBhZGRlZCB0byBzY3JvbGxlciBhbmQgc2l6ZXIgdG8gaGlkZSBzY3JvbGxiYXJcbiAgdmFyIHNjcm9sbGVyR2FwID0gMzA7XG5cbiAgLy8gUmV0dXJuZWQgb3IgdGhyb3duIGJ5IHZhcmlvdXMgcHJvdG9jb2xzIHRvIHNpZ25hbCAnSSdtIG5vdFxuICAvLyBoYW5kbGluZyB0aGlzJy5cbiAgdmFyIFBhc3MgPSBDb2RlTWlycm9yLlBhc3MgPSB7dG9TdHJpbmc6IGZ1bmN0aW9uKCl7cmV0dXJuIFwiQ29kZU1pcnJvci5QYXNzXCI7fX07XG5cbiAgLy8gUmV1c2VkIG9wdGlvbiBvYmplY3RzIGZvciBzZXRTZWxlY3Rpb24gJiBmcmllbmRzXG4gIHZhciBzZWxfZG9udFNjcm9sbCA9IHtzY3JvbGw6IGZhbHNlfSwgc2VsX21vdXNlID0ge29yaWdpbjogXCIqbW91c2VcIn0sIHNlbF9tb3ZlID0ge29yaWdpbjogXCIrbW92ZVwifTtcblxuICBmdW5jdGlvbiBEZWxheWVkKCkge3RoaXMuaWQgPSBudWxsO31cbiAgRGVsYXllZC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24obXMsIGYpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5pZCk7XG4gICAgdGhpcy5pZCA9IHNldFRpbWVvdXQoZiwgbXMpO1xuICB9O1xuXG4gIC8vIENvdW50cyB0aGUgY29sdW1uIG9mZnNldCBpbiBhIHN0cmluZywgdGFraW5nIHRhYnMgaW50byBhY2NvdW50LlxuICAvLyBVc2VkIG1vc3RseSB0byBmaW5kIGluZGVudGF0aW9uLlxuICB2YXIgY291bnRDb2x1bW4gPSBDb2RlTWlycm9yLmNvdW50Q29sdW1uID0gZnVuY3Rpb24oc3RyaW5nLCBlbmQsIHRhYlNpemUsIHN0YXJ0SW5kZXgsIHN0YXJ0VmFsdWUpIHtcbiAgICBpZiAoZW5kID09IG51bGwpIHtcbiAgICAgIGVuZCA9IHN0cmluZy5zZWFyY2goL1teXFxzXFx1MDBhMF0vKTtcbiAgICAgIGlmIChlbmQgPT0gLTEpIGVuZCA9IHN0cmluZy5sZW5ndGg7XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSBzdGFydEluZGV4IHx8IDAsIG4gPSBzdGFydFZhbHVlIHx8IDA7Oykge1xuICAgICAgdmFyIG5leHRUYWIgPSBzdHJpbmcuaW5kZXhPZihcIlxcdFwiLCBpKTtcbiAgICAgIGlmIChuZXh0VGFiIDwgMCB8fCBuZXh0VGFiID49IGVuZClcbiAgICAgICAgcmV0dXJuIG4gKyAoZW5kIC0gaSk7XG4gICAgICBuICs9IG5leHRUYWIgLSBpO1xuICAgICAgbiArPSB0YWJTaXplIC0gKG4gJSB0YWJTaXplKTtcbiAgICAgIGkgPSBuZXh0VGFiICsgMTtcbiAgICB9XG4gIH07XG5cbiAgLy8gVGhlIGludmVyc2Ugb2YgY291bnRDb2x1bW4gLS0gZmluZCB0aGUgb2Zmc2V0IHRoYXQgY29ycmVzcG9uZHMgdG9cbiAgLy8gYSBwYXJ0aWN1bGFyIGNvbHVtbi5cbiAgdmFyIGZpbmRDb2x1bW4gPSBDb2RlTWlycm9yLmZpbmRDb2x1bW4gPSBmdW5jdGlvbihzdHJpbmcsIGdvYWwsIHRhYlNpemUpIHtcbiAgICBmb3IgKHZhciBwb3MgPSAwLCBjb2wgPSAwOzspIHtcbiAgICAgIHZhciBuZXh0VGFiID0gc3RyaW5nLmluZGV4T2YoXCJcXHRcIiwgcG9zKTtcbiAgICAgIGlmIChuZXh0VGFiID09IC0xKSBuZXh0VGFiID0gc3RyaW5nLmxlbmd0aDtcbiAgICAgIHZhciBza2lwcGVkID0gbmV4dFRhYiAtIHBvcztcbiAgICAgIGlmIChuZXh0VGFiID09IHN0cmluZy5sZW5ndGggfHwgY29sICsgc2tpcHBlZCA+PSBnb2FsKVxuICAgICAgICByZXR1cm4gcG9zICsgTWF0aC5taW4oc2tpcHBlZCwgZ29hbCAtIGNvbCk7XG4gICAgICBjb2wgKz0gbmV4dFRhYiAtIHBvcztcbiAgICAgIGNvbCArPSB0YWJTaXplIC0gKGNvbCAlIHRhYlNpemUpO1xuICAgICAgcG9zID0gbmV4dFRhYiArIDE7XG4gICAgICBpZiAoY29sID49IGdvYWwpIHJldHVybiBwb3M7XG4gICAgfVxuICB9XG5cbiAgdmFyIHNwYWNlU3RycyA9IFtcIlwiXTtcbiAgZnVuY3Rpb24gc3BhY2VTdHIobikge1xuICAgIHdoaWxlIChzcGFjZVN0cnMubGVuZ3RoIDw9IG4pXG4gICAgICBzcGFjZVN0cnMucHVzaChsc3Qoc3BhY2VTdHJzKSArIFwiIFwiKTtcbiAgICByZXR1cm4gc3BhY2VTdHJzW25dO1xuICB9XG5cbiAgZnVuY3Rpb24gbHN0KGFycikgeyByZXR1cm4gYXJyW2Fyci5sZW5ndGgtMV07IH1cblxuICB2YXIgc2VsZWN0SW5wdXQgPSBmdW5jdGlvbihub2RlKSB7IG5vZGUuc2VsZWN0KCk7IH07XG4gIGlmIChpb3MpIC8vIE1vYmlsZSBTYWZhcmkgYXBwYXJlbnRseSBoYXMgYSBidWcgd2hlcmUgc2VsZWN0KCkgaXMgYnJva2VuLlxuICAgIHNlbGVjdElucHV0ID0gZnVuY3Rpb24obm9kZSkgeyBub2RlLnNlbGVjdGlvblN0YXJ0ID0gMDsgbm9kZS5zZWxlY3Rpb25FbmQgPSBub2RlLnZhbHVlLmxlbmd0aDsgfTtcbiAgZWxzZSBpZiAoaWUpIC8vIFN1cHByZXNzIG15c3RlcmlvdXMgSUUxMCBlcnJvcnNcbiAgICBzZWxlY3RJbnB1dCA9IGZ1bmN0aW9uKG5vZGUpIHsgdHJ5IHsgbm9kZS5zZWxlY3QoKTsgfSBjYXRjaChfZSkge30gfTtcblxuICBmdW5jdGlvbiBpbmRleE9mKGFycmF5LCBlbHQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgKytpKVxuICAgICAgaWYgKGFycmF5W2ldID09IGVsdCkgcmV0dXJuIGk7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIGZ1bmN0aW9uIG1hcChhcnJheSwgZikge1xuICAgIHZhciBvdXQgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSBvdXRbaV0gPSBmKGFycmF5W2ldLCBpKTtcbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgZnVuY3Rpb24gbm90aGluZygpIHt9XG5cbiAgZnVuY3Rpb24gY3JlYXRlT2JqKGJhc2UsIHByb3BzKSB7XG4gICAgdmFyIGluc3Q7XG4gICAgaWYgKE9iamVjdC5jcmVhdGUpIHtcbiAgICAgIGluc3QgPSBPYmplY3QuY3JlYXRlKGJhc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICBub3RoaW5nLnByb3RvdHlwZSA9IGJhc2U7XG4gICAgICBpbnN0ID0gbmV3IG5vdGhpbmcoKTtcbiAgICB9XG4gICAgaWYgKHByb3BzKSBjb3B5T2JqKHByb3BzLCBpbnN0KTtcbiAgICByZXR1cm4gaW5zdDtcbiAgfTtcblxuICBmdW5jdGlvbiBjb3B5T2JqKG9iaiwgdGFyZ2V0LCBvdmVyd3JpdGUpIHtcbiAgICBpZiAoIXRhcmdldCkgdGFyZ2V0ID0ge307XG4gICAgZm9yICh2YXIgcHJvcCBpbiBvYmopXG4gICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KHByb3ApICYmIChvdmVyd3JpdGUgIT09IGZhbHNlIHx8ICF0YXJnZXQuaGFzT3duUHJvcGVydHkocHJvcCkpKVxuICAgICAgICB0YXJnZXRbcHJvcF0gPSBvYmpbcHJvcF07XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJpbmQoZikge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZi5hcHBseShudWxsLCBhcmdzKTt9O1xuICB9XG5cbiAgdmFyIG5vbkFTQ0lJU2luZ2xlQ2FzZVdvcmRDaGFyID0gL1tcXHUwMGRmXFx1MDU4N1xcdTA1OTAtXFx1MDVmNFxcdTA2MDAtXFx1MDZmZlxcdTMwNDAtXFx1MzA5ZlxcdTMwYTAtXFx1MzBmZlxcdTM0MDAtXFx1NGRiNVxcdTRlMDAtXFx1OWZjY1xcdWFjMDAtXFx1ZDdhZl0vO1xuICB2YXIgaXNXb3JkQ2hhckJhc2ljID0gQ29kZU1pcnJvci5pc1dvcmRDaGFyID0gZnVuY3Rpb24oY2gpIHtcbiAgICByZXR1cm4gL1xcdy8udGVzdChjaCkgfHwgY2ggPiBcIlxceDgwXCIgJiZcbiAgICAgIChjaC50b1VwcGVyQ2FzZSgpICE9IGNoLnRvTG93ZXJDYXNlKCkgfHwgbm9uQVNDSUlTaW5nbGVDYXNlV29yZENoYXIudGVzdChjaCkpO1xuICB9O1xuICBmdW5jdGlvbiBpc1dvcmRDaGFyKGNoLCBoZWxwZXIpIHtcbiAgICBpZiAoIWhlbHBlcikgcmV0dXJuIGlzV29yZENoYXJCYXNpYyhjaCk7XG4gICAgaWYgKGhlbHBlci5zb3VyY2UuaW5kZXhPZihcIlxcXFx3XCIpID4gLTEgJiYgaXNXb3JkQ2hhckJhc2ljKGNoKSkgcmV0dXJuIHRydWU7XG4gICAgcmV0dXJuIGhlbHBlci50ZXN0KGNoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzRW1wdHkob2JqKSB7XG4gICAgZm9yICh2YXIgbiBpbiBvYmopIGlmIChvYmouaGFzT3duUHJvcGVydHkobikgJiYgb2JqW25dKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBFeHRlbmRpbmcgdW5pY29kZSBjaGFyYWN0ZXJzLiBBIHNlcmllcyBvZiBhIG5vbi1leHRlbmRpbmcgY2hhciArXG4gIC8vIGFueSBudW1iZXIgb2YgZXh0ZW5kaW5nIGNoYXJzIGlzIHRyZWF0ZWQgYXMgYSBzaW5nbGUgdW5pdCBhcyBmYXJcbiAgLy8gYXMgZWRpdGluZyBhbmQgbWVhc3VyaW5nIGlzIGNvbmNlcm5lZC4gVGhpcyBpcyBub3QgZnVsbHkgY29ycmVjdCxcbiAgLy8gc2luY2Ugc29tZSBzY3JpcHRzL2ZvbnRzL2Jyb3dzZXJzIGFsc28gdHJlYXQgb3RoZXIgY29uZmlndXJhdGlvbnNcbiAgLy8gb2YgY29kZSBwb2ludHMgYXMgYSBncm91cC5cbiAgdmFyIGV4dGVuZGluZ0NoYXJzID0gL1tcXHUwMzAwLVxcdTAzNmZcXHUwNDgzLVxcdTA0ODlcXHUwNTkxLVxcdTA1YmRcXHUwNWJmXFx1MDVjMVxcdTA1YzJcXHUwNWM0XFx1MDVjNVxcdTA1YzdcXHUwNjEwLVxcdTA2MWFcXHUwNjRiLVxcdTA2NWVcXHUwNjcwXFx1MDZkNi1cXHUwNmRjXFx1MDZkZS1cXHUwNmU0XFx1MDZlN1xcdTA2ZThcXHUwNmVhLVxcdTA2ZWRcXHUwNzExXFx1MDczMC1cXHUwNzRhXFx1MDdhNi1cXHUwN2IwXFx1MDdlYi1cXHUwN2YzXFx1MDgxNi1cXHUwODE5XFx1MDgxYi1cXHUwODIzXFx1MDgyNS1cXHUwODI3XFx1MDgyOS1cXHUwODJkXFx1MDkwMC1cXHUwOTAyXFx1MDkzY1xcdTA5NDEtXFx1MDk0OFxcdTA5NGRcXHUwOTUxLVxcdTA5NTVcXHUwOTYyXFx1MDk2M1xcdTA5ODFcXHUwOWJjXFx1MDliZVxcdTA5YzEtXFx1MDljNFxcdTA5Y2RcXHUwOWQ3XFx1MDllMlxcdTA5ZTNcXHUwYTAxXFx1MGEwMlxcdTBhM2NcXHUwYTQxXFx1MGE0MlxcdTBhNDdcXHUwYTQ4XFx1MGE0Yi1cXHUwYTRkXFx1MGE1MVxcdTBhNzBcXHUwYTcxXFx1MGE3NVxcdTBhODFcXHUwYTgyXFx1MGFiY1xcdTBhYzEtXFx1MGFjNVxcdTBhYzdcXHUwYWM4XFx1MGFjZFxcdTBhZTJcXHUwYWUzXFx1MGIwMVxcdTBiM2NcXHUwYjNlXFx1MGIzZlxcdTBiNDEtXFx1MGI0NFxcdTBiNGRcXHUwYjU2XFx1MGI1N1xcdTBiNjJcXHUwYjYzXFx1MGI4MlxcdTBiYmVcXHUwYmMwXFx1MGJjZFxcdTBiZDdcXHUwYzNlLVxcdTBjNDBcXHUwYzQ2LVxcdTBjNDhcXHUwYzRhLVxcdTBjNGRcXHUwYzU1XFx1MGM1NlxcdTBjNjJcXHUwYzYzXFx1MGNiY1xcdTBjYmZcXHUwY2MyXFx1MGNjNlxcdTBjY2NcXHUwY2NkXFx1MGNkNVxcdTBjZDZcXHUwY2UyXFx1MGNlM1xcdTBkM2VcXHUwZDQxLVxcdTBkNDRcXHUwZDRkXFx1MGQ1N1xcdTBkNjJcXHUwZDYzXFx1MGRjYVxcdTBkY2ZcXHUwZGQyLVxcdTBkZDRcXHUwZGQ2XFx1MGRkZlxcdTBlMzFcXHUwZTM0LVxcdTBlM2FcXHUwZTQ3LVxcdTBlNGVcXHUwZWIxXFx1MGViNC1cXHUwZWI5XFx1MGViYlxcdTBlYmNcXHUwZWM4LVxcdTBlY2RcXHUwZjE4XFx1MGYxOVxcdTBmMzVcXHUwZjM3XFx1MGYzOVxcdTBmNzEtXFx1MGY3ZVxcdTBmODAtXFx1MGY4NFxcdTBmODZcXHUwZjg3XFx1MGY5MC1cXHUwZjk3XFx1MGY5OS1cXHUwZmJjXFx1MGZjNlxcdTEwMmQtXFx1MTAzMFxcdTEwMzItXFx1MTAzN1xcdTEwMzlcXHUxMDNhXFx1MTAzZFxcdTEwM2VcXHUxMDU4XFx1MTA1OVxcdTEwNWUtXFx1MTA2MFxcdTEwNzEtXFx1MTA3NFxcdTEwODJcXHUxMDg1XFx1MTA4NlxcdTEwOGRcXHUxMDlkXFx1MTM1ZlxcdTE3MTItXFx1MTcxNFxcdTE3MzItXFx1MTczNFxcdTE3NTJcXHUxNzUzXFx1MTc3MlxcdTE3NzNcXHUxN2I3LVxcdTE3YmRcXHUxN2M2XFx1MTdjOS1cXHUxN2QzXFx1MTdkZFxcdTE4MGItXFx1MTgwZFxcdTE4YTlcXHUxOTIwLVxcdTE5MjJcXHUxOTI3XFx1MTkyOFxcdTE5MzJcXHUxOTM5LVxcdTE5M2JcXHUxYTE3XFx1MWExOFxcdTFhNTZcXHUxYTU4LVxcdTFhNWVcXHUxYTYwXFx1MWE2MlxcdTFhNjUtXFx1MWE2Y1xcdTFhNzMtXFx1MWE3Y1xcdTFhN2ZcXHUxYjAwLVxcdTFiMDNcXHUxYjM0XFx1MWIzNi1cXHUxYjNhXFx1MWIzY1xcdTFiNDJcXHUxYjZiLVxcdTFiNzNcXHUxYjgwXFx1MWI4MVxcdTFiYTItXFx1MWJhNVxcdTFiYThcXHUxYmE5XFx1MWMyYy1cXHUxYzMzXFx1MWMzNlxcdTFjMzdcXHUxY2QwLVxcdTFjZDJcXHUxY2Q0LVxcdTFjZTBcXHUxY2UyLVxcdTFjZThcXHUxY2VkXFx1MWRjMC1cXHUxZGU2XFx1MWRmZC1cXHUxZGZmXFx1MjAwY1xcdTIwMGRcXHUyMGQwLVxcdTIwZjBcXHUyY2VmLVxcdTJjZjFcXHUyZGUwLVxcdTJkZmZcXHUzMDJhLVxcdTMwMmZcXHUzMDk5XFx1MzA5YVxcdWE2NmYtXFx1YTY3MlxcdWE2N2NcXHVhNjdkXFx1YTZmMFxcdWE2ZjFcXHVhODAyXFx1YTgwNlxcdWE4MGJcXHVhODI1XFx1YTgyNlxcdWE4YzRcXHVhOGUwLVxcdWE4ZjFcXHVhOTI2LVxcdWE5MmRcXHVhOTQ3LVxcdWE5NTFcXHVhOTgwLVxcdWE5ODJcXHVhOWIzXFx1YTliNi1cXHVhOWI5XFx1YTliY1xcdWFhMjktXFx1YWEyZVxcdWFhMzFcXHVhYTMyXFx1YWEzNVxcdWFhMzZcXHVhYTQzXFx1YWE0Y1xcdWFhYjBcXHVhYWIyLVxcdWFhYjRcXHVhYWI3XFx1YWFiOFxcdWFhYmVcXHVhYWJmXFx1YWFjMVxcdWFiZTVcXHVhYmU4XFx1YWJlZFxcdWRjMDAtXFx1ZGZmZlxcdWZiMWVcXHVmZTAwLVxcdWZlMGZcXHVmZTIwLVxcdWZlMjZcXHVmZjllXFx1ZmY5Zl0vO1xuICBmdW5jdGlvbiBpc0V4dGVuZGluZ0NoYXIoY2gpIHsgcmV0dXJuIGNoLmNoYXJDb2RlQXQoMCkgPj0gNzY4ICYmIGV4dGVuZGluZ0NoYXJzLnRlc3QoY2gpOyB9XG5cbiAgLy8gRE9NIFVUSUxJVElFU1xuXG4gIGZ1bmN0aW9uIGVsdCh0YWcsIGNvbnRlbnQsIGNsYXNzTmFtZSwgc3R5bGUpIHtcbiAgICB2YXIgZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnKTtcbiAgICBpZiAoY2xhc3NOYW1lKSBlLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgICBpZiAoc3R5bGUpIGUuc3R5bGUuY3NzVGV4dCA9IHN0eWxlO1xuICAgIGlmICh0eXBlb2YgY29udGVudCA9PSBcInN0cmluZ1wiKSBlLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNvbnRlbnQpKTtcbiAgICBlbHNlIGlmIChjb250ZW50KSBmb3IgKHZhciBpID0gMDsgaSA8IGNvbnRlbnQubGVuZ3RoOyArK2kpIGUuYXBwZW5kQ2hpbGQoY29udGVudFtpXSk7XG4gICAgcmV0dXJuIGU7XG4gIH1cblxuICB2YXIgcmFuZ2U7XG4gIGlmIChkb2N1bWVudC5jcmVhdGVSYW5nZSkgcmFuZ2UgPSBmdW5jdGlvbihub2RlLCBzdGFydCwgZW5kLCBlbmROb2RlKSB7XG4gICAgdmFyIHIgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIHIuc2V0RW5kKGVuZE5vZGUgfHwgbm9kZSwgZW5kKTtcbiAgICByLnNldFN0YXJ0KG5vZGUsIHN0YXJ0KTtcbiAgICByZXR1cm4gcjtcbiAgfTtcbiAgZWxzZSByYW5nZSA9IGZ1bmN0aW9uKG5vZGUsIHN0YXJ0LCBlbmQpIHtcbiAgICB2YXIgciA9IGRvY3VtZW50LmJvZHkuY3JlYXRlVGV4dFJhbmdlKCk7XG4gICAgdHJ5IHsgci5tb3ZlVG9FbGVtZW50VGV4dChub2RlLnBhcmVudE5vZGUpOyB9XG4gICAgY2F0Y2goZSkgeyByZXR1cm4gcjsgfVxuICAgIHIuY29sbGFwc2UodHJ1ZSk7XG4gICAgci5tb3ZlRW5kKFwiY2hhcmFjdGVyXCIsIGVuZCk7XG4gICAgci5tb3ZlU3RhcnQoXCJjaGFyYWN0ZXJcIiwgc3RhcnQpO1xuICAgIHJldHVybiByO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHJlbW92ZUNoaWxkcmVuKGUpIHtcbiAgICBmb3IgKHZhciBjb3VudCA9IGUuY2hpbGROb2Rlcy5sZW5ndGg7IGNvdW50ID4gMDsgLS1jb3VudClcbiAgICAgIGUucmVtb3ZlQ2hpbGQoZS5maXJzdENoaWxkKTtcbiAgICByZXR1cm4gZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZUNoaWxkcmVuQW5kQWRkKHBhcmVudCwgZSkge1xuICAgIHJldHVybiByZW1vdmVDaGlsZHJlbihwYXJlbnQpLmFwcGVuZENoaWxkKGUpO1xuICB9XG5cbiAgdmFyIGNvbnRhaW5zID0gQ29kZU1pcnJvci5jb250YWlucyA9IGZ1bmN0aW9uKHBhcmVudCwgY2hpbGQpIHtcbiAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT0gMykgLy8gQW5kcm9pZCBicm93c2VyIGFsd2F5cyByZXR1cm5zIGZhbHNlIHdoZW4gY2hpbGQgaXMgYSB0ZXh0bm9kZVxuICAgICAgY2hpbGQgPSBjaGlsZC5wYXJlbnROb2RlO1xuICAgIGlmIChwYXJlbnQuY29udGFpbnMpXG4gICAgICByZXR1cm4gcGFyZW50LmNvbnRhaW5zKGNoaWxkKTtcbiAgICBkbyB7XG4gICAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT0gMTEpIGNoaWxkID0gY2hpbGQuaG9zdDtcbiAgICAgIGlmIChjaGlsZCA9PSBwYXJlbnQpIHJldHVybiB0cnVlO1xuICAgIH0gd2hpbGUgKGNoaWxkID0gY2hpbGQucGFyZW50Tm9kZSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gYWN0aXZlRWx0KCkge1xuICAgIHZhciBhY3RpdmVFbGVtZW50ID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgICB3aGlsZSAoYWN0aXZlRWxlbWVudCAmJiBhY3RpdmVFbGVtZW50LnJvb3QgJiYgYWN0aXZlRWxlbWVudC5yb290LmFjdGl2ZUVsZW1lbnQpXG4gICAgICBhY3RpdmVFbGVtZW50ID0gYWN0aXZlRWxlbWVudC5yb290LmFjdGl2ZUVsZW1lbnQ7XG4gICAgcmV0dXJuIGFjdGl2ZUVsZW1lbnQ7XG4gIH1cbiAgLy8gT2xkZXIgdmVyc2lvbnMgb2YgSUUgdGhyb3dzIHVuc3BlY2lmaWVkIGVycm9yIHdoZW4gdG91Y2hpbmdcbiAgLy8gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCBpbiBzb21lIGNhc2VzIChkdXJpbmcgbG9hZGluZywgaW4gaWZyYW1lKVxuICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8IDExKSBhY3RpdmVFbHQgPSBmdW5jdGlvbigpIHtcbiAgICB0cnkgeyByZXR1cm4gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDsgfVxuICAgIGNhdGNoKGUpIHsgcmV0dXJuIGRvY3VtZW50LmJvZHk7IH1cbiAgfTtcblxuICBmdW5jdGlvbiBjbGFzc1Rlc3QoY2xzKSB7IHJldHVybiBuZXcgUmVnRXhwKFwiKF58XFxcXHMpXCIgKyBjbHMgKyBcIig/OiR8XFxcXHMpXFxcXHMqXCIpOyB9XG4gIHZhciBybUNsYXNzID0gQ29kZU1pcnJvci5ybUNsYXNzID0gZnVuY3Rpb24obm9kZSwgY2xzKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBub2RlLmNsYXNzTmFtZTtcbiAgICB2YXIgbWF0Y2ggPSBjbGFzc1Rlc3QoY2xzKS5leGVjKGN1cnJlbnQpO1xuICAgIGlmIChtYXRjaCkge1xuICAgICAgdmFyIGFmdGVyID0gY3VycmVudC5zbGljZShtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aCk7XG4gICAgICBub2RlLmNsYXNzTmFtZSA9IGN1cnJlbnQuc2xpY2UoMCwgbWF0Y2guaW5kZXgpICsgKGFmdGVyID8gbWF0Y2hbMV0gKyBhZnRlciA6IFwiXCIpO1xuICAgIH1cbiAgfTtcbiAgdmFyIGFkZENsYXNzID0gQ29kZU1pcnJvci5hZGRDbGFzcyA9IGZ1bmN0aW9uKG5vZGUsIGNscykge1xuICAgIHZhciBjdXJyZW50ID0gbm9kZS5jbGFzc05hbWU7XG4gICAgaWYgKCFjbGFzc1Rlc3QoY2xzKS50ZXN0KGN1cnJlbnQpKSBub2RlLmNsYXNzTmFtZSArPSAoY3VycmVudCA/IFwiIFwiIDogXCJcIikgKyBjbHM7XG4gIH07XG4gIGZ1bmN0aW9uIGpvaW5DbGFzc2VzKGEsIGIpIHtcbiAgICB2YXIgYXMgPSBhLnNwbGl0KFwiIFwiKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFzLmxlbmd0aDsgaSsrKVxuICAgICAgaWYgKGFzW2ldICYmICFjbGFzc1Rlc3QoYXNbaV0pLnRlc3QoYikpIGIgKz0gXCIgXCIgKyBhc1tpXTtcbiAgICByZXR1cm4gYjtcbiAgfVxuXG4gIC8vIFdJTkRPVy1XSURFIEVWRU5UU1xuXG4gIC8vIFRoZXNlIG11c3QgYmUgaGFuZGxlZCBjYXJlZnVsbHksIGJlY2F1c2UgbmFpdmVseSByZWdpc3RlcmluZyBhXG4gIC8vIGhhbmRsZXIgZm9yIGVhY2ggZWRpdG9yIHdpbGwgY2F1c2UgdGhlIGVkaXRvcnMgdG8gbmV2ZXIgYmVcbiAgLy8gZ2FyYmFnZSBjb2xsZWN0ZWQuXG5cbiAgZnVuY3Rpb24gZm9yRWFjaENvZGVNaXJyb3IoZikge1xuICAgIGlmICghZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKSByZXR1cm47XG4gICAgdmFyIGJ5Q2xhc3MgPSBkb2N1bWVudC5ib2R5LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJDb2RlTWlycm9yXCIpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYnlDbGFzcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGNtID0gYnlDbGFzc1tpXS5Db2RlTWlycm9yO1xuICAgICAgaWYgKGNtKSBmKGNtKTtcbiAgICB9XG4gIH1cblxuICB2YXIgZ2xvYmFsc1JlZ2lzdGVyZWQgPSBmYWxzZTtcbiAgZnVuY3Rpb24gZW5zdXJlR2xvYmFsSGFuZGxlcnMoKSB7XG4gICAgaWYgKGdsb2JhbHNSZWdpc3RlcmVkKSByZXR1cm47XG4gICAgcmVnaXN0ZXJHbG9iYWxIYW5kbGVycygpO1xuICAgIGdsb2JhbHNSZWdpc3RlcmVkID0gdHJ1ZTtcbiAgfVxuICBmdW5jdGlvbiByZWdpc3Rlckdsb2JhbEhhbmRsZXJzKCkge1xuICAgIC8vIFdoZW4gdGhlIHdpbmRvdyByZXNpemVzLCB3ZSBuZWVkIHRvIHJlZnJlc2ggYWN0aXZlIGVkaXRvcnMuXG4gICAgdmFyIHJlc2l6ZVRpbWVyO1xuICAgIG9uKHdpbmRvdywgXCJyZXNpemVcIiwgZnVuY3Rpb24oKSB7XG4gICAgICBpZiAocmVzaXplVGltZXIgPT0gbnVsbCkgcmVzaXplVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICByZXNpemVUaW1lciA9IG51bGw7XG4gICAgICAgIGZvckVhY2hDb2RlTWlycm9yKG9uUmVzaXplKTtcbiAgICAgIH0sIDEwMCk7XG4gICAgfSk7XG4gICAgLy8gV2hlbiB0aGUgd2luZG93IGxvc2VzIGZvY3VzLCB3ZSB3YW50IHRvIHNob3cgdGhlIGVkaXRvciBhcyBibHVycmVkXG4gICAgb24od2luZG93LCBcImJsdXJcIiwgZnVuY3Rpb24oKSB7XG4gICAgICBmb3JFYWNoQ29kZU1pcnJvcihvbkJsdXIpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gRkVBVFVSRSBERVRFQ1RJT05cblxuICAvLyBEZXRlY3QgZHJhZy1hbmQtZHJvcFxuICB2YXIgZHJhZ0FuZERyb3AgPSBmdW5jdGlvbigpIHtcbiAgICAvLyBUaGVyZSBpcyAqc29tZSoga2luZCBvZiBkcmFnLWFuZC1kcm9wIHN1cHBvcnQgaW4gSUU2LTgsIGJ1dCBJXG4gICAgLy8gY291bGRuJ3QgZ2V0IGl0IHRvIHdvcmsgeWV0LlxuICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uIDwgOSkgcmV0dXJuIGZhbHNlO1xuICAgIHZhciBkaXYgPSBlbHQoJ2RpdicpO1xuICAgIHJldHVybiBcImRyYWdnYWJsZVwiIGluIGRpdiB8fCBcImRyYWdEcm9wXCIgaW4gZGl2O1xuICB9KCk7XG5cbiAgdmFyIHp3c3BTdXBwb3J0ZWQ7XG4gIGZ1bmN0aW9uIHplcm9XaWR0aEVsZW1lbnQobWVhc3VyZSkge1xuICAgIGlmICh6d3NwU3VwcG9ydGVkID09IG51bGwpIHtcbiAgICAgIHZhciB0ZXN0ID0gZWx0KFwic3BhblwiLCBcIlxcdTIwMGJcIik7XG4gICAgICByZW1vdmVDaGlsZHJlbkFuZEFkZChtZWFzdXJlLCBlbHQoXCJzcGFuXCIsIFt0ZXN0LCBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcInhcIildKSk7XG4gICAgICBpZiAobWVhc3VyZS5maXJzdENoaWxkLm9mZnNldEhlaWdodCAhPSAwKVxuICAgICAgICB6d3NwU3VwcG9ydGVkID0gdGVzdC5vZmZzZXRXaWR0aCA8PSAxICYmIHRlc3Qub2Zmc2V0SGVpZ2h0ID4gMiAmJiAhKGllICYmIGllX3ZlcnNpb24gPCA4KTtcbiAgICB9XG4gICAgdmFyIG5vZGUgPSB6d3NwU3VwcG9ydGVkID8gZWx0KFwic3BhblwiLCBcIlxcdTIwMGJcIikgOlxuICAgICAgZWx0KFwic3BhblwiLCBcIlxcdTAwYTBcIiwgbnVsbCwgXCJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IHdpZHRoOiAxcHg7IG1hcmdpbi1yaWdodDogLTFweFwiKTtcbiAgICBub2RlLnNldEF0dHJpYnV0ZShcImNtLXRleHRcIiwgXCJcIik7XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICAvLyBGZWF0dXJlLWRldGVjdCBJRSdzIGNydW1teSBjbGllbnQgcmVjdCByZXBvcnRpbmcgZm9yIGJpZGkgdGV4dFxuICB2YXIgYmFkQmlkaVJlY3RzO1xuICBmdW5jdGlvbiBoYXNCYWRCaWRpUmVjdHMobWVhc3VyZSkge1xuICAgIGlmIChiYWRCaWRpUmVjdHMgIT0gbnVsbCkgcmV0dXJuIGJhZEJpZGlSZWN0cztcbiAgICB2YXIgdHh0ID0gcmVtb3ZlQ2hpbGRyZW5BbmRBZGQobWVhc3VyZSwgZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoXCJBXFx1MDYyZUFcIikpO1xuICAgIHZhciByMCA9IHJhbmdlKHR4dCwgMCwgMSkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAg
23459aWYgKCFyMCB8fCByMC5sZWZ0ID09IHIwLnJpZ2h0KSByZXR1cm4gZmFsc2U7IC8vIFNhZmFyaSByZXR1cm5zIG51bGwgaW4gc29tZSBjYXNlcyAoIzI3ODApXG4gICAgdmFyIHIxID0gcmFuZ2UodHh0LCAxLCAyKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTt
vendor: 20,473 bytes, line 23459
23459cbiAgICByZXR1cm4gYmFkQmlkaVJlY3RzID0gKHIxLnJpZ2h0IC0gcjAucmlnaHQgPCAzKTtcbiAgfVxuXG4gIC8vIFNlZSBpZiBcIlwiLnNwbGl0IGlzIHRoZSBicm9rZW4gSUUgdmVyc2lvbiwgaWYgc28sIHByb3ZpZGUgYW5cbiAgLy8gYWx0ZXJuYXRpdmUgd2F5IHRvIHNwbGl0IGxpbmVzLlxuICB2YXIgc3BsaXRMaW5lc0F1dG8gPSBDb2RlTWlycm9yLnNwbGl0TGluZXMgPSBcIlxcblxcbmJcIi5zcGxpdCgvXFxuLykubGVuZ3RoICE9IDMgPyBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICB2YXIgcG9zID0gMCwgcmVzdWx0ID0gW10sIGwgPSBzdHJpbmcubGVuZ3RoO1xuICAgIHdoaWxlIChwb3MgPD0gbCkge1xuICAgICAgdmFyIG5sID0gc3RyaW5nLmluZGV4T2YoXCJcXG5cIiwgcG9zKTtcbiAgICAgIGlmIChubCA9PSAtMSkgbmwgPSBzdHJpbmcubGVuZ3RoO1xuICAgICAgdmFyIGxpbmUgPSBzdHJpbmcuc2xpY2UocG9zLCBzdHJpbmcuY2hhckF0KG5sIC0gMSkgPT0gXCJcXHJcIiA/IG5sIC0gMSA6IG5sKTtcbiAgICAgIHZhciBydCA9IGxpbmUuaW5kZXhPZihcIlxcclwiKTtcbiAgICAgIGlmIChydCAhPSAtMSkge1xuICAgICAgICByZXN1bHQucHVzaChsaW5lLnNsaWNlKDAsIHJ0KSk7XG4gICAgICAgIHBvcyArPSBydCArIDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQucHVzaChsaW5lKTtcbiAgICAgICAgcG9zID0gbmwgKyAxO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9IDogZnVuY3Rpb24oc3RyaW5nKXtyZXR1cm4gc3RyaW5nLnNwbGl0KC9cXHJcXG4/fFxcbi8pO307XG5cbiAgdmFyIGhhc1NlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24gPyBmdW5jdGlvbih0ZSkge1xuICAgIHRyeSB7IHJldHVybiB0ZS5zZWxlY3Rpb25TdGFydCAhPSB0ZS5zZWxlY3Rpb25FbmQ7IH1cbiAgICBjYXRjaChlKSB7IHJldHVybiBmYWxzZTsgfVxuICB9IDogZnVuY3Rpb24odGUpIHtcbiAgICB0cnkge3ZhciByYW5nZSA9IHRlLm93bmVyRG9jdW1lbnQuc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7fVxuICAgIGNhdGNoKGUpIHt9XG4gICAgaWYgKCFyYW5nZSB8fCByYW5nZS5wYXJlbnRFbGVtZW50KCkgIT0gdGUpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gcmFuZ2UuY29tcGFyZUVuZFBvaW50cyhcIlN0YXJ0VG9FbmRcIiwgcmFuZ2UpICE9IDA7XG4gIH07XG5cbiAgdmFyIGhhc0NvcHlFdmVudCA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgZSA9IGVsdChcImRpdlwiKTtcbiAgICBpZiAoXCJvbmNvcHlcIiBpbiBlKSByZXR1cm4gdHJ1ZTtcbiAgICBlLnNldEF0dHJpYnV0ZShcIm9uY29weVwiLCBcInJldHVybjtcIik7XG4gICAgcmV0dXJuIHR5cGVvZiBlLm9uY29weSA9PSBcImZ1bmN0aW9uXCI7XG4gIH0pKCk7XG5cbiAgdmFyIGJhZFpvb21lZFJlY3RzID0gbnVsbDtcbiAgZnVuY3Rpb24gaGFzQmFkWm9vbWVkUmVjdHMobWVhc3VyZSkge1xuICAgIGlmIChiYWRab29tZWRSZWN0cyAhPSBudWxsKSByZXR1cm4gYmFkWm9vbWVkUmVjdHM7XG4gICAgdmFyIG5vZGUgPSByZW1vdmVDaGlsZHJlbkFuZEFkZChtZWFzdXJlLCBlbHQoXCJzcGFuXCIsIFwieFwiKSk7XG4gICAgdmFyIG5vcm1hbCA9IG5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgdmFyIGZyb21SYW5nZSA9IHJhbmdlKG5vZGUsIDAsIDEpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiBiYWRab29tZWRSZWN0cyA9IE1hdGguYWJzKG5vcm1hbC5sZWZ0IC0gZnJvbVJhbmdlLmxlZnQpID4gMTtcbiAgfVxuXG4gIC8vIEtFWSBOQU1FU1xuXG4gIHZhciBrZXlOYW1lcyA9IENvZGVNaXJyb3Iua2V5TmFtZXMgPSB7XG4gICAgMzogXCJFbnRlclwiLCA4OiBcIkJhY2tzcGFjZVwiLCA5OiBcIlRhYlwiLCAxMzogXCJFbnRlclwiLCAxNjogXCJTaGlmdFwiLCAxNzogXCJDdHJsXCIsIDE4OiBcIkFsdFwiLFxuICAgIDE5OiBcIlBhdXNlXCIsIDIwOiBcIkNhcHNMb2NrXCIsIDI3OiBcIkVzY1wiLCAzMjogXCJTcGFjZVwiLCAzMzogXCJQYWdlVXBcIiwgMzQ6IFwiUGFnZURvd25cIiwgMzU6IFwiRW5kXCIsXG4gICAgMzY6IFwiSG9tZVwiLCAzNzogXCJMZWZ0XCIsIDM4OiBcIlVwXCIsIDM5OiBcIlJpZ2h0XCIsIDQwOiBcIkRvd25cIiwgNDQ6IFwiUHJpbnRTY3JuXCIsIDQ1OiBcIkluc2VydFwiLFxuICAgIDQ2OiBcIkRlbGV0ZVwiLCA1OTogXCI7XCIsIDYxOiBcIj1cIiwgOTE6IFwiTW9kXCIsIDkyOiBcIk1vZFwiLCA5MzogXCJNb2RcIixcbiAgICAxMDY6IFwiKlwiLCAxMDc6IFwiPVwiLCAxMDk6IFwiLVwiLCAxMTA6IFwiLlwiLCAxMTE6IFwiL1wiLCAxMjc6IFwiRGVsZXRlXCIsXG4gICAgMTczOiBcIi1cIiwgMTg2OiBcIjtcIiwgMTg3OiBcIj1cIiwgMTg4OiBcIixcIiwgMTg5OiBcIi1cIiwgMTkwOiBcIi5cIiwgMTkxOiBcIi9cIiwgMTkyOiBcImBcIiwgMjE5OiBcIltcIiwgMjIwOiBcIlxcXFxcIixcbiAgICAyMjE6IFwiXVwiLCAyMjI6IFwiJ1wiLCA2MzIzMjogXCJVcFwiLCA2MzIzMzogXCJEb3duXCIsIDYzMjM0OiBcIkxlZnRcIiwgNjMyMzU6IFwiUmlnaHRcIiwgNjMyNzI6IFwiRGVsZXRlXCIsXG4gICAgNjMyNzM6IFwiSG9tZVwiLCA2MzI3NTogXCJFbmRcIiwgNjMyNzY6IFwiUGFnZVVwXCIsIDYzMjc3OiBcIlBhZ2VEb3duXCIsIDYzMzAyOiBcIkluc2VydFwiXG4gIH07XG4gIChmdW5jdGlvbigpIHtcbiAgICAvLyBOdW1iZXIga2V5c1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTA7IGkrKykga2V5TmFtZXNbaSArIDQ4XSA9IGtleU5hbWVzW2kgKyA5Nl0gPSBTdHJpbmcoaSk7XG4gICAgLy8gQWxwaGFiZXRpYyBrZXlzXG4gICAgZm9yICh2YXIgaSA9IDY1OyBpIDw9IDkwOyBpKyspIGtleU5hbWVzW2ldID0gU3RyaW5nLmZyb21DaGFyQ29kZShpKTtcbiAgICAvLyBGdW5jdGlvbiBrZXlzXG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gMTI7IGkrKykga2V5TmFtZXNbaSArIDExMV0gPSBrZXlOYW1lc1tpICsgNjMyMzVdID0gXCJGXCIgKyBpO1xuICB9KSgpO1xuXG4gIC8vIEJJREkgSEVMUEVSU1xuXG4gIGZ1bmN0aW9uIGl0ZXJhdGVCaWRpU2VjdGlvbnMob3JkZXIsIGZyb20sIHRvLCBmKSB7XG4gICAgaWYgKCFvcmRlcikgcmV0dXJuIGYoZnJvbSwgdG8sIFwibHRyXCIpO1xuICAgIHZhciBmb3VuZCA9IGZhbHNlO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3JkZXIubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBwYXJ0ID0gb3JkZXJbaV07XG4gICAgICBpZiAocGFydC5mcm9tIDwgdG8gJiYgcGFydC50byA+IGZyb20gfHwgZnJvbSA9PSB0byAmJiBwYXJ0LnRvID09IGZyb20pIHtcbiAgICAgICAgZihNYXRoLm1heChwYXJ0LmZyb20sIGZyb20pLCBNYXRoLm1pbihwYXJ0LnRvLCB0byksIHBhcnQubGV2ZWwgPT0gMSA/IFwicnRsXCIgOiBcImx0clwiKTtcbiAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWZvdW5kKSBmKGZyb20sIHRvLCBcImx0clwiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJpZGlMZWZ0KHBhcnQpIHsgcmV0dXJuIHBhcnQubGV2ZWwgJSAyID8gcGFydC50byA6IHBhcnQuZnJvbTsgfVxuICBmdW5jdGlvbiBiaWRpUmlnaHQocGFydCkgeyByZXR1cm4gcGFydC5sZXZlbCAlIDIgPyBwYXJ0LmZyb20gOiBwYXJ0LnRvOyB9XG5cbiAgZnVuY3Rpb24gbGluZUxlZnQobGluZSkgeyB2YXIgb3JkZXIgPSBnZXRPcmRlcihsaW5lKTsgcmV0dXJuIG9yZGVyID8gYmlkaUxlZnQob3JkZXJbMF0pIDogMDsgfVxuICBmdW5jdGlvbiBsaW5lUmlnaHQobGluZSkge1xuICAgIHZhciBvcmRlciA9IGdldE9yZGVyKGxpbmUpO1xuICAgIGlmICghb3JkZXIpIHJldHVybiBsaW5lLnRleHQubGVuZ3RoO1xuICAgIHJldHVybiBiaWRpUmlnaHQobHN0KG9yZGVyKSk7XG4gIH1cblxuICBmdW5jdGlvbiBsaW5lU3RhcnQoY20sIGxpbmVOKSB7XG4gICAgdmFyIGxpbmUgPSBnZXRMaW5lKGNtLmRvYywgbGluZU4pO1xuICAgIHZhciB2aXN1YWwgPSB2aXN1YWxMaW5lKGxpbmUpO1xuICAgIGlmICh2aXN1YWwgIT0gbGluZSkgbGluZU4gPSBsaW5lTm8odmlzdWFsKTtcbiAgICB2YXIgb3JkZXIgPSBnZXRPcmRlcih2aXN1YWwpO1xuICAgIHZhciBjaCA9ICFvcmRlciA/IDAgOiBvcmRlclswXS5sZXZlbCAlIDIgPyBsaW5lUmlnaHQodmlzdWFsKSA6IGxpbmVMZWZ0KHZpc3VhbCk7XG4gICAgcmV0dXJuIFBvcyhsaW5lTiwgY2gpO1xuICB9XG4gIGZ1bmN0aW9uIGxpbmVFbmQoY20sIGxpbmVOKSB7XG4gICAgdmFyIG1lcmdlZCwgbGluZSA9IGdldExpbmUoY20uZG9jLCBsaW5lTik7XG4gICAgd2hpbGUgKG1lcmdlZCA9IGNvbGxhcHNlZFNwYW5BdEVuZChsaW5lKSkge1xuICAgICAgbGluZSA9IG1lcmdlZC5maW5kKDEsIHRydWUpLmxpbmU7XG4gICAgICBsaW5lTiA9IG51bGw7XG4gICAgfVxuICAgIHZhciBvcmRlciA9IGdldE9yZGVyKGxpbmUpO1xuICAgIHZhciBjaCA9ICFvcmRlciA/IGxpbmUudGV4dC5sZW5ndGggOiBvcmRlclswXS5sZXZlbCAlIDIgPyBsaW5lTGVmdChsaW5lKSA6IGxpbmVSaWdodChsaW5lKTtcbiAgICByZXR1cm4gUG9zKGxpbmVOID09IG51bGwgPyBsaW5lTm8obGluZSkgOiBsaW5lTiwgY2gpO1xuICB9XG4gIGZ1bmN0aW9uIGxpbmVTdGFydFNtYXJ0KGNtLCBwb3MpIHtcbiAgICB2YXIgc3RhcnQgPSBsaW5lU3RhcnQoY20sIHBvcy5saW5lKTtcbiAgICB2YXIgbGluZSA9IGdldExpbmUoY20uZG9jLCBzdGFydC5saW5lKTtcbiAgICB2YXIgb3JkZXIgPSBnZXRPcmRlcihsaW5lKTtcbiAgICBpZiAoIW9yZGVyIHx8IG9yZGVyWzBdLmxldmVsID09IDApIHtcbiAgICAgIHZhciBmaXJzdE5vbldTID0gTWF0aC5tYXgoMCwgbGluZS50ZXh0LnNlYXJjaCgvXFxTLykpO1xuICAgICAgdmFyIGluV1MgPSBwb3MubGluZSA9PSBzdGFydC5saW5lICYmIHBvcy5jaCA8PSBmaXJzdE5vbldTICYmIHBvcy5jaDtcbiAgICAgIHJldHVybiBQb3Moc3RhcnQubGluZSwgaW5XUyA/IDAgOiBmaXJzdE5vbldTKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0YXJ0O1xuICB9XG5cbiAgZnVuY3Rpb24gY29tcGFyZUJpZGlMZXZlbChvcmRlciwgYSwgYikge1xuICAgIHZhciBsaW5lZGlyID0gb3JkZXJbMF0ubGV2ZWw7XG4gICAgaWYgKGEgPT0gbGluZWRpcikgcmV0dXJuIHRydWU7XG4gICAgaWYgKGIgPT0gbGluZWRpcikgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBhIDwgYjtcbiAgfVxuICB2YXIgYmlkaU90aGVyO1xuICBmdW5jdGlvbiBnZXRCaWRpUGFydEF0KG9yZGVyLCBwb3MpIHtcbiAgICBiaWRpT3RoZXIgPSBudWxsO1xuICAgIGZvciAodmFyIGkgPSAwLCBmb3VuZDsgaSA8IG9yZGVyLmxlbmd0aDsgKytpKSB7XG4gICAgICB2YXIgY3VyID0gb3JkZXJbaV07XG4gICAgICBpZiAoY3VyLmZyb20gPCBwb3MgJiYgY3VyLnRvID4gcG9zKSByZXR1cm4gaTtcbiAgICAgIGlmICgoY3VyLmZyb20gPT0gcG9zIHx8IGN1ci50byA9PSBwb3MpKSB7XG4gICAgICAgIGlmIChmb3VuZCA9PSBudWxsKSB7XG4gICAgICAgICAgZm91bmQgPSBpO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbXBhcmVCaWRpTGV2ZWwob3JkZXIsIGN1ci5sZXZlbCwgb3JkZXJbZm91bmRdLmxldmVsKSkge1xuICAgICAgICAgIGlmIChjdXIuZnJvbSAhPSBjdXIudG8pIGJpZGlPdGhlciA9IGZvdW5kO1xuICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChjdXIuZnJvbSAhPSBjdXIudG8pIGJpZGlPdGhlciA9IGk7XG4gICAgICAgICAgcmV0dXJuIGZvdW5kO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmb3VuZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1vdmVJbkxpbmUobGluZSwgcG9zLCBkaXIsIGJ5VW5pdCkge1xuICAgIGlmICghYnlVbml0KSByZXR1cm4gcG9zICsgZGlyO1xuICAgIGRvIHBvcyArPSBkaXI7XG4gICAgd2hpbGUgKHBvcyA+IDAgJiYgaXNFeHRlbmRpbmdDaGFyKGxpbmUudGV4dC5jaGFyQXQocG9zKSkpO1xuICAgIHJldHVybiBwb3M7XG4gIH1cblxuICAvLyBUaGlzIGlzIG5lZWRlZCBpbiBvcmRlciB0byBtb3ZlICd2aXN1YWxseScgdGhyb3VnaCBiaS1kaXJlY3Rpb25hbFxuICAvLyB0ZXh0IC0tIGkuZS4sIHByZXNzaW5nIGxlZnQgc2hvdWxkIG1ha2UgdGhlIGN1cnNvciBnbyBsZWZ0LCBldmVuXG4gIC8vIHdoZW4gaW4gUlRMIHRleHQuIFRoZSB0cmlja3kgcGFydCBpcyB0aGUgJ2p1bXBzJywgd2hlcmUgUlRMIGFuZFxuICAvLyBMVFIgdGV4dCB0b3VjaCBlYWNoIG90aGVyLiBUaGlzIG9mdGVuIHJlcXVpcmVzIHRoZSBjdXJzb3Igb2Zmc2V0XG4gIC8vIHRvIG1vdmUgbW9yZSB0aGFuIG9uZSB1bml0LCBpbiBvcmRlciB0byB2aXN1YWxseSBtb3ZlIG9uZSB1bml0LlxuICBmdW5jdGlvbiBtb3ZlVmlzdWFsbHkobGluZSwgc3RhcnQsIGRpciwgYnlVbml0KSB7XG4gICAgdmFyIGJpZGkgPSBnZXRPcmRlcihsaW5lKTtcbiAgICBpZiAoIWJpZGkpIHJldHVybiBtb3ZlTG9naWNhbGx5KGxpbmUsIHN0YXJ0LCBkaXIsIGJ5VW5pdCk7XG4gICAgdmFyIHBvcyA9IGdldEJpZGlQYXJ0QXQoYmlkaSwgc3RhcnQpLCBwYXJ0ID0gYmlkaVtwb3NdO1xuICAgIHZhciB0YXJnZXQgPSBtb3ZlSW5MaW5lKGxpbmUsIHN0YXJ0LCBwYXJ0LmxldmVsICUgMiA/IC1kaXIgOiBkaXIsIGJ5VW5pdCk7XG5cbiAgICBmb3IgKDs7KSB7XG4gICAgICBpZiAodGFyZ2V0ID4gcGFydC5mcm9tICYmIHRhcmdldCA8IHBhcnQudG8pIHJldHVybiB0YXJnZXQ7XG4gICAgICBpZiAodGFyZ2V0ID09IHBhcnQuZnJvbSB8fCB0YXJnZXQgPT0gcGFydC50bykge1xuICAgICAgICBpZiAoZ2V0QmlkaVBhcnRBdChiaWRpLCB0YXJnZXQpID09IHBvcykgcmV0dXJuIHRhcmdldDtcbiAgICAgICAgcGFydCA9IGJpZGlbcG9zICs9IGRpcl07XG4gICAgICAgIHJldHVybiAoZGlyID4gMCkgPT0gcGFydC5sZXZlbCAlIDIgPyBwYXJ0LnRvIDogcGFydC5mcm9tO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFydCA9IGJpZGlbcG9zICs9IGRpcl07XG4gICAgICAgIGlmICghcGFydCkgcmV0dXJuIG51bGw7XG4gICAgICAgIGlmICgoZGlyID4gMCkgPT0gcGFydC5sZXZlbCAlIDIpXG4gICAgICAgICAgdGFyZ2V0ID0gbW92ZUluTGluZShsaW5lLCBwYXJ0LnRvLCAtMSwgYnlVbml0KTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHRhcmdldCA9IG1vdmVJbkxpbmUobGluZSwgcGFydC5mcm9tLCAxLCBieVVuaXQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG1vdmVMb2dpY2FsbHkobGluZSwgc3RhcnQsIGRpciwgYnlVbml0KSB7XG4gICAgdmFyIHRhcmdldCA9IHN0YXJ0ICsgZGlyO1xuICAgIGlmIChieVVuaXQpIHdoaWxlICh0YXJnZXQgPiAwICYmIGlzRXh0ZW5kaW5nQ2hhcihsaW5lLnRleHQuY2hhckF0KHRhcmdldCkpKSB0YXJnZXQgKz0gZGlyO1xuICAgIHJldHVybiB0YXJnZXQgPCAwIHx8IHRhcmdldCA+IGxpbmUudGV4dC5sZW5ndGggPyBudWxsIDogdGFyZ2V0O1xuICB9XG5cbiAgLy8gQmlkaXJlY3Rpb25hbCBvcmRlcmluZyBhbGdvcml0aG1cbiAgLy8gU2VlIGh0dHA6Ly91bmljb2RlLm9yZy9yZXBvcnRzL3RyOS90cjktMTMuaHRtbCBmb3IgdGhlIGFsZ29yaXRobVxuICAvLyB0aGF0IHRoaXMgKHBhcnRpYWxseSkgaW1wbGVtZW50cy5cblxuICAvLyBPbmUtY2hhciBjb2RlcyB1c2VkIGZvciBjaGFyYWN0ZXIgdHlwZXM6XG4gIC8vIEwgKEwpOiAgIExlZnQtdG8tUmlnaHRcbiAgLy8gUiAoUik6ICAgUmlnaHQtdG8tTGVmdFxuICAvLyByIChBTCk6ICBSaWdodC10by1MZWZ0IEFyYWJpY1xuICAvLyAxIChFTik6ICBFdXJvcGVhbiBOdW1iZXJcbiAgLy8gKyAoRVMpOiAgRXVyb3BlYW4gTnVtYmVyIFNlcGFyYXRvclxuICAvLyAlIChFVCk6ICBFdXJvcGVhbiBOdW1iZXIgVGVybWluYXRvclxuICAvLyBuIChBTik6ICBBcmFiaWMgTnVtYmVyXG4gIC8vICwgKENTKTogIENvbW1vbiBOdW1iZXIgU2VwYXJhdG9yXG4gIC8vIG0gKE5TTSk6IE5vbi1TcGFjaW5nIE1hcmtcbiAgLy8gYiAoQk4pOiAgQm91bmRhcnkgTmV1dHJhbFxuICAvLyBzIChCKTogICBQYXJhZ3JhcGggU2VwYXJhdG9yXG4gIC8vIHQgKFMpOiAgIFNlZ21lbnQgU2VwYXJhdG9yXG4gIC8vIHcgKFdTKTogIFdoaXRlc3BhY2VcbiAgLy8gTiAoT04pOiAgT3RoZXIgTmV1dHJhbHNcblxuICAvLyBSZXR1cm5zIG51bGwgaWYgY2hhcmFjdGVycyBhcmUgb3JkZXJlZCBhcyB0aGV5IGFwcGVhclxuICAvLyAobGVmdC10by1yaWdodCksIG9yIGFuIGFycmF5IG9mIHNlY3Rpb25zICh7ZnJvbSwgdG8sIGxldmVsfVxuICAvLyBvYmplY3RzKSBpbiB0aGUgb3JkZXIgaW4gd2hpY2ggdGhleSBvY2N1ciB2aXN1YWxseS5cbiAgdmFyIGJpZGlPcmRlcmluZyA9IChmdW5jdGlvbigpIHtcbiAgICAvLyBDaGFyYWN0ZXIgdHlwZXMgZm9yIGNvZGVwb2ludHMgMCB0byAweGZmXG4gICAgdmFyIGxvd1R5cGVzID0gXCJiYmJiYmJiYmJ0c3R3c2JiYmJiYmJiYmJiYmJic3NzdHdOTiUlJU5OTk5OTixOLE4xMTExMTExMTExTk5OTk5OTkxMTExMTExMTExMTExMTExMTExMTExMTExMTk5OTk5OTExMTExMTExMTExMTExMTExMTExMTExMTExOTk5OYmJiYmJic2JiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiLE4lJSUlTk5OTkxOTk5OTiUlMTFOTE5OTjFMTk5OTk5MTExMTExMTExMTExMTExMTExMTExMTE5MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTlwiO1xuICAgIC8vIENoYXJhY3RlciB0eXBlcyBmb3IgY29kZXBvaW50cyAweDYwMCB0byAweDZmZlxuICAgIHZhciBhcmFiaWNUeXBlcyA9IFwicnJycnJycnJycnJyLHJOTm1tbW1tbXJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJybW1tbW1tbW1tbW1tbW1ycnJycnJybm5ubm5ubm5ubiVubnJycm1ycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycm1tbW1tbW1tbW1tbW1tbW1tbW1ObW1tbVwiO1xuICAgIGZ1bmN0aW9uIGNoYXJUeXBlKGNvZGUpIHtcbiAgICAgIGlmIChjb2RlIDw9IDB4ZjcpIHJldHVybiBsb3dUeXBlcy5jaGFyQXQoY29kZSk7XG4gICAgICBlbHNlIGlmICgweDU5MCA8PSBjb2RlICYmIGNvZGUgPD0gMHg1ZjQpIHJldHVybiBcIlJcIjtcbiAgICAgIGVsc2UgaWYgKDB4NjAwIDw9IGNvZGUgJiYgY29kZSA8PSAweDZlZCkgcmV0dXJuIGFyYWJpY1R5cGVzLmNoYXJBdChjb2RlIC0gMHg2MDApO1xuICAgICAgZWxzZSBpZiAoMHg2ZWUgPD0gY29kZSAmJiBjb2RlIDw9IDB4OGFjKSByZXR1cm4gXCJyXCI7XG4gICAgICBlbHNlIGlmICgweDIwMDAgPD0gY29kZSAmJiBjb2RlIDw9IDB4MjAwYikgcmV0dXJuIFwid1wiO1xuICAgICAgZWxzZSBpZiAoY29kZSA9PSAweDIwMGMpIHJldHVybiBcImJcIjtcbiAgICAgIGVsc2UgcmV0dXJuIFwiTFwiO1xuICAgIH1cblxuICAgIHZhciBiaWRpUkUgPSAvW1xcdTA1OTAtXFx1MDVmNFxcdTA2MDAtXFx1MDZmZlxcdTA3MDAtXFx1MDhhY10vO1xuICAgIHZhciBpc05ldXRyYWwgPSAvW3N0d05dLywgaXNTdHJvbmcgPSAvW0xScl0vLCBjb3VudHNBc0xlZnQgPSAvW0xiMW5dLywgY291bnRzQXNOdW0gPSAvWzFuXS87XG4gICAgLy8gQnJvd3NlcnMgc2VlbSB0byBhbHdheXMgdHJlYXQgdGhlIGJvdW5kYXJpZXMgb2YgYmxvY2sgZWxlbWVudHMgYXMgYmVpbmcgTC5cbiAgICB2YXIgb3V0ZXJUeXBlID0gXCJMXCI7XG5cbiAgICBmdW5jdGlvbiBCaWRpU3BhbihsZXZlbCwgZnJvbSwgdG8pIHtcbiAgICAgIHRoaXMubGV2ZWwgPSBsZXZlbDtcbiAgICAgIHRoaXMuZnJvbSA9IGZyb207IHRoaXMudG8gPSB0bztcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24oc3RyKSB7XG4gICAgICBpZiAoIWJpZGlSRS50ZXN0KHN0cikpIHJldHVybiBmYWxzZTtcbiAgICAgIHZhciBsZW4gPSBzdHIubGVuZ3RoLCB0eXBlcyA9IFtdO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIHR5cGU7IGkgPCBsZW47ICsraSlcbiAgICAgICAgdHlwZXMucHVzaCh0eXBlID0gY2hhclR5cGUoc3RyLmNoYXJDb2RlQXQoaSkpKTtcblxuICAgICAgLy8gVzEuIEV4YW1pbmUgZWFjaCBub24tc3BhY2luZyBtYXJrIChOU00pIGluIHRoZSBsZXZlbCBydW4sIGFuZFxuICAgICAgLy8gY2hhbmdlIHRoZSB0eXBlIG9mIHRoZSBOU00gdG8gdGhlIHR5cGUgb2YgdGhlIHByZXZpb3VzXG4gICAgICAvLyBjaGFyYWN0ZXIuIElmIHRoZSBOU00gaXMgYXQgdGhlIHN0YXJ0IG9mIHRoZSBsZXZlbCBydW4sIGl0IHdpbGxcbiAgICAgIC8vIGdldCB0aGUgdHlwZSBvZiBzb3IuXG4gICAgICBmb3IgKHZhciBpID0gMCwgcHJldiA9IG91dGVyVHlwZTsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZXNbaV07XG4gICAgICAgIGlmICh0eXBlID09IFwibVwiKSB0eXBlc1tpXSA9IHByZXY7XG4gICAgICAgIGVsc2UgcHJldiA9IHR5cGU7XG4gICAgICB9XG5cbiAgICAgIC8vIFcyLiBTZWFyY2ggYmFja3dhcmRzIGZyb20gZWFjaCBpbnN0YW5jZSBvZiBhIEV1cm9wZWFuIG51bWJlclxuICAgICAgLy8gdW50aWwgdGhlIGZpcnN0IHN0cm9uZyB0eXBlIChSLCBMLCBBTCwgb3Igc29yKSBpcyBmb3VuZC4gSWYgYW5cbiAgICAgIC8vIEFMIGlzIGZvdW5kLCBjaGFuZ2UgdGhlIHR5cGUgb2YgdGhlIEV1cm9wZWFuIG51bWJlciB0byBBcmFiaWNcbiAgICAgIC8vIG51bWJlci5cbiAgICAgIC8vIFczLiBDaGFuZ2UgYWxsIEFMcyB0byBSLlxuICAgICAgZm9yICh2YXIgaSA9IDAsIGN1ciA9IG91dGVyVHlwZTsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZXNbaV07XG4gICAgICAgIGlmICh0eXBlID09IFwiMVwiICYmIGN1ciA9PSBcInJcIikgdHlwZXNbaV0gPSBcIm5cIjtcbiAgICAgICAgZWxzZSBpZiAoaXNTdHJvbmcudGVzdCh0eXBlKSkgeyBjdXIgPSB0eXBlOyBpZiAodHlwZSA9PSBcInJcIikgdHlwZXNbaV0gPSBcIlJcIjsgfVxuICAgICAgfVxuXG4gICAgICAvLyBXNC4gQSBzaW5nbGUgRXVyb3BlYW4gc2VwYXJhdG9yIGJldHdlZW4gdHdvIEV1cm9wZWFuIG51bWJlcnNcbiAgICAgIC8vIGNoYW5nZXMgdG8gYSBFdXJvcGVhbiBudW1iZXIuIEEgc2luZ2xlIGNvbW1vbiBzZXBhcmF0b3IgYmV0d2VlblxuICAgICAgLy8gdHdvIG51bWJlcnMgb2YgdGhlIHNhbWUgdHlwZSBjaGFuZ2VzIHRvIHRoYXQgdHlwZS5cbiAgICAgIGZvciAodmFyIGkgPSAxLCBwcmV2ID0gdHlwZXNbMF07IGkgPCBsZW4gLSAxOyArK2kpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlc1tpXTtcbiAgICAgICAgaWYgKHR5cGUgPT0gXCIrXCIgJiYgcHJldiA9PSBcIjFcIiAmJiB0eXBlc1tpKzFdID09IFwiMVwiKSB0eXBlc1tpXSA9IFwiMVwiO1xuICAgICAgICBlbHNlIGlmICh0eXBlID09IFwiLFwiICYmIHByZXYgPT0gdHlwZXNbaSsxXSAmJlxuICAgICAgICAgICAgICAgICAocHJldiA9PSBcIjFcIiB8fCBwcmV2ID09IFwiblwiKSkgdHlwZXNbaV0gPSBwcmV2O1xuICAgICAgICBwcmV2ID0gdHlwZTtcbiAgICAgIH1cblxuICAgICAgLy8gVzUuIEEgc2VxdWVuY2Ugb2YgRXVyb3BlYW4gdGVybWluYXRvcnMgYWRqYWNlbnQgdG8gRXVyb3BlYW5cbiAgICAgIC8vIG51bWJlcnMgY2hhbmdlcyB0byBhbGwgRXVyb3BlYW4gbnVtYmVycy5cbiAgICAgIC8vIFc2LiBPdGhlcndpc2UsIHNlcGFyYXRvcnMgYW5kIHRlcm1pbmF0b3JzIGNoYW5nZSB0byBPdGhlclxuICAgICAgLy8gTmV1dHJhbC5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlc1tpXTtcbiAgICAgICAgaWYgKHR5cGUgPT0gXCIsXCIpIHR5cGVzW2ldID0gXCJOXCI7XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gXCIlXCIpIHtcbiAgICAgICAgICBmb3IgKHZhciBlbmQgPSBpICsgMTsgZW5kIDwgbGVuICYmIHR5cGVzW2VuZF0gPT0gXCIlXCI7ICsrZW5kKSB7fVxuICAgICAgICAgIHZhciByZXBsYWNlID0gKGkgJiYgdHlwZXNbaS0xXSA9PSBcIiFcIikgfHwgKGVuZCA8IGxlbiAmJiB0eXBlc1tlbmRdID09IFwiMVwiKSA/IFwiMVwiIDogXCJOXCI7XG4gICAgICAgICAgZm9yICh2YXIgaiA9IGk7IGogPCBlbmQ7ICsraikgdHlwZXNbal0gPSByZXBsYWNlO1xuICAgICAgICAgIGkgPSBlbmQgLSAxO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFc3LiBTZWFyY2ggYmFja3dhcmRzIGZyb20gZWFjaCBpbnN0YW5jZSBvZiBhIEV1cm9wZWFuIG51bWJlclxuICAgICAgLy8gdW50aWwgdGhlIGZpcnN0IHN0cm9uZyB0eXBlIChSLCBMLCBvciBzb3IpIGlzIGZvdW5kLiBJZiBhbiBMIGlzXG4gICAgICAvLyBmb3VuZCwgdGhlbiBjaGFuZ2UgdGhlIHR5cGUgb2YgdGhlIEV1cm9wZWFuIG51bWJlciB0byBMLlxuICAgICAgZm9yICh2YXIgaSA9IDAsIGN1ciA9IG91dGVyVHlwZTsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZXNbaV07XG4gICAgICAgIGlmIChjdXIgPT0gXCJMXCIgJiYgdHlwZSA9PSBcIjFcIikgdHlwZXNbaV0gPSBcIkxcIjtcbiAgICAgICAgZWxzZSBpZiAoaXNTdHJvbmcudGVzdCh0eXBlKSkgY3VyID0gdHlwZTtcbiAgICAgIH1cblxuICAgICAgLy8gTjEuIEEgc2VxdWVuY2Ugb2YgbmV1dHJhbHMgdGFrZXMgdGhlIGRpcmVjdGlvbiBvZiB0aGVcbiAgICAgIC8vIHN1cnJvdW5kaW5nIHN0cm9uZyB0ZXh0IGlmIHRoZSB0ZXh0IG9uIGJvdGggc2lkZXMgaGFzIHRoZSBzYW1lXG4gICAgICAvLyBkaXJlY3Rpb24uIEV1cm9wZWFuIGFuZCBBcmFiaWMgbnVtYmVycyBhY3QgYXMgaWYgdGhleSB3ZXJlIFIgaW5cbiAgICAgIC8vIHRlcm1zIG9mIHRoZWlyIGluZmx1ZW5jZSBvbiBuZXV0cmFscy4gU3RhcnQtb2YtbGV2ZWwtcnVuIChzb3IpXG4gICAgICAvLyBhbmQgZW5kLW9mLWxldmVsLXJ1biAoZW9yKSBhcmUgdXNlZCBhdCBsZXZlbCBydW4gYm91bmRhcmllcy5cbiAgICAgIC8vIE4yLiBBbnkgcmVtYWluaW5nIG5ldXRyYWxzIHRha2UgdGhlIGVtYmVkZGluZyBkaXJlY3Rpb24uXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIGlmIChpc05ldXRyYWwudGVzdCh0eXBlc1tpXSkpIHtcbiAgICAgICAgICBmb3IgKHZhciBlbmQgPSBpICsgMTsgZW5kIDwgbGVuICYmIGlzTmV1dHJhbC50ZXN0KHR5cGVzW2VuZF0pOyArK2VuZCkge31cbiAgICAgICAgICB2YXIgYmVmb3JlID0gKGkgPyB0eXBlc1tpLTFdIDogb3V0ZXJUeXBlKSA9PSBcIkxcIjtcbiAgICAgICAgICB2YXIgYWZ0ZXIgPSAoZW5kIDwgbGVuID8gdHlwZXNbZW5kXSA6IG91dGVyVHlwZSkgPT0gXCJMXCI7XG4gICAgICAgICAgdmFyIHJlcGxhY2UgPSBiZWZvcmUgfHwgYWZ0ZXIgPyBcIkxcIiA6IFwiUlwiO1xuICAgICAgICAgIGZvciAodmFyIGogPSBpOyBqIDwgZW5kOyArK2opIHR5cGVzW2pdID0gcmVwbGFjZTtcbiAgICAgICAgICBpID0gZW5kIC0gMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBIZXJlIHdlIGRlcGFydCBmcm9tIHRoZSBkb2N1bWVudGVkIGFsZ29yaXRobSwgaW4gb3JkZXIgdG8gYXZvaWRcbiAgICAgIC8vIGJ1aWxkaW5nIHVwIGFuIGFjdHVhbCBsZXZlbHMgYXJyYXkuIFNpbmNlIHRoZXJlIGFyZSBvbmx5IHRocmVlXG4gICAgICAvLyBsZXZlbHMgKDAsIDEsIDIpIGluIGFuIGltcGxlbWVudGF0aW9uIHRoYXQgZG9lc24ndCB0YWtlXG4gICAgICAvLyBleHBsaWNpdCBlbWJlZGRpbmcgaW50byBhY2NvdW50LCB3ZSBjYW4gYnVpbGQgdXAgdGhlIG9yZGVyIG9uXG4gICAgICAvLyB0aGUgZmx5LCB3aXRob3V0IGZvbGxvd2luZyB0aGUgbGV2ZWwtYmFzZWQgYWxnb3JpdGhtLlxuICAgICAgdmFyIG9yZGVyID0gW10sIG07XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjspIHtcbiAgICAgICAgaWYgKGNvdW50c0FzTGVmdC50ZXN0KHR5cGVzW2ldKSkge1xuICAgICAgICAgIHZhciBzdGFydCA9IGk7XG4gICAgICAgICAgZm9yICgrK2k7IGkgPCBsZW4gJiYgY291bnRzQXNMZWZ0LnRlc3QodHlwZXNbaV0pOyArK2kpIHt9XG4gICAgICAgICAgb3JkZXIucHVzaChuZXcgQmlkaVNwYW4oMCwgc3RhcnQsIGkpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgcG9zID0gaSwgYXQgPSBvcmRlci5sZW5ndGg7XG4gICAgICAgICAgZm9yICgrK2k7IGkgPCBsZW4gJiYgdHlwZXNbaV0gIT0gXCJMXCI7ICsraSkge31cbiAgICAgICAgICBmb3IgKHZhciBqID0gcG9zOyBqIDwgaTspIHtcbiAgICAgICAgICAgIGlmIChjb3VudHNBc051bS50ZXN0KHR5cGVzW2pdKSkge1xuICAgICAgICAgICAgICBpZiAocG9zIDwgaikgb3JkZXIuc3BsaWNlKGF0LCAwLCBuZXcgQmlkaVNwYW4oMSwgcG9zLCBqKSk7XG4gICAgICAgICAgICAgIHZhciBuc3RhcnQgPSBqO1xuICAgICAgICAgICAgICBmb3IgKCsrajsgaiA8IGkgJiYgY291bnRzQXNOdW0udGVzdCh0eXBlc1tqXSk7ICsraikge31cbiAgICAgICAgICAgICAgb3JkZXIuc3BsaWNlKGF0LCAwLCBuZXcgQmlkaVNwYW4oMiwgbnN0YXJ0LCBqKSk7XG4gICAgICAgICAgICAgIHBvcyA9IGo7XG4gICAgICAgICAgICB9IGVsc2UgKytqO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocG9zIDwgaSkgb3JkZXIuc3BsaWNlKGF0LCAwLCBuZXcgQmlkaVNwYW4oMSwgcG9zLCBpKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChvcmRlclswXS5sZXZlbCA9PSAxICYmIChtID0gc3RyLm1hdGNoKC9eXFxzKy8pKSkge1xuICAgICAgICBvcmRlclswXS5mcm9tID0gbVswXS5sZW5ndGg7XG4gICAgICAgIG9yZGVyLnVuc2hpZnQobmV3IEJpZGlTcGFuKDAsIDAsIG1bMF0ubGVuZ3RoKSk7XG4gICAgICB9XG4gICAgICBpZiAobHN0KG9yZGVyKS5sZXZlbCA9PSAxICYmIChtID0gc3RyLm1hdGNoKC9cXHMrJC8pKSkge1xuICAgICAgICBsc3Qob3JkZXIpLnRvIC09IG1bMF0ubGVuZ3RoO1xuICAgICAgICBvcmRlci5wdXNoKG5ldyBCaWRpU3BhbigwLCBsZW4gLSBtWzBdLmxlbmd0aCwgbGVuKSk7XG4gICAgICB9XG4gICAgICBpZiAob3JkZXJbMF0ubGV2ZWwgPT0gMilcbiAgICAgICAgb3JkZXIudW5zaGlmdChuZXcgQmlkaVNwYW4oMSwgb3JkZXJbMF0udG8sIG9yZGVyWzBdLnRvKSk7XG4gICAgICBpZiAob3JkZXJbMF0ubGV2ZWwgIT0gbHN0KG9yZGVyKS5sZXZlbClcbiAgICAgICAgb3JkZXIucHVzaChuZXcgQmlkaVNwYW4ob3JkZXJbMF0ubGV2ZWwsIGxlbiwgbGVuKSk7XG5cbiAgICAgIHJldHVybiBvcmRlcjtcbiAgICB9O1xuICB9KSgpO1xuXG4gIC8vIFRIRSBFTkRcblxuICBDb2RlTWlycm9yLnZlcnNpb24gPSBcIjUu
23459OC4wXCI7XG5cbiAgcmV0dXJuIENvZGVNaXJyb3I7XG59KTtcbiIsIi8vIENvZGVNaXJyb3IsIGNvcHlyaWdodCAoYykgYnkgTWFyaWpuIEhhdmVyYmVrZSBhbmQgb3RoZXJzXG4vLyBEaXN0cmlidXRlZCB1bmRlciBhbiBNSVQgbGljZW5zZTogaHR0cDovL2NvZGVtaXJyb3IubmV0L0xJQ0VOU0VcblxuKGZ1bmN0aW9uKG1vZCkge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlID09IFwib2JqZWN0XCIpIC8vIENvbW1vbkpTXG4gICAgbW9kKHJlcXVpcmUoXCIuLi8uLi9saWIvY29kZW1pcnJvclwiKSk7XG4gIGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIC8vIEFNRFxuICAgIGRlZmluZShbXCIuLi8uLi9saWIvY29kZW1pcnJvclwiXSwgbW9kKTtcbiAgZWxzZSAvLyBQbGFpbiBicm93c2VyIGVudlxuICAgIG1vZChDb2RlTWlycm9yKTtcbn0pKGZ1bmN0aW9uKENvZGVNaXJyb3IpIHtcblwidXNlIHN0cmljdFwiO1xuXG5Db2RlTWlycm9yLmRlZmluZU1vZGUoXCJjbGlrZVwiLCBmdW5jdGlvbihjb25maWcsIHBhcnNlckNvbmZpZykge1xuICB2YXIgaW5kZW50VW5pdCA9IGNvbmZpZy5pbmRlbnRVbml0LFxuICAgICAgc3RhdGVtZW50SW5kZW50VW5pdCA9IHBhcnNlckNvbmZpZy5zdGF0ZW1lbnRJbmRlbnRVbml0IHx8IGluZGVudFVuaXQsXG4gICAgICBkb250QWxpZ25DYWxscyA9IHBhcnNlckNvbmZpZy5kb250QWxpZ25DYWxscyxcbiAgICAgIGtleXdvcmRzID0gcGFyc2VyQ29uZmlnLmtleXdvcmRzIHx8IHt9LFxuICAgICAgdHlwZXMgPSBwYXJzZXJDb25maWcudHlwZXMgfHwge30sXG4gICAgICBidWlsdGluID0gcGFyc2VyQ29uZmlnLmJ1aWx0aW4gfHwge30sXG4gICAgICBibG9ja0tleXdvcmRzID0gcGFyc2VyQ29uZmlnLmJsb2NrS2V5d29yZHMgfHwge30sXG4gICAgICBkZWZLZXl3b3JkcyA9IHBhcnNlckNvbmZpZy5kZWZLZXl3b3JkcyB8fCB7fSxcbiAgICAgIGF0b21zID0gcGFyc2VyQ29uZmlnLmF0b21zIHx8IHt9LFxuICAgICAgaG9va3MgPSBwYXJzZXJDb25maWcuaG9va3MgfHwge30sXG4gICAgICBtdWx0aUxpbmVTdHJpbmdzID0gcGFyc2VyQ29uZmlnLm11bHRpTGluZVN0cmluZ3MsXG4gICAgICBpbmRlbnRTdGF0ZW1lbnRzID0gcGFyc2VyQ29uZmlnLmluZGVudFN0YXRlbWVudHMgIT09IGZhbHNlLFxuICAgICAgaW5kZW50U3dpdGNoID0gcGFyc2VyQ29uZmlnLmluZGVudFN3aXRjaCAhPT0gZmFsc2UsXG4gICAgICBuYW1lc3BhY2VTZXBhcmF0b3IgPSBwYXJzZXJDb25maWcubmFtZXNwYWNlU2VwYXJhdG9yLFxuICAgICAgaXNQdW5jdHVhdGlvbkNoYXIgPSBwYXJzZXJDb25maWcuaXNQdW5jdHVhdGlvbkNoYXIgfHwgL1tcXFtcXF17fVxcKFxcKSw
234597XFw6XFwuXS8sXG4gICAgICBpc051bWJlckNoYXIgPSBwYXJzZXJDb25maWcuaXNOdW1iZXJDaGFyIHx8IC9cXGQvLFxuICAgICAgaXNPcGVyYXRvckNoYXIgPSBwYXJzZXJDb25maWcuaXNPcGVyYXRvckNoYXIgfHwgL1srXFwtKiYlPTw+IT98XFwvXS8sXG4gICAgICBlbmRTdGF0ZW1lbnQgPSBwYXJzZXJDb25maWcuZW5kU3RhdGVtZW50IHx8IC9eWzs6LF0kLztcblxuICB2YXIgY3VyUHVuYywgaXNEZWZLZXl3b3JkO1xuXG4gIGZ1bmN0aW9uIHRva2VuQmFzZShzdHJlYW0sIHN0YXRlKSB7XG4gICAgdmFyIGNoID0gc3RyZWFtLm5leHQoKTtcbiAgICBpZiAoaG9va3NbY2hdKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gaG9va3NbY2hdKHN0cmVhbSwgc3RhdGUpO1xuICAgICAgaWYgKHJlc3VsdCAhPT0gZmFsc2UpIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIGlmIChjaCA9PSAnXCInIHx8IGNoID09IFwiJ1wiKSB7XG4gICAgICBzdGF0ZS50b2tlbml6ZSA9IHRva2VuU3RyaW5nKGNoKTtcbiAgICAgIHJldHVybiBzdGF0ZS50b2tlbml6ZShzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gICAgaWYgKGlzUHVuY3R1YXRpb25DaGFyLnRlc3QoY2gpKSB7XG4gICAgICBjdXJQdW5jID0gY2g7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKGlzTnVtYmVyQ2hhci50ZXN0KGNoKSkge1xuICAgICAgc3RyZWFtLmVhdFdoaWxlKC9bXFx3XFwuXS8pO1xuICAgICAgcmV0dXJuIFwibnVtYmVyXCI7XG4gICAgfVxuICAgIGlmIChjaCA9PSBcIi9cIikge1xuICAgICAgaWYgKHN0cmVhbS5lYXQoXCIqXCIpKSB7XG4gICAgICAgIHN0YXRlLnRva2VuaXplID0gdG9rZW5Db21tZW50O1xuICAgICAgICByZXR1cm4gdG9rZW5Db21tZW50KHN0cmVhbSwgc3RhdGUpO1xuICAgICAgfVxuICAgICAgaWYgKHN0cmVhbS5lYXQoXCIvXCIpKSB7XG4gICAgICAgIHN0cmVhbS5za2lwVG9FbmQoKTtcbiAgICAgICAgcmV0dXJuIFwiY29tbWVudFwiO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNPcGVyYXRvckNoYXIudGVzdChjaCkpIHtcbiAgICAgIHN0cmVhbS5lYXRXaGlsZShpc09wZXJhdG9yQ2hhcik7XG4gICAgICByZXR1cm4gXCJvcGVyYXRvclwiO1xuICAgIH1cbiAgICBzdHJlYW0uZWF0V2hpbGUoL1tcXHdcXCRfXFx4YTEtXFx1ZmZmZl0vKTtcbiAgICBpZiAobmFtZXNwYWNlU2VwYXJhdG9yKSB3aGlsZSAoc3RyZWFtLm1hdGNoKG5hbWVzcGFjZVNlcGFyYXRvcikpXG4gICAgICBzdHJlYW0uZWF0V2hpbGUoL1tcXHdcXCRfXFx4YTEtXFx1ZmZmZl0vKTtcblxuICAgIHZhciBjdXIgPSBzdHJlYW0uY3VycmVudCgpO1xuICAgIGlmIChjb250YWlucyhrZXl3b3JkcywgY3VyKSkge1xuICAgICAgaWYgKGNvbnRhaW5zKGJsb2NrS2V5d29yZHMsIGN1cikpIGN1clB1bmMgPSBcIm5ld3N0YXRlbWVudFwiO1xuICAgICAgaWYgKGNvbnRhaW5zKGRlZktleXdvcmRzLCBjdXIpKSBpc0RlZktleXdvcmQgPSB0cnVlO1xuICAgICAgcmV0dXJuIFwia2V5d29yZFwiO1xuICAgIH1cbiAgICBpZiAoY29udGFpbnModHlwZXMsIGN1cikpIHJldHVybiBcInZhcmlhYmxlLTNcIjtcbiAgICBpZiAoY29udGFpbnMoYnVpbHRpbiwgY3VyKSkge1xuICAgICAgaWYgKGNvbnRhaW5zKGJsb2NrS2V5d29yZHMsIGN1cikpIGN1clB1bmMgPSBcIm5ld3N0YXRlbWVudFwiO1xuICAgICAgcmV0dXJuIFwiYnVpbHRpblwiO1xuICAgIH1cbiAgICBpZiAoY29udGFpbnMoYXRvbXMsIGN1cikpIHJldHVybiBcImF0b21cIjtcbiAgICByZXR1cm4gXCJ2YXJpYWJsZVwiO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9rZW5TdHJpbmcocXVvdGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oc3RyZWFtLCBzdGF0ZSkge1xuICAgICAgdmFyIGVzY2FwZWQgPSBmYWxzZSwgbmV4dCwgZW5kID0gZmFsc2U7XG4gICAgICB3aGlsZSAoKG5leHQgPSBzdHJlYW0ubmV4dCgpKSAhPSBudWxsKSB7XG4gICAgICAgIGlmIChuZXh0ID09IHF1b3RlICYmICFlc2NhcGVkKSB7ZW5kID0gdHJ1ZTsgYnJlYWs7fVxuICAgICAgICBlc2NhcGVkID0gIWVzY2FwZWQgJiYgbmV4dCA9PSBcIlxcXFxcIjtcbiAgICAgIH1cbiAgICAgIGlmIChlbmQgfHwgIShlc2NhcGVkIHx8IG11bHRpTGluZVN0cmluZ3MpKVxuICAgICAgICBzdGF0ZS50b2tlbml6ZSA9IG51bGw7XG4gICAgICByZXR1cm4gXCJzdHJpbmdcIjtcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gdG9rZW5Db21tZW50KHN0cmVhbSwgc3RhdGUpIHtcbiAgICB2YXIgbWF5YmVFbmQgPSBmYWxzZSwgY2g7XG4gICAgd2hpbGUgKGNoID0gc3RyZWFtLm5leHQoKSkge1xuICAgICAgaWYgKGNoID09IFwiL1wiICYmIG1heWJlRW5kKSB7XG4gICAgICAgIHN0YXRlLnRva2VuaXplID0gbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBtYXliZUVuZCA9IChjaCA9PSBcIipcIik7XG4gICAgfVxuICAgIHJldHVybiBcImNvbW1lbnRcIjtcbiAgfVxuXG4gIGZ1bmN0aW9uIENvbnRleHQoaW5kZW50ZWQsIGNvbHVtbiwgdHlwZSwgYWxpZ24sIHByZXYpIHtcbiAgICB0aGlzLmluZGVudGVkID0gaW5kZW50ZWQ7XG4gICAgdGhpcy5jb2x1bW4gPSBjb2x1bW47XG4gICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB0aGlzLmFsaWduID0gYWxpZ247XG4gICAgdGhpcy5wcmV2ID0gcHJldjtcbiAgfVxuICBmdW5jdGlvbiBpc1N0YXRlbWVudCh0eXBlKSB7XG4gICAgcmV0dXJuIHR5cGUgPT0gXCJzdGF0ZW1lbnRcIiB8fCB0eXBlID09IFwic3dpdGNoc3RhdGVtZW50XCIgfHwgdHlwZSA9PSBcIm5hbWVzcGFjZVwiO1xuICB9XG4gIGZ1bmN0aW9uIHB1c2hDb250ZXh0KHN0YXRlLCBjb2wsIHR5cGUpIHtcbiAgICB2YXIgaW5kZW50ID0gc3RhdGUuaW5kZW50ZWQ7XG4gICAgaWYgKHN0YXRlLmNvbnRleHQgJiYgaXNTdGF0ZW1lbnQoc3RhdGUuY29udGV4dC50eXBlKSAmJiAhaXNTdGF0ZW1lbnQodHlwZSkpXG4gICAgICBpbmRlbnQgPSBzdGF0ZS5jb250ZXh0LmluZGVudGVkO1xuICAgIHJldHVybiBzdGF0ZS5jb250ZXh0ID0gbmV3IENvbnRleHQoaW5kZW50LCBjb2wsIHR5cGUsIG51bGwsIHN0YXRlLmNvbnRleHQpO1xuICB9XG4gIGZ1bmN0aW9uIHBvcENvbnRleHQoc3RhdGUpIHtcbiAgICB2YXIgdCA9IHN0YXRlLmNvbnRleHQudHlwZTtcbiAgICBpZiAodCA9PSBcIilcIiB8fCB0ID09IFwiXVwiIHx8IHQgPT0gXCJ9XCIpXG4gICAgICBzdGF0ZS5pbmRlbnRlZCA9IHN0YXRlLmNvbnRleHQuaW5kZW50ZWQ7XG4gICAgcmV0dXJuIHN0YXRlLmNvbnRleHQgPSBzdGF0ZS5jb250ZXh0LnByZXY7XG4gIH1cblxuICBmdW5jdGlvbiB0eXBlQmVmb3JlKHN0cmVhbSwgc3Rh
23459dGUpIHtcbiAgICBpZiAoc3RhdGUucHJldlRva2VuID09IFwidmFyaWFibGVcIiB8fCBzdGF0ZS5wcmV2VG9rZW4gPT0gXCJ2YXJpYWJsZS0zXCIpIHJldHVybiB0cnVlO1xuICAgIGlmICgvXFxTKD86W14tIF0+fFsqXFxdXSlcXHMqJHxcXCokLy50ZXN0KHN0cmVhbS5zdHJpbmcuc2xpY2UoMCwgc3RyZWFtLnN0YXJ0KSkpIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNUb3BTY29wZShjb250ZXh0KSB7XG4gICAgZm9yICg7Oykge1xuICAgICAgaWYgKCFjb250ZXh0IHx8IGNvbnRleHQudHlwZSA9PSBcInRvcFwiKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGlmIChjb250ZXh0LnR5cGUgPT0gXCJ9XCIgJiYgY29udGV4dC5wcmV2LnR5cGUgIT0gXCJuYW1lc3BhY2VcIikgcmV0dXJuIGZhbHNlO1xuICAgICAgY29udGV4dCA9IGNvbnRleHQucHJldjtcbiAgICB9XG4gIH1cblxuICAvLyBJbnRlcmZhY2VcblxuICByZXR1cm4ge1xuICAgIHN0YXJ0U3RhdGU6IGZ1bmN0aW9uKGJhc2Vjb2x1bW4pIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRva2VuaXplOiBudWxsLFxuICAgICAgICBjb250ZXh0OiBuZXcgQ29udGV4dCgoYmFzZWNvbHVtbiB8fCAwKSAtIGluZGVudFVuaXQsIDAsIFwidG9wXCIsIGZhbHNlKSxcbiAgICAgICAgaW5kZW50ZWQ6IDAsXG4gICAgICAgIHN0YXJ0T2ZMaW5lOiB0cnVlLFxuICAgICAgICBwcmV2VG9rZW46IG51bGxcbiAgICAgIH07XG4gICAgfSxcblxuICAgIHRva2VuOiBmdW5jdGlvbihzdHJlYW0sIHN0YXRlKSB7XG4gICAgICB2Y
23459XIgY3R4ID0gc3RhdGUuY29udGV4dDtcbiAgICAgIGlmIChzdHJlYW0uc29sKCkpIHtcbiAgICAgICAgaWYgKGN0eC5hbGlnbiA9PSBudWxsKSBjdHguYWxpZ24gPSBmYWxzZTtcbiAgICAgICAgc3RhdGUuaW5kZW50ZWQgPSBzdHJlYW0uaW5kZW50YXRpb24oKTtcbiAgICAgICAgc3RhdGUuc3RhcnRPZkxpbmUgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHN0cmVhbS5lYXRTcGFjZSgpKSByZXR1cm4gbnVsbDtcbiAgICAgIGN1clB1bmMgPSBpc0RlZktleXdvcmQgPSBudWxsO1xuICAgICAgdmFyIHN0eWxlID0gKHN0YXRlLnRva2VuaXplIHx8IHRva2VuQmFzZSkoc3RyZWFtLCBzdGF0ZSk7XG4gICAgICBpZiAoc3R5bGUgPT0gXCJjb21tZW50XCIgfHwgc3R5bGUgPT0gXCJtZXRhXCIpIHJldHVybiBzdHlsZTtcbiAgICAgIGlmIChjdHguYWxpZ24gPT0gbnVsbCkgY3R4LmFsaWduID0gdHJ1ZTtcblxuICAgICAgaWYgKGVuZFN0YXRlbWVudC50ZXN0KGN1clB1bmMpKSB3aGlsZSAoaXNTdGF0ZW1lbnQoc3RhdGUuY29udGV4dC50eXBlKSkgcG9wQ29udGV4dChzdGF0ZSk7XG4gICAgICBlbHNlIGlmIChjdXJQdW5jID09IFwie1wiKSBwdXNoQ29udGV4dChzdGF0ZSwgc3RyZWFtLmNvbHVtbigpLCBcIn1cIik7XG4gICAgICBlbHNlIGlmIChjdXJQdW5jID09IFwiW1wiKSBwdXNoQ29udGV4dChzdGF0ZSwgc3RyZWFtLmNvbHVtbigpLCBcIl1cIik7XG4gICAgICBlbHNlIGlmIChjdXJQdW5jID09IFwiKFwiKSBwdXNoQ29udGV4dChzdGF0ZSwgc3RyZWFtLmNvbHVtbigpLCBcIilcIik7XG4gICAgICBlbHNlIGlmIChjdXJQdW5jID09IFwifVwiKSB7XG4gICAgICAgIHdoaWxlIChpc1N0YXRlbWVudChjdHgudHlwZSkpIGN0eCA9IHBvcENvbnRleHQoc3RhdGUpO1xuICAgICAgICBpZiAoY3R4LnR5cGUgPT0gXCJ9XCIpIGN0eCA9IHBvcENvbnRleHQoc3RhdGUpO1xuICAgICAgICB3aGlsZSAoaXNTdGF0ZW1lbnQoY3R4LnR5cGUpKSBjdHggPSBwb3BDb250ZXh0KHN0YXRlKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGN1clB1bmMgPT0gY3R4LnR5cGUpIHBvcENvbnRleHQoc3RhdGUpO1xuICAgICAgZWxzZSBpZiAoaW5kZW50U3RhdGVtZW50cyAmJlxuICAgICAgICAgICAgICAgKCgoY3R4LnR5cGUgPT0gXCJ9XCIgfHwgY3R4LnR5cGUgPT0gXCJ0b3BcIikgJiYgY3VyUHVuYyAhPSBcIjtcIikgfHxcbiAgICAgICAgICAgICAgICAoaXNTdGF0ZW1lbnQoY3R4LnR5cGUpICYmIGN1clB1bmMgPT0gXCJuZXdzdGF0ZW1lbnRcIikpKSB7XG4gICAgICAgIHZhciB0eXBlID0gXCJzdGF0ZW1lbnRcIjtcbiAgICAgICAgaWYgKGN1clB1bmMgPT0gXCJuZXdzdGF0ZW1lbnRcIiAmJiBpbmRlbnRTd2l0Y2ggJiYgc3RyZWFtLmN1cnJlbnQoKSA9PSBcInN3aXRjaFwiKVxuICAgICAgICAgIHR5cGUgPSBcInN3aXRjaHN0YXRlbWVudFwiO1xuICAgICAgICBlbHNlIGlmIChzdHlsZSA9PSBcImtleXdvcmRcIiAmJiBzdHJlYW0uY3VycmVudCgpID09IFwibmFtZXNwYWNlXCIpXG4gICAgICAgICAgdHlwZSA9IFwibmFtZXNwYWNlXCI7XG4gICAgICAgIHB1c2hDb250ZXh0KHN0YXRlLCBzdHJlYW0uY29sdW1uKCksIHR5cGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3R5bGUgPT0gXCJ2YXJpYWJsZVwiICYmXG4gICAgICAgICAgKChzdGF0ZS5wcmV2VG9rZW4gPT0gXCJkZWZcIiB8fFxuICAgICAgICAgICAgKHBhcnNlckNvbmZpZy50eXBlRmlyc3REZWZpbml0aW9ucyAmJiB0eXBlQmVmb3JlKHN0cmVhbSwgc3RhdGUpICYmXG4gICAgICAgICAgICAgaXNUb3BTY29wZShzdGF0ZS5jb250ZXh0KSAmJiBzdHJlYW0ubWF0Y2goL15cXHMqXFwoLywgZmFsc2UpKSkpKVxuICAgICAgICBzdHlsZSA9IFwiZGVmXCI7XG5cbiAgICAgIGlmIChob29rcy50b2tlbikge1xuICAgICAgICB2Y
23459XIgcmVzdWx0ID0gaG9va3MudG9rZW4oc3RyZWFtLCBzdGF0ZSwgc3R5bGUpO1xuICAgICAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHN0eWxlID0gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBpZiAoc3R5bGUgPT0gXCJkZWZcIiAmJiBwYXJzZXJDb25maWcuc3R5bGVEZWZzID09PSBmYWxzZSkgc3R5bGUgPSBcInZhcmlhYmxlXCI7XG5cbiAgICAgIHN0YXRlLnN0YXJ0T2ZMaW5lID0gZmFsc2U7XG4gICAgICBzdGF0ZS5wcmV2VG9rZW4gPSBpc0RlZktleXdvcmQgPyBcImRlZlwiIDogc3R5bGUgfHwgY3VyUHVuYztcbiAgICAgIHJldHVybiBzdHlsZTtcbiAgICB9LFxuXG4gICAgaW5kZW50OiBmdW5jdGlvbihzdGF0ZSwgdGV4dEFmdGVyKSB7XG4gICAgICBpZiAoc3RhdGUudG9rZW5pemUgIT0gdG9rZW5CYXNlICYmIHN0YXRlLnRva2VuaXplICE9IG51bGwpIHJldHVybiBDb2RlTWlycm9yLlBhc3M7XG4gICAgICB2YXIgY3R4ID0gc3RhdGUuY29udGV4dCwgZmlyc3RDaGFyID0gdGV4dEFmdGVyICYmIHRleHRBZnRlci5jaGFyQXQoMCk7XG4gICAgICBpZiAoaXNTdGF0ZW1lbnQoY3R4LnR5cGUpICYmIGZpcnN0Q2hhciA9PSBcIn1cIikgY3R4ID0gY3R4LnByZXY7XG4gICAgICBpZiAoaG9va3MuaW5kZW50KSB7XG4gICAgICAgIHZhciBob29rID0gaG9va3MuaW5kZW50KHN0YXRlLCBjdHgsIHRleHRBZnRlcik7XG4gICAgICAgIGlmICh0eXBlb2YgaG9vayA9PSBcIm51bWJlclwiKSByZXR1cm4gaG9va1xuICAgICAgfVxuICAgICAgdmFyIGNsb3NpbmcgPSBmaXJzdENoYXIgPT0gY3R4LnR5cGU7XG4gICAgICB2Y
23459XIgc3dpdGNoQmxvY2sgPSBjdHgucHJldiAmJiBjdHgucHJldi50eXBlID09IFwic3dpdGNoc3RhdGVtZW50XCI7XG4gICAgICBpZiAoaXNTdGF0ZW1lbnQoY3R4LnR5cGUpKVxuICAgICAgICByZXR1cm4gY3R4LmluZGVudGVkICsgKGZpcnN0Q2hhciA9PSBcIntcIiA/IDAgOiBzdGF0ZW1lbnRJbmRlbnRVbml0KTtcbiAgICAgIGlmIChjdHguYWxpZ24gJiYgKCFkb250QWxpZ25DYWxscyB8fCBjdHgudHlwZSAhPSBcIilcIikpXG4gICAgICAgIHJldHVybiBjdHguY29sdW1uICsgKGNsb3NpbmcgPyAwIDogMSk7XG4gICAgICBpZiAoY3R4LnR5cGUgPT0gXCIpXCIgJiYgIWNsb3NpbmcpXG4gICAgICAgIHJldHVybiBjdHguaW5kZW50ZWQgKyBzdGF0ZW1lbnRJbmRlbnRVbml0O1xuXG4gICAgICByZXR1cm4gY3R4LmluZGVudGVkICsgKGNsb3NpbmcgPyAwIDogaW5kZW50VW5pdCkgK1xuICAgICAgICAoIWNsb3NpbmcgJiYgc3dpdGNoQmxvY2sgJiYgIS9eKD86Y2FzZXxkZWZhdWx0KVxcYi8udGVzdCh0ZXh0QWZ0ZXIpID8gaW5kZW50VW5pdCA6IDApO1xuICAgIH0sXG5cbiAgICBlbGVjdHJpY0lucHV0OiBpbmRlbnRTd2l0Y2ggPyAvXlxccyooPzpjYXNlIC4qPzp8ZGVmYXVsdDp8XFx7XFx9P3xcXH0pJC8gOiAvXlxccypbe31dJC8sXG4gICAgYmxvY2tDb21tZW50U3RhcnQ6IFwiLypcIixcbiAgICBibG9ja0NvbW1lbnRFbmQ6IFwiKi9cIixcbiAgICBsaW5lQ29tbWVudDogXCIvL1wiLFxuICAgIGZvbGQ6IFwiYnJhY2VcIlxuICB9O1xufSk7XG5cbiAgZnVuY3Rpb24gd29yZHMoc3RyKSB7XG4gICAgdmFyIG9iaiA9IHt9LCB3b3JkcyA9IHN0ci5zcGxpdChcIiBcIik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB3b3Jkcy5sZW5ndGg7ICsraSkgb2JqW3dvcmRzW2ldXSA9IHRydWU7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuICBmdW5jdGlvbiBjb250YWlucyh3b3Jkcywgd29yZCkge1xuICAgIGlmICh0eXBlb2Ygd29yZHMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgcmV0dXJuIHdvcmRzKHdvcmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gd29yZHMucHJvcGVydHlJc0VudW1lcmFibGUod29yZCk7XG4gICAgfVxuICB9XG4gIHZhciBjS2V5d29yZHMgPSBcImF1dG8gaWYgYnJlYWsgY2FzZSByZWdpc3RlciBjb250aW51ZSByZXR1cm4gZGVmYXVsdCBkbyBzaXplb2YgXCIgK1xuICAgIFwic3RhdGljIGVsc2Ugc3RydWN0IHN3aXRjaCBleHRlcm4gdHlwZWRlZiBmbG9hdCB1bmlvbiBmb3IgXCIgK1xuICAgIFwiZ290byB3aGlsZSBlbnVtIGNvbnN0IHZvbGF0aWxlXCI7XG4gIHZhciBjVHlwZXMgPSBcImludCBsb25nIGNoYXIgc2hvcnQgZG91YmxlIGZsb2F0IHVuc2lnbmVkIHNpZ25lZCB2b2lkIHNpemVfdCBwdHJkaWZmX3RcIjtcblxuICBmdW5jdGlvbiBjcHBIb29rKHN0cmVhbSwgc3RhdGUpIHtcbiAgICBpZiAoIXN0YXRlLnN0YXJ0T2ZMaW5lKSByZXR1cm4gZmFsc2U7XG4gICAgZm9yICg7Oykge1xuICAgICAgaWYgKHN0cmVhbS5za2lwVG8oXCJcXFxcXCIpKSB7XG4gICAgICAgIHN0cmVhbS5uZXh0KCk7XG4gICAgICAgIGlmIChzdHJlYW0uZW9sKCkpIHtcbiAgICAgICAgICBzdGF0ZS50b2tlbml6ZSA9IGNwcEhvb2s7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0cmVhbS5za2lwVG9FbmQoKTtcbiAgICAgICAgc3RhdGUudG9rZW5pemUgPSBudWxsO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIFwibWV0YVwiO1xuICB9XG5cbiAgZnVuY3Rpb24gcG9pbnRlckhvb2soX3N0cmVhbSwgc3RhdGUpIHtcbiAgICBpZiAoc3RhdGUucHJldlRva2VuID09IFwidmFyaWFibGUtM1wiKSByZXR1cm4gXCJ2YXJpYWJsZS0zXCI7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gY3BwMTRMaXRlcmFsKHN0cmVhbSkge1xuICAgIHN0cmVhbS5lYXRXaGlsZSgvW1xcd1xcLiddLyk7XG4gICAgcmV0dXJuIFwibnVtYmVyXCI7XG4gIH1cblxuICBmdW5jdGlvbiBjcHAxMVN0cmluZ0hvb2soc3RyZWFtLCBzdGF0ZSkge1xuICAgIHN0cmVhbS5iYWNrVXAoMSk7XG4gICAgLy8gUmF3IHN0cmluZ3MuXG4gICAgaWYgKHN0cmVhbS5tYXRjaCgvKFJ8dThSfHVSfFVSfExSKS8pKSB7XG4gICAgICB2Y
23459XIgbWF0Y2ggPSBzdHJlYW0ubWF0Y2goL1wiKFteXFxzXFxcXCgpXXswLDE2fSlcXCgvKTtcbiAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgc3RhdGUuY3BwMTFSYXdTdHJpbmdEZWxpbSA9IG1hdGNoWzFdO1xuICAgICAgc3RhdGUudG9rZW5pemUgPSB0b2tlblJhd1N0cmluZztcbiAgICAgIHJldHVybiB0b2tlblJhd1N0cmluZyhzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gICAgLy8gVW5pY29kZSBzdHJpbmdzL2NoYXJzLlxuICAgIGlmIChzdHJlYW0ubWF0Y2goLyh1OHx1fFV8TCkvKSkge1xuICAgICAgaWYgKHN0cmVhbS5tYXRjaCgvW1wiJ10vLCAvKiBlYXQgKi8gZmFsc2UpKSB7XG4gICAgICAgIHJldHVybiBcInN0cmluZ1wiO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvLyBJZ25vcmUgdGhpcyBob29rLlxuICAgIHN0cmVhbS5uZXh0KCk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gY3BwTG9va3NMaWtlQ29uc3RydWN0b3Iod29yZCkge1xuICAgIHZhciBsYXN0VHdvID0gLyhcXHcrKTo6KFxcdyspJC8uZXhlYyh3b3JkKTtcbiAgICByZXR1cm4gbGFzdFR3byAmJiBsYXN0VHdvWzFdID09IGxhc3RUd29bMl07XG4gIH1cblxuICAvLyBDIy1zdHlsZSBzdHJpbmdzIHdoZXJlIFwiXCIgZXNjYXBlcyBhIHF1b3RlLlxuICBmdW5jdGlvbiB0b2tlbkF0U3RyaW5nKHN0cmVhbSwgc3RhdGUpIHtcbiAgICB2YXIgbmV4dDtcbiAgICB3aGlsZSAoKG5leHQgPSBzdHJlYW0ubmV4dCgpKSAhPSBudWxsKSB7XG4gICAgICBpZiAobmV4dCA9PSAnXCInICYmICFzdHJlYW0uZWF0KCdcIicpKSB7XG4gICAgICAgIHN0YXRlLnRva2VuaXplID0gbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBcInN0cmluZ1wiO1xuICB9XG5cbiAgLy8gQysrMTEgcmF3IHN0cmluZyBsaXRlcmFsIGlzIDxwcmVmaXg+XCI8ZGVsaW0+KCBhbnl0aGluZyApPGRlbGltPlwiLCB3aGVyZVxuICAvLyA8ZGVsaW0+IGNhbiBiZSBhIHN0cmluZyB1cCB0byAxNiBjaGFyYWN0ZXJzIGxvbmcuXG4gIGZ1bmN0aW9uIHRva2VuUmF3U3RyaW5nKHN0cmVhbSwgc3RhdGUpIHtcbiAgICAvLyBFc2NhcGUgY2hhcmFjdGVycyB0aGF0IGhhdmUgc3BlY2lhbCByZWdleCBtZWFuaW5ncy5cbiAgICB2YXIgZGVsaW0gPSBzdGF0ZS5jcHAxMVJhd1N0cmluZ0RlbGltLnJlcGxhY2UoL1teXFx3XFxzXS9nLCAnXFxcXCQmJyk7XG4gICAgdmFyIG1hdGNoID0gc3RyZWFtLm1hdGNoKG5ldyBSZWdFeHAoXCIuKj9cXFxcKVwiICsgZGVsaW0gKyAnXCInKSk7XG4gICAgaWYgKG1hdGNoKVxuICAgICAgc3RhdGUudG9rZW5pemUgPSBudWxsO1xuICAgIGVsc2VcbiAgICAgIHN0cmVhbS5za2lwVG9FbmQoKTtcbiAgICByZXR1cm4gXCJzdHJpbmdcIjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlZihtaW1lcywgbW9kZSkge1xuICAgIGlmICh0eXBlb2YgbWltZXMgPT0gXCJzdHJpbmdcIikgbWltZXMgPSBbbWltZXNdO1xuICAgIHZhciB3b3JkcyA9IFtdO1xuICAgIGZ1bmN0aW9uIGFkZChvYmopIHtcbiAgICAgIGlmIChvYmopIGZvciAodmFyIHByb3AgaW4gb2JqKSBpZiAob2JqLmhhc093blByb3BlcnR5KHByb3ApKVxuICAgICAgICB3b3Jkcy5wdXNoKHByb3ApO1xuICAgIH1cbiAgICBhZGQobW9kZS5rZXl3b3Jkcyk7XG4gICAgYWRkKG1vZGUudHlwZXMpO1xuICAgIGFkZChtb2RlLmJ1aWx0aW4pO1xuICAgIGFkZChtb2RlLmF0b21zKTtcbiAgICBpZiAod29yZHMubGVuZ3RoKSB7XG4gICAgICBtb2RlLmhlbHBlclR5cGUgPSBtaW1lc1swXTtcbiAgICAgIENvZGVNaXJyb3IucmVnaXN0ZXJIZWxwZXIoXCJoaW50V29yZHNcIiwgbWltZXNbMF0sIHdvcmRzKTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1pbWVzLmxlbmd0aDsgKytpKVxuICAgICAgQ29kZU1pcnJvci5kZWZpbmVNSU1FKG1pbWVzW2ldLCBtb2RlKTtcbiAgfVxuXG4gIGRlZihbXCJ0ZXh0L3gtY3NyY1wiLCBcInRleHQveC1jXCIsIFwidGV4dC94LWNoZHJcIl0sIHtcbiAgICBuYW1lOiBcImNsaWtlXCIsXG4gICAga2V5d29yZHM6IHdvcmRzKGNLZXl3b3JkcyksXG4gICAgdHlwZXM6IHdvcmRzKGNUeXBlcyArIFwiIGJvb2wgX0NvbXBsZXggX0Jvb2wgZmxvYXRfdCBkb3VibGVfdCBpbnRwdHJfdCBpbnRtYXhfdCBcIiArXG4gICAgICAgICAgICAgICAgIFwiaW50OF90IGludDE2X3QgaW50MzJfdCBpbnQ2NF90IHVpbnRwdHJfdCB1aW50bWF4X3QgdWludDhfdCB1aW50MTZfdCBcIiArXG4gICAgICAgICAgICAgICAgIFwidWludDMyX3QgdWludDY0X3RcIiksXG4gICAgYmxvY2tLZXl3b3Jkczogd29yZHMoXCJjYXNlIGRvIGVsc2UgZm9yIGlmIHN3aXRjaCB3aGlsZSBzdHJ1Y3RcIiksXG4gICAgZGVmS2V5d29yZHM6IHdvcmRzKFwic3RydWN0XCIpLFxuICAgIHR5cGVGaXJzdERlZmluaXRpb25zOiB0cnVlLFxuICAgIGF0b21zOiB3b3JkcyhcIm51bGwgdHJ1ZSBmYWxzZVwiKSxcbiAgICBob29rczoge1wiI1wiOiBjcHBIb29rLCBcIipcIjogcG9pbnRlckhvb2t9LFxuICAgIG1vZGVQcm9wczoge2ZvbGQ6IFtcImJyYWNlXCIsIFwiaW5jbHVkZVwiXX1cbiAgfSk7XG5cbiAgZGVmKFtcInRleHQveC1jKytzcmNcIiwgXCJ0ZXh0L3gtYysraGRyXCJdLCB7XG4gICAgbmFtZTogXCJjbGlrZVwiLFxuICAgIGtleXdvcmRzOiB3b3JkcyhjS2V5d29yZHMgKyBcIiBhc20gZHluYW1pY19jYXN0IG5hbWVzcGFjZSByZWludGVycHJldF9jYXN0IHRyeSBleHBsaWNpdCBuZXcgXCIgK1xuICAgICAgICAgICAgICAgICAgICBcInN0YXRpY19jYXN0IHR5cGVpZCBjYXRjaCBvcGVyYXRvciB0ZW1wbGF0ZSB0eXBlbmFtZSBjbGFzcyBmcmllbmQgcHJpdmF0ZSBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwidGhpcyB1c2luZyBjb25zdF9jYXN0IGlubGluZSBwdWJsaWMgdGhyb3cgdmlydHVhbCBkZWxldGUgbXV0YWJsZSBwcm90ZWN0ZWQgXCIgK1xuICAgICAgICAgICAgICAgICAgICBcImFsaWduYXMgYWxpZ25vZiBjb25zdGV4cHIgZGVjbHR5cGUgbnVsbHB0ciBub2V4Y2VwdCB0aHJlYWRfbG9jYWwgZmluYWwgXCIgK1xuICAgICAgICAgICAgICAgICAgICBcInN0YXRpY19hc3NlcnQgb3ZlcnJpZGVcIiksXG4gICAgdHlwZXM6IHdvcmRzKGNUeXBlcyArIFwiIGJvb2wgd2NoYXJfdFwiKSxcbiAgICBibG9ja0tleXdvcmRzOiB3b3JkcyhcImNhdGNoIGNsYXNzIGRvIGVsc2UgZmluYWxseSBmb3IgaWYgc3RydWN0IHN3aXRjaCB0cnkgd2hpbGVcIiksXG4gICAgZGVmS2V5d29yZHM6IHdvcmRzKFwiY2xhc3MgbmFtZXNwYWNlIHN0cnVjdCBlbnVtIHVuaW9uXCIpLFxuICAgIHR5cGVGaXJzdERlZmluaXRpb25zOiB0cnVlLFxuICAgIGF0b21zOiB3b3JkcyhcInRydWUgZmFsc2UgbnVsbFwiKSxcbiAgICBob29rczoge1xuICAgICAgXCIjXCI6IGNwcEhvb2ssXG4gICAgICBcIipcIjogcG9pbnRlckhvb2ssXG4gICAgICBcInVcIjogY3BwMTFTdHJpbmdIb29rLF
23459xuICAgICAgXCJVXCI6IGNwcDExU3RyaW5nSG9vayxcbiAgICAgIFwiTFwiOiBjcHAxMVN0cmluZ0hvb2ssXG4gICAgICBcIlJcIjogY3BwMTFTdHJpbmdIb29rLFxuICAgICAgXCIwXCI6IGNwcDE0TGl0ZXJhbCxcbiAgICAgIFwiMVwiOiBjcHAxNExpdGVyYWwsXG4gICAgICBcIjJcIjogY3BwMTRMaXRlcmFsLFxuICAgICAgXCIzXCI6IGNwcDE0TGl0ZXJhbCxcbiAgICAgIFwiNFwiOiBjcHAxNExpdGVyYWwsXG4gICAgICBcIjVcIjogY3BwMTRMaXRlcmFsLFxuICAgICAgXCI2XCI6IGNwcDE0TGl0ZXJhbCxcbiAgICAgIFwiN1wiOiBjcHAxNExpdGVyYWwsXG4gICAgICBcIjhcIjogY3BwMTRMaXRlcmFsLFxuICAgICAgXCI5XCI6IGNwcDE0TGl0ZXJhbCxcbiAgICAgIHRva2VuOiBmdW5jdGlvbihzdHJlYW0sIHN0YXRlLCBzdHlsZSkge1xuICAgICAgICBpZiAoc3R5bGUgPT0gXCJ2YXJpYWJsZVwiICYmIHN0cmVhbS5wZWVrKCkgPT0gXCIoXCIgJiZcbiAgICAgICAgICAgIChzdGF0ZS5wcmV2VG9rZW4gPT0gXCI7XCIgfHwgc3RhdGUucHJldlRva2VuID09IG51bGwgfHxcbiAgICAgICAgICAgICBzdGF0ZS5wcmV2VG9rZW4gPT0gXCJ9XCIpICYmXG4gICAgICAgICAgICBjcHBMb29rc0xpa2VDb25zdHJ1Y3RvcihzdHJlYW0uY3VycmVudCgpKSlcbiAgICAgICAgICByZXR1cm4gXCJkZWZcIjtcbiAgICAgIH1cbiAgICB9LFxuICAgIG5hbWVzcGFjZVNlcGFyYXRvcjogXCI6OlwiLFxuICAgIG1vZGVQcm9wczoge2ZvbGQ6IFtcImJyYWNlXCIsIFwiaW5jbHVkZVwiXX1cbiAgfSk7XG5cbiAgZGVmKFwidGV4dC94LWphdmFcIiwge1xuICAgIG5hbWU6IFwiY2xpa2VcIixcbiAgICBrZXl3b3Jkczogd29yZHMoXCJhYnN0cmFjdCBhc3NlcnQgYnJlYWsgY2FzZSBjYXRjaCBjbGFzcyBjb25zdCBjb250aW51ZSBkZWZhdWx0IFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJkbyBlbHNlIGVudW0gZXh0ZW5kcyBmaW5hbCBmaW5hbGx5IGZsb2F0IGZvciBnb3RvIGlmIGltcGxlbWVudHMgaW1wb3J0IFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJpbnN0YW5jZW9mIGludGVyZmFjZSBuYXRpdmUgbmV3IHBhY2thZ2UgcHJpdmF0ZSBwcm90ZWN0ZWQgcHVibGljIFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJyZXR1cm4gc3RhdGljIHN0cmljdGZwIHN1cGVyIHN3aXRjaCBzeW5jaHJvbml6ZWQgdGhpcyB0aHJvdyB0aHJvd3MgdHJhbnNpZW50IFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJ0cnkgdm9sYXRpbGUgd2hpbGVcIiksXG4gICAgdHlwZXM6IHdvcmRzKFwiYnl0ZSBzaG9ydCBpbnQgbG9uZyBmbG9hdCBkb3VibGUgYm9vbGVhbiBjaGFyIHZvaWQgQm9vbGVhbiBCeXRlIENoYXJhY3RlciBEb3VibGUgRmxvYXQgXCIgK1xuICAgICAgICAgICAgICAgICBcIkludGVnZXIgTG9uZyBOdW1iZXIgT2JqZWN0IFNob3J0IFN0cmluZyBTdHJpbmdCdWZmZXIgU3RyaW5nQnVpbGRlciBWb2lkXCIpLFxuICAgIGJsb2NrS2V5d29yZHM6IHdvcmRzKFwiY2F0Y2ggY2xhc3MgZG8gZWxzZSBmaW5hbGx5IGZvciBpZiBzd2l0Y2ggdHJ5IHdoaWxlXCIpLFxuICAgIGRlZktleXdvcmRzOiB3b3JkcyhcImNsYXNzIGludGVyZmFjZSBwYWNrYWdlIGVudW1cIiksXG4gICAgdHlwZUZpcnN0RGVmaW5pdGlvbnM6IHRydWUsXG4gICAgYXRvbXM6IHdvcmRzKFwidHJ1ZSBmYWxzZSBudWxsXCIpLFxuICAgIGVuZFN0YXRlbWVudDogL15bOzpdJC8sXG4gICAgaG9va3M6IHtcbiAgICAgIFwiQFwiOiBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgICAgc3RyZWFtLmVhdFdoaWxlKC9bXFx3XFwkX10vKTtcbiAgICAgICAgcmV0dXJuIFwibWV0YVwiO1xuICAgICAgfVxuICAgIH0sXG4gICAgbW9kZVByb3BzOiB7Zm9sZDogW1wiYnJhY2VcIiwgXCJpbXBvcnRcIl19XG4gIH0pO1xuXG4gIGRlZihcInRleHQveC1jc2hhcnBcIiwge1xuICAgIG5hbWU6IFwiY2xpa2VcIixcbiAgICBrZXl3b3Jkczogd29yZHMoXCJhYnN0cmFjdCBhcyBhc3luYyBhd2FpdCBiYXNlIGJyZWFrIGNhc2UgY2F0Y2ggY2hlY2tlZCBjbGFzcyBjb25zdCBjb250aW51ZVwiICtcbiAgICAgICAgICAgICAgICAgICAgXCIgZGVmYXVsdCBkZWxlZ2F0ZSBkbyBlbHNlIGVudW0gZXZlbnQgZXhwbGljaXQgZXh0ZXJuIGZpbmFsbHkgZml4ZWQgZm9yXCIgK1xuICAgICAgICAgICAgICAgICAgICBcIiBmb3JlYWNoIGdvdG8gaWYgaW1wbGljaXQgaW4gaW50ZXJmYWNlIGludGVybmFsIGlzIGxvY2sgbmFtZXNwYWNlIG5ld1wiICtcbiAgICAgICAgICAgICAgICAgICAgXCIgb3BlcmF0b3Igb3V0IG92ZXJyaWRlIHBhcmFtcyBwcml2YXRlIHByb3RlY3RlZCBwdWJsaWMgcmVhZG9ubHkgcmVmIHJldHVybiBzZWFsZWRcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiIHNpemVvZiBzdGFja2FsbG9jIHN0YXRpYyBzdHJ1Y3Qgc3dpdGNoIHRoaXMgdGhyb3cgdHJ5IHR5cGVvZiB1bmNoZWNrZWRcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiIHVuc2FmZSB1c2luZyB2aXJ0dWFsIHZvaWQgdm9sYXRpbGUgd2hpbGUgYWRkIGFsaWFzIGFzY2VuZGluZyBkZXNjZW5kaW5nIGR5bmFtaWMgZnJvbSBnZXRcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiIGdsb2JhbCBncm91cCBpbnRvIGpvaW4gbGV0IG9yZGVyYnkgcGFydGlhbCByZW1vdmUgc2VsZWN0IHNldCB2YWx1ZSB2YXIgeWllbGRcIiksXG4gICAgdHlwZXM6IHdvcmRzKFwiQWN0aW9uIEJvb2xlYW4gQnl0ZSBDaGFyIERhdGVUaW1lIERhdGVUaW1lT2Zmc2V0IERlY2ltYWwgRG91YmxlIEZ1bmNcIiArXG4gICAgICAgICAgICAgICAgIFwiIEd1aWQgSW50MTYgSW50MzIgSW50NjQgT2JqZWN0IFNCeXRlIFNpbmdsZSBTdHJpbmcgVGFzayBUaW1lU3BhbiBVSW50MTYgVUludDMyXCIgK1xuICAgICAgICAgICAgICAgICBcIiBVSW50NjQgYm9vbCBieXRlIGNoYXIgZGVjaW1hbCBkb3VibGUgc2hvcnQgaW50IGxvbmcgb2JqZWN0XCIgICtcbiAgICAgICAgICAgICAgICAgXCIgc2J5dGUgZmxvYXQgc3RyaW5nIHVzaG9ydCB1aW50IHVsb25nXCIpLFxuICAgIGJsb2NrS2V5d29yZHM6IHdvcmRzKFwiY2F0Y2ggY2xhc3MgZG8gZWxzZSBmaW5hbGx5IGZvciBmb3JlYWNoIGlmIHN0cnVjdCBzd2l0Y2ggdHJ5IHdoaWxlXCIpLFxuICAgIGRlZktleXdvcmRzOiB3b3JkcyhcImNsYXNzIGludGVyZmFjZSBuYW1lc3BhY2Ugc3RydWN0IHZhclwiKSxcbiAgICB0eX
23459BlRmlyc3REZWZpbml0aW9uczogdHJ1ZSxcbiAgICBhdG9tczogd29yZHMoXCJ0cnVlIGZhbHNlIG51bGxcIiksXG4gICAgaG9va3M6IHtcbiAgICAgIFwiQFwiOiBmdW5jdGlvbihzdHJlYW0sIHN0YXRlKSB7XG4gICAgICAgIGlmIChzdHJlYW0uZWF0KCdcIicpKSB7XG4gICAgICAgICAgc3RhdGUudG9rZW5pemUgPSB0b2tlbkF0U3RyaW5nO1xuICAgICAgICAgIHJldHVybiB0b2tlbkF0U3RyaW5nKHN0cmVhbSwgc3RhdGUpO1xuICAgICAgICB9XG4gICAgICAgIHN0cmVhbS5lYXRXaGlsZSgvW1xcd1xcJF9dLyk7XG4gICAgICAgIHJldHVybiBcIm1ldGFcIjtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIHRva2VuVHJpcGxlU3RyaW5nKHN0cmVhbSwgc3RhdGUpIHtcbiAgICB2YXIgZXNjYXBlZCA9IGZhbHNlO1xuICAgIHdoaWxlICghc3RyZWFtLmVvbCgpKSB7XG4gICAgICBpZiAoIWVzY2FwZWQgJiYgc3RyZWFtLm1hdGNoKCdcIlwiXCInKSkge1xuICAgICAgICBzdGF0ZS50b2tlbml6ZSA9IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZXNjYXBlZCA9IHN0cmVhbS5uZXh0KCkgPT0gXCJcXFxcXCIgJiYgIWVzY2FwZWQ7XG4gICAgfVxuICAgIHJldHVybiBcInN0cmluZ1wiO1xuICB9XG5cbiAgZGVmKFwidGV4dC94LXNjYWxhXCIsIHtcbiAgICBuYW1lOiBcImNsaWtlXCIsXG4gICAga2V5d29yZHM6IHdvcmRzKFxuXG4gICAgICAvKiBzY2FsYSAqL1xuICAgICAgXCJhYnN0cmFjdCBjYXNlIGNhdGNoIGNsYXNzIGRlZiBkbyBlbHNlIGV4dGVuZHMgZmluYWwgZmluYWxseSBmb3IgZm9yU29tZSBpZiBcIiArXG4gICAgICBcImltcGxpY2l0IGltcG9ydCBsYXp5IG1hdGNoIG5ldyBudWxsIG9iamVjdCBvdmVycmlkZSBwYWNrYWdlIHByaXZhdGUgcHJvdGVjdGVkIHJldHVybiBcIiArXG4gICAgICBcInNlYWxlZCBzdXBlciB0aGlzIHRocm93IHRyYWl0IHRyeSB0eXBlIHZhbCB2YXIgd2hpbGUgd2l0aCB5aWVsZCBfIDogPSA9PiA8LSA8OiBcIiArXG4gICAgICBcIjwlID46ICMgQCBcIiArXG5cbiAgICAgIC8qIHBhY2thZ2Ugc2NhbGEgKi9cbiAgICAgIFwiYXNzZXJ0IGFzc3VtZSByZXF1aXJlIHByaW50IHByaW50bG4gcHJpbnRmIHJlYWRMaW5lIHJlYWRCb29sZWFuIHJlYWRCeXRlIHJlYWRTaG9ydCBcIiArXG4gICAgICBcInJlYWRDaGFyIHJlYWRJbnQgcmVhZExvbmcgcmVhZEZsb2F0IHJlYWREb3VibGUgXCIgK1xuXG4gICAgICBcIjo6ICM6OiBcIlxuICAgICksXG4gICAgdHlwZXM6IHdvcmRzKFxuICAgICAgXCJBbnlWYWwgQXBwIEFwcGxpY2F0aW9uIEFycmF5IEJ1ZmZlcmVkSXRlcmF0b3IgQmlnRGVjaW1hbCBCaWdJbnQgQ2hhciBDb25zb2xlIEVpdGhlciBcIiArXG4gICAgICBcIkVudW1lcmF0aW9uIEVxdWl2IEVycm9yIEV4Y2VwdGlvbiBGcmFjdGlvbmFsIEZ1bmN0aW9uIEluZGV4ZWRTZXEgSW50ZWdyYWwgSXRlcmFibGUgXCIgK1xuICAgICAgXCJJdGVyYXRvciBMaXN0IE1hcCBOdW1lcmljIE5pbCBOb3ROdWxsIE9wdGlvbiBPcmRlcmVkIE9yZGVyaW5nIFBhcnRpYWxGdW5jdGlvbiBQYXJ0aWFsT3JkZXJpbmcgXCIgK1xuICAgICAgXCJQcm9kdWN0IFByb3h5IFJhbmdlIFJlc3BvbmRlciBTZXEgU2VyaWFsaXphYmxlIFNldCBTcGVjaWFsaXphYmxlIFN0cmVhbSBTdHJpbmdCdWlsZGVyIFwiICtcbiAgICAgIFwiU3RyaW5nQ29udGV4dCBTeW1ib2wgVGhyb3dhYmxlIFRyYXZlcnNhYmxlIFRyYXZlcnNhYmxlT25jZSBUdXBsZSBVbml0IFZlY3RvciBcIiArXG5cbiAgICAgIC8qIHBhY2thZ2UgamF2YS5sYW5nICovXG4gICAgICBcIkJvb2xlYW4gQnl0ZSBDaGFyYWN0ZXIgQ2hhclNlcXVlbmNlIENsYXNzIENsYXNzTG9hZGVyIENsb25lYWJsZSBDb21wYXJhYmxlIFwiICtcbiAgICAgIFwiQ29tcGlsZXIgRG91YmxlIEV4Y2VwdGlvbiBGbG9hdCBJbnRlZ2VyIExvbmcgTWF0aCBOdW1iZXIgT2JqZWN0IFBhY2thZ2UgUGFpciBQcm9jZXNzIFwiICtcbiAgICAgIFwiUnVudGltZSBSdW5uYWJsZSBTZWN1cml0eU1hbmFnZXIgU2hvcnQgU3RhY2tUcmFjZUVsZW1lbnQgU3RyaWN0TWF0aCBTdHJpbmcgXCIgK1xuICAgICAgXCJTdHJpbmdCdWZmZXIgU3lzdGVtIFRocmVhZCBUaHJlYWRHcm91cCBUaHJlYWRMb2NhbCBUaHJvd2FibGUgVHJpcGxlIFZvaWRcIlxuICAgICksXG4gICAgbXVsdGlMaW5lU3RyaW5nczogdHJ1ZSxcbiAgICBibG9ja0tleXdvcmRzOiB3b3JkcyhcImNhdGNoIGNsYXNzIGRvIGVsc2UgZmluYWxseSBmb3IgZm9yU29tZSBpZiBtYXRjaCBzd2l0Y2ggdHJ5IHdoaWxlXCIpLFxuICAgIGRlZktleXdvcmRzOiB3b3JkcyhcImNsYXNzIGRlZiBvYmplY3QgcGFja2FnZSB0cmFpdCB0eXBlIHZhbCB2YXJcIiksXG4gICAgYXRvbXM6IHdvcmRzKFwidHJ1ZSBmYWxzZSBudWxsXCIpLFxuICAgIGluZGVudFN0YXRlbWVudHM6IGZhbHNlLFxuICAgIGluZGVudFN3aXRjaDogZmFsc2UsXG4gICAgaG9va3M6IHtcbiAgICAgIFwiQFwiOiBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgICAgc3RyZWFtLmVhdFdoaWxlKC9bXFx3XFwkX10vKTtcbiAgICAgICAgcmV0dXJuIFwibWV0YVwiO1xuICAgICAgfSxcbiAgICAgICdcIic6IGZ1bmN0aW9uKHN0cmVhbSwgc3RhdGUpIHtcbiAgICAgICAgaWYgKCFzdHJlYW0ubWF0Y2goJ1wiXCInKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBzdGF0ZS50b2tlbml6ZSA9IHRva2VuVHJpcGxlU3RyaW5nO1xuICAgICAgICByZXR1cm4gc3RhdGUudG9rZW5pemUoc3RyZWFtLCBzdGF0ZSk7XG4gICAgICB9LFxuICAgICAgXCInXCI6IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgICBzdHJlYW0uZWF0V2hpbGUoL1tcXHdcXCRfXFx4YTEtXFx1ZmZmZl0vKTtcbiAgICAgICAgcmV0dXJuIFwiYXRvbVwiO1xuICAgICAgfVxuICAgIH0sXG4gICAgbW9kZVByb3BzOiB7Y2xvc2VCcmFja2V0czoge3RyaXBsZXM6ICdcIid9fVxuICB9KTtcblxuICBkZWYoXCJ0ZXh0L3gta290bGluXCIsIHtcbiAgICBuYW1lOiBcImNsaWtlXCIsXG4gICAga2V5d29yZHM6IHdvcmRzKFxuICAgICAgLyprZXl3b3JkcyovXG4gICAgICBcInBhY2thZ2UgYXMgdHlwZWFsaWFzIGNsYXNzIGludGVyZmFjZSB0aGlzIHN1cGVyIHZhbCBcIiArXG4gICAgICBcInZhciBmdW4gZm9yIGlzIGluIFRoaXMgdGhyb3cgcmV0dXJuIFwiICtcbiAgICAgIFwiYnJlYWsgY29udGludWUgb2JqZWN0IGlmIGVsc2Ugd2h
23459pbGUgZG8gdHJ5IHdoZW4gIWluICFpcyBhcz9cIiArXG5cbiAgICAgIC8qc29mdCBrZXl3b3JkcyovXG4gICAgICBcImZpbGUgaW1wb3J0IHdoZXJlIGJ5IGdldCBzZXQgYWJzdHJhY3QgZW51bSBvcGVuIGlubmVyIG92ZXJyaWRlIHByaXZhdGUgcHVibGljIGludGVybmFsIFwiICtcbiAgICAgIFwicHJvdGVjdGVkIGNhdGNoIGZpbmFsbHkgb3V0IGZpbmFsIHZhcmFyZyByZWlmaWVkIGR5bmFtaWMgY29tcGFuaW9uIGNvbnN0cnVjdG9yIGluaXQgXCIgK1xuICAgICAgXCJzZWFsZWQgZmllbGQgcHJvcGVydHkgcmVjZWl2ZXIgcGFyYW0gc3BhcmFtIGxhdGVpbml0IGRhdGEgaW5saW5lIG5vaW5saW5lIHRhaWxyZWMgXCIgK1xuICAgICAgXCJleHRlcm5hbCBhbm5vdGF0aW9uIGNyb3NzaW5saW5lXCJcbiAgICApLFxuICAgIHR5cGVzOiB3b3JkcyhcbiAgICAgIC8qIHBhY2thZ2UgamF2YS5sYW5nICovXG4gICAgICBcIkJvb2xlYW4gQnl0ZSBDaGFyYWN0ZXIgQ2hhclNlcXVlbmNlIENsYXNzIENsYXNzTG9hZGVyIENsb25lYWJsZSBDb21wYXJhYmxlIFwiICtcbiAgICAgIFwiQ29tcGlsZXIgRG91YmxlIEV4Y2VwdGlvbiBGbG9hdCBJbnRlZ2VyIExvbmcgTWF0aCBOdW1iZXIgT2JqZWN0IFBhY2thZ2UgUGFpciBQcm9jZXNzIFwiICtcbiAgICAgIFwiUnVudGltZSBSdW5uYWJsZSBTZWN1cml0eU1hbmFnZXIgU2hvcnQgU3RhY2tUcmFjZUVsZW1lbnQgU3RyaWN0TWF0aCBTdHJpbmcgXCIgK1xuICAgICAgXCJTdHJpbmdCdWZmZXIgU3lzdGVtIFRocmVhZCBUaHJlYWRHcm91cCBUaHJlYWRMb2NhbCBUaHJvd2FibGUgVHJpcGxlIFZvaWRcIlxuICAgICksXG4gICAgbXVsdGlMaW5lU3RyaW5nczogdHJ1ZSxcbiAgICBibG9ja0tleXdvcmRzOiB3b3JkcyhcImNhdGNoIGNsYXNzIGRvIGVsc2UgZmluYWxseSBmb3IgaWYgd2hlcmUgdHJ5IHdoaWxlIGVudW1cIiksXG4gICAgZGVmS2V5d29yZHM6IHdvcmRzKFwiY2xhc3MgdmFsIHZhciBvYmplY3QgcGFja2FnZSBpbnRlcmZhY2UgZnVuXCIpLFxuICAgIGF0b21zOiB3b3JkcyhcInRydWUgZmFsc2UgbnVsbCB0aGlzXCIpLFxuICAgIG1vZGVQcm9wczoge2Nsb3NlQnJhY2tldHM6IHt0cmlwbGVzOiAnXCInfX1cbiAgfSk7XG5cbiAgZGVmKFtcIngtc2hhZGVyL3gtdmVydGV4XCIsIFwieC1zaGFkZXIveC1mcmFnbWVudFwiXSwge1xuICAgIG5hbWU6IFwiY2xpa2VcIixcbiAgICBrZXl3b3Jkczogd29yZHMoXCJzYW1wbGVyMU
23459Qgc2FtcGxlcjJEIHNhbXBsZXIzRCBzYW1wbGVyQ3ViZSBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwic2FtcGxlcjFEU2hhZG93IHNhbXBsZXIyRFNoYWRvdyBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiY29uc3QgYXR0cmlidXRlIHVuaWZvcm0gdmFyeWluZyBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiYnJlYWsgY29udGludWUgZGlzY2FyZCByZXR1cm4gXCIgK1xuICAgICAgICAgICAgICAgICAgICBcImZvciB3aGlsZSBkbyBpZiBlbHNlIHN0cnVjdCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiaW4gb3V0IGlub3V0XCIpLFxuICAgIHR5cGVzOiB3b3JkcyhcImZsb2F0IGludCBib29sIHZvaWQgXCIgK1xuICAgICAgICAgICAgICAgICBcInZlYzIgdmVjMyB2ZWM0IGl2ZWMyIGl2ZWMzIGl2ZWM0IGJ2ZWMyIGJ2ZWMzIGJ2ZWM0IFwiICtcbiAgICAgICAgICAgICAgICAgXCJtYXQyIG1hdDMgbWF0NFwiKSxcbiAgICBibG9ja0tleXdvcmRzOiB3b3JkcyhcImZvciB3aGlsZSBkbyBpZiBlbHNlIHN0cnVjdFwiKSxcbiAgICBidWlsdGluOiB3b3JkcyhcInJhZGlhbnMgZGVncmVlcyBzaW4gY29zIHRhbiBhc2luIGFjb3MgYXRhbiBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwicG93IGV4cCBsb2cgZXhwMiBzcXJ0IGludmVyc2VzcXJ0IFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJhYnMgc2lnbiBmbG9vciBjZWlsIGZyYWN0IG1vZCBtaW4gbWF4IGNsYW1wIG1peCBzdGVwIHNtb290aHN0ZXAgXCIgK1xuICAgICAgICAgICAgICAgICAgICBcImxlbmd0aCBkaXN0YW5jZSBkb3QgY3Jvc3Mgbm9ybWFsaXplIGZ0cmFuc2Zvcm0gZmFjZWZvcndhcmQgXCIgK1xuICAgICAgICAgICAgICAgICAgICBcInJlZmxlY3QgcmVmcmFjdCBtYXRyaXhDb21wTXVsdCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwibGVzc1RoYW4gbGVzc1RoYW5FcXVhbCBncmVhdGVyVGhhbiBncmVhdGVyVGhhbkVxdWFsIFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJlcXVhbCBub3RFcXVhbCBhbnkgYWxsIG5vdCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwidGV4dHVyZTFEIHRleHR1cmUxRFByb2ogdGV4dHVyZTFETG9kIHRleHR1cmUxRFByb2pMb2QgXCIgK1xuICAgICAgICAgICAgICAgICAgICBcInRleHR1cmUyRCB0ZXh0dXJlMkRQcm9qIHRleHR1cmUyRExvZCB0ZXh0dXJlMkRQcm9qTG9kIFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJ0ZXh0dXJlM0QgdGV4dHVyZTNEUHJvaiB0ZXh0dXJlM0RMb2QgdGV4dHVyZTNEUHJvakxvZCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwidGV4dHVyZUN1YmUgdGV4dHVyZUN1YmVMb2QgXCIgK1xuICAgICAgICAgICAgICAgICAgICBcInNoYWRvdzFEIHNoYWRvdzJEIHNoYWRvdzFEUHJvaiBzaGFkb3cyRFByb2ogXCIgK1xuICAgICAgICAgICAgICAgICAgICBcInNoYWRvdzFETG9kIHNoYWRvdzJETG9kIHNoYWRvdzFEUHJvakxvZCBzaGFkb3cyRFByb2pMb2QgXCIgK1xuICAgICAgICAgICAgICAgICAgICBcImRGZHggZEZkeSBmd2lkdGggXCIgK1xuICAgICAgICAgICAgICAgICAgICBcIm5vaXNlMSBub2lzZTIgbm9pc2UzIG5vaXNlNFwiKSxcbiAgICBhdG9tczogd29yZHMoXCJ0cnVlIGZhbHNlIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX0ZyYWdDb2xvciBnbF9TZWNvbmRhcnlDb2xvciBnbF9Ob3JtYWwgZ2xfVmVydGV4IFwiICtcbiAgICAgICAgICAgICAgICBcImdsX011bHRpVGV4Q29vcmQwIGdsX011bHRpVGV4Q29vcmQxIGdsX011bHRpVGV4Q29vcmQyIGdsX011bHRpVGV4Q29vcmQzIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX011bHRpVGV4Q29vcmQ0IGdsX011bHRpVGV4Q29vcmQ1IGdsX011bHRpVGV4Q29vcmQ2IGdsX011bHRpVGV4Q29vcmQ3IFwiICtcbiAgICAgICAgICAgICAgICBcImdsX0ZvZ0Nvb3JkIGdsX1BvaW50Q29vcmQgXCIgK1xuICAgICAgICAgICAgICAgIFwiZ2xfUG9zaXRpb24gZ2xfUG9pbnRTaXplIGdsX0NsaXBWZXJ0ZXggXCIgK1xuICAgICAgICAgICAgICAgIFwiZ2xfRnJvbnRDb2xvciBnbF9CYWNrQ29sb3IgZ2xfRnJvbnRTZWNvbmRhcnlDb2xvciBnbF9CYWNrU2Vjb25kYXJ5Q29sb3IgXCIgK1xuICAgICAgICAgICAgICAgIFwiZ2xfVGV4Q29vcmQgZ2xfRm9nRnJhZ0Nvb3JkIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX0ZyYWdDb29yZCBnbF9Gcm9udEZhY2luZyBcIiArXG4gICAgICAgICAgICAgICAgXCJnbF9GcmFnRGF0YSBnbF9GcmFnRGVwdGggXCIgK1xuICAgICAgICAgICAgICAgIFwiZ2xfTW9kZWxWaWV3TWF0cml4IGdsX1Byb2plY3Rpb25NYXRyaXggZ2xfTW9kZWxWaWV3UHJvamVjdGlvbk1hdHJpeCBcIiArXG4gICAgICAgICAgICAgICAgXCJnbF9UZXh0dXJlTWF0cml4IGdsX05vcm1hbE1hdHJpeCBnbF9Nb2RlbFZpZXdNYXRyaXhJbnZlcnNlIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX1Byb2plY3Rpb25NYXRyaXhJbnZlcnNlIGdsX01vZGVsVmlld1Byb2plY3Rpb25NYXRyaXhJbnZlcnNlIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX1RleHVyZU1hdHJpeFRyYW5zcG9zZSBnbF9Nb2RlbFZpZXdNYXRyaXhJbnZlcnNlVHJhbnNwb3NlIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX1Byb2plY3Rpb25NYXRyaXhJbnZlcnNlVHJhbnNwb3NlIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX01vZGVsVmlld1Byb2plY3Rpb25NYXRyaXhJbnZlcnNlVHJhbnNwb3NlIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX1RleHR1cmVNYXRyaXhJbnZlcnNlVHJhbnNwb3NlIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX05vcm1hbFNjYWxlIGdsX0RlcHRoUmFuZ2UgZ2xfQ2xpcFBsYW5lIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX1BvaW50IGdsX0Zyb250TWF0ZXJpYWwgZ2xfQmFja01hdGVyaWFsIGdsX0xpZ2h0U291cmNlIGdsX0xpZ2h0TW9kZWwgXCIgK1xuICAgICAgICAgICAgICAgIFwiZ2xfRnJvbnRMaWdodE1vZGVsUHJvZHVjdCBnbF9CYWNrTGlnaHRNb2RlbFByb2R1Y3QgXCIgK1xuICAgICAgICAgICAgICAgIFwiZ2xfVGV4dHVyZUNvbG9yIGdsX0V5ZVBsYW5lUyBnbF9FeWVQbGFuZVQgZ2xfRXllUGxhbmVSIGdsX0V5ZVBsYW5lUSBcIiArXG4gICAgICAgICAgICAgICAgXCJnbF9Gb2dQYXJhbWV0ZXJzIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX01heExpZ2h0cyBnbF9NYXhDbGlwUGxhbmVzIGdsX01heFRleHR1cmVVbml0cyBnbF9NYXhUZXh0dXJlQ29vcmRzIFwiICtcbiAgICAgICAgICAgICAgICBcImdsX01heFZlcnRleEF0dHJpYnMgZ2xfTWF4VmVydGV4VW5pZm9ybUNvbXBvbmVudHMgZ2xfTWF4VmFyeWluZ0Zsb2F0cyBcIiArXG4gICAgICAgICAgICAgICAgXCJnbF9NYXhWZXJ0ZXhUZXh0dXJlSW1hZ2VVbml0cyBnbF9NYXhUZXh0dXJlSW1hZ2VVbml0cyBcIiArXG4gICAgICAgICAgICAgICAgXCJnbF9NYXhGcmFnbWVudFVuaWZvcm1
23459Db21wb25lbnRzIGdsX01heENvbWJpbmVUZXh0dXJlSW1hZ2VVbml0cyBcIiArXG4gICAgICAgICAgICAgICAgXCJnbF9NYXhEcmF3QnVmZmVyc1wiKSxcbiAgICBpbmRlbnRTd2l0Y2g6IGZhbHNlLFxuICAgIGhvb2tzOiB7XCIjXCI6IGNwcEhvb2t9LFxuICAgIG1vZGVQcm9wczoge2ZvbGQ6IFtcImJyYWNlXCIsIFwiaW5jbHVkZVwiXX1cbiAgfSk7XG5cbiAgZGVmKFwidGV4dC94LW5lc2NcIiwge1xuICAgIG5hbWU6IFwiY2xpa2VcIixcbiAgICBrZXl3b3Jkczogd29yZHMoY0tleXdvcmRzICsgXCJhcyBhdG9taWMgYXN5bmMgY2FsbCBjb21tYW5kIGNvbXBvbmVudCBjb21wb25lbnRzIGNvbmZpZ3VyYXRpb24gZXZlbnQgZ2VuZXJpYyBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiaW1wbGVtZW50YXRpb24gaW5jbHVkZXMgaW50ZXJmYWNlIG1vZHVsZSBuZXcgbm9yYWNlIG54X3N0cnVjdCBueF91bmlvbiBwb3N0IHByb3ZpZGVzIFwiICtcbiAgICAgICAgICAgICAgICAgICAgXCJzaWduYWwgdGFzayB1c2VzIGFic3RyYWN0IGV4dGVuZHNcIiksXG4gICAgdHlwZXM6IHdvcmRzKGNUeXBlcyksXG4gICAgYmxvY2tLZXl3b3Jkczogd29yZHMoXCJjYXNlIGRvIGVsc2UgZm9yIGlmIHN3aXRjaCB3aGlsZSBzdHJ1Y3RcIiksXG4gICAgYXRvbXM6IHdvcmRzKFwibnVsbCB0cnVlIGZhbHNlXCIpLFxuICAgIGhvb2tzOiB7XCIjXCI6IGNwcEhvb2t9LFxuICAgIG1vZGVQcm9wczoge2ZvbGQ6IFtcImJyYWNlXCIsIFwiaW5jbHVkZVwiXX1cbiAgfSk7XG5cbiAgZGVmKFwidGV4dC94LW9iamVjdGl2ZWNcIiwge1xuICAgIG5hbWU6IFwiY2xpa2VcIixcbiAgICBrZXl3b3Jkczogd29yZHMoY0tleXdvcmRzICsgXCJpbmxpbmUgcmVzdHJpY3QgX0Jvb2wgX0NvbXBsZXggX0ltYWdpbmVyeSBCT09MIENsYXNzIGJ5Y29weSBieXJlZiBpZCBJTVAgaW4gXCIgK1xuICAgICAgICAgICAgICAgICAgICBcImlub3V0IG5pbCBvbmV3YXkgb3V0IFByb3RvY29sIFNFTCBzZWxmIHN1cGVyIGF0b21pYyBub25hdG9taWMgcmV0YWluIGNvcHkgcmVhZHdyaXRlIHJlYWRvbmx5XCIpLFxuICAgIHR5cGVzOiB3b3JkcyhjVHlwZXMpLFxuICAgIGF0b21zOiB3b3JkcyhcIllFUyBOTyBOVUxMIE5JTEwgT04gT0ZGIHRydWUgZmFsc2VcIiksXG4gICAgaG9va3M6IHtcbiAgICAgIFwiQFwiOiBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgICAgc3RyZWFtLmVhdFdoaWxlKC9bXFx3XFwkXS8pO1xuICAgICAgICByZXR1cm4gXCJrZXl3b3JkXCI7XG4gICAgICB9LFxuICAgICAgXCIjXCI6IGNwcEhvb2ssXG4gICAgICBpbmRlbnQ6IGZ1bmN0aW9uKF9zdGF0ZSwgY3R4LCB0ZXh0QWZ0ZXIpIHtcbiAgICAgICAgaWYgKGN0eC50eXBlID09IFwic3RhdGVtZW50XCIgJiYgL15AXFx3Ly50ZXN0KHRleHRBZnRlcikpIHJldHVybiBjdHguaW5kZW50ZWRcbiAgICAgIH1cbiAgICB9LFxuICAgIG1vZGVQcm9wczoge2ZvbGQ6IFwiYnJhY2VcIn1cbiAgfSk7XG5cbiAgZGVmKFwidGV4dC94LXNxdWlycmVsXCIsIHtcbiAgICBuYW1lOiBcImNsaWtlXCIsXG4gICAga2V5d29yZHM6IHdvcmRzKFwiYmFzZSBicmVhayBjbG9uZSBjb250aW51ZSBjb25zdCBkZWZhdWx0IGRlbGV0ZSBlbnVtIGV4dGVuZHMgZnVuY3Rpb24gaW4gY2xhc3NcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiIGZvcmVhY2ggbG9jYWwgcmVzdW1lIHJldHVybiB0aGlzIHRocm93IHR5cGVvZiB5aWVsZCBjb25zdHJ1Y3RvciBpbnN0YW5jZW9mIHN0YXRpY1wiKSxcbiAgICB0eXBlczogd29yZHMoY1R5cGVzKSxcbiAgICBibG9ja0tleXdvcmRzOiB3b3JkcyhcImNhc2UgY2F0Y2ggY2xhc3MgZWxzZSBmb3IgZm9yZWFjaCBpZiBzd2l0Y2ggdHJ5IHdoaWxlXCIpLFxuICAgIGRlZktleXdvcmRzOiB3b3JkcyhcImZ1bmN0aW9uIGxvY2FsIGNsYXNzXCIpLFxuICAgIHR5cGVGaXJzdERlZmluaXRpb25zOiB0cnVlLFxuICAgIGF0b21zOiB3b3JkcyhcInRydWUgZmFsc2UgbnVsbFwiKSxcbiAgICBob29rczoge1wiI1wiOiBjcHBIb29rfSxcbiAgICBtb2RlUHJvcHM6IHtmb2xkOiBbXCJicmFjZVwiLCBcImluY2x1ZGVcIl19XG4gIH0pO1xuXG4gIC8vIENleWxvbiBTdHJpbmdzIG5lZWQgdG8gZGVhbCB3aXRoIGludGVycG9sYXRpb25cbiAgdmFyIHN0cmluZ1Rva2VuaXplciA9IG51bGw7XG4gIGZ1bmN0aW9uIHRva2VuQ2V5bG9uU3RyaW5nKHR5cGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oc3RyZWFtLCBzdGF0ZSkge1xuICAgICAgdmFyIGVzY2FwZWQgPSBmYWxzZSwgbmV4dCwgZW5kID0gZmFsc2U7XG4gICAgICB3aGlsZSAoIXN0cmVhbS5lb2woKSkge1xuICAgICAgICBpZiAoIWVzY2FwZWQgJiYgc3RyZWFtLm1hdGNoKCdcIicpICYmXG4gICAgICAgICAgICAgICh0eXBlID09IFwic2luZ2xlXCIgfHwgc3RyZWFtLm1hdGNoKCdcIlwiJykpKSB7XG4gICAgICAgICAgZW5kID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWVzY2FwZWQgJiYgc3RyZWFtLm1hdGNoKCdgYCcpKSB7XG4gICAgICAgICAgc3RyaW5nVG9rZW5pemVyID0gdG9rZW5DZXlsb25TdHJpbmcodHlwZSk7XG4gICAgICAgICAgZW5kID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBuZXh0ID0gc3RyZWFtLm5leHQoKTtcbiAgICAgICAgZXNjYXBlZCA9IHR5cGUgPT0gXCJzaW5nbGVcIiAmJiAhZXNjYXBlZCAmJiBuZXh0ID09IFwiXFxcXFwiO1xuICAgICAgfVxuICAgICAgaWYgKGVuZClcbiAgICAgICAgICBzdGF0ZS50b2tlbml6ZSA9IG51bGw7XG4gICAgICByZXR1cm4gXCJzdHJpbmdcIjtcbiAgICB9XG4gIH1cblxuICBkZWYoXCJ0ZXh0L3gtY2V5bG9uXCIsIHtcbiAgICBuYW1lOiBcImNsaWtlXCIsXG4gICAga2V5d29yZHM6IHdvcmRzKFwiYWJzdHJhY3RzIGFsaWFzIGFzc2VtYmx5IGFzc2VydCBhc3NpZ24gYnJlYWsgY2FzZSBjYXRjaCBjbGFzcyBjb250aW51ZSBkeW5hbWljIGVsc2VcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiIGV4aXN0cyBleHRlbmRzIGZpbmFsbHkgZm9yIGZ1bmN0aW9uIGdpdmVuIGlmIGltcG9ydCBpbiBpbnRlcmZhY2UgaXMgbGV0IG1vZHVsZSBuZXdcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiIG5vbmVtcHR5IG9iamVjdCBvZiBvdXQgb3V0ZXIgcGFja2FnZSByZXR1cm4gc2F0aXNmaWVzIHN1cGVyIHN3aXRjaCB0aGVuIHRoaXMgdGhyb3dcIiArXG4gICAgICAgICAgICAgICAgICAgIFwiIHRyeSB2YWx1ZSB2b2lkIHdoaWxlXCIpLFxuICAgIHR5cGVzOiBmdW5jdGlvbih3b3JkKSB7XG4gICAgICAgIC8vIEluIENleWxvbiBhbGwgaWRlbnRpZmllcnMgdGhhdCBzdGFydCB3aXRoIGFuIHVwcGVyY2FzZSBhcmUgdHlwZXNcbiAgICAgICAgdmFyIGZpcnN0ID0gd29yZC5jaGFyQXQoMCk7XG4gICAgICAgI
23459HJldHVybiAoZmlyc3QgPT09IGZpcnN0LnRvVXBwZXJDYXNlKCkgJiYgZmlyc3QgIT09IGZpcnN0LnRvTG93ZXJDYXNlKCkpO1xuICAgIH0sXG4gICAgYmxvY2tLZXl3b3Jkczogd29yZHMoXCJjYXNlIGNhdGNoIGNsYXNzIGR5bmFtaWMgZWxzZSBmaW5hbGx5IGZvciBmdW5jdGlvbiBpZiBpbnRlcmZhY2UgbW9kdWxlIG5ldyBvYmplY3Qgc3dpdGNoIHRyeSB3aGlsZVwiKSxcbiAgICBkZWZLZXl3b3Jkczogd29yZHMoXCJjbGFzcyBkeW5hbWljIGZ1bmN0aW9uIGludGVyZmFjZSBtb2R1bGUgb2JqZWN0IHBhY2thZ2UgdmFsdWVcIiksXG4gICAgYnVpbHRpbjogd29yZHMoXCJhYnN0cmFjdCBhY3R1YWwgYWxpYXNlZCBhbm5vdGF0aW9uIGJ5IGRlZmF1bHQgZGVwcmVjYXRlZCBkb2MgZmluYWwgZm9ybWFsIGxhdGUgbGljZW5zZVwiICtcbiAgICAgICAgICAgICAgICAgICBcIiBuYXRpdmUgb3B0aW9uYWwgc2VhbGVkIHNlZSBzZXJpYWxpemFibGUgc2hhcmVkIHN1cHByZXNzV2FybmluZ3MgdGFnZ2VkIHRocm93cyB2YXJpYWJsZVwiKSxcbiAgICBpc1B1bmN0dWF0aW9uQ2hhcjogL1tcXFtcXF17fVxcKFxcKSw7XFw6XFwuYF0vLFxuICAgIGlzT3BlcmF0b3JDaGFyOiAvWytcXC0qJiU9PD4hP3xefjpcXC9dLyxcbiAgICBpc051bWJlckNoYXI6IC9bXFxkIyRdLyxcbiAgICBtdWx0aUxpbmVTdHJpbmdzOiB0cnVlLFxuICAgIHR5cGVGaXJzdERlZmluaXRpb25zOiB0cnVlLFxuICAgIGF0b21zOiB3b3JkcyhcInRydWUgZmFsc2UgbnVsbCBsYXJnZXIgc21hbGxlciBlcXVhbCBlbXB0eSBmaW5pc2hlZFwiKSxcbiAgICBpbmRlbnRTd2l0Y2g6IGZhbHNlLFxuICAgIHN0eWxlRGVmczogZmFsc2UsXG4gICAgaG9va3M6IHtcbiAgICAgIFwiQFwiOiBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICAgICAgc3RyZWFtLmVhdFdoaWxlKC9bXFx3XFwkX10vKTtcbiAgICAgICAgcmV0dXJuIFwibWV0YVwiO1xuICAgICAgfSxcbiAgICAgICdcIic6IGZ1bmN0aW9uKHN0cmVhbSwgc3RhdGUpIHtcbiAgICAgICAgICBzdGF0ZS50b2tlbml6ZSA9IHRva2VuQ2V5bG9uU3RyaW5nKHN0cmVhbS5tYXRjaCgnXCJcIicpID8gXCJ0cmlwbGVcIiA6IFwic2luZ2xlXCIpO1xuICAgICAgICAgIHJldHVybiBzdGF0ZS50b2tlbml6ZShzdHJlYW0sIHN0YXRlKTtcbiAgICAgICAgfSxcbiAgICAgICdgJzogZnVuY3Rpb24oc3RyZWFtLCBzdGF0ZSkge1xuICAgICAgICAgIGlmICghc3RyaW5nVG9rZW5pemVyIHx8ICFzdHJlYW0ubWF0Y2goJ2AnKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIHN0YXRlLnRva2VuaXplID0gc3RyaW5nVG9rZW5pemVyO1xuICAgICAgICAgIHN0cmluZ1Rva2VuaXplciA9IG51bGw7XG4gICAgICAgICAgcmV0dXJuIHN0YXRlLnRva2VuaXplKHN0cmVhbSwgc3RhdGUpO1xuICAgICAgICB9LFxuICAgICAgXCInXCI6IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgICBzdHJlYW0uZWF0V2hpbGUoL1tcXHdcXCRfXFx4YTEtXFx1ZmZmZl0vKTtcbiAgICAgICAgcmV0dXJuIFwiYXRvbVwiO1xuICAgICAgfSxcbiAgICAgIHRva2VuOiBmdW5jdGlvbihfc3RyZWFtLCBzdGF0ZSwgc3R5bGUpIHtcbiAgICAgICAgICBpZiAoKHN0eWxlID09IFwidmFyaWFibGVcIiB8fCBzdHlsZSA9PSBcInZhcmlhYmxlLTNcIikgJiZcbiAgICAgICAgICAgICAgc3RhdGUucHJldlRva2VuID09IFwiLlwiKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJ2YXJpYWJsZS0yXCI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSxcbiAgICBtb2RlUHJvcHM6IHtcbiAgICAgICAgZm9sZDogW1wiYnJhY2VcIiwgXCJpbXBvcnRcIl0sXG4gICAgICAgIGNsb3NlQnJhY2tldHM6IHt0cmlwbGVzOiAnXCInfVxuICAgIH1cbiAgfSk7XG5cbn0pO1xuIiwicmVxdWlyZSgnLi4vbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3InKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vbW9kdWxlcy9jb3JlLmdldC1pdGVyYXRvcicpOyIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24nKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy8kLmNvcmUnKS5PYmplY3QuYXNzaWduOyIsInZhciAkID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy8kJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGNyZWF0ZShQLCBEKXtcbiAgcmV0dXJuICQuY3JlYXRlKFAsIEQpO1xufTsiLCJ2YXIgJCA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvJCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eShpdCwga2V5LCBkZXNjKXtcbiAgcmV0dXJuICQuc2V0RGVzYyhpdCwga2V5LCBkZXNjKTtcbn07IiwidmFyICQgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzLyQnKTtcbnJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3InKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGl0LCBrZXkpe1xuICByZXR1cm4gJC5nZXREZXNjKGl0LCBrZXkpO1xufTsiLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5vYmplY3Qua2V5cycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzLyQuY29yZScpLk9iamVjdC5rZXlzOyIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM2Lm9iamVjdC5zZXQtcHJvdG90eXBlLW9mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvJC5jb3JlJykuT2JqZWN0LnNldFByb3RvdHlwZU9mOyIsInJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC50by1zdHJpbmcnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5pdGVyYXRvcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5wcm9taXNlJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uL21vZHVsZXMvJC5jb3JlJykuUHJvbWlzZTsiLCJyZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc2V0Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNy5zZXQudG8tanNvbicpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi9tb2R1bGVzLyQuY29yZScpLlNldDsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgaWYodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYSBmdW5jdGlvbiEnKTtcbiAgcmV0dXJuIGl0O1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKCl7IC8qIGVtcHR5ICovIH07IiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi8kLmlzLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIGlmKCFpc09iamVjdChpdCkpdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYW4gb2JqZWN0IScpO1xuICByZXR1cm4gaXQ7XG59OyIsIi8vIGdldHRpbmcgdGFnIGZyb20gMTkuMS4zLjYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZygpXG52YXIgY29mID0gcmVxdWlyZSgnLi8kLmNvZicpXG4gICwgVEFHID0gcmVxdWlyZSgnLi8kLndrcycpKCd0b1N0cmluZ1RhZycpXG4gIC8vIEVTMyB3cm9uZyBoZXJlXG4gICwgQVJHID0gY29mKGZ1bmN0aW9uKCl7IHJldHVybi
23459Bhcmd1bWVudHM7IH0oKSkgPT0gJ0FyZ3VtZW50cyc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICB2YXIgTywgVCwgQjtcbiAgcmV0dXJuIGl0ID09PSB1bmRlZmluZWQgPyAnVW5kZWZpbmVkJyA6IGl0ID09PSBudWxsID8gJ051bGwnXG4gICAgLy8gQEB0b1N0cmluZ1RhZyBjYXNlXG4gICAgOiB0eXBlb2YgKFQgPSAoTyA9IE9iamVjdChpdCkpW1RBR10pID09ICdzdHJpbmcnID8gVFxuICAgIC8vIGJ1aWx0aW5UYWcgY2FzZVxuICAgIDogQVJHID8gY29mKE8pXG4gICAgLy8gRVMzIGFyZ3VtZW50cyBmYWxsYmFja1xuICAgIDogKEIgPSBjb2YoTykpID09ICdPYmplY3QnICYmIHR5cGVvZiBPLmNhbGxlZSA9PSAnZnVuY3Rpb24nID8gJ0FyZ3VtZW50cycgOiBCO1xufTsiLCJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKGl0KS5zbGljZSg4LCAtMSk7XG59OyIsIid1c2Ugc3RyaWN0JztcbnZhciAkICAgICAgICAgICAgPSByZXF1aXJlKCcuLyQnKVxuICAsIGhpZGUgICAgICAgICA9IHJlcXVpcmUoJy4vJC5oaWRlJylcbiAgLCByZWRlZmluZUFsbCAgPSByZXF1aXJlKCcuLyQucmVkZWZpbmUtYWxsJylcbiAgLCBjdHggICAgICAgICAgPSByZXF1aXJlKCcuLyQuY3R4JylcbiAgLCBzdHJpY3ROZXcgICAgPSByZXF1aXJlKCcuLyQuc3RyaWN0LW5ldycpXG4gICwgZGVmaW5lZCAgICAgID0gcmVxdWlyZSgnLi8kLmRlZmluZWQnKVxuICAsIGZvck9mICAgICAgICA9IHJlcXVpcmUoJy4vJC5mb3Itb2YnKVxuICAsICRpdGVyRGVmaW5lICA9IHJlcXVpcmUoJy4vJC5pdGVyLWRlZmluZScpXG4gICwgc3RlcCAgICAgICAgID0gcmVxdWlyZSgnLi8kLml0ZXItc3RlcCcpXG4gICwgSUQgICAgICAgICAgID0gcmVxdWlyZSgnLi8kLnVpZCcpKCdpZCcpXG4gICwgJGhhcyAgICAgICAgID0gcmVxdWlyZSgnLi8kLmhhcycpXG4gICwgaXNPYmplY3QgICAgID0gcmVxdWlyZSgnLi8kLmlzLW9iamVjdCcpXG4gICwgc2V0U3BlY2llcyAgID0gcmVxdWlyZSgnLi8kLnNldC1zcGVjaWVzJylcbiAgLCBERVNDUklQVE9SUyAgPSByZXF1aXJlKCcuLyQuZGVzY3JpcHRvcnMnKVxuICAsIGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGUgfHwgaXNPYmplY3RcbiAgLCBTSVpFICAgICAgICAgPSBERVNDUklQVE9SUyA/ICdfcycgOiAnc2l6ZSdcbiAgLCBpZCAgICAgICAgICAgPSAwO1xuXG52YXIgZmFzdEtleSA9IGZ1bmN0aW9uKGl0LCBjcmVhdGUpe1xuICAvLyByZXR1cm4gcHJpbWl0aXZlIHdpdGggcHJlZml4XG4gIGlmKCFpc09iamVjdChpdCkpcmV0dXJuIHR5cGVvZiBpdCA9PSAnc3ltYm9sJyA/IGl0IDogKHR5cGVvZiBpdCA9PSAnc3RyaW5nJyA/ICdTJyA6ICdQJykgKyBpdDtcbiAgaWYoISRoYXMoaXQsIElEKSl7XG4gICAgLy8gY2FuJ3Qgc2V0IGlkIHRvIGZyb3plbiBvYmplY3RcbiAgICBpZighaXNFeHRlbnNpYmxlKGl0KSlyZXR1cm4gJ0YnO1xuICAgIC8vIG5vdCBuZWNlc3NhcnkgdG8gYWRkIGlkXG4gICAgaWYoIWNyZWF0ZSlyZXR1cm4gJ0UnO1xuICAgIC8vIGFkZCBtaXNzaW5nIG9iamVjdCBpZFxuICAgIGhpZGUoaXQsIElELCArK2lkKTtcbiAgLy8gcmV0dXJuIG9iamVjdCBpZCB3aXRoIHByZWZpeFxuICB9IHJldHVybiAnTycgKyBpdFtJRF07XG59O1xuXG52YXIgZ2V0RW50cnkgPSBmdW5jdGlvbih0aGF0LCBrZXkpe1xuICAvLyBmYXN0IGNhc2VcbiAgdmFyIGluZGV4ID0gZmFzdEtleShrZXkpLCBlbnRyeTtcbiAgaWYoaW5kZXggIT09ICdGJylyZXR1cm4gdGhhdC5faVtpbmRleF07XG4gIC8vIGZyb3plbiBvYmplY3QgY2FzZVxuICBmb3IoZW50cnkgPSB0aGF0Ll9mOyBlbnRyeTsgZW50cnkgPSBlbnRyeS5uKXtcbiAgICBpZihlbnRyeS5rID09IGtleSlyZXR1cm4gZW50cnk7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRDb25zdHJ1Y3RvcjogZnVuY3Rpb24od3JhcHBlciwgTkFNRSwgSVNfTUFQLCBBRERFUil7XG4gICAgdmFyIEMgPSB3cmFwcGVyKGZ1bmN0aW9uKHRoYXQsIGl0ZXJhYmxlKXtcbiAgICAgIHN0cmljdE5ldyh0aGF0LCBDLCBOQU1FKTtcbiAgICAgIHRoYXQuX2kgPSAkLmNyZWF0ZShudWxsKTsgLy8gaW5kZXhcbiAgICAgIHRoYXQuX2YgPSB1bmRlZmluZWQ7ICAgICAgLy8gZmlyc3QgZW50cnlcbiAgICAgIHRoYXQuX2wgPSB1bmRlZmluZWQ7ICAgICAgLy8gbGFzdCBlbnRyeVxuICAgICAgdGhhdFtTSVpFXSA9IDA7ICAgICAgICAgICAvLyBzaXplXG4gICAgICBpZihpdGVyYWJsZSAhPSB1bmRlZmluZWQpZm9yT2YoaXRlcmFibGUsIElTX01BUCwgdGhhdFtBRERFUl0sIHRoYXQpO1xuICAgIH0pO1xuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCB7XG4gICAgICAvLyAyMy4xLjMuMSBNYXAucHJvdG90eXBlLmNsZWFyKClcbiAgICAgIC8vIDIzLjIuMy4yIFNldC5wcm90b3R5cGUuY2xlYXIoKVxuICAgICAgY2xlYXI6IGZ1bmN0aW9uIGNsZWFyKCl7XG4gICAgICAgIGZvcih2YXIgdGhhdCA9IHRoaXMsIGRhdGEgPSB0aGF0Ll9pLCBlbnRyeSA9IHRoYXQuX2Y7IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm4pe1xuICAgICAgICAgIGVudHJ5LnIgPSB0cnVlO1xuICAgICAgICAgIGlmKGVudHJ5LnApZW50cnkucCA9IGVudHJ5LnAubiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBkZWxldGUgZGF0YVtlbnRyeS5pXTtcbiAgICAgICAgfVxuICAgICAgICB0aGF0Ll9mID0gdGhhdC5fbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhhdFtTSVpFXSA9IDA7XG4gICAgICB9LFxuICAgICAgLy8gMjMuMS4zLjMgTWFwLnByb3RvdHlwZS5kZWxldGUoa2V5KVxuICAgICAgLy8gMjMuMi4zLjQgU2V0LnByb3RvdHlwZS5kZWxldGUodmFsdWUpXG4gICAgICAnZGVsZXRlJzogZnVuY3Rpb24oa2V5KXtcbiAgICAgICAgdmFyIHRoYXQgID0gdGhpc1xuICAgICAgICAgICwgZW50cnkgPSBnZXRFbnRyeSh0aGF0LCBrZXkpO1xuICAgICAgICBpZihlbnRyeSl7XG4gICAgICAgICAgdmFyIG5leHQgPSBlbnRyeS5uXG4gICAgICAgICAgICAsIHByZXYgPSBlbnRyeS5wO1xuICAgICAgICAgIGRlbGV0ZSB0aGF0Ll9pW2VudHJ5LmldO1xuICAgICAgICAgIGVudHJ5LnIgPSB0cnVlO1xuICAgICAgICAgIGlmKHByZXYpcHJldi5uID0gbmV4dDtcbiAgICAgICAgICBpZihuZXh0KW5leHQucCA9IHByZXY7XG4gICAgICAgICAgaWYodGhhdC5fZiA9PSBlbnRyeSl0aGF0Ll9mID0gbmV4dDtcbiAgICAgICAgICBpZih0aGF0Ll9sID09IGVudHJ5KXRoYXQuX2wgPSBwcmV2O1xuICAgICAgICAgI
23459HRoYXRbU0laRV0tLTtcbiAgICAgICAgfSByZXR1cm4gISFlbnRyeTtcbiAgICAgIH0sXG4gICAgICAvLyAyMy4yLjMuNiBTZXQucHJvdG90eXBlLmZvckVhY2goY2FsbGJhY2tmbiwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbiAgICAgIC8vIDIzLjEuMy41IE1hcC5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxuICAgICAgZm9yRWFjaDogZnVuY3Rpb24gZm9yRWFjaChjYWxsYmFja2ZuIC8qLCB0aGF0ID0gdW5kZWZpbmVkICovKXtcbiAgICAgICAgdmFyIGYgPSBjdHgoY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIDMpXG4gICAgICAgICAgLCBlbnRyeTtcbiAgICAgICAgd2hpbGUoZW50cnkgPSBlbnRyeSA/IGVudHJ5Lm4gOiB0aGlzLl9mKXtcbiAgICAgICAgICBmKGVudHJ5LnYsIGVudHJ5LmssIHRoaXMpO1xuICAgICAgICAgIC8vIHJldmVydCB0byB0aGUgbGFzdCBleGlzdGluZyBlbnRyeVxuICAgICAgICAgIHdoaWxlKGVudHJ5ICYmIGVudHJ5LnIpZW50cnkgPSBlbnRyeS5wO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgLy8gMjMuMS4zLjcgTWFwLnByb3RvdHlwZS5oYXMoa2V5KVxuICAgICAgLy8gMjMuMi4zLjcgU2V0LnByb3RvdHlwZS5oYXModmFsdWUpXG4gICAgICBoYXM6IGZ1bmN0aW9uIGhhcyhrZXkpe1xuICAgICAgICByZXR1cm4gISFnZXRFbnRyeSh0aGlzLCBrZXkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmKERFU0NSSVBUT1JTKSQuc2V0RGVzYyhDLnByb3RvdHlwZSwgJ3NpemUnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uKCl7XG4gICAgICAgIHJldHVybiBkZWZpbmVkKHRoaXNbU0laRV0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBDO1xuICB9LFxuICBkZWY6IGZ1bmN0aW9uKHRoYXQsIGtleSwgdmFsdWUpe1xuICAgIHZhciBlbnRyeSA9IGdldEVudHJ5KHRoYXQsIGtleSlcbiAgICAgICwgcHJldiwgaW5kZXg7XG4gICAgLy8gY2hhbmdlIGV4aXN0aW5nIGVudHJ5XG4gICAgaWYoZW50cnkpe1xuICAgICAgZW50cnkudiA9IHZhbHVlO1xuICAgIC8vIGNyZWF0ZSBuZXcgZW50cnlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhhdC5fbCA9IGVudHJ5ID0ge1xuICAgICAgICBpOiBpbmRleCA9IGZhc3RLZXkoa2V5LCB0cnVlKSwgLy8gPC0gaW5kZXhcbiAgICAgICAgazoga2V5LCAgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIGtleVxuICAgICAgICB2OiB2YWx1ZSwgICAgICAgICAgICAgICAgICAgICAgLy8gPC0gdmFsdWVcbiAgICAgICAgcDogcHJldiA9IHRoYXQuX2wsICAgICAgICAgICAgIC8vIDwtIHByZXZpb3VzIGVudHJ5XG4gICAgICAgIG46IHVuZGVmaW5lZCwgICAgICAgICAgICAgICAgICAvLyA8LSBuZXh0IGVudHJ5XG4gICAgICAgIHI6IGZhbHNlICAgICAgICAgICAgICAgICAgICAgICAvLyA8LSByZW1vdmVkXG4gICAgICB9O1xuICAgICAgaWYoIXRoYXQuX2YpdGhhdC5fZiA9IGVudHJ5O1xuICAgICAgaWYocHJldilwcmV2Lm4gPSBlbnRyeTtcbiAgICAgIHRoYXRbU0laRV0rKztcbiAgICAgIC8vIGFkZCB0byBpbmRleFxuICAgICAgaWYoaW5kZXggIT09ICdGJyl0aGF0Ll9pW2luZGV4XSA9IGVudHJ5O1xuICAgIH0gcmV0dXJuIHRoYXQ7XG4gIH0sXG4gIGdldEVudHJ5OiBnZXRFbnRyeSxcbiAgc2V0U3Ryb25nOiBmdW5jdGlvbihDLCBOQU1FLCBJU19NQVApe1xuICAgIC8vIGFkZCAua2V5cywgLnZhbHVlcywgLmVudHJpZXMsIFtAQGl0ZXJhdG9yXVxuICAgIC8vIDIzLjEuMy40LCAyMy4xLjMuOCwgMjMuMS4zLjExLCAyMy4xLjMuMTIsIDIzLjIuMy41LCAyMy4yLjMuOCwgMjMuMi4zLjEwLCAyMy4yLjMuMTFcbiAgICAkaXRlckRlZmluZShDLCBOQU1FLCBmdW5jdGlvbihpdGVyYXRlZCwga2luZCl7XG4gICAgICB0aGlzLl90ID0gaXRlcmF0ZWQ7ICAvLyB0YXJnZXRcbiAgICAgIHRoaXMuX2sgPSBraW5kOyAgICAgIC8vIGtpbmRcbiAgICAgIHRoaXMuX2wgPSB1bmRlZmluZWQ7IC8vIHByZXZpb3VzXG4gICAgfSwgZnVuY3Rpb24oKXtcbiAgICAgIHZhciB0aGF0ICA9IHRoaXNcbiAgICAgICAgLCBraW5kICA9IHRoYXQuX2tcbiAgICAgICAgLCBlbnRyeSA9IHRoYXQuX2w7XG4gICAgICAvLyByZXZlcnQgdG8gdGhlIGxhc3QgZXhpc3RpbmcgZW50cnlcbiAgICAgIHdoaWxlKGVudHJ5ICYmIGVudHJ5LnIpZW50cnkgPSBlbnRyeS5wO1xuICAgICAgLy8gZ2V0IG5leHQgZW50cnlcbiAgICAgIGlmKCF0aGF0Ll90IHx8ICEodGhhdC5fbCA9IGVudHJ5ID0gZW50cnkgPyBlbnRyeS5uIDogdGhhdC5fdC5fZikpe1xuICAgICAgICAvLyBvciBmaW5pc2ggdGhlIGl0ZXJhdGlvblxuICAgICAgICB0aGF0Ll90ID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gc3RlcCgxKTtcbiAgICAgIH1cbiAgICAgIC8vIHJldHVybiBzdGVwIGJ5IGtpbmRcbiAgICAgIGlmKGtpbmQgPT0gJ2tleXMnICApcmV0dXJuIHN0ZXAoMCwgZW50cnkuayk7XG4gICAgICBpZihraW5kID09ICd2YWx1ZXMnKXJldHVybiBzdGVwKDAsIGVudHJ5LnYpO1xuICAgICAgcmV0dXJuIHN0ZXAoMCwgW2VudHJ5LmssIGVudHJ5LnZdKTtcbiAgICB9LCBJU19NQVAgPyAnZW50cmllcycgOiAndmFsdWVzJyAsICFJU19NQVAsIHRydWUpO1xuXG4gICAgLy8gYWRkIFtAQHNwZWNpZXNdLCAyMy4xLjIuMiwgMjMuMi4yLjJcbiAgICBzZXRTcGVjaWVzKE5BTUUpO1xuICB9XG59OyIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9EYXZpZEJydWFudC9NYXAtU2V0LnByb3RvdHlwZS50b0pTT05cbnZhciBmb3JPZiAgID0gcmVxdWlyZSgnLi8kLmZvci1vZicpXG4gICwgY2xhc3NvZiA9IHJlcXVpcmUoJy4vJC5jbGFzc29mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKE5BTUUpe1xuICByZXR1cm4gZnVuY3Rpb24gdG9KU09OKCl7XG4gICAgaWYoY2xhc3NvZih0aGlzKSAhPSBOQU1FKXRocm93IFR5cGVFcnJvcihOQU1FICsgXCIjdG9KU09OIGlzbid0IGdlbmVyaWNcIik7XG4gICAgdmFyIGFyciA9IFtdO1xuICAgIGZvck9mKHRoaXMsIGZhbHNlLCBhcnIucHVzaCwgYXJyKTtcbiAgICByZXR1cm4gYXJyO1xuICB9O1xufTsiLCIndXNlIHN0cmljdCc7XG52YXIgJCAgICAgICAgICAgICAgPSByZXF1aXJlKCcuLyQnKVxuICAsIGdsb2JhbCAgICAgICAgID0gcmVxdWlyZSgnLi8kLmdsb2JhbCcpXG4gICwgJGV4cG9ydCAgICAgICAgPSByZXF1aXJlKCcuLyQuZXhwb3J0JylcbiAgLCBmYWlscyAgICAgICAgICA9IHJlcXVpcmUoJy4vJC5mYWlscycpXG4gICwgaGlkZSAgICAgICAgICAgPSByZXF1aXJlKCcuLyQuaGlkZScpXG4gICwgcmVkZWZpbmVBbGwgICAgPSByZXF1aXJlKCcuLyQucmVkZWZpbmUtYWxsJylcbiAgLCBmb3JPZiAgICAgICAgICA9IHJlcXVpcmUoJy4vJC5mb3Itb2YnKVxuICAsIHN0cmljdE5ldyAgICAgID0gcmVxdWlyZSgnLi8kLnN0cmljdC1uZXcnKVxuICAsIGlzT2JqZWN0ICAgICAgID0gcmVxdWlyZSgnLi8kLmlzLW9iamVjdCcpXG4gICwgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuLyQuc2V0LXRvLXN0cmluZy10YWcnKVxuICAsIERFU0NSSVBUT1JTICAgID0gcmVxdWlyZSgnLi8kLmRlc2NyaXB0b3JzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oTkFNRSwgd3JhcHBlciwgbWV0aG9kcywgY29tbW9uLCBJU19NQVAsIElTX1dFQUspe1xuICB2YXIgQmFzZSAgPSBnbG9iYWxbTkFNRV1cbiAgICAsIEMgICAgID0gQmFzZVxuICAgICwgQURERVIgPSBJU19NQVAgPyAnc2V0JyA6ICdhZGQnXG4gICAgLCBwcm90byA9IEMgJiYgQy5wcm90b3R5cGVcbiAgICAsIE8gICAgID0ge307XG4gIGlmKCFERVNDUklQVE9SUyB8fCB0eXBlb2YgQyAhPSAnZnVuY3Rpb24nIHx8ICEoSVNfV0VBSyB8fCBwcm90by5mb3JFYWNoICYmICFmYWlscyhmdW5jdGlvbigpe1xuICAgIG5ldyBDKCkuZW50cmllcygpLm5leHQoKTtcbiAgfSkpKXtcbiAgICAvLyBjcmVhdGUgY29sbGVjdGlvbiBjb25zdHJ1Y3RvclxuICAgIEMgPSBjb21tb24uZ2V0Q29uc3RydWN0b3Iod3JhcHBlciwgTkFNRSwgSVNfTUFQLCBBRERFUik7XG4gICAgcmVkZWZpbmVBbGwoQy5wcm90b3R5cGUsIG1ldGhvZHMpO1xuICB9IGVsc2Uge1xuICAgIEMgPSB3cmFwcGVyKGZ1bmN0aW9uKHRhcmdldCwgaXRlcmFibGUpe1xuICAgICAgc3RyaWN0TmV3KHRhcmdldCwgQywgTkFNRSk7XG4gICAgICB0YXJnZXQuX2MgPSBuZXcgQmFzZTtcbiAgICAgIGlmKGl0ZXJhYmxlICE9IHVuZGVmaW5lZClmb3JPZihpdGVyYWJsZSwgSVNfTUFQLCB0YXJnZXRbQURERVJdLCB0YXJnZXQpO1xuICAgIH0pO1xuICAgICQuZWFjaC5jYWxsKCdhZGQsY2xlYXIsZGVsZXRlLGZvckVhY2gsZ2V0LGhhcyxzZXQsa2V5cyx2YWx1ZXMsZW50cmllcycuc3BsaXQoJywnKSxmdW5jdGlvbihLRVkpe1xuICAgICAgdmFyIElTX0FEREVSID0gS0VZID09ICdhZGQnIHx8IEtFWSA9PSAnc2V0JztcbiAgICAgIGlmKEtFWSBpbiBwcm90byAmJiAhKElTX1dFQUsgJiYgS0VZID09ICdjbGVhcicpKWhpZGUoQy5wcm90b3R5cGUsIEtFWSwgZnVuY3Rpb24oYSwgYil7XG4gICAgICAgIGlmKCFJU19BRERFUiAmJiBJU19XRUFLICYmICFpc09iamVjdChhKSlyZXR1cm4gS0VZID09ICdnZXQnID8gdW5kZWZpbmVkIDogZmFsc2U7XG4gICAgICAgI
23459HZhciByZXN1bHQgPSB0aGlzLl9jW0tFWV0oYSA9PT0gMCA/IDAgOiBhLCBiKTtcbiAgICAgICAgcmV0dXJuIElTX0FEREVSID8gdGhpcyA6IHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGlmKCdzaXplJyBpbiBwcm90bykkLnNldERlc2MoQy5wcm90b3R5cGUsICdzaXplJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbigpe1xuICAgICAgICByZXR1cm4gdGhpcy5fYy5zaXplO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgc2V0VG9TdHJpbmdUYWcoQywgTkFNRSk7XG5cbiAgT1tOQU1FXSA9IEM7XG4gICRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GLCBPKTtcblxuICBpZighSVNfV0VBSyljb21tb24uc2V0U3Ryb25nKEMsIE5BTUUsIElTX01BUCk7XG5cbiAgcmV0dXJuIEM7XG59OyIsInZhciBjb3JlID0gbW9kdWxlLmV4cG9ydHMgPSB7dmVyc2lvbjogJzEuMi42J307XG5pZih0eXBlb2YgX19lID09ICdudW1iZXInKV9fZSA9IGNvcmU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWYiLCIvLyBvcHRpb25hbCAvIHNpbXBsZSBjb250ZXh0IGJpbmRpbmdcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuLyQuYS1mdW5jdGlvbicpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmbiwgdGhhdCwgbGVuZ3RoKXtcbiAgYUZ1bmN0aW9uKGZuKTtcbiAgaWYodGhhdCA9PT0gdW5kZWZpbmVkKXJldHVybiBmbjtcbiAgc3dpdGNoKGxlbmd0aCl7XG4gICAgY2FzZSAxOiByZXR1cm4gZnVuY3Rpb24oYSl7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhKTtcbiAgICB9O1xuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uKGEsIGIpe1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYik7XG4gICAgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbihhLCBiLCBjKXtcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEsIGIsIGMpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKC8qIC4uLmFyZ3MgKi8pe1
23459xuICAgIHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuICB9O1xufTsiLCIvLyA3LjIuMSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIGlmKGl0ID09IHVuZGVmaW5lZCl0aHJvdyBUeXBlRXJyb3IoXCJDYW4ndCBjYWxsIG1ldGhvZCBvbiAgXCIgKyBpdCk7XG4gIHJldHVybiBpdDtcbn07IiwiLy8gVGhhbmsncyBJRTggZm9yIGhpcyBmdW5ueSBkZWZpbmVQcm9wZXJ0eVxubW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi8kLmZhaWxzJykoZnVuY3Rpb24oKXtcbiAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgJ2EnLCB7Z2V0OiBmdW5jdGlvbigpeyByZXR1cm4gNzsgfX0pLmEgIT0gNztcbn0pOyIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vJC5pcy1vYmplY3QnKVxuICAsIGRvY3VtZW50ID0gcmVxdWlyZSgnLi8kLmdsb2JhbCcpLmRvY3VtZW50XG4gIC8vIGluIG9sZCBJRSB0eXBlb2YgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBpcyAnb2JqZWN0J1xuICAsIGlzID0gaXNPYmplY3QoZG9jdW1lbnQpICYmIGlzT2JqZWN0KGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBpcyA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaXQpIDoge307XG59OyIsInZhciBnbG9iYWwgICAgPSByZXF1aXJlKCcuLyQuZ2xvYmFsJylcbiAgLCBjb3JlICAgICAgPSByZXF1aXJlKCcuLyQuY29yZScpXG4gICwgY3R4ICAgICAgID0gcmVxdWlyZSgnLi8kLmN0eCcpXG4gICwgUFJPVE9UWVBFID0gJ3Byb3RvdHlwZSc7XG5cbnZhciAkZXhwb3J0ID0gZnVuY3Rpb24odHlwZSwgbmFtZSwgc291cmNlKXtcbiAgdmFyIElTX0ZPUkNFRCA9IHR5cGUgJiAkZXhwb3J0LkZcbiAgICAsIElTX0dMT0JBTCA9IHR5cGUgJiAkZXhwb3J0LkdcbiAgICAsIElTX1NUQVRJQyA9IHR5cGUgJiAkZXhwb3J0LlNcbiAgICAsIElTX1BST1RPICA9IHR5cGUgJiAkZXhwb3J0LlBcbiAgICAsIElTX0JJTkQgICA9IHR5cGUgJiAkZXhwb3J0LkJcbiAgICAsIElTX1dSQVAgICA9IHR5cGUgJiAkZXhwb3J0LldcbiAgICAsIGV4cG9ydHMgICA9IElTX0dMT0JBTCA/IGNvcmUgOiBjb3JlW25hbWVdIHx8IChjb3JlW25hbWVdID0ge30pXG4gICAgLCB0YXJnZXQgICAgPSBJU19HTE9CQUwgPyBnbG9iYWwgOiBJU19TVEFUSUMgPyBnbG9iYWxbbmFtZV0gOiAoZ2xvYmFsW25hbWVdIHx8IHt9KVtQUk9UT1RZUEVdXG4gICAgLCBrZXksIG93biwgb3V0O1xuICBpZihJU19HTE9CQUwpc291cmNlID0gbmFtZTtcbiAgZm9yKGtleSBpbiBzb3VyY2Upe1xuICAgIC8vIGNvbnRhaW5zIGluIG5hdGl2ZVxuICAgIG93biA9ICFJU19GT1JDRUQgJiYgdGFyZ2V0ICYmIGtleSBpbiB0YXJnZXQ7XG4gICAgaWYob3duICYmIGtleSBpbiBleHBvcnRzKWNvbnRpbnVlO1xuICAgIC8vIGV4cG9ydCBuYXRpdmUgb3IgcGFzc2VkXG4gICAgb3V0ID0gb3duID8gdGFyZ2V0W2tleV0gOiBzb3VyY2Vba2V5XTtcbiAgICAvLyBwcmV2ZW50IGdsb2JhbCBwb2xsdXRpb24gZm9yIG5hbWVzcGFjZXNcbiAgICBleHBvcnRzW2tleV0gPSBJU19HTE9CQUwgJiYgdHlwZW9mIHRhcmdldFtrZXldICE9ICdmdW5jdGlvbicgPyBzb3VyY2Vba2V5XVxuICAgIC8vIGJpbmQgdGltZXJzIHRvIGdsb2JhbCBmb3IgY2FsbCBmcm9tIGV4cG9ydCBjb250ZXh0XG4gICAgOiBJU19CSU5EICYmIG93biA/IGN0eChvdXQsIGdsb2JhbClcbiAgICAvLyB3cmFwIGdsb2JhbCBjb25zdHJ1Y3RvcnMgZm9yIHByZXZlbnQgY2hhbmdlIHRoZW0gaW4gbGlicmFyeVxuICAgIDogSVNfV1JBUCAmJiB0YXJnZXRba2V5XSA9PSBvdXQgPyAoZnVuY3Rpb24oQyl7XG4gICAgICB2Y
23459XIgRiA9IGZ1bmN0aW9uKHBhcmFtKXtcbiAgICAgICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBDID8gbmV3IEMocGFyYW0pIDogQyhwYXJhbSk7XG4gICAgICB9O1xuICAgICAgRltQUk9UT1RZUEVdID0gQ1tQUk9UT1RZUEVdO1xuICAgICAgcmV0dXJuIEY7XG4gICAgLy8gbWFrZSBzdGF0aWMgdmVyc2lvbnMgZm9yIHByb3RvdHlwZSBtZXRob2RzXG4gICAgfSkob3V0KSA6IElTX1BST1RPICYmIHR5cGVvZiBvdXQgPT0gJ2Z1bmN0aW9uJyA/IGN0eChGdW5jdGlvbi5jYWxsLCBvdXQpIDogb3V0O1xuICAgIGlmKElTX1BST1RPKShleHBvcnRzW1BST1RPVFlQRV0gfHwgKGV4cG9ydHNbUFJPVE9UWVBFXSA9IHt9KSlba2V5XSA9IG91dDtcbiAgfVxufTtcbi8vIHR5cGUgYml0bWFwXG4kZXhwb3J0LkYgPSAxOyAgLy8gZm9yY2VkXG4kZXhwb3J0LkcgPSAyOyAgLy8gZ2xvYmFsXG4kZXhwb3J0LlMgPSA0OyAgLy8gc3RhdGljXG4kZXhwb3J0LlAgPSA4OyAgLy8gcHJvdG9cbiRleHBvcnQuQiA9IDE2OyAvLyBiaW5kXG4kZXhwb3J0LlcgPSAzMjsgLy8gd3JhcFxubW9kdWxlLmV4cG9ydHMgPSAkZXhwb3J0OyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZXhlYyl7XG4gIHRyeSB7XG4gICAgcmV0dXJuICEhZXhlYygpO1xuICB9IGNhdGNoKGUpe1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59OyIsInZhciBjdHggICAgICAgICA9IHJlcXVpcmUoJy4vJC5jdHgnKVxuICAsIGNhbGwgICAgICAgID0gcmVxdWlyZSgnLi8kLml0ZXItY2FsbCcpXG4gICwgaXNBcnJheUl0ZXIgPSByZXF1aXJlKCcuLyQuaXMtYXJyYXktaXRlcicpXG4gICwgYW5PYmplY3QgICAgPSByZXF1aXJlKCcuLyQuYW4tb2JqZWN0JylcbiAgLCB0b0xlbmd0aCAgICA9IHJlcXVpcmUoJy4vJC50by1sZW5ndGgnKVxuICAsIGdldEl0ZXJGbiAgID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXRlcmFibGUsIGVudHJpZXMsIGZuLCB0aGF0KXtcbiAgdmFyIGl0ZXJGbiA9IGdldEl0ZXJGbihpdGVyYWJsZSlcbiAgICAsIGYgICAgICA9IGN0eChmbiwgdGhhdCwgZW50cmllcyA/IDIgOiAxKVxuICAgICwgaW5kZXggID0gMFxuICAgICwgbGVuZ3RoLCBzdGVwLCBpdGVyYXRvcjtcbiAgaWYodHlwZW9mIGl0ZXJGbiAhPSAnZnVuY3Rpb24nKXRocm93IFR5cGVFcnJvcihpdGVyYWJsZSArICcgaXMgbm90IGl0ZXJhYmxlIScpO1xuICAvLyBmYXN0IGNhc2UgZm9yIGFycmF5cyB3aXRoIGRlZmF1bHQgaXRlcmF0b3JcbiAgaWYoaXNBcnJheUl0ZXIoaXRlckZuKSlmb3IobGVuZ3RoID0gdG9MZW5ndGgoaXRlcmFibGUubGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4Kyspe1xuICAgIGVudHJpZXMgPyBmKGFuT2JqZWN0KHN0ZXAgPSBpdGVyYWJsZVtpbmRleF0pWzBdLCBzdGVwWzFdKSA6IGYoaXRlcmFibGVbaW5kZXhdKTtcbiAgfSBlbHNlIGZvcihpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKGl0ZXJhYmxlKTsgIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lOyApe1xuICAgIGNhbGwoaXRlcmF0b3IsIGYsIHN0ZXAudmFsdWUsIGVudHJpZXMpO1xuICB9XG59OyIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy84NiNpc3N1ZWNvbW1lbnQtMTE1NzU5MDI4XG52YXIgZ2xvYmFsID0gbW9kdWxlLmV4cG9ydHMgPSB0eXBlb2Ygd2luZG93ICE9ICd1bmRlZmluZWQnICYmIHdpbmRvdy5NYXRoID09IE1hdGhcbiAgPyB3aW5kb3cgOiB0eXBlb2Ygc2VsZiAhPSAndW5kZWZpbmVkJyAmJiBzZWxmLk1hdGggPT0gTWF0aCA/IHNlbGYgOiBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xuaWYodHlwZW9mIF9fZyA9PSAnbnVtYmVyJylfX2cgPSBnbG9iYWw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWYiLCJ2YXIgaGFzT3duUHJvcGVydHkgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIGtleSl7XG4gIHJldHVybiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGl0LCBrZXkpO1xufTsiLCJ2YXIgJCAgICAgICAgICA9IHJlcXVpcmUoJy4vJCcpXG4gICwgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vJC5wcm9wZXJ0eS1kZXNjJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vJC5kZXNjcmlwdG9ycycpID8gZnVuY3Rpb24ob2JqZWN0LCBrZXksIHZhbHVlKXtcbiAgcmV0dXJuICQuc2V0RGVzYyhvYmplY3QsIGtleSwgY3JlYXRlRGVzYygxLCB2YWx1ZSkpO1xufSA6IGZ1bmN0aW9uKG9iamVjdCwga2V5LCB2YWx1ZSl7XG4gIG9iamVjdFtrZXldID0gdmFsdWU7XG4gIHJldHVybiBvYmplY3Q7XG59OyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi8kLmdsb2JhbCcpLmRvY3VtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDsiLCIvLyBmYXN0IGFwcGx5LCBodHRwOi8vanNwZXJmLmxua2l0LmNvbS9mYXN0LWFwcGx5LzVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm4sIGFyZ3MsIHRoYXQpe1xuICB2YXIgdW4gPSB0aGF0ID09PSB1bmRlZmluZWQ7XG4gIHN3aXRjaChhcmdzLmxlbmd0aCl7XG4gICAgY2FzZSAwOiByZXR1cm4gdW4gPyBmbigpXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQpO1xuICAgIGNhc2UgMTogcmV0dXJuIHVuID8gZm4oYXJnc1swXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSk7XG4gICAgY2FzZSAyOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICBjYXNlIDM6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgIGNhc2UgNDogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSk7XG4gIH0gcmV0dXJuICAgICAgICAgICAgICBmbi5hcHBseSh0aGF0LCBhcmdzKTtcbn07IiwiLy8gZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBhbmQgbm9uLWVudW1lcmFibGUgb2xkIFY4IHN0cmluZ3NcbnZhciBjb2YgPSByZXF1aXJlKCcuLyQuY29mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdCgneicpLnByb3BlcnR5SXNFbnVtZXJhYmxlKDApID8gT2JqZWN0IDogZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gY29mKGl0KSA9PSAnU3RyaW5nJyA/IGl0LnNwbGl0KCcnKSA6IE9iamVjdChpdCk7XG59OyIsIi8vIGNoZWNrIG9uIGRlZmF1bHQgQXJyYXkgaXRlcmF0b3JcbnZhciBJdGVyYXRvcnMgID0gcmVxdWlyZSgnLi8kLml0ZXJhdG9ycycpXG4gICwgSVRFUkFUT1IgICA9IHJlcXVpcmUoJy4vJC53a3MnKSgnaXRlcmF0b3InKVxuICAsIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gaXQgIT09IHVuZGVmaW5lZCAmJiAoSXRlcmF0b3JzLkFycmF5ID09PSBpdCB8fCBBcnJheVByb3RvW0lURVJBVE9SXSA9PT0gaXQpO1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIHR5cGVvZiBpdCA9PT0gJ29iamVjdCcgPyBpdCAhPT0gbnVsbCA6IHR5cGVvZiBpdCA9PT0gJ2Z1bmN0aW9uJztcbn07IiwiLy8gY2FsbCBzb21ldGhpbmcgb24gaXRlcmF0b3Igc3RlcCB3aXRoIHNhZmUgY2xvc2luZyBvbiBlcnJvclxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi8kLmFuLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdGVyYXRvciwgZm4sIHZhbHVlLCBlbnRyaWVzKXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZW50cmllcyA/IGZuKGFuT2JqZWN0KHZhbHVlKVswXSwgdmFsdWVbMV0pIDogZm4odmFsdWUpO1xuICAvLyA3LjQuNiBJdGVyYXRvckNsb3NlKGl0ZXJhdG9yLCBjb21wbGV0aW9uKVxuICB9IGNhdGNoKGUpe1xuICAgIHZhciByZXQgPSBpdGVyYXRvclsncmV0dXJuJ107XG4gICAgaWYocmV0ICE9PSB1bmRlZmluZWQpYW5PYmplY3QocmV0LmNhbGwoaXRlcmF0b3IpKTtcbiAgICB0aHJvdyBlO1xuICB9XG59OyIsIid1c2Ugc3RyaWN0JztcbnZhciAkICAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vJCcpXG4gICwgZGVzY3JpcHRvciAgICAgPSByZXF1aXJlKCcuLyQucHJvcGVydHktZGVzYycpXG4gICwgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuLyQuc2V0LXRvLXN0cmluZy10YWcnKVxuICAsIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG5cbi8vIDI1LjEuMi4xLjEgJUl0ZXJhdG9yUHJvdG90eXBlJVtAQGl0ZXJhdG9yXSgpXG5yZXF1aXJlKCcuLyQuaGlkZScpKEl0ZXJhdG9yUHJvdG90eXBlLCByZXF1aXJlKCcuLyQud2tzJykoJ2l0ZXJhdG9yJyksIGZ1bmN0aW9uKCl7IHJldHVybi
23459B0aGlzOyB9KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCl7XG4gIENvbnN0cnVjdG9yLnByb3RvdHlwZSA9ICQuY3JlYXRlKEl0ZXJhdG9yUHJvdG90eXBlLCB7bmV4dDogZGVzY3JpcHRvcigxLCBuZXh0KX0pO1xuICBzZXRUb1N0cmluZ1RhZyhDb25zdHJ1Y3RvciwgTkFNRSArICcgSXRlcmF0b3InKTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgICAgICAgID0gcmVxdWlyZSgnLi8kLmxpYnJhcnknKVxuICAsICRleHBvcnQgICAgICAgID0gcmVxdWlyZSgnLi8kLmV4cG9ydCcpXG4gICwgcmVkZWZpbmUgICAgICAgPSByZXF1aXJlKCcuLyQucmVkZWZpbmUnKVxuICAsIGhpZGUgICAgICAgICAgID0gcmVxdWlyZSgnLi8kLmhpZGUnKVxuICAsIGhhcyAgICAgICAgICAgID0gcmVxdWlyZSgnLi8kLmhhcycpXG4gICwgSXRlcmF0b3JzICAgICAgPSByZXF1aXJlKCcuLyQuaXRlcmF0b3JzJylcbiAgLCAkaXRlckNyZWF0ZSAgICA9IHJlcXVpcmUoJy4vJC5pdGVyLWNyZWF0ZScpXG4gICwgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuLyQuc2V0LXRvLXN0cmluZy10YWcnKVxuICAsIGdldFByb3RvICAgICAgID0gcmVxdWlyZSgnLi8kJykuZ2V0UHJvdG9cbiAgLCBJVEVSQVRPUiAgICAgICA9IHJlcXVpcmUoJy4vJC53a3MnKSgnaXRlcmF0b3InKVxuICAsIEJVR0dZICAgICAgICAgID0gIShbXS5rZXlzICYmICduZXh0JyBpbiBbXS5rZXlzKCkpIC8vIFNhZmFyaSBoYXMgYnVnZ3kgaXRlcmF0b3JzIHcvbyBgbmV4dGBcbiAgLCBGRl9JVEVSQVRPUiAgICA9ICdAQGl0ZXJhdG9yJ1xuICAsIEtFWVMgICAgICAgICAgID0gJ2tleXMnXG4gICwgVkFMVUVTICAgICAgICAgPSAndmFsdWVzJztcblxudmFyIHJldHVyblRoaXMgPSBmdW5jdGlvbigpeyByZXR1cm4gdGhpczsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihCYXNlLCBOQU1FLCBDb25zdHJ1Y3RvciwgbmV4dCwgREVGQVVMVCwgSVNfU0VULCBGT1JDRUQpe1xuICAkaXRlckNyZWF0ZShDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCk7XG4gIHZhciBnZXRNZXRob2QgPSBmdW5jdGlvbihraW5kKXtcbiAgICBpZighQlVHR1kgJiYga2luZCBpbiBwcm90bylyZXR1cm4gcHJvdG9ba2luZF07XG4gICAgc3dpdGNoKGtpbmQpe1xuICAgICAgY2FzZSBLRVlTOiByZXR1cm4gZnVuY3Rpb24ga2V5cygpeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICAgICAgY2FzZSBWQUxVRVM6IHJldHVybiBmdW5jdGlvbiB2YWx1ZXMoKXsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgICB9IHJldHVybiBmdW5jdGlvbiBlbnRyaWVzKCl7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gIH07XG4gIHZhciBUQUcgICAgICAgID0gTkFNRSArICcgSXRlcmF0b3InXG4gICAgLCBERUZfVkFMVUVTID0gREVGQVVMVCA9PSBWQUxVRVNcbiAgICAsIFZBTFVFU19CVUcgPSBmYWxzZVxuICAgICwgcHJvdG8gICAgICA9IEJhc2UucHJvdG90eXBlXG4gICAgLCAkbmF0aXZlICAgID0gcHJvdG9bSVRFUkFUT1JdIHx8IHByb3RvW0ZGX0lURVJBVE9SXSB8fCBERUZBVUxUICYmIHByb3RvW0RFRkFVTFRdXG4gICAgLCAkZGVmYXVsdCAgID0gJG5hdGl2ZSB8fCBnZXRNZXRob2QoREVGQVVMVClcbiAgICAsIG1ldGhvZHMsIGtleTtcbiAgLy8gRml4IG5hdGl2ZVxuICBpZigkbmF0aXZlKXtcbiAgICB2YXIgSXRlcmF0b3JQcm90b3R5cGUgPSBnZXRQcm90bygkZGVmYXVsdC5jYWxsKG5ldyBCYXNlKSk7XG4gICAgLy8gU2V0IEBAdG9TdHJpbmdUYWcgdG8gbmF0aXZlIGl0ZXJhdG9yc1xuICAgIHNldFRvU3RyaW5nVGFnKEl0ZXJhdG9yUHJvdG90eXBlLCBUQUcsIHRydWUpO1xuICAgIC8vIEZGIGZpeFxuICAgIGlmKCFMSUJSQVJZICYmIGhhcyhwcm90bywgRkZfSVRFUkFUT1IpKWhpZGUoSXRlcmF0b3JQcm90b3R5cGUsIElURVJBVE9SLCByZXR1cm5UaGlzKTtcbiAgICAvLyBmaXggQXJyYXkje3ZhbHVlcywgQEBpdGVyYXRvcn0ubmFtZSBpbiBWOCAvIEZGXG4gICAgaWYoREVGX1ZBTFVFUyAmJiAkbmF0aXZlLm5hbWUgIT09IFZBTFVFUyl7XG4gICAgICBWQUxVRVNfQlVHID0gdHJ1ZTtcbiAgICAgICRkZWZhdWx0ID0gZnVuY3Rpb24gdmFsdWVzKCl7IHJldHVybiAkbmF0aXZlLmNhbGwodGhpcyk7IH07XG4gICAgfVxuICB9XG4gIC8vIERlZmluZSBpdGVyYXRvclxuICBpZigoIUxJQlJBUlkgfHwgRk9SQ0VEKSAmJiAoQlVHR1kgfHwgVkFMVUVTX0JVRyB8fCAhcHJvdG9bSVRFUkFUT1JdKSl7XG4gICAgaGlkZShwcm90bywgSVRFUkFUT1IsICRkZWZhdWx0KTtcbiAgfVxuICAvLyBQbHVnIGZvciBsaWJyYXJ5XG4gIEl0ZXJhdG9yc1tOQU1FXSA9ICRkZWZhdWx0O
234591xuICBJdGVyYXRvcnNbVEFHXSAgPSByZXR1cm5UaGlzO1xuICBpZihERUZBVUxUKXtcbiAgICBtZXRob2RzID0ge1xuICAgICAgdmFsdWVzOiAgREVGX1ZBTFVFUyAgPyAkZGVmYXVsdCA6IGdldE1ldGhvZChWQUxVRVMpLFxuICAgICAga2V5czogICAgSVNfU0VUICAgICAgPyAkZGVmYXVsdCA6IGdldE1ldGhvZChLRVlTKSxcbiAgICAgIGVudHJpZXM6ICFERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoJ2VudHJpZXMnKVxuICAgIH07XG4gICAgaWYoRk9SQ0VEKWZvcihrZXkgaW4gbWV0aG9kcyl7XG4gICAgICBpZighKGtleSBpbiBwcm90bykpcmVkZWZpbmUocHJvdG8sIGtleSwgbWV0aG9kc1trZXldKTtcbiAgICB9IGVsc2UgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoQlVHR1kgfHwgVkFMVUVTX0JVRyksIE5BTUUsIG1ldGhvZHMpO1xuICB9XG4gIHJldHVybiBtZXRob2RzO1xufTsiLCJ2YXIgSVRFUkFUT1IgICAgID0gcmVxdWlyZSgnLi8kLndrcycpKCdpdGVyYXRvcicpXG4gICwgU0FGRV9DTE9TSU5HID0gZmFsc2U7XG5cbnRyeSB7XG4gIHZhciByaXRlciA9IFs3XVtJVEVSQVRPUl0oKTtcbiAgcml0ZXJbJ3JldHVybiddID0gZnVuY3Rpb24oKXsgU0FGRV9DTE9TSU5HID0gdHJ1ZTsgfTtcbiAgQXJyYXkuZnJvbShyaXRlciwgZnVuY3Rpb24oKXsgdGhyb3cgMjsgfSk7XG59IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZXhlYywgc2tpcENsb3Npbmcpe1xuICBpZighc2tpcENsb3NpbmcgJiYgIVNBRkVfQ0xPU0lORylyZXR1cm4gZmFsc2U7XG4gIHZhciBzYWZlID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgdmFyIGFyciAgPSBbN11cbiAgICAgICwgaXRlciA9IGFycltJVEVSQVRPUl0oKTtcbiAgICBpdGVyLm5leHQgPSBmdW5jdGlvbigpeyByZXR1cm4ge2RvbmU6IHNhZmUgPSB0cnVlfTsgfTtcbiAgICBhcnJbSVRFUkFUT1JdID0gZnVuY3Rpb24oKXsgcmV0dXJuIGl0ZXI7IH07XG4gICAgZXhlYyhhcnIpO1xuICB9IGNhdGNoKGUpeyAvKiBlbXB0eSAqLyB9XG4gIHJldHVybiBzYWZlO1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGRvbmUsIHZhbHVlKXtcbiAgcmV0dXJuIHt2YWx1ZTogdmFsdWUsIGRvbmU6ICEhZG9uZX07XG59OyIsIm1vZHVsZS5leHBvcnRzID0ge307IiwidmFyICRPYmplY3QgPSBPYmplY3Q7XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY3JlYXRlOiAgICAgJE9iamVjdC5jcmVhdGUsXG4gIGdldFByb3RvOiAgICRPYmplY3QuZ2V0UHJvdG90eXBlT2YsXG4gIGlzRW51bTogICAgIHt9LnByb3BlcnR5SXNFbnVtZXJhYmxlLFxuICBnZXREZXNjOiAgICAkT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcixcbiAgc2V0RGVzYzogICAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0eSxcbiAgc2V0RGVzY3M6ICAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzLFxuICBnZXRLZXlzOiAgICAkT2JqZWN0LmtleXMsXG4gIGdldE5hbWVzOiAgICRPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyxcbiAgZ2V0U3ltYm9sczogJE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMsXG4gIGVhY2g6ICAgICAgIFtdLmZvckVhY2hcbn07IiwibW9kdWxlLmV4cG9ydHMgPSB0cnVlOyIsInZhciBnbG9iYWwgICAgPSByZXF1aXJlKCcuLyQuZ2xvYmFsJylcbiAgLCBtYWNyb3Rhc2sgPSByZXF1aXJlKCcuLyQudGFzaycpLnNldFxuICAsIE9ic2VydmVyICA9IGdsb2JhbC5NdXRhdGlvbk9ic2VydmVyIHx8IGdsb2JhbC5XZWJLaXRNdXRhdGlvbk9ic2VydmVyXG4gICwgcHJvY2VzcyAgID0gZ2xvYmFsLnByb2Nlc3NcbiAgLCBQcm9taXNlICAgPSBnbG9iYWwuUHJvbWlzZVxuICAsIGlzTm9kZSAgICA9IHJlcXVpcmUoJy4vJC5jb2YnKShwcm9jZXNzKSA9PSAncHJvY2VzcydcbiAgLCBoZWFkLCBsYXN0LCBub3RpZnk7XG5cbnZhciBmbHVzaCA9IGZ1bmN0aW9uKCl7XG4gIHZhciBwYXJlbnQsIGRvbWFpbiwgZm47XG4gIGlmKGlzTm9kZSAmJiAocGFyZW50ID0gcHJvY2Vzcy5kb21haW4pKXtcbiAgICBwcm9jZXNzLmRvbWFpbiA9IG51bGw7XG4gICAgcGFyZW50LmV4aXQoKTtcbiAgfVxuICB3aGlsZShoZWFkKXtcbiAgICBkb21haW4gPSBoZWFkLmRvbWFpbjtcbiAgICBmbiAgICAgPSBoZWFkLmZuO1xuICAgIGlmKGRvbWFpbilkb21haW4uZW50ZXIoKTtcbiAgICBmbigpOyAvLyA8LSBjdXJyZW50bHkgd2UgdXNlIGl0IG9ubHkgZm9yIFByb21pc2UgLSB0cnkgLyBjYXRjaCBub3QgcmVxdWlyZWRcbiAgICBpZihkb21haW4pZG9tYWluLmV4aXQoKTtcbiAgICBoZWFkID0gaGVhZC5uZXh0O1xuICB9IGxhc3QgPSB1bmRlZmluZWQ7XG4gIGlmKHBhcmVudClwYXJlbnQuZW50ZXIoKTtcbn07XG5cbi8vIE5vZGUuanNcbmlmKGlzTm9kZSl7XG4gIG5vdGlmeSA9IGZ1bmN0aW9uKCl7XG4gICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gIH07XG4vLyBicm93c2VycyB3aXRoIE11dGF0aW9uT2JzZXJ2ZXJcbn0gZWxzZSBpZihPYnNlcnZlcil7XG4gIHZhciB0b2dnbGUgPSAxXG4gICAgLCBub2RlICAgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJyk7XG4gIG5ldyBPYnNlcnZlcihmbHVzaCkub2JzZXJ2ZShub2RlLCB7Y2hhcmFjdGVyRGF0YTogdHJ1ZX0pOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICBub3RpZnkgPSBmdW5jdGlvbigpe1xuICAgIG5vZGUuZGF0YSA9IHRvZ2dsZSA9IC10b2dnbGU7XG4gIH07XG4vLyBlbnZpcm9ubWVudHMgd2l0aCBtYXliZSBub24tY29tcGxldGVseSBjb3JyZWN0LCBidXQgZXhpc3RlbnQgUHJvbWlzZVxufSBlbHNlIGlmKFByb21pc2UgJiYgUHJvbWlzZS5yZXNvbHZlKXtcbiAgbm90aWZ5ID0gZnVuY3Rpb24oKXtcbiAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZsdXNoKTtcbiAgfTtcbi8vIGZvciBvdGhlciBlbnZpcm9ubWVudHMgLSBtYWNyb3Rhc2sgYmFzZWQgb246XG4vLyAtIHNldEltbWVkaWF0ZVxuLy8gLSBNZXNzYWdlQ2hhbm5lbFxuLy8gLSB3aW5kb3cucG9zdE1lc3NhZ1xuLy8gLSBvbnJlYWR5c3RhdGVjaGFuZ2Vcbi8vIC0gc2V0VGltZW91dFxufSBlbHNlIHtcbiAgbm90aWZ5ID0gZnVuY3Rpb24oKXtcbiAgICAvLyBzdHJhbmdlIElFICsgd2VicGFjayBkZXYgc2VydmVyIGJ1ZyAtIHVzZSAuY2FsbChnbG9iYWwpXG4gICAgbWFjcm90YXNrLmNhbGwoZ2xvYmFsLCBmbHVzaCk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYXNhcChmbil7XG4gIHZhciB0YXNrID0ge2ZuOiBmbiwgbmV4dDogdW5kZWZpbmVkLCBkb21haW46IGlzTm9kZSAmJiBwcm9jZXNzLmRvbWFpbn07XG4gIGlmKGxhc3QpbGFzdC5uZXh0ID0gdGFzaztcbiAgaWYoIWhlYWQpe1xuICAgIGhlYWQgPSB0YXNrO1xuICAgIG5vdGlmeSgpO1xuICB9IGxhc3QgPSB0YXNrO1xufTsiLCIvLyAxOS4xLjIuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlLCAuLi4pXG52YXIgJCAgICAgICAgPSByZXF1aXJlKCcuLyQnKVxuICAsIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi8kLnRvLW9iamVjdCcpXG4gICwgSU9iamVjdCAgPSByZXF1aXJlKCcuLyQuaW9iamVjdCcpO1xuXG4vLyBzaG91bGQgd29yayB3aXRoIHN5bWJvbHMgYW5kIHNob3VsZCBoYXZlIGRldGVybWluaXN0aWMgcHJvcGVydHkgb3JkZXIgKFY4IGJ1Zylcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi8kLmZhaWxzJykoZnVuY3Rpb24oKXtcbiAgdmFyIGEgPSBPYmplY3QuYXNzaWduXG4gICAgLCBBID0ge31cbiAgICAsIEIgPSB7fVxuICAgICwgUyA9IFN5bWJvbCgpXG4gICAgLCBLID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0JztcbiAgQVtTXSA9IDc7XG4gIEsuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24oayl7IEJba10gPSBrOyB9KTtcbiAgcmV0dXJuIGEoe30sIEEpW1NdICE9IDcgfHwgT2JqZWN0LmtleXMoYSh7fSwgQikpLmpvaW4oJycpICE9IEs7XG59
23459KSA/IGZ1bmN0aW9uIGFzc2lnbih0YXJnZXQsIHNvdXJjZSl7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgdmFyIFQgICAgID0gdG9PYmplY3QodGFyZ2V0KVxuICAgICwgJCQgICAgPSBhcmd1bWVudHNcbiAgICAsICQkbGVuID0gJCQubGVuZ3RoXG4gICAgLCBpbmRleCA9IDFcbiAgICAsIGdldEtleXMgICAgPSAkLmdldEtleXNcbiAgICAsIGdldFN5bWJvbHMgPSAkLmdldFN5bWJvbHNcbiAgICAsIGlzRW51bSAgICAgPSAkLmlzRW51bTtcbiAgd2hpbGUoJCRsZW4gPiBpbmRleCl7XG4gICAgdmFyIFMgICAgICA9IElPYmplY3QoJCRbaW5kZXgrK10pXG4gICAgICAsIGtleXMgICA9IGdldFN5bWJvbHMgPyBnZXRLZXlzKFMpLmNvbmNhdChnZXRTeW1ib2xzKFMpKSA6IGdldEtleXMoUylcbiAgICAgICwgbGVuZ3RoID0ga2V5cy5sZW5ndGhcbiAgICAgICwgaiAgICAgID0gMFxuICAgICAgLCBrZXk7XG4gICAgd2hpbGUobGVuZ3RoID4gailpZihpc0VudW0uY2FsbChTLCBrZXkgPSBrZXlzW2orK10pKVRba2V5XSA9IFNba2V5XTtcbiAgfVxuICByZXR1cm4gVDtcbn0gOiBPYmplY3QuYXNzaWduOyIsIi8vIG1vc3QgT2JqZWN0IG1ldGhvZHMgYnkgRVM2IHNob3VsZCBhY2NlcHQgcHJpbWl0aXZlc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuLyQuZXhwb3J0JylcbiAgLCBjb3JlICAgID0gcmVxdWlyZSgnLi8kLmNvcmUnKVxuICAsIGZhaWxzICAgPSByZXF1aXJlKCcuLyQuZmFpbHMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oS0VZLCBleGVjKXtcbiAgdmFyIGZuICA9IChjb3JlLk9iamVjdCB8fCB7fSlbS0VZXSB8fCBPYmplY3RbS0VZXVxuICAgICwgZXhwID0ge307XG4gIGV4cFtLRVldID0gZXhlYyhmbik7XG4gICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogZmFpbHMoZnVuY3Rpb24oKXsgZm4oMSk7IH0pLCAnT2JqZWN0JywgZXhwKTtcbn07IiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihiaXRtYXAsIHZhbHVlKXtcbiAgcmV0dXJuIHtcbiAgICBlbnVtZXJhYmxlICA6ICEoYml0bWFwICYgMSksXG4gICAgY29uZmlndXJhYmxlOiAhKGJpdG1hcCAmIDIpLFxuICAgIHdyaXRhYmxlICAgIDogIShiaXRtYXAgJiA0KSxcbiAgICB2YWx1ZSAgICAgICA6IHZhbHVlXG4gIH07XG59OyIsInZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vJC5yZWRlZmluZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih0YXJnZXQsIHNyYyl7XG4gIGZvcih2YXIga2V5IGluIHNyYylyZWRlZmluZSh0YXJnZXQsIGtleSwgc3JjW2tleV0pO1xuICByZXR1cm4gdGFyZ2V0O1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vJC5oaWRlJyk7IiwiLy8gNy4yLjkgU2FtZVZhbHVlKHgsIHkpXG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5pcyB8fCBmdW5jdGlvbiBpcyh4LCB5KXtcbiAgcmV0dXJuIHggPT09IHkgPyB4ICE9PSAwIHx8IDEgLyB4ID09PSAxIC8geSA6IHggIT0geCAmJiB5ICE9IHk7XG59OyIsIi8vIFdvcmtzIHdpdGggX19wcm90b19fIG9ubHkuIE9sZCB2OCBjYW4ndCB3b3JrIHdpdGggbnVsbCBwcm90byBvYmplY3RzLlxuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cbnZhciBnZXREZXNjICA9IHJlcXVpcmUoJy4vJCcpLmdldERlc2NcbiAgLCBpc09iamVjdCA9IHJlcXVpcmUoJy4vJC5pcy1vYmplY3QnKVxuICAsIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi8kLmFuLW9iamVjdCcpO1xudmFyIGNoZWNrID0gZnVuY3Rpb24oTywgcHJvdG8pe1xuICBhbk9iamVjdChPKTtcbiAgaWYoIWlzT2JqZWN0KHByb3RvKSAmJiBwcm90byAhPT0gbnVsbCl0aHJvdyBUeXBlRXJyb3IocHJvdG8gKyBcIjogY2FuJ3Qgc2V0IGFzIHByb3RvdHlwZSFcIik7XG59O1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNldDogT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8ICgnX19wcm90b19fJyBpbiB7fSA/IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgICBmdW5jdGlvbih0ZXN0LCBidWdneSwgc2V0KXtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNldCA9IHJlcXVpcmUoJy4vJC5jdHgnKShGdW5jdGlvbi5jYWxsLCBnZXREZXNjKE9iamVjdC5wcm90b3R5cGUsICdfX3Byb3RvX18nKS5zZXQsIDIpO1xuICAgICAgICBzZXQodGVzdCwgW10pO1xuICAgICAgICBidWdneSA9ICEodGVzdCBpbnN0YW5jZW9mIEFycmF5KTtcbiAgICAgIH0gY2F0Y2goZSl7IGJ1Z2d5ID0gdHJ1ZTsgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNldFByb3RvdHlwZU9mKE8sIHByb3RvKXtcbiAgICAgICAgY2hlY2soTywgcHJvdG8pO1xuICAgICAgICBpZihidWdneSlPLl9fcHJvdG9fXyA9IHByb3RvO1xuICAgICAgICBlbHNlIHNldChPLCBwcm90byk7XG4gICAgICAgIHJldHVybiBPO1xuICAgICAgfTtcbiAgICB9KHt9LCBmYWxzZSkgOiB1bmRlZmluZWQpLFxuICBjaGVjazogY2hlY2tcbn07IiwiJ3VzZSBzdHJpY3QnO1xudmFyIGNvcm
23459UgICAgICAgID0gcmVxdWlyZSgnLi8kLmNvcmUnKVxuICAsICQgICAgICAgICAgID0gcmVxdWlyZSgnLi8kJylcbiAgLCBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vJC5kZXNjcmlwdG9ycycpXG4gICwgU1BFQ0lFUyAgICAgPSByZXF1aXJlKCcuLyQud2tzJykoJ3NwZWNpZXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihLRVkpe1xuICB2YXIgQyA9IGNvcmVbS0VZXTtcbiAgaWYoREVTQ1JJUFRPUlMgJiYgQyAmJiAhQ1tTUEVDSUVTXSkkLnNldERlc2MoQywgU1BFQ0lFUywge1xuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzOyB9XG4gIH0pO1xufTsiLCJ2YXIgZGVmID0gcmVxdWlyZSgnLi8kJykuc2V0RGVzY1xuICAsIGhhcyA9IHJlcXVpcmUoJy4vJC5oYXMnKVxuICAsIFRBRyA9IHJlcXVpcmUoJy4vJC53a3MnKSgndG9TdHJpbmdUYWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCwgdGFnLCBzdGF0KXtcbiAgaWYoaXQgJiYgIWhhcyhpdCA9IHN0YXQgPyBpdCA6IGl0LnByb3RvdHlwZSwgVEFHKSlkZWYoaXQsIFRBRywge2NvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHRhZ30pO1xufTsiLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi8kLmdsb2JhbCcpXG4gICwgU0hBUkVEID0gJ19fY29yZS1qc19zaGFyZWRfXydcbiAgLCBzdG9yZSAgPSBnbG9iYWxbU0hBUkVEXSB8fCAoZ2xvYmFsW1NIQVJFRF0gPSB7fSk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGtleSl7XG4gIHJldHVybiBzdG9yZVtrZXldIHx8IChzdG9yZVtrZXldID0ge30pO1xufTsiLCIvLyA3LjMuMjAgU3BlY2llc0NvbnN0cnVjdG9yKE8sIGRlZmF1bHRDb25zdHJ1Y3RvcilcbnZhciBhbk9iamVjdCAgPSByZXF1aXJlKCcuLyQuYW4tb2JqZWN0JylcbiAgLCBhRnVuY3Rpb24gPSByZXF1aXJlKCcuLyQuYS1mdW5jdGlvbicpXG4gICwgU1BFQ0lFUyAgID0gcmVxdWlyZSgnLi8kLndrcycpKCdzcGVjaWVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKE8sIEQpe1xuICB2YXIgQyA9IGFuT2JqZWN0KE8pLmNvbnN0cnVjdG9yLCBTO1xuICByZXR1cm4gQyA9PT0gdW5kZWZpbmVkIHx8IChTID0gYW5PYmplY3QoQylbU1BFQ0lFU10pID09IHVuZGVmaW5lZCA/IEQgOiBhRnVuY3Rpb24oUyk7XG59OyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQsIENvbnN0cnVjdG9yLCBuYW1lKXtcbiAgaWYoIShpdCBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSl0aHJvdyBUeXBlRXJyb3IobmFtZSArIFwiOiB1c2UgdGhlICduZXcnIG9wZXJhdG9yIVwiKTtcbiAgcmV0dXJuIGl0O1xufTsiLCJ2YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi8kLnRvLWludGVnZXInKVxuICAsIGRlZmluZWQgICA9IHJlcXVpcmUoJy4vJC5kZWZpbmVkJyk7XG4vLyB0cnVlICAtPiBTdHJpbmcjYXRcbi8vIGZhbHNlIC0+IFN0cmluZyNjb2RlUG9pbnRBdFxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihUT19TVFJJTkcpe1xuICByZXR1cm4gZnVuY3Rpb24odGhhdCwgcG9zKXtcbiAgICB2YXIgcyA9IFN0cmluZyhkZWZpbmVkKHRoYXQpKVxuICAgICAgLCBpID0gdG9JbnRlZ2VyKHBvcylcbiAgICAgICwgbCA9IHMubGVuZ3RoXG4gICAgICAsIGEsIGI7XG4gICAgaWYoaSA8IDAgfHwgaSA+PSBsKXJldHVybiBUT19TVFJJTkcgPyAnJyA6IHVuZGVmaW5lZDtcbiAgICBhID0gcy5jaGFyQ29kZUF0KGkpO1xuICAgIHJldHVybiBhIDwgMHhkODAwIHx8IGEgPiAweGRiZmYgfHwgaSArIDEgPT09IGwgfHwgKGIgPSBzLmNoYXJDb2RlQXQoaSArIDEpKSA8IDB4ZGMwMCB8fCBiID4gMHhkZmZmXG4gICAgICA/IFRPX1NUUklORyA/IHMuY2hhckF0KGkpIDogYVxuICAgICAgOiBUT19TVFJJTkcgPyBzLnNsaWNlKGksIGkgKyAyKSA6IChhIC0gMHhkODAwIDw8IDEwKSArIChiIC0gMHhkYzAwKSArIDB4MTAwMDA7XG4gIH07XG59OyIsInZhciBjdHggICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuLyQuY3R4JylcbiAgLCBpbnZva2UgICAgICAgICAgICAgPSByZXF1aXJlKCcuLyQuaW52b2tlJylcbiAgLCBodG1sICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuLyQuaHRtbCcpXG4gICwgY2VsICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi8kLmRvbS1jcmVhdGUnKVxuICAsIGdsb2JhbCAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vJC5nbG9iYWwnKVxuICAsIHByb2Nlc3MgICAgICAgICAgICA9IGdsb2JhbC5wcm9jZXNzXG4gICwgc2V0VGFzayAgICAgICAgICAgID0gZ2xvYmFsLnNldEltbWVkaWF0ZVxuICAsIGNsZWFyVGFzayAgICAgICAgICA9IGdsb2JhbC5jbGVhckltbWVkaWF0ZVxuICAsIE1lc3NhZ2VDaGFubmVsICAgICA9IGdsb2JhbC5NZXNzYWdlQ2hhbm5lbFxuICAsIGNvdW50ZXIgICAgICAgICAgICA9IDBcbiAgLCBxdWV1ZSAgICAgICAgICAgICAgPSB7fVxuICAsIE9OUkVBRFlTVEFURUNIQU5HRSA9ICdvbnJlYWR5c3RhdGVjaGFuZ2UnXG4gICwgZGVmZXIsIGNoYW5uZWwsIHBvcnQ7XG52YXIgcnVuID0gZnVuY3Rpb24oKXtcbiAgdmFyIGlkID0gK3RoaXM7XG4gIGlmKHF1ZXVlLmhhc093blByb3BlcnR5KGlkKSl7XG4gICAgdmFyIGZuID0gcXVldWVbaWRdO1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gICAgZm4oKTtcbiAgfVxufTtcbnZhciBsaXN0bmVyID0gZnVuY3Rpb24oZXZlbnQpe1xuICBydW4uY2FsbChldmVudC5kYXRhKTtcbn07XG4vLyBOb2RlLmpzIDAuOSsgJiBJRTEwKyBoYXMgc2V0SW1tZWRpYXRlLCBvdGhlcndpc2U6XG5pZighc2V0VGFzayB8fCAhY2xlYXJUYXNrKXtcbiAgc2V0VGFzayA9IGZ1bmN0aW9uIHNldEltbWVkaWF0ZShmbil7XG4gICAgdmFyIGFyZ3MgPSBbXSwgaSA9IDE7XG4gICAgd2hpbGUoYXJndW1lbnRzLmxlbmd0aCA+IGkpYXJncy5wdXNoKGFyZ3VtZW50c1tpKytdKTtcbiAgICBxdWV1ZVsrK2NvdW50ZXJdID0gZnVuY3Rpb24oKXtcbiAgICAgIGludm9rZSh0eXBlb2YgZm4gPT0gJ2Z1bmN0aW9uJyA/IGZuIDogRnVuY3Rpb24oZm4pLCBhcmdzKTtcbiAgICB9O1xuICAgIGRlZmVyKGNvdW50ZXIpO1xuICAgIHJldHVybi
23459Bjb3VudGVyO1xuICB9O1xuICBjbGVhclRhc2sgPSBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZShpZCl7XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgfTtcbiAgLy8gTm9kZS5qcyAwLjgtXG4gIGlmKHJlcXVpcmUoJy4vJC5jb2YnKShwcm9jZXNzKSA9PSAncHJvY2Vzcycpe1xuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhjdHgocnVuLCBpZCwgMSkpO1xuICAgIH07XG4gIC8vIEJyb3dzZXJzIHdpdGggTWVzc2FnZUNoYW5uZWwsIGluY2x1ZGVzIFdlYldvcmtlcnNcbiAgfSBlbHNlIGlmKE1lc3NhZ2VDaGFubmVsKXtcbiAgICBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsO1xuICAgIHBvcnQgICAgPSBjaGFubmVsLnBvcnQyO1xuICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gbGlzdG5lcjtcbiAgICBkZWZlciA9IGN0eChwb3J0LnBvc3RNZXNzYWdlLCBwb3J0LCAxKTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBwb3N0TWVzc2FnZSwgc2tpcCBXZWJXb3JrZXJzXG4gIC8vIElFOCBoYXMgcG9zdE1lc3NhZ2UsIGJ1dCBpdCdzIHN5bmMgJiB0eXBlb2YgaXRzIHBvc3RNZXNzYWdlIGlzICdvYmplY3QnXG4gIH0gZWxzZSBpZihnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lciAmJiB0eXBlb2YgcG9zdE1lc3NhZ2UgPT0gJ2Z1bmN0aW9uJyAmJiAhZ2xvYmFsLmltcG9ydFNjcmlwdHMpe1xuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xuICAgICAgZ2xvYmFsLnBvc3RNZXNzYWdlKGlkICsgJycsICcqJyk7XG4gICAgfTtcbiAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGxpc3RuZXIsIGZhbHNlKTtcbiAgLy8gSUU4LVxuICB9IGVsc2UgaWYoT05SRUFEWVNUQVRFQ0hBTkdF
23459IGluIGNlbCgnc2NyaXB0Jykpe1xuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xuICAgICAgaHRtbC5hcHBlbmRDaGlsZChjZWwoJ3NjcmlwdCcpKVtPTlJFQURZU1RBVEVDSEFOR0VdID0gZnVuY3Rpb24oKXtcbiAgICAgICAgaHRtbC5yZW1vdmVDaGlsZCh0aGlzKTtcbiAgICAgICAgcnVuLmNhbGwoaWQpO1xuICAgICAgfTtcbiAgICB9O1xuICAvLyBSZXN0IG9sZCBicm93c2Vyc1xuICB9IGVsc2Uge1xuICAgIGRlZmVyID0gZnVuY3Rpb24oaWQpe1xuICAgICAgc2V0VGltZW91dChjdHgocnVuLCBpZCwgMSksIDApO1xuICAgIH07XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZXQ6ICAgc2V0VGFzayxcbiAgY2xlYXI6IGNsZWFyVGFza1xufTsiLCIvLyA3LjEuNCBUb0ludGVnZXJcbnZhciBjZWlsICA9IE1hdGguY2VpbFxuICAsIGZsb29yID0gTWF0aC5mbG9vcjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gaXNOYU4oaXQgPSAraXQpID8gMCA6IChpdCA+IDAgPyBmbG9vciA6IGNlaWwpKGl0KTtcbn07IiwiLy8gdG8gaW5kZXhlZCBvYmplY3QsIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vJC5pb2JqZWN0JylcbiAgLCBkZWZpbmVkID0gcmVxdWlyZSgnLi8kLmRlZmluZWQnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gSU9iamVjdChkZWZpbmVkKGl0KSk7XG59OyIsIi8vIDcuMS4xNSBUb0xlbmd0aFxudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vJC50by1pbnRlZ2VyJylcbiAgLCBtaW4gICAgICAgPSBNYXRoLm1pbjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gaXQgPiAwID8gbWluKHRvSW50ZWdlcihpdCksIDB4MWZmZmZmZmZmZmZmZmYpIDogMDsgLy8gcG93KDIsIDUzKSAtIDEgPT0gOTAwNzE5OTI1NDc0MDk5MVxufTsiLCIvLyA3LjEuMTMgVG9PYmplY3QoYXJndW1lbnQpXG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vJC5kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIE9iamVjdChkZWZpbmVkKGl0KSk7XG59OyIsInZhciBpZCA9IDBcbiAgLCBweCA9IE1hdGgucmFuZG9tKCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGtleSl7XG4gIHJldHVybiAnU3ltYm9sKCcuY29uY2F0KGtleSA9PT0gdW5kZWZpbmVkID8gJycgOiBrZXksICcpXycsICgrK2lkICsgcHgpLnRvU3RyaW5nKDM2KSk7XG59OyIsInZhciBzdG9yZSAgPSByZXF1aXJlKCcuLyQuc2hhcmVkJykoJ3drcycpXG4gICwgdWlkICAgID0gcmVxdWlyZSgnLi8kLnVpZCcpXG4gICwgU3ltYm9sID0gcmVxdWlyZSgnLi8kLmdsb2JhbCcpLlN5bWJvbDtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24obmFtZSl7XG4gIHJldHVybiBzdG9yZVtuYW1lXSB8fCAoc3RvcmVbbmFtZV0gPVxuICAgIFN5bWJvbCAmJiBTeW1ib2xbbmFtZV0gfHwgKFN5bWJvbCB8fCB1aWQpKCdTeW1ib2wuJyArIG5hbWUpKTtcbn07IiwidmFyIGNsYXNzb2YgICA9IHJlcXVpcmUoJy4vJC5jbGFzc29mJylcbiAgLCBJVEVSQVRPUiAgPSByZXF1aXJlKCcuLyQud2tzJykoJ2l0ZXJhdG9yJylcbiAgLCBJdGVyYXRvcnMgPSByZXF1aXJlKCcuLyQuaXRlcmF0b3JzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vJC5jb3JlJykuZ2V0SXRlcmF0b3JNZXRob2QgPSBmdW5jdGlvbihpdCl7XG4gIGlmKGl0ICE9IHVuZGVmaW5lZClyZXR1cm4gaXRbSVRFUkFUT1JdXG4gICAgfHwgaXRbJ0BAaXRlcmF0b3InXVxuICAgIHx8IEl0ZXJhdG9yc1tjbGFzc29mKGl0KV07XG59OyIsInZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vJC5hbi1vYmplY3QnKVxuICAsIGdldCAgICAgID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi8kLmNvcmUnKS5nZXRJdGVyYXRvciA9IGZ1bmN0aW9uKGl0KXtcbiAgdmFyIGl0ZXJGbiA9IGdldChpdCk7XG4gIGlmKHR5cGVvZiBpdGVyRm4gIT0gJ2Z1bmN0aW9uJyl0aHJvdyBUeXBlRXJyb3IoaXQgKyAnIGlzIG5vdCBpdGVyYWJsZSEnKTtcbiAgcmV0dXJuIGFuT2JqZWN0KGl0ZXJGbi5jYWxsKGl0KSk7XG59OyIsIid1c2Ugc3RyaWN0JztcbnZhciBhZGRUb1Vuc2NvcGFibGVzID0gcmVxdWlyZSgnLi8kLmFkZC10by11bnNjb3BhYmxlcycpXG4gICwgc3RlcCAgICAgICAgICAgICA9IHJlcXVpcmUoJy4vJC5pdGVyLXN0ZXAnKVxuICAsIEl0ZXJhdG9ycyAgICAgICAgPSByZXF1aXJlKCcuLyQuaXRlcmF0b3JzJylcbiAgLCB0b0lPYmplY3QgICAgICAgID0gcmVxdWlyZSgnLi8kLnRvLWlvYmplY3QnKTtcblxuLy8gMjIuMS4zLjQgQXJyYXkucHJvdG90eXBlLmVudHJpZXMoKVxuLy8gMjIuMS4zLjEzIEFycmF5LnByb3RvdHlwZS5rZXlzKClcbi8vIDIyLjEuMy4yOSBBcnJheS5wcm90b3R5cGUudmFsdWVzKClcbi8vIDIyLjEuMy4zMCBBcnJheS5wcm90b3R5cGVbQEBpdGVyYXRvcl0oKVxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLyQuaXRlci1kZWZpbmUnKShBcnJheSwgJ0FycmF5JywgZnVuY3Rpb24oaXRlcmF0ZWQsIGtpbmQpe1xuICB0aGlzLl90ID0gdG9JT2JqZWN0KGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4gIHRoaXMuX2sgPSBraW5kOyAgICAgICAgICAgICAgICAvLyBraW5kXG4vLyAyMi4xLjUuMi4xICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uKCl7XG4gIHZhciBPICAgICA9IHRoaXMuX3RcbiAgICAsIGtpbmQgID0gdGhpcy5fa1xuICAgICwgaW5kZXggPSB0aGlzLl9pKys7XG4gIGlmKCFPIHx8IGluZGV4ID49IE8ubGVuZ3RoKXtcbiAgICB0aGlzLl90ID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiBzdGVwKDEpO1xuICB9XG4gIGlmKGtpbmQgPT0gJ2tleXMnICApcmV0dXJuIHN0ZXAoMCwgaW5kZXgpO1xuICBpZihraW5kID09ICd2YWx1ZXMnKXJldHVybiBzdGVwKDAsIE9baW5kZXhdKTtcbiAgcmV0dXJuIHN0ZXAoMCwgW2luZGV4LCBPW2luZGV4XV0pO1xufSwgJ3ZhbHVlcycpO1xuXG4vLyBhcmd1bWVudHNMaXN0W0BAaXRlcmF0b3JdIGlzICVBcnJheVByb3RvX3ZhbHVlcyUgKDkuNC40LjYsIDkuNC40LjcpXG5JdGVyYXRvcnMuQXJndW1lbnRzID0gSXRlcmF0b3JzLkFycmF5O1xuXG5hZGRUb1Vuc2NvcGFibGVzKCdrZXlzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCd2YWx1ZXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ2VudHJpZXMnKTsiLCIvLyAxOS4xLjMuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuLyQuZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GLCAnT2JqZWN0Jywge2Fzc2lnbjogcmVxdWlyZSgnLi8kLm9iamVjdC1hc3NpZ24nKX0pOyIsIi8vIDE5LjEuMi42IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUClcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuLyQudG8taW9iamVjdCcpO1xuXG5yZXF1aXJlKCcuLyQub2JqZWN0LXNhcCcpKCdnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3InLCBmdW5jdGlvbigkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKXtcbiAgcmV0dXJuIGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcihpdCwga2V5KXtcbiAgICByZXR1cm4gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0b0lPYmplY3QoaXQpLCBrZXkpO1xuICB9O1xufSk7IiwiLy8gMTkuMS4yLjE0IE9iamVjdC5rZXlzKE8pXG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuLyQudG8tb2JqZWN0Jyk7XG5cbnJlcXVpcmUoJy4vJC5vYmplY3Qtc2FwJykoJ2tleXMnLCBmdW5jdGlvbigka2V5cyl7XG4gIHJldHVybi
23459BmdW5jdGlvbiBrZXlzKGl0KXtcbiAgICByZXR1cm4gJGtleXModG9PYmplY3QoaXQpKTtcbiAgfTtcbn0pOyIsIi8vIDE5LjEuMy4xOSBPYmplY3Quc2V0UHJvdG90eXBlT2YoTywgcHJvdG8pXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vJC5leHBvcnQnKTtcbiRleHBvcnQoJGV4cG9ydC5TLCAnT2JqZWN0Jywge3NldFByb3RvdHlwZU9mOiByZXF1aXJlKCcuLyQuc2V0LXByb3RvJykuc2V0fSk7IixudWxsLCIndXNlIHN0cmljdCc7XG52YXIgJCAgICAgICAgICA9IHJlcXVpcmUoJy4vJCcpXG4gICwgTElCUkFSWSAgICA9IHJlcXVpcmUoJy4vJC5saWJyYXJ5JylcbiAgLCBnbG9iYWwgICAgID0gcmVxdWlyZSgnLi8kLmdsb2JhbCcpXG4gICwgY3R4ICAgICAgICA9IHJlcXVpcmUoJy4vJC5jdHgnKVxuICAsIGNsYXNzb2YgICAgPSByZXF1aXJlKCcuLyQuY2xhc3NvZicpXG4gICwgJGV4cG9ydCAgICA9IHJlcXVpcmUoJy4vJC5leHBvcnQnKVxuICAsIGlzT2JqZWN0ICAgPSByZXF1aXJlKCcuLyQuaXMtb2JqZWN0JylcbiAgLCBhbk9iamVjdCAgID0gcmVxdWlyZSgnLi8kLmFuLW9iamVjdCcpXG4gICwgYUZ1bmN0aW9uICA9IHJlcXVpcmUoJy4vJC5hLWZ1bmN0aW9uJylcbiAgLCBzdHJpY3ROZXcgID0gcmVxdWlyZSgnLi8kLnN0cmljdC1uZXcnKVxuICAsIGZvck9mICAgICAgPSByZXF1aXJlKCcuLyQuZm9yLW9mJylcbiAgLCBzZXRQcm90byAgID0gcmVxdWlyZSgnLi8kLnNldC1wcm90bycpLnNldFxuICAsIHNhbWUgICAgICAgPSByZXF1aXJlKCcuLyQuc2FtZS12YWx1ZScpXG4gICwgU1BFQ0lFUyAgICA9IHJlcXVpcmUoJy4vJC53a3MnKSgnc3BlY2llcycpXG4gICwgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi8kLnNwZWNpZXMtY29uc3RydWN0b3InKVxuICAsIGFzYXAgICAgICAgPSByZXF1aXJlKCcuLyQubWljcm90YXNrJylcbiAgLCBQUk9NSVNFICAgID0gJ1Byb21pc2UnXG4gICwgcHJvY2VzcyAgICA9IGdsb2JhbC5wcm9jZXNzXG4gICwgaXNOb2RlICAgICA9IGNsYXNzb2YocHJvY2VzcykgPT0gJ3Byb2Nlc3MnXG4gICwgUCAgICAgICAgICA9IGdsb2JhbFtQUk9NSVNFXVxuICAsIGVtcHR5ICAgICAgPSBmdW5jdGlvbigpeyAvKiBlbXB0eSAqLyB9XG4gICwgV3JhcHBlcjtcblxudmFyIHRlc3RSZXNvbHZlID0gZnVuY3Rpb24oc3ViKXtcbiAgdmFyIHRlc3QgPSBuZXcgUChlbXB0eSksIHByb21pc2U7XG4gIGlmKHN1Yil0ZXN0LmNvbnN0cnVjdG9yID0gZnVuY3Rpb24oZXhlYyl7XG4gICAgZXhlYyhlbXB0eSwgZW1wdHkpO1xuICB9O1xuICAocHJvbWlzZSA9IFAucmVzb2x2ZSh0ZXN0KSlbJ2NhdGNoJ10oZW1wdHkpO1xuICByZXR1cm4gcHJvbWlzZSA9PT0gdGVzdDtcbn07XG5cbnZhciBVU0VfTkFUSVZFID0gZnVuY3Rpb24oKXtcbiAgdmFyIHdvcmtzID0gZmFsc2U7XG4gIGZ1bmN0aW9uIFAyKHgpe1xuICAgIHZhciBzZWxmID0gbmV3IFAoeCk7XG4gICAgc2V0UHJvdG8oc2VsZiwgUDIucHJvdG90eXBlKTtcbiAgICByZXR1cm4gc2VsZjtcbiAgfVxuICB0cnkge1xuICAgIHdvcmtzID0gUCAmJiBQLnJlc29sdmUgJiYgdGVzdFJlc29sdmUoKTtcbiAgICBzZXRQcm90byhQMiwgUCk7XG4gICAgUDIucHJvdG90eXBlID0gJC5jcmVhdGUoUC5wcm90b3R5cGUsIHtjb25zdHJ1Y3Rvcjoge3ZhbHVlOiBQMn19KTtcbiAgICAvLyBhY3R1YWwgRmlyZWZveCBoYXMgYnJva2VuIHN1YmNsYXNzIHN1cHBvcnQsIHRlc3QgdGhhdFxuICAgIGlmKCEoUDIucmVzb2x2ZSg1KS50aGVuKGZ1bmN0aW9uKCl7fSkgaW5zdGFuY2VvZiBQMikpe1xuICAgICAgd29ya3MgPSBmYWxzZTtcbiAgICB9XG4gICAgLy8gYWN0dWFsIFY4IGJ1ZywgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTQxNjJcbiAgICBpZih3b3JrcyAmJiByZXF1aXJlKCcuLyQuZGVzY3JpcHRvcnMnKSl7XG4gICAgICB2Y
23459XIgdGhlbmFibGVUaGVuR290dGVuID0gZmFsc2U7XG4gICAgICBQLnJlc29sdmUoJC5zZXREZXNjKHt9LCAndGhlbicsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbigpeyB0aGVuYWJsZVRoZW5Hb3R0ZW4gPSB0cnVlOyB9XG4gICAgICB9KSk7XG4gICAgICB3b3JrcyA9IHRoZW5hYmxlVGhlbkdvdHRlbjtcbiAgICB9XG4gIH0gY2F0Y2goZSl7IHdvcmtzID0gZmFsc2U7IH1cbiAgcmV0dXJuIHdvcmtzO1xufSgpO1xuXG4vLyBoZWxwZXJzXG52YXIgc2FtZUNvbnN0cnVjdG9yID0gZnVuY3Rpb24oYSwgYil7XG4gIC8vIGxpYnJhcnkgd3JhcHBlciBzcGVjaWFsIGNhc2VcbiAgaWYoTElCUkFSWSAmJiBhID09PSBQICYmIGIgPT09IFdyYXBwZXIpcmV0dXJuIHRydWU7XG4gIHJldHVybiBzYW1lKGEsIGIpO1xufTtcbnZhciBnZXRDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uKEMpe1xuICB2YXIgUyA9IGFuT2JqZWN0KEMpW1NQRUNJRVNdO1xuICByZXR1cm4gUyAhPSB1bmRlZmluZWQgPyBTIDogQztcbn07XG52YXIgaXNUaGVuYWJsZSA9IGZ1bmN0aW9uKGl0KXtcbiAgdmFyIHRoZW47XG4gIHJldHVybiBpc09iamVjdChpdCkgJiYgdHlwZW9mICh0aGVuID0gaXQudGhlbikgPT0gJ2Z1bmN0aW9uJyA/IHRoZW4gOiBmYWxzZTtcbn07XG52YXIgUHJvbWlzZUNhcGFiaWxpdHkgPSBmdW5jdGlvbihDKXtcbiAgdmFyIHJlc29sdmUsIHJlamVjdDtcbiAgdGhpcy5wcm9taXNlID0gbmV3IEMoZnVuY3Rpb24oJCRyZXNvbHZlLCAkJHJlamVjdCl7XG4gICAgaWYocmVzb2x2ZSAhPT0gdW5kZWZpbmVkIHx8IHJlamVjdCAhPT0gdW5kZWZpbmVkKXRocm93IFR5cGVFcnJvcignQmFkIFByb21pc2UgY29uc3RydWN0b3InKTtcbiAgICByZXNvbHZlID0gJCRyZXNvbHZlO1xuICAgIHJlamVjdCAgPSAkJHJlamVjdDtcbiAgfSk7XG4gIHRoaXMucmVzb2x2ZSA9IGFGdW5jdGlvbihyZXNvbHZlKSxcbiAgdGhpcy5yZWplY3QgID0gYUZ1bmN0aW9uKHJlamVjdClcbn07XG52YXIgcGVyZm9ybSA9IGZ1bmN0aW9uKGV4ZWMpe1xuICB0cnkge1xuICAgIGV4ZWMoKTtcbiAgfSBjYXRjaChlKXtcbiAgICByZXR1cm4ge2Vycm9yOiBlfTtcbiAgfVxufTtcbnZhciBub3RpZnkgPSBmdW5jdGlvbihyZWNvcmQsIGlzUmVqZWN0KXtcbiAgaWYocmVjb3JkLm4pcmV0dXJuO1xuICByZWNvcmQubiA9IHRydWU7XG4gIHZhciBjaGFpbiA9IHJlY29yZC5jO1xuICBhc2FwKGZ1bmN0aW9uKCl7XG4gICAgdmFyIHZhbHVlID0gcmVjb3JkLnZcbiAgICAgICwgb2sgICAgPSByZWNvcmQucyA9PSAxXG4gICAgICAsIGkgICAgID0gMDtcbiAgICB2YXIgcnVuID0gZnVuY3Rpb24ocmVhY3Rpb24pe1xuICAgICAgdmFyIGhhbmRsZXIgPSBvayA/IHJlYWN0aW9uLm9rIDogcmVhY3Rpb24uZmFpbFxuICAgICAgICAsIHJlc29sdmUgPSByZWFjdGlvbi5yZXNvbHZlXG4gICAgICAgICwgcmVqZWN0ICA9IHJlYWN0aW9uLnJlamVjdFxuICAgICAgICAsIHJlc3VsdCwgdGhlbjtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmKGhhbmRsZXIpe1xuICAgICAgICAgIGlmKCFvaylyZWNvcmQuaCA9IHRydWU7XG4gICAgICAgICAgcmVzdWx0ID0gaGFuZGxlciA9PT0gdHJ1ZSA/IHZhbHVlIDogaGFuZGxlcih2YWx1ZSk7XG4gICAgICAgICAgaWYocmVzdWx0ID09PSByZWFjdGlvbi5wcm9taXNlKXtcbiAgICAgICAgICAgIHJlamVjdChUeXBlRXJyb3IoJ1Byb21pc2UtY2hhaW4gY3ljbGUnKSk7XG4gICAgICAgICAgfSBlbHNlIGlmKHRoZW4gPSBpc1RoZW5hYmxlKHJlc3VsdCkpe1xuICAgICAgICAgICAgdGhlbi5jYWxsKHJlc3VsdCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgIHJlamVjdChlKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHdoaWxlKGNoYWluLmxlbmd0aCA+IGkpcnVuKGNoYWluW2krK10pOyAvLyB2YXJpYWJsZSBsZW5ndGggLSBjYW4ndCB1c2UgZm9yRWFjaFxuICAgIGNoYWluLmxlbmd0aCA9IDA7XG4gICAgcmVjb3JkLm4gPSBmYWxzZTtcbiAgICBpZihpc1JlamVjdClzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICB2Y
23459XIgcHJvbWlzZSA9IHJlY29yZC5wXG4gICAgICAgICwgaGFuZGxlciwgY29uc29sZTtcbiAgICAgIGlmKGlzVW5oYW5kbGVkKHByb21pc2UpKXtcbiAgICAgICAgaWYoaXNOb2RlKXtcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmKGhhbmRsZXIgPSBnbG9iYWwub251bmhhbmRsZWRyZWplY3Rpb24pe1xuICAgICAgICAgIGhhbmRsZXIoe3Byb21pc2U6IHByb21pc2UsIHJlYXNvbjogdmFsdWV9KTtcbiAgICAgICAgfSBlbHNlIGlmKChjb25zb2xlID0gZ2xvYmFsLmNvbnNvbGUpICYmIGNvbnNvbGUuZXJyb3Ipe1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbicsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSByZWNvcmQuYSA9IHVuZGVmaW5lZDtcbiAgICB9LCAxKTtcbiAgfSk7XG59O1xudmFyIGlzVW5oYW5kbGVkID0gZnVuY3Rpb24ocHJvbWlzZSl7XG4gIHZhciByZWNvcmQgPSBwcm9taXNlLl9kXG4gICAgLCBjaGFpbiAgPSByZWNvcmQuYSB8fCByZWNvcmQuY1xuICAgICwgaSAgICAgID0gMFxuICAgICwgcmVhY3Rpb247XG4gIGlmKHJlY29yZC5oKXJldHVybiBmYWxzZTtcbiAgd2hpbGUoY2hhaW4ubGVuZ3RoID4gaSl7XG4gICAgcmVhY3Rpb24gPSBjaGFpbltpKytdO1xuICAgIGlmKHJlYWN0aW9uLmZhaWwgfHwgIWlzVW5oYW5kbGVkKHJlYWN0aW9uLnByb21pc2UpKXJldHVybiBmYWxzZTtcbiAgfSByZXR1cm4gdHJ1ZTtcbn07XG52YXIgJHJlamVjdCA9IGZ1bmN0aW9uKHZhbHVlKXtcbiAgdmFyIHJlY29yZCA9IHRoaXM7XG4gIGlmKHJlY29yZC5kKXJldHVybjtcbiAgcmVjb3JkLmQgPSB0cnVlO1xuICByZWNvcmQgPSByZWNvcmQuciB8fCByZWNvcmQ7IC8vIHVud3JhcFxuICByZWNvcmQudiA9IHZhbHVlO1xuICByZWNvcmQucyA9IDI7XG4gIHJlY29yZC5hID0gcmVjb3JkLmMuc2xpY2UoKTtcbiAgbm90aWZ5KHJlY29yZCwgdHJ1ZSk7XG59O1xudmFyICRyZXNvbHZlID0gZnVuY3Rpb24odmFsdWUpe1xuICB2YXIgcmVjb3JkID0gdGhpc1xuICAgICwgdGhlbjtcbiAgaWYocmVjb3JkLmQpcmV0dXJuO1xuICByZWNvcmQuZCA9IHRydWU7XG4gIHJlY29yZCA9IHJlY29yZC5yIHx8IHJlY29yZDsgLy8gdW53cmFwXG4gIHRyeSB7XG4gICAgaWYocmVjb3JkLnAgPT09IHZhbHVlKXRocm93IFR5cGVFcnJvcihcIlByb21pc2UgY2FuJ3QgYmUgcmVzb2x2ZWQgaXRzZWxmXCIpO1xuICAgIGlmKHRoZW4gPSBpc1RoZW5hYmxlKHZhbHVlKSl7XG4gICAgICBhc2FwKGZ1bmN0aW9uKCl7XG4gICAgICAgIHZhciB3cmFwcGVyID0ge3I6IHJlY29yZCwgZDogZmFsc2V9OyAvLyB3cmFwXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhlbi5jYWxsKHZhbHVlLCBjdHgoJHJlc29sdmUsIHdyYXBwZXIsIDEpLCBjdHgoJHJlamVjdCwgd3JhcHBlciwgMSkpO1xuICAgICAgICB9IGNhdGNoKGUpe1xuICAgICAgICAgICRyZWplY3QuY2FsbCh3cmFwcGVyLCBlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlY29yZC52ID0gdmFsdWU7XG4gICAgICByZWNvcmQucyA9IDE7XG4gICAgICBub3RpZnkocmVjb3JkLCBmYWxzZSk7XG4gICAgfVxuICB9IGNhdGNoKGUpe1xuICAgICRyZWplY3QuY2FsbCh7cjogcmVjb3JkLCBkOiBmYWxzZX0sIGUpOyAvLyB3cmFwXG4gIH1cbn07XG5cbi8vIGNvbnN0cnVjdG9yIHBvbHlmaWxsXG5pZighVVNFX05BVElWRSl7XG4gIC8vIDI1LjQuMy4xIFByb21pc2UoZXhlY3V0b3IpXG4gIFAgPSBmdW5jdGlvbiBQcm9taXNlKGV4ZWN1dG9yKXtcbiAgICBhRnVuY3Rpb24oZXhlY3V0b3IpO1xuICAgIHZhciByZWNvcmQgPSB0aGlzLl9kID0ge1xuICAgICAgcDogc3RyaWN0TmV3KHRoaXMsIFAsIFBST01JU0UpLCAgICAgICAgIC8vIDwtIHByb21pc2VcbiAgICAgIGM6IFtdLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8LSBhd2FpdGluZyByZWFjdGlvbnNcbiAgICAgIGE6IHVuZGVmaW5lZCwgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8LSBjaGVja2VkIGluIGlzVW5oYW5kbGVkIHJlYWN0aW9uc1xuICAgICAgczogMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIHN0YXRlXG4gICAgICBkOiBmYWxzZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gPC0gZG9uZVxuICAgICAgdjogdW5kZWZpbmVkLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIHZhbHVlXG4gICAgICBoOiBmYWxzZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gPC0gaGFuZGxlZCByZWplY3Rpb25cbiAgICAgIG46IGZhbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA8LSBub3RpZnlcbiAgICB9O1xuICAgIHRyeSB7XG4gICAgICBleGVjdXRvcihjdHgoJHJlc29sdmUsIHJlY29yZCwgMSksIGN0eCgkcmVqZWN0LCByZWNvcmQsIDEpKTtcbiAgICB9IGNhdGNoKGVycil7XG4gICAgICAkcmVqZWN0LmNhbGwocmVjb3JkLCBlcnIpO1xuICAgIH1cbiAgfTtcbiAgcmVxdWlyZSgnLi8kLnJlZGVmaW5lLWFsbCcpKFAucHJvdG90eXBlLCB7XG4gICAgLy8gMjUuNC41LjMgUHJvbWlzZS5wcm90b3R5cGUudGhlbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZClcbiAgICB0aGVuOiBmdW5jdGlvbiB0aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKXtcbiAgICAgIHZhciByZWFjdGlvbiA9IG5ldyBQcm9taXNlQ2FwYWJpbGl0eShzcGVjaWVzQ29uc3RydWN0b3IodGhpcywgUCkpXG4gICAgICAgICwgcHJvbWlzZSAgPSByZWFjdGlvbi5wcm9taXNlXG4gICAgICAgICwgcmVjb3JkICAgPSB0aGlzLl9kO1xuICAgICAgcmVhY3Rpb24ub2sgICA9IHR5cGVvZiBvbkZ1bGZpbGxlZCA9PSAnZnVuY3Rpb24nID8gb25GdWxmaWxsZWQgOiB0cnVlO1xuICAgICAgcmVhY3Rpb24uZmFpbCA9IHR5cGVvZiBvblJlamVjdGVkID09ICdmdW5jdGlvbicgJiYgb25SZWplY3RlZDtcbiAgICAgIHJlY29yZC5jLnB1c2gocmVhY3Rpb24pO1xuICAgICAgaWYocmVjb3JkLmEpcmVjb3JkLmEucHVzaChyZWFjdGlvbik7XG4gICAgICBpZihyZWNvcmQucylub3RpZnkocmVjb3JkLCBmYWxzZSk7XG4gICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9LFxuICAgIC8vIDI1LjQuNS4xIFByb21pc2UucHJvdG90eXBlLmNhdGNoKG9uUmVqZWN0ZWQpXG4gICAgJ2NhdGNoJzogZnVuY3Rpb24ob25SZWplY3RlZCl7XG4gICAgICByZXR1cm4gdGhpcy50aGVuKHVuZGVmaW5lZCwgb25SZWplY3RlZCk7XG4gICAgfVxuICB9KTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwge1Byb21pc2U6IFB9KTtcbnJlcXVpcmUoJy4vJC5zZXQtdG8tc3RyaW5nLXRhZycpKFAsIFBST01JU0UpO1xucmVxdWlyZSgnLi8kLnNldC1zcGVjaWVzJykoUFJPTUlTRSk7XG5XcmFwcGVyID0gcmVxdWlyZSgnLi8kLmNvcmUnKVtQUk9NSVNFXTtcblxuLy8gc3RhdGljc1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgUFJPTUlTRSwge1xuICAvLyAyNS40LjQuNSBQcm9taXNlLnJlamVjdChyKVxuICByZWplY3Q6IGZ1bmN0aW9uIHJlamVjdChyKXtcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ldyBQcm9taXNlQ2FwYWJpbGl0eSh0aGlzKVxuICAgICAgLCAkJHJlamVjdCAgID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgJCRyZWplY3Qocik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICghVVNFX05BVElWRSB8fCB0ZXN0UmVzb2x2ZSh0cnVlKSksIFBST01JU0UsIHtcbiAgLy8gMjUuNC40LjYgUHJvbWlzZS5yZXNvbHZlKHgpXG4gIHJlc29sdmU6IGZ1bmN0aW9uIHJlc29sdmUoeCl7XG4gICAgLy8gaW5zdGFuY2VvZiBpbnN0ZWFkIG9mIGludGVybmFsIHNsb3QgY2hlY2sgYmVjYXVzZSB3ZSBzaG91bGQgZml4IGl0IHdpdGhvdXQgcmVwbGFjZW1lbnQgbmF0aXZlIFByb21pc2UgY29yZVxuICAgIGlmKHggaW5zdGFuY2VvZiBQICYmIHNhbWVDb25zdHJ1Y3Rvcih4Lm
23459NvbnN0cnVjdG9yLCB0aGlzKSlyZXR1cm4geDtcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ldyBQcm9taXNlQ2FwYWJpbGl0eSh0aGlzKVxuICAgICAgLCAkJHJlc29sdmUgID0gY2FwYWJpbGl0eS5yZXNvbHZlO1xuICAgICQkcmVzb2x2ZSh4KTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG59KTtcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIShVU0VfTkFUSVZFICYmIHJlcXVpcmUoJy4vJC5pdGVyLWRldGVjdCcpKGZ1bmN0aW9uKGl0ZXIpe1xuICBQLmFsbChpdGVyKVsnY2F0Y2gnXShmdW5jdGlvbigpe30pO1xufSkpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC4xIFByb21pc2UuYWxsKGl0ZXJhYmxlKVxuICBhbGw6IGZ1bmN0aW9uIGFsbChpdGVyYWJsZSl7XG4gICAgdmFyIEMgICAgICAgICAgPSBnZXRDb25zdHJ1Y3Rvcih0aGlzKVxuICAgICAgLCBjYXBhYmlsaXR5ID0gbmV3IFByb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgICAsIHJlc29sdmUgICAgPSBjYXBhYmlsaXR5LnJlc29sdmVcbiAgICAgICwgcmVqZWN0ICAgICA9IGNhcGFiaWxpdHkucmVqZWN0XG4gICAgICAsIHZhbHVlcyAgICAgPSBbXTtcbiAgICB2YXIgYWJydXB0ID0gcGVyZm9ybShmdW5jdGlvbigpe1xuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCB2YWx1ZXMucHVzaCwgdmFsdWVzKTtcbiAgICAgIHZhciByZW1haW5pbmcgPSB2YWx1ZXMubGVuZ3RoXG4gICAgICAgICwgcmVzdWx0cyAgID0gQXJyYXkocmVtYWluaW5nKTtcbiAgICAgIGlmKHJlbWFpbmluZykkLmVhY2guY2FsbCh2YWx1ZXMsIGZ1bmN0aW9uKHByb21pc2UsIGluZGV4KXtcbiAgICAgICAgdmFyIGFscmVhZHlDYWxsZWQgPSBmYWxzZTtcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oZnVuY3Rpb24odmFsdWUpe1xuICAgICAgICAgIGlmKGFscmVhZHlDYWxsZWQpcmV0dXJuO1xuICAgICAgICAgIGFscmVhZHlDYWxsZWQgPSB0cnVlO1xuICAgICAgICAgIHJlc3VsdHNbaW5kZXhdID0gdmFsdWU7XG4gICAgICAgICAgLS1yZW1haW5pbmcgfHwgcmVzb2x2ZShyZXN1bHRzKTtcbiAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgICAgZWxzZSByZXNvbHZlKHJlc3VsdHMpO1xuICAgIH0pO1xuICAgIGlmKGFicnVwdClyZWplY3QoYWJydXB0LmVycm9yKTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9LFxuICAvLyAyNS40LjQuNCBQcm9taXNlLnJhY2UoaXRlcmFibGUpXG4gIHJhY2U6IGZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpe1xuICAgIHZhciBDICAgICAgICAgID0gZ2V0Q29uc3RydWN0b3IodGhpcylcbiAgICAgICwgY2FwYWJpbGl0eSA9IG5ldyBQcm9taXNlQ2FwYWJpbGl0eShDKVxuICAgICAgLCByZWplY3QgICAgID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgdmFyIGFicnVwdCA9IHBlcmZvcm0oZnVuY3Rpb24oKXtcbiAgICAgIGZvck9mKGl0ZXJhYmxlLCBmYWxzZSwgZnVuY3Rpb24ocHJvbWlzZSl7XG4gICAgICAgIEMucmVzb2x2ZShwcm9taXNlKS50aGVuKGNhcGFiaWxpdHkucmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGlmKGFicnVwdClyZWplY3QoYWJydXB0LmVycm9yKTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG52YXIgc3Ryb25nID0gcmVxdWlyZSgnLi8kLmNvbGxlY3Rpb24tc3Ryb25nJyk7XG5cbi8vIDIzLjIgU2V0IE9iamVjdHNcbnJlcXVpcmUoJy4vJC5jb2xsZWN0aW9uJykoJ1NldCcsIGZ1bmN0aW9uKGdldCl7XG4gIHJldHVybiBmdW5jdGlvbiBTZXQoKXsgcmV0dXJuIGdldCh0aGlzLCBhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7IH07XG59LCB7XG4gIC8vIDIzLjIuMy4xIFNldC5wcm90b3R5cGUuYWRkKHZhbHVlKVxuICBhZGQ6IGZ1bmN0aW9uIGFkZCh2YWx1ZSl7XG4gICAgcmV0dXJuIHN0cm9uZy5kZWYodGhpcywgdmFsdWUgPSB2YWx1ZSA9PT0gMCA/IDAgOiB2YWx1ZSwgdmFsdWUpO1xuICB9XG59LCBzdHJvbmcpOyIsIid1c2Ugc3RyaWN0JztcbnZhciAkYXQgID0gcmVxdWlyZSgnLi8kLnN0cmluZy1hdCcpKHRydWUpO1xuXG4vLyAyMS4xLjMuMjcgU3RyaW5nLnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5yZXF1aXJlKCcuLyQuaXRlci1kZWZpbmUnKShTdHJpbmcsICdTdHJpbmcnLCBmdW5jdGlvbihpdGVyYXRlZCl7XG4gIHRoaXMuX3QgPSBTdHJpbmcoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbi8vIDIxLjEuNS4yLjEgJVN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uKCl7XG4gIHZhciBPICAgICA9IHRoaXMuX3RcbiAgICAsIGluZGV4ID0gdGhpcy5faVxuICAgICwgcG9pbnQ7XG4gIGlmKGluZGV4ID49IE8ubGVuZ3RoKXJldHVybiB7dmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZX07XG4gIHBvaW50ID0gJGF0KE8sIGluZGV4KTtcbiAgdGhpcy5faSArPSBwb2ludC5sZW5ndGg7XG4gIHJldHVybiB7dmFsdWU6IHBvaW50LCBkb25lOiBmYWxzZX07XG59KTsiLCIvLyBodHRwczovL2dpdGh1Yi5jb20vRGF2aWRCcnVhbnQvTWFwLVNldC5wcm90b3R5cGUudG9KU09OXG52YXIgJGV4cG9ydCAgPSByZXF1aXJlKCcuLyQuZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnU2V0Jywge3RvSlNPTjogcmVxdWlyZSgnLi8kLmNvbGxlY3Rpb24tdG8tanNvbicpKCdTZXQnKX0pOyIsInJlcXVpcmUoJy4vZXM2LmFycmF5Lml0ZXJhdG9yJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi8kLml0ZXJhdG9ycycpO1xuSXRlcmF0b3JzLk5vZGVMaXN0ID0gSXRlcmF0b3JzLkhUTUxDb2xsZWN0aW9uID0gSXRlcmF0b3JzLkFycmF5OyIsIi8qIVxuSVNDIExpY2Vuc2VcblxuQ29weXJpZ2h0IChjKSAyMDE0LTIwMTgsIEFuZHJlYSBHaWFtbWFyY2hpLCBAV2ViUmVmbGVjdGlvblxuXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmVcbmNvcHlyaWdodCBub3RpY2UgYW5kIHR
23459oaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMuXG5cblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRVxuT1IgT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cblxuKi9cbi8vIGdsb2JhbCB3aW5kb3cgT2JqZWN0XG4vLyBvcHRpb25hbCBwb2x5ZmlsbCBpbmZvXG4vLyAgICAnYXV0bycgdXNlZCBieSBkZWZhdWx0LCBldmVyeXRoaW5nIGlzIGZlYXR1cmUgZGV0ZWN0ZWRcbi8vICAgICdmb3JjZScgdXNlIHRoZSBwb2x5ZmlsbCBldmVuIGlmIG5vdCBmdWxseSBuZWVkZWRcbmZ1bmN0aW9uIGluc3RhbGxDdXN0b21FbGVtZW50cyh3aW5kb3csIHBvbHlmaWxsKSB7J3VzZSBzdHJpY3QnO1xuXG4gIC8vIERPIE5PVCBVU0UgVEhJUyBGSUxFIERJUkVDVExZLCBJVCBXT04nVCBXT1JLXG4gIC8vIFRISVMgSVMgQSBQUk9KRUNUIEJBU0VEIE9OIEEgQlVJTEQgU1lTVEVNXG4gIC8vIFRISVMgRklMRSBJUyBKVVNUIFdSQVBQRUQgVVAgUkVTVUxUSU5HIElOXG4gIC8vIGJ1aWxkL2RvY3VtZW50LXJlZ2lzdGVyLWVsZW1lbnQubm9kZS5qc1xuXG4gIHZhclxuICAgIGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50LFxuICAgIE9iamVjdCA9IHdpbmRvdy5PYmplY3RcbiAgO1xuXG4gIHZhciBodG1sQ2xhc3MgPSAoZnVuY3Rpb24gKGluZm8pIHtcbiAgICAvLyAoQykgQW5kcmVhIEdpYW1tYXJjaGkgLSBAV2ViUmVmbGVjdGlvbiAtIE1JVCBTdHlsZVxuICAgIHZhclxuICAgICAgY2F0Y2hDbGFzcyA9IC9eW0EtWl0rW2Etel0vLFxuICAgICAgZmlsdGVyQnkgPSBmdW5jdGlvbiAocmUpIHtcbiAgICAgICAgdmFyIGFyciA9IFtdLCB0YWc7XG4gICAgICAgIGZvciAodGFnIGluIHJlZ2lzdGVyKSB7XG4gICAgICAgICAgaWYgKHJlLnRlc3QodGFnKSkgYXJyLnB1c2godGFnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXJyO1xuICAgICAgfSxcbiAgICAgIGFkZCA9IGZ1bmN0aW9uIChDbGFzcywgdGFnKSB7XG4gICAgICAgIHRhZyA9IHRhZy50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBpZiAoISh0YWcgaW4gcmVnaXN0ZXIpKSB7XG4gICAgICAgICAgcmVnaXN0ZXJbQ2xhc3NdID0gKHJlZ2lzdGVyW0NsYXNzXSB8fCBbXSkuY29uY2F0KHRhZyk7XG4gICAgICAgICAgcmVnaXN0ZXJbdGFnXSA9IChyZWdpc3Rlclt0YWcudG9VcHBlckNhc2UoKV0gPSBDbGFzcyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICByZWdpc3RlciA9IChPYmplY3QuY3JlYXRlIHx8IE9iamVjdCkobnVsbCksXG4gICAgICBodG1sQ2xhc3MgPSB7fSxcbiAgICAgIGksIHNlY3Rpb24sIHRhZ3MsIENsYXNzXG4gICAgO1xuICAgIGZvciAoc2VjdGlvbiBpbiBpbmZvKSB7XG4gICAgICBmb3IgKENsYXNzIGluIGluZm9bc2VjdGlvbl0pIHtcbiAgICAgICAgdGFncyA9IGluZm9bc2VjdGlvbl1bQ2xhc3NdO1xuICAgICAgICByZWdpc3RlcltDbGFzc10gPSB0YWdzO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGFncy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHJlZ2lzdGVyW3RhZ3NbaV0udG9Mb3dlckNhc2UoKV0gPVxuICAgICAgICAgIHJlZ2lzdGVyW3RhZ3NbaV0udG9VcHBlckNhc2UoKV0gPSBDbGFzcztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBodG1sQ2xhc3MuZ2V0ID0gZnVuY3Rpb24gZ2V0KHRhZ09yQ2xhc3MpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdGFnT3JDbGFzcyA9PT0gJ3N0cmluZycgP1xuICAgICAgICAocmVnaXN0ZXJbdGFnT3JDbGFzc10gfHwgKGNhdGNoQ2xhc3MudGVzdCh0YWdPckNsYXNzKSA/IFtdIDogJycpKSA6XG4gICAgICAgIGZpbHRlckJ5KHRhZ09yQ2xhc3MpO1xuICAgIH07XG4gICAgaHRtbENsYXNzLnNldCA9IGZ1bmN0aW9uIHNldCh0YWcsIENsYXNzKSB7XG4gICAgICByZXR1cm4gKGNhdGNoQ2xhc3MudGVzdCh0YWcpID9cbiAgICAgICAgYWRkKHRhZywgQ2xhc3MpIDpcbiAgICAgICAgYWRkKENsYXNzLCB0YWcpXG4gICAgICApLCBodG1sQ2xhc3M7XG4gICAgfTtcbiAgICByZXR1cm4gaHRtbENsYXNzO1xuICB9KHtcbiAgICBcImNvbGxlY3Rpb25zXCI6IHtcbiAgICAgIFwiSFRNTEFsbENvbGxlY3Rpb25cIjogW1xuICAgICAgICBcImFsbFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MQ29sbGVjdGlvblwiOiBbXG4gICAgICAgIFwiZm9ybXNcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTEZvcm1Db250cm9sc0NvbGxlY3Rpb25cIjogW1xuICAgICAgICBcImVsZW1lbnRzXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxPcHRpb25zQ29sbGVjdGlvblwiOiBbXG4gICAgICAgIFwib3B0aW9uc1wiXG4gICAgICBdXG4gICAgfSxcbiAgICBcImVsZW1lbnRzXCI6IHtcbiAgICAgIFwiRWxlbWVudFwiOiBbXG4gICAgICAgIFwiZWxlbWVudFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MQW5jaG9yRWxlbWVudFwiOiBbXG4gICAgICAgIFwiYVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MQXBwbGV0RWxlbWVudFwiOiBbXG4gICAgICAgIFwiYXBwbGV0XCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxBcmVhRWxlbWVudFwiOiBbXG4gICAgICAgIFwiYXJlYVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MQXR0YWNobWVudEVsZW1lbnRcIjogW1xuICAgICAgICBcImF0dGFjaG1lbnRcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTEF1ZGlvRWxlbWVudFwiOiBbXG4gICAgICAgIFwiYXVkaW9cIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTEJSRWxlbWVudFwiOiBbXG4gICAgICAgIFwiYnJcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTEJhc2VFbGVtZW50XCI6IFtcbiAgICAgICAgXCJiYXNlXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxCb2R5RWxlbWVudFwiOiBbXG4gICAgICAgIFwiYm9keVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MQnV0dG9uRWxlbWVudFwiOiBbXG4gICAgICAgIFwiYnV0dG9uXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxDYW52YXNFbGVtZW50XCI6IFtcbiAgICAgICAgXCJjYW52YXNcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTENvbnRlbnRFbGVtZW50XCI6IFtcbiAgICAgICAgXCJjb250ZW50XCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxETGlzdEVsZW1lbnRcIjogW1xuICAgICAgICBcImRsXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxEYXRhRWxlbWVudFwiOiBbXG4gICAgICAgIFwiZGF0YVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MRGF0YUxpc3RFbGVtZW50XCI6IFtcbiAgICAgICAgXCJkYXRhbGlzdFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MRGV0YWlsc0VsZW1lbnRcIjogW1xuICAgICAgICBcImRldGFpbHNcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTERpYWxvZ0VsZW1lbnRcIjogW1xuICAgICAgICBcImRpYWxvZ1wiXG4gICAgICBdLFxuICAgICAgXCJIVE1MRGlyZWN0b3J5RWxlbWVudFwiOiBbXG4gICAgICAgIFwiZGlyXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxEaXZFbGVtZW50XCI6IFtcbiAgICAgICAgXCJkaXZcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTERvY3VtZW50XCI6IFtcbiAgICAgICAgXCJkb2N1bWVudFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MRWxlbWVudFwiOiBbXG4gICAgICAgIFwiZWxlbWVudFwiLFxuICAgICAgICBcImFiYnJcIixcbiAgICAgICAgXCJhZGRyZXNzXCIsXG4gICAgICAgIFwiYXJ0aWNsZVwiLFxuICAgICAgICBcImFzaWRlXCIsXG4gICAgICAgIFwiYlwiLFxuICAgICAgICBcImJkaVwiLFxuICAgICAgICBcImJkb1wiLFxuICAgICAgICBcImNpdGVcIixcbiAgICAgICAgXCJjb2RlXCIsXG4gICAgICAgIFwiY29tbWFuZFwiLFxuICAgICAgICBcImRkXCIsXG4gICAgICAgIFwiZGZuXCIsXG4gICAgICAgIFwiZHRcIixcbiAgICAgICAgXCJlbVwiLFxuICAgICAgICBcImZpZ2NhcHRpb25cIixcbiAgICAgICAgXCJmaWd1cmVcIixcbiAgICAgICAgXCJmb290ZXJcIixcbiAgICAgICAgXCJoZWFkZXJcIixcbiAgICAgICAgXCJpXCIsXG4gICAgICAgIFwia2JkXCIsXG4gICAgICAgIFwibWFya1wiLFxuICAgICAgICBcIm5hdlwiLFxuICAgICAgICBcIm5vc2NyaXB0XCIsXG4gICAgICAgIFwicnBcIixcbiAgICAgICAgXCJydFwiLFxuICAgICAgICBcInJ1YnlcIixcbiAgICAgICAgXCJzXCIsXG4gICAgICAgIFwic2FtcFwiLFxuICAgICAgICBcInNlY3Rpb25cIixcbiAgICAgICAgXCJzbWFsbFwiLFxuICAgICAgICBcInN0cm9uZ1wiLFxuICAgICAgICBcInN1YlwiLFxuICAgICAgICBcInN1bW1hcnlcIixcbiAgICAgICAgXCJzdXBcIixcbiAgICAgICAgXCJ1XCIsXG4gICAgICAgIFwidmFyXCIsXG4gICAgICAgIFwid2JyXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxFbWJlZEVsZW1lbnRcIjogW1xuICAgICAgICBcImVtYmVkXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxGaWVsZFNldEVsZW1lbnRcIjogW1xuICAgICAgICBcImZpZWxkc2V0XCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxGb250RWxlbWVudFwiOiBbXG4gICAgICAgIFwiZm9udFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MRm9ybUVsZW1lbnRcIjogW1xuICAgICAgICBcImZvcm1cIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTEZyYW1lRWxlbWVudFwiOiBbXG4gICAgICAgIFwiZnJhbWVcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTEZyYW1lU2V0RWxlbWVudFwiOiBbXG4gICAgICAgIFwiZnJhbWVzZXRcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTEhSRWxlbWVudFwiOiBbXG4gICAgICAgIFwiaHJcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTEhlYWRFbGVtZW50XCI6IFtcbiAgICAgICAgXCJoZWFkXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxIZWFkaW5nRWxlbWVudFwiOiBbXG4gICAgICAgIFwiaDFcIixcbiAgICAgICAgXCJoMlwiLFxuICAgICAgICBcImgzXCIsXG4gICAgICAgIFwiaD
23459RcIixcbiAgICAgICAgXCJoNVwiLFxuICAgICAgICBcImg2XCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxIdG1sRWxlbWVudFwiOiBbXG4gICAgICAgIFwiaHRtbFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MSUZyYW1lRWxlbWVudFwiOiBbXG4gICAgICAgIFwiaWZyYW1lXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxJbWFnZUVsZW1lbnRcIjogW1xuICAgICAgICBcImltZ1wiXG4gICAgICBdLFxuICAgICAgXCJIVE1MSW5wdXRFbGVtZW50XCI6IFtcbiAgICAgICAgXCJpbnB1dFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MS2V5Z2VuRWxlbWVudFwiOiBbXG4gICAgICAgIFwia2V5Z2VuXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxMSUVsZW1lbnRcIjogW1xuICAgICAgICBcImxpXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxMYWJlbEVsZW1lbnRcIjogW1xuICAgICAgICBcImxhYmVsXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxMZWdlbmRFbGVtZW50XCI6IFtcbiAgICAgICAgXCJsZWdlbmRcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTExpbmtFbGVtZW50XCI6IFtcbiAgICAgICAgXCJsaW5rXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxNYXBFbGVtZW50XCI6IFtcbiAgICAgICAgXCJtYXBcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTE1hcnF1ZWVFbGVtZW50XCI6IFtcbiAgICAgICAgXCJtYXJxdWVlXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxNZWRpYUVsZW1lbnRcIjogW1xuICAgICAgICBcIm1lZGlhXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxNZW51RWxlbWVudFwiOiBbXG4gICAgICAgIFwibWVudVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MTWVudUl0ZW1FbGVtZW50XCI6IFtcbiAgICAgICAgXCJtZW51aXRlbVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MTWV0YUVsZW1lbnRcIjogW1xuICAgICAgICBcIm1ldGFcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTE1ldGVyRWxlbWVudFwiOiBbXG4gICAgICAgIFwibWV0ZXJcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTE1vZEVsZW1lbnRcIjogW1xuICAgICAgICBcImRlbFwiLFxuICAgICAgICBcImluc1wiXG4gICAgICBdLFxuICAgICAgXCJIVE1MT0xpc3RFbGVtZW50XCI6IFtcbiAgICAgICAgXCJvbFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MT2JqZWN0RWxlbWVudFwiOiBbXG4gICAgICAgIFwib2JqZWN0XCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxPcHRHcm91cEVsZW1lbnRcIjogW1xuICAgICAgICBcIm9wdGdyb3VwXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxPcHRpb25FbGVtZW50XCI6IFtcbiAgICAgICAgXCJvcHRpb25cIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTE91dHB1dEVsZW1lbnRcIjogW1xuICAgICAgICBcIm91dHB1dFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MUGFyYWdyYXBoRWxlbWVudFwiOiBbXG4gICAgICAgIFwicFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MUGFyYW1FbGVtZW50XCI6IFtcbiAgICAgICAgXCJwYXJhbVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MUGljdHVyZUVsZW1lbnRcIjogW1xuICAgICAgICBcInBpY3R1cmVcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTFByZUVsZW1lbnRcIjogW1xuICAgICAgICBcInByZVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MUHJvZ3Jlc3NFbGVtZW50XCI6IFtcbiAgICAgICAgXCJwcm9ncmVzc1wiXG4gICAgICBdLFxuICAgICAgXCJIVE1MUXVvdGVFbGVtZW50XCI6IFtcbiAgICAgICAgXCJibG9ja3F1b3RlXCIsXG4gICAgICAgIFwicVwiLFxuICAgICAgICBcInF1b3RlXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxTY3JpcHRFbGVtZW50XCI6IFtcbiAgICAgICAgXCJzY3JpcHRcIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTFNlbGVjdEVsZW1lbnRcIjogW1xuICAgICAgICBcInNlbGVjdFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MU2hhZG93RWxlbWVudFwiOiBbXG4gICAgICAgIFwic2hhZG93XCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxTbG90RWxlbWVudFwiOiBbXG4gICAgICAgIFwic2xvdFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MU291cmNlRWxlbWVudFwiOiBbXG4gICAgICAgIFwic291cmNlXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxTcGFuRWxlbWVudFwiOiBbXG4gICAgICAgIFwic3BhblwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MU3R5bGVFbGVtZW50XCI6IFtcbiAgICAgICAgXCJzdHlsZVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MVGFibGVDYXB0aW9uRWxlbWVudFwiOiBbXG4gICAgICAgIFwiY2FwdGlvblwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MVGFibGVDZWxsRWxlbWVudFwiOiBbXG4gICAgICAgIFwidGRcIixcbiAgICAgICAgXCJ0aFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MVGFibGVDb2xFbGVtZW50XCI6IFtcbiAgICAgICAgXCJjb2xcIixcbiAgICAgICAgXCJjb2xncm91cFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MVGFibGVFbGVtZW50XCI6IFtcbiAgICAgICAgXCJ0YWJsZVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MVGFibGVSb3dFbGVtZW50XCI6IFtcbiAgICAgICAgXCJ0clwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MVGFibGVTZWN0aW9uRWxlbWVudFwiOiBbXG4gICAgICAgIFwidGhlYWRcIixcbiAgICAgICAgXCJ0Ym9keVwiLFxuICAgICAgICBcInRmb290XCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxUZW1wbGF0ZUVsZW1lbnRcIjogW1xuICAgICAgICBcInRlbXBsYXRlXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxUZXh0QXJlYUVsZW1lbnRcIjogW1xuICAgICAgICBcInRleHRhcmVhXCJcbiAgICAgIF0sXG4gICAgICBcIkhUTUxUaW1lRWxlbWVudFwiOiBbXG4gICAgICAgIFwidGltZVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MVGl0bGVFbGVtZW50XCI6IFtcbiAgICAgICAgXCJ0aXRsZVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MVHJhY2tFbGVtZW50XCI6IFtcbiAgICAgICAgXCJ0cmFja1wiXG4gICAgICBdLFxuICAgICAgXCJIVE1MVUxpc3RFbGVtZW50XCI6IFtcbiAgICAgICAgXCJ1bFwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MVW5rbm93bkVsZW1lbnRcIjogW1xuICAgICAgICBcInVua25vd25cIixcbiAgICAgICAgXCJ2aGdyb3VwdlwiLFxuICAgICAgICBcInZrZXlnZW5cIlxuICAgICAgXSxcbiAgICAgIFwiSFRNTFZpZGVvRWxlbWVudFwiOiBbXG4gICAgICAgIFwidmlkZW9cIlxuICAgICAgXVxuICAgIH0sXG4gICAgXCJub2Rlc1wiOiB7XG4gICAgICBcIkF0dHJcIjogW1xuICAgICAgICBcIm5vZGVcIlxuICAgICAgXSxcbiAgICAgIFwiQXVkaW9cIjogW1xuICAgICAgICBcImF1ZGlvXCJcbiAgICAgIF0sXG4gICAgICBcIkNEQVRBU2VjdGlvblwiOiBbXG4gICAgICAgIFwibm9kZVwiXG4gICAgICBdLFxuICAgICAgXCJDaGFyYWN0ZXJEYXRhXCI6IFtcbiAgICAgICAgXCJub2RlXCJcbiAgICAgIF0sXG4gICAgICBcIkNvbW1lbnRcIjogW1xuICAgICAgICBcIiNjb21tZW50XCJcbiAgICAgIF0sXG4gICAgICBcIkRvY3VtZW50XCI6IFtcbiAgICAgICAgXCIjZG9jdW1lbnRcIlxuICAgICAgXSxcbiAgICAgIFwiRG9jdW1lbnRGcmFnbWVudFwiOiBbXG4gICAgICAgIFwiI2RvY3VtZW50LWZyYWdtZW50XCJcbiAgICAgIF0sXG4gICAgICBcIkRvY3VtZW50VHlwZVwiOiBbXG4gICAgICAgIFwibm9kZVwiXG4gICAgICBdLFxuICAgICAgXCJIVE1MRG9jdW1lbnRcIjogW1xuICAgICAgICBcIiNkb2N1bWVudFwiXG4gICAgICBdLFxuICAgICAgXCJJbWFnZVwiOiBbXG4gICAgICAgIFwiaW1nXCJcbiAgICAgIF0sXG4gICAgICBcIk9wdGlvblwiOiBbXG4gICAgICAgIFwib3B0aW9uXCJcbiAgICAgIF0sXG4gICAgICBcIlByb2Nlc3NpbmdJbnN0cnVjdGlvblwiOiBbXG4gICAgICAgIFwibm9kZVwiXG4gICAgICBdLFxuICAgICAgXCJTaGFkb3dSb290XCI6IFtcbiAgICAgICAgXCIjc2hhZG93LXJvb3RcIlxuICAgICAgXSxcbiAgICAgIFwiVGV4dFwiOiBbXG4gICAgICAgIFwiI3RleHRcIlxuICAgICAgXSxcbiAgICAgIFwiWE1MRG9jdW1lbnRcIjogW1xuICAgICAgICBcInhtbFwiXG4gICAgICBdXG4gICAgfVxuICB9KSk7XG4gIFxuICBcbiAgICBcbiAgLy8gcGFzc2VkIGF0IHJ1bnRpbWUsIGNvbmZpZ3VyYWJsZSB2aWEgbm9kZWpzIG1vZHVsZVxuICBpZiAodHlwZW9mIHBvbHlmaWxsICE9PSAnb2JqZWN0JykgcG9seWZpbGwgPSB7dHlwZTogcG9seWZpbGwgfHwgJ2F1dG8nfTtcbiAgXG4gIHZhclxuICAgIC8vIFYwIHBvbHlmaWxsIGVudHJ5XG4gICAgUkVHSVNURVJfRUxFTUVOVCA9ICdyZWdpc3RlckVsZW1lbnQnLFxuICBcbiAgICAvLyBwc2V1ZG8tcmFuZG9tIG51bWJlciB1c2VkIGFzIGV4cGFuZG8vdW5pcXVlIG5hbWUgb24gZmVhdHVyZSBkZXRlY3Rpb25cbiAgICBVSUQgPSB3aW5kb3cuTWF0aC5yYW5kb20oKSAqIDEwZTQgPj4gMCxcbiAgXG4gICAgLy8gSUUgPCAxMSBvbmx5ICsgb2xkIFdlYktpdCBmb3IgYXR0cmlidXRlcyArIGZlYXR1cmUgZGV0ZWN0aW9uXG4gICAgRVhQQU5ET19VSUQgPSAnX18nICsgUkVHSVNURVJfRUxFTUVOVCArIFVJRCxcbiAgXG4gICAgLy8gc2hvcnRjdXRzIGFuZCBjb3N0YW50c1xuICAgIEFERF9FVkVOVF9MSVNURU5FUiA9ICdhZGRFdmVudExpc3RlbmVyJyxcbiAgICBBVFRBQ0hFRCA9ICdhdHRhY2hlZCcsXG4gICAgQ0FMTEJBQ0sgPSAnQ2FsbGJhY2snLFxuICAgIERFVEFDSEVEID0gJ2RldGFjaGVkJyxcbiAgICBFWFRFTkRTID0gJ2V4dGVuZHMnLFxuICBcbiAgICBBVFRSSUJVVEVfQ0hBTkdFRF9DQUxMQkFDSyA9ICdhdHRyaWJ1dGVDaGFuZ2VkJyArIENBTExCQUNLLFxuICAgIEFUVEFDSEVEX0NBTExCQUNLID0gQVRUQUNIRUQgKyBDQUxMQkFDSyxcbiAgICBDT05ORUNURURfQ0FMTEJBQ0sgPSAnY29ubmVjdGVkJyArIENBTExCQUNLLFxuICAgIERJU0NPTk5FQ1RFRF9DQUxMQkFDSyA9ICdkaXNjb25uZWN0ZWQnICsgQ0FMTEJBQ0ssXG4gICAgQ1JFQVRFRF9DQUxMQkFDSyA9ICdjcmVhdGVkJyArIENBTExCQUNLLFxuICAgIERFVEFDSEVEX0NBTExCQUNLID0gREVUQUNIRUQgKyBDQUxMQkFDSyxcbiAgXG4gICAgQURESVRJT04gPSAnQURESVRJT04nLFxuICAgIE1PRElGSUNBVElPTiA9ICdNT0RJRklDQVRJT04nLFxuICAgIFJFTU9WQUwgPSAnUkVNT1ZBTCcsXG4gIFxuICAgIERPTV9BVFRSX01PRElGSUVEID0gJ0RPTUF0dHJNb2RpZmllZCcsXG4gICAgRE9NX0NPTlRFTlRfTE9BREVEID0gJ0RPTUNvbnRlbnRMb2FkZWQnLFxuICAgIERPTV9TVUJUUkVFX01PRElGSUVEID0gJ0RPTVN1YnRyZWVNb2RpZmllZCcsXG4gIFxuICAgIFBSRUZJWF9UQUcgPSAnPCcsXG4gICAgUFJFRklYX0lTID0gJz0nLFxuICBcbiAgICAvLyB2YWxpZCBhbmQgaW52YWxpZCBub2RlIG5hbWVzXG4gICAgdmFsaWROYW1lID0gL15bQS1aXVsuX0EtWjAtOV0qLVstLl9BLVowLTldKiQvLFxuICAgIGludmFsaWROYW1lcyA9IFtcbiAgICAgICdBTk5PVEFUSU9OLVhNTCcsXG4gICAgICAnQ09MT1ItUFJPRklMRScsXG4gICAgICAnRk9OVC1GQUNFJyxcbiAgICAgICdGT05ULUZBQ0UtU1JDJyxcbiAgICAgICdGT05ULUZBQ0UtVVJJJyxcbiAgICAgICdGT05ULUZBQ0UtRk9STUFUJyxcbiAgICAgICdGT05ULUZBQ0UtTkFNRScsXG4gICAgICAnTUlTU0lORy1HTFlQSCdcbiAgICBdLFxuICBcbiAgICAvLyByZWdpc3RlcmVkIHR5cGVzIGFuZCB0aGVpciBwcm90b3R5cGVzXG4gICAgdHlwZXMgPSBbXSxcbiAgICBwcm90b3MgPSBbXSxcbiAgXG4gICAgLy8gdG8gcXVlcnkgc3Vibm9kZXNcbiAgICBxdWVyeSA9ICcnLFxuICBcbiAgICAvLyBodG1sIHNob3J0Y3V0IHVzZWQgdG8gZmVhdHVyZSBkZXRlY3RcbiAgICBkb2
23459N1bWVudEVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsXG4gIFxuICAgIC8vIEVTNSBpbmxpbmUgaGVscGVycyB8fCBiYXNpYyBwYXRjaGVzXG4gICAgaW5kZXhPZiA9IHR5cGVzLmluZGV4T2YgfHwgZnVuY3Rpb24gKHYpIHtcbiAgICAgIGZvcih2YXIgaSA9IHRoaXMubGVuZ3RoOyBpLS0gJiYgdGhpc1tpXSAhPT0gdjspe31cbiAgICAgIHJldHVybiBpO1xuICAgIH0sXG4gIFxuICAgIC8vIG90aGVyIGhlbHBlcnMgLyBzaG9ydGN1dHNcbiAgICBPUCA9IE9iamVjdC5wcm90b3R5cGUsXG4gICAgaE9QID0gT1AuaGFzT3duUHJvcGVydHksXG4gICAgaVBPID0gT1AuaXNQcm90b3R5cGVPZixcbiAgXG4gICAgZGVmaW5lUHJvcGVydHkgPSBPYmplY3QuZGVmaW5lUHJvcGVydHksXG4gICAgZW1wdHkgPSBbXSxcbiAgICBnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcixcbiAgICBnT1BOID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMsXG4gICAgZ1BPID0gT2JqZWN0LmdldFByb3RvdHlwZU9mLFxuICAgIHNQTyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZixcbiAgXG4gICAgLy8ganNoaW50IHByb3RvOiB0cnVlXG4gICAgaGFzUHJvdG8gPSAhIU9iamVjdC5fX3Byb3RvX18sXG4gIFxuICAgIC8vIFYxIGhlbHBlcnNcbiAgICBmaXhHZXRDbGFzcyA9IGZhbHNlLFxuICAgIERSRUNFVjEgPSAnX19kcmVDRXYxJyxcbiAgICBjdXN0b21FbGVtZW50cyA9IHdpbmRvdy5jdXN0b21FbGVtZW50cyxcbiAgICB1c2FibGVDdXN0b21FbGVtZW50cyA9ICEvXmZvcmNlLy50ZXN0KHBvbHlmaWxsLnR5cGUpICYmICEhKFxuICAgICAgY3VzdG9tRWxlbWVudHMgJiZcbiAgICAgIGN1c3RvbUVsZW1lbnRzLmRlZmluZSAmJlxuICAgICAgY3VzdG9tRWxlbWVudHMuZ2V0ICYmXG4gICAgICBjdXN0b21FbGVtZW50cy53aGVuRGVmaW5lZFxuICAgICksXG4gICAgRGljdCA9IE9iamVjdC5jcmVhdGUgfHwgT2JqZWN0LFxuICAgIE1hcCA9IHdpbmRvdy5NYXAgfHwgZnVuY3Rpb24gTWFwKCkge1xuICAgICAgdmFyIEsgPSBbXSwgViA9IFtdLCBpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoaykge1xuICAgICAgICAgIHJldHVybiBWW2luZGV4T2YuY2FsbChLLCBrKV07XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogZnVuY3Rpb24gKGssIHYpIHtcbiAgICAgICAgICBpID0gaW5kZXhPZi5jYWxsKEssIGspO1xuICAgICAgICAgIGlmIChpIDwgMCkgVltLLnB1c2goaykgLSAxXSA9IHY7XG4gICAgICAgICAgZWxzZSBWW2ldID0gdjtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9LFxuICAgIFByb21pc2UgPSB3aW5kb3cuUHJvbWlzZSB8fCBmdW5jdGlvbiAoZm4pIHtcbiAgICAgIHZhclxuICAgICAgICBub3RpZnkgPSBbXSxcbiAgICAgICAgZG9uZSA9IGZhbHNlLFxuICAgICAgICBwID0ge1xuICAgICAgICAgICdjYXRjaCc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBwO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgJ3RoZW4nOiBmdW5jdGlvbiAoY2IpIHtcbiAgICAgICAgICAgIG5vdGlmeS5wdXNoKGNiKTtcbiAgICAgICAgICAgIGlmIChkb25lKSBzZXRUaW1lb3V0KHJlc29sdmUsIDEpO1xuICAgICAgICAgICAgcmV0dXJuIHA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICA7XG4gICAgICBmdW5jdGlvbiByZXNvbHZlKHZhbHVlKSB7XG4gICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICB3aGlsZSAobm90aWZ5Lmxlbmd0aCkgbm90aWZ5LnNoaWZ0KCkodmFsdWUpO1xuICAgICAgfVxuICAgICAgZm4ocmVzb2x2ZSk7XG4gICAgICByZXR1cm4gcDtcbiAgICB9LFxuICAgIGp1c3RDcmVhdGVkID0gZmFsc2UsXG4gICAgY29uc3RydWN0b3JzID0gRGljdChudWxsKSxcbiAgICB3YWl0aW5nTGlzdCA9IERpY3QobnVsbCksXG4gICAgbm9kZU5hbWVzID0gbmV3IE1hcCgpLFxuICAgIHNlY29uZEFyZ3VtZW50ID0gZnVuY3Rpb24gKGlzKSB7XG4gICAgICByZXR1cm4gaXMudG9Mb3dlckNhc2UoKTtcbiAgICB9LFxuICBcbiAgICAvLyB1c2VkIHRvIGNyZWF0ZSB1bmlxdWUgaW5zdGFuY2VzXG4gICAgY3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiBCcmlkZ2UocHJvdG8pIHtcbiAgICAgIC8vIHNpbGx5IGJyb2tlbiBwb2x5ZmlsbCBwcm9iYWJseSBldmVyIHVzZWQgYnV0IHNob3J0IGVub3VnaCB0byB3b3JrXG4gICAgICByZXR1cm4gcHJvdG8gPyAoKEJyaWRnZS5wcm90b3R5cGUgPSBwcm90byksIG5ldyBCcmlkZ2UoKSkgOiB0aGlzO1xuICAgIH0sXG4gIFxuICAgIC8vIHdpbGwgc2V0IHRoZSBwcm90b3R5cGUgaWYgcG9zc2libGVcbiAgICAvLyBvciBjb3B5IG92ZXIgYWxsIHByb3BlcnRpZXNcbiAgICBzZXRQcm90b3R5cGUgPSBzUE8gfHwgKFxuICAgICAgaGFzUHJvdG8gP1xuICAgICAgICBmdW5jdGlvbiAobywgcCkge1xuICAgICAgICAgIG8uX19wcm90b19fID0gcDtcbiAgICAgICAgICByZXR1cm4gbztcbiAgICAgICAgfSA6IChcbiAgICAgIChnT1BOICYmIGdPUEQpID9cbiAgICAgICAgKGZ1bmN0aW9uKCl7XG4gICAgICAgICAgZnVuY3Rpb24gc2V0UHJvcGVydGllcyhvLCBwKSB7XG4gICAgICAgICAgICBmb3IgKHZhclxuICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgIG5hbWVzID0gZ09QTihwKSxcbiAgICAgICAgICAgICAgaSA9IDAsIGxlbmd0aCA9IG5hbWVzLmxlbmd0aDtcbiAgICAgICAgICAgICAgaSA8IGxlbmd0aDsgaSsrXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAga2V5ID0gbmFtZXNbaV07XG4gICAgICAgICAgICAgIGlmICghaE9QLmNhbGwobywga2V5KSkge1xuICAgICAgICAgICAgICAgIGRlZmluZVByb3BlcnR5KG8sIGtleSwgZ09QRChwLCBrZXkpKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG8sIHApIHtcbiAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgc2V0UHJvcGVydGllcyhvLCBwKTtcbiAgICAgICAgICAgIH0gd2hpbGUgKChwID0gZ1BPKHApKSAmJiAhaVBPLmNhbGwocCwgbykpO1xuICAgICAgICAgICAgcmV0dXJuIG87XG4gICAgICAgICAgfTtcbiAgICAgICAgfSgpKSA6XG4gICAgICAgIGZ1bmN0aW9uIChvLCBwKSB7XG4gICAgICAgICAgZm9yICh2YXIga2V5IGluIHApIHtcbiAgICAgICAgICAgIG9ba2V5XSA9IHBba2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG87XG4gICAgICAgI
23459H1cbiAgICApKSxcbiAgXG4gICAgLy8gRE9NIHNob3J0Y3V0cyBhbmQgaGVscGVycywgaWYgYW55XG4gIFxuICAgIE11dGF0aW9uT2JzZXJ2ZXIgPSB3aW5kb3cuTXV0YXRpb25PYnNlcnZlciB8fFxuICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cuV2ViS2l0TXV0YXRpb25PYnNlcnZlcixcbiAgXG4gICAgSFRNTEFuY2hvckVsZW1lbnQgPSB3aW5kb3cuSFRNTEFuY2hvckVsZW1lbnQsXG4gIFxuICAgIEhUTUxFbGVtZW50UHJvdG90eXBlID0gKFxuICAgICAgd2luZG93LkhUTUxFbGVtZW50IHx8XG4gICAgICB3aW5kb3cuRWxlbWVudCB8fFxuICAgICAgd2luZG93Lk5vZGVcbiAgICApLnByb3RvdHlwZSxcbiAgXG4gICAgSUU4ID0gIWlQTy5jYWxsKEhUTUxFbGVtZW50UHJvdG90eXBlLCBkb2N1bWVudEVsZW1lbnQpLFxuICBcbiAgICBzYWZlUHJvcGVydHkgPSBJRTggPyBmdW5jdGlvbiAobywgaywgZCkge1xuICAgICAgb1trXSA9IGQudmFsdWU7XG4gICAgICByZXR1cm4gbztcbiAgICB9IDogZGVmaW5lUHJvcGVydHksXG4gIFxuICAgIGlzVmFsaWROb2RlID0gSUU4ID9cbiAgICAgIGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICAgIHJldHVybiBub2RlLm5vZGVUeXBlID09PSAxO1xuICAgICAgfSA6XG4gICAgICBmdW5jdGlvbiAobm9kZSkge1xuICAgICAgICByZXR1cm4gaVBPLmNhbGwoSFRNTEVsZW1lbnRQcm90b3R5cGUsIG5vZGUpO1xuICAgICAgfSxcbiAgXG4gICAgdGFyZ2V0cyA9IElFOCAmJiBbXSxcbiAgXG4gICAgYXR0YWNoU2hhZG93ID0gSFRNTEVsZW1lbnRQcm90b3R5cGUuYXR0YWNoU2hhZG93LFxuICAgIGNsb25lTm9kZSA9IEhUTUxFbGVtZW50UHJvdG90eXBlLmNsb25lTm9kZSxcbiAgICBjbG9zZXN0ID0gSFRNTEVsZW1lbnRQcm90b3R5cGUuY2xvc2VzdCB8fCBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgd2hpbGUgKHNlbGYgJiYgc2VsZi5ub2RlTmFtZSAhPT0gbmFtZSlcbiAgICAgICAgc2VsZiA9IHNlbGYucGFyZW50Tm9kZTtcbiAgICAgIHJldHVybiBzZWxmO1xuICAgIH0sXG4gICAgZGlzcGF0Y2hFdmVudCA9IEhUTUxFbGVtZW50UHJvdG90eXBlLmRpc3BhdGNoRXZlbnQsXG4gICAgZ2V0QXR0cmlidXRlID0gSFRNTEVsZW1lbnRQcm90b3R5cGUuZ2V0QXR0cmlidXRlLFxuICAgIGhhc0F0dHJpYnV0ZSA9IEhUTUxFbGVtZW50UHJvdG90eXBlLmhhc0F0dHJpYnV0ZSxcbiAgICByZW1vdmVBdHRyaWJ1dGUgPSBIVE1MRWxlbWVudFByb3RvdHlwZS5yZW1vdmVBdHRyaWJ1dGUsXG4gICAgc2V0QXR0cmlidXRlID0gSFRNTEVsZW1lbnRQcm90b3R5cGUuc2V0QXR0cmlidXRlLFxuICBcbiAgICAvLyByZXBsYWNlZCBsYXRlciBvblxuICAgIGNyZWF0ZUVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50LFxuICAgIGltcG9ydE5vZGUgPSBkb2N1bWVudC5pbXBvcnROb2RlLFxuICAgIHBhdGNoZWRDcmVhdGVFbGVtZW50ID0gY3JlYXRlRWxlbWVudCxcbiAgXG4gICAgLy8gc2hhcmVkIG9ic2VydmVyIGZvciBhbGwgYXR0cmlidXRlc1xuICAgIGF0dHJpYnV0ZXNPYnNlcnZlciA9IE11dGF0aW9uT2JzZXJ2ZXIgJiYge1xuICAgICAgYXR0cmlidXRlczogdHJ1ZSxcbiAgICAgIGNoYXJhY3RlckRhdGE6IHRydWUsXG4gICAgICBhdHRyaWJ1dGVPbGRWYWx1ZTogdHJ1ZVxuICAgIH0sXG4gIFxuICAgIC8vIHVzZWZ1bCB0byBkZXRlY3Qgb25seSBpZiB0aGVyZSdzIG5vIE11dGF0aW9uT2JzZXJ2ZXJcbiAgICBET01BdHRyTW9kaWZpZWQgPSBNdXRhdGlvbk9ic2VydmVyIHx8IGZ1bmN0aW9uKGUpIHtcbiAgICAgIGRvZXNOb3RTdXBwb3J0RE9NQXR0ck1vZGlmaWVkID0gZmFsc2U7XG4gICAgICBkb2
23459N1bWVudEVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgRE9NX0FUVFJfTU9ESUZJRUQsXG4gICAgICAgIERPTUF0dHJNb2RpZmllZFxuICAgICAgKTtcbiAgICB9LFxuICBcbiAgICAvLyB3aWxsIGJvdGggYmUgdXNlZCB0byBtYWtlIERPTU5vZGVJbnNlcnRlZCBhc3luY2hyb25vdXNcbiAgICBhc2FwUXVldWUsXG4gICAgYXNhcFRpbWVyID0gMCxcbiAgXG4gICAgLy8gaW50ZXJuYWwgZmxhZ3NcbiAgICBWMCA9IFJFR0lTVEVSX0VMRU1FTlQgaW4gZG9jdW1lbnQgJiZcbiAgICAgICAgICEvXmZvcmNlLWFsbC8udGVzdChwb2x5ZmlsbC50eXBlKSxcbiAgICBzZXRMaXN0ZW5lciA9IHRydWUsXG4gICAganVzdFNldHVwID0gZmFsc2UsXG4gICAgZG9lc05vdFN1cHBvcnRET01BdHRyTW9kaWZpZWQgPSB0cnVlLFxuICAgIGRyb3BEb21Db250ZW50TG9hZGVkID0gdHJ1ZSxcbiAgXG4gICAgLy8gbmVlZGVkIGZvciB0aGUgaW5uZXJIVE1MIGhlbHBlclxuICAgIG5vdEZyb21Jbm5lckhUTUxIZWxwZXIgPSB0cnVlLFxuICBcbiAgICAvLyBvcHRpb25hbGx5IGRlZmluZWQgbGF0ZXIgb25cbiAgICBvblN1YnRyZWVNb2RpZmllZCxcbiAgICBjYWxsRE9NQXR0ck1vZGlmaWVkLFxuICAgIGdldEF0dHJpYnV0ZXNNaXJyb3IsXG4gICAgb2JzZXJ2ZXIsXG4gICAgb2JzZXJ2ZSxcbiAgXG4gICAgLy8gYmFzZWQgb24gc2V0dGluZyBwcm90b3R5cGUgY2FwYWJpbGl0eVxuICAgIC8vIHdpbGwgY2hlY2sgcHJvdG8gb3IgdGhlIGV4cGFuZG8gYXR0cmlidXRlXG4gICAgLy8gaW4gb3JkZXIgdG8gc2V0dXAgdGhlIG5vZGUgb25jZVxuICAgIHBhdGNoSWZOb3RBbHJlYWR5LFxuICAgIHBhdGNoLFxuICBcbiAgICAvLyB1c2VkIGZvciB0ZXN0c1xuICAgIHRtcFxuICA7XG4gIFxuICAvLyBJRTExIGRpc2Nvbm5lY3RlZENhbGxiYWNrIGlzc3VlICNcbiAgLy8gdG8gYmUgdGVzdGVkIGJlZm9yZSBhbnkgY3JlYXRlRWxlbWVudCBwYXRjaFxuICBpZiAoTXV0YXRpb25PYnNlcnZlcikge1xuICAgIC8vIG9yaWdpbmFsIGZpeDpcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vamF2YW4vbXV0YXRpb24tb2JzZXJ2ZXItaW5uZXItaHRtbC1zaGltXG4gICAgdG1wID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdG1wLmlubmVySFRNTCA9ICc8ZGl2PjxkaXY+PC9kaXY+PC9kaXY+JztcbiAgICBuZXcgTXV0YXRpb25PYnNlcnZlcihmdW5jdGlvbiAobXV0YXRpb25zLCBvYnNlcnZlcikge1xuICAgICAgaWYgKFxuICAgICAgICBtdXRhdGlvbnNbMF0gJiZcbiAgICAgICAgbXV0YXRpb25zWzBdLnR5cGUgPT0gJ2NoaWxkTGlzdCcgJiZcbiAgICAgICAgIW11dGF0aW9uc1swXS5yZW1vdmVkTm9kZXNbMF0uY2hpbGROb2Rlcy5sZW5ndGhcbiAgICAgICkge1xuICAgICAgICB0bXAgPSBnT1BEKEhUTUxFbGVtZW50UHJvdG90eXBlLCAnaW5uZXJIVE1MJyk7XG4gICAgICAgIHZhciBzZXQgPSB0bXAgJiYgdG1wLnNldDtcbiAgICAgICAgaWYgKHNldClcbiAgICAgICAgICBkZWZpbmVQcm9wZXJ0eShIVE1MRWxlbWVudFByb3RvdHlwZSwgJ2lubmVySFRNTCcsIHtcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgIHdoaWxlICh0aGlzLmxhc3RDaGlsZClcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUNoaWxkKHRoaXMubGFzdENoaWxkKTtcbiAgICAgICAgICAgICAgc2V0LmNhbGwodGhpcywgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgdG1wID0gbnVsbDtcbiAgICB9KS5vYnNlcnZlKHRtcCwge2NoaWxkTGlzdDogdHJ1ZSwgc3VidHJlZTogdHJ1ZX0pO1xuICAgIHRtcC5pbm5lckhUTUwgPSBcIlwiO1xuICB9XG4gIFxuICAvLyBvbmx5IGlmIG5lZWRlZFxuICBpZiAoIVYwKSB7XG4gIFxuICAgIGlmIChzUE8gfHwgaGFzUHJvdG8pIHtcbiAgICAgICAgcGF0Y2hJZk5vdEFscmVhZHkgPSBmdW5jdGlvbiAobm9kZSwgcHJvdG8pIHtcbiAgICAgICAgICBpZiAoIWlQTy5jYWxsKHByb3RvLCBub2RlKSkge1xuICAgICAgICAgICAgc2V0dXBOb2RlKG5vZGUsIHByb3RvKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHBhdGNoID0gc2V0dXBOb2RlO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHBhdGNoSWZOb3RBbHJlYWR5ID0gZnVuY3Rpb24gKG5vZGUsIHByb3RvKSB7XG4gICAgICAgICAgaWYgKCFub2RlW0VYUEFORE9fVUlEXSkge1xuICAgICAgICAgICAgbm9kZVtFWFBBTkRPX1VJRF0gPSBPYmplY3QodHJ1ZSk7XG4gICAgICAgICAgICBzZXR1cE5vZGUobm9kZSwgcHJvdG8pO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcGF0Y2ggPSBwYXRjaElmTm90QWxyZWFkeTtcbiAgICB9XG4gIFxuICAgIGlmIChJRTgpIHtcbiAgICAgIGRvZXNOb3RTdXBwb3J0RE9NQXR0ck1vZGlmaWVkID0gZmFsc2U7XG4gICAgICAoZnVuY3Rpb24gKCl7XG4gICAgICAgIHZhclxuICAgICAgICAgIGRlc2NyaXB0b3IgPSBnT1BEKEhUTUxFbGVtZW50UHJvdG90eXBlLCBBRERfRVZFTlRfTElTVEVORVIpLFxuICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIgPSBkZXNjcmlwdG9yLnZhbHVlLFxuICAgICAgICAgIHBhdGNoZWRSZW1vdmVBdHRyaWJ1dGUgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgdmFyIGUgPSBuZXcgQ3VzdG9tRXZlbnQoRE9NX0FUVFJfTU9ESUZJRUQsIHtidWJibGVzOiB0cnVlfSk7XG4gICAgICAgICAgICBlLmF0dHJOYW1lID0gbmFtZTtcbiAgICAgICAgICAgIGUucHJldlZhbHVlID0gZ2V0QXR0cmlidXRlLmNhbGwodGhpcywgbmFtZSk7XG4gICAgICAgICAgICBlLm5ld1ZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIGVbUkVNT1ZBTF0gPSBlLmF0dHJDaGFuZ2UgPSAyO1xuICAgICAgICAgICAgcmVtb3ZlQXR0cmlidXRlLmNhbGwodGhpcywgbmFtZSk7XG4gICAgICAgICAgICBkaXNwYXRjaEV2ZW50LmNhbGwodGhpcywgZSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBwYXRjaGVkU2V0QXR0cmlidXRlID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlKSB7XG4gICAgICAgICAgICB2Y
23459XJcbiAgICAgICAgICAgICAgaGFkID0gaGFzQXR0cmlidXRlLmNhbGwodGhpcywgbmFtZSksXG4gICAgICAgICAgICAgIG9sZCA9IGhhZCAmJiBnZXRBdHRyaWJ1dGUuY2FsbCh0aGlzLCBuYW1lKSxcbiAgICAgICAgICAgICAgZSA9IG5ldyBDdXN0b21FdmVudChET01fQVRUUl9NT0RJRklFRCwge2J1YmJsZXM6IHRydWV9KVxuICAgICAgICAgICAgO1xuICAgICAgICAgICAgc2V0QXR0cmlidXRlLmNhbGwodGhpcywgbmFtZSwgdmFsdWUpO1xuICAgICAgICAgICAgZS5hdHRyTmFtZSA9IG5hbWU7XG4gICAgICAgICAgICBlLnByZXZWYWx1ZSA9IGhhZCA/IG9sZCA6IG51bGw7XG4gICAgICAgICAgICBlLm5ld1ZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAoaGFkKSB7XG4gICAgICAgICAgICAgIGVbTU9ESUZJQ0FUSU9OXSA9IGUuYXR0ckNoYW5nZSA9IDE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBlW0FERElUSU9OXSA9IGUuYXR0ckNoYW5nZSA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkaXNwYXRjaEV2ZW50LmNhbGwodGhpcywgZSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBvblByb3BlcnR5Q2hhbmdlID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIC8vIGpzaGludCBlcW51bGw6dHJ1ZVxuICAgICAgICAgICAgdmFyXG4gICAgICAgICAgICAgIG5vZGUgPSBlLmN1cnJlbnRUYXJnZXQsXG4gICAgICAgICAgICAgIHN1cGVyU2VjcmV0ID0gbm9kZVtFWFBBTkRPX1VJRF0sXG4gICAgICAgICAgICAgIHByb3BlcnR5TmFtZSA9IGUucHJvcGVydHlOYW1lLFxuICAgICAgICAgICAgICBldmVudFxuICAgICAgICAgICAgO1xuICAgICAgICAgICAgaWYgKHN1cGVyU2VjcmV0Lmhhc093blByb3BlcnR5KHByb3BlcnR5TmFtZSkpIHtcbiAgICAgICAgICAgICAgc3VwZXJTZWNyZXQgPSBzdXBlclNlY3JldFtwcm9wZXJ0eU5hbWVdO1xuICAgICAgICAgICAgICBldmVudCA9IG5ldyBDdXN0b21FdmVudChET01fQVRUUl9NT0RJRklFRCwge2J1YmJsZXM6IHRydWV9KTtcbiAgICAgICAgICAgICAgZXZlbnQuYXR0ck5hbWUgPSBzdXBlclNlY3JldC5uYW1lO1xuICAgICAgICAgICAgICBldmVudC5wcmV2VmFsdWUgPSBzdXBlclNlY3JldC52YWx1ZSB8fCBudWxsO1xuICAgICAgICAgICAgICBldmVudC5uZXdWYWx1ZSA9IChzdXBlclNlY3JldC52YWx1ZSA9IG5vZGVbcHJvcGVydHlOYW1lXSB8fCBudWxsKTtcbiAgICAgICAgICAgICAgaWYgKGV2ZW50LnByZXZWYWx1ZSA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZXZlbnRbQURESVRJT05dID0gZXZlbnQuYXR0ckNoYW5nZSA9IDA7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXZlbnRbTU9ESUZJQ0FUSU9OXSA9IGV2ZW50LmF0dHJDaGFuZ2UgPSAxO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQuY2FsbChub2RlLCBldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICA7XG4gICAgICAgIGRlc2NyaXB0b3IudmFsdWUgPSBmdW5jdGlvbiAodHlwZSwgaGFuZGxlciwgY2FwdHVyZSkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGUgPT09IERPTV9BVFRSX01PRElGSUVEICYmXG4gICAgICAgICAgICB0aGlzW0FUVFJJQlVURV9DSEFOR0VEX0NBTExCQUNLXSAmJlxuICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUgIT09IHBhdGNoZWRTZXRBdHRyaWJ1dGVcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXNbRVhQQU5ET19VSURdID0ge1xuICAgICAgICAgICAgICBjbGFzc05hbWU6IHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnY2xhc3MnLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB0aGlzLmNsYXNzTmFtZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUgPSBwYXRjaGVkU2V0QXR0cmlidXRlO1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVBdHRyaWJ1dGUgPSBwYXRjaGVkUmVtb3ZlQXR0cmlidXRlO1xuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lci5jYWxsKHRoaXMsICdwcm9wZXJ0eWNoYW5nZScsIG9uUHJvcGVydHlDaGFuZ2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBhZGRFdmVudExpc3RlbmVyLmNhbGwodGhpcywgdHlwZSwgaGFuZGxlciwgY2FwdHVyZSk7XG4gICAgICAgIH07XG4gICAgICAgIGRlZmluZVByb3BlcnR5KEhUTUxFbGVtZW50UHJvdG90eXBlLCBBRERfRVZFTlRfTElTVEVORVIsIGRlc2NyaXB0b3IpO1xuICAgICAgfSgpKTtcbiAgICB9IGVsc2UgaWYgKCFNdXRhdGlvbk9ic2VydmVyKSB7XG4gICAgICBkb2
23459N1bWVudEVsZW1lbnRbQUREX0VWRU5UX0xJU1RFTkVSXShET01fQVRUUl9NT0RJRklFRCwgRE9NQXR0ck1vZGlmaWVkKTtcbiAgICAgIGRvY3VtZW50RWxlbWVudC5zZXRBdHRyaWJ1dGUoRVhQQU5ET19VSUQsIDEpO1xuICAgICAgZG9jdW1lbnRFbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShFWFBBTkRPX1VJRCk7XG4gICAgICBpZiAoZG9lc05vdFN1cHBvcnRET01BdHRyTW9kaWZpZWQpIHtcbiAgICAgICAgb25TdWJ0cmVlTW9kaWZpZWQgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgIHZhclxuICAgICAgICAgICAgbm9kZSA9IHRoaXMsXG4gICAgICAgICAgICBvbGRBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgbmV3QXR0cmlidXRlcyxcbiAgICAgICAgICAgIGtleVxuICAgICAgICAgIDtcbiAgICAgICAgICBpZiAobm9kZSA9PT0gZS50YXJnZXQpIHtcbiAgICAgICAgICAgIG9sZEF0dHJpYnV0ZXMgPSBub2RlW0VYUEFORE9fVUlEXTtcbiAgICAgICAgICAgIG5vZGVbRVhQQU5ET19VSURdID0gKG5ld0F0dHJpYnV0ZXMgPSBnZXRBdHRyaWJ1dGVzTWlycm9yKG5vZGUpKTtcbiAgICAgICAgICAgIGZvciAoa2V5IGluIG5ld0F0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgICAgaWYgKCEoa2V5IGluIG9sZEF0dHJpYnV0ZXMpKSB7XG4gICAgICAgICAgICAgICAgLy8gYXR0cmlidXRlIHdhcyBhZGRlZFxuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsRE9NQXR0ck1vZGlmaWVkKFxuICAgICAgICAgICAgICAgICAgMCxcbiAgICAgICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICBvbGRBdHRyaWJ1dGVzW2tleV0sXG4gICAgICAgICAgICAgICAgICBuZXdBdHRyaWJ1dGVzW2tleV0sXG4gICAgICAgICAgICAgICAgICBBRERJVElPTlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3QXR0cmlidXRlc1trZXldICE9PSBvbGRBdHRyaWJ1dGVzW2tleV0pIHtcbiAgICAgICAgICAgICAgICAvLyBhdHRyaWJ1dGUgd2FzIGNoYW5nZWRcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FsbERPTUF0dHJNb2RpZmllZChcbiAgICAgICAgICAgICAgICAgIDEsXG4gICAgICAgICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgb2xkQXR0cmlidXRlc1trZXldLFxuICAgICAgICAgICAgICAgICAgbmV3QXR0cmlidXRlc1trZXldLFxuICAgICAgICAgICAgICAgICAgTU9ESUZJQ0FUSU9OXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gY2hlY2tpbmcgaWYgaXQgaGFzIGJlZW4gcmVtb3ZlZFxuICAgICAgICAgICAgZm9yIChrZXkgaW4gb2xkQXR0cmlidXRlcykge1xuICAgICAgICAgICAgICBpZiAoIShrZXkgaW4gbmV3QXR0cmlidXRlcykpIHtcbiAgICAgICAgICAgICAgICAvLyBhdHRyaWJ1dGUgcmVtb3ZlZFxuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsRE9NQXR0ck1vZGlmaWVkKFxuICAgICAgICAgICAgICAgICAgMixcbiAgICAgICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICBvbGRBdHRyaWJ1dGVzW2tleV0sXG4gICAgICAgICAgICAgICAgICBuZXdBdHRyaWJ1dGVzW2tleV0sXG4gICAgICAgICAgICAgICAgICBSRU1PVkFMXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY2FsbERPTUF0dHJNb2RpZmllZCA9IGZ1bmN0aW9uIChcbiAgICAgICAgICBhdHRyQ2hhbmdlLFxuICAgICAgICAgIGN1cnJlbnRUYXJnZXQsXG4gICAgICAgICAgYXR0ck5hbWUsXG4gICAgICAgICAgcHJldlZhbHVlLFxuICAgICAgICAgIG5ld1ZhbHVlLFxuICAgICAgICAgIGFjdGlvblxuICAgICAgICApIHtcbiAgICAgICAgICB2Y
23459XIgZSA9IHtcbiAgICAgICAgICAgIGF0dHJDaGFuZ2U6IGF0dHJDaGFuZ2UsXG4gICAgICAgICAgICBjdXJyZW50VGFyZ2V0OiBjdXJyZW50VGFyZ2V0LFxuICAgICAgICAgICAgYXR0ck5hbWU6IGF0dHJOYW1lLFxuICAgICAgICAgICAgcHJldlZhbHVlOiBwcmV2VmFsdWUsXG4gICAgICAgICAgICBuZXdWYWx1ZTogbmV3VmFsdWVcbiAgICAgICAgICB9O1xuICAgICAgICAgIGVbYWN0aW9uXSA9IGF0dHJDaGFuZ2U7XG4gICAgICAgICAgb25ET01BdHRyTW9kaWZpZWQoZSk7XG4gICAgICAgIH07XG4gICAgICAgIGdldEF0dHJpYnV0ZXNNaXJyb3IgPSBmdW5jdGlvbiAobm9kZSkge1xuICAgICAgICAgIGZvciAodmFyXG4gICAgICAgICAgICBhdHRyLCBuYW1lLFxuICAgICAgICAgICAgcmVzdWx0ID0ge30sXG4gICAgICAgICAgICBhdHRyaWJ1dGVzID0gbm9kZS5hdHRyaWJ1dGVzLFxuICAgICAgICAgICAgaSA9IDAsIGxlbmd0aCA9IGF0dHJpYnV0ZXMubGVuZ3RoO1xuICAgICAgICAgICAgaSA8IGxlbmd0aDsgaSsrXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBhdHRyID0gYXR0cmlidXRlc1tpXTtcbiAgICAgICAgICAgIG5hbWUgPSBhdHRyLm5hbWU7XG4gICAgICAgICAgICBpZiAobmFtZSAhPT0gJ3NldEF0dHJpYnV0ZScpIHtcbiAgICAgICAgICAgICAgcmVzdWx0W25hbWVdID0gYXR0ci52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gIFxuICAgIC8vIHNldCBhcyBlbnVtZXJhYmxlLCB3cml0YWJsZSBhbmQgY29uZmlndXJhYmxlXG4gICAgZG9jdW1lbnRbUkVHSVNURVJfRUxFTUVOVF0gPSBmdW5jdGlvbiByZWdpc3RlckVsZW1lbnQodHlwZSwgb3B0aW9ucykge1xuICAgICAgdXBwZXJUeXBlID0gdHlwZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgaWYgKHNldExpc3RlbmVyKSB7XG4gICAgICAgIC8vIG9ubHkgZmlyc3QgdGltZSBkb2N1bWVudC5yZWdpc3RlckVsZW1lbnQgaXMgdXNlZFxuICAgICAgICAvLyB3ZSBuZWVkIHRvIHNldCB0aGlzIGxpc3RlbmVyXG4gICAgICAgIC8vIHNldHRpbmcgaXQgYnkgZGVmYXVsdCBtaWdodCBzbG93IGRvd24gZm9yIG5vIHJlYXNvblxuICAgICAgICBzZXRMaXN0ZW5lciA9IGZhbHNlO1xuICAgICAgICBpZiAoTXV0YXRpb25PYnNlcnZlcikge1xuICAgICAgICAgIG9ic2VydmVyID0gKGZ1bmN0aW9uKGF0dGFjaGVkLCBkZXRhY2hlZCl7XG4gICAgICAgICAgICBmdW5jdGlvbiBjaGVja0VtQWxsKGxpc3QsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBsaXN0Lmxlbmd0aDsgaSA8IGxlbmd0aDsgY2FsbGJhY2sobGlzdFtpKytdKSl7fVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBNdXRhdGlvbk9ic2VydmVyKGZ1bmN0aW9uIChyZWNvcmRzKSB7XG4gICAgICAgICAgICAgIGZvciAodmFyXG4gICAgICAgICAgICAgICAgY3VycmVudCwgbm9kZSwgbmV3VmFsdWUsXG4gICAgICAgICAgICAgICAgaSA9IDAsIGxlbmd0aCA9IHJlY29yZHMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKytcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudCA9IHJlY29yZHNbaV07XG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnQudHlwZSA9PT0gJ2NoaWxkTGlzdCcpIHtcbiAgICAgICAgICAgICAgICAgIGNoZWNrRW1BbGwoY3VycmVudC5hZGRlZE5vZGVzLCBhdHRhY2hlZCk7XG4gICAgICAgICAgICAgICAgICBjaGVja0VtQWxsKGN1cnJlbnQucmVtb3ZlZE5vZGVzLCBkZXRhY2hlZCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIG5vZGUgPSBjdXJyZW50LnRhcmdldDtcbiAgICAgICAgICAgICAgICAgIGlmIChub3RGcm9tSW5uZXJIVE1MSGVscGVyICYmXG4gICAgICAgICAgICAgICAgICAgICAgbm9kZVtBVFRSSUJVVEVfQ0hBTkdFRF9DQUxMQkFDS10gJiZcbiAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50LmF0dHJpYnV0ZU5hbWUgIT09ICdzdHlsZScpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWUgPSBnZXRBdHRyaWJ1dGUuY2FsbChub2RlLCBjdXJyZW50LmF0dHJpYnV0ZU5hbWUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobmV3VmFsdWUgIT09IGN1cnJlbnQub2xkVmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBub2RlW0FUVFJJQlVURV9DSEFOR0VEX0NBTExCQUNLXShcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQuYXR0cmlidXRlTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQub2xkVmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0oZXhlY3V0ZUFjdGlvbihBVFRBQ0hFRCksIGV4ZWN1dGVBY3Rpb24oREVUQUNIRUQpKSk7XG4gICAgICAgICAgb2JzZXJ2ZSA9IGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICAgICAgICBvYnNlcnZlci5vYnNlcnZlKFxuICAgICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY2hpbGRMaXN0OiB0cnVlLFxuICAgICAgICAgICAgICAgIHN1YnRyZWU6IHRydWVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICAgIH07XG4gICAgICAgICAgb2JzZXJ2ZShkb2N1bWVudCk7XG4gICAgICAgICAgaWYgKGF0dGFjaFNoYWRvdykge1xuICAgICAgICAgICAgSFRNTEVsZW1lbnRQcm90b3R5cGUuYXR0YWNoU2hhZG93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICByZXR1cm4gb2JzZXJ2ZShhdHRhY2hTaGFkb3cuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhc2FwUXVldWUgPSBbXTtcbiAgICAgICAgICBkb2
23459N1bWVudFtBRERfRVZFTlRfTElTVEVORVJdKCdET01Ob2RlSW5zZXJ0ZWQnLCBvbkRPTU5vZGUoQVRUQUNIRUQpKTtcbiAgICAgICAgICBkb2N1bWVudFtBRERfRVZFTlRfTElTVEVORVJdKCdET01Ob2RlUmVtb3ZlZCcsIG9uRE9NTm9kZShERVRBQ0hFRCkpO1xuICAgICAgICB9XG4gIFxuICAgICAgICBkb2N1bWVudFtBRERfRVZFTlRfTElTVEVORVJdKERPTV9DT05URU5UX0xPQURFRCwgb25SZWFkeVN0YXRlQ2hhbmdlKTtcbiAgICAgICAgZG9jdW1lbnRbQUREX0VWRU5UX0xJU1RFTkVSXSgncmVhZHlzdGF0ZWNoYW5nZScsIG9uUmVhZHlTdGF0ZUNoYW5nZSk7XG4gIFxuICAgICAgICBkb2N1bWVudC5pbXBvcnROb2RlID0gZnVuY3Rpb24gKG5vZGUsIGRlZXApIHtcbiAgICAgICAgICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgcmV0dXJuIHNldHVwQWxsKGRvY3VtZW50LCBpbXBvcnROb2RlLCBbbm9kZSwgISFkZWVwXSk7XG4gICAgICAgICAgICBjYXNlIDExOlxuICAgICAgICAgICAgICBmb3IgKHZhclxuICAgICAgICAgICAgICAgIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxuICAgICAgICAgICAgICAgIGNoaWxkTm9kZXMgPSBub2RlLmNoaWxkTm9kZXMsXG4gICAgICAgICAgICAgICAgbGVuZ3RoID0gY2hpbGROb2Rlcy5sZW5ndGgsXG4gICAgICAgICAgICAgICAgaSA9IDA7IGkgPCBsZW5ndGg7IGkrK1xuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuaW1wb3J0Tm9kZShjaGlsZE5vZGVzW2ldLCAhIWRlZXApKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGZyYWdtZW50O1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIGNsb25lTm9kZS5jYWxsKG5vZGUsICEhZGVlcCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICBcbiAgICAgICAgSFRNTEVsZW1lbnRQcm90b3R5cGUuY2xvbmVOb2RlID0gZnVuY3Rpb24gKGRlZXApIHtcbiAgICAgICAgICByZXR1cm4gc2V0dXBBbGwodGhpcywgY2xvbmVOb2RlLCBbISFkZWVwXSk7XG4gICAgICAgIH07XG4gICAgICB9XG4gIFxuICAgICAgaWYgKGp1c3RTZXR1cCkgcmV0dXJuIChqdXN0U2V0dXAgPSBmYWxzZSk7XG4gIFxuICAgICAgaWYgKC0yIDwgKFxuICAgICAgICBpbmRleE9mLmNhbGwodHlwZXMsIFBSRUZJWF9JUyArIHVwcGVyVHlwZSkgK1xuICAgICAgICBpbmRleE9mLmNhbGwodHlwZXMsIFBSRUZJWF9UQUcgKyB1cHBlclR5cGUpXG4gICAgICApKSB7XG4gICAgICAgIHRocm93VHlwZUVycm9yKHR5cGUpO1xuICAgICAgfVxuICBcbiAgICAgIGlmICghdmFsaWROYW1lLnRlc3QodXBwZXJUeXBlKSB8fCAtMSA8IGluZGV4T2YuY2FsbChpbnZhbGlkTmFtZXMsIHVwcGVyVHlwZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgdHlwZSAnICsgdHlwZSArICcgaXMgaW52YWxpZCcpO1xuICAgICAgfVxuICBcbiAgICAgIHZhclxuICAgICAgICBjb25zdHJ1Y3RvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gZXh0ZW5kaW5nID9cbiAgICAgICAgICAgIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQobm9kZU5hbWUsIHVwcGVyVHlwZSkgOlxuICAgICAgICAgICAgZG9jdW1lbnQuY3JlYXRlRWxlbWVudChub2RlTmFtZSk7XG4gICAgICAgIH0sXG4gICAgICAgIG9wdCA9IG9wdGlvbnMgfHwgT1AsXG4gICAgICAgIGV4dGVuZGluZyA9IGhPUC5jYWxsKG9wdCwgRVhURU5EUyksXG4gICAgICAgIG5vZGVOYW1lID0gZXh0ZW5kaW5nID8gb3B0aW9uc1tFWFRFTkRTXS50b1VwcGVyQ2FzZSgpIDogdXBwZXJUeXBlLFxuICAgICAgICB1cHBlclR5cGUsXG4gICAgICAgIGlcbiAgICAgIDtcbiAgXG4gICAgICBpZiAoZXh0ZW5kaW5nICYmIC0xIDwgKFxuICAgICAgICBpbmRleE9mLmNhbGwodHlwZXMsIFBSRUZJWF9UQUcgKyBub2RlTmFtZSlcbiAgICAgICkpIHtcbiAgICAgICAgdGhyb3dUeXBlRXJyb3Iobm9kZU5hbWUpO1xuICAgICAgfVxuICBcbiAgICAgIGkgPSB0eXBlcy5wdXNoKChleHRlbmRpbmcgPyBQUkVGSVhfSVMgOiBQUkVGSVhfVEFHKSArIHVwcGVyVHlwZSkgLSAxO1xuICBcbiAgICAgIHF1ZXJ5ID0gcXVlcnkuY29uY2F0KFxuICAgICAgICBxdWVyeS5sZW5ndGggPyAnLCcgOiAnJyxcbiAgICAgICAgZXh0ZW5kaW5nID8gbm9kZU5hbWUgKyAnW2lzPVwiJyArIHR5cGUudG9Mb3dlckNhc2UoKSArICdcIl0nIDogbm9kZU5hbWVcbiAgICAgICk7XG4gIFxuICAgICAgY29uc3RydWN0b3IucHJvdG90eXBlID0gKFxuICAgICAgICBwcm90b3NbaV0gPSBoT1AuY2FsbChvcHQsICdwcm90b3R5cGUnKSA/XG4gICAgICAgICAgb3B0LnByb3RvdHlwZSA6XG4gICAgICAgICAgY3JlYXRlKEhUTUxFbGVtZW50UHJvdG90eXBlKVxuICAgICAgKTtcbiAgXG4gICAgICBpZiAocXVlcnkubGVuZ3RoKSBsb29wQW5kVmVyaWZ5KFxuICAgICAgICBkb2
23459N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KSxcbiAgICAgICAgQVRUQUNIRURcbiAgICAgICk7XG4gIFxuICAgICAgcmV0dXJuIGNvbnN0cnVjdG9yO1xuICAgIH07XG4gIFxuICAgIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgPSAocGF0Y2hlZENyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbiAobG9jYWxOYW1lLCB0eXBlRXh0ZW5zaW9uKSB7XG4gICAgICB2YXJcbiAgICAgICAgaXMgPSBnZXRJcyh0eXBlRXh0ZW5zaW9uKSxcbiAgICAgICAgbm9kZSA9IGlzID9cbiAgICAgICAgICBjcmVhdGVFbGVtZW50LmNhbGwoZG9jdW1lbnQsIGxvY2FsTmFtZSwgc2Vjb25kQXJndW1lbnQoaXMpKSA6XG4gICAgICAgICAgY3JlYXRlRWxlbWVudC5jYWxsKGRvY3VtZW50LCBsb2NhbE5hbWUpLFxuICAgICAgICBuYW1lID0gJycgKyBsb2NhbE5hbWUsXG4gICAgICAgIGkgPSBpbmRleE9mLmNhbGwoXG4gICAgICAgICAgdHlwZXMsXG4gICAgICAgICAgKGlzID8gUFJFRklYX0lTIDogUFJFRklYX1RBRykgK1xuICAgICAgICAgIChpcyB8fCBuYW1lKS50b1VwcGVyQ2FzZSgpXG4gICAgICAgICksXG4gICAgICAgIHNldHVwID0gLTEgPCBpXG4gICAgICA7XG4gICAgICBpZiAoaXMpIHtcbiAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoJ2lzJywgaXMgPSBpcy50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgaWYgKHNldHVwKSB7XG4gICAgICAgICAgc2V0dXAgPSBpc0luUVNBKG5hbWUudG9VcHBlckNhc2UoKSwgaXMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBub3RGcm9tSW5uZXJIVE1MSGVscGVyID0gIWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQuaW5uZXJIVE1MSGVscGVyO1xuICAgICAgaWYgKHNldHVwKSBwYXRjaChub2RlLCBwcm90b3NbaV0pO1xuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfSk7XG4gIFxuICB9XG4gIFxuICAvLyBuZWVkZWQgZHVlIHVuYmVsaWV2YWJsZSBJRTExIGJlaGF2aW9yXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9XZWJSZWZsZWN0aW9uL2RvY3VtZW50LXJlZ2lzdGVyLWVsZW1lbnQvaXNzdWVzLzE3NSNpc3N1ZWNvbW1lbnQtNTIwOTA0Njg4XG4gIGFkZEV2ZW50TGlzdGVuZXIoXG4gICAgJ2JlZm9yZXVubG9hZCcsXG4gICAgZnVuY3Rpb24gKCkge1xuICAgICAgZGVsZXRlIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQ7XG4gICAgICBkZWxldGUgZG9jdW1lbnQuaW1wb3J0Tm9kZTtcbiAgICAgIGRlbGV0ZSBkb2N1bWVudFtSRUdJU1RFUl9FTEVNRU5UXTtcbiAgICB9LFxuICAgIGZhbHNlXG4gICk7XG4gIFxuICBmdW5jdGlvbiBBU0FQKCkge1xuICAgIHZhciBxdWV1ZSA9IGFzYXBRdWV1ZS5zcGxpY2UoMCwgYXNhcFF1ZXVlLmxlbmd0aCk7XG4gICAgYXNhcFRpbWVyID0gMDtcbiAgICB3aGlsZSAocXVldWUubGVuZ3RoKSB7XG4gICAgICBxdWV1ZS5zaGlmdCgpLmNhbGwoXG4gICAgICAgIG51bGwsIHF1ZXVlLnNoaWZ0KClcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIFxuICBmdW5jdGlvbiBsb29wQW5kVmVyaWZ5KGxpc3QsIGFjdGlvbikge1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBsaXN0Lmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICB2ZXJpZnlBbmRTZXR1cEFuZEFjdGlvbihsaXN0W2ldLCBhY3Rpb24pO1xuICAgIH1cbiAgfVxuICBcbiAgZnVuY3Rpb24gbG9vcEFuZFNldHVwKGxpc3QpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gbGlzdC5sZW5ndGgsIG5vZGU7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgbm9kZSA9IGxpc3RbaV07XG4gICAgICBwYXRjaChub2RlLCBwcm90b3NbZ2V0VHlwZUluZGV4KG5vZGUpXSk7XG4gICAgfVxuICB9XG4gIFxuICBmdW5jdGlvbiBleGVjdXRlQWN0aW9uKGFjdGlvbikge1xuICAgIHJldHVybiBmdW5jdGlvbiAobm9kZSkge1xuICAgICAgaWYgKGlzVmFsaWROb2RlKG5vZGUpKSB7XG4gICAgICAgIHZlcmlmeUFuZFNldHVwQW5kQWN0aW9uKG5vZGUsIGFjdGlvbik7XG4gICAgICAgIGlmIChxdWVyeS5sZW5ndGgpIGxvb3BBbmRWZXJpZnkoXG4gICAgICAgICAgbm9kZS5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KSxcbiAgICAgICAgICBhY3Rpb25cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG4gIFxuICBmdW5jdGlvbiBnZXRUeXBlSW5kZXgodGFyZ2V0KSB7XG4gICAgdmFyXG4gICAgICBpcyA9IGdldEF0dHJpYnV0ZS5jYWxsKHRhcmdldCwgJ2lzJyksXG4gICAgICBub2RlTmFtZSA9IHRhcmdldC5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpLFxuICAgICAgaSA9IGluZGV4T2YuY2FsbChcbiAgICAgICAgdHlwZXMsXG4gICAgICAgIGlzID9cbiAgICAgICAgICAgIFBSRUZJWF9JUyArIGlzLnRvVXBwZXJDYXNlKCkgOlxuICAgICAgICAgICAgUFJFRklYX1RBRyArIG5vZGVOYW1lXG4gICAgICApXG4gICAgO1xuICAgIHJldHVybiBpcyAmJiAtMSA8IGkgJiYgIWlzSW5RU0Eobm9kZU5hbWUsIGlzKSA/IC0xIDogaTtcbiAgfVxuICBcbiAgZnVuY3Rpb24gaXNJblFTQShuYW1lLCB0eXBlKSB7XG4gICAgcmV0dXJuIC0xIDwgcXVlcnkuaW5kZXhPZihuYW1lICsgJ1tpcz1cIicgKyB0eXBlICsgJ1wiXScpO1xuICB9XG4gIFxuICBmdW5jdGlvbiBvbkRPTUF0dHJNb2RpZmllZChlKSB7XG4gICAgdmFyXG4gICAgICBub2RlID0gZS5jdXJyZW50VGFyZ2V0LFxuICAgICAgYXR0ckNoYW5nZSA9IGUuYXR0ckNoYW5nZSxcbiAgICAgIGF0dHJOYW1lID0gZS5hdHRyTmFtZSxcbiAgICAgIHRhcmdldCA9IGUudGFyZ2V0LFxuICAgICAgYWRkaXRpb24gPSBlW0FERElUSU9OXSB8fCAyLFxuICAgICAgcmVtb3ZhbCA9IGVbUkVNT1ZBTF0gfHwgM1xuICAgIDtcbiAgICBpZiAobm90RnJvbUlubmVySFRNTEhlbHBlciAmJlxuICAgICAgICAoIXRhcmdldCB8fCB0YXJnZXQgPT09IG5vZGUpICYmXG4gICAgICAgIG5vZGVbQVRUUklCVVRFX0NIQU5HRURfQ0FMTEJBQ0tdICYmXG4gICAgICAgIGF0dHJOYW1lICE9PSAnc3R5bGUnICYmIChcbiAgICAgICAgICBlLnByZXZWYWx1ZSAhPT0gZS5uZXdWYWx1ZSB8fFxuICAgICAgICAgIC8vIElFOSwgSUUxMCwgYW5kIE9wZXJhIDEyIGdvdGNoYVxuICAgICAgICAgIGUubmV3VmFsdWUgPT09ICcnICYmIChcbiAgICAgICAgICAgIGF0dHJDaGFuZ2UgPT09IGFkZGl0aW9uIHx8XG4gICAgICAgICAgICBhdHRyQ2hhbmdlID09PSByZW1vdmFsXG4gICAgICAgICAgKVxuICAgICkpIHtcbiAgICAgIG5vZGVbQVRUUklCVVRFX0NIQU5HRURfQ0FMTEJBQ0tdKFxuICAgICAgICBhdHRyTmFtZSxcbiAgICAgICAgYXR0ckNoYW5nZSA9PT0gYWRkaXRpb24gPyBudWxsIDogZS5wcmV2VmFsdWUsXG4gICAgICAgIGF0dHJDaGFuZ2UgPT09IHJlbW92YWwgPyBudWxsIDogZS5uZXdWYWx1ZVxuICAgICAgKTtcbiAgICB9XG4gI
23459H1cbiAgXG4gIGZ1bmN0aW9uIG9uRE9NTm9kZShhY3Rpb24pIHtcbiAgICB2YXIgZXhlY3V0b3IgPSBleGVjdXRlQWN0aW9uKGFjdGlvbik7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChlKSB7XG4gICAgICBhc2FwUXVldWUucHVzaChleGVjdXRvciwgZS50YXJnZXQpO1xuICAgICAgaWYgKGFzYXBUaW1lcikgY2xlYXJUaW1lb3V0KGFzYXBUaW1lcik7XG4gICAgICBhc2FwVGltZXIgPSBzZXRUaW1lb3V0KEFTQVAsIDEpO1xuICAgIH07XG4gIH1cbiAgXG4gIGZ1bmN0aW9uIG9uUmVhZHlTdGF0ZUNoYW5nZShlKSB7XG4gICAgaWYgKGRyb3BEb21Db250ZW50TG9hZGVkKSB7XG4gICAgICBkcm9wRG9tQ29udGVudExvYWRlZCA9IGZhbHNlO1xuICAgICAgZS5jdXJyZW50VGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoRE9NX0NPTlRFTlRfTE9BREVELCBvblJlYWR5U3RhdGVDaGFuZ2UpO1xuICAgIH1cbiAgICBpZiAocXVlcnkubGVuZ3RoKSBsb29wQW5kVmVyaWZ5KFxuICAgICAgKGUudGFyZ2V0IHx8IGRvY3VtZW50KS5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KSxcbiAgICAgIGUuZGV0YWlsID09PSBERVRBQ0hFRCA/IERFVEFDSEVEIDogQVRUQUNIRURcbiAgICApO1xuICAgIGlmIChJRTgpIHB1cmdlKCk7XG4gIH1cbiAgXG4gIGZ1bmN0aW9uIHBhdGNoZWRTZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpIHtcbiAgICAvLyBqc2hpbnQgdmFsaWR0aGlzOnRydWVcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgc2V0QXR0cmlidXRlLmNhbGwoc2VsZiwgbmFtZSwgdmFsdWUpO1xuICAgIG9uU3VidHJlZU1vZGlmaWVkLmNhbGwoc2VsZiwge3RhcmdldDogc2VsZn0pO1xuICB9XG4gIFxuICBmdW5jdGlvbiBzZXR1cEFsbChjb250ZXh0LCBjYWxsYmFjaywgYXJncykge1xuICAgIHZhclxuICAgICAgbm9kZSA9IGNhbGxiYWNrLmFwcGx5KGNvbnRleHQsIGFyZ3MpLFxuICAgICAgaSA9IGdldFR5cGVJbmRleChub2RlKVxuICAgIDtcbiAgICBpZiAoLTEgPCBpKSBwYXRjaChub2RlLCBwcm90b3NbaV0pO1xuICAgIGlmIChhcmdzLnBvcCgpICYmIHF1ZXJ5Lmxlbmd0aClcbiAgICAgIGxvb3BBbmRTZXR1cChub2RlLnF1ZXJ5U2VsZWN0b3JBbGwocXVlcnkpKTtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuICBcbiAgZnVuY3Rpb24gc2V0dXBOb2RlKG5vZGUsIHByb3RvKSB7XG4gICAgc2V0UHJvdG90eXBlKG5vZGUsIHByb3RvKTtcbiAgICBpZiAob2JzZXJ2ZXIpIHtcbiAgICAgIG9ic2VydmVyLm9ic2VydmUobm9kZSwgYXR0cmlidXRlc09ic2VydmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGRvZXNOb3RTdXBwb3J0RE9NQXR0ck1vZGlmaWVkKSB7XG4gICAgICAgIG5vZGUuc2V0QXR0cmlidXRlID0gcGF0Y2hlZFNldEF0dHJpYnV0ZTtcbiAgICAgICAgbm9kZVtFWFBBTkRPX1VJRF0gPSBnZXRBdHRyaWJ1dGVzTWlycm9yKG5vZGUpO1xuICAgICAgICBub2RlW0FERF9FVkVOVF9MSVNURU5FUl0oRE9NX1NVQlRSRUVfTU9ESUZJRUQsIG9uU3VidHJlZU1vZGlmaWVkKTtcbiAgICAgIH1cbiAgICAgIG5vZGVbQUREX0VWRU5UX0xJU1RFTkVSXShET01fQVRUUl9NT0RJRklFRCwgb25ET01BdHRyTW9kaWZpZWQpO1xuICAgIH1cbiAgICBpZiAobm9kZVtDUkVBVEVEX0NBTExCQUNLXSAmJiBub3RGcm9tSW5uZXJIVE1MSGVscGVyKSB7XG4gICAgICBub2RlLmNyZWF0ZWQgPSB0cnVlO1xuICAgICAgbm9kZVtDUkVBVEVEX0NBTExCQUNLXSgpO1xuICAgICAgbm9kZS5jcmVhdGVkID0gZmFsc2U7XG4gICAgfVxuICB9XG4gIFxuICBmdW5jdGlvbiBwdXJnZSgpIHtcbiAgICBmb3IgKHZhclxuICAgICAgbm9kZSxcbiAgICAgIGkgPSAwLFxuICAgICAgbGVuZ3RoID0gdGFyZ2V0cy5sZW5ndGg7XG4gICAgICBpIDwgbGVuZ3RoOyBpKytcbiAgICApIHtcbiAgICAgIG5vZGUgPSB0YXJnZXRzW2ldO1xuICAgICAgaWYgKCFkb2N1bWVudEVsZW1lbnQuY29udGFpbnMobm9kZSkpIHtcbiAgICAgICAgbGVuZ3RoLS07XG4gICAgICAgIHRhcmdldHMuc3BsaWNlKGktLSwgMSk7XG4gICAgICAgIHZlcmlmeUFuZFNldHVwQW5kQWN0aW9uKG5vZGUsIERFVEFDSEVEKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgXG4gIGZ1bmN0aW9uIHRocm93VHlwZUVycm9yKHR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgJyArIHR5cGUgKyAnIHR5cGUgaXMgYWxyZWFkeSByZWdpc3RlcmVkJyk7XG4gIH1cbiAgXG4gIGZ1bmN0aW9uIHZlcmlmeUFuZFNldHVwQW5kQWN0aW9uKG5vZGUsIGFjdGlvbikge1xuICAgIHZhclxuICAgICAgZm4sXG4gICAgICBpID0gZ2V0VHlwZUluZGV4KG5vZGUpLFxuICAgICAgY291bnRlckFjdGlvblxuICAgIDtcbiAgICBpZiAoKC0xIDwgaSkgJiYgIWNsb3Nlc3QuY2FsbChub2RlLCAnVEVNUExBVEUnKSkge1xuICAgICAgcGF0Y2hJZk5vdEFscmVhZHkobm9kZSwgcHJvdG9zW2ldKTtcbiAgICAgIGkgPSAwO1xuICAgICAgaWYgKGFjdGlvbiA9PT0gQVRUQUNIRUQgJiYgIW5vZGVbQVRUQUNIRURdKSB7XG4gICAgICAgIG5vZGVbREVUQUNIRURdID0gZmFsc2U7XG4gICAgICAgIG5vZGVbQVRUQUNIRURdID0gdHJ1ZTtcbiAgICAgICAgY291bnRlckFjdGlvbiA9ICdjb25uZWN0ZWQnO1xuICAgICAgICBpID0gMTtcbiAgICAgICAgaWYgKElFOCAmJiBpbmRleE9mLmNhbGwodGFyZ2V0cywgbm9kZSkgPCAwKSB7XG4gICAgICAgICAgdGFyZ2V0cy5wdXNoKG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PT0gREVUQUNIRUQgJiYgIW5vZGVbREVUQUNIRURdKSB7XG4gICAgICAgIG5vZGVbQVRUQUNIRURdID0gZmFsc2U7XG4gICAgICAgIG5vZGVbREVUQUNIRURdID0gdHJ1ZTtcbiAgICAgICAgY291bnRlckFjdGlvbiA9ICdkaXNjb25uZWN0ZWQnO1xuICAgICAgICBpID0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChpICYmIChmbiA9IChcbiAgICAgICAgbm9kZVthY3Rpb24gKyBDQUxMQkFDS10gfHxcbiAgICAgICAgbm9kZVtjb3VudGVyQWN0aW9uICsgQ0FMTEJBQ0tdXG4gICAgICApKSkgZm4uY2FsbChub2RlKTtcbiAgICB9XG4gIH1cbiAgXG4gIC8vIFYxIGluIGRhIEhvdXNlIVxuICBmdW5jdGlvbiBDdXN0b21FbGVtZW50UmVnaXN0cnkoKSB7fVxuICBcbiAgQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZSA9IHtcbiAgICBjb25zdHJ1Y3RvcjogQ3VzdG9tRWxlbWVudFJlZ2lzdHJ5LFxuICAgIC8vIGEgd29ya2Fyb3VuZCBmb3IgdGhlIHN0dWJib3JuIFdlYktpdFxuICAgIGRlZmluZTogdXNhYmxlQ3VzdG9tRWxlbWVudHMgP1xuICAgICAgZnVuY3Rpb24gKG5hbWUsIENsYXNzLCBvcHRpb25zKSB7XG4gICAgICAgIGlmIChvcHRpb25zKSB7XG4gICAgICAgICAgQ0VSRGVmaW5lKG5hbWUsIENsYXNzLCBvcHRpb25zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2Y
23459XIgTkFNRSA9IG5hbWUudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICBjb25zdHJ1Y3RvcnNbTkFNRV0gPSB7XG4gICAgICAgICAgICBjb25zdHJ1Y3RvcjogQ2xhc3MsXG4gICAgICAgICAgICBjcmVhdGU6IFtOQU1FXVxuICAgICAgICAgIH07XG4gICAgICAgICAgbm9kZU5hbWVzLnNldChDbGFzcywgTkFNRSk7XG4gICAgICAgICAgY3VzdG9tRWxlbWVudHMuZGVmaW5lKG5hbWUsIENsYXNzKTtcbiAgICAgICAgfVxuICAgICAgfSA6XG4gICAgICBDRVJEZWZpbmUsXG4gICAgZ2V0OiB1c2FibGVDdXN0b21FbGVtZW50cyA/XG4gICAgICBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gY3VzdG9tRWxlbWVudHMuZ2V0KG5hbWUpIHx8IGdldChuYW1lKTtcbiAgICAgIH0gOlxuICAgICAgZ2V0LFxuICAgIHdoZW5EZWZpbmVkOiB1c2FibGVDdXN0b21FbGVtZW50cyA/XG4gICAgICBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yYWNlKFtcbiAgICAgICAgICBjdXN0b21FbGVtZW50cy53aGVuRGVmaW5lZChuYW1lKSxcbiAgICAgICAgICB3aGVuRGVmaW5lZChuYW1lKVxuICAgICAgICBdKTtcbiAgICAgIH0gOlxuICAgICAgd2hlbkRlZmluZWRcbiAgfTtcbiAgXG4gIGZ1bmN0aW9uIENFUkRlZmluZShuYW1lLCBDbGFzcywgb3B0aW9ucykge1xuICAgIHZhclxuICAgICAgaXMgPSBvcHRpb25zICYmIG9wdGlvbnNbRVhURU5EU10gfHwgJycsXG4gICAgICBDUHJvdG8gPSBDbGFzcy5wcm90b3R5cGUsXG4gICAgICBwcm90byA9IGNyZWF0ZShDUHJvdG8pLFxuICAgICAgYXR0cmlidXRlcyA9IENsYXNzLm9ic2VydmVkQXR0cmlidXRlcyB8fCBlbXB0eSxcbiAgICAgIGRlZmluaXRpb24gPSB7cHJvdG90eXBlOiBwcm90b31cbiAgICA7XG4gICAgLy8gVE9ETzogaXMgdGhpcyBuZWVkZWQgYXQgYWxsIHNpbmNlIGl0J3MgaW5oZXJpdGVkP1xuICAgIC8vIGRlZmluZVByb3BlcnR5KHByb3RvLCAnY29uc3RydWN0b3InLCB7dmFsdWU6IENsYXNzfSk7XG4gICAgc2FmZVByb3BlcnR5KHByb3RvLCBDUkVBVEVEX0NBTExCQUNLLCB7XG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKGp1c3RDcmVhdGVkKSBqdXN0Q3JlYXRlZCA9IGZhbHNlO1xuICAgICAgICAgIGVsc2UgaWYgKCF0aGlzW0RSRUNFVjFdKSB7XG4gICAgICAgICAgICB0aGlzW0RSRUNFVjFdID0gdHJ1ZTtcbiAgICAgICAgICAgIG5ldyBDbGFzcyh0aGlzKTtcbiAgICAgICAgICAgIGlmIChDUHJvdG9bQ1JFQVRFRF9DQUxMQkFDS10pXG4gICAgICAgICAgICAgIENQcm90b1tDUkVBVEVEX0NBTExCQUNLXS5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgdmFyIGluZm8gPSBjb25zdHJ1Y3RvcnNbbm9kZU5hbWVzLmdldChDbGFzcyldO1xuICAgICAgICAgICAgaWYgKCF1c2FibGVDdXN0b21FbGVtZW50cyB8fCBpbmZvLmNyZWF0ZS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgIG5vdGlmeUF0dHJpYnV0ZXModGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHNhZmVQcm9wZXJ0eShwcm90bywgQVRUUklCVVRFX0NIQU5HRURfQ0FMTEJBQ0ssIHtcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICBpZiAoLTEgPCBpbmRleE9mLmNhbGwoYXR0cmlidXRlcywgbmFtZSkpIHtcbiAgICAgICAgICBpZiAoQ1Byb3RvW0FUVFJJQlVURV9DSEFOR0VEX0NBTExCQUNLXSlcbiAgICAgICAgICAgIENQcm90b1tBVFRSSUJVVEVfQ0hBTkdFRF9DQUxMQkFDS10uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChDUHJvdG9bQ09OTkVDVEVEX0NBTExCQUNLXSkge1xuICAgICAgc2FmZVByb3BlcnR5KHByb3RvLCBBVFRBQ0hFRF9DQUxMQkFDSywge1xuICAgICAgICB2YWx1ZTogQ1Byb3RvW0NPTk5FQ1RFRF9DQUxMQkFDS11cbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoQ1Byb3RvW0RJU0NPTk5FQ1RFRF9DQUxMQkFDS10pIHtcbiAgICAgIHNhZmVQcm9wZXJ0eShwcm90bywgREVUQUNIRURfQ0FMTEJBQ0ssIHtcbiAgICAgICAgdmFsdWU6IENQcm90b1tESVNDT05ORUNURURfQ0FMTEJBQ0tdXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKGlzKSBkZWZpbml0aW9uW0VYVEVORFNdID0gaXM7XG4gICAgbmFtZSA9IG5hbWUudG9VcHBlckNhc2UoKTtcbiAgICBjb25zdHJ1Y3RvcnNbbmFtZV0gPSB7XG4gICAgICBjb25zdHJ1Y3RvcjogQ2xhc3MsXG4gICAgICBjcmVhdGU6IGlzID8gW2lzLCBzZWNvbmRBcmd1bWVudChuYW1lKV0gOiBbbmFtZV1cbiAgICB9O1xuICAgIG5vZGVOYW1lcy5zZXQoQ2xhc3MsIG5hbWUpO1xuICAgIGRvY3VtZW50W1JFR0lTVEVSX0VMRU1FTlRdKG5hbWUudG9Mb3dlckNhc2UoKSwgZGVmaW5pdGlvbik7XG4gICAgd2hlbkRlZmluZWQobmFtZSk7XG4gICAgd2FpdGluZ0xpc3RbbmFtZV0ucigpO1xuICB9XG4gIFxuICBmdW5jdGlvbiBnZXQobmFtZSkge1xuICAgIHZhciBpbmZvID0gY29uc3RydWN0b3JzW25hbWUudG9VcHBlckNhc2UoKV07XG4gICAgcmV0dXJuIGluZm8gJiYgaW5mby5jb25zdHJ1Y3RvcjtcbiAgfVxuICBcbiAgZnVuY3Rpb24gZ2V0SXMob3B0aW9ucykge1xuICAgIHJldHVybiB0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycgP1xuICAgICAgICBvcHRpb25zIDogKG9wdGlvbnMgJiYgb3B0aW9ucy5pcyB8fCAnJyk7XG4gIH1cbiAgXG4gIGZ1bmN0aW9uIG5vdGlmeUF0dHJpYnV0ZXMoc2VsZikge1xuICAgIHZhclxuICAgICAgY2FsbGJhY2sgPSBzZWxmW0FUVFJJQlVURV9DSEFOR0VEX0NBTExCQUNLXSxcbiAgICAgIGF0dHJpYnV0ZXMgPSBjYWxsYmFjayA/IHNlbGYuYXR0cmlidXRlcyA6IGVtcHR5LFxuICAgICAgaSA9IGF0dHJpYnV0ZXMubGVuZ3RoLFxuICAgICAgYXR0cmlidXRlXG4gICAgO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGF0dHJpYnV0ZSA9ICBhdHRyaWJ1dGVzW2ldOyAvLyB8fCBhdHRyaWJ1dGVzLml0ZW0oaSk7XG4gICAgICBjYWxsYmFjay5jYWxsKFxuICAgICAgICBzZWxmLFxuICAgICAgICBhdHRyaWJ1dGUubmFtZSB8fCBhdHRyaWJ1dGUubm9kZU5hbWUsXG4gICAgICAgIG51bGwsXG4gICAgICAgIGF0dHJpYnV0ZS52YWx1ZSB8fCBhdHRyaWJ1dGUubm9kZVZhbHVlXG4gICAgICApO1xuICAgIH1cbiAgfVxuICBcbiAgZnVuY3Rpb24gd2hlbkRlZmluZWQobmFtZSkge1xuICAgIG5hbWUgPSBuYW1lLnRvVXBwZXJDYXNlKCk7XG4gICAgaWYgKCEobmFtZSBpbiB3YWl0aW5nTGlzdCkpIHtcbiAgICAgIHdhaXRpbmdMaXN0W25hbWVdID0ge307XG4gICAgICB3YWl0aW5nTGlzdFtuYW1lXS5wID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgd2FpdGluZ0xpc3RbbmFtZV0uciA9IHJlc29sdmU7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHdhaXRpbmdMaXN0W25hbWVdLnA7XG4gIH1cbiAgXG4gIGZ1bmN0aW9uIHBvbHlmaWxsVjEoKSB7XG4gICAgaWYgKGN1c3RvbUVsZW1lbnRzKSBkZWxldGUgd2luZG93LmN1c3RvbUVsZW1lbnRzO1xuICAgIGRlZmluZVByb3BlcnR5KHdpbmRvdywgJ2N1c3RvbUVsZW1lbnRzJywge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgdmFsdWU6IG5ldyBDdXN0b21FbGVtZW50UmVnaXN0cnkoKVxuICAgIH0pO1xuICAgIGRlZmluZVByb3BlcnR5KHdpbmRvdywgJ0N1c3RvbUVsZW1lbnRSZWdpc3RyeScsIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHZhbHVlOiBDdXN0b21FbGVtZW50UmVnaXN0cnlcbiAgICB9KTtcbiAgICBmb3IgKHZhclxuICAgICAgcGF0Y2hDbGFzcyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgI
23459HZhciBDbGFzcyA9IHdpbmRvd1tuYW1lXTtcbiAgICAgICAgaWYgKENsYXNzKSB7XG4gICAgICAgICAgd2luZG93W25hbWVdID0gZnVuY3Rpb24gQ3VzdG9tRWxlbWVudHNWMShzZWxmKSB7XG4gICAgICAgICAgICB2YXIgaW5mbywgaXNOYXRpdmU7XG4gICAgICAgICAgICBpZiAoIXNlbGYpIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgaWYgKCFzZWxmW0RSRUNFVjFdKSB7XG4gICAgICAgICAgICAgIGp1c3RDcmVhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgaW5mbyA9IGNvbnN0cnVjdG9yc1tub2RlTmFtZXMuZ2V0KHNlbGYuY29uc3RydWN0b3IpXTtcbiAgICAgICAgICAgICAgaXNOYXRpdmUgPSB1c2FibGVDdXN0b21FbGVtZW50cyAmJiBpbmZvLmNyZWF0ZS5sZW5ndGggPT09IDE7XG4gICAgICAgICAgICAgIHNlbGYgPSBpc05hdGl2ZSA/XG4gICAgICAgICAgICAgICAgUmVmbGVjdC5jb25zdHJ1Y3QoQ2xhc3MsIGVtcHR5LCBpbmZvLmNvbnN0cnVjdG9yKSA6XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuY3JlYXRlRWxlbWVudC5hcHBseShkb2N1bWVudCwgaW5mby5jcmVhdGUpO1xuICAgICAgICAgICAgICBzZWxmW0RSRUNFVjFdID0gdHJ1ZTtcbiAgICAgICAgICAgICAganVzdENyZWF0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgaWYgKCFpc05hdGl2ZSkgbm90aWZ5QXR0cmlidXRlcyhzZWxmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzZWxmO1xuICAgICAgICAgIH07XG4gICAgICAgICAgd2luZG93W25hbWVdLnByb3RvdHlwZSA9IENsYXNzLnByb3RvdHlwZTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgQ2xhc3MucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gd2luZG93W25hbWVdO1xuICAgICAgICAgIH0gY2F0Y2goV2ViS2l0KSB7XG4gICAgICAgICAgICBmaXhHZXRDbGFzcyA9IHRydWU7XG4gICAgICAgICAgICBkZWZpbmVQcm9wZXJ0eShDbGFzcywgRFJFQ0VWMSwge3ZhbHVlOiB3aW5kb3dbbmFtZV19KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBDbGFzc2VzID0gaHRtbENsYXNzLmdldCgvXkhUTUxbQS1aXSpbYS16XS8pLFxuICAgICAgaSA9IENsYXNzZXMubGVuZ3RoO1xuICAgICAgaS0tO1xuICAgICAgcGF0Y2hDbGFzcyhDbGFzc2VzW2ldKVxuICAgICkge31cbiAgICAoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCA9IGZ1bmN0aW9uIChuYW1lLCBvcHRpb25zKSB7XG4gICAgICB2Y
23459XIgaXMgPSBnZXRJcyhvcHRpb25zKTtcbiAgICAgIHJldHVybiBpcyA/XG4gICAgICAgIHBhdGNoZWRDcmVhdGVFbGVtZW50LmNhbGwodGhpcywgbmFtZSwgc2Vjb25kQXJndW1lbnQoaXMpKSA6XG4gICAgICAgIHBhdGNoZWRDcmVhdGVFbGVtZW50LmNhbGwodGhpcywgbmFtZSk7XG4gICAgfSk7XG4gICAgaWYgKCFWMCkge1xuICAgICAganVzdFNldHVwID0gdHJ1ZTtcbiAgICAgIGRvY3VtZW50W1JFR0lTVEVSX0VMRU1FTlRdKCcnKTtcbiAgICB9XG4gIH1cbiAgXG4gIC8vIGlmIGN1c3RvbUVsZW1lbnRzIGlzIG5vdCB0aGVyZSBhdCBhbGxcbiAgaWYgKCFjdXN0b21FbGVtZW50cyB8fCAvXmZvcmNlLy50ZXN0KHBvbHlmaWxsLnR5cGUpKSBwb2x5ZmlsbFYxKCk7XG4gIGVsc2UgaWYoIXBvbHlmaWxsLm5vQnVpbHRJbikge1xuICAgIC8vIGlmIGF2YWlsYWJsZSB0ZXN0IGV4dGVuZHMgd29yayBhcyBleHBlY3RlZFxuICAgIHRyeSB7XG4gICAgICAoZnVuY3Rpb24gKERSRSwgb3B0aW9ucywgbmFtZSkge1xuICAgICAgICB2YXIgcmUgPSBuZXcgUmVnRXhwKCdePGFcXFxccytpcz0oXFwnfFwiKScgKyBuYW1lICsgJ1xcXFwxPjwvYT4kJyk7XG4gICAgICAgIG9wdGlvbnNbRVhURU5EU10gPSAnYSc7XG4gICAgICAgIERSRS5wcm90b3R5cGUgPSBjcmVhdGUoSFRNTEFuY2hvckVsZW1lbnQucHJvdG90eXBlKTtcbiAgICAgICAgRFJFLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IERSRTtcbiAgICAgICAgd2luZG93LmN1c3RvbUVsZW1lbnRzLmRlZmluZShuYW1lLCBEUkUsIG9wdGlvbnMpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIXJlLnRlc3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScsIHtpczogbmFtZX0pLm91dGVySFRNTCkgfHxcbiAgICAgICAgICAhcmUudGVzdCgobmV3IERSRSgpKS5vdXRlckhUTUwpXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IG9wdGlvbnM7XG4gICAgICAgIH1cbiAgICAgIH0oXG4gICAgICAgIGZ1bmN0aW9uIERSRSgpIHtcbiAgICAgICAgICByZXR1cm4gUmVmbGVjdC5jb25zdHJ1Y3QoSFRNTEFuY2hvckVsZW1lbnQsIFtdLCBEUkUpO1xuICAgICAgICB9LFxuICAgICAgICB7fSxcbiAgICAgICAgJ2RvY3VtZW50LXJlZ2lzdGVyLWVsZW1lbnQtYScgKyBVSURcbiAgICAgICkpO1xuICAgIH0gY2F0Y2gob19PKSB7XG4gICAgICAvLyBvciBmb3JjZSB0aGUgcG9seWZpbGwgaWYgbm90XG4gICAgICAvLyBhbmQga2VlcCBpbnRlcm5hbCBvcmlnaW5hbCByZWZlcmVuY2VcbiAgICAgIHBvbHlmaWxsVjEoKTtcbiAgICB9XG4gIH1cbiAgXG4gIC8vIEZpcmVGb3ggb25seSBpc3N1ZVxuICBpZighcG9seWZpbGwubm9CdWlsdEluKSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChjcmVhdGVFbGVtZW50LmNhbGwoZG9jdW1lbnQsICdhJywgJ2EnKS5vdXRlckhUTUwuaW5kZXhPZignaXMnKSA8IDApXG4gICAgICAgIHRocm93IHt9O1xuICAgIH0gY2F0Y2goRmlyZUZveCkge1xuICAgICAgc2Vjb25kQXJndW1lbnQgPSBmdW5jdGlvbiAoaXMpIHtcbiAgICAgICAgcmV0dXJuIHtpczogaXMudG9Mb3dlckNhc2UoKX07XG4gICAgICB9O1xuICAgIH1cbiAgfVxuICBcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbnN0YWxsQ3VzdG9tRWxlbWVudHM7XG5pbnN0YWxsQ3VzdG9tRWxlbWVudHMoZ2xvYmFsKTtcbiIsInZhciB3aW47XG5cbmlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgd2luID0gd2luZG93O1xufSBlbHNlIGlmICh0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgd2luID0gZ2xvYmFsO1xufSBlbHNlIGlmICh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIil7XG4gICAgd2luID0gc2VsZjtcbn0gZWxzZSB7XG4gICAgd2luID0ge307XG59XG5cbm1vZHVsZS5leHBvcnRzID0gd2luO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcblx0dHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOlxuXHR0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOlxuXHQoZ2xvYmFsLkdsc2xDYW52YXMgPSBmYWN0b3J5KCkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7XG5cbnZhciBjb21tb25qc0dsb2JhbCA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgPyBzZWxmIDoge307XG5cbnZhciB3aW47XG5cbmlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgd2luID0gd2luZG93O1xufSBlbHNlIGlmICh0eXBlb2YgY29tbW9uanNHbG9iYWwgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICB3aW4gPSBjb21tb25qc0dsb2JhbDtcbn0gZWxzZSBpZiAodHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIpe1xuICAgIHdpbiA9IHNlbGY7XG59IGVsc2Uge1xuICAgIHdpbiA9IHt9O1xufVxuXG52YXIgd2luZG93XzEgPSB3aW47XG5cbnZhciBpc0Z1bmN0aW9uXzEgPSBpc0Z1bmN0aW9uO1xuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uIChmbikge1xuICBpZiAoIWZuKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgdmFyIHN0cmluZyA9IHRvU3RyaW5nLmNhbGwoZm4pO1xuICByZXR1cm4gc3RyaW5nID09PSAnW29iamVjdCBGdW5jdGlvbl0nIHx8XG4gICAgKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJyAmJiBzdHJpbmcgIT09ICdbb2JqZWN0IFJlZ0V4cF0nKSB8fFxuICAgICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAvLyBJRTggYW5kIGJlbG93XG4gICAgIChmbiA9PT0gd2luZG93LnNldFRpbWVvdXQgfHxcbiAgICAgIGZuID09PSB3aW5kb3cuYWxlcnQgfHxcbiAgICAgIGZuID09PSB3aW5kb3cuY29uZmlybSB8fFxuICAgICAgZm4gPT09IHdpbmRvdy5wcm9tcHQpKVxufVxuXG52YXIgdHJpbSA9IGZ1bmN0aW9uKHN0cmluZykge1xuICByZXR1cm4gc3RyaW5nLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcbn07XG52YXIgaXNBcnJheSA9IGZ1bmN0aW9uKGFyZykge1xuICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH07XG5cbnZhciBwYXJzZUhlYWRlcnMgPSBmdW5jdGlvbiAoaGVhZGVycykge1xuICBpZiAoIWhlYWRlcnMpXG4gICAgcmV0dXJuIHt9XG5cbiAgdmFyIHJlc3VsdCA9IHt9O1xuXG4gIHZhciBoZWFkZXJzQXJyID0gdHJpbShoZWFkZXJzKS5zcGxpdCgnXFxuJyk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZWFkZXJzQXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHJvdyA9IGhlYWRlcnNBcnJbaV07XG4gICAgdmFyIGluZGV4ID0gcm93LmluZGV4T2YoJzonKVxuICAgICwga2V5ID0gdHJpbShyb3cuc2xpY2UoMCwgaW5kZXgpKS50b0xvd2VyQ2FzZSgpXG4gICAgLCB2YWx1ZSA9IHRyaW0ocm93LnNsaWNlKGluZGV4ICsgMSkpO1xuXG4gICAgaWYgKHR5cGVvZihyZXN1bHRba2V5XSkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXN1bHRba2V5XSA9IHZhbHVlO1xuICAgIH0gZWxzZSBpZiAoaXNBcnJheShyZXN1bHRba2V5XSkpIHtcbiAgICAgIHJlc3VsdFtrZXldLnB1c2godmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHRba2V5XSA9IFsgcmVzdWx0W2tleV0sIHZhbHVlIF07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdFxufTtcblxudmFyIGltbXV0YWJsZSA9IGV4dGVuZDtcblxudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuZnVuY3Rpb24gZXh0ZW5kKCkge1xuICAgIHZhciB0YXJnZXQgPSB7fTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgI
23459HZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07XG5cbiAgICAgICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0YXJnZXRcbn1cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cblxuXG5cblxudmFyIHhociA9IGNyZWF0ZVhIUjtcbi8vIEFsbG93IHVzZSBvZiBkZWZhdWx0IGltcG9ydCBzeW50YXggaW4gVHlwZVNjcmlwdFxudmFyIGRlZmF1bHRfMSA9IGNyZWF0ZVhIUjtcbmNyZWF0ZVhIUi5YTUxIdHRwUmVxdWVzdCA9IHdpbmRvd18xLlhNTEh0dHBSZXF1ZXN0IHx8IG5vb3A7XG5jcmVhdGVYSFIuWERvbWFpblJlcXVlc3QgPSBcIndpdGhDcmVkZW50aWFsc1wiIGluIChuZXcgY3JlYXRlWEhSLlhNTEh0dHBSZXF1ZXN0KCkpID8gY3JlYXRlWEhSLlhNTEh0dHBSZXF1ZXN0IDogd2luZG93XzEuWERvbWFpblJlcXVlc3Q7XG5cbmZvckVhY2hBcnJheShbXCJnZXRcIiwgXCJwdXRcIiwgXCJwb3N0XCIsIFwicGF0Y2hcIiwgXCJoZWFkXCIsIFwiZGVsZXRlXCJdLCBmdW5jdGlvbihtZXRob2QpIHtcbiAgICBjcmVhdGVYSFJbbWV0aG9kID09PSBcImRlbGV0ZVwiID8gXCJkZWxcIiA6IG1ldGhvZF0gPSBmdW5jdGlvbih1cmksIG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICAgIG9wdGlvbnMgPSBpbml0UGFyYW1zKHVyaSwgb3B0aW9ucywgY2FsbGJhY2spO1xuICAgICAgICBvcHRpb25zLm1ldGhvZCA9IG1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuICAgICAgICByZXR1cm4gX2NyZWF0ZVhIUihvcHRpb25zKVxuICAgIH07XG59KTtcblxuZnVuY3Rpb24gZm9yRWFjaEFycmF5KGFycmF5LCBpdGVyYXRvcikge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaXRlcmF0b3IoYXJyYXlbaV0pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gaXNFbXB0eShvYmope1xuICAgIGZvcih2YXIgaSBpbiBvYmope1xuICAgICAgICBpZihvYmouaGFzT3duUHJvcGVydHkoaSkpIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZVxufVxuXG5mdW5jdGlvbiBpbml0UGFyYW1zKHVyaSwgb3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICB2YXIgcGFyYW1zID0gdXJpO1xuXG4gICAgaWYgKGlzRnVuY3Rpb25fMShvcHRpb25zKSkge1xuICAgICAgICBjYWxsYmFjayA9IG9wdGlvbnM7XG4gICAgICAgIGlmICh0eXBlb2YgdXJpID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBwYXJhbXMgPSB7dXJpOnVyaX07XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXJhbXMgPSBpbW11dGFibGUob3B0aW9ucywge3VyaTogdXJpfSk7XG4gICAgfVxuXG4gICAgcGFyYW1zLmNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgcmV0dXJuIHBhcmFtc1xufVxuXG5mdW5jdGlvbiBjcmVhdGVYSFIodXJpLCBvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIG9wdGlvbnMgPSBpbml0UGFyYW1zKHVyaSwgb3B0aW9ucywgY2FsbGJhY2spO1xuICAgIHJldHVybiBfY3JlYXRlWEhSKG9wdGlvbnMpXG59XG5cbmZ1bmN0aW9uIF9jcmVhdGVYSFIob3B0aW9ucykge1xuICAgIGlmKHR5cGVvZiBvcHRpb25zLmNhbGxiYWNrID09PSBcInVuZGVmaW5lZFwiKXtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2FsbGJhY2sgYXJndW1lbnQgbWlzc2luZ1wiKVxuICAgIH1cblxuICAgIHZhciBjYWxsZWQgPSBmYWxzZTtcbiAgICB2YXIgY2FsbGJhY2sgPSBmdW5jdGlvbiBjYk9uY2UoZXJyLCByZXNwb25zZSwgYm9keSl7XG4gICAgICAgIGlmKCFjYWxsZWQpe1xuICAgICAgICAgICAgY2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIG9wdGlvbnMuY2FsbGJhY2soZXJyLCByZXNwb25zZSwgYm9keSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcmVhZHlzdGF0ZWNoYW5nZSgpIHtcbiAgICAgICAgaWYgKHhoci5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KGxvYWRGdW5jLCAwKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldEJvZHkoKSB7XG4gICAgICAgIC8vIENocm9tZSB3aXRoIHJlcXVlc3RUeXBlPWJsb2IgdGhyb3dzIGVycm9ycyBhcnJvdW5kIHdoZW4gZXZlbiB0ZXN0aW5nIGFjY2VzcyB0byByZXNwb25zZVRleHRcbiAgICAgICAgdmFyIGJvZHkgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKHhoci5yZXNwb25zZSkge1xuICAgICAgICAgICAgYm9keSA9IHhoci5yZXNwb25zZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJvZHkgPSB4aHIucmVzcG9uc2VUZXh0IHx8IGdldFhtbCh4aHIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzSnNvbikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBib2R5ID0gSlNPTi5wYXJzZShib2R5KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYm9keVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGVycm9yRnVuYyhldnQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRUaW1lcik7XG4gICAgICAgIGlmKCEoZXZ0IGluc3RhbmNlb2YgRXJyb3IpKXtcbiAgICAgICAgICAgIGV2dCA9IG5ldyBFcnJvcihcIlwiICsgKGV2dCB8fCBcIlVua25vd24gWE1MSHR0cFJlcXVlc3QgRXJyb3JcIikgKTtcbiAgICAgICAgfVxuICAgICAgICBldnQuc3RhdHVzQ29kZSA9IDA7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhldnQsIGZhaWx1cmVSZXNwb25zZSlcbiAgICB9XG5cbiAgICAvLyB3aWxsIGxvYWQgdGhlIGRhdGEgJiBwcm9jZXNzIHRoZSByZXNwb25zZSBpbiBhIHNwZWNpYWwgcmVzcG9uc2Ugb2JqZWN0XG4gICAgZnVuY3Rpb24gbG9hZEZ1bmMoKSB7XG4gICAgICAgIGlmIChhYm9ydGVkKSByZXR1cm5cbiAgICAgICAgdmFyIHN0YXR1cztcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRUaW1lcik7XG4gICAgICAgIGlmKG9wdGlvbnMudXNlWERSICYmIHhoci5zdGF0dXM9PT11bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vSUU4IENPUlMgR0VUIHN1Y2Nlc3NmdWwgcmVzcG9uc2UgZG9lc24ndCBoYXZlIGEgc3RhdHVzIGZpZWxkLCBidXQgYm9keSBpcyBmaW5lXG4gICAgICAgICAgICBzdGF0dXMgPSAyMDA7XG4gICAgICAgI
23459H0gZWxzZSB7XG4gICAgICAgICAgICBzdGF0dXMgPSAoeGhyLnN0YXR1cyA9PT0gMTIyMyA/IDIwNCA6IHhoci5zdGF0dXMpO1xuICAgICAgICB9XG4gICAgICAgIHZhciByZXNwb25zZSA9IGZhaWx1cmVSZXNwb25zZTtcbiAgICAgICAgdmFyIGVyciA9IG51bGw7XG5cbiAgICAgICAgaWYgKHN0YXR1cyAhPT0gMCl7XG4gICAgICAgICAgICByZXNwb25zZSA9IHtcbiAgICAgICAgICAgICAgICBib2R5OiBnZXRCb2R5KCksXG4gICAgICAgICAgICAgICAgc3RhdHVzQ29kZTogc3RhdHVzLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgICAgICAgICAgIHVybDogdXJpLFxuICAgICAgICAgICAgICAgIHJhd1JlcXVlc3Q6IHhoclxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMpeyAvL3JlbWVtYmVyIHhociBjYW4gaW4gZmFjdCBiZSBYRFIgZm9yIENPUlMgaW4gSUVcbiAgICAgICAgICAgICAgICByZXNwb25zZS5oZWFkZXJzID0gcGFyc2VIZWFkZXJzKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlcnIgPSBuZXcgRXJyb3IoXCJJbnRlcm5hbCBYTUxIdHRwUmVxdWVzdCBFcnJvclwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCByZXNwb25zZSwgcmVzcG9uc2UuYm9keSlcbiAgICB9XG5cbiAgICB2YXIgeGhyID0gb3B0aW9ucy54aHIgfHwgbnVsbDtcblxuICAgIGlmICgheGhyKSB7XG4gICAgICAgIGlmIChvcHRpb25zLmNvcnMgfHwgb3B0aW9ucy51c2VYRFIpIHtcbiAgICAgICAgICAgIHhociA9IG5ldyBjcmVhdGVYSFIuWERvbWFpblJlcXVlc3QoKTtcbiAgICAgICAgfWVsc2V7XG4gICAgICAgICAgICB4aHIgPSBuZXcgY3JlYXRlWEhSLlhNTEh0dHBSZXF1
23459ZXN0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIga2V5O1xuICAgIHZhciBhYm9ydGVkO1xuICAgIHZhciB1cmkgPSB4aHIudXJsID0gb3B0aW9ucy51cmkgfHwgb3B0aW9ucy51cmw7XG4gICAgdmFyIG1ldGhvZCA9IHhoci5tZXRob2QgPSBvcHRpb25zLm1ldGhvZCB8fCBcIkdFVFwiO1xuICAgIHZhciBib2R5ID0gb3B0aW9ucy5ib2R5IHx8IG9wdGlvbnMuZGF0YTtcbiAgICB2YXIgaGVhZGVycyA9IHhoci5oZWFkZXJzID0gb3B0aW9ucy5oZWFkZXJzIHx8IHt9O1xuICAgIHZhciBzeW5jID0gISFvcHRpb25zLnN5bmM7XG4gICAgdmFyIGlzSnNvbiA9IGZhbHNlO1xuICAgIHZhciB0aW1lb3V0VGltZXI7XG4gICAgdmFyIGZhaWx1cmVSZXNwb25zZSA9IHtcbiAgICAgICAgYm9keTogdW5kZWZpbmVkLFxuICAgICAgICBoZWFkZXJzOiB7fSxcbiAgICAgICAgc3RhdHVzQ29kZTogMCxcbiAgICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICAgIHVybDogdXJpLFxuICAgICAgICByYXdSZXF1ZXN0OiB4aHJcbiAgICB9O1xuXG4gICAgaWYgKFwianNvblwiIGluIG9wdGlvbnMgJiYgb3B0aW9ucy5qc29uICE9PSBmYWxzZSkge1xuICAgICAgICBpc0pzb24gPSB0cnVlO1xuICAgICAgICBoZWFkZXJzW1wiYWNjZXB0XCJdIHx8IGhlYWRlcnNbXCJBY2NlcHRcIl0gfHwgKGhlYWRlcnNbXCJBY2NlcHRcIl0gPSBcImFwcGxpY2F0aW9uL2pzb25cIik7IC8vRG9uJ3Qgb3ZlcnJpZGUgZXhpc3RpbmcgYWNjZXB0IGhlYWRlciBkZWNsYXJlZCBieSB1c2VyXG4gICAgICAgIGlmIChtZXRob2QgIT09IFwiR0VUXCIgJiYgbWV0aG9kICE9PSBcIkhFQURcIikge1xuICAgICAgICAgICAgaGVhZGVyc1tcImNvbnRlbnQtdHlwZVwiXSB8fCBoZWFkZXJzW1wiQ29udGVudC1UeXBlXCJdIHx8IChoZWFkZXJzW1wiQ29udGVudC1UeXBlXCJdID0gXCJhcHBsaWNhdGlvbi9qc29uXCIpOyAvL0Rvbid0IG92ZXJyaWRlIGV4aXN0aW5nIGFjY2VwdCBoZWFkZXIgZGVjbGFyZWQgYnkgdXNlclxuICAgICAgICAgICAgYm9keSA9IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMuanNvbiA9PT0gdHJ1ZSA/IGJvZHkgOiBvcHRpb25zLmpzb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHJlYWR5c3RhdGVjaGFuZ2U7XG4gICAgeGhyLm9ubG9hZCA9IGxvYWRGdW5jO1xuICAgIHhoci5vbmVycm9yID0gZXJyb3JGdW5jO1xuICAgIC8vIElFOSBtdXN0IGhhdmUgb25wcm9ncmVzcyBiZSBzZXQgdG8gYSB1bmlxdWUgZnVuY3Rpb24uXG4gICAgeGhyLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIElFIG11c3QgZGllXG4gICAgfTtcbiAgICB4aHIub25hYm9ydCA9IGZ1bmN0aW9uKCl7XG4gICAgICAgIGFib3J0ZWQgPSB0cnVlO1xuICAgIH07XG4gICAgeGhyLm9udGltZW91dCA9IGVycm9yRnVuYztcbiAgICB4aHIub3BlbihtZXRob2QsIHVyaSwgIXN5bmMsIG9wdGlvbnMudXNlcm5hbWUsIG9wdGlvbnMucGFzc3dvcmQpO1xuICAgIC8vaGFzIHRvIGJlIGFmdGVyIG9wZW5cbiAgICBpZighc3luYykge1xuICAgICAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gISFvcHRpb25zLndpdGhDcmVkZW50aWFscztcbiAgICB9XG4gICAgLy8gQ2Fubm90IHNldCB0aW1lb3V0IHdpdGggc3luYyByZXF1ZXN0XG4gICAgLy8gbm90IHNldHRpbmcgdGltZW91dCBvbiB0aGUgeGhyIG9iamVjdCwgYmVjYXVzZSBvZiBvbGQgd2Via2l0cyBldGMuIG5vdCBoYW5kbGluZyB0aGF0IGNvcnJlY3RseVxuICAgIC8vIGJvdGggbnBtJ3MgcmVxdWVzdCBhbmQganF1ZXJ5IDEueCB1c2UgdGhpcyBraW5kIG9mIHRpbWVvdXQsIHNvIHRoaXMgaXMgYmVpbmcgY29uc2lzdGVudFxuICAgIGlmICghc3luYyAmJiBvcHRpb25zLnRpbWVvdXQgPiAwICkge1xuICAgICAgICB0aW1lb3V0VGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICBpZiAoYWJvcnRlZCkgcmV0dXJuXG4gICAgICAgICAgICBhYm9ydGVkID0gdHJ1ZTsvL0lFOSBtYXkgc3RpbGwgY2FsbCByZWFkeXN0YXRlY2hhbmdlXG4gICAgICAgICAgICB4aHIuYWJvcnQoXCJ0aW1lb3V0XCIpO1xuICAgICAgICAgICAgdmFyIGUgPSBuZXcgRXJyb3IoXCJYTUxIdHRwUmVxdWVzdCB0aW1lb3V0XCIpO1xuICAgICAgICAgICAgZS5jb2RlID0gXCJFVElNRURPVVRcIjtcbiAgICAgICAgICAgIGVycm9yRnVuYyhlKTtcbiAgICAgICAgfSwgb3B0aW9ucy50aW1lb3V0ICk7XG4gICAgfVxuXG4gICAgaWYgKHhoci5zZXRSZXF1ZXN0SGVhZGVyKSB7XG4gICAgICAgIGZvcihrZXkgaW4gaGVhZGVycyl7XG4gICAgICAgICAgICBpZihoZWFkZXJzLmhhc093blByb3BlcnR5KGtleSkpe1xuICAgICAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5oZWFkZXJzICYmICFpc0VtcHR5KG9wdGlvbnMuaGVhZGVycykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSGVhZGVycyBjYW5ub3QgYmUgc2V0IG9uIGFuIFhEb21haW5SZXF1ZXN0IG9iamVjdFwiKVxuICAgIH1cblxuICAgIGlmIChcInJlc3BvbnNlVHlwZVwiIGluIG9wdGlvbnMpIHtcbiAgICAgICAgeGhyLnJlc3BvbnNlVHlwZSA9IG9wdGlvbnMucmVzcG9uc2VUeXBlO1xuICAgIH1cblxuICAgIGlmIChcImJlZm9yZVNlbmRcIiBpbiBvcHRpb25zICYmXG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmJlZm9yZVNlbmQgPT09IFwiZnVuY3Rpb25cIlxuICAgICkge1xuICAgICAgICBvcHRpb25zLmJlZm9yZVNlbmQoeGhyKTtcbiAgICB9XG5cbiAgICAvLyBNaWNyb3NvZnQgRWRnZSBicm93c2VyIHNlbmRzIFwidW5kZWZpbmVkXCIgd2hlbiBzZW5kIGlzIGNhbGxlZCB3aXRoIHVuZGVmaW5lZCB2YWx1ZS5cbiAgICAvLyBYTUxIdHRwUmVxdWVzdCBzcGVjIHNheXMgdG8gcGFzcyBudWxsIGFzIGJvZHkgdG8gaW5kaWNhdGUgbm8gYm9keVxuICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbmF1Z3R1ci94aHIvaXNzdWVzLzEwMC5cbiAgICB4aHIuc2
23459VuZChib2R5IHx8IG51bGwpO1xuXG4gICAgcmV0dXJuIHhoclxuXG5cbn1cblxuZnVuY3Rpb24gZ2V0WG1sKHhocikge1xuICAgIC8vIHhoci5yZXNwb25zZVhNTCB3aWxsIHRocm93IEV4Y2VwdGlvbiBcIkludmFsaWRTdGF0ZUVycm9yXCIgb3IgXCJET01FeGNlcHRpb25cIlxuICAgIC8vIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvWE1MSHR0cFJlcXVlc3QvcmVzcG9uc2VYTUwuXG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHhoci5yZXNwb25zZVR5cGUgPT09IFwiZG9jdW1lbnRcIikge1xuICAgICAgICAgICAgcmV0dXJuIHhoci5yZXNwb25zZVhNTFxuICAgICAgICB9XG4gICAgICAgIHZhciBmaXJlZm94QnVnVGFrZW5FZmZlY3QgPSB4aHIucmVzcG9uc2VYTUwgJiYgeGhyLnJlc3BvbnNlWE1MLmRvY3VtZW50RWxlbWVudC5ub2RlTmFtZSA9PT0gXCJwYXJzZXJlcnJvclwiO1xuICAgICAgICBpZiAoeGhyLnJlc3BvbnNlVHlwZSA9PT0gXCJcIiAmJiAhZmlyZWZveEJ1Z1Rha2VuRWZmZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4geGhyLnJlc3BvbnNlWE1MXG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgcmV0dXJuIG51bGxcbn1cblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnhoci5kZWZhdWx0ID0gZGVmYXVsdF8xO1xuXG52YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiID8gZnVuY3Rpb24gKG9iaikge1xuICByZXR1cm4gdHlwZW9mIG9iajtcbn0gOiBmdW5jdGlvbiAob2JqKSB7XG4gIHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqO1xufTtcblxuXG5cblxuXG52YXIgYXN5bmNHZW5lcmF0b3IgPSBmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEF3YWl0VmFsdWUodmFsdWUpIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiBBc3luY0dlbmVyYXRvcihnZW4pIHtcbiAgICB2YXIgZnJvbnQsIGJhY2s7XG5cbiAgICBmdW5jdGlvbiBzZW5kKGtleSwgYXJnKSB7XG4gICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICB2Y
23459XIgcmVxdWVzdCA9IHtcbiAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICBhcmc6IGFyZyxcbiAgICAgICAgICByZXNvbHZlOiByZXNvbHZlLFxuICAgICAgICAgIHJlamVjdDogcmVqZWN0LFxuICAgICAgICAgIG5leHQ6IG51bGxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoYmFjaykge1xuICAgICAgICAgIGJhY2sgPSBiYWNrLm5leHQgPSByZXF1ZXN0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZyb250ID0gYmFjayA9IHJlcXVlc3Q7XG4gICAgICAgICAgcmVzdW1lKGtleSwgYXJnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVzdW1lKGtleSwgYXJnKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gZ2VuW2tleV0oYXJnKTtcbiAgICAgICAgdmFyIHZhbHVlID0gcmVzdWx0LnZhbHVlO1xuXG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEF3YWl0VmFsdWUpIHtcbiAgICAgICAgICBQcm9taXNlLnJlc29sdmUodmFsdWUudmFsdWUpLnRoZW4oZnVuY3Rpb24gKGFyZykge1xuICAgICAgICAgICAgcmVzdW1lKFwibmV4dFwiLCBhcmcpO1xuICAgICAgICAgIH0sIGZ1bmN0aW9uIChhcmcpIHtcbiAgICAgICAgICAgIHJlc3VtZShcInRocm93XCIsIGFyZyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2V0dGxlKHJlc3VsdC5kb25lID8gXCJyZXR1cm5cIiA6IFwibm9ybWFsXCIsIHJlc3VsdC52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBzZXR0bGUoXCJ0aHJvd1wiLCBlcnIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldHRsZSh0eXBlLCB2YWx1ZSkge1xuICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgIGNhc2UgXCJyZXR1cm5cIjpcbiAgICAgICAgICBmcm9udC5yZXNvbHZlKHtcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgIGRvbmU6IHRydWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIFwidGhyb3dcIjpcbiAgICAgICAgICBmcm9udC5yZWplY3QodmFsdWUpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgZnJvbnQucmVzb2x2ZSh7XG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgICAgICBkb25lOiBmYWxzZVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBmcm9udCA9IGZyb250Lm5leHQ7XG5cbiAgICAgIGlmIChmcm9udCkge1xuICAgICAgICByZXN1bWUoZnJvbnQua2V5LCBmcm9udC5hcmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYmFjayA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5faW52b2tlID0gc2VuZDtcblxuICAgIGlmICh0eXBlb2YgZ2VuLnJldHVybiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICB0aGlzLnJldHVybiA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5hc3luY0l0ZXJhdG9yKSB7XG4gICAgQXN5bmNHZW5lcmF0b3IucHJvdG90eXBlW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG4gIH1cblxuICBBc3luY0dlbmVyYXRvci5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uIChhcmcpIHtcbiAgICByZXR1cm4gdGhpcy5faW52b2tlKFwibmV4dFwiLCBhcmcpO1xuICB9O1xuXG4gIEFzeW5jR2VuZXJhdG9yLnByb3RvdHlwZS50aHJvdyA9IGZ1bmN0aW9uIChhcmcpIHtcbiAgICByZXR1cm4gdGhpcy5faW52b2tlKFwidGhyb3dcIiwgYXJnKTtcbiAgfTtcblxuICBBc3luY0dlbmVyYXRvci5wcm90b3R5cGUucmV0dXJuID0gZnVuY3Rpb24gKGFyZykge1xuICAgIHJldHVybiB0aGlzLl9pbnZva2UoXCJyZXR1cm5cIiwgYXJnKTtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIHdyYXA6IGZ1bmN0aW9uIChmbikge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBc3luY0dlbmVyYXRvcihmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTtcbiAgICAgIH07XG4gICAgfSxcbiAgICBhd2FpdDogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICByZXR1cm4gbmV3IEF3YWl0VmFsdWUodmFsdWUpO1xuICAgIH1cbiAgfTtcbn0oKTtcblxuXG5cblxuXG52YXIgY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7XG4gIGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTtcbiAgfVxufTtcblxudmFyIGNyZWF0ZUNsYXNzID0gZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2Y
23459XIgZGVzY3JpcHRvciA9IHByb3BzW2ldO1xuICAgICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlO1xuICAgICAgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlO1xuICAgICAgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykge1xuICAgIGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7XG4gICAgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7XG4gICAgcmV0dXJuIENvbnN0cnVjdG9yO1xuICB9O1xufSgpO1xuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cbnZhciB0b0NvbnN1bWFibGVBcnJheSA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkge1xuICAgIGZvciAodmFyIGkgPSAwLCBhcnIyID0gQXJyYXkoYXJyLmxlbmd0aCk7IGkgPCBhcnIubGVuZ3RoOyBpKyspIGFycjJbaV0gPSBhcnJbaV07XG5cbiAgICByZXR1cm4gYXJyMjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShhcnIpO1xuICB9XG59O1xuXG52YXIgbGFzdEVycm9yID0gJyc7XG5cbi8qKlxuICogQ3JlYXRlcyB0aGUgSFRMTSBmb3IgYSBmYWlsdXJlIG1lc3NhZ2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBjYW52YXNDb250YWluZXJJZCBpZCBvZiBjb250YWluZXIgb2YgdGhcbiAqICAgICAgICBjYW52YXMuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBodG1sLlxuICovXG5mdW5jdGlvbiBtYWtlRmFpbEhUTUwobXNnKSB7XG4gICAgcmV0dXJuICdcXG48dGFibGUgc3R5bGU9XCJiYWNrZ3JvdW5kLWNvbG9yOiAjOENFOyB3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlO1wiPjx0cj5cXG48dGQgYWxpZ249XCJjZW50ZXJcIj5cXG48ZGl2IHN0eWxlPVwiZGlzcGxheTogdGFibGUtY2VsbDsgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcIj5cXG48ZGl2IHN0eWxlPVwiXCI+JyArIG1zZyArICc8L2Rpdj5cXG48L2Rpdj5cXG48L3RkPjwvdHI+PC90YWJsZT5cXG4nO1xufVxuXG4vKipcbiAqIE1lc3NhZ2UgZm9yIGdldHRpbmcgYSB3ZWJnbCBicm93c2VyXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG52YXIgR0VUX0FfV0VCR0xfQlJPV1NFUiA9ICdcXG5cXHRUaGlzIHBhZ2UgcmVxdWlyZXMgYSBicm93c2VyIHRoYXQgc3VwcG9ydHMgV2ViR0wuPGJyLz5cXG5cXHQ8YSBocmVmPVwiaHR0cDovL2dldC53ZWJnbC5vcmdcIj5DbGljayBoZXJlIHRvIHVwZ3JhZGUgeW91ciBicm93c2VyLjwvYT5cXG4nO1xuXG4vKipcbiAqIE1lc3NhZ2UgZm9yIG5lZWQgYmV0dGVyIGhhcmR3YXJlXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG52YXIgT1RIRVJfUFJPQkxFTSA9ICdcXG5cXHRJdCBkb2VzIG5vdCBhcHBlYXIgeW91ciBjb21wdXRlciBjYW4gc3VwcG9ydCBXZWJHTC48YnIvPlxcblxcdDxhIGhyZWY9XCJodHRwOi8vZ2V0LndlYmdsLm9yZy90cm91Ymxlc2hvb3RpbmcvXCI+Q2xpY2sgaGVyZSBmb3IgbW9yZSBpbmZvcm1hdGlvbi48L2E+XFxuJztcblxuLyoqXG4gKiBDb2RlIHRvIHJldHVybiBpbiBgb25FcnJvcmAgY2FsbGJhY2sgd2hlbiB0aGUgYnJvd3NlciBkb2Vzbid0IHN1cHBvcnQgd2ViZ2xcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbnZhciBFUlJPUl9CUk9XU0VSX1NVUFBPUlQgPSAxO1xuXG4vKipcbiAqIENvZGUgdG8gcmV0dXJuIGluIGBvbkVycm9yYCBjYWxsYmFjayB0aGVyZSdzIGFueSBvdGhlciBwcm9ibGVtIHJlbGF0ZWQgdG8gd2ViZ2xcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbnZhciBFUlJPUl9PVEhFUiA9IDI7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHdlYmdsIGNvbnRleHQuIElmIGNyZWF0aW9uIGZhaWxzIGl0IHdpbGxcbiAqIGNoYW5nZSB0aGUgY29udGVudHMgb2YgdGhlIGNvbnRhaW5lciBvZiB0aGUgPGNhbnZhcz5cbiAqIHRhZyB0byBhbiBlcnJvciBtZXNzYWdlIHdpdGggdGhlIGNvcnJlY3QgbGlua3MgZm9yIFdlYkdMLFxuICogdW5sZXNzIGBvbkVycm9yYCBvcHRpb24gaXMgZGVmaW5lZCB0byBhIGNhbGxiYWNrLFxuICogd2hpY2ggYWxsb3dzIGZvciBjdXN0b20gZXJyb3IgaGFuZGxpbmcuLlxuICogQHBhcmFtIHtFbGVtZW50fSBjYW52YXMuIFRoZSBjYW52YXMgZWxlbWVudCB0byBjcmVhdGUgYVxuICogICAgIGNvbnRleHQgZnJvbS5cbiAqIEBwYXJhbSB7V2ViR0xDb250ZXh0Q3JlYXRpb25BdHRyaWJ1dGVzfSBvcHRBdHRyaWJzIEFueVxuICogICAgIGNyZWF0aW9uIGF0dHJpYnV0ZXMgeW91IHdhbnQgdG8gcGFzcyBpbi5cbiAqIEByZXR1cm4ge1dlYkdMUmVuZGVyaW5nQ29udGV4dH0gVGhlIGNyZWF0ZWQgY29udGV4dC5cbiAqL1xuZnVuY3Rpb24gc2V0dXBXZWJHTChjYW52YXMsIG9wdEF0dHJpYnMsIG9uRXJyb3IpIHtcbiAgICBmdW5jdGlvbiBzaG93TGluayhzdHIpIHtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IGNhbnZhcy5wYXJlbnROb2RlO1xuICAgICAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICAgICAgICBjb250YWluZXIuaW5uZXJIVE1MID0gbWFrZUZhaWxIVE1MKHN0cik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoYW5kbGVFcnJvcihlcnJvckNvZGUsIG1zZykge1xuICAgICAgICBpZiAodHlwZW9mIG9uRXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIG9uRXJyb3IoZXJyb3JDb2RlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNob3dMaW5rKG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXdpbmRvdy5XZWJHTFJlbmRlcmluZ0NvbnRleHQpIHtcbiAgICAgICAgaGFuZGxlRXJyb3IoRVJST1JfQlJPV1NFUl9TVVBQT1JULCBHRVRfQV9XRUJHTF9CUk9XU0VSKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIGNvbnRleHQgPSBjcmVhdGUzRENvbnRleHQoY2FudmFzLCBvcHRBdHRyaWJzKTtcbiAgICBpZiAoIWNvbnRleHQpIHtcbiAgICAgICAgaGFuZGxlRXJyb3IoRVJST1JfT1RIRVIsIE9USEVSX1BST0JMRU0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRleHQuZ2V0RXh0ZW5zaW9uKCdPRVNfc3RhbmRhcmRfZGVyaXZhdGl2ZXMnKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRleHQ7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHdlYmdsIGNvbnRleHQuXG4gKiBAcGFyYW0geyFDYW52YXN9IGNhbnZhcyBUaGUgY2FudmFzIHRhZyB0byBnZXQgY29udGV4dFxuICogICAgIGZyb20uIElmIG9uZSBpcyBub3QgcGFzc2VkIGluIG9uZSB3aWxsIGJlIGNyZWF0ZWQuXG4gKiBAcmV0dXJuIHshV2ViR0xDb250ZXh0fSBUaGUgY3JlYXRlZCBjb250ZXh0LlxuICovXG5mdW5jdGlvbiBjcmVhdGUzRENvbnRleHQoY2FudmFzLCBvcHRBdHRyaWJzKSB7XG4gICAgdmFyIG5hbWVzID0gWyd3ZWJnbCcsICdleHBlcmltZW50YWwtd2ViZ2wnXTtcbiAgICB2YXIgY29udGV4dCA9IG51bGw7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IG5hbWVzLmxlbmd0aDsgKytpaSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KG5hbWVzW2lpXSwgb3B0QXR0cmlicyk7XG4gICAgICAgI
23459H0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChjb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNvbnRleHQ7XG59XG5cbi8qXG4gKlx0Q3JlYXRlIGEgVmVydGV4IG9mIGEgc3BlY2lmaWMgdHlwZSAoZ2wuVkVSVEVYX1NIQURFUi8pXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVNoYWRlcihtYWluLCBzb3VyY2UsIHR5cGUsIG9mZnNldCkge1xuICAgIHZhciBnbCA9IG1haW4uZ2w7XG5cbiAgICB2YXIgc2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKHR5cGUpO1xuICAgIGdsLnNoYWRlclNvdXJjZShzaGFkZXIsIHNvdXJjZSk7XG4gICAgZ2wuY29tcGlsZVNoYWRlcihzaGFkZXIpO1xuXG4gICAgdmFyIGNvbXBpbGVkID0gZ2wuZ2V0U2hhZGVyUGFyYW1ldGVyKHNoYWRlciwgZ2wuQ09NUElMRV9TVEFUVVMpO1xuXG4gICAgaWYgKCFjb21waWxlZCkge1xuICAgICAgICAvLyBTb21ldGhpbmcgd2VudCB3cm9uZyBkdXJpbmcgY29tcGlsYXRpb247IGdldCB0aGUgZXJyb3JcbiAgICAgICAgbGFzdEVycm9yID0gZ2wuZ2V0U2hhZGVySW5mb0xvZyhzaGFkZXIpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCcqKiogRXJyb3IgY29tcGlsaW5nIHNoYWRlciAnICsgc2hhZGVyICsgJzonICsgbGFzdEVycm9yKTtcbiAgICAgICAgbWFpbi50cmlnZ2VyKCdlcnJvcicsIHtcbiAgICAgICAgICAgIHNoYWRlcjogc2hhZGVyLFxuICAgICAgICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICAgICAgICB0eXBlOiB0eXBlLFxuICAgICAgICAgICAgZXJyb3I6IGxhc3RFcnJvcixcbiAgICAgICAgICAgIG9mZnNldDogb2Zmc2V0IHx8IDBcbiAgICAgICAgfSk7XG4gICAgICAgIGdsLmRlbGV0ZVNoYWRlcihzaGFkZXIpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gc2hhZGVyO1xufVxuXG4vKipcbiAqIExvYWRzIGEgc2hhZGVyLlxuICogQHBhcmFtIHshV2ViR0xDb250ZXh0fSBnbCBUaGUgV2ViR0xDb250ZXh0IHRvIHVzZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzaGFkZXJTb3VyY2UgVGhlIHNoYWRlciBzb3VyY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gc2hhZGVyVHlwZSBUaGUgdHlwZSBvZiBzaGFkZXIuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKHN0cmluZyk6IHZvaWQpIG9wdF9lcnJvckNhbGxiYWNrIGNhbGxiYWNrIGZvciBlcnJvcnMuXG4gKiBAcmV0dXJuIHshV2ViR0xTaGFkZXJ9IFRoZSBjcmVhdGVkIHNoYWRlci5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUHJvZ3JhbShtYWluLCBzaGFkZXJzLCBvcHRBdHRyaWJzLCBvcHRMb2NhdGlvbnMpIHtcbiAgICB2YXIgZ2wgPSBtYWluLmdsO1xuXG4gICAgdmFyIHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCk7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IHNoYWRlcnMubGVuZ3RoOyArK2lpKSB7XG4gICAgICAgIGdsLmF0dGFjaFNoYWRlcihwcm9ncmFtLCBzaGFkZXJzW2lpXSk7XG4gICAgfVxuICAgIGlmIChvcHRBdHRyaWJzKSB7XG4gICAgICAgIGZvciAodmFyIF9paSA9IDA7IF9paSA8IG9wdEF0dHJpYnMubGVuZ3RoOyArK19paSkge1xuICAgICAgICAgICAgZ2wuYmluZEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sIG9wdExvY2F0aW9ucyA/IG9wdExvY2F0aW9uc1tfaWldIDogX2lpLCBvcHRBdHRyaWJzW19paV0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdsLmxpbmtQcm9ncmFtKHByb2dyYW0pO1xuXG4gICAgLy8gQ2hlY2sgdGhlIGxpbmsgc3RhdHVzXG4gICAgdmFyIGxpbmtlZCA9IGdsLmdldFByb2dyYW1QYXJhbWV0ZXIocHJvZ3JhbSwgZ2wuTElOS19TVEFUVVMpO1xuICAgIGlmICghbGlua2VkKSB7XG4gICAgICAgIC8vIHNvbWV0aGluZyB3ZW50IHdyb25nIHdpdGggdGhlIGxpbmtcbiAgICAgICAgbGFzdEVycm9yID0gZ2wuZ2V0UHJvZ3JhbUluZm9Mb2cocHJvZ3JhbSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdFcnJvciBpbiBwcm9ncmFtIGxpbmtpbmc6JyArIGxhc3RFcnJvcik7XG4gICAgICAgIGdsLmRlbGV0ZVByb2dyYW0ocHJvZ3JhbSk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gcHJvZ3JhbTtcbn1cblxuLy8gQnkgQnJldHQgQ2FtYmVyIG9uXG4vLyBodHRwczovL2dpdGh1Yi5jb20vdGFuZ3JhbXMvdGFuZ3JhbS9ibG9iL21hc3Rlci9zcmMvZ2wvZ2xzbC5qc1xuZnVuY3Rpb24gcGFyc2VVbmlmb3Jtcyh1bmlmb3Jtcykge1xuICAgIHZhciBwcmVmaXggPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IG51bGw7XG5cbiAgICB2YXIgcGFyc2VkID0gW107XG5cbiAgICBmb3IgKHZhciBuYW1lIGluIHVuaWZvcm1zKSB7XG4gICAgICAgIHZhciB1bmlmb3JtID0gdW5pZm9ybXNbbmFtZV07XG4gICAgICAgIHZhciB1ID0gdm9pZCAwO1xuXG4gICAgICAgIGlmIChwcmVmaXgpIHtcbiAgICAgICAgICAgIG5hbWUgPSBwcmVmaXggKyAnLicgKyBuYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2luZ2xlIGZsb2F0XG4gICAgICAgIGlmICh0eXBlb2YgdW5pZm9ybSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHBhcnNlZC5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnZmxvYXQnLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogJzFmJyxcbiAgICAgICAgICAgICAgICBuYW1lOiBuYW1lLFxuICAgICAgICAgICAgICAgIHZhbHVlOiB1bmlmb3JtXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBBcnJheTogdmVjdG9yLCBhcnJheSBvZiBmbG9hdHMsIGFycmF5IG9mIHRleHR1cmVzLCBvciBhcnJheSBvZiBzdHJ1Y3RzXG4gICAgICAgIGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodW5pZm9ybSkpIHtcbiAgICAgICAgICAgICAgICAvLyBOdW1lcmljIHZhbHVlc1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdW5pZm9ybVswXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZmxvYXQgdmVjdG9ycyAodmVjMiwgdmVjMywgdmVjNClcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVuaWZvcm0ubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZWQucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2Zsb2F0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICcxZicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdW5pZm9ybVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgI
23459H1cbiAgICAgICAgICAgICAgICAgICAgLy8gZmxvYXQgdmVjdG9ycyAodmVjMiwgdmVjMywgdmVjNClcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodW5pZm9ybS5sZW5ndGggPj0gMiAmJiB1bmlmb3JtLmxlbmd0aCA8PSA0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VkLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndmVjJyArIHVuaWZvcm0ubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q6IHVuaWZvcm0ubGVuZ3RoICsgJ2Z2JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHVuaWZvcm1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZsb2F0IGFycmF5XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh1bmlmb3JtLmxlbmd0aCA+IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VkLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2Zsb2F0W10nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiAnMWZ2JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IG5hbWUgKyAnWzBdJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB1bmlmb3JtXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogYXNzdW1lIG1hdHJpeCBmb3IgKHR5cGVvZiA9PSBGbG9hdDMyQXJyYXkgJiYgbGVuZ3RoID09IDE2KT9cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gQXJyYXkgb2YgdGV4dHVyZXNcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgdW5pZm9ybVswXSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlZC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc2FtcGxlcjJEJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q6ICcxaScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdW5pZm9ybVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gQXJyYXkgb2YgYXJyYXlzIC0gYnV0IG9ubHkgYXJyYXlzIG9mIHZlY3RvcnMgYXJlIGFsbG93ZWQgaW4gdGhpcyBjYXNlXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodW5pZm9ybVswXSkgJiYgdHlwZW9mIHVuaWZvcm1bMF1bMF0gPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmxvYXQgdmVjdG9ycyAodmVjMiwgdmVjMywgdmVjNClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodW5pZm9ybVswXS5sZW5ndGggPj0gMiAmJiB1bmlmb3JtWzBdLmxlbmd0aCA8PSA0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBlYWNoIHZlY3RvciBpbiB0aGUgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh1ID0gMDsgdSA8IHVuaWZvcm0ubGVuZ3RoOyB1KyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlZC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndmVjJyArIHVuaWZvcm1bMF0ubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZDogdW5pZm9ybVt1XS5sZW5ndGggKyAnZnYnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IG5hbWUgKyAnWycgKyB1ICsgJ10nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB1bmlmb3JtW3VdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlbHNlIGVycm9yP1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQXJyYXkgb2Ygc3RydWN0dXJlc1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoX3R5cGVvZih1bmlmb3JtWzBdKSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh1ID0gMDsgdSA8IHVuaWZvcm0ubGVuZ3RoOyB1KyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBlYWNoIHN0cnVjdCBpbiB0aGUgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlZC5wdXNoLmFwcGx5KHBhcnNlZCwgdG9Db25zdW1hYmxlQXJyYXkocGFyc2VVbmlmb3Jtcyh1bmlmb3JtW3VdLCBuYW1lICsgJ1snICsgdSArICddJykpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJvb2xlYW5cbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB1bmlmb3JtID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyc2VkLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2Jvb2wnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiAnMWknLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB1bmlmb3JtXG4gICAgICAgICAgICAgICAgICAgI
23459H0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBUZXh0dXJlXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHVuaWZvcm0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZWQucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3NhbXBsZXIyRCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiAnMWknLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IG5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHVuaWZvcm1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0cnVjdHVyZVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICgodHlwZW9mIHVuaWZvcm0gPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHVuaWZvcm0pKSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgZWFjaCBmaWVsZCBpbiB0aGUgc3RydWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VkLnB1c2guYXBwbHkocGFyc2VkLCB0b0NvbnN1bWFibGVBcnJheShwYXJzZVVuaWZvcm1zKHVuaWZvcm0sIG5hbWUpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgIC8vIFRPRE86IHN1cHBvcnQgb3RoZXIgbm9uLWZsb2F0IHR5cGVzPyAoaW50LCBldGMuKVxuICAgIH1cbiAgICByZXR1cm4gcGFyc2VkO1xufVxuXG5mdW5jdGlvbiBpc0NhbnZhc1Zpc2libGUoY2FudmFzKSB7XG4gICAgdmFyIGJvdW5kID0gY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiBib3VuZC50b3AgKyBib3VuZC5oZWlnaHQgPiAwICYmIGJvdW5kLnRvcCA8ICh3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCk7XG59XG5cbmZ1bmN0aW9uIGlzUG93ZXJPZjIodmFsdWUpIHtcbiAgICByZXR1cm4gKHZhbHVlICYgdmFsdWUgLSAxKSA9PT0gMDtcbn1cblxuZnVuY3Rpb24gaXNTYWZhcmkoKSB7XG4gICAgcmV0dXJuICgvXigoPyFjaHJvbWV8YW5kcm9pZCkuKSpzYWZhcmkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpXG4gICAgKTtcbn1cblxuXG5cblxuXG5cblxuZnVuY3Rpb24gaXNEaWZmKGEsIGIpIHtcbiAgICBpZiAoYSAmJiBiKSB7XG4gICAgICAgIHJldHVybiBhLnRvU3RyaW5nKCkgIT09IGIudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBnZXRGaWxlKHVybCkge1xuICAgIHZhciBodHRwUmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIGh0dHBSZXF1ZXN0Lm9wZW4oXCJHRVRcIiwgdXJsLCBmYWxzZSk7XG4gICAgaHR0cFJlcXVlc3Quc2VuZCgpO1xuICAgIGlmIChodHRwUmVxdWVzdC5zdGF0dXMgPT0gMjAwKSByZXR1cm4gaHR0cFJlcXVlc3QucmVzcG9uc2VUZXh0O2Vsc2UgcmV0dXJuIFwiXCI7XG59XG5cbmZ1bmN0aW9uIHN1YnNjcmliZU1peGluJDEodGFyZ2V0KSB7XG4gICAgdmFyIGxpc3RlbmVycyA9IG5ldyBTZXQoKTtcblxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHRhcmdldCwge1xuICAgICAgICBvbjogZnVuY3Rpb24gb24odHlwZSwgZikge1xuICAgICAgICAgICAgdmFyIGxpc3RlbmVyID0ge307XG4gICAgICAgICAgICBsaXN0ZW5lclt0eXBlXSA9IGY7XG4gICAgICAgICAgICBsaXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTtcbiAgICAgICAgfSxcbiAgICAgICAgb2ZmOiBmdW5jdGlvbiBvZmYodHlwZSwgZikge1xuICAgICAgICAgICAgaWYgKGYpIHtcbiAgICAgICAgICAgICAgICB2Y
23459XIgbGlzdGVuZXIgPSB7fTtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lclt0eXBlXSA9IGY7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzLmRlbGV0ZShsaXN0ZW5lcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3IgPSBsaXN0ZW5lcnNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDsgIShfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gKF9zdGVwID0gX2l0ZXJhdG9yLm5leHQoKSkuZG9uZSk7IF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXRlbSA9IF9zdGVwLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBfZGlkSXRlcmF0b3JFcnJvcjIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBfaXRlcmF0b3JFcnJvcjIgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yMiA9IE9iamVjdC5rZXlzKGl0ZW0pW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXAyOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yID0gKF9zdGVwMiA9IF9pdGVyYXRvcjIubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjIgPSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXkgPSBfc3RlcDIudmFsdWU7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gdHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzLmRlbGV0ZShpdGVtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yMiA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IyID0gZXJyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24yICYmIF9pdGVyYXRvcjIucmV0dXJuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaXRlcmF0b3IyLnJldHVybigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3IyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yRXJyb3IgPSBlcnI7XG4gICAgICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiAmJiBfaXRlcmF0b3IucmV0dXJuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yLnJldHVybigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9kaWRJdGVyYXRvckVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3I7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGxpc3RTdWJzY3JpcHRpb25zOiBmdW5jdGlvbiBsaXN0U3Vic2NyaXB0aW9ucygpIHtcbiAgICAgICAgICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMyA9IHRydWU7XG4gICAgICAgICAgICB2Y
23459XIgX2RpZEl0ZXJhdG9yRXJyb3IzID0gZmFsc2U7XG4gICAgICAgICAgICB2YXIgX2l0ZXJhdG9yRXJyb3IzID0gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIF9pdGVyYXRvcjMgPSBsaXN0ZW5lcnNbU3ltYm9sLml0ZXJhdG9yXSgpLCBfc3RlcDM7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMgPSAoX3N0ZXAzID0gX2l0ZXJhdG9yMy5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uMyA9IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGl0ZW0gPSBfc3RlcDMudmFsdWU7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coaXRlbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvcjMgPSBlcnI7XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjMgJiYgX2l0ZXJhdG9yMy5yZXR1cm4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF9pdGVyYXRvcjMucmV0dXJuKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoX2RpZEl0ZXJhdG9yRXJyb3IzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBfaXRlcmF0b3JFcnJvcjM7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHN1YnNjcmliZTogZnVuY3Rpb24gc3Vic2NyaWJlKGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTtcbiAgICAgICAgfSxcbiAgICAgICAgdW5zdWJzY3JpYmU6IGZ1bmN0aW9uIHVuc3Vic2NyaWJlKGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnMuZGVsZXRlKGxpc3RlbmVyKTtcbiAgICAgICAgfSxcbiAgICAgICAgdW5zdWJzY3JpYmVBbGw6IGZ1bmN0aW9uIHVuc3Vic2NyaWJlQWxsKCkge1xuICAgICAgICAgICAgbGlzdGVuZXJzLmNsZWFyKCk7XG4gICAgICAgIH0sXG4gICAgICAgIHRyaWdnZXI6IGZ1bmN0aW9uIHRyaWdnZXIoZXZlbnQpIHtcbiAgICAgICAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBkYXRhID0gQXJyYXkoX2xlbiA+IDEgPyBfbGVuIC0gMSA6IDApLCBfa2V5ID0gMTsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgICAgICAgICAgIGRhdGFbX2tleSAtIDFdID0gYXJndW1lbnRzW19rZXldO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2Y
23459XIgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjQgPSB0cnVlO1xuICAgICAgICAgICAgdmFyIF9kaWRJdGVyYXRvckVycm9yNCA9IGZhbHNlO1xuICAgICAgICAgICAgdmFyIF9pdGVyYXRvckVycm9yNCA9IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBfaXRlcmF0b3I0ID0gbGlzdGVuZXJzW1N5bWJvbC5pdGVyYXRvcl0oKSwgX3N0ZXA0OyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb240ID0gKF9zdGVwNCA9IF9pdGVyYXRvcjQubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbjQgPSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsaXN0ZW5lciA9IF9zdGVwNC52YWx1ZTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyW2V2ZW50XSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJbZXZlbnRdLmFwcGx5KGxpc3RlbmVyLCB0b0NvbnN1bWFibGVBcnJheShkYXRhKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBfZGlkSXRlcmF0b3JFcnJvcjQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIF9pdGVyYXRvckVycm9yNCA9IGVycjtcbiAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uNCAmJiBfaXRlcmF0b3I0LnJldHVybikge1xuICAgICAgICAgICAgICAgICAgICAgICAgX2l0ZXJhdG9yNC5yZXR1cm4oKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcjQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yNDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG4vLyBUZXh0dXJlIG1hbmFnZW1lbnRcbi8vIEdMIHRleHR1cmUgd3JhcHBlciBvYmplY3QgZm9yIGtlZXBpbmcgdHJhY2sgb2YgYSBnbG9iYWwgc2V0IG9mIHRleHR1cmVzLCBrZXllZCBieSBhIHVuaXF1ZSB1c2VyLWRlZmluZWQgbmFtZVxuXG52YXIgVGV4dHVyZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBUZXh0dXJlKGdsLCBuYW1lKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiB7fTtcbiAgICAgICAgY2xhc3NDYWxsQ2hlY2sodGhpcywgVGV4dHVyZSk7XG5cbiAgICAgICAgc3Vic2NyaWJlTWl4aW4kMSh0aGlzKTtcblxuICAgICAgICB0aGlzLmdsID0gZ2w7XG4gICAgICAgIHRoaXMudGV4dHVyZSA9IGdsLmNyZWF0ZVRleHR1cmUoKTtcbiAgICAgICAgaWYgKHRoaXMudGV4dHVyZSkge1xuICAgICAgICAgICAgdGhpcy52YWxpZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5iaW5kKCk7XG5cbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5zb3VyY2UgPSBudWxsO1xuICAgICAgICB0aGlzLnNvdXJjZVR5cGUgPSBudWxsO1xuICAgICAgICB0aGlzLmxvYWRpbmcgPSBudWxsOyAvLyBhIFByb21pc2Ugb2JqZWN0IHRvIHRyYWNrIHRoZSBsb2FkaW5nIHN0YXRlIG9mIHRoaXMgdGV4dHVyZVxuXG4gICAgICAgIC8vIERlZmF1bHQgdG8gYSAxLXBpeGVsIGJsYWNrIHRleHR1cmUgc28gd2UgY2FuIHNhZmVseSByZW5kZXIgd2hpbGUgd2Ugd2FpdCBmb3IgYW4gaW1hZ2UgdG8gbG9hZFxuICAgICAgICAvLyBTZWU6IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTk3MjIyNDcvd2ViZ2wtd2FpdC1mb3ItdGV4dHVyZS10by1sb2FkXG4gICAgICAgIHRoaXMuc2V0RGF0YSgxLCAxLCBuZXcgVWludDhBcnJheShbMCwgMCwgMCwgMjU1XSksIHsgZmlsdGVyaW5nOiAnbGluZWFyJyB9KTtcbiAgICAgICAgdGhpcy5zZXRGaWx0ZXJpbmcob3B0aW9ucy5maWx0ZXJpbmcpO1xuXG4gICAgICAgIHRoaXMubG9hZChvcHRpb25zKTtcbiAgICB9XG5cbiAgICAvLyBEZXN0cm95IGEgc2luZ2xlIHRleHR1cmUgaW5zdGFuY2VcblxuXG4gICAgY3JlYXRlQ2xhc3MoVGV4dHVyZSwgW3tcbiAgICAgICAga2V5OiAnZGVzdHJveScsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5nbC5kZWxldGVUZXh0dXJlKHRoaXMudGV4dHVyZSk7XG4gICAgICAgICAgICB0aGlzLnRleHR1cmUgPSBudWxsO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuZGF0YTtcbiAgICAgICAgICAgIHRoaXMuZGF0YSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnZhbGlkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2JpbmQnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gYmluZCh1bml0KSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMudmFsaWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIHVuaXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgaWYgKFRleHR1cmUuYWN0aXZlVW5pdCAhPT0gdW5pdCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmdsLmFjdGl2ZVRleHR1cmUodGhpcy5nbC5URVhUVVJFMCArIHVuaXQpO1xuICAgICAgICAgICAgICAgICAgICBUZXh0dXJlLmFjdGl2ZVVuaXQgPSB1bml0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChUZXh0dXJlLmFjdGl2ZVRleHR1cmUgIT09IHRoaXMudGV4dHVyZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2wuYmluZFRleHR1cmUodGhpcy5nbC5URVhUVVJFXzJELCB0aGlzLnRleHR1cmUpO1xuICAgICAgICAgICAgICAgIFRleHR1cmUuYWN0aXZlVGV4dHVyZSA9IHRoaXMudGV4dHVyZTtcbiAgICAgICAgICAgI
23459H1cbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnbG9hZCcsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBsb2FkKCkge1xuICAgICAgICAgICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHt9O1xuXG4gICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBudWxsO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMudXJsID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnVybCA9PT0gdW5kZWZpbmVkIHx8IG9wdGlvbnMudXJsICE9PSB0aGlzLnVybCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFVybChvcHRpb25zLnVybCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChvcHRpb25zLmVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldEVsZW1lbnQob3B0aW9ucy5lbGVtZW50LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAob3B0aW9ucy5kYXRhICYmIG9wdGlvbnMud2lkdGggJiYgb3B0aW9ucy5oZWlnaHQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldERhdGEob3B0aW9ucy53aWR0aCwgb3B0aW9ucy5oZWlnaHQsIG9wdGlvbnMuZGF0YSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXRzIHRleHR1cmUgZnJvbSBhbiB1cmxcblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnc2V0VXJsJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldFVybCh1cmwpIHtcbiAgICAgICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnVybCA9IHVybDsgLy8gc2F2ZSBVUkwgcmVmZXJlbmNlICh3aWxsIGJlIG92ZXJ3cml0dGVuIHdoZW4gZWxlbWVudCBpcyBsb2FkZWQgYmVsb3cpXG4gICAgICAgICAgICB0aGlzLnNvdXJjZSA9IHRoaXMudXJsO1xuICAgICAgICAgICAgdGhpcy5zb3VyY2VUeXBlID0gJ3VybCc7XG5cbiAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgICAgICB2Y
23459XIgZXh0ID0gdXJsLnNwbGl0KCcuJykucG9wKCkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgICAgICB2YXIgaXNWaWRlbyA9IGV4dCA9PT0gJ29ndicgfHwgZXh0ID09PSAnd2VibScgfHwgZXh0ID09PSAnbXA0JztcblxuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIGlmIChpc1ZpZGVvKSB7XG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmF1dG9wbGF5ID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50Lm11dGVkID0gdHJ1ZTsgLyogcmVxdWlyZWQgZm9yIG1vZGVybiBicm93c2VycyB0byBhdXRvcGxheSB2aWRlbyAqL1xuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucGxheSgpOyAvKiBkb2Vzbid0IGJsb2NrIHByb21pc2UgYnV0IG5lZWRzIGEgbW9yZSBlbGVnYW50IHNvbHV0aW9uICovXG4gICAgICAgICAgICAgICAgICAgIH0sIDEpO1xuXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuZmlsdGVyaW5nID0gJ25lYXJlc3QnO1xuICAgICAgICAgICAgICAgICAgICAvLyBlbGVtZW50LnByZWxvYWQgPSAnYXV0byc7XG4gICAgICAgICAgICAgICAgICAgIC8vIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgICAgICAgICAgICAgLy8gZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50ID0gbmV3IEltYWdlKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZWxlbWVudC5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRFbGVtZW50KGVsZW1lbnQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVGV4dHVyZSBcXCcnICsgX3RoaXMubmFtZSArICdcXCc6IGZhaWxlZCB0byBsb2FkIHVybDogXFwnJyArIF90aGlzLnNvdXJjZSArICdcXCcnLCBlLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKF90aGlzKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGVsZW1lbnQub25lcnJvciA9IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdhcm4gYW5kIHJlc29sdmUgb24gZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1RleHR1cmUgXFwnJyArIF90aGlzLm5hbWUgKyAnXFwnOiBmYWlsZWQgdG8gbG9hZCB1cmw6IFxcJycgKyBfdGhpcy5zb3VyY2UgKyAnXFwnJywgZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoX3RoaXMpO1xuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAvLyBTYWZhcmkgaGFzIGEgYnVnIGxvYWRpbmcgZGF0YS1VUkwgZWxlbWVudHMgd2l0aCBDT1JTIGVuYWJsZWQsIHNvIGl0IG11c3QgYmUgZGlzYWJsZWQgaW4gdGhhdCBjYXNlXG4gICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTEyMzk3OFxuICAgICAgICAgICAgICAgIGlmICghKGlzU2FmYXJpKCkgJiYgX3RoaXMuc291cmNlLnNsaWNlKDAsIDUpID09PSAnZGF0YTonKSkge1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmNyb3NzT3JpZ2luID0gJ2Fub255bW91cyc7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZWxlbWVudC5zcmMgPSBfdGhpcy5zb3VyY2U7XG4gICAgICAgICAgICAgICAgaWYgKGlzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0RWxlbWVudChlbGVtZW50LCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvYWRpbmc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXRzIHRleHR1cmUgdG8gYSByYXcgaW1hZ2UgYnVmZmVyXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3NldERhdGEnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gc2V0RGF0YSh3aWR0aCwgaGVpZ2h0LCBkYXRhKSB7XG4gICAgICAgICAgICB2Y
23459XIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDoge307XG5cbiAgICAgICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXG4gICAgICAgICAgICB0aGlzLnNvdXJjZSA9IGRhdGE7XG4gICAgICAgICAgICB0aGlzLnNvdXJjZVR5cGUgPSAnZGF0YSc7XG5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlKG9wdGlvbnMpO1xuICAgICAgICAgICAgdGhpcy5zZXRGaWx0ZXJpbmcob3B0aW9ucyk7XG5cbiAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvYWRpbmc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXRzIHRoZSB0ZXh0dXJlIHRvIHRyYWNrIGEgZWxlbWVudCAoY2FudmFzL2ltYWdlKVxuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICdzZXRFbGVtZW50JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHNldEVsZW1lbnQoZWxlbWVudCwgb3B0aW9ucykge1xuICAgICAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgICAgIHZhciBlbCA9IGVsZW1lbnQ7XG5cbiAgICAgICAgICAgIC8vIGEgc3RyaW5nIGVsZW1lbnQgaXMgaW50ZXJwZXRlZCBhcyBhIENTUyBzZWxlY3RvclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50IHx8IGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50IHx8IGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zb3VyY2UgPSBlbGVtZW50O1xuICAgICAgICAgICAgICAgIHRoaXMuc291cmNlVHlwZSA9ICdlbGVtZW50JztcblxuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy5zb3VyY2UudmlkZW9XaWR0aDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLnNvdXJjZS52aWRlb0hlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5dGhyb3VnaCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMi5pbnRlcnZhbElEID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMi51cGRhdGUob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCAxNSk7XG4gICAgICAgICAgICAgICAgICAgIH0sIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5jdXJyZW50VGltZSA9IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnBsYXkoKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGUob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc2V0RmlsdGVyaW5nKG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2Y
23459XIgbXNnID0gJ3RoZSBcXCdlbGVtZW50XFwnIHBhcmFtZXRlciAoYGVsZW1lbnQ6ICcgKyBKU09OLnN0cmluZ2lmeShlbCkgKyAnYCkgbXVzdCBiZSBhIENTUyAnO1xuICAgICAgICAgICAgICAgIG1zZyArPSAnc2VsZWN0b3Igc3RyaW5nLCBvciBhIDxjYW52YXM+LCA8aW1hZ2U+IG9yIDx2aWRlbz4gb2JqZWN0JztcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnVGV4dHVyZSBcXCcnICsgdGhpcy5uYW1lICsgJ1xcJzogJyArIG1zZywgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMubG9hZGluZyA9IFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvYWRpbmc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVcGxvYWRzIGN1cnJlbnQgaW1hZ2Ugb3IgYnVmZmVyIHRvIHRoZSBHUFUgKGNhbiBiZSB1c2VkIHRvIHVwZGF0ZSBhbmltYXRlZCB0ZXh0dXJlcyBvbiB0aGUgZmx5KVxuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICd1cGRhdGUnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdXBkYXRlKCkge1xuICAgICAgICAgICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHt9O1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMudmFsaWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuYmluZCgpO1xuICAgICAgICAgICAgdGhpcy5nbC5waXhlbFN0b3JlaSh0aGlzLmdsLlVOUEFDS19GTElQX1lfV0VCR0wsIG9wdGlvbnMuVU5QQUNLX0ZMSVBfWV9XRUJHTCA9PT0gZmFsc2UgPyBmYWxzZSA6IHRydWUpO1xuICAgICAgICAgICAgdGhpcy5nbC5waXhlbFN0b3JlaSh0aGlzLmdsLlVOUEFDS19QUkVNVUxUSVBMWV9BTFBIQV9XRUJHTCwgb3B0aW9ucy5VTlBBQ0tfUFJFTVVMVElQTFlfQUxQSEFfV0VCR0wgfHwgZmFsc2UpO1xuXG4gICAgICAgICAgICAvLyBJbWFnZSBvciBDYW52YXMgZWxlbWVudFxuICAgICAgICAgICAgaWYgKHRoaXMuc291cmNlVHlwZSA9PT0gJ2VsZW1lbnQnICYmICh0aGlzLnNvdXJjZSBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50IHx8IHRoaXMuc291cmNlIGluc3RhbmNlb2YgSFRNTFZpZGVvRWxlbWVudCB8fCB0aGlzLnNvdXJjZSBpbnN0YW5jZW9mIEhUTUxJbWFnZUVsZW1lbnQgJiYgdGhpcy5zb3VyY2UuY29tcGxldGUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc291cmNlIGluc3RhbmNlb2YgSFRNTFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy5zb3VyY2UudmlkZW9XaWR0aDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLnNvdXJjZS52aWRlb0hlaWdodDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLndpZHRoID0gdGhpcy5zb3VyY2Uud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5zb3VyY2UuaGVpZ2h0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmdsLnRleEltYWdlMkQodGhpcy5nbC5URVhUVVJFXzJELCAwLCB0aGlzLmdsLlJHQkEsIHRoaXMuZ2wuUkdCQSwgdGhpcy5nbC5VTlNJR05FRF9CWVRFLCB0aGlzLnNvdXJjZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSYXcgaW1hZ2UgYnVmZmVyXG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLnNvdXJjZVR5cGUgPT09ICdkYXRhJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmdsLnRleEltYWdlMkQodGhpcy5nbC5URVhUVVJFXzJELCAwLCB0aGlzLmdsLlJHQkEsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0LCAwLCB0aGlzLmdsLlJHQkEsIHRoaXMuZ2wuVU5TSUdORURfQllURSwgdGhpcy5zb3VyY2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudHJpZ2dlcignbG9hZGVkJywgdGhpcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBEZXRlcm1pbmVzIGFwcHJvcHJpYXRlIGZpbHRlcmluZyBtb2RlXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3NldEZpbHRlcmluZycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRGaWx0ZXJpbmcoKSB7XG4gICAgICAgICAgICB2Y
23459XIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDoge307XG5cbiAgICAgICAgICAgIGlmICghdGhpcy52YWxpZCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5wb3dlck9mMiA9IGlzUG93ZXJPZjIodGhpcy53aWR0aCkgJiYgaXNQb3dlck9mMih0aGlzLmhlaWdodCk7XG4gICAgICAgICAgICAvLyBsZXQgZGVmdWFsdEZpbHRlciA9ICh0aGlzLnBvd2VyT2YyID8gJ21pcG1hcCcgOiAnbGluZWFyJyk7XG4gICAgICAgICAgICAvLyB0aGlzLmZpbHRlcmluZyA9IG9wdGlvbnMuZmlsdGVyaW5nIHx8IGRlZnVhbHRGaWx0ZXI7XG4gICAgICAgICAgICB0aGlzLmZpbHRlcmluZyA9IG9wdGlvbnMuZmlsdGVyaW5nIHx8ICdsaW5lYXInO1xuXG4gICAgICAgICAgICB2YXIgZ2wgPSB0aGlzLmdsO1xuICAgICAgICAgICAgdGhpcy5iaW5kKCk7XG5cbiAgICAgICAgICAgIC8vIEZvciBwb3dlci1vZi0yIHRleHR1cmVzLCB0aGUgZm9sbG93aW5nIHByZXNldHMgYXJlIGF2YWlsYWJsZTpcbiAgICAgICAgICAgIC8vIG1pcG1hcDogbGluZWFyIGJsZW5kIGZyb20gbmVhcmVzdCBtaXBcbiAgICAgICAgICAgIC8vIGxpbmVhcjogbGluZWFyIGJsZW5kIGZyb20gb3JpZ2luYWwgaW1hZ2UgKG5vIG1pcHMpXG4gICAgICAgICAgICAvLyBuZWFyZXN0OiBuZWFyZXN0IHBpeGVsIGZyb20gb3JpZ2luYWwgaW1hZ2UgKG5vIG1pcHMsICdibG9ja3knIGxvb2spXG4gICAgICAgICAgICBpZiAodGhpcy5wb3dlck9mMikge1xuICAgICAgICAgICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1MsIG9wdGlvbnMuVEVYVFVSRV9XUkFQX1MgfHwgZ2wuUkVQRUFUKTtcbiAgICAgICAgICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9ULCBvcHRpb25zLlRFWFRVUkVfV1JBUF9UIHx8IGdsLlJFUEVBVCk7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5maWx0ZXJpbmcgPT09ICdtaXBtYXAnKSB7XG4gICAgICAgICAgICAgICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NSU5fRklMVEVSLCBnbC5MSU5FQVJfTUlQTUFQX0xJTkVBUik7IC8vIFRPRE86IHVzZSB0cmlsaW5lYXIgZmlsdGVyaW5nIGJ5IGRlZnVhbHQgaW5zdGVhZD9cbiAgICAgICAgICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01BR19GSUxURVIsIGdsLkxJTkVBUik7XG4gICAgICAgICAgICAgICAgICAgIGdsLmdlbmVyYXRlTWlwbWFwKGdsLlRFWFRVUkVfMkQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5maWx0ZXJpbmcgPT09ICdsaW5lYXInKSB7XG4gICAgICAgICAgICAgICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NSU5fRklMVEVSLCBnbC5MSU5FQVIpO1xuICAgICAgICAgICAgICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUFHX0ZJTFRFUiwgZ2wuTElORUFSKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZmlsdGVyaW5nID09PSAnbmVhcmVzdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01JTl9GSUxURVIsIGdsLk5FQVJFU1QpO1xuICAgICAgICAgICAgICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUFHX0ZJTFRFUiwgZ2wuTkVBUkVTVCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBXZWJHTCBoYXMgc3RyaWN0IHJlcXVpcmVtZW50cyBvbiBub24tcG93ZXItb2YtMiB0ZXh0dXJlczpcbiAgICAgICAgICAgICAgICAvLyBObyBtaXBtYXBzIGFuZCBtdXN0IGNsYW1wIHRvIGVkZ2VcbiAgICAgICAgICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9TLCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICAgICAgICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9ULCBnbC5DTEFNUF9UT19FREdFKTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmZpbHRlcmluZyA9PT0gJ21pcG1hcCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXJpbmcgPSAnbGluZWFyJztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5maWx0ZXJpbmcgPT09ICduZWFyZXN0Jykge1xuICAgICAgICAgICAgICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUlOX0ZJTFRFUiwgZ2wuTkVBUkVTVCk7XG4gICAgICAgICAgICAgICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NQUdfRklMVEVSLCBnbC5ORUFSRVNUKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBkZWZhdWx0IHRvIGxpbmVhciBmb3Igbm9uLXBvd2VyLW9mLTIgdGV4dHVyZXNcbiAgICAgICAgICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01JTl9GSUxURVIsIGdsLkxJTkVBUik7XG4gICAgICAgICAgICAgICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NQUdfRklMVEVSLCBnbC5MSU5FQVIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1dKTtcbiAgICByZXR1cm4gVGV4dHVyZTtcbn0oKTtcblxuVGV4dHVyZS5nZXRNYXhUZXh0dXJlU2l6ZSA9IGZ1bmN0aW9uIChnbCkge1xuICAgIHJldHVybiBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX1RFWFRVUkVfU0laRSk7XG59O1xuXG4vLyBHbG9iYWwgc2V0IG9mIHRleHR1cmVzLCBieSBuYW1lXG5UZXh0dXJlLmFjdGl2ZVVuaXQgPSAtMTtcblxuLypcblRoZSBNSVQgTGljZW5zZSAoTUlUKVxuXG5Db3B5cmlnaHQgKGMpIDIwMTUgUGF0cmljaW8gR29uemFsZXogVml2byAoIGh0dHA6Ly93d3cucGF0cmljaW9nb256YWxlenZpdm8uY29tIClcblxuUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weSBvZlxudGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgJ1NvZnR3YXJlJyksIHRvIGRlYWwgaW5cbnRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG9cbnVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mXG50aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sXG5zdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcblxuVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHR
23459oaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG5jb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgJ0FTIElTJywgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1NcbkZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUlxuQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSXG5JTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTlxuQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cbiovXG5cbnZhciBHbHNsQ2FudmFzID0gZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEdsc2xDYW52YXMoY2FudmFzLCBjb250ZXh0T3B0aW9ucywgb3B0aW9ucykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIGNsYXNzQ2FsbENoZWNrKHRoaXMsIEdsc2xDYW52YXMpO1xuXG4gICAgICAgIHN1YnNjcmliZU1peGluJDEodGhpcyk7XG5cbiAgICAgICAgY29udGV4dE9wdGlvbnMgPSBjb250ZXh0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICAgICAgaWYgKGNhbnZhcy5oYXNBdHRyaWJ1dGUoJ2RhdGEtZnVsbHNjcmVlbicpICYmIChjYW52YXMuZ2V0QXR0cmlidXRlKCdkYXRhLWZ1bGxzY3JlZW4nKSA9PSBcIjFcIiB8fCBjYW52YXMuZ2V0QXR0cmlidXRlKCdkYXRhLWZ1bGxzY3JlZW4nKSA9PSBcInRydWVcIikpIHtcbiAgICAgICAgICAgIHRoaXMud2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuICAgICAgICAgICAgY2FudmFzLndpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XG4gICAgICAgICAgICBjYW52YXMuaGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy53aWR0aCA9IGNhbnZhcy5jbGllbnRXaWR0aDtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gY2FudmFzLmNsaWVudEhlaWdodDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FudmFzID0gY2FudmFzO1xuICAgICAgICB0aGlzLmdsID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmRlcHMgPSB7fTtcbiAgICAgICAgdGhpcy5wcm9ncmFtID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLnRleHR1cmVzID0ge307XG4gICAgICAgIHRoaXMuYnVmZmVycyA9IHt9O1xuICAgICAgICB0aGlzLnVuaWZvcm1zID0ge307XG4gICAgICAgIHRoaXMudmJvID0ge307XG4gICAgICAgIHRoaXMuaXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmFuaW1hdGlvbkZyYW1lUmVxdWVzdCA9IHVuZGVmaW5lZDtcblxuICAgICAgICB0aGlzLkJVRkZFUl9DT1VOVCA9IDA7XG4gICAgICAgIC8vIHRoaXMuVEVYVFVSRV9DT1VOVCA9IDA7XG5cbiAgICAgICAgdGhpcy52ZXJ0ZXhTdHJpbmcgPSBjb250ZXh0T3B0aW9ucy52ZXJ0ZXhTdHJpbmcgfHwgJ1xcbiNpZmRlZiBHTF9FU1xcbnByZWNpc2lvbiBtZWRpdW1wIGZsb2F0O1xcbiNlbmRpZlxcblxcbmF0dHJpYnV0ZSB2ZWMyIGFfcG9zaXRpb247XFxuYXR0cmlidXRlIHZlYzIgYV90ZXhjb29yZDtcXG5cXG52YXJ5aW5nIHZlYzIgdl90ZXhjb29yZDtcXG5cXG52b2lkIG1haW4oKSB7XFxuICAgIGdsX1Bvc2l0aW9uID0gdmVjNChhX3Bvc2l0aW9uLCAwLjAsIDEuMCk7XFxuICAgIHZfdGV4Y29vcmQgPSBhX3RleGNvb3JkO1xcbn1cXG4nO1xuICAgICAgICB0aGlzLmZyYWdtZW50U3RyaW5nID0gY29udGV4dE9wdGlvbnMuZnJhZ21lbnRTdHJpbmcgfHwgJ1xcbiNpZmRlZiBHTF9FU1xcbnByZWNpc2lvbiBtZWRpdW1wIGZsb2F0O1xcbiNlbmRpZlxcblxcbnZhcnlpbmcgdmVjMiB2X3RleGNvb3JkO1xcblxcbnZvaWQgbWFpbigpe1xcbiAgICBnbF9GcmFnQ29sb3IgPSB2ZWM0KDAuMCk7XFxufVxcbic7XG5cbiAgICAgICAgLy8gR0wgQ29udGV4dFxuICAgICAgICB2Y
23459XIgZ2wgPSBzZXR1cFdlYkdMKGNhbnZhcywgY29udGV4dE9wdGlvbnMsIG9wdGlvbnMub25FcnJvcik7XG4gICAgICAgIGlmICghZ2wpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmdsID0gZ2w7XG4gICAgICAgIHRoaXMudGltZUxvYWQgPSB0aGlzLnRpbWVQcmV2ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgICAgIHRoaXMudGltZURlbHRhID0gMC4wO1xuICAgICAgICB0aGlzLmZvcmNlUmVuZGVyID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5wYXVzZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZWFsVG9DU1NQaXhlbHMgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyB8fCAxO1xuXG4gICAgICAgIC8vIEFsbG93IGFscGhhXG4gICAgICAgIGNhbnZhcy5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBjb250ZXh0T3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IgfHwgJ3JnYmEoMSwxLDEsMCknO1xuXG4gICAgICAgIC8vIExvYWQgc2hhZGVyXG4gICAgICAgIGlmIChjYW52YXMuaGFzQXR0cmlidXRlKCdkYXRhLWZyYWdtZW50JykpIHtcbiAgICAgICAgICAgIHRoaXMuZnJhZ21lbnRTdHJpbmcgPSBjYW52YXMuZ2V0QXR0cmlidXRlKCdkYXRhLWZyYWdtZW50Jyk7XG4gICAgICAgIH0gZWxzZSBpZiAoY2FudmFzLmhhc0F0dHJpYnV0ZSgnZGF0YS1mcmFnbWVudC11cmwnKSkge1xuICAgICAgICAgICAgdmFyIHNvdXJjZSA9IGNhbnZhcy5nZXRBdHRyaWJ1dGUoJ2RhdGEtZnJhZ21lbnQtdXJsJyk7XG4gICAgICAgICAgICB4aHIuZ2V0KHNvdXJjZSwgZnVuY3Rpb24gKGVycm9yLCByZXNwb25zZSwgYm9keSkge1xuICAgICAgICAgICAgICAgIF90aGlzLmxvYWQoYm9keSwgX3RoaXMudmVydGV4U3RyaW5nKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTG9hZCBzaGFkZXJcbiAgICAgICAgaWYgKGNhbnZhcy5oYXNBdHRyaWJ1dGUoJ2RhdGEtdmVydGV4JykpIHtcbiAgICAgICAgICAgIHRoaXMudmVydGV4U3RyaW5nID0gY2FudmFzLmdldEF0dHJpYnV0ZSgnZGF0YS12ZXJ0ZXgnKTtcbiAgICAgICAgfSBlbHNlIGlmIChjYW52YXMuaGFzQXR0cmlidXRlKCdkYXRhLXZlcnRleC11cmwnKSkge1xuICAgICAgICAgICAgdmFyIF9zb3VyY2UgPSBjYW52YXMuZ2V0QXR0cmlidXRlKCdkYXRhLXZlcnRleC11cmwnKTtcbiAgICAgICAgICAgIHhoci5nZXQoX3NvdXJjZSwgZnVuY3Rpb24gKGVycm9yLCByZXNwb25zZSwgYm9keSkge1xuICAgICAgICAgICAgICAgIF90aGlzLmxvYWQoX3RoaXMuZnJhZ21lbnRTdHJpbmcsIGJvZHkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmxvYWQoKTtcblxuICAgICAgICBpZiAoIXRoaXMucHJvZ3JhbSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGVmaW5lIFZlcnRleCBidWZmZXJcbiAgICAgICAgdmFyIHRleENvb3Jkc0xvYyA9IGdsLmdldEF0dHJpYkxvY2F0aW9uKHRoaXMucHJvZ3JhbSwgJ2FfdGV4Y29vcmQnKTtcbiAgICAgICAgdGhpcy52Ym8udGV4Q29vcmRzID0gZ2wuY3JlYXRlQnVmZmVyKCk7XG4gICAgICAgIHRoaXMuZ2wuYmluZEJ1ZmZlcihnbC5BUlJBWV9CVUZGRVIsIHRoaXMudmJvLnRleENvb3Jkcyk7XG4gICAgICAgIHRoaXMuZ2wuYnVmZmVyRGF0YShnbC5BUlJBWV9CVUZGRVIsIG5ldyBGbG9hdDMyQXJyYXkoWzAuMCwgMC4wLCAxLjAsIDAuMCwgMC4wLCAxLjAsIDAuMCwgMS4wLCAxLjAsIDAuMCwgMS4wLCAxLjBdKSwgZ2wuU1RBVElDX0RSQVcpO1xuICAgICAgICB0aGlzLmdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHRleENvb3Jkc0xvYyk7XG4gICAgICAgIHRoaXMuZ2wudmVydGV4QXR0cmliUG9pbnRlcih0ZXhDb29yZHNMb2MsIDIsIGdsLkZMT0FULCBmYWxzZSwgMCwgMCk7XG5cbiAgICAgICAgdmFyIHZlcnRpY2VzTG9jID0gZ2wuZ2V0QXR0cmliTG9jYXRpb24odGhpcy5wcm9ncmFtLCAnYV9wb3NpdGlvbicpO1xuICAgICAgICB0aGlzLnZiby52ZXJ0aWNlcyA9IGdsLmNyZWF0ZUJ1ZmZlcigpO1xuICAgICAgICB0aGlzLmdsLmJpbmRCdWZmZXIoZ2wuQVJSQVlfQlVGRkVSLCB0aGlzLnZiby52ZXJ0aWNlcyk7XG4gICAgICAgIHRoaXMuZ2wuYnVmZmVyRGF0YShnbC5BUlJBWV9CVUZGRVIsIG5ldyBGbG9hdDMyQXJyYXkoWy0xLjAsIC0xLjAsIDEuMCwgLTEuMCwgLTEuMCwgMS4wLCAtMS4wLCAxLjAsIDEuMCwgLTEuMCwgMS4wLCAxLjBdKSwgZ2wuU1RBVElDX0RSQVcpO1xuICAgICAgICB0aGlzLmdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHZlcnRpY2VzTG9jKTtcbiAgICAgICAgdGhpcy5nbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHZlcnRpY2VzTG9jLCAyLCBnbC5GTE9BVCwgZmFsc2UsIDAsIDApO1xuXG4gICAgICAgIC8vIGxvYWQgVEVYVFVSRVNcbiAgICAgICAgaWYgKGNhbnZhcy5oYXNBdHRyaWJ1dGUoJ2RhdGEtdGV4dHVyZXMnKSkge1xuICAgICAgICAgICAgdmFyIGltZ0xpc3QgPSBjYW52YXMuZ2V0QXR0cmlidXRlKCdkYXRhLXRleHR1cmVzJykuc3BsaXQoJywnKTtcbiAgICAgICAgICAgIGZvciAodmFyIG5JbWcgaW4gaW1nTGlzdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0VW5pZm9ybSgndV90ZXgnICsgbkltZywgaW1nTGlzdFtuSW1nXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PSBFVkVOVFNcbiAgICAgICAgdmFyIG1vdXNlID0ge1xuICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgIHk6IDBcbiAgICAgICAgfTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIG1vdXNlLnggPSBlLmNsaWVudFggfHwgZS5wYWdlWDtcbiAgICAgICAgICAgIG1vdXNlLnkgPSBlLmNsaWVudFkgfHwgZS5wYWdlWTtcbiAgICAgICAgfSwgZmFsc2UpO1xuXG4gICAgICAgIHZhciBzYW5kYm94ID0gdGhpcztcbiAgICAgICAgZnVuY3Rpb24gUmVuZGVyTG9vcCgpIHtcbiAgICAgICAgICAgIGlmIChzYW5kYm94Lm5Nb3VzZSA+IDEpIHtcbiAgICAgICAgICAgICAgICBzYW5kYm94LnNldE1vdXNlKG1vdXNlKTtcbiAgICAgICAgICAgI
23459H1cblxuICAgICAgICAgICAgaWYgKHNhbmRib3gucmVzaXplKCkpIHtcbiAgICAgICAgICAgICAgICBzYW5kYm94LmZvcmNlUmVuZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2FuZGJveC5yZW5kZXIoKTtcbiAgICAgICAgICAgIHNhbmRib3guYW5pbWF0aW9uRnJhbWVSZXF1ZXN0ID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShSZW5kZXJMb29wKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0YXJ0XG4gICAgICAgIHRoaXMuc2V0TW91c2UoeyB4OiAwLCB5OiAwIH0pO1xuICAgICAgICBSZW5kZXJMb29wKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGNyZWF0ZUNsYXNzKEdsc2xDYW52YXMsIFt7XG4gICAgICAgIGtleTogJ2Rlc3Ryb3knLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICAgICAgICAgIC8vIFN0b3AgdGhlIGFuaW1hdGlvblxuICAgICAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5hbmltYXRpb25GcmFtZVJlcXVlc3QpO1xuXG4gICAgICAgICAgICB0aGlzLmFuaW1hdGVkID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmlzVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGZvciAodmFyIHRleCBpbiB0aGlzLnRleHR1cmVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRleC5kZXN0cm95KSB7XG4gICAgICAgICAgICAgICAgICAgIHRleC5kZXN0cm95KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy50ZXh0dXJlcyA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgYXR0IGluIHRoaXMuYXR0cmlicykge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2wuZGVsZXRlQnVmZmVyKHRoaXMuYXR0cmlic1thdHRdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZ2wudXNlUHJvZ3JhbShudWxsKTtcbiAgICAgICAgICAgIHRoaXMuZ2wuZGVsZXRlUHJvZ3JhbSh0aGlzLnByb2dyYW0pO1xuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHRoaXMuYnVmZmVycykge1xuICAgICAgICAgICAgICAgIHZhciBidWZmZXIgPSB0aGlzLmJ1ZmZlcnNba2V5XTtcbiAgICAgICAgICAgICAgICB0aGlzLmdsLmRlbGV0ZVByb2dyYW0oYnVmZmVyLnByb2dyYW0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnByb2dyYW0gPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5nbCA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2xvYWQnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gbG9hZChmcmFnU3RyaW5nLCB2ZXJ0U3RyaW5nKSB7XG4gICAgICAgICAgICB2Y
23459XIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICAgICAgLy8gTG9hZCB2ZXJ0ZXggc2hhZGVyIGlmIHRoZXJlIGlzIG9uZVxuICAgICAgICAgICAgaWYgKHZlcnRTdHJpbmcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZlcnRleFN0cmluZyA9IHZlcnRTdHJpbmc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIExvYWQgZnJhZ21lbnQgc2hhZGVyIGlmIHRoZXJlIGlzIG9uZVxuICAgICAgICAgICAgaWYgKGZyYWdTdHJpbmcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZyYWdtZW50U3RyaW5nID0gZnJhZ1N0cmluZztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGxpbmVzID0gdGhpcy5mcmFnbWVudFN0cmluZy5zcGxpdCgvXFxyP1xcbi8pO1xuICAgICAgICAgICAgdGhpcy5mcmFnbWVudFN0cmluZyA9IFwiI2RlZmluZSBQTEFURk9STV9XRUJHTFxcbiNsaW5lIDBcXG5cIjtcblxuICAgICAgICAgICAgbGluZXMuZm9yRWFjaChmdW5jdGlvbiAobGluZSwgaSkge1xuICAgICAgICAgICAgICAgIHZhciBsaW5lX3RyaW0gPSBsaW5lLnRyaW0oKTtcbiAgICAgICAgICAgICAgICBpZiAobGluZV90cmltLnN0YXJ0c1dpdGgoJyNpbmNsdWRlIFxcXCJseWdpYScpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBkZXAgPSBsaW5lX3RyaW0uc3Vic3RyaW5nKDE1KS5yZXBsYWNlKC9cXCd8XFxcInxcXDt8XFxzL2csICcnKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlcC5lbmRzV2l0aCgnZ2xzbCcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMyLmRlcHNbZGVwXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHVybCA9IFwiaHR0cHM6Ly9seWdpYS54eXpcIiArIGRlcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIuZGVwc1tkZXBdID0gZ2V0RmlsZSh1cmwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLmZyYWdtZW50U3RyaW5nICs9IF90aGlzMi5kZXBzW2RlcF0gKyAnXFxuI2xpbmUgJyArIChpICsgMSkgKyAnXFxuJztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBfdGhpczIuZnJhZ21lbnRTdHJpbmcgKz0gbGluZSArICdcXG4nO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuZnJhZ21lbnRTdHJpbmcpO1xuXG4gICAgICAgICAgICB0aGlzLmFuaW1hdGVkID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLm5EZWx0YSA9ICh0aGlzLmZyYWdtZW50U3RyaW5nLm1hdGNoKC91X2RlbHRhL2cpIHx8IFtdKS5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLm5UaW1lID0gKHRoaXMuZnJhZ21lbnRTdHJpbmcubWF0Y2goL3VfdGltZS9nKSB8fCBbXSkubGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5uRGF0ZSA9ICh0aGlzLmZyYWdtZW50U3RyaW5nLm1hdGNoKC91X2RhdGUvZykgfHwgW10pLmxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMubk1vdXNlID0gKHRoaXMuZnJhZ21lbnRTdHJpbmcubWF0Y2goL3VfbW91c2UvZykgfHwgW10pLmxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMuYW5pbWF0ZWQgPSB0aGlzLm5EYXRlID4gMSB8fCB0aGlzLm5UaW1lID4gMSB8fCB0aGlzLm5Nb3VzZSA+IDE7XG5cbiAgICAgICAgICAgIHZhciBuVGV4dHVyZXMgPSB0aGlzLmZyYWdtZW50U3RyaW5nLnNlYXJjaCgvc2FtcGxlcjJEL2cpO1xuICAgICAgICAgICAgaWYgKG5UZXh0dXJlcykge1xuICAgICAgICAgICAgICAgIHZhciBfbGluZXMgPSB0aGlzLmZyYWdtZW50U3RyaW5nLnNwbGl0KCdcXG4nKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IF9saW5lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB2Y
23459XIgbWF0Y2ggPSBfbGluZXNbaV0ubWF0Y2goL3VuaWZvcm1cXHMqc2FtcGxlcjJEXFxzKihbXFx3XSopO1xccypcXC9cXC9cXHMqKFtcXHd8XFw6XFwvXFwvfFxcLnxcXC18XFxfXSopL2kpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHQgPSBtYXRjaFsyXS5zcGxpdCgnLicpLnBvcCgpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2hbMV0gJiYgbWF0Y2hbMl0gJiYgKGV4dCA9PT0gJ2pwZycgfHwgZXh0ID09PSAnanBlZycgfHwgZXh0ID09PSAncG5nJyB8fCBleHQgPT09ICdvZ3YnIHx8IGV4dCA9PT0gJ3dlYm0nIHx8IGV4dCA9PT0gJ21wNCcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRVbmlmb3JtKG1hdGNoWzFdLCBtYXRjaFsyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIG1haW4gPSBfbGluZXNbaV0ubWF0Y2goL1xccyp2b2lkXFxzKm1haW5cXHMqL2cpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobWFpbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB2ZXJ0ZXhTaGFkZXIgPSBjcmVhdGVTaGFkZXIodGhpcywgdGhpcy52ZXJ0ZXhTdHJpbmcsIHRoaXMuZ2wuVkVSVEVYX1NIQURFUik7XG4gICAgICAgICAgICB2Y
23459XIgZnJhZ21lbnRTaGFkZXIgPSBjcmVhdGVTaGFkZXIodGhpcywgdGhpcy5mcmFnbWVudFN0cmluZywgdGhpcy5nbC5GUkFHTUVOVF9TSEFERVIpO1xuXG4gICAgICAgICAgICAvLyBJZiBGcmFnbWVudCBzaGFkZXIgZmFpbHMgbG9hZCBhIGVtcHR5IG9uZSB0byBzaWduIHRoZSBlcnJvclxuICAgICAgICAgICAgaWYgKCFmcmFnbWVudFNoYWRlcikge1xuICAgICAgICAgICAgICAgIGZyYWdtZW50U2hhZGVyID0gY3JlYXRlU2hhZGVyKHRoaXMsICd2b2lkIG1haW4oKXtcXG5cXHRnbF9GcmFnQ29sb3IgPSB2ZWM0KDEuMCk7XFxufScsIHRoaXMuZ2wuRlJBR01FTlRfU0hBREVSKTtcbiAgICAgICAgICAgICAgICB0aGlzLmlzVmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pc1ZhbGlkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ3JlYXRlIGFuZCB1c2UgcHJvZ3JhbVxuICAgICAgICAgICAgdmFyIHByb2dyYW0gPSBjcmVhdGVQcm9ncmFtKHRoaXMsIFt2ZXJ0ZXhTaGFkZXIsIGZyYWdtZW50U2hhZGVyXSk7IC8vLCBbMCwxXSxbJ2FfdGV4Y29vcmQnLCdhX3Bvc2l0aW9uJ10pO1xuICAgICAgICAgICAgdGhpcy5nbC51c2VQcm9ncmFtKHByb2dyYW0pO1xuXG4gICAgICAgICAgICAvLyBEZWxldGUgc2hhZGVyc1xuICAgICAgICAgICAgLy8gdGhpcy5nbC5kZXRhY2hTaGFkZXIocHJvZ3JhbSwgdmVydGV4U2hhZGVyKTtcbiAgICAgICAgICAgIC8vIHRoaXMuZ2wuZGV0YWNoU2hhZGVyKHByb2dyYW0sIGZyYWdtZW50U2hhZGVyKTtcbiAgICAgICAgICAgIHRoaXMuZ2wuZGVsZXRlU2hhZGVyKHZlcnRleFNoYWRlcik7XG4gICAgICAgICAgICB0aGlzLmdsLmRlbGV0ZVNoYWRlcihmcmFnbWVudFNoYWRlcik7XG5cbiAgICAgICAgICAgIHRoaXMucHJvZ3JhbSA9IHByb2dyYW07XG4gICAgICAgICAgICB0aGlzLmNoYW5nZSA9IHRydWU7XG5cbiAgICAgICAgICAgIHRoaXMuQlVGRkVSX0NPVU5UID0gMDtcbiAgICAgICAgICAgIHZhciBidWZmZXJzID0gdGhpcy5nZXRCdWZmZXJzKHRoaXMuZnJhZ21lbnRTdHJpbmcpO1xuICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKGJ1ZmZlcnMpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZFByb2dyYW1zKGJ1ZmZlcnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5idWZmZXJzID0gYnVmZmVycztcbiAgICAgICAgICAgIHRoaXMudGV4dXJlSW5kZXggPSB0aGlzLkJVRkZFUl9DT1VOVDtcblxuICAgICAgICAgICAgLy8gVHJpZ2dlciBldmVudFxuICAgICAgICAgICAgdGhpcy50cmlnZ2VyKCdsb2FkJywge30pO1xuXG4gICAgICAgICAgICB0aGlzLmZvcmNlUmVuZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3Rlc3QnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdGVzdChjYWxsYmFjaywgZnJhZ1N0cmluZywgdmVydFN0cmluZykge1xuICAgICAgICAgICAgLy8gVGhhbmtzIHRvIEB0aGVzcGl0ZSBmb3IgdGhlIGhlbHAgaGVyZVxuICAgICAgICAgICAgLy8gaHR0cHM6Ly93d3cua2hyb25vcy5vcmcvcmVnaXN0cnkvd2ViZ2wvZXh0ZW5zaW9ucy9FWFRfZGlzam9pbnRfdGltZXJfcXVlcnkvXG4gICAgICAgICAgICB2Y
23459XIgcHJlX3Rlc3RfdmVydCA9IHRoaXMudmVydGV4U3RyaW5nO1xuICAgICAgICAgICAgdmFyIHByZV90ZXN0X2ZyYWcgPSB0aGlzLmZyYWdtZW50U3RyaW5nO1xuICAgICAgICAgICAgdmFyIHByZV90ZXN0X3BhdXNlZCA9IHRoaXMucGF1c2VkO1xuXG4gICAgICAgICAgICB2YXIgZXh0ID0gdGhpcy5nbC5nZXRFeHRlbnNpb24oJ0VYVF9kaXNqb2ludF90aW1lcl9xdWVyeScpO1xuICAgICAgICAgICAgdmFyIHF1ZXJ5ID0gZXh0LmNyZWF0ZVF1ZXJ5RVhUKCk7XG4gICAgICAgICAgICB2YXIgd2FzVmFsaWQgPSB0aGlzLmlzVmFsaWQ7XG5cbiAgICAgICAgICAgIGlmIChmcmFnU3RyaW5nIHx8IHZlcnRTdHJpbmcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWQoZnJhZ1N0cmluZywgdmVydFN0cmluZyk7XG4gICAgICAgICAgICAgICAgd2FzVmFsaWQgPSB0aGlzLmlzVmFsaWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JjZVJlbmRlciA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5wYXVzZWQgPSB0cnVlO1xuICAgICAgICAgICAgZXh0LmJlZ2luUXVlcnlFWFQoZXh0LlRJTUVfRUxBUFNFRF9FWFQsIHF1ZXJ5KTtcbiAgICAgICAgICAgIHRoaXMuZm9yY2VSZW5kZXIgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgICAgIGV4dC5lbmRRdWVyeUVYVChleHQuVElNRV9FTEFQU0VEX0VYVCk7XG5cbiAgICAgICAgICAgIHZhciBzYW5kYm94ID0gdGhpcztcbiAgICAgICAgICAgIGZ1bmN0aW9uIGZpbmlzaFRlc3QoKSB7XG4gICAgICAgICAgICAgICAgLy8gUmV2ZXJ0IGNoYW5nZXMuLi4gZ28gYmFjayB0byBub3JtYWxcbiAgICAgICAgICAgICAgICBzYW5kYm94LnBhdXNlZCA9IHByZV90ZXN0X3BhdXNlZDtcbiAgICAgICAgICAgICAgICBpZiAoZnJhZ1N0cmluZyB8fCB2ZXJ0U3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIHNhbmRib3gubG9hZChwcmVfdGVzdF9mcmFnLCBwcmVfdGVzdF92ZXJ0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmdW5jdGlvbiB3YWl0Rm9yVGVzdCgpIHtcbiAgICAgICAgICAgICAgICBzYW5kYm94LmZvcmNlUmVuZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBzYW5kYm94LnJlbmRlcigpO1xuICAgICAgICAgICAgICAgIHZhciBhdmFpbGFibGUgPSBleHQuZ2V0UXVlcnlPYmplY3RFWFQocXVlcnksIGV4dC5RVUVSWV9SRVNVTFRfQVZBSUxBQkxFX0VYVCk7XG4gICAgICAgICAgICAgICAgdmFyIGRpc2pvaW50ID0gc2FuZGJveC5nbC5nZXRQYXJhbWV0ZXIoZXh0LkdQVV9ESVNKT0lOVF9FWFQpO1xuICAgICAgICAgICAgICAgIGlmIChhdmFpbGFibGUgJiYgIWRpc2pvaW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXQgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3YXNWYWxpZDogd2FzVmFsaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBmcmFnOiBmcmFnU3RyaW5nIHx8IHNhbmRib3guZnJhZ21lbnRTdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJ0OiB2ZXJ0U3RyaW5nIHx8IHNhbmRib3gudmVydGV4U3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZUVsYXBzZWRNczogZXh0LmdldFF1ZXJ5T2JqZWN0RVhUKHF1ZXJ5LCBleHQuUVVFUllfUkVTVUxUX0VYVCkgLyAxMDAwMDAwLjBcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgZmluaXNoVGVzdCgpO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhyZXQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUod2FpdEZvclRlc3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHdhaXRGb3JUZXN0KCk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2xvYWRUZXh0dXJlJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGxvYWRUZXh0dXJlKG5hbWUsIHVybEVsZW1lbnRPckRhdGEsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdXJsRWxlbWVudE9yRGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLnVybCA9IHVybEVsZW1lbnRPckRhdGE7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCh0eXBlb2YgdXJsRWxlbWVudE9yRGF0YSA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YodXJsRWxlbWVudE9yRGF0YSkpID09PSAnb2JqZWN0JyAmJiB1cmxFbGVtZW50T3JEYXRhLmRhdGEgJiYgdXJsRWxlbWVudE9yRGF0YS53aWR0aCAmJi
23459B1cmxFbGVtZW50T3JEYXRhLmhlaWdodCkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuZGF0YSA9IHVybEVsZW1lbnRPckRhdGEuZGF0YTtcbiAgICAgICAgICAgICAgICBvcHRpb25zLndpZHRoID0gdXJsRWxlbWVudE9yRGF0YS53aWR0aDtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmhlaWdodCA9IHVybEVsZW1lbnRPckRhdGEuaGVpZ2h0O1xuICAgICAgICAgICAgfSBlbHNlIGlmICgodHlwZW9mIHVybEVsZW1lbnRPckRhdGEgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHVybEVsZW1lbnRPckRhdGEpKSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmVsZW1lbnQgPSB1cmxFbGVtZW50T3JEYXRhO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy50ZXh0dXJlc1tuYW1lXSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRleHR1cmVzW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZXNbbmFtZV0ubG9hZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50ZXh0dXJlc1tuYW1lXS5vbignbG9hZGVkJywgZnVuY3Rpb24gKGFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMy5mb3JjZVJlbmRlciA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy50ZXh0dXJlc1tuYW1lXSA9IG5ldyBUZXh0dXJlKHRoaXMuZ2wsIG5hbWUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIHRoaXMudGV4dHVyZXNbbmFtZV0ub24oJ2xvYWRlZCcsIGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzMy5mb3JjZVJlbmRlciA9IHRydWU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3JlZnJlc2hVbmlmb3JtcycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZWZyZXNoVW5pZm9ybXMoKSB7XG4gICAgICAgICAgICB0aGlzLnVuaWZvcm1zID0ge307XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3NldFVuaWZvcm0nLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gc2V0VW5pZm9ybShuYW1lKSB7XG4gICAgICAgICAgICB2Y
23459XIgdSA9IHt9O1xuXG4gICAgICAgICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgdmFsdWUgPSBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICAgICAgICAgICAgdmFsdWVbX2tleSAtIDFdID0gYXJndW1lbnRzW19rZXldO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB1W25hbWVdID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLnNldFVuaWZvcm1zKHUpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdzZXRVbmlmb3JtcycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRVbmlmb3Jtcyh1bmlmb3Jtcykge1xuICAgICAgICAgICAgdmFyIHBhcnNlZCA9IHBhcnNlVW5pZm9ybXModW5pZm9ybXMpO1xuICAgICAgICAgICAgLy8gU2V0IGVhY2ggdW5pZm9ybVxuICAgICAgICAgICAgZm9yICh2YXIgdSBpbiBwYXJzZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAocGFyc2VkW3VdLnR5cGUgPT09ICdzYW1wbGVyMkQnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEZvciB0ZXh0dXJlcywgd2UgbmVlZCB0byB0cmFjayB0ZXh0dXJlIHVuaXRzLCBzbyB3ZSBoYXZlIGEgc3BlY2lhbCBzZXR0ZXJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy51bmlmb3JtVGV4dHVyZShwYXJzZWRbdV0ubmFtZSwgcGFyc2VkW3VdLnZhbHVlWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkVGV4dHVyZShwYXJzZWRbdV0ubmFtZSwgcGFyc2VkW3VdLnZhbHVlWzBdKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVuaWZvcm0ocGFyc2VkW3VdLm1ldGhvZCwgcGFyc2VkW3VdLnR5cGUsIHBhcnNlZFt1XS5uYW1lLCBwYXJzZWRbdV0udmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZm9yY2VSZW5kZXIgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdzZXRNb3VzZScsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRNb3VzZShtb3VzZSkge1xuICAgICAgICAgICAgLy8gc2V0IHRoZSBtb3VzZSB1bmlmb3JtXG4gICAgICAgICAgICB2Y
23459XIgcmVjdCA9IHRoaXMuY2FudmFzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgaWYgKG1vdXNlICYmIG1vdXNlLnggJiYgbW91c2UueCA+PSByZWN0LmxlZnQgJiYgbW91c2UueCA8PSByZWN0LnJpZ2h0ICYmIG1vdXNlLnkgJiYgbW91c2UueSA+PSByZWN0LnRvcCAmJiBtb3VzZS55IDw9IHJlY3QuYm90dG9tKSB7XG5cbiAgICAgICAgICAgICAgICB2YXIgbW91c2VfeCA9IChtb3VzZS54IC0gcmVjdC5sZWZ0KSAqIHRoaXMucmVhbFRvQ1NTUGl4ZWxzO1xuICAgICAgICAgICAgICAgIHZhciBtb3VzZV95ID0gdGhpcy5jYW52YXMuaGVpZ2h0IC0gKG1vdXNlLnkgLSByZWN0LnRvcCkgKiB0aGlzLnJlYWxUb0NTU1BpeGVscztcblxuICAgICAgICAgICAgICAgIHRoaXMudW5pZm9ybSgnMmYnLCAndmVjMicsICd1X21vdXNlJywgbW91c2VfeCwgbW91c2VfeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBleDogcHJvZ3JhbS51bmlmb3JtKCczZicsICdwb3NpdGlvbicsIHgsIHksIHopO1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICd1bmlmb3JtJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHVuaWZvcm0obWV0aG9kLCB0eXBlLCBuYW1lKSB7XG4gICAgICAgICAgICAvLyAndmFsdWUnIGlzIGEgbWV0aG9kLWFwcHJvcHJpYXRlIGFyZ3VtZW50cyBsaXN0XG4gICAgICAgICAgICB0aGlzLnVuaWZvcm1zW25hbWVdID0gdGhpcy51bmlmb3Jtc1tuYW1lXSB8fCB7fTtcbiAgICAgICAgICAgIHZhciB1bmlmb3JtID0gdGhpcy51bmlmb3Jtc1tuYW1lXTtcblxuICAgICAgICAgICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCB2YWx1ZSA9IEFycmF5KF9sZW4yID4gMyA/IF9sZW4yIC0gMyA6IDApLCBfa2V5MiA9IDM7IF9rZXkyIDwgX2xlbjI7IF9rZXkyKyspIHtcbiAgICAgICAgICAgICAgICB2YWx1ZVtfa2V5MiAtIDNdID0gYXJndW1lbnRzW19rZXkyXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGNoYW5nZSA9IGlzRGlmZih1bmlmb3JtLnZhbHVlLCB2YWx1ZSk7XG5cbiAgICAgICAgICAgIC8vIHJlbWVtYmVyIGFuZCBrZWVwIHRyYWNrIG9mIHVuaWZvcm1zIGxvY2F0aW9uIHRvIHNhdmUgY2FsbHNcbiAgICAgICAgICAgIGlmIChjaGFuZ2UgfHwgdGhpcy5jaGFuZ2UgfHwgIXVuaWZvcm0ubG9jYXRpb24gfHwgIXVuaWZvcm0udmFsdWUpIHtcbiAgICAgICAgICAgICAgICB1bmlmb3JtLm5hbWUgPSBuYW1lO1xuICAgICAgICAgICAgICAgIHVuaWZvcm0udHlwZSA9IHR5cGU7XG4gICAgICAgICAgICAgICAgdW5pZm9ybS52YWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHVuaWZvcm0ubWV0aG9kID0gJ3VuaWZvcm0nICsgbWV0aG9kO1xuICAgICAgICAgICAgICAgIHRoaXMuZ2wudXNlUHJvZ3JhbSh0aGlzLnByb2dyYW0pO1xuICAgICAgICAgICAgICAgIHVuaWZvcm0ubG9jYXRpb24gPSB0aGlzLmdsLmdldFVuaWZvcm1Mb2NhdGlvbih0aGlzLnByb2dyYW0sIG5hbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuZ2xbdW5pZm9ybS5tZXRob2RdLmFwcGx5KHRoaXMuZ2wsIFt1bmlmb3JtLmxvY2F0aW9uXS5jb25jYXQodW5pZm9ybS52YWx1ZSkpO1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIGNoYW5nZSB1cGRhdGUgYW5kIHRoZXJlIGlzIGJ1ZmZlciB1cGRhdGUgbWFudWFsbHkgb25lIGJ5IG9uZVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiB0aGlzLmJ1ZmZlcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJ1ZmZlciA9IHRoaXMuYnVmZmVyc1trZXldO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmdsLnVzZVByb2dyYW0oYnVmZmVyLnByb2dyYW0pO1xuICAgICAgICAgICAgICAgICAgICB2Y
23459XIgbG9jYXRpb24gPSB0aGlzLmdsLmdldFVuaWZvcm1Mb2NhdGlvbihidWZmZXIucHJvZ3JhbSwgbmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2xbdW5pZm9ybS5tZXRob2RdLmFwcGx5KHRoaXMuZ2wsIFtsb2NhdGlvbl0uY29uY2F0KHVuaWZvcm0udmFsdWUpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3VuaWZvcm1UZXh0dXJlJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHVuaWZvcm1UZXh0dXJlKG5hbWUsIHRleHR1cmUsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRleHR1cmVzW25hbWVdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRUZXh0dXJlKG5hbWUsIHRleHR1cmUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVuaWZvcm0oJzFpJywgJ3NhbXBsZXIyRCcsIG5hbWUsIHRoaXMudGV4dXJlSW5kZXgpO1xuXG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHRoaXMuYnVmZmVycykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgYnVmZmVyID0gdGhpcy5idWZmZXJzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2wudXNlUHJvZ3JhbShidWZmZXIucHJvZ3JhbSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2wuYWN0aXZlVGV4dHVyZSh0aGlzLmdsLlRFWFRVUkUwICsgdGhpcy50ZXh1cmVJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2wuYmluZFRleHR1cmUodGhpcy5nbC5URVhUVVJFXzJELCB0aGlzLnRleHR1cmVzW25hbWVdLnRleHR1cmUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmdsLnVzZVByb2dyYW0odGhpcy5wcm9ncmFtKTtcbiAgICAgICAgICAgICAgICB0aGlzLmdsLmFjdGl2ZVRleHR1cmUodGhpcy5nbC5URVhUVVJFMCArIHRoaXMudGV4dXJlSW5kZXgpO1xuICAgICAgICAgICAgICAgIHRoaXMuZ2wuYmluZFRleHR1cmUodGhpcy5nbC5URVhUVVJFXzJELCB0aGlzLnRleHR1cmVzW25hbWVdLnRleHR1cmUpO1xuICAgICAgICAgICAgICAgIHRoaXMudW5pZm9ybSgnMmYnLCAndmVjMicsIG5hbWUgKyAnUmVzb2x1dGlvbicsIHRoaXMudGV4dHVyZXNbbmFtZV0ud2lkdGgsIHRoaXMudGV4dHVyZXNbbmFtZV0uaGVpZ2h0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAncmVzaXplJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlc2l6ZSgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLndpZHRoICE9PSB0aGlzLmNhbnZhcy5jbGllbnRXaWR0aCB8fCB0aGlzLmhlaWdodCAhPT0gdGhpcy5jYW52YXMuY2xpZW50SGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWFsVG9DU1NQaXhlbHMgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyB8fCAxO1xuXG4gICAgICAgICAgICAgICAgLy8gTG9va3VwIHRoZSBzaXplIHRoZSBicm93c2VyIGlzIGRpc3BsYXlpbmcgdGhlIGNhbnZhcyBpbiBDU1MgcGl4ZWxzXG4gICAgICAgICAgICAgICAgLy8gYW5kIGNvbXB1dGUgYSBzaXplIG5lZWRlZCB0byBtYWtlIG91ciBkcmF3aW5nYnVmZmVyIG1hdGNoIGl0IGluXG4gICAgICAgICAgICAgICAgLy8gZGV2aWNlIHBpeGVscy5cbiAgICAgICAgICAgICAgICB2Y
23459XIgZGlzcGxheVdpZHRoID0gTWF0aC5mbG9vcih0aGlzLmdsLmNhbnZhcy5jbGllbnRXaWR0aCAqIHRoaXMucmVhbFRvQ1NTUGl4ZWxzKTtcbiAgICAgICAgICAgICAgICB2YXIgZGlzcGxheUhlaWdodCA9IE1hdGguZmxvb3IodGhpcy5nbC5jYW52YXMuY2xpZW50SGVpZ2h0ICogdGhpcy5yZWFsVG9DU1NQaXhlbHMpO1xuXG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGNhbnZhcyBpcyBub3QgdGhlIHNhbWUgc2l6ZS5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5nbC5jYW52YXMud2lkdGggIT09IGRpc3BsYXlXaWR0aCB8fCB0aGlzLmdsLmNhbnZhcy5oZWlnaHQgIT09IGRpc3BsYXlIZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTWFrZSB0aGUgY2FudmFzIHRoZSBzYW1lIHNpemVcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nbC5jYW52YXMud2lkdGggPSBkaXNwbGF5V2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2wuY2FudmFzLmhlaWdodCA9IGRpc3BsYXlIZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgdmlld3BvcnQgdG8gbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nbC52aWV3cG9ydCgwLCAwLCB0aGlzLmdsLmNhbnZhcy53aWR0aCwgdGhpcy5nbC5jYW52YXMuaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy53aWR0aCA9IHRoaXMuY2FudmFzLmNsaWVudFdpZHRoO1xuICAgICAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5jYW52YXMuY2xpZW50SGVpZ2h0O1xuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplU3dhcHBhYmxlQnVmZmVycygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3JlbmRlcicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgICAgICB0aGlzLnZpc2libGUgPSBpc0NhbnZhc1Zpc2libGUodGhpcy5jYW52YXMpO1xuICAgICAgICAgICAgaWYgKHRoaXMuZm9yY2VSZW5kZXIgfHwgdGhpcy5jaGFuZ2UgfHwgdGhpcy5hbmltYXRlZCAmJiB0aGlzLnZpc2libGUgJiYgIXRoaXMucGF1c2VkKSB7XG5cbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgVW5pZm9ybXMgd2hlbiBhcmUgbmVlZFxuICAgICAgICAgICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUoKTtcbiAgICAgICAgICAgICAgICB2Y
23459XIgbm93ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgICAgICAgICAgICAgdGhpcy50aW1lRGVsdGEgPSAobm93IC0gdGhpcy50aW1lUHJldikgLyAxMDAwLjA7XG4gICAgICAgICAgICAgICAgdGhpcy50aW1lUHJldiA9IG5vdztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5uRGVsdGEgPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNldCB0aGUgZGVsdGEgdGltZSB1bmlmb3JtXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudW5pZm9ybSgnMWYnLCAnZmxvYXQnLCAndV9kZWx0YScsIHRoaXMudGltZURlbHRhKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5uVGltZSA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc2V0IHRoZSBlbGFwc2VkIHRpbWUgdW5pZm9ybVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVuaWZvcm0oJzFmJywgJ2Zsb2F0JywgJ3VfdGltZScsIChub3cgLSB0aGlzLnRpbWVMb2FkKSAvIDEwMDAuMCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubkRhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2V0IGRhdGUgdW5pZm9ybTogeWVhci9tb250aC9kYXkvdGltZV9pbl9zZWNcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51bmlmb3JtKCc0ZicsICdmbG9hdCcsICd1X2RhdGUnLCBkYXRlLmdldEZ1bGxZZWFyKCksIGRhdGUuZ2V0TW9udGgoKSwgZGF0ZS5nZXREYXRlKCksIGRhdGUuZ2V0SG91cnMoKSAqIDM2MDAgKyBkYXRlLmdldE1pbnV0ZXMoKSAqIDYwICsgZGF0ZS5nZXRTZWNvbmRzKCkgKyBkYXRlLmdldE1pbGxpc2Vjb25kcygpICogMC4wMDEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIHNldCB0aGUgcmVzb2x1dGlvbiB1bmlmb3JtXG4gICAgICAgICAgICAgICAgdGhpcy51bmlmb3JtKCcyZicsICd2ZWMyJywgJ3VfcmVzb2x1dGlvbicsIHRoaXMuY2FudmFzLndpZHRoLCB0aGlzLmNhbnZhcy5oZWlnaHQpO1xuXG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHRoaXMuYnVmZmVycykge1xuICAgICAgICAgICAgICAgICAgICB2Y
23459XIgYnVmZmVyID0gdGhpcy5idWZmZXJzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudW5pZm9ybSgnMWknLCAnc2FtcGxlcjJEJywgYnVmZmVyLm5hbWUsIGJ1ZmZlci5idW5kbGUuaW5wdXQuaW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMudGV4dXJlSW5kZXggPSB0aGlzLkJVRkZFUl9DT1VOVDtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciB0ZXggaW4gdGhpcy50ZXh0dXJlcykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVuaWZvcm1UZXh0dXJlKHRleCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudGV4dXJlSW5kZXgrKztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlclByb2dyYW1zKCk7XG5cbiAgICAgICAgICAgICAgICAvLyBUcmlnZ2VyIGV2ZW50XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyKCdyZW5kZXInLCB7fSk7XG4gICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2UgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLmZvcmNlUmVuZGVyID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3BhdXNlJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHBhdXNlKCkge1xuICAgICAgICAgICAgdGhpcy5wYXVzZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdwbGF5JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHBsYXkoKSB7XG4gICAgICAgICAgICB0aGlzLnBhdXNlZCA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVuZGVyIG1haW4gYW5kIGJ1ZmZlcnMgcHJvZ3JhbXNcblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAncmVuZGVyUHJvZ3JhbXMnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyUHJvZ3JhbXMoKSB7XG4gICAgICAgICAgICB2Y
23459XIgZ2wgPSB0aGlzLmdsO1xuICAgICAgICAgICAgdmFyIFcgPSBnbC5jYW52YXMud2lkdGg7XG4gICAgICAgICAgICB2YXIgSCA9IGdsLmNhbnZhcy5oZWlnaHQ7XG5cbiAgICAgICAgICAgIGdsLnZpZXdwb3J0KDAsIDAsIFcsIEgpO1xuXG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gdGhpcy5idWZmZXJzKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJ1ZmZlciA9IHRoaXMuYnVmZmVyc1trZXldO1xuICAgICAgICAgICAgICAgIGJ1ZmZlci5idW5kbGUucmVuZGVyKFcsIEgsIGJ1ZmZlci5wcm9ncmFtLCBidWZmZXIubmFtZSk7XG4gICAgICAgICAgICAgICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBudWxsKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZ2wudXNlUHJvZ3JhbSh0aGlzLnByb2dyYW0pO1xuICAgICAgICAgICAgZ2wuZHJhd0FycmF5cyhnbC5UUklBTkdMRVMsIDAsIDYpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcGFyc2UgaW5wdXQgc3RyaW5nc1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICdnZXRCdWZmZXJzJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldEJ1ZmZlcnMoZnJhZ1N0cmluZykge1xuICAgICAgICAgICAgdmFyIGJ1ZmZlcnMgPSB7fTtcbiAgICAgICAgICAgIGlmIChmcmFnU3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgZnJhZ1N0cmluZy5yZXBsYWNlKC8oPzpeXFxzKikoKD86I2lmfCNlbGlmKSg/OlxccyopKGRlZmluZWRcXHMqXFwoXFxzKkJVRkZFUl8pKFxcZCspKD86XFxzKlxcKSl8KD86I2lmZGVmKSg/OlxccypCVUZGRVJfKShcXGQrKSg/OlxccyopKS9nbSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB2Y
23459XIgaSA9IGFyZ3VtZW50c1szXSB8fCBhcmd1bWVudHNbNF07XG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcnNbJ3VfYnVmZmVyJyArIGldID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZnJhZ21lbnQ6ICcjZGVmaW5lIEJVRkZFUl8nICsgaSArICdcXG4nICsgZnJhZ1N0cmluZ1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcnM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBsb2FkIGJ1ZmZlcnMgcHJvZ3JhbXNcblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnbG9hZFByb2dyYW1zJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGxvYWRQcm9ncmFtcyhidWZmZXJzKSB7XG4gICAgICAgICAgICB2YXIgZ2xzbCA9IHRoaXM7XG4gICAgICAgICAgICB2YXIgZ2wgPSB0aGlzLmdsO1xuICAgICAgICAgICAgdmFyIHZlcnRleCA9IGNyZWF0ZVNoYWRlcihnbHNsLCBnbHNsLnZlcnRleFN0cmluZywgZ2wuVkVSVEVYX1NIQURFUik7XG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gYnVmZmVycykge1xuICAgICAgICAgICAgICAgIHZhciBidWZmZXIgPSBidWZmZXJzW2tleV07XG4gICAgICAgICAgICAgICAgdmFyIGZyYWdtZW50ID0gY3JlYXRlU2hhZGVyKGdsc2wsIGJ1ZmZlci5mcmFnbWVudCwgZ2wuRlJBR01FTlRfU0hBREVSLCAxKTtcbiAgICAgICAgICAgICAgICBpZiAoIWZyYWdtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGZyYWdtZW50ID0gY3JlYXRlU2hhZGVyKGdsc2wsICd2b2lkIG1haW4oKXtcXG5cXHRnbF9GcmFnQ29sb3IgPSB2ZWM0KDEuMCk7XFxufScsIGdsLkZSQUdNRU5UX1NIQURFUik7XG4gICAgICAgICAgICAgICAgICAgIGdsc2wuaXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGdsc2wuaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhciBwcm9ncmFtID0gY3JlYXRlUHJvZ3JhbShnbHNsLCBbdmVydGV4LCBmcmFnbWVudF0pO1xuICAgICAgICAgICAgICAgIGJ1ZmZlci5uYW1lID0ga2V5O1xuICAgICAgICAgICAgICAgIGJ1ZmZlci5wcm9ncmFtID0gcHJvZ3JhbTtcbiAgICAgICAgICAgICAgICBidWZmZXIuYnVuZGxlID0gZ2xzbC5jcmVhdGVTd2FwcGFibGVCdWZmZXIoZ2xzbC5jYW52YXMud2lkdGgsIGdsc2wuY2FudmFzLmhlaWdodCwgcHJvZ3JhbSk7XG4gICAgICAgICAgICAgICAgZ2wuZGVsZXRlU2hhZGVyKGZyYWdtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGdsLmRlbGV0ZVNoYWRlcih2ZXJ0ZXgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY3JlYXRlIGFuIGlucHV0IC8gb3V0cHV0IHN3YXBwYWJsZSBidWZmZXJcblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnY3JlYXRlU3dhcHBhYmxlQnVmZmVyJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNyZWF0ZVN3YXBwYWJsZUJ1ZmZlcihXLCBILCBwcm9ncmFtKSB7XG4gICAgICAgICAgICB2Y
23459XIgaW5wdXQgPSB0aGlzLmNyZWF0ZUJ1ZmZlcihXLCBILCBwcm9ncmFtKTtcbiAgICAgICAgICAgIHZhciBvdXRwdXQgPSB0aGlzLmNyZWF0ZUJ1ZmZlcihXLCBILCBwcm9ncmFtKTtcbiAgICAgICAgICAgIHZhciBnbCA9IHRoaXMuZ2w7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGlucHV0OiBpbnB1dCxcbiAgICAgICAgICAgICAgICBvdXRwdXQ6IG91dHB1dCxcbiAgICAgICAgICAgICAgICBzd2FwOiBmdW5jdGlvbiBzd2FwKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcCA9IGlucHV0O1xuICAgICAgICAgICAgICAgICAgICBpbnB1dCA9IG91dHB1dDtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0ID0gdGVtcDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnB1dCA9IGlucHV0O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm91dHB1dCA9IG91dHB1dDtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKFcsIEgsIHByb2dyYW0sIG5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgZ2wudXNlUHJvZ3JhbShwcm9ncmFtKTtcbiAgICAgICAgICAgICAgICAgICAgZ2wudmlld3BvcnQoMCwgMCwgVywgSCk7XG4gICAgICAgICAgICAgICAgICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgdGhpcy5pbnB1dC5idWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICBnbC5mcmFtZWJ1ZmZlclRleHR1cmUyRChnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRoaXMub3V0cHV0LnRleHR1cmUsIDApO1xuICAgICAgICAgICAgICAgICAgICBnbC5kcmF3QXJyYXlzKGdsLlRSSUFOR0xFUywgMCwgNik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3dhcCgpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVzaXplOiBmdW5jdGlvbiByZXNpemUoVywgSCwgcHJvZ3JhbSwgbmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBnbC51c2VQcm9ncmFtKHByb2dyYW0pO1xuICAgICAgICAgICAgICAgICAgICBnbC52aWV3cG9ydCgwLCAwLCBXLCBIKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnB1dC5yZXNpemUoVywgSCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0LnJlc2l6ZShXLCBIKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY3JlYXRlIGEgYnVmZmVyc1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICdjcmVhdGVCdWZmZXInLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY3JlYXRlQnVmZmVyKFcsIEgsIHByb2dyYW0pIHtcbiAgICAgICAgICAgIHZhciBnbCA9IHRoaXMuZ2w7XG4gICAgICAgICAgICB2Y
23459XIgaW5kZXggPSB0aGlzLkJVRkZFUl9DT1VOVDtcbiAgICAgICAgICAgIHRoaXMuQlVGRkVSX0NPVU5UICs9IDI7XG4gICAgICAgICAgICBnbC5nZXRFeHRlbnNpb24oJ09FU190ZXh0dXJlX2Zsb2F0Jyk7XG4gICAgICAgICAgICB2YXIgdGV4dHVyZSA9IGdsLmNyZWF0ZVRleHR1cmUoKTtcbiAgICAgICAgICAgIGdsLmFjdGl2ZVRleHR1cmUoZ2wuVEVYVFVSRTAgKyBpbmRleCk7XG4gICAgICAgICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICAgICAgICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgZ2wuUkdCQSwgVywgSCwgMCwgZ2wuUkdCQSwgZ2wuRkxPQVQsIG51bGwpO1xuICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01JTl9GSUxURVIsIGdsLk5FQVJFU1QpO1xuICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01BR19GSUxURVIsIGdsLk5FQVJFU1QpO1xuICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX1dSQVBfUywgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9ULCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICAgICAgICAgIHZhciBidWZmZXIgPSBnbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBpbmRleDogaW5kZXgsXG4gICAgICAgICAgICAgICAgdGV4dHVyZTogdGV4dHVyZSxcbiAgICAgICAgICAgICAgICBidWZmZXI6IGJ1ZmZlcixcbiAgICAgICAgICAgICAgICBXOiBXLFxuICAgICAgICAgICAgICAgIEg6IEgsXG4gICAgICAgICAgICAgICAgcmVzaXplOiBmdW5jdGlvbiByZXNpemUoVywgSCkge1xuICAgICAgICAgICAgICAgICAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIGJ1ZmZlcik7XG4gICAgICAgICAgICAgICAgICAgIHZhciBtaW5XID0gTWF0aC5taW4oVywgdGhpcy5XKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1pbkggPSBNYXRoLm1pbihILCB0aGlzLkgpO1xuICAgICAgICAgICAgICAgICAgICB2Y
23459XIgcGl4ZWxzID0gbmV3IEZsb2F0MzJBcnJheShtaW5XICogbWluSCAqIDQpO1xuICAgICAgICAgICAgICAgICAgICBnbC5yZWFkUGl4ZWxzKDAsIDAsIG1pblcsIG1pbkgsIGdsLlJHQkEsIGdsLkZMT0FULCBwaXhlbHMpO1xuICAgICAgICAgICAgICAgICAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIG51bGwpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbmV3SW5kZXggPSBpbmRleCArIDE7XG4gICAgICAgICAgICAgICAgICAgIHZhciBuZXdUZXh0dXJlID0gZ2wuY3JlYXRlVGV4dHVyZSgpO1xuICAgICAgICAgICAgICAgICAgICBnbC5hY3RpdmVUZXh0dXJlKGdsLlRFWFRVUkUwICsgbmV3SW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCBuZXdUZXh0dXJlKTtcbiAgICAgICAgICAgICAgICAgICAgZ2wudGV4SW1hZ2UyRChnbC5URVhUVVJFXzJELCAwLCBnbC5SR0JBLCBXLCBILCAwLCBnbC5SR0JBLCBnbC5GTE9BVCwgbnVsbCk7XG4gICAgICAgICAgICAgICAgICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NSU5fRklMVEVSLCBnbC5ORUFSRVNUKTtcbiAgICAgICAgICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01BR19GSUxURVIsIGdsLk5FQVJFU1QpO1xuICAgICAgICAgICAgICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9TLCBnbC5DTEFNUF9UT19FREdFKTtcbiAgICAgICAgICAgICAgICAgICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX1dSQVBfVCwgZ2wuQ0xBTVBfVE9fRURHRSk7XG4gICAgICAgICAgICAgICAgICAgIGdsLnRleFN1YkltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgMCwgMCwgbWluVywgbWluSCwgZ2wuUkdCQSwgZ2wuRkxPQVQsIHBpeGVscyk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBuZXdCdWZmZXIgPSBnbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuICAgICAgICAgICAgICAgICAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIG51bGwpO1xuICAgICAgICAgICAgICAgICAgICBnbC5kZWxldGVUZXh0dXJlKHRleHR1cmUpO1xuICAgICAgICAgICAgICAgICAgICBnbC5hY3RpdmVUZXh0dXJlKGdsLlRFWFRVUkUwICsgaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCBuZXdUZXh0dXJlKTtcbiAgICAgICAgICAgICAgICAgICAgaW5kZXggPSB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIHRleHR1cmUgPSB0aGlzLnRleHR1cmUgPSBuZXdUZXh0dXJlO1xuICAgICAgICAgICAgICAgICAgICBidWZmZXIgPSB0aGlzLmJ1ZmZlciA9IG5ld0J1ZmZlcjtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5XID0gVztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5IID0gSDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVzaXplIGJ1ZmZlcnMgb24gY2FudmFzIHJlc2l6ZVxuICAgICAgICAvLyBjb25zaWRlciBhcHBseWluZyBhIHRocm90dGxlIG9mIDUwIG1zIG9uIGNhbnZhcyByZXNpemVcbiAgICAgICAgLy8gdG8gYXZvaWQgcmVxdWVzdEFuaW1hdGlvbkZyYW1lIGFuZCBHbCB2aW9sYXRpb25zXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3Jlc2l6ZVN3YXBwYWJsZUJ1ZmZlcnMnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVzaXplU3dhcHBhYmxlQnVmZmVycygpIHtcbiAgICAgICAgICAgIHZhciBnbCA9IHRoaXMuZ2w7XG4gICAgICAgICAgICB2Y
23459XIgVyA9IGdsLmNhbnZhcy53aWR0aCxcbiAgICAgICAgICAgICAgICBIID0gZ2wuY2FudmFzLmhlaWdodDtcbiAgICAgICAgICAgIGdsLnZpZXdwb3J0KDAsIDAsIFcsIEgpO1xuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIHRoaXMuYnVmZmVycykge1xuICAgICAgICAgICAgICAgIHZhciBidWZmZXIgPSB0aGlzLmJ1ZmZlcnNba2V5XTtcbiAgICAgICAgICAgICAgICBidWZmZXIuYnVuZGxlLnJlc2l6ZShXLCBILCBidWZmZXIucHJvZ3JhbSwgYnVmZmVyLm5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZ2wudXNlUHJvZ3JhbSh0aGlzLnByb2dyYW0pO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICd2ZXJzaW9uJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHZlcnNpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gJzAuMS43JztcbiAgICAgICAgfVxuICAgIH1dKTtcbiAgICByZXR1cm4gR2xzbENhbnZhcztcbn0oKTtcblxuZnVuY3Rpb24gbG9hZEFsbEdsc2xDYW52YXMoKSB7XG4gICAgdmFyIGxpc3QgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdnbHNsQ2FudmFzJyk7XG4gICAgaWYgKGxpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICB3aW5kb3cuZ2xzbENhbnZhc2VzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIHNhbmRib3ggPSBuZXcgR2xzbENhbnZhcyhsaXN0W2ldKTtcbiAgICAgICAgICAgIGlmIChzYW5kYm94LmlzVmFsaWQpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuZ2xzbENhbnZhc2VzLnB1c2goc2FuZGJveCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgZnVuY3Rpb24gKCkge1xuICAgIGxvYWRBbGxHbHNsQ2FudmFzKCk7XG59KTtcblxucmV0dXJuIEdsc2xDYW52YXM7XG5cbn0pKSk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGlzRnVuY3Rpb25cblxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uIChmbikge1xuICBpZiAoIWZuKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgdmFyIHN0cmluZyA9IHRvU3RyaW5nLmNhbGwoZm4pXG4gIHJldHVybiBzdHJpbmcgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXScgfHxcbiAgICAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nICYmIHN0cmluZyAhPT0gJ1tvYmplY3QgUmVnRXhwXScpIHx8XG4gICAgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmXG4gICAgIC8vIElFOCBhbmQgYmVsb3dcbiAgICAgKGZuID09PSB3aW5kb3cuc2V0VGltZW91dCB8fFxuICAgICAgZm4gPT09IHdpbmRvdy5hbGVydCB8fFxuICAgICAgZm4gPT09IHdpbmRvdy5jb25maXJtIHx8XG4gICAgICBmbiA9PT0gd2luZG93LnByb21wdCkpXG59O1xuIiwidmFyIHRyaW0gPSBmdW5jdGlvbihzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJyk7XG59XG4gICwgaXNBcnJheSA9IGZ1bmN0aW9uKGFyZykge1xuICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmcpID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaGVhZGVycykge1xuICBpZiAoIWhlYWRlcnMpXG4gICAgcmV0dXJuIHt9XG5cbiAgdmFyIHJlc3VsdCA9IHt9XG5cbiAgdmFyIGhlYWRlcnNBcnIgPSB0cmltKGhlYWRlcnMpLnNwbGl0KCdcXG4nKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgaGVhZGVyc0Fyci5sZW5ndGg7IGkrKykge1xuICAgIHZhciByb3cgPSBoZWFkZXJzQXJyW2ldXG4gICAgdmFyIGluZGV4ID0gcm93LmluZGV4T2YoJzonKVxuICAgICwga2V5ID0gdHJpbShyb3cuc2xpY2UoMCwgaW5kZXgpKS50b0xvd2VyQ2FzZSgpXG4gICAgLCB2YWx1ZSA9IHRyaW0ocm93LnNsaWNlKGluZGV4ICsgMSkpXG5cbiAgICBpZiAodHlwZW9mKHJlc3VsdFtrZXldKSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJlc3VsdFtrZXldID0gdmFsdWVcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkocmVzdWx0W2tleV0pKSB7XG4gICAgICByZXN1bHRba2V5XS5wdXNoKHZhbHVlKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHRba2V5XSA9IFsgcmVzdWx0W2tleV0sIHZhbHVlIF1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0XG59XG4iLCJcInVzZSBzdHJpY3RcIjtcbnZhciB3aW5kb3cgPSByZXF1aXJlKFwiZ2xvYmFsL3dpbmRvd1wiKVxudmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKFwiaXMtZnVuY3Rpb25cIilcbnZhciBwYXJzZUhlYWRlcnMgPSByZXF1aXJlKFwicGFyc2UtaGVhZGVyc1wiKVxudmFyIHh0ZW5kID0gcmVxdWlyZShcInh0ZW5kXCIpXG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlWEhSXG4vLyBBbGxvdyB1c2Ugb2YgZGVmYXVsdCBpbXBvcnQgc3ludGF4IGluIFR5cGVTY3JpcHRcbm1vZHVsZS5leHBvcnRzLmRlZmF1bHQgPSBjcmVhdGVYSFI7XG5jcmVhdGVYSFIuWE1MSHR0cFJlcXVlc3QgPSB3aW5kb3cuWE1MSHR0cFJlcXVlc3QgfHwgbm9vcFxuY3JlYXRlWEhSLlhEb21haW5SZXF1ZXN0ID0gXCJ3aXRoQ3JlZGVudGlhbHNcIiBpbiAobmV3IGNyZWF0ZVhIUi5YTUxIdHRwUmVxdWVzdCgpKSA/IGNyZWF0ZVhIUi5YTUxIdHRwUmVxdWVzdCA6IHdpbmRvdy5YRG9tYWluUmVxdWVzdFxuXG5mb3JFYWNoQXJyYXkoW1wiZ2V0XCIsIFwicHV0XCIsIFwicG9zdFwiLCBcInBhdGNoXCIsIFwiaGVhZFwiLCBcImRlbGV0ZVwiXSwgZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgY3JlYXRlWEhSW21ldGhvZCA9PT0gXCJkZWxldGVcIiA/IFwiZGVsXCIgOiBtZXRob2RdID0gZnVuY3Rpb24odXJpLCBvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgICBvcHRpb25zID0gaW5pdFBhcmFtcyh1cmksIG9wdGlvbnMsIGNhbGxiYWNrKVxuICAgICAgICBvcHRpb25zLm1ldGhvZCA9IG1ldGhvZC50b1VwcGVyQ2FzZSgpXG4gICAgICAgIHJldHVybiBfY3JlYXRlWEhSKG9wdGlvbnMpXG4gICAgfVxufSlcblxuZnVuY3Rpb24gZm9yRWFjaEFycmF
234595KGFycmF5LCBpdGVyYXRvcikge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaXRlcmF0b3IoYXJyYXlbaV0pXG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0VtcHR5KG9iail7XG4gICAgZm9yKHZhciBpIGluIG9iail7XG4gICAgICAgIGlmKG9iai5oYXNPd25Qcm9wZXJ0eShpKSkgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIHJldHVybiB0cnVlXG59XG5cbmZ1bmN0aW9uIGluaXRQYXJhbXModXJpLCBvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIHZhciBwYXJhbXMgPSB1cmlcblxuICAgIGlmIChpc0Z1bmN0aW9uKG9wdGlvbnMpKSB7XG4gICAgICAgIGNhbGxiYWNrID0gb3B0aW9uc1xuICAgICAgICBpZiAodHlwZW9mIHVyaSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgcGFyYW1zID0ge3VyaTp1cml9XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXJhbXMgPSB4dGVuZChvcHRpb25zLCB7dXJpOiB1cml9KVxuICAgIH1cblxuICAgIHBhcmFtcy5jYWxsYmFjayA9IGNhbGxiYWNrXG4gICAgcmV0dXJuIHBhcmFtc1xufVxuXG5mdW5jdGlvbiBjcmVhdGVYSFIodXJpLCBvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIG9wdGlvbnMgPSBpbml0UGFyYW1zKHVyaSwgb3B0aW9ucywgY2FsbGJhY2spXG4gICAgcmV0dXJuIF9jcmVhdGVYSFIob3B0aW9ucylcbn1cblxuZnVuY3Rpb24gX2NyZWF0ZVhIUihvcHRpb25zKSB7XG4gICAgaWYodHlwZW9mIG9wdGlvbnMuY2FsbGJhY2sgPT09IFwidW5kZWZpbmVkXCIpe1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjYWxsYmFjayBhcmd1bWVudCBtaXNzaW5nXCIpXG4gICAgfVxuXG4gICAgdmFyIGNhbGxlZCA9IGZhbHNlXG4gICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gY2JPbmNlKGVyciwgcmVzcG9uc2UsIGJvZHkpe1xuICAgICAgICBpZighY2FsbGVkKXtcbiAgICAgICAgICAgIGNhbGxlZCA9IHRydWVcbiAgICAgICAgICAgIG9wdGlvbnMuY2FsbGJhY2soZXJyLCByZXNwb25zZSwgYm9keSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlYWR5c3RhdGVjaGFuZ2UoKSB7XG4gICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChsb2FkRnVuYywgMClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldEJvZHkoKSB7XG4gICAgICAgIC8vIENocm9tZSB3aXRoIHJlcXVlc3RUeXBlPWJsb2IgdGhyb3dzIGVycm9ycyBhcnJvdW5kIHdoZW4gZXZlbiB0ZXN0aW5nIGFjY2VzcyB0byByZXNwb25zZVRleHRcbiAgICAgICAgdmFyIGJvZHkgPSB1bmRlZmluZWRcblxuICAgICAgICBpZiAoeGhyLnJlc3BvbnNlKSB7XG4gICAgICAgICAgICBib2R5ID0geGhyLnJlc3BvbnNlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBib2R5ID0geGhyLnJlc3BvbnNlVGV4dCB8fCBnZXRYbWwoeGhyKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzSnNvbikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBib2R5ID0gSlNPTi5wYXJzZShib2R5KVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBib2R5XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXJyb3JGdW5jKGV2dCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dFRpbWVyKVxuICAgICAgICBpZighKGV2dCBpbnN0YW5jZW9mIEVycm9yKSl7XG4gICAgICAgICAgICBldnQgPSBuZXcgRXJyb3IoXCJcIiArIChldnQgfHwgXCJVbmtub3duIFhNTEh0dHBSZXF1
23459ZXN0IEVycm9yXCIpIClcbiAgICAgICAgfVxuICAgICAgICBldnQuc3RhdHVzQ29kZSA9IDBcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGV2dCwgZmFpbHVyZVJlc3BvbnNlKVxuICAgIH1cblxuICAgIC8vIHdpbGwgbG9hZCB0aGUgZGF0YSAmIHByb2Nlc3MgdGhlIHJlc3BvbnNlIGluIGEgc3BlY2lhbCByZXNwb25zZSBvYmplY3RcbiAgICBmdW5jdGlvbiBsb2FkRnVuYygpIHtcbiAgICAgICAgaWYgKGFib3J0ZWQpIHJldHVyblxuICAgICAgICB2YXIgc3RhdHVzXG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0VGltZXIpXG4gICAgICAgIGlmKG9wdGlvbnMudXNlWERSICYmIHhoci5zdGF0dXM9PT11bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vSUU4IENPUlMgR0VUIHN1Y2Nlc3NmdWwgcmVzcG9uc2UgZG9lc24ndCBoYXZlIGEgc3RhdHVzIGZpZWxkLCBidXQgYm9keSBpcyBmaW5lXG4gICAgICAgICAgICBzdGF0dXMgPSAyMDBcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0YXR1cyA9ICh4aHIuc3RhdHVzID09PSAxMjIzID8gMjA0IDogeGhyLnN0YXR1cylcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVzcG9uc2UgPSBmYWlsdXJlUmVzcG9uc2VcbiAgICAgICAgdmFyIGVyciA9IG51bGxcblxuICAgICAgICBpZiAoc3RhdHVzICE9PSAwKXtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge1xuICAgICAgICAgICAgICAgIGJvZHk6IGdldEJvZHkoKSxcbiAgICAgICAgICAgICAgICBzdGF0dXNDb2RlOiBzdGF0dXMsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICAgICAgICAgICAgaGVhZGVyczoge30sXG4gICAgICAgICAgICAgICAgdXJsOiB1cmksXG4gICAgICAgICAgICAgICAgcmF3UmVxdWVzdDogeGhyXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZih4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKXsgLy9yZW1lbWJlciB4aHIgY2FuIGluIGZhY3QgYmUgWERSIGZvciBDT1JTIGluIElFXG4gICAgICAgICAgICAgICAgcmVzcG9uc2UuaGVhZGVycyA9IHBhcnNlSGVhZGVycyh4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlcnIgPSBuZXcgRXJyb3IoXCJJbnRlcm5hbCBYTUxIdHRwUmVxdWVzdCBFcnJvclwiKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIHJlc3BvbnNlLCByZXNwb25zZS5ib2R5KVxuICAgIH1cblxuICAgIHZhciB4aHIgPSBvcHRpb25zLnhociB8fCBudWxsXG5cbiAgICBpZiAoIXhocikge1xuICAgICAgICBpZiAob3B0aW9ucy5jb3JzIHx8IG9wdGlvbnMudXNlWERSKSB7XG4gICAgICAgICAgICB4aHIgPSBuZXcgY3JlYXRlWEhSLlhEb21haW5SZXF1ZXN0KClcbiAgICAgICAgfWVsc2V7XG4gICAgICAgICAgICB4aHIgPSBuZXcgY3JlYXRlWEhSLlhNTEh0dHBSZXF1
23459ZXN0KClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHZhciBrZXlcbiAgICB2YXIgYWJvcnRlZFxuICAgIHZhciB1cmkgPSB4aHIudXJsID0gb3B0aW9ucy51cmkgfHwgb3B0aW9ucy51cmxcbiAgICB2YXIgbWV0aG9kID0geGhyLm1ldGhvZCA9IG9wdGlvbnMubWV0aG9kIHx8IFwiR0VUXCJcbiAgICB2YXIgYm9keSA9IG9wdGlvbnMuYm9keSB8fCBvcHRpb25zLmRhdGFcbiAgICB2YXIgaGVhZGVycyA9IHhoci5oZWFkZXJzID0gb3B0aW9ucy5oZWFkZXJzIHx8IHt9XG4gICAgdmFyIHN5bmMgPSAhIW9wdGlvbnMuc3luY1xuICAgIHZhciBpc0pzb24gPSBmYWxzZVxuICAgIHZhciB0aW1lb3V0VGltZXJcbiAgICB2YXIgZmFpbHVyZVJlc3BvbnNlID0ge1xuICAgICAgICBib2R5OiB1bmRlZmluZWQsXG4gICAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgICBzdGF0dXNDb2RlOiAwLFxuICAgICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgICAgdXJsOiB1cmksXG4gICAgICAgIHJhd1JlcXVlc3Q6IHhoclxuICAgIH1cblxuICAgIGlmIChcImpzb25cIiBpbiBvcHRpb25zICYmIG9wdGlvbnMuanNvbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgaXNKc29uID0gdHJ1ZVxuICAgICAgICBoZWFkZXJzW1wiYWNjZXB0XCJdIHx8IGhlYWRlcnNbXCJBY2NlcHRcIl0gfHwgKGhlYWRlcnNbXCJBY2NlcHRcIl0gPSBcImFwcGxpY2F0aW9uL2pzb25cIikgLy9Eb24ndCBvdmVycmlkZSBleGlzdGluZyBhY2NlcHQgaGVhZGVyIGRlY2xhcmVkIGJ5IHVzZXJcbiAgICAgICAgaWYgKG
234591ldGhvZCAhPT0gXCJHRVRcIiAmJiBtZXRob2QgIT09IFwiSEVBRFwiKSB7XG4gICAgICAgICAgICBoZWFkZXJzW1wiY29udGVudC10eXBlXCJdIHx8IGhlYWRlcnNbXCJDb250ZW50LVR5cGVcIl0gfHwgKGhlYWRlcnNbXCJDb250ZW50LVR5cGVcIl0gPSBcImFwcGxpY2F0aW9uL2pzb25cIikgLy9Eb24ndCBvdmVycmlkZSBleGlzdGluZyBhY2NlcHQgaGVhZGVyIGRlY2xhcmVkIGJ5IHVzZXJcbiAgICAgICAgICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShvcHRpb25zLmpzb24gPT09IHRydWUgPyBib2R5IDogb3B0aW9ucy5qc29uKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHJlYWR5c3RhdGVjaGFuZ2VcbiAgICB4aHIub25sb2FkID0gbG9hZEZ1bmNcbiAgICB4aHIub25lcnJvciA9IGVycm9yRnVuY1xuICAgIC8vIElFOSBtdXN0IGhhdmUgb25wcm9ncmVzcyBiZSBzZXQgdG8gYSB1bmlxdWUgZnVuY3Rpb24uXG4gICAgeGhyLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIElFIG11c3QgZGllXG4gICAgfVxuICAgIHhoci5vbmFib3J0ID0gZnVuY3Rpb24oKXtcbiAgICAgICAgYWJvcnRlZCA9IHRydWU7XG4gICAgfVxuICAgIHhoci5vbnRpbWVvdXQgPSBlcnJvckZ1bmNcbiAgICB4aHIub3BlbihtZXRob2QsIHVyaSwgIXN5bmMsIG9wdGlvbnMudXNlcm5hbWUsIG9wdGlvbnMucGFzc3dvcmQpXG4gICAgLy9oYXMgdG8gYmUgYWZ0ZXIgb3BlblxuICAgIGlmKCFzeW5jKSB7XG4gICAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSAhIW9wdGlvbnMud2l0aENyZWRlbnRpYWxzXG4gICAgfVxuICAgIC8vIENhbm5vdCBzZXQgdGltZW91dCB3aXRoIHN5bmMgcmVxdWVzdFxuICAgIC8vIG5vdCBzZXR0aW5nIHRpbWVvdXQgb24gdGhlIHhociBvYmplY3QsIGJlY2F1c2Ugb2Ygb2xkIHdlYmtpdHMgZXRjLiBub3QgaGFuZGxpbmcgdGhhdCBjb3JyZWN0bHlcbiAgICAvLyBib3RoIG5wbSdzIHJlcXVlc3QgYW5kIGpxdWVyeSAxLnggdXNlIHRoaXMga2luZCBvZiB0aW1lb3V0LCBzbyB0aGlzIGlzIGJlaW5nIGNvbnNpc3RlbnRcbiAgICBpZiAoIXN5bmMgJiYgb3B0aW9ucy50aW1lb3V0ID4gMCApIHtcbiAgICAgICAgdGltZW91dFRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgICAgICAgaWYgKGFib3J0ZWQpIHJldHVyblxuICAgICAgICAgICAgYWJvcnRlZCA9IHRydWUvL0lFOSBtYXkgc3RpbGwgY2FsbCByZWFkeXN0YXRlY2hhbmdlXG4gICAgICAgICAgICB4aHIuYWJvcnQoXCJ0aW1lb3V0XCIpXG4gICAgICAgICAgICB2Y
23459XIgZSA9IG5ldyBFcnJvcihcIlhNTEh0dHBSZXF1ZXN0IHRpbWVvdXRcIilcbiAgICAgICAgICAgIGUuY29kZSA9IFwiRVRJTUVET1VUXCJcbiAgICAgICAgICAgIGVycm9yRnVuYyhlKVxuICAgICAgICB9LCBvcHRpb25zLnRpbWVvdXQgKVxuICAgIH1cblxuICAgIGlmICh4aHIuc2V0UmVxdWVzdEhlYWRlcikge1xuICAgICAgICBmb3Ioa2V5IGluIGhlYWRlcnMpe1xuICAgICAgICAgICAgaWYoaGVhZGVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKXtcbiAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5oZWFkZXJzICYmICFpc0VtcHR5KG9wdGlvbnMuaGVhZGVycykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSGVhZGVycyBjYW5ub3QgYmUgc2V0IG9uIGFuIFhEb21haW5SZXF1ZXN0IG9iamVjdFwiKVxuICAgIH1cblxuICAgIGlmIChcInJlc3BvbnNlVHlwZVwiIGluIG9wdGlvbnMpIHtcbiAgICAgICAgeGhyLnJlc3BvbnNlVHlwZSA9IG9wdGlvbnMucmVzcG9uc2VUeXBlXG4gICAgfVxuXG4gICAgaWYgKFwiYmVmb3JlU2VuZFwiIGluIG9wdGlvbnMgJiZcbiAgICAgICAgdHlwZW9mIG9wdGlvbnMuYmVmb3JlU2VuZCA9PT0gXCJmdW5jdGlvblwiXG4gICAgKSB7XG4gICAgICAgIG9wdGlvbnMuYmVmb3JlU2VuZCh4aHIpXG4gICAgfVxuXG4gICAgLy8gTWljcm9zb2Z0IEVkZ2UgYnJvd3NlciBzZW5kcyBcInVuZGVmaW5lZFwiIHdoZW4gc2VuZCBpcyBjYWxsZWQgd2l0aCB1bmRlZmluZWQgdmFsdWUuXG4gICAgLy8gWE1MSHR0cFJlcXVlc3Qgc3BlYyBzYXlzIHRvIHBhc3MgbnVsbCBhcyBib2R5IHRvIGluZGljYXRlIG5vIGJvZHlcbiAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL25hdWd0dXIveGhyL2lzc3Vlcy8xMDAuXG4gICAgeGhyLnNlbmQoYm9keSB8fCBudWxsKVxuXG4gICAgcmV0dXJuIHhoclxuXG5cbn1cblxuZnVuY3Rpb24gZ2V0WG1sKHhocikge1xuICAgIC8vIHhoci5yZXNwb25zZVhNTCB3aWxsIHRocm93IEV4Y2VwdGlvbiBcIkludmFsaWRTdGF0ZUVycm9yXCIgb3IgXCJET01FeGNlcHRpb25cIlxuICAgIC8vIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvWE1MSHR0cFJlcXVlc3QvcmVzcG9uc2VYTUwuXG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHhoci5yZXNwb25zZVR5cGUgPT09IFwiZG9jdW1lbnRcIikge1xuICAgICAgICAgICAgcmV0dXJuIHhoci5yZXNwb25zZVhNTFxuICAgICAgICB9XG4gICAgICAgIHZhciBmaXJlZm94QnVnVGFrZW5FZmZlY3QgPSB4aHIucmVzcG9uc2VYTUwgJiYgeGhyLnJlc3BvbnNlWE1MLmRvY3VtZW50RWxlbWVudC5ub2RlTmFtZSA9PT0gXCJwYXJzZXJlcnJvclwiXG4gICAgICAgIGlmICh4aHIucmVzcG9uc2VUeXBlID09PSBcIlwiICYmICFmaXJlZm94QnVnVGFrZW5FZmZlY3QpIHtcbiAgICAgICAgICAgIHJldHVybiB4aHIucmVzcG9uc2VYTUxcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICByZXR1cm4gbnVsbFxufVxuXG5mdW5jdGlvbiBub29wKCkge31cbiIsIm1vZHVsZS5leHBvcnRzID0gZXh0ZW5kXG5cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbmZ1bmN0aW9uIGV4dGVuZCgpIHtcbiAgICB2YXIgdGFyZ2V0ID0ge31cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV1cblxuICAgICAgICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGFyZ2V0XG59XG4iLCJpbXBvcnQgXCJkb2N1bWVudC1yZWdpc3Rlci1lbGVtZW50XCI7XG5pbXBvcnQgU2hhZGVyIGZyb20gXCIuL2NvcmUvU2hhZGVyXCI7XG5pbXBvcnQgeyBpbml0RWRpdG9yLCBmb2N1c0FsbCB9IGZyb20gXCIuL2NvcmUvRWRpdG9yXCI7XG5cbmltcG9ydCBNZW51IGZyb20gXCIuL3VpL01lbnVcIjtcbmltcG9ydCBIZWxwZXJzIGZyb20gXCIuL3VpL0hlbHBlcnNcIjtcbmltcG9ydCBFcnJvcnNEaXNwbGF5IGZyb20gXCIuL3VpL0Vycm9yc0Rpc3BsYXlcIjtcbmltcG9ydCBWaXN1YWxEZWJ1Z2dlciBmcm9tIFwiLi91aS9WaXN1YWxEZWJ1Z2dlclwiO1xuaW1wb3J0IEV4cG9ydEljb24gZnJvbSBcIi4vdWkvRXhwb3J0SWNvblwiO1xuXG5pbXBvcnQgRmlsZURyb3AgZnJvbSBcIi4vaW8vRmlsZURyb3BcIjtcbmltcG9ydCBIYXNoV2F0Y2ggZnJvbSBcIi4vaW8vSGFzaFdhdGNoXCI7XG5pbXBvcnQgQnVmZmVyTWFuYWdlciBmcm9tIFwiLi9pby9CdWZmZXJNYW5hZ2VyXCI7XG5pbXBvcnQgTG9jYWxTdG9yYWdlIGZyb20gXCIuL2lvL0xvY2FsU3RvcmFnZVwiO1xuY29uc3QgU1RPUkFHRV9MQVNUX0VESVRPUl9DT05URU5UID0gXCJsYXN0LWNvbnRlbnRcIjtcblxuLy8gSW1wb3J0IFV0aWxzXG5pbXBvcnQgeGhyIGZyb20gXCJ4aHJcIjtcbmltcG9ydCB7IHN1YnNjcmliZU1peGluIH0gZnJvbSBcIi4vdG9vbHMvbWl4aW5cIjtcbmltcG9ydCB7IHNhdmVBcyB9IGZyb20gXCIuL3Rvb2xzL2Rvd25sb2FkXCI7XG5pbXBvcnQgeyBnZXRKU09OIH0gZnJvbSBcIi4vdG9vbHMvY29tbW9uXCI7XG5pbXBvcnQgQ29kZU1pcnJvciBmcm9tIFwiY29kZW1pcnJvclwiO1xuXG4vLyAvLyBDcm9zcyBzdG9yYWdlIGZvciBPcGVuZnJhbWUgLS0gYWxsb3dzIHJlc3RyaWN0ZWQgYWNjZXNzIHRvIGNlcnRhaW4gbG9jYWxTdG9yYWdlIG9wZXJhdGlvbnNcbi8vIC8vIG9uIHRoZSBvcGVuZnJhbWUgZG9tYWluXG4vLyBpbXBvcnQgeyBDcm9zc1N0b3JhZ2VDbGllbnQgfSBmcm9tIFwiY3Jvc3Mtc3RvcmFnZVwiO1xuLy8gaW1wb3J0IHsgZ2V0TW9kZSB9IGZyb20gXCJjb2RlbWlycm9yXCI7XG5cbmNvbnN0IEVNUFRZX0ZSQUdfU0hBREVSID0gYC8vIEF1dGhvcjpcbi8vIFRpdGxlOlxuXG4jaWZkZWYgR0xfRVNcbnByZWNpc2lvbiBtZWRpdW1wIGZsb2F0O1xuI2VuZGlmXG5cbnVuaWZvcm0gdmVjMiB1X3Jlc29sdXRpb247XG51bmlmb3JtIHZlYzIgdV9tb3VzZTtcbnVuaWZvcm0gZmxvYXQgdV90aW1lO1xuXG52b2lkIG1haW4oKSB7XG4gICAgdmVjMiBzdCA9IGdsX0ZyYWdDb29yZC54eS91X3Jlc29sdXRpb24ueHk7XG4gICAgc3QueCAqPSB1X3Jlc29sdXRpb24ueC91X3Jlc29sdXRpb24ueTtcblxuICAgI
23459HZlYzMgY29sb3IgPSB2ZWMzKDAuKTtcbiAgICBjb2xvciA9IHZlYzMoc3QueCxzdC55LGFicyhzaW4odV90aW1lKSkpO1xuXG4gICAgZ2xfRnJhZ0NvbG9yID0gdmVjNChjb2xvciwxLjApO1xufWA7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEdsc2xFZGl0b3Ige1xuICBjb25zdHJ1Y3RvcihzZWxlY3Rvciwgb3B0aW9ucykge1xuICAgIHRoaXMuY3JlYXRlRm9udExpbmsoKTtcbiAgICBzdWJzY3JpYmVNaXhpbih0aGlzKTtcblxuICAgIGlmIChcbiAgICAgIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgc2VsZWN0b3Iubm9kZVR5cGUgJiZcbiAgICAgIHNlbGVjdG9yLm5vZGVUeXBlID09PSAxXG4gICAgKSB7XG4gICAgICB0aGlzLmNvbnRhaW5lciA9IHNlbGVjdG9yO1xuICAgIH0gXG4gICAgZWxzZSBpZiAodHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiKSB7XG4gICAgICB0aGlzLmNvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgICAgaWYgKCF0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGVsZW1lbnQgJHtzZWxlY3Rvcn0gbm90IHByZXNlbnRgKTtcbiAgICAgIH1cbiAgICB9IFxuICAgIGVsc2Uge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIFwiRXJyb3IsIHR5cGUgXCIgKyB0eXBlb2Ygc2VsZWN0b3IgKyBcIiBvZiBcIiArIHNlbGVjdG9yICsgXCIgaXMgdW5rbm93blwiXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMub3B0aW9ucyA9IHt9O1xuICAgIHRoaXMuY2hhbmdlID0gZmFsc2U7XG4gICAgdGhpcy5hdXRvdXBkYXRlID0gdHJ1ZTtcbiAgICB0aGlzLmx5Z2lhX2dsb2IgPSBudWxsO1xuXG4gICAgaWYgKG9wdGlvbnMpXG4gICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pbWdzID09PSB1bmRlZmluZWQpXG4gICAgICB0aGlzLm9wdGlvbnMuaW1ncyA9IFtdO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5kaXNwbGF5X21lbnUgPT09IHVuZGVmaW5lZClcbiAgICAgIHRoaXMub3B0aW9ucy5kaXNwbGF5X21lbnUgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMuY29udGFpbmVyLmhhc0F0dHJpYnV0ZShcImRhdGEtdGV4dHVyZXNcIikpIHtcbiAgICAgIGxldCBpbWdMaXN0ID0gdGhpcy5jb250YWluZXIuZ2V0QXR0cmlidXRlKFwiZGF0YS10ZXh0dXJlc1wiKS5zcGxpdChcIixcIik7XG4gICAgICBmb3IgKGxldCBpIGluIGltZ0xpc3QpXG4gICAgICAgIHRoaXMub3B0aW9ucy5pbWdzLnB1c2goaW1nTGlzdFtpXSk7XG4gICAgICBcbiAgICB9XG5cbiAgICAvLyBEZWZhdWx0IFRoZW1lXG4gICAgaWYgKCF0aGlzLm9wdGlvbnMudGhlbWUpXG4gICAgICB0aGlzLm9wdGlvbnMudGhlbWUgPSBcImRlZmF1bHRcIjtcblxuICAgIC8vIERlZmF1bHQgQ29udGV4dFxuICAgIGlmICghdGhpcy5vcHRpb25zLmZyYWcpIHtcbiAgICAgIHZhciBpbm5lckhUTUwgPSB0aGlzLmNvbnRhaW5lci5pbm5lckhUTUwucmVwbGFjZSgvJmx0O2JyJmd0Oy9nLCBcIlwiKTtcbiAgICAgIGlubmVySFRNTCA9IGlubmVySFRNTC5yZXBsYWNlKC88YnI+L2csIFwiXCIpO1xuICAgICAgaW5uZXJIVE1MID0gaW5uZXJIVE1MLnJlcGxhY2UoLyZuYnNwOy9nLCBcIlwiKTtcbiAgICAgIGlubmVySFRNTCA9IGlubmVySFRNTC5yZXBsYWNlKC8mbHQ7L2csIFwiPFwiKTtcbiAgICAgIGlubmVySFRNTCA9IGlubmVySFRNTC5yZXBsYWNlKC8mZ3Q7L2csIFwiPlwiKTtcbiAgICAgIGlubmVySFRNTCA9IGlubmVySFRNTC5yZXBsYWNlKC8mYW1wOy9nLCBcIiZcIik7XG4gICAgICB0aGlzLm9wdGlvbnMuZnJhZyA9IGlubmVySFRNTCB8fCBFTVBUWV9GUkFHX1NIQURFUjtcblxuICAgICAgaWYgKGlubmVySFRNTClcbiAgICAgICAgdGhpcy5jb250YWluZXIuaW5uZXJIVE1MID0gXCJcIjtcbiAgICB9XG5cbiAgICAvLyBEZWZhdWx0IGludmlzaWJsZSBGcmFnbWVudCBoZWFkZXJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5mcmFnX2hlYWRlcilcbiAgICAgIHRoaXMub3B0aW9ucy5mcmFnX2hlYWRlciA9IFwiXCI7XG5cbiAgICAvLyBEZWZhdWx0IGludmlzaWJsZSBGcmFnbWVudCBmb290ZXJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5mcmFnX2Zvb3RlcilcbiAgICAgIHRoaXMub3B0aW9ucy5mcmFnX2Zvb3RlciA9IFwiXCI7XG5cbiAgICAvLyBMaXN0ZW4gdG8gaGFzaCBjaGFuZ2VzXG4gICAgaWYgKHRoaXMub3B0aW9ucy53YXRjaEhhc2gpXG4gICAgICBuZXcgSGFzaFdhdGNoKHRoaXMpO1xuXG4gICAgLy8gTG9hZCBVSVxuICAgIGlmICh0aGlzLm9wdGlvbnMubWVudSlcbiAgICAgIHRoaXMubWVudSA9IG5ldyBNZW51KHRoaXMpO1xuXG4gICAgLy8gU3VwcG9ydCBmb3IgbXVsdGlwbGUgYnVmZmVyc1xuICAgIGlmICh0aGlzLm9wdGlvbnMubXVsdGlwbGVCdWZmZXJzKVxuICAgICAgdGhpcy5idWZmZXJNYW5hZ2VyID0gbmV3IEJ1ZmZlck1hbmFnZXIodGhpcyk7XG5cbiAgICAvLyBMaXN0ZW4gdG8gZmlsZSBkcm9wc1xuICAgIGlmICh0aGlzLm9wdGlvbnMuZmlsZURyb3BzKVxuICAgICAgbmV3IEZpbGVEcm9wKHRoaXMpO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pbmRlbnRVbml0ID09PSB1bmRlZmluZWQpXG4gICAgICB0aGlzLm9wdGlvbnMuaW5kZW50VW5pdCA9IDQ7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnRhYlNpemUgPT09IHVuZGVmaW5lZClcbiAgICAgIHRoaXMub3B0aW9ucy50YWJTaXplID0gNDtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMuaW5kZW50V2l0aFRhYnMgPT09IHVuZGVmaW5lZClcbiAgICAgIHRoaXMub3B0aW9ucy5pbmRlbnRXaXRoVGFicyA9IGZhbHNlO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5saW5lV3JhcHBpbmcgPT09IHVuZGVmaW5lZClcbiAgICAgIHRoaXMub3B0aW9ucy5saW5lV3JhcHBpbmcgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5hdXRvZm9jdXMgPT09IHVuZGVmaW5lZClcbiAgICAgIHRoaXMub3B0aW9ucy5hdXRvZm9jdXMgPSB0cnVlO1xuXG4gICAgLy8gQ09SRSBlbGVtZW50c1xuICAgIHRoaXMuc2hhZGVyID0gbmV3IFNoYWRlcih0aGlzKTtcbiAgICB0aGlzLmVkaXRvciA9IGluaXRFZGl0b3IodGhpcyk7XG5cbiAgICB0aGlzLmhlbHBlcnMgPSBuZXcgSGVscGVycyh0aGlzKTtcbiAgICB0aGlzLmVycm9yc0Rpc3BsYXkgPSBuZXcgRXJyb3JzRGlzcGxheSh0aGlzKTtcbiAgICB0aGlzLnZpc3VhbERlYnVnZ2VyID0gbmV3IFZpc3VhbERlYnVnZ2VyKH
23459RoaXMpO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5leHBvcnRJY29uKVxuICAgICAgdGhpcy5leHBvcnQgPSBuZXcgRXhwb3J0SWNvbih0aGlzKTtcblxuICAgIC8vIEVWRU5UU1xuICAgIHRoaXMuZWRpdG9yLm9uKFwiY2hhbmdlXCIsICgpID0+IHtcbiAgICAgIGlmICh0aGlzLmF1dG91cGRhdGUpIHtcbiAgICAgICAgdGhpcy51cGRhdGUoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmICh0aGlzLm9wdGlvbnMuY2FudmFzX2ZvbGxvdykge1xuICAgICAgdGhpcy5zaGFkZXIuZWwuc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG5cbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuY2FudmFzX2Zsb2F0KVxuICAgICAgICB0aGlzLnNoYWRlci5lbC5zdHlsZS5mbG9hdCA9IHRoaXMub3B0aW9ucy5jYW52YXNfZmxvYXQ7XG5cbiAgICAgIHRoaXMuZWRpdG9yLm9uKFwiY3Vyc29yQWN0aXZpdHlcIiwgKGNtKSA9PiB7XG4gICAgICAgIGxldCBoZWlnaHQgPVxuICAgICAgICAgIGNtLmhlaWdodEF0TGluZShjbS5nZXRDdXJzb3IoKS5saW5lICsgMSwgXCJsb2NhbFwiKSAtXG4gICAgICAgICAgdGhpcy5zaGFkZXIuZWwuY2xpZW50SGVpZ2h0O1xuICAgICAgICBpZiAoaGVpZ2h0IDwgMCkge1xuICAgICAgICAgIGhlaWdodCA9IDAuMDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNoYWRlci5lbC5zdHlsZS50b3AgPSBoZWlnaHQudG9TdHJpbmcoKSArIFwicHhcIjtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuZWRpdG9yLm9uKCdpbnB1dFJlYWQnLCAoY20sIGNoYW5nZSkgPT4ge1xuICAgICAgbGV0IGN1ciA9IGNtLmdldEN1cnNvcigpLFxuICAgICAgICAgIHRva2VuID0gY20uZ2V0VG9rZW5BdChjdXIpO1xuICAgICAgbGV0IGxpbmUgPSB0b2tlbi5zdHJpbmcudHJpbSgpO1xuICAgICAgICAgIFxuICAgICAgaWYgKGxpbmUuc3RhcnRzV2l0aCgnI2luY2x1ZGUnKSkge1xuICAgICAgICBsZXQgcGF0aCA9IGxpbmUuc3Vic3RyaW5nKDEwKTtcbiAgICAgICAgaWYgKHRoaXMubHlnaWFfZ2xvYiA9PT0gbnVsbCkge1xuICAgICAgICAgIGdldEpTT04oJ2h0dHBzOi8vbHlnaWEueHl6L2dsc2wuanNvbicsIChlcnIsIGRhdGEpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgdGhpcy5seWdpYV9nbG9iID0gZGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zb2xlLmxvZygnYXV0b2NvbXBsZXRlIGZvcicsIHBhdGgpO1xuXG4gICAgICAgIGxldCBzdGFydCA9IHRva2VuLnN0YXJ0O1xuICAgICAgICBsZXQgZW5kID0gY3VyLmNoO1xuICAgICAgICBsZXQgbGluZU4gPSBjdXIubGluZTtcblxuICAgICAgICBsZXQgcmVzdWx0ID0gW11cblxuICAgICAgICBpZiAodGhpcy5seWdpYV9nbG9iICE9PSBudWxsKSB7XG4gICAgICAgICAgdGhpcy5seWdpYV9nbG9iLmZvckVhY2goICh3KSA9PiB7aWYgKHcuc3RhcnRzV2l0aChwYXRoKSkgcmVzdWx0LnB1c2goJyNpbmNsdWRlIFxcXCInICsgdyArICdcXFwiJyk7fSApO1xuICAgICAgICAgIHJlc3VsdC5zb3J0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBDb2RlTWlycm9yLnNob3dIaW50KGNtLCAoKSA9PiB7XG4gICAgICAgICAgICBsZXQgcnRhID0ge1xuICAgICAgICAgICAgICBsaXN0OiByZXN1bHQsIFxuICAgICAgICAgICAgICBmcm9tOiBDb2RlTWlycm9yLlBvcyhsaW5lTiwgc3RhcnQpLFxuICAgICAgICAgICAgICB0bzogQ29kZU1pcnJvci5Qb3MobGluZU4sIGVuZClcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHJ0YSk7XG4gICAgICAgICAgICByZXR1cm4gcnRhO1xuICAgICAgICAgIH0sIHtjb21wbGV0ZVNpbmdsZTogdHJ1ZSwgYWxpZ25XaXRoV29yZDogdHJ1ZX0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBJZiB0aGUgdXNlciBiYWlscyBmb3Igd2hhdGV2ZXIgcmVhc29uLCBoYXN0aWx5IHNob3ZlIHRoZSBjb250ZW50cyBvZlxuICAgIC8vIHRoZSBlZGl0b3IgaW50byBzb21lIGtpbmQgb2Ygc3RvcmFnZS4gVGhpcyBvdmVyd3JpdGVzIHdoYXRldmVyIHdhc1xuICAgIC8vIHRoZXJlIGJlZm9yZS4gTm90ZSB0aGF0IHRoZXJlIGlzIG5vdCByZWFsbHkgYSB3YXkgb2YgaGFuZGxpbmcgdW5sb2FkXG4gICAgLy8gd2l0aCBvdXIgb3duIFVJIGFuZCBsb2dpYywgc2luY2UgdGhpcyBhbGxvd3MgZm9yIHdpZGVzcHJlYWQgYWJ1c2VcbiAgICAvLyBvZiBub3JtYWwgYnJvd3NlciBmdW5jdGlvbmFsaXR5LlxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiYmVmb3JldW5sb2FkXCIsIChldmVudCkgPT4ge1xuICAgICAgbGV0IGNvbnRlbnQgPSB7fTtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5idWZmZXJNYW5hZ2VyICYmXG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuYnVmZmVyTWFuYWdlci5idWZmZXJzKS5sZW5ndGggIT09IDBcbiAgICAgICkge1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gdGhpcy5idWZmZXJNYW5hZ2VyLmJ1ZmZlcnMpIHtcbiAgICAgICAgICBjb250ZW50W2tleV0gPSB0aGlzLmJ1ZmZlck1hbmFnZXIuYnVmZmVyc1trZXldLmdldFZhbHVlKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRlbnRbbmV3IERhdGUoKS5nZXRUaW1lKCkudG9TdHJpbmcoKV0gPSB0aGlzLmVkaXRvci5nZXRWYWx1ZSgpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLm1lbnUpIHtcbiAgICAgICAgTG9jYWxTdG9yYWdlLnNldEl0ZW0oXG4gICAgICAgICAgU1RPUkFHRV9MQVNUX0VESVRPUl9DT05URU5ULFxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGNvbnRlbnQpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLm1lbnUpIHtcbiAgICAgIC8vIElmIHRoZXJlIGlzIHByZXZpdXMgY29udGVudCBsb2FkIGl0LlxuICAgICAgbGV0IG9sZENvbnRlbnQgPSBKU09OLnBhcnNlKFxuICAgICAgICBMb2NhbFN0b3JhZ2UuZ2V0SXRlbShTVE9SQUdFX0xBU1RfRURJVE9SX0NPTlRFTlQpXG4gICAgICApO1xuICAgICAgaWYgKG9sZENvbnRlbnQpIHtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIG9sZENvbnRlbnQpIHtcbiAgICAgICAgICB0aGlzLm9wZW4ob2xkQ29udGVudFtrZXldLCBrZXkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm5ldygpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm5ldygpO1xuICAgIH1cblxuICAgIC8vIGlmICh0aGlzLm9wdGlvbnMubWVudSB8fCB0aGlzLm9wdGlvbnMuZXhwb3J0SWNvbikge1xuICAgIC8vICAgLy8gc2V0dXAgQ3Jvc3NTdG9yYWdlIGNsaWVudFxuICAgIC8vICAgdGhpcy5zdG9yYWdlID0gbmV3IENyb3NzU3RvcmFnZUNsaWVudChcImh0dHBzOi8vb3BlbmZyYW1lLmlvL2h1Yi5odG1sXCIpO1xuICAgIC8vICAgdGhpcy5zdG9yYWdlLm9uQ29ubmVjdCgpLnRoZW4oKCkgPT4ge1xuICAgIC8vICAgICBjb25zb2xlLmxvZyhcIkNvbm5lY3RlZCB0byBPcGVuRnJhbWUgW29dXCIpO1xuICAgIC8vICAgfSk7XG4gICAgLy8gICAvLyB9KS
234595iaW5kKHRoaXMpO1xuICAgIC8vIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbmV3KCkge1xuICAgIHRoaXMuc2V0Q29udGVudChcbiAgICAgIHRoaXMub3B0aW9ucy5mcmFnIHx8IEVNUFRZX0ZSQUdfU0hBREVSLFxuICAgICAgbmV3IERhdGUoKS5nZXRUaW1lKCkudG9TdHJpbmcoKVxuICAgICk7XG4gICAgdGhpcy50cmlnZ2VyKFwibmV3X2NvbnRlbnRcIiwge30pO1xuICAgIHRoaXMub3B0aW9ucy5mcmFnID0gbnVsbDtcbiAgfVxuXG4gIHNldENvbnRlbnQoc2hhZGVyLCB0YWJOYW1lKSB7XG4gICAgLy8gSWYgdGhlIHN0cmluZyBpcyBDT0RFXG4gICAgaWYgKHRoaXMuc2hhZGVyICYmIHRoaXMuc2hhZGVyLmNhbnZhcykge1xuICAgICAgaWYgKHRoaXMuZGVidWdnaW5nKSB7XG4gICAgICAgIHRoaXMuZGVidWdnaW5nID0gZmFsc2U7XG4gICAgICAgIGZvY3VzQWxsKHRoaXMuZWRpdG9yKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2hhZGVyLmNhbnZhcy5sb2FkKFxuICAgICAgICB0aGlzLm9wdGlvbnMuZnJhZ19oZWFkZXIgKyBzaGFkZXIgKyB0aGlzLm9wdGlvbnMuZnJhZ19mb290ZXJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZWRpdG9yKSB7XG4gICAgICBpZiAodGFiTmFtZSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuYnVmZmVyTWFuYWdlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuYnVmZmVyTWFuYWdlci5vcGVuKHRhYk5hbWUsIHNoYWRlcik7XG4gICAgICAgIHRoaXMuYnVmZmVyTWFuYWdlci5zZWxlY3QodGFiTmFtZSk7XG4gICAgICB9IFxuICAgICAgZWxzZSB7XG4gICAgICAgIHRoaXMuZWRpdG9yLnNldFZhbHVlKHNoYWRlcik7XG4gICAgICAgIHRoaXMuZWRpdG9yLnNldFNpemUobnVsbCwgdGhpcy5lZGl0b3IuZ2V0RG9jKCkuaGVpZ2h0ICsgXCJweFwiKTtcbiAgICAgICAgdGhpcy5lZGl0b3Iuc2V0U2l6ZShudWxsLCBcImF1dG9cIik7XG4gICAgICAgIHRoaXMuZmlsZW5hbWUgPSB0YWJOYW1lO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmNoYW5nZSA9IHRydWU7XG4gIH1cblxuICBvcGVuKHNoYWRlciwgdGFiTmFtZSkge1xuICAgIGlmICh0eXBlb2Ygc2hhZGVyID09PSBcIm9iamVjdFwiKSB7XG4gICAgICBjb25zdCByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgICAgbGV0IGdlID0gdGhpcztcbiAgICAgIHJlYWRlci5vbmxvYWQgPSAoZSkgPT4ge1xuICAgICAgICBnZS5zZXRDb250ZW50KGUudGFyZ2V0LnJlc3VsdCwgc2hhZGVyLm5hbWUpO1xuICAgICAgfTtcbiAgICAgIHJlYWRlci5yZWFkQXNUZXh0KHNoYWRlcik7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygc2hhZGVyID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBpZiAoL1xcLmZyYWckLy50ZXN0KHNoYWRlcikgfHwgL1xcLmZzJC8udGVzdChzaGFkZXIpKSB7XG4gICAgICAgIC8vIElmIHRoZSBzdHJpbmcgaXMgYW4gVVJMXG4gICAgICAgIHhoci5nZXQoc2hhZGVyLCAoZXJyb3IsIHJlc3BvbnNlLCBib2R5KSA9PiB7XG4gICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIkVycm9yIGRvd25sb2FkaW5nIFwiLCBzaGFkZXIsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5zZXRDb250ZW50KGJvZHksIHRhYk5hbWUpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0Q29udGVudChzaGFkZXIsIHRhYk5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldENvbnRlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yLmdldFZhbHVlKCk7XG4gIH1cblxuICBnZXRBdXRob3IoKSB7XG4gICAgbGV0IGNvbnRlbnQgPSB0aGlzLmdldENvbnRlbnQoKTtcbiAgICBsZXQgcmVzdWx0ID0gY29udGVudC5tYXRjaChcbiAgICAgIC9cXC9cXC9cXHMqW0F8YV11dGhvclxccypbXFw6XT9cXHMqKFtcXHd8XFxzfFxcQHxcXCh8XFwpfFxcLXxcXF9dKikvaVxuICAgICk7XG4gICAgaWYgKHJlc3VsdCAmJiAhKHJlc3VsdFsxXSA9PT0gXCIgXCIgfHwgcmVzdWx0WzFdID09PSBcIlwiKSkge1xuICAgICAgbGV0IGF1dGhvciA9IHJlc3VsdFsxXS5yZXBsYWNlKC8oXFxyXFxufFxcbnxcXHIpL2dtLCBcIlwiKTtcbiAgICAgIHJldHVybiBhdXRob3I7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBcInVua25vd25cIjtcbiAgICB9XG4gIH1cblxuICBnZXRUaXRsZSgpIHtcbiAgICBsZXQgY29udGVudCA9IHRoaXMuZ2V0Q29udGVudCgpO1xuICAgIGxldCByZXN1bHQgPSBjb250ZW50Lm1hdGNoKFxuICAgICAgL1xcL1xcL1xccypbVHx0XWl0bGVcXHMqOlxccyooW1xcd3xcXHN8XFxAfFxcKHxcXCl8XFwtfFxcX10qKS9pXG4gICAgKTtcbiAgICBpZiAocmVzdWx0ICYmICEocmVzdWx0WzFdID09PSBcIiBcIiB8fCByZXN1bHRbMV0gPT09IFwiXCIpKSB7XG4gICAgICBsZXQgdGl0bGUgPSByZXN1bHRbMV0ucmVwbGFjZSgvKFxcclxcbnxcXG58XFxyKS9nbSwgXCJcIik7XG4gICAgICByZXR1cm4gdGl0bGU7XG4gICAgfSBlbHNlIGlmICh0aGlzLmJ1ZmZlck1hbmFnZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyTWFuYWdlci5jdXJyZW50O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gXCJ1bmtub3duXCI7XG4gICAgfVxuICB9XG5cbiAgLy8gUmV0dXJucyBQcm9taXNlXG4gIGdldE9mVG9rZW4oKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RvcmFnZS5nZXQoXCJhY2Nlc3NUb2tlblwiKTtcbiAgfVxuXG4gIGRvd25sb2FkKCkge1xuICAgIGxldCBjb250ZW50ID0gdGhpcy5nZXRDb250ZW50KCk7XG4gICAgbGV0IG5hbWUgPSB0aGlzLmdldFRpdGxlKCk7XG4gICAgaWYgKG5hbWUgIT09IFwiXCIpIHtcbiAgICAgIG5hbWUgKz0gXCItXCI7XG4gICAgfVxuICAgIG5hbWUgKz0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICAvLyBEb3dubG9hZCBjb2RlXG4gICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtjb250ZW50XSwgeyB0eXBlOiBcInRleHQvcGxhaW5cIiB9KTtcbiAgICBzYXZlQXMoYmxvYiwgbmFtZSArIFwiLmZyYWdcIik7XG4gICAgdGhpcy5lZGl0b3IuZG9jLm1hcmtDbGVhbigpO1xuICAgIHRoaXMuY2hhbmdlID0gZmFsc2U7XG4gIH1cblxuICB1cGRhdGUoKSB7XG4gICAgaWYgKHRoaXMuZGVidWdnaW5nKSB7XG4gICAgICB0aGlzLmRlYnVnZ2luZyA9IGZhbHNlO1xuICAgICAgZm9jdXNBbGwodGhpcy5lZGl0b3IpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnZpc3VhbERlYnVnZ2VyLnRlc3RpbmdSZXN1bHRzLmxlbmd0aCkgXG4gICAgICB0aGlzLnZpc3VhbERlYnVnZ2VyLmNsZWFuKCk7XG4gICAgXG4gICAgdGhpcy5zaGFkZXIuY2FudmFzLmxvYWQoXG4gICAgICB0aGlzLm9wdGlvbnMuZnJhZ19oZWFkZXIgK1xuICAgICAgICB0aGlzLmVkaXRvci5nZXRWYWx1ZSgpICtcbiAgICAgICAgdGhpcy5vcHRpb25zLmZyYWdfZm9vdGVyXG4gICAgKTtcbiAgfVxuXG4gIGNyZWF0ZUZvbnRMaW5rKCkge1xuICAgIHZhciBoZWFkID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJoZWFkXCIpWzBdO1xuICAgIHZhciBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImxpbmtcIik7XG4gICAgbGluay5ocmVmID0gXCJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2ljb24/ZmFtaWx5PU1h
23459dGVyaWFsK0ljb25zXCI7XG4gICAgbGluay50eXBlID0gXCJ0ZXh0L2Nzc1wiO1xuICAgIGxpbmsucmVsID0gXCJzdHlsZXNoZWV0XCI7XG4gICAgbGluay5tZWRpYSA9IFwic2NyZWVuLHByaW50XCI7XG4gICAgaGVhZC5hcHBlbmRDaGlsZChsaW5rKTtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0uYXBwZW5kQ2hpbGQobGluayk7XG4gIH1cblxuICB0b2dnbGVQcmVzZW50YXRpb25XaW5kb3coZmxhZykge1xuICAgIHRoaXMucFdpbmRvd09wZW4gPSBmbGFnO1xuICAgIGlmIChmbGFnKVxuICAgICAgdGhpcy5zaGFkZXIub3BlbldpbmRvdygpO1xuICAgIGVsc2VcbiAgICAgIHRoaXMuc2hhZGVyLmNsb3NlV2luZG93KCk7XG4gIH1cblxuICBvbkNsb3NlUHJlc2VudGF0aW9uV2luZG93KCkge1xuICAgIHRoaXMucFdpbmRvd09wZW4gPSBmYWxzZTtcbiAgfVxufVxuXG53aW5kb3cuR2xzbEVkaXRvciA9IEdsc2xFZGl0b3I7XG5cbnZhciBHbHNsV2ViQ29tcG9uZW50ID0gZnVuY3Rpb24gKCkge307XG5HbHNsV2ViQ29tcG9uZW50LnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoSFRNTEVsZW1lbnQucHJvdG90eXBlKTtcbkdsc2xXZWJDb21wb25lbnQucHJvdG90eXBlLmNyZWF0ZWRDYWxsYmFjayA9IGZ1bmN0aW9uIGNyZWF0ZWRDYWxsYmFjaygpIHtcbiAgdmFyIG9wdGlvbnMgPSB7XG4gICAgY2FudmFzX3NpemU6IDE1MCxcbiAgICBjYW52YXNfZm9sbG93OiB0cnVlLFxuICAgIHRvb2x0aXBzOiB0cnVlLFxuICB9O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5hdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGF0dHJpYnV0ZSA9IHRoaXMuYXR0cmlidXRlc1tpXTtcbiAgICBpZiAoYXR0cmlidXRlLnNwZWNpZmllZCkge1xuICAgICAgdmFyIHZhbHVlID0gYXR0cmlidXRlLnZhbHVlO1xuXG4gICAgICBpZiAodmFsdWUgPT09IFwidHJ1ZVwiKVxuICAgICAgICB2YWx1ZSA9IHRydWU7XG4gICAgICBlbHNlIGlmICh2YWx1ZSA9PT0gXCJmYWxzZVwiKVxuICAgICAgICB2YWx1ZSA9IGZhbHNlO1xuICAgICAgZWxzZSBpZiAocGFyc2VJbnQodmFsdWUpKVxuICAgICAgICB2YWx1ZSA9IHBhcnNlSW50KHZhbHVlKTtcblxuICAgICAgb3B0aW9uc1thdHRyaWJ1dGUubmFtZV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICB0aGlzLmdsc2xFZGl0b3IgPSBuZXcgR2xzbEVkaXRvcih0aGlzLCBvcHRpb25zKTtcbn07XG5cbmRvY3VtZW50LnJlZ2lzdGVyRWxlbWVudChcImdsc2wtZWRpdG9yXCIsIEdsc2xXZWJDb21wb25lbnQpO1xuIiwiLy8gSW1wb3J0IENvZGVNaXJyb3JcbmltcG9ydCBDb2RlTWlycm9yIGZyb20gJ2NvZGVtaXJyb3InO1xuXG4vLyBJbXBvcnQgQ29kZU1pcnJvciBhZGRvbnMgYW5kIG1vZHVsZXNcbmltcG9ydCAnY29kZW1pcnJvci9hZGRvbi9zZWFyY2gvc2VhcmNoJztcbmltcG9ydCAnY29kZW1pcnJvci9hZGRvbi9zZWFyY2gvc2VhcmNoY3Vyc29yJztcbmltcG9ydCAnY29kZW1pcnJvci9hZGRvbi9jb21tZW50L2NvbW1lbnQnO1xuaW1wb3J0ICdjb2RlbWlycm9yL2FkZG9uL2RpYWxvZy9kaWFsb2cnO1xuaW1wb3J0ICdjb2RlbWlycm9yL2FkZG9uL2VkaXQvbWF0Y2hicmFja2V0cyc7XG5pbXBvcnQgJ2NvZGVtaXJyb3IvYWRkb24vZWRpdC9jbG9zZWJyYWNrZXRzJztcbmltcG9ydCAnY29kZW1pcnJvci9hZGRvbi93cmFwL2hhcmR3cmFwJztcbmltcG9ydCAnY29kZW1pcnJvci9hZGRvbi9mb2xkL2ZvbGRjb2RlJztcbmltcG9ydCAnY29kZW1pcnJvci9hZGRvbi9mb2xkL2ZvbGRndXR0ZXInO1xuaW1wb3J0ICdjb2RlbWlycm9yL2FkZG9uL2ZvbGQvaW5kZW50LWZvbGQnO1xuaW1wb3J0ICdjb2RlbWlycm9yL2FkZG9uL2hpbnQvc2hvdy1oaW50JztcbmltcG9ydCAnY29kZW1pcnJvci9hZGRvbi9oaW50L2phdmFzY3JpcHQtaGludCc7XG5pbXBvcnQgJ2NvZGVtaXJyb3IvYWRkb24vZGlzcGxheS9ydWxlcnMnO1xuaW1wb3J0ICdjb2RlbWlycm9yL2FkZG9uL2Rpc3BsYXkvcGFuZWwnO1xuaW1wb3J0ICdjb2RlbWlycm9yL2FkZG9uL2hpbnQvc2hvdy1oaW50JztcbmltcG9ydCAnY29kZW1pcnJvci9tb2RlL2NsaWtlL2NsaWtlLmpzJztcblxuLy8gS2V5bWFwXG5pbXBvcnQgJ2NvZGVtaXJyb3Iva2V5bWFwL3N1YmxpbWUnO1xuXG5jb25zdCBVTkZPQ1VTX0NMQVNTID0gJ2dlX2VkaXRvci11bmZvY3VzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRFZGl0b3IgKG1haW4pIHtcbiAgICBpZiAobWFpbi5vcHRpb25zLmxpbmVOdW1iZXJzID09PSB1bmRlZmluZWQpXG4gICAgICAgIG1haW4ub3B0aW9ucy5saW5lTnVtYmVycyA9IHRydWU7XG5cbiAgICAvLyBDUkVBVEUgQU5EIFNUQVJUIENPREVNSVJST1JcbiAgICBsZXQgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2dlX2VkaXRvcicpO1xuXG4gICAgLy8gSWYgdGhlcmUgaXMgYSBtZW51IG9mZnNldCB0aGUgZWRpdG9yIHRvIGNvbWUgYWZ0ZXIgaXRcbiAgICBpZiAobWFpbi5tZW51KVxuICAgICAgICBlbC5zdHlsZS5wYWRkaW5nVG9wID0gKG1haW4ubWVudS5lbC5jbGllbnRIZWlnaHQgfHwgbWFpbi5tZW51LmVsLm9mZnNldEhlaWdodCB8fCBtYWluLm1lbnUuZWwuc2Nyb2xsSGVpZ2h0KSArICdweCc7XG5cbiAgICBtYWluLmNvbnRhaW5lci5hcHBlbmRDaGlsZChlbCk7XG5cbiAgICBmdW5jdGlvbiBmaWxsSW5jbHVkZShjbSwgb3B0aW9uKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSggKGFjY2VwdCkgPT4ge1xuICAgICAgICAgIHNldFRpbWVvdXQoICgpID0+IHtcbiAgICAgICAgICAgIGxldCBjdXIgPSBjbS5nZXRDdXJzb3IoKS4gXG4gICAgICAgICAgICAgICAgbGluZSA9IGNtLmdldExpbmUoY3VyLmxpbmUpLnRyaW0oKTtcbiAgICAgICAgICAgIHZhciBzdGFydCA9IGN1ci5jaCwgZW5kID0gY3VyLmNoO1xuXG4gICAgICAgICAgICBpZiAobGluZS5zdGFydHNXaXRoKCcjaW5jbHVkZSBcXFwibHlnaWEnKSkge1xuICAgICAgICAgICAgICAgIGxldCBwYXRoID0gbGluZS5zdWJzdHJpbmcoMTApO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmx5Z2lhX2dsb2IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgIGdldEpTT04oJ2h0dHBzOi8vbHlnaWEueHl6L2dsc2wuanNvbicsIChlcnIsIGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVyciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgI
23459HRoaXMubHlnaWFfZ2xvYiA9IGRhdGE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnYXV0b2NvbXBsZXRlIGZvcicsIHBhdGgpO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnQgPSB0b2tlbi5zdGFydDtcbiAgICAgICAgICAgICAgICBsZXQgZW5kID0gY3VyLmNoO1xuICAgICAgICAgICAgICAgIGxldCBsaW5lTiA9IGN1ci5saW5lO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gW11cbiAgICAgICAgXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubHlnaWFfZ2xvYiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5seWdpYV9nbG9iLmZvckVhY2goICh3KSA9PiB7aWYgKHcuc3RhcnRzV2l0aChwYXRoKSkgcmVzdWx0LnB1c2goJyNpbmNsdWRlIFxcXCInICsgdyArICdcXFwiJyk7fSApO1xuICAgICAgICAgICAgICAgICAgcmVzdWx0LnNvcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2cobGluZU4sIHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYWNjZXB0KHtsaXN0OiByZXN1bHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb206IENvZGVNaXJyb3IuUG9zKGN1ci5saW5lLCBzdGFydCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvOiBDb2RlTWlycm9yLlBvcyhjdXIubGluZSwgZW5kKX0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGFjY2VwdChudWxsKVxuICAgICAgICAgIH0sIDEwMCk7XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgbGV0IGNtID0gQ29kZU1pcnJvcihlbCwge1xuICAgICAgICB2YWx1ZTogbWFpbi5vcHRpb25zLmZyYWcsXG4gICAgICAgIHZpZXdwb3J0TWFyZ2luOiBJbmZpbml0eSxcbiAgICAgICAgbGluZU51bWJlcnM6IG1haW4ub3B0aW9ucy5saW5lTnVtYmVycyxcbiAgICAgICAgbWF0Y2hCcmFja2V0czogdHJ1ZSxcbiAgICAgICAgbW9kZTogJ3gtc2hhZGVyL3gtZnJhZ21lbnQnLFxuICAgICAgICBrZXlNYXA6ICdzdWJsaW1lJyxcbiAgICAgICAgYXV0b0Nsb3NlQnJhY2tldHM6IHRydWUsXG4gICAgICAgIGV4dHJhS2V5czogeyAnQ3RybC1TcGFjZSc6ICdhdXRvY29tcGxldGUnIH0sXG4gICAgICAgIHNob3dDdXJzb3JXaGVuU2VsZWN0aW5nOiB0cnVlLFxuICAgICAgICB0aGVtZTogbWFpbi5vcHRpb25zLnRoZW1lLFxuICAgICAgICBkcmFnRHJvcDogZmFsc2UsXG4gICAgICAgIGluZGVudFVuaXQ6IG1haW4ub3B0aW9ucy5pbmRlbnRVbml0LFxuICAgICAgICB0YWJTaXplOiBtYWluLm9wdGlvbnMudGFiU2l6ZSxcbiAgICAgICAgaW5kZW50V2l0aFRhYnM6IG1haW4ub3B0aW9ucy5pbmRlbnRXaXRoVGFicyxcbiAgICAgICAgZ3V0dGVyczogbWFpbi5vcHRpb25zLmxpbmVOdW1iZXJzID8gWydDb2RlTWlycm9yLWxpbmVudW1iZXJzJywgJ2JyZWFrcG9pbnRzJ10gOiBmYWxzZSxcbiAgICAgICAgbGluZVdyYXBwaW5nOiBtYWluLm9wdGlvbnMubGluZVdyYXBwaW5nLFxuICAgICAgICBhdXRvZm9jdXM6IG1haW4ub3B0aW9ucy5hdXRvZm9jdXNcbiAgICB9KTtcblxuICAgIHJldHVybiBjbTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVuZm9jdXNMaW5lKGNtLCBsaW5lKSB7XG4gICAgaWYgKGxpbmUgPT09IG51bGwpIHtyZXR1cm47fVxuICAgIGNtLmdldERvYygpLmFkZExpbmVDbGFzcyhsaW5lLCAnZ3V0dGVyJywgVU5GT0NVU19DTEFTUyk7XG4gICAgY20uZ2V0RG9jKCkuYWRkTGluZUNsYXNzKGxpbmUsICd0ZXh0JywgVU5GT0NVU19DTEFTUyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1bmZvY3VzQWxsKGNtKSB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGogPSBjbS5nZXREb2MoKS5saW5lQ291bnQoKTsgaSA8PSBqOyBpKyspXG4gICAgICAgIHVuZm9jdXNMaW5lKGNtLCBpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZvY3VzTGluZShjbSwgbGluZSkge1xuICAgIGlmIChsaW5lID09PSBudWxsKSB7cmV0dXJuO31cbiAgICBjbS5nZXREb2MoKS5yZW1vdmVMaW5lQ2xhc3MobGluZSwgJ2d1dHRlcicsIFVORk9DVVNfQ0xBU1MpO1xuICAgIGNtLmdldERvYygpLnJlbW92ZUxpbmVDbGFzcyhsaW5lLCAndGV4dCcsIFVORk9DVVNfQ0xBU1MpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZm9jdXNBbGwoY20pIHtcbiAgICBmb3IgKGxldCBpID0gMCwgaiA9IGNtLmdldERvYygpLmxpbmVDb3VudCgpOyBpIDw9IGo7IGkrKylcbiAgICAgICAgZm9jdXNMaW5lKGNtLCBpKTtcbn1cbiIsImltcG9ydCBHbHNsQ2FudmFzIGZyb20gXCJnbHNsQ2FudmFzXCI7XG5pbXBvcnQgeyBzdWJzY3JpYmVJbnRlcmFjdGl2ZURvbSB9IGZyb20gXCIuLi90b29scy9pbnRlcmFjdGl2ZURvbVwiO1xuaW1wb3J0IE1lZGlhQ2FwdHVyZSBmcm9tIFwiLi4vdG9vbHMvbWVkaWFDYXB0dXJlXCI7XG5pbXBvcnQgTWVudUl0ZW0gZnJvbSBcIi4uL3VpL01lbnVJdGVtXCI7XG5pbXBvcnQgeyBzYXZlQXMgfSBmcm9tIFwiLi4vdG9vbHMvZG93bmxvYWRcIjtcblxudmFyIENPTlRST0xTX0NMQVNTTkFNRSA9IFwiZ2VfY29udHJvbFwiO1xudmFyIENPTlRST0xTX1BBTkVMX0NMQVNTTkFNRSA9IFwiZ2VfY29udHJvbF9wYW5lbFwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTaGFkZXIge1xuICBjb25zdHJ1Y3RvcihtYWluKSB7XG4gICAgdGhpcy5tYWluID0gbWFpbjtcbiAgICB0aGlzLm9wdGlvbnMgPSBtYWluLm9wdGlvbnM7XG4gICAgdGhpcy5mcmFnID0gXCJcIjtcblxuICAgIC8vIERPTSBDT05UQUlORVJcbiAgICB0aGlzLmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIFwiZ2VfY2FudmFzX2NvbnRhaW5lclwiKTtcbiAgICAvLyBDUkVBVEUgQU5EIFNUQVJUIEdMU0xDQU5WQVNcbiAgICB0aGlzLmVsQ2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICB0aGlzLmVsQ2FudmFzLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIFwiZ2VfY2FudmFzXCIpO1xuICAgIHRoaXMuZWxDYW52YXMuc2V0QXR0cmlidXRlKFxuICAgICAgXCJkYXRhLWZyYWdtZW50XCIsXG4gICAgICB0aGlzLm9wdGlvbnMuZnJhZ19oZWFkZXIgKyB0aGlzLm9wdGlvbnMuZnJhZyArIHRoaXMub3B0aW9ucy5mcmFnX2Zvb3RlclxuICAgICk7XG4gICAgdGhpcy5lbC5hcHBlbmRDaGlsZCh0aGlzLmVsQ2FudmFzKTtcbiAgICBsZXQgZ2xzbGNhbnZhcyA9IG5ldyBHbHNsQ2FudmFzKHRoaXMuZWxDYW52YXMsIHtcbiAgICAgIHByZW11bHRpcGxpZWRBbHBoYTogZmFsc2UsXG4gICAgICBwcmVzZXJ2ZURyYXdpbmdCdWZmZXI6IHRydWUsXG4gICAgICBiYWNrZ3JvdW5k
23459Q29sb3I6IFwicmdiYSgxLDEsMSwxKVwiLFxuICAgIH0pO1xuXG4gICAgbGV0IHdpZHRoID0gdGhpcy5vcHRpb25zLmNhbnZhc193aWR0aCB8fCB0aGlzLm9wdGlvbnMuY2FudmFzX3NpemUgfHwgXCIyNTBcIjtcbiAgICBsZXQgaGVpZ2h0ID1cbiAgICAgIHRoaXMub3B0aW9ucy5jYW52YXNfaGVpZ2h0IHx8IHRoaXMub3B0aW9ucy5jYW52YXNfc2l6ZSB8fCBcIjI1MFwiO1xuICAgIGdsc2xjYW52YXMuY2FudmFzLnN0eWxlLndpZHRoID0gd2lkdGggKyBcInB4XCI7XG4gICAgZ2xzbGNhbnZhcy5jYW52YXMuc3R5bGUuaGVpZ2h0ID0gaGVpZ2h0ICsgXCJweFwiO1xuICAgIGdsc2xjYW52YXMucmVzaXplKCk7XG5cbiAgICB0aGlzLmNhbnZhcyA9IGdsc2xjYW52YXM7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmltZ3MgJiYgdGhpcy5vcHRpb25zLmltZ3MubGVuZ3RoID4gMCkge1xuICAgICAgZm9yIChsZXQgaSBpbiB0aGlzLm9wdGlvbnMuaW1ncykge1xuICAgICAgICB0aGlzLmNhbnZhcy5zZXRVbmlmb3JtKFwidV90ZXhcIiArIGksIHRoaXMub3B0aW9ucy5pbWdzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNZWRpYSBDYXB0dXJlXG4gICAgdGhpcy5tZWRpYUNhcHR1cmUgPSBuZXcgTWVkaWFDYXB0dXJlKCk7XG4gICAgdGhpcy5tZWRpYUNhcHR1cmUuc2V0Q2FudmFzKHRoaXMuZWxDYW52YXMpO1xuICAgIHRoaXMuY2FudmFzLm9uKFwicmVuZGVyXCIsICgpID0+IHtcbiAgICAgIHRoaXMubWVkaWFDYXB0dXJlLmNvbXBsZXRlU2NyZWVuc2hvdCgpO1xuICAgIH0pO1xuXG4gICAgaWYgKG1haW4ub3B0aW9ucy5kaXNwbGF5TWVudSkge1xuICAgICAgLy8gQ09OVFJPTFNcbiAgICAgIHRoaXMuY29udHJvbHNDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidWxcIik7XG4gICAgICB0aGlzLmNvbnRyb2xzQ29udGFpbmVyLmNsYXNzTmFtZSA9IENPTlRST0xTX0NMQVNTTkFNRTtcbiAgICAgIHRoaXMuY29udHJvbFBhbmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInVsXCIpO1xuICAgICAgdGhpcy5jb250cm9sUGFuZWwuY2xhc3NOYW1lID0gQ09OVFJPTFNfUEFORUxfQ0xBU1NOQU1FO1xuICAgICAgdGhpcy5jb250cm9sc0NvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLmNvbnRyb2xQYW5lbCk7XG4gICAgICB0aGlzLmVsLmFwcGVuZENoaWxkKHRoaXMuY29udHJvbHNDb250YWluZXIpO1xuICAgICAgdGhpcy5jb250cm9scyA9IHt9O1xuICAgICAgLy8gcGxheS9zdG9wXG4gICAgICAvLyB0aGlzLmNvbnRyb2xzLnBsYXlQYXVzZSA9IG5ldyBNZW51SXRlbSh0aGlzLmNvbnRyb2xQYW5lbCwgJ2dlX2NvbnRyb2xfZWxlbWVudCcsICc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+cGF1c2U8L2k+JywgKGV2ZW50KSA9PiB7XG4gICAgICB0aGlzLmNvbnRyb2xzLnBsYXlQYXVzZSA9IG5ldyBNZW51SXRlbShcbiAgICAgICAgdGhpcy5jb250cm9sUGFuZWwsXG4gICAgICAgIFwiZ2VfY29udHJvbF9lbGVtZW50XCIsXG4gICAgICAgICc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+cGF1c2U8L2k+JyxcbiAgICAgICAgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBpZiAoZ2xzbGNhbnZhcy5wYXVzZWQpIHtcbiAgICAgICAgICAgIGdsc2xjYW52YXMucGxheSgpO1xuICAgICAgICAgICAgLy8gdGhpcy5jb250cm9scy5wbGF5UGF1c2UubmFtZSA9ICc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+cGF1c2U8L2k+JzsvLydQYXVzZSc7XG4gICAgICAgICAgICB0aGlzLmNvbnRyb2xzLnBsYXlQYXVzZS5uYW1lID1cbiAgICAgICAgICAgICAgJzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj5wYXVzZTwvaT4nOyAvLydQYXVzZSc7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsc2xjYW52YXMucGF1c2UoKTtcbiAgICAgICAgICAgIHRoaXMuY29udHJvbHMucGxheVBhdXNlLm5hbWUgPVxuICAgICAgICAgICAgICAnPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPnBsYXlfYXJyb3c8L2k+JzsgLy8nUGxheSc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgICAgLy8gcmVjXG4gICAgICB0aGlzLmlzQ2FwdHVyaW5nID0gZmFsc2U7XG4gICAgICAvLyBsZXQgcmVjID0gbmV3IE1lbnVJdGVtKHRoaXMuY29udHJvbFBhbmVsLCAnZ2VfY29udHJvbF9lbGVtZW50JywgJzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj5maWJlcl9tYW51YWxfcmVjb3JkPC9pPicsIChldmVudCkgPT4ge1xuICAgICAgbGV0IHJlYyA9IG5ldyBNZW51SXRlbShcbiAgICAgICAgdGhpcy5jb250cm9sUGFuZWwsXG4gICAgICAgIFwiZ2VfY29udHJvbF9lbGVtZW50XCIsXG4gICAgICAgICc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+JiN4RTA2MTs8L2k+JyxcbiAgICAgICAgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBpZiAodGhpcy5pc0NhcHR1cmluZykge1xuICAgICAgICAgICAgdGhpcy5zdG9wVmlkZW9DYXB0dXJlKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRWaWRlb0NhcHR1cmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgICB0aGlzLmNvbnRyb2xzLnJlYyA9IHJlYztcbiAgICAgIHRoaXMuY29udHJvbHMucmVjLmJ1dHRvbi5zdHlsZS5jb2xvciA9IFwicmVkXCI7XG5cbiAgICAgIC8vIHByZXNlbnQgbW9kZSAob25seSBpZiB0aGVyZSBpcyBhIHByZXNlbnRhdGlvbi5odG1sIGZpbGUgdG8gcG9pbnQgdG8pXG4gICAgICAvLyB0aGlzLmNvbnRyb2xzLnByZXNlbnRhdGlvbk1vZGUgPSBuZXcgTWVudUl0ZW0odGhpcy5jb250cm9sUGFuZWwsICdnZV9jb250cm9sX2VsZW1lbnQnLCAnPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPm9wZW5faW5fbmV3PC9pPicsIChldmVudCkgPT4ge1xuICAgICAgdGhpcy5jb250cm9scy5wcmVzZW50YXRpb25Nb2RlID0gbmV3IE1lbnVJdGVtKFxuICAgICAgICB0aGlzLmNvbnRyb2xQYW5lbCxcbiAgICAgICAgXCJnZV9jb250cm9sX2VsZW1lbnRcIixcbiAgICAgICAgJzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj5vcGVuX2luX25ldzwvaT4nLFxuICAgICAgICAoZXZlbnQpID0+IHtcbiAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIGlmIChtYWluLnBXaW5kb3dPcGVuKSB7XG4gICAgICAgICAgICBtYWluLnRvZ2dsZVByZXNlbnRhdGlvbldpbmRvdyhmYWxzZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1haW4udG9nZ2xlUHJlc2VudGF0aW9uV2luZG93KHRydWUpO1xuICAgICAgICAgI
23459H1cbiAgICAgICAgfVxuICAgICAgKTtcblxuICAgICAgdGhpcy5lbENvbnRyb2wgPSB0aGlzLmVsLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoQ09OVFJPTFNfQ0xBU1NOQU1FKVswXTtcbiAgICAgIHRoaXMuZWxDb250cm9sLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZWVudGVyXCIsIChldmVudCkgPT4ge1xuICAgICAgICB0aGlzLnNob3dDb250cm9scygpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLmVsQ29udHJvbC5hZGRFdmVudExpc3RlbmVyKFwibW91c2VsZWF2ZVwiLCAoZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5oaWRlQ29udHJvbHMoKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5lbENhbnZhcy5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIChldmVudCkgPT4ge1xuICAgICAgICBpZiAoZXZlbnQub2Zmc2V0WSA+IHRoaXMuZWxDYW52YXMuY2xpZW50SGVpZ2h0ICogMC42Nikge1xuICAgICAgICAgIHRoaXMuc2hvd0NvbnRyb2xzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5oaWRlQ29udHJvbHMoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLmhpZGVDb250cm9scygpO1xuICAgIH1cblxuICAgIC8vID09PT09PT09PT0gRVZFTlRTXG4gICAgLy8gRHJhZ2dhYmxlL3Jlc2l6YWJsZS9zbmFwcGFibGVcbiAgICBpZiAoXG4gICAgICBtYWluLm9wdGlvbnMuY2FudmFzX2RyYWdnYWJsZSB8fFxuICAgICAgbWFpbi5vcHRpb25zLmNhbnZhc19yZXNpemFibGUgfHxcbiAgICAgIG1haW4ub3B0aW9ucy5jYW52YXNfc25hcGFibGVcbiAgICApIHtcbiAgICAgIHN1YnNjcmliZUludGVyYWN0aXZlRG9tKHRoaXMuZWwsIHtcbiAgICAgICAgbW92ZTogbWFpbi5vcHRpb25zLmNhbnZhc19kcmFnZ2FibGUsXG4gICAgICAgIHJlc2l6ZTogbWFpbi5vcHRpb25zLmNhbnZhc19yZXNpemFibGUsXG4gICAgICAgIHNuYXA6IG1haW4ub3B0aW9ucy5jYW52YXNfc25hcGFibGUsXG4gICAgICB9KTtcblxuICAgICAgaWYgKG1haW4ub3B0aW9ucy5jYW52YXNfc2l6ZSA9PT0gXCJoYWxmc2NyZWVuXCIpIHtcbiAgICAgICAgdGhpcy5lbC5zbmFwUmlnaHQoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5lbC5vbihcIm1vdmVcIiwgKGV2ZW50KSA9PiB7XG4gICAgICAgIGV2ZW50LmVsLnN0eWxlLndpZHRoID0gZXZlbnQuZWwuY2xpZW50V2lkdGggKyBcInB4XCI7XG4gICAgICAgIGV2ZW50LmVsLnN0eWxlLmhlaWdodCA9IGV2ZW50LmVsLmNsaWVudEhlaWdodCArIFwicHhcIjtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5lbC5vbihcInJlc2l6ZVwiLCAoZXZlbnQpID0+IHtcbiAgICAgICAgZ2xzbGNhbnZhcy5jYW52YXMuc3R5bGUud2lkdGggPSBldmVudC5lbC5jbGllbnRXaWR0aCArIFwicHhcIjtcbiAgICAgICAgZ2xzbGNhbnZhcy5jYW52YXMuc3R5bGUuaGVpZ2h0ID0gZXZlbnQuZWwuY2xpZW50SGVpZ2h0ICsgXCJweFwiO1xuICAgICAgICBnbHNsY2FudmFzLnJlc2l6ZSgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlcmUgaXMgYSBtZW51IG9mZnNldCB0aGUgZWRpdG9yIHRvIGNvbWUgYWZ0ZXIgaXRcbiAgICBpZiAobWFpbi5tZW51KSB7XG4gICAgICB0aGlzLmVsLnN0eWxlLnRvcCA9XG4gICAgICAgIChtYWluLm1lbnUuZWwuY2xpZW50SGVpZ2h0IHx8XG4gICAgICAgICAgbWFpbi5tZW51LmVsLm9mZnNldEhlaWdodCB8fFxuICAgICAgICAgIG1haW4ubWVudS5lbC5zY3JvbGxIZWlnaHQpICsgXCJweFwiO1xuICAgIH1cblxuICAgIC8vIEFkZCBhbGwgdGhpcyB0byB0aGUgbWFpbiBjb250YWluZXJcbiAgICBtYWluLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLmVsKTtcbiAgICBnbHNsY2FudmFzLnJlc2l6ZSgpO1xuICB9XG5cbiAgaGlkZUNvbnRyb2xzKCkge1xuICAgIGlmICh0aGlzLmVsQ29udHJvbCAmJiB0aGlzLmVsQ29udHJvbC5jbGFzc05hbWUgPT09IENPTlRST0xTX0NMQVNTTkFNRSkge1xuICAgICAgdGhpcy5lbENvbnRyb2wuY2xhc3NOYW1lID1cbiAgICAgICAgQ09OVFJPTFNfQ0xBU1NOQU1FICsgXCIgXCIgKyBDT05UUk9MU19DTEFTU05BTUUgKyBcIl9oaWRkZW5cIjtcbiAgICB9XG4gIH1cblxuICBzaG93Q29udHJvbHMoKSB7XG4gICAgaWYgKFxuICAgICAgdGhpcy5lbENvbnRyb2wgJiZcbiAgICAgIHRoaXMuZWxDb250cm9sLmNsYXNzTmFtZSA9PT1cbiAgICAgICAgQ09OVFJPTFNfQ0xBU1NOQU1FICsgXCIgXCIgKyBDT05UUk9MU19DTEFTU05BTUUgKyBcIl9oaWRkZW5cIlxuICAgICkge1xuICAgICAgdGhpcy5lbENvbnRyb2wuY2xhc3NOYW1lID0gQ09OVFJPTFNfQ0xBU1NOQU1FO1xuICAgIH1cbiAgfVxuXG4gIHJlcXVlc3RSZWRyYXcoKSB7XG4gICAgdGhpcy5jYW52YXMuZm9yY2VSZW5kZXIgPSB0cnVlO1xuICAgIHRoaXMuY2FudmFzLnJlbmRlcigpO1xuICB9XG5cbiAgc2NyZWVuc2hvdCgpIHtcbiAgICB0aGlzLnJlcXVlc3RSZWRyYXcoKTtcbiAgICByZXR1cm4gdGhpcy5tZWRpYUNhcHR1cmUuc2NyZWVuc2hvdCgpO1xuICB9XG5cbiAgc3RhcnRWaWRlb0NhcHR1cmUoKSB7XG4gICAgdGhpcy5yZXF1ZXN0UmVkcmF3KCk7XG4gICAgaWYgKHRoaXMubWVkaWFDYXB0dXJlLnN0YXJ0VmlkZW9DYXB0dXJlKCkpIHtcbiAgICAgIHRoaXMuaXNDYXB0dXJpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5jb250cm9scy5yZWMuYnV0dG9uLnN0eWxlLmNvbG9yID0gXCJ3aGl0ZVwiO1xuICAgICAgLy8gdGhpcy5jb250cm9scy5yZWMubmFtZSA9ICc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+c3RvcDwvaT4nO1xuICAgICAgdGhpcy5jb250cm9scy5yZWMubmFtZSA9ICc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+JiN4RTA2MTs8L2k+JztcbiAgICB9XG4gIH1cblxuICBzdG9wVmlkZW9DYXB0dXJlKCkge1xuICAgIGlmICh0aGlzLmlzQ2FwdHVyaW5nKSB7XG4gICAgICB0aGlzLmlzQ2FwdHVyaW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmNvbnRyb2xzLnJlYy5idXR0b24uc3R5bGUuY29sb3IgPSBcInJlZFwiO1xuICAgICAgLy8gdGhpcy5jb250cm9scy5yZWMubmFtZSA9ICc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+ZmliZXJfbWFudWFsX3JlY29yZDwvaT4nO1xuICAgICAgdGhpcy5jb250cm9scy5yZWMubmFtZSA9ICc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+c3RvcDwvaT4nO1xuICAgICAgdGhpcy5tZWRpYUNhcHR1cmUuc3RvcFZpZGVvQ2FwdHVyZSgpLnRoZW4oKHZpZGVvKSA9PiB7XG4gICAgICAgI
23459HNhdmVBcyh2aWRlby5ibG9iLCBgJHtOdW1iZXIobmV3IERhdGUoKSl9LndlYm1gKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG9wZW5XaW5kb3coKSB7XG4gICAgdGhpcy5vcmlnaW5hbFNpemUgPSB7XG4gICAgICB3aWR0aDogdGhpcy5jYW52YXMuY2FudmFzLmNsaWVudFdpZHRoLFxuICAgICAgaGVpZ2h0OiB0aGlzLmNhbnZhcy5jYW52YXMuY2xpZW50SGVpZ2h0LFxuICAgIH07XG4gICAgdGhpcy5wcmVzZW50YXRpb25XaW5kb3cgPSB3aW5kb3cub3BlbihcIlwiLCBcIl9ibGFua1wiLCBcInByZXNlbnRhdGlvbldpbmRvd1wiKTtcbiAgICB0aGlzLnNldFVwUHJlc2VudGF0aW9uV2luZG93KCk7XG4gIH1cblxuICBjbG9zZVdpbmRvdygpIHtcbiAgICBpZiAodGhpcy5wcmVzZW50YXRpb25XaW5kb3cpIHtcbiAgICAgIHRoaXMucHJlc2VudGF0aW9uV2luZG93LmNsb3NlKCk7XG4gICAgfVxuICB9XG5cbiAgc2V0Q2FudmFzU2l6ZSh3LCBoKSB7XG4gICAgdGhpcy5jYW52YXMuY2FudmFzLnN0eWxlLndpZHRoID0gdyArIFwicHhcIjtcbiAgICB0aGlzLmNhbnZhcy5jYW52YXMuc3R5bGUuaGVpZ2h0ID0gaCArIFwicHhcIjtcbiAgfVxuXG4gIHNldFVwUHJlc2VudGF0aW9uV2luZG93KCkge1xuICAgIHRoaXMucHJlc2VudGF0aW9uV2luZG93LmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5jYW52YXMuY2FudmFzKTtcbiAgICB2YXIgZCA9IHRoaXMucHJlc2VudGF0aW9uV2luZG93LmRvY3VtZW50O1xuICAgIHZhciBkaXYgPSBkLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgZGl2LmFwcGVuZENoaWxkKGQuY3JlYXRlVGV4dE5vZGUoXCJQcm9qZWN0b3IgbW9kZVwiKSk7XG4gICAgdmFyIHNwYW4gPSB0aGlzLnByZXNlbnRhdGlvbldpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgICBkaXYuYXBwZW5kQ2hpbGQoc3Bhbik7XG4gICAgc3Bhbi5hcHBlbmRDaGlsZChcbiAgICAgIGQuY3JlYXRlVGV4dE5vZGUoXG4gICAgICAgIFwiIC0gSWYgdGhlIGNhbnZhcyBkb2Vzbid0IHVwZGF0ZSwgZHJhZyB0aGlzIHdpbmRvdyBhbmQgcmV2ZWFsIHRoZSBlZGl0b3JcIlxuICAgICAgKVxuICAgICk7XG4gICAgZC5ib2R5LmFwcGVuZENoaWxkKGRpdik7XG5cbiAgICBkLnRpdGxlID0gXCJHTFNMIEVkaXRvclwiO1xuICAgIGQuYm9keS5zdHlsZS5wYWRkaW5nID0gXCIwXCI7XG4gICAgZC5ib2R5LnN0eWxlLm1hcmdpbiA9IFwiMFwiO1xuICAgIGQuYm9keS5zdHlsZS5iYWNrZ3JvdW5kID0gXCIjMTcxZTIyXCI7XG4gICAgZC5ib2R5LnN0eWxlLm92ZXJmbG93ID0gXCJoaWRkZW5cIjtcblxuICAgIGRpdi5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICBkaXYuc3R5bGUud2lkdGggPSBcIjEwMCVcIjtcbiAgICBkaXYuc3R5bGUuYmFja2dyb3VuZCA9IFwicmdiYSgwLCAwLCAwLCAwLjUpXCI7XG4gICAgZGl2LnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xuICAgIGRpdi5zdHlsZS50b3AgPSBcIjBcIjtcbiAgICBkaXYuc3R5bGUubGVmdCA9IFwiMFwiO1xuICAgIGRpdi5zdHlsZS5yaWdodCA9IFwiMFwiO1xuICAgIGRpdi5zdHlsZS5wYWRkaW5nID0gXCIxNnB4XCI7XG4gICAgZGl2LnN0eWxlLmNvbG9yID0gXCIjZmZmZmZmXCI7XG4gICAgZGl2LnN0eWxlLmZvbnRTaXplID0gXCIxNHB4XCI7XG4gICAgZGl2LnN0eWxlLmZvbnRGYW1pbHkgPSBcIkhlbHZldGljYSwgR2VuZXZhLCBzYW5zLXNlcmlmXCI7XG4gICAgZGl2LnN0eWxlLmZvbnRXZWlnaHQgPSBcIjQwMFwiO1xuICAgIGRpdi5zdHlsZS5sZXR0ZXJTcGFjaW5nID0gXCIwLjFlbVwiO1xuICAgIGRpdi5zdHlsZS50ZXh0QWxpZ24gPSBcImNlbnRlclwiO1xuICAgIGRpdi5zdHlsZS5vcGFjaXR5ID0gXCIxXCI7XG4gICAgZGl2LnN0eWxlLnpJbmRleCA9IFwiOTk5OVwiO1xuICAgIGRpdi5zdHlsZS5zZXRQcm9wZXJ0eShcIi13ZWJraXQtdHJhbnNpdGlvblwiLCBcIm9wYWNpdHkgMS41c1wiKTtcbiAgICBkaXYuc3R5bGUuc2V0UHJvcGVydHkoXCItbW96LXRyYW5zaXRpb25cIiwgXCJvcGFjaXR5IDEuNXNcIik7XG4gICAgZGl2LnN0eWxlLnNldFByb3BlcnR5KFwidHJhbnNpdGlvblwiLCBcIm9wYWNpdHkgMS41c1wiKTtcblxuICAgIHNwYW4uc3R5bGUuY29sb3IgPSBcInJnYmEoMjU1LCAyNTUsIDI1NSwgMC41KVwiO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBkaXYuc3R5bGUub3BhY2l0eSA9IDA7XG4gICAgfSwgNDAwMCk7XG5cbiAgICB0aGlzLnNldENhbnZhc1NpemUoXG4gICAgICB0aGlzLnByZXNlbnRhdGlvbldpbmRvdy5pbm5lcldpZHRoLFxuICAgICAgdGhpcy5wcmVzZW50YXRpb25XaW5kb3cuaW5uZXJIZWlnaHRcbiAgICApO1xuICAgIHRoaXMucHJlc2VudGF0aW9uV2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICBcInJlc2l6ZVwiLFxuICAgICAgdGhpcy5vblByZXNlbnRhdGlvbldpbmRvd1Jlc2l6ZS5iaW5kKHRoaXMpXG4gICAgKTtcbiAgICB0aGlzLnByZXNlbnRhdGlvbldpbmRvdy5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgXCJ1bmxvYWRcIixcbiAgICAgIHRoaXMub25QcmVzZW50YXRpb25XaW5kb3dDbG9zZS5iaW5kKHRoaXMpXG4gICAgKTtcbiAgfVxuXG4gIG9uUHJlc2VudGF0aW9uV2luZG93Q2xvc2UoKSB7XG4gICAgdGhpcy5lbC5hcHBlbmRDaGlsZCh0aGlzLmNhbnZhcy5jYW52YXMpO1xuICAgIHRoaXMuc2V0Q2FudmFzU2l6ZSh0aGlzLm9yaWdpbmFsU2l6ZS53aWR0aCwgdGhpcy5vcmlnaW5hbFNpemUuaGVpZ2h0KTtcbiAgICB0aGlzLmNhbnZhcy5yZXNpemUoKTtcblxuICAgIHRoaXMubWFpbi5vbkNsb3NlUHJlc2VudGF0aW9uV2luZG93KCk7XG4gICAgdGhpcy5tYWluLm1lbnUub25DbG9zZVByZXNlbnRhdGlvbldpbmRvdygpO1xuICAgIHRoaXMucHJlc2VudGF0aW9uV2luZG93ID0gbnVsbDtcbiAgfVxuXG4gIG9uUHJlc2VudGF0aW9uV2luZG93UmVzaXplKCkge1xuICAgIGlmICh0aGlzLnByZXNlbnRhdGlvbldpbmRvdykge1xuICAgICAgdGhpcy5zZXRDYW52YXNTaXplKFxuICAgICAgICB0aGlzLnByZXNlbnRhdGlvbldpbmRvdy5pbm5lcldpZHRoLFxuICAgICAgICB0aGlzLnByZXNlbnRhdGlvbldpbmRvdy5pbm5lckhlaWdodFxuICAgICAgKTtcbiAgICAgIHRoaXMuY2FudmFzLnJlc2l6ZSgpO1xuICAgIH1cbiAgfVxufVxuIiwiLy8gSW1wb3J0IENvZGVNaXJyb3JcbmltcG9ydCBDb2RlTWlycm9yIGZyb20gJ2NvZGVtaXJyb3InO1xuaW1wb3J0ICdjb2RlbWlycm9yL21vZGUvY2xpa2UvY2xpa2UuanMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCdWZmZXJNYW5hZ2VyIHtcbiAgICBjb25zdHJ1Y3RvciAobWFpbikge1xuICAgICAgICB0aGlzLm1haW4gPSBtYWluO1xuICAgICAgICB0aGlzLmJ1ZmZlcnMgPSB7fTtcbiAgICAgICAgdGhpcy50YWJzID0ge307XG4gICAgICAgI
23459HRoaXMuY3VycmVudCA9ICd1bnRpdGxlZCc7XG4gICAgfVxuXG4gICAgb3BlbiAobmFtZSwgY29udGVudCkge1xuICAgICAgICBpZiAoIXRoaXMuZWwpIHtcbiAgICAgICAgICAgIC8vIENyZWF0ZSBET00gZWxlbWVudFxuICAgICAgICAgICAgdGhpcy5lbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3VsJyk7XG4gICAgICAgICAgICB0aGlzLmVsLmNsYXNzTmFtZSA9ICdnZV9wYW5lbCc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5tYWluLmNoYW5nZSAmJiB0aGlzLmN1cnJlbnQgPT09ICd1bnRpdGxlZCcpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdPcGVuIEN1cnJlbnQgaW4gYSBkaWZmZXJlbnQgdGFiJyk7XG4gICAgICAgICAgICB0aGlzLm9wZW4odGhpcy5jdXJyZW50LCB0aGlzLm1haW4uZ2V0Q29udGVudCgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYnVmZmVyc1tuYW1lXSA9IENvZGVNaXJyb3IuRG9jKGNvbnRlbnQsICd4LXNoYWRlci94LWZyYWdtZW50Jyk7XG5cbiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IHRhYlxuICAgICAgICBsZXQgdGFiID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKTtcbiAgICAgICAgdGFiLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnZ2VfcGFuZWxfdGFiJyk7XG4gICAgICAgIHRhYi50ZXh0Q29udGVudCA9IG5hbWU7XG4gICAgICAgIENvZGVNaXJyb3Iub24odGFiLCAnY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdChuYW1lKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbGV0IGNsb3NlID0gdGFiLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKSk7XG4gICAgICAgIGNsb3NlLnRleHRDb250ZW50ID0gJ3gnO1xuICAgICAgICBjbG9zZS5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2dlX3BhbmVsX3RhYl9jbG9zZScpO1xuICAgICAgICBDb2RlTWlycm9yLm9uKGNsb3NlLCAnY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlKG5
23459hbWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLmVsLmFwcGVuZENoaWxkKHRhYik7XG4gICAgICAgIHRoaXMudGFic1tuYW1lXSA9IHRhYjtcblxuICAgICAgICBpZiAodGhpcy5lbCAmJiAhdGhpcy5wYW5lbCAmJiB0aGlzLmdldExlbmd0aCgpID4gMSkge1xuICAgICAgICAgICAgLy8gQ3JlYXRlIFBhbmVsIENNIGVsZW1lbnRcbiAgICAgICAgICAgIHRoaXMucGFuZWwgPSB0aGlzLm1haW4uZWRpdG9yLmFkZFBhbmVsKHRoaXMuZWwsIHsgcG9zaXRpb246ICd0b3AnIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2VsZWN0IChuYW1lKSB7XG4gICAgICAgIGxldCBidWYgPSB0aGlzLmJ1ZmZlcnNbbmFtZV07XG5cbiAgICAgICAgaWYgKGJ1ZiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYnVmLmdldEVkaXRvcigpKSB7XG4gICAgICAgICAgICBidWYgPSBidWYubGlua2VkRG9jKHsgc2hhcmVkSGlzdDogdHJ1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgb2xkID0gdGhpcy5tYWluLmVkaXRvci5zd2FwRG9jKGJ1Zik7XG4gICAgICAgIGxldCBsaW5rZWQgPSBvbGQuaXRlckxpbmtlZERvY3MoZnVuY3Rpb24oZG9jKSB7XG4gICAgICAgICAgICBsaW5rZWQgPSBkb2M7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAobGlua2VkKSB7XG4gICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIGRvY3VtZW50IGluIGJ1ZmZlcnMgaXMgdGhlIG9uZSB0aGUgb3RoZXIgdmlldyBpcyBsb29raW5nIGF0XG4gICAgICAgICAgICBmb3IgKGxldCBidWZmZXJOYW1lIGluIHRoaXMuYnVmZmVycykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmJ1ZmZlcnNbYnVmZmVyTmFtZV0gPT09IG9sZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1ZmZlcnNbYnVmZmVyTmFtZV0gPSBsaW5rZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb2xkLnVubGlua0RvYyhsaW5rZWQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm1haW4ub3B0aW9ucy5hdXRvZm9jdXMpIHtcbiAgICAgICAgICAgIHRoaXMubWFpbi5lZGl0b3IuZm9jdXMoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1haW4uc2V0Q29udGVudCh0aGlzLm1haW4uZ2V0Q29udGVudCgpKTtcblxuICAgICAgICBpZiAodGhpcy50YWJzW3RoaXMuY3VycmVudF0pIHtcbiAgICAgICAgICAgIHRoaXMudGFic1t0aGlzLmN1cnJlbnRdLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnZ2VfcGFuZWxfdGFiJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50YWJzW25hbWVdLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnZ2VfcGFuZWxfdGFiX2FjdGl2ZScpO1xuICAgICAgICB0aGlzLmN1cnJlbnQgPSBuYW1lO1xuXG4gICAgICAgIHRoaXMubWFpbi5lZGl0b3Iuc2V0U2l6ZShudWxsLCAnYXV0bycpO1xuICAgICAgICB0aGlzLm1haW4uZWRpdG9yLmdldFdyYXBwZXJFbGVtZW50KCkuc3R5bGUuaGVpZ2h0ID0gJ2F1dG8nO1xuXG4gICAgICAgIHRoaXMubWFpbi50cmlnZ2VyKCduZXdfY29udGVudCcsIHt9KTtcbiAgICB9XG5cbiAgICBjbG9zZSAobmFtZSkge1xuICAgICAgICBsZXQgbmVlZENoYW5nZSA9IG5hbWUgPT09IHRoaXMuZ2V0Q3VycmVudCgpO1xuXG4gICAgICAgIHRoaXMuZWwucmVtb3ZlQ2hpbGQodGhpcy50YWJzW25hbWVdKTtcbiAgICAgICAgZGVsZXRlIHRoaXMudGFic1tuYW1lXTtcbiAgICAgICAgZGVsZXRlIHRoaXMuYnVmZmVyc1tuYW1lXTtcblxuICAgICAgICBpZiAodGhpcy5nZXRMZW5ndGgoKSA9PT0gMSkge1xuICAgICAgICAgICAgdGhpcy5wYW5lbC5jbGVhcigpO1xuICAgICAgICAgICAgdGhpcy5wYW5lbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuZWwgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobmVlZENoYW5nZSkge1xuICAgICAgICAgICAgZm9yIChsZXQgcHJvcCBpbiB0aGlzLnRhYnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdChwcm9wKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldEN1cnJlbnQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50O1xuICAgIH1cblxuICAgIGdldExlbmd0aCAoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmJ1ZmZlcnMpLmxlbmd0aDtcbiAgICB9XG59XG4iLCIvKlxuT3JpZ2luYWw6IGh0dHBzOi8vZ2l0aHViLmNvbS90YW5ncmFtcy90YW5ncmFtLXBsYXkvYmxvYi9naC1wYWdlcy9zcmMvanMvYWRkb25zL3VpL0ZpbGVEcm9wLmpzXG5BdXRob3I6IExvdSBIdWFuZyAoQHNhaWtvZmlzaClcbiovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZpbGVEcm9wIHtcbiAgICBjb25zdHJ1Y3RvciAobWFpbikge1xuICAgICAgICAvLyBTZXQgdXAgZHJhZy9kcm9wIGZpbGUgbGlzdGVuZXJzXG4gICAgICAgIG1haW4uY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdlbnRlcicsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgLy8gQ2hlY2sgdG8gbWFrZSBzdXJlIHRoYXQgZHJvcHBlZCBpdGVtcyBhcmUgZmlsZXMuXG4gICAgICAgICAgICAvLyBUaGlzIHByZXZlbnRzIG90aGVyIGRyYWdzIChlLmcuIHRleHQgaW4gZWRpdG9yKVxuICAgICAgICAgICAgLy8gZnJvbSB0dXJuaW5nIG9uIHRoZSBmaWxlIGRyb3AgYXJlYS5cbiAgICAgICAgICAgIC8vIFNlZSBoZXJlOiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzY4NDgwNDMvaG93LWRvLWktZGV0ZWN0LWEtZmlsZS1pcy1iZWluZy1kcmFnZ2VkLXJhdGhlci10aGFuLWEtZHJhZ2dhYmxlLWVsZW1lbnQtb24tbXktcGFcbiAgICAgICAgICAgIC8vIFRlc3RlZCBpbiBDaHJvbWUsIEZpcmVmb3gsIFNhZmFyaSA4XG4gICAgICAgICAgICB2Y
23459XIgdHlwZXMgPSBldmVudC5kYXRhVHJhbnNmZXIudHlwZXM7XG4gICAgICAgICAgICBpZiAodHlwZXMgIT09IG51bGwgJiYgKCh0eXBlcy5pbmRleE9mKSA/ICh0eXBlcy5pbmRleE9mKCdGaWxlcycpICE9PSAtMSkgOiB0eXBlcy5jb250YWlucygnYXBwbGljYXRpb24veC1tb3otZmlsZScpKSkge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgZXZlbnQuZGF0YVRyYW5zZmVyLmRyb3BFZmZlY3QgPSAnY29weSc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgIG1haW4uY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdvdmVyJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAvLyBSZXF1aXJlZCB0byBwcmV2ZW50IGJyb3dzZXIgZnJvbSBuYXZpZ2F0aW5nIHRvIGEgZmlsZVxuICAgICAgICAgICAgLy8gaW5zdGVhZCBvZiByZWNlaXZpbmcgYSBkYXRhIHRyYW5zZmVyXG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9LCBmYWxzZSk7XG5cbiAgICAgICAgbWFpbi5jb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ2xlYXZlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9LCB0cnVlKTtcblxuICAgICAgICBtYWluLmNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdkcm9wJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGFUcmFuc2Zlci5maWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZSA9IGV2ZW50LmRhdGFUcmFuc2Zlci5maWxlc1swXTtcbiAgICAgICAgICAgICAgICBtYWluLm9wZW4oZmlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIGZhbHNlKTtcbiAgICB9XG59XG4iLCJleHBvcnQgZGVmYXVsdCBjbGFzcyBIYXNoV2F0Y2gge1xuICAgIGNvbnN0cnVjdG9yIChtYWluKSB7XG4gICAgICAgIHRoaXMubWFpbiA9IG1haW47XG4gICAgICAgIHRoaXMuY2hlY2soKTtcblxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignaGFzaGNoYW5nZScsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2soKTtcbiAgICAgICAgfSwgZmFsc2UpO1xuICAgIH1cblxuICAgIGNoZWNrKCkge1xuICAgICAgICBpZiAod2luZG93LmxvY2F0aW9uLmhhc2ggIT09ICcnKSB7XG4gICAgICAgICAgICB0aGlzLm1haW4ub3B0aW9ucy5pbWdzID0gW107XG5cbiAgICAgICAgICAgIGxldCBoYXNoZXMgPSBsb2NhdGlvbi5oYXNoLnNwbGl0KCcmJyk7XG4gICAgICAgICAgICBmb3IgKGxldCBpIGluIGhhc2hlcykge1xuICAgICAgICAgICAgICAgIGxldCBleHQgPSBoYXNoZXNbaV0uc3Vic3RyKGhhc2hlc1tpXS5sYXN0SW5kZXhPZignLicpICsgMSk7XG4gICAgICAgICAgICAgICAgbGV0IHBhdGggPSBoYXNoZXNbaV07XG5cbiAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IGhhc2ggaWYgaXMgcHJlc2VudFxuICAgICAgICAgICAgICAgIGlmIChwYXRoLnNlYXJjaCgnIycpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoLnN1YnN0cigxKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgZmlsZW5hbWUgPSBwYXRoLnNwbGl0KCcvJykucG9wKCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoZXh0ID09PSAnZnJhZycpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYWluLm9wZW4ocGF0aCwgZmlsZW5hbWUucmVwbGFjZSgvXFwuW14vLl0rJC8sICcnKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGV4dCA9PT0gJ3BuZycgfHwgZXh0ID09PSAnanBnJyB8fCBleHQgPT09ICdQTkcnIHx8IGV4dCA9PT0gJ0pQRycpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYWluLm9wdGlvbnMuaW1ncy5wdXNoKHBhdGgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBxdWVyeSA9IHBhcnNlUXVlcnkod2luZG93LmxvY2F0aW9uLnNlYXJjaC5zbGljZSgxKSk7XG4gICAgICAgIGlmIChxdWVyeSkge1xuICAgICAgICAgICAgZm9yIChsZXQga2V5IGluIHF1ZXJ5KSB7XG4gICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gJ2xvZycpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubWFpbi5idWZmZXJNYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbG9ncyA9IHF1ZXJ5LmxvZy5zcGxpdCgnLCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSBpbiBsb2dzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYWluLm9wZW4oJ2h0dHBzOi8vdGhlYm9va29mc2hhZGVycy5jb20vbG9nLycgKyBsb2dzW2ldICsgJy5mcmFnJywgbG9nc1tpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1haW4ub3BlbignaHR0cHM6Ly90aGVib29rb2ZzaGFkZXJzLmNvbS9sb2cvJyArIHF1ZXJ5LmxvZyArICcuZnJhZycsIHF1ZXJ5LmxvZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHF1ZXJ5W2tleV07XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ3RydWUnIHx8IHZhbHVlID09PSAnZmFsc2UnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9ICh2YWx1ZSA9PSAndHJ1ZScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBhcnNlRmxvYXQodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhcnNlRmxvYXQodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgI
23459HRoaXMubWFpbi5vcHRpb25zW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlUXVlcnkgKHFzdHIpIHtcbiAgICBsZXQgcXVlcnkgPSB7fTtcbiAgICBsZXQgYSA9IHFzdHIuc3BsaXQoJyYnKTtcbiAgICBmb3IgKGxldCBpIGluIGEpIHtcbiAgICAgICAgbGV0IGIgPSBhW2ldLnNwbGl0KCc9Jyk7XG4gICAgICAgIHF1ZXJ5W2RlY29kZVVSSUNvbXBvbmVudChiWzBdKV0gPSBkZWNvZGVVUklDb21wb25lbnQoYlsxXSk7XG4gICAgfVxuICAgIHJldHVybiBxdWVyeTtcbn1cbiIsIi8qXG5PcmlnaW5hbDogaHR0cHM6Ly9naXRodWIuY29tL3RhbmdyYW1zL3RhbmdyYW0tcGxheS9ibG9iL2doLXBhZ2VzL3NyYy9qcy9hZGRvbnMvTG9jYWxTdG9yYWdlLmpzXG5BdXRob3I6IExvdSBIdWFuZyAoQHNhaWtvZmlzaClcbiovXG5cbi8qKlxuICogIExvY2FsIHN0b3JhZ2VcbiAqXG4gKiAgUHJvdmlkZXMgYSBjb21tb24gaW50ZXJmYWNlIGZvciB0aGUgYXBwbGljYXRpb24gd2hlcmUgbW9kdWxlcyBjYW5cbiAqICByZXF1ZXN0IHN0b3JhZ2Ugb2YgdmFsdWVzIGFjcm9zcyBtdWx0aXBsZSB1c2VyIHNlc3Npb25zIHZpYSB0aGVcbiAqICBicm93c2VyJ3MgTG9jYWxTdG9yYWdlIEFQSS5cbiAqXG4gKiAgQnJvd3NlciBzdXBwb3J0IGlzIGdvb2QsIHNvIG5vIGZhbGxiYWNrcyBhcmUgaW1wbGVtZW50ZWQuXG4gKiAgVGhpcyBtb2R1bGUgbWFuYWdlcyBuYW1lc3BhY2luZyBmb3IgVGFuZ3JhbSBQbGF5IHRvIHByZXZlbnQgbmFtZVxuICogIGNvbGxpc2lvbnMgd2l0aCBvdGhlciBsaWJyYXJpZXMsIGJyb3dzZXIgZXh0ZW5zaW9ucywgZXRjLlxuICovXG5jb25zdCBMT0NBTF9TVE9SQUdFX1BSRUZJWCA9ICdnbHNsRWRpdG9yLSc7XG5cbmNvbnN0IExvY2FsU3RvcmFnZSA9IHtcbiAgICAvKipcbiAgICAgKiAgc2V0SXRlbSgpXG4gICAgICogIE5hbWVzcGFjZXMga2V5IG5hbWUgdG8gVGFuZ3JhbSBQbGF5IGFwcGxpY2F0aW9uIGFuZCBhZGRzXG4gICAgICogIHRoZSB2YWx1ZSB0byBMb2NhbFN0b3JhZ2UuXG4gICAgICovXG4gICAgc2V0SXRlbSAoa2V5LCB2YWx1ZSkge1xuICAgICAgICBpZiAod2luZG93LmxvY2FsU3RvcmFnZSkge1xuICAgICAgICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKExPQ0FMX1NUT1JBR0VfUFJFRklYICsga2V5LCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogIHB1c2hJdGVtKClcbiAgICAgKiAgU3RvcmUgdmFsdWVzIGFzIGFuIGFycmF5LiBJZiB0aGUga2V5IGRvZXNuJ3QgZXhpc3QgYXMgYW4gb2JqZWN0LCBjcmVhdGUgaXQuXG4gICAgICogIE5vdGUgdGhhdCB0aGlzIG92ZXJ3cml0ZXMgYW4gb2xkIHZhbHVlIGlmIGl0IGlzIHByZXNlbnQgYW5kIG5vdCBhIEpTT04gb2JqZWN0IVxuICAgICAqICBJZiBpdCBleGlzdHMsIHJldHJlaXZlIGl0LCBzZXJpYWxpemUgaXQgaW50byBKU09OLCBwdXNoIHRoZSBuZXcgdmFsdWUsXG4gICAgICogIHJlLWVuY29kZSB0byBhIHN0cmluZyBhbmQgdGhlbiBzZXQgaXQgYmFjayBpbiBsb2NhbFN0b3JhZ2UuXG4gICAgICogIE5vIG90aGVyIGFycmF5IG1ldGhvZHMgYXJlIGltcGxlbWVudGVkLiBJZiB5b3UgbmVlZCB0byBkZWxldGUgaXRlbXMsIGV0Y1xuICAgICAqICB0aGVuIHJldHJpZXZlIHRoZSBzdHJpbmcgYXMgbm9ybWFsLCBkbyB0aGUgd29yayBpbiB5b3VyIHNjcmlwdCwgYW5kIHRoZW5cbiAgICAgKiAgc2V0IGl0IHRvIHRoZSBuZXcgc3RyaW5naWZpZWQgYXJyYXkgaW5zdGVhZCBvZiBwdXNoaW5nIGl0LlxuICAgICAqL1xuICAgIHB1c2hJdGVtIChrZXksIHZhbHVlKSB7XG4gICAgICAgIGxldCBzdG9yZWQ7XG4gICAgICAgIHN0b3JlZCA9IHRoaXMuZ2V0SXRlbShrZXkpO1xuICAgICAgICAvLyBJbiBjYXNlIHRoZXJlIGlzIGEgcHJldmlvdXNseSBzdG9yZWQgaXRlbSBoZXJlIHRoYXQgaXMgbm90XG4gICAgICAgIC8vIHBhcnNlYWJsZSBKU09OLCBkb24ndCBmYWlsXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzdG9yZWQgPSBKU09OLnBhcnNlKHN0b3JlZCk7XG4gICAgICAgICAgICBzdG9yZWQuYXJyID0gc3RvcmVkLmFyciB8fCBbXTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgc3RvcmVkID0geyBhcnI6IFtdIH07XG4gICAgICAgIH1cbiAgICAgICAgc3RvcmVkLmFyci5wdXNoKHZhbHVlKTtcbiAgICAgICAgdGhpcy5zZXRJdGVtKGtleSwgSlNPTi5zdHJpbmdpZnkoc3RvcmVkKSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqICBnZXRJdGVtKClcbiAgICAgKiAgUmV0cmlldmVzIHZhbHVlIGZvciB0aGUgZ2l2ZW4ga2V5IG5hbWUgYW5kIGFwcGxpY2F0aW9uIG5hbWVzcGFjZS5cbiAgICAgKi9cbiAgICBnZXRJdGVtIChrZXkpIHtcbiAgICAgICAgaWYgKHdpbmRvdy5sb2NhbFN0b3JhZ2UpIHtcbiAgICAgICAgICAgIHJldHVybiB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oTE9DQUxfU1RPUkFHRV9QUkVGSVggKyBrZXkpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqICByZW1vdmVJdGVtKClcbiAgICAgKiAgUmVtb3ZlcyBrZXktdmFsdWUgcGFpciB1bmRlciB0aGUgYXBwbGljYXRpb24gbmFtZXNwYWNlLlxuICAgICAqL1xuICAgIHJlbW92ZUl0ZW0gKGtleSkge1xuICAgICAgICBpZiAod2luZG93LmxvY2FsU3RvcmFnZSkge1xuICAgICAgICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKExPQ0FMX1NUT1JBR0VfUFJFRklYICsga2V5KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiAgY2xlYXIoKVxuICAgICAqICBMb29wcyB0aHJvdWdoIGFsbCB2YWx1ZXMgaW4gbG9jYWxTdG9yYWdlIHVuZGVyIHRoZSBhcHBsaWNhdGlvblxuICAgICAqICBuYW1lc3BhY2UgYW5kIHJlbW92ZXMgdGhlbSwgcHJlc2VydmluZyBvdGhlciBrZXktdmFsdWUgcGFpcnMgaW5cbiAgICAgKiAgbG9jYWxTdG9yYWdlLlxuICAgICAqL1xuICAgIGNsZWFyICgpIHtcbiAgICAgICAgaWYgKHdpbmRvdy5sb2NhbFN0b3JhZ2UpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGtleSBpbiB3aW5kb3cubG9jYWxTdG9yYWdlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGtleS5pbmRleE9mKExPQ0FMX1NUT1JBR0VfUFJFRklYKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oTE9DQUxfU1RPUkFHRV9QUkVGSVggKyBrZXkpO1xuICAgICAgICAgICAgICAgI
23459H1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBMb2NhbFN0b3JhZ2U7XG4iLCJleHBvcnQgZnVuY3Rpb24gZ2V0RG9tT3JpZ2luIChlbCkge1xuICAgIGNvbnN0IGJveCA9IChlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QpID8gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgOiB7IHRvcDogMCwgbGVmdDogMCB9O1xuICAgIGNvbnN0IGRvYyA9IGVsICYmIGVsLm93bmVyRG9jdW1lbnQ7XG4gICAgY29uc3QgYm9keSA9IGRvYy5ib2R5O1xuICAgIGNvbnN0IHdpbiA9IGRvYy5kZWZhdWx0VmlldyB8fCBkb2MucGFyZW50V2luZG93IHx8IHdpbmRvdztcbiAgICBjb25zdCBkb2NFbGVtID0gZG9jLmRvY3VtZW50RWxlbWVudCB8fCBib2R5LnBhcmVudE5vZGU7XG4gICAgY29uc3QgY2xpZW50VG9wID0gZG9jRWxlbS5jbGllbnRUb3AgfHwgYm9keS5jbGllbnRUb3AgfHwgMDsgLy8gYm9yZGVyIG9uIGh0bWwgb3IgYm9keSBvciBib3RoXG4gICAgY29uc3QgY2xpZW50TGVmdCA9IGRvY0VsZW0uY2xpZW50TGVmdCB8fCBib2R5LmNsaWVudExlZnQgfHwgMDtcblxuICAgIHJldHVybiB7XG4gICAgICAgIGxlZnQ6IGJveC5sZWZ0ICsgKHdpbi5wYWdlWE9mZnNldCB8fCBkb2NFbGVtLnNjcm9sbExlZnQpIC0gY2xpZW50TGVmdCxcbiAgICAgICAgdG9wOiBib3gudG9wICsgKHdpbi5wYWdlWU9mZnNldCB8fCBkb2NFbGVtLnNjcm9sbFRvcCkgLSBjbGllbnRUb3BcbiAgICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGV2aWNlUGl4ZWxSYXRpbyAoY3R4KSB7XG4gICAgbGV0IGRldmljZVBpeGVsUmF0aW8gPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbyB8fCAxO1xuICAgIGxldCBiYWNraW5nU3RvcmVSYXRpbyA9IGN0eC53ZWJraXRCYWNraW5nU3RvcmVQaXhlbFJhdGlvIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lm1vekJhY2tpbmdTdG9yZVBpeGVsUmF0aW8gfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgubXNCYWNraW5nU3RvcmVQaXhlbFJhdGlvIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lm9CYWNraW5nU3RvcmVQaXhlbFJhdGlvIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4LmJhY2tpbmdTdG9yZVBpeGVsUmF0aW8gfHwgMTtcbiAgICByZXR1cm4gZGV2aWNlUGl4ZWxSYXRpbyAvIGJhY2tpbmdTdG9yZVJhdGlvO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SlNPTih1cmwsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIHhoci5vcGVuKCdHRVQnLCB1cmwsIHRydWUpO1xuICAgIHhoci5yZXNwb25zZVR5cGUgPSAnanNvbic7XG4gICAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHN0YXR1cyA9IHhoci5zdGF0dXM7XG4gICAgICBpZiAoc3RhdHVzID09PSAyMDApIHtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgeGhyLnJlc3BvbnNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhbGxiYWNrKHN0YXR1cywgeGhyLnJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHhoci5zZW5kKCk7XG59O1xuIiwiXG5leHBvcnQgZnVuY3Rpb24gaXNDb21tZW50ZWQoY20sIG5MaW5lLCBtYXRjaCkge1xuICAgIGxldCB0b2tlbiA9IGNtLmdldFRva2VuQXQoeyBsaW5lOiBuTGluZSwgY2g6IG1hdGNoLmluZGV4IH0pO1xuICAgIGlmICh0b2tlbiAmJiB0b2tlbi50eXBlKSB7XG4gICAgICAgIHJldHVybiB0b2tlbi50eXBlID09PSAnY29tbWVudCc7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTGluZUFmdGVyTWFpbihjbSwgbkxpbmUpIHtcbiAgICBsZXQgdG90YWxMaW5lcyA9IGNtLmdldERvYygpLnNpemU7XG4gICAgbGV0IHZvaWRSRSA9IG5ldyBSZWdFeHAoJ3ZvaWQgbWFpblxcXFxzKlxcXFwoXFxcXHMqW3ZvaWRdKlxcXFwpJywgJ2knKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5MaW5lICYmIGkgPCB0b3RhbExpbmVzOyBpKyspIHtcbiAgICAgICAgLy8gRG8gbm90IHN0YXJ0IHVudGlsIGJlaW5nIGluc2lkZSB0aGUgbWFpbiBmdW5jdGlvblxuICAgICAgICBsZXQgdm9pZE1hdGNoID0gdm9pZFJFLmV4ZWMoY20uZ2V0TGluZShpKSk7XG4gICAgICAgIGlmICh2b2lkTWF0Y2gpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZhcmlhYmxlVHlwZShjbSwgc1ZhcmlhYmxlKSB7XG4gICAgbGV0IG5MaW5lcyA9IGNtLmdldERvYygpLnNpemU7XG5cbiAgICAvLyBTaG93IGxpbmUgd2hlcmUgdGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSBpcyBiZWVuIGFzaWduZWRcbiAgICBsZXQgdW5pZm9ybVJFID0gbmV3IFJlZ0V4cCgnXFxcXHMqdW5pZm9ybVxcXFxzKyhmbG9hdHx2ZWMyfHZlYzN8dmVjNClcXFxccysnICsgc1ZhcmlhYmxlICsgJ1xcXFxzKjsnKTtcbiAgICBsZXQgdm9pZFJFID0gbmV3IFJlZ0V4cCgndm9pZCBtYWluXFxcXHMqXFxcXChcXFxccypbdm9pZF0qXFxcXCknLCAnaScpO1xuICAgIGxldCB2b2lkSU4gPSBmYWxzZTtcbiAgICBsZXQgY29uc3RydWN0UkUgPSBuZXcgUmVnRXhwKCcoZmxvYXR8dmVjXFxcXGQpXFxcXHMrKCcgKyBzVmFyaWFibGUgKyAnKVxcXFxzKls7XT8nLCAnaScpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbkxpbmVzOyBpKyspIHtcbiAgICAgICAgaWYgKCF2b2lkSU4pIHtcbiAgICAgICAgICAgIC8vIERvIG5vdCBzdGFydCB1bnRpbCBiZWluZyBpbnNpZGUgdGhlIG1haW4gZnVuY3Rpb25cbiAgICAgICAgICAgIGxldCB2b2lkTWF0Y2ggPSB2b2lkUkUuZXhlYyhjbS5nZXRMaW5lKGkpKTtcbiAgICAgICAgICAgIGlmICh2b2lkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICB2b2lkSU4gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IHVuaWZvcm1NYXRjaCA9IHVuaWZvcm1SRS5leGVjKGNtLmdldExpbmUoaSkpO1xuICAgICAgICAgICAgICAgIGlmICh1bmlmb3JtTWF0Y2ggJiYgIWlzQ29tbWVudGVkKGNtLCBpLCB1bmlmb3JtTWF0Y2gpKSB7XG4gICAgICAgICAgICAgICAgICAgI
23459HJldHVybiB1bmlmb3JtTWF0Y2hbMV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IGNvbnN0cnVjdE1hdGNoID0gY29uc3RydWN0UkUuZXhlYyhjbS5nZXRMaW5lKGkpKTtcbiAgICAgICAgICAgIGlmIChjb25zdHJ1Y3RNYXRjaCAmJiBjb25zdHJ1Y3RNYXRjaFsxXSAmJiAhaXNDb21tZW50ZWQoY20sIGksIGNvbnN0cnVjdE1hdGNoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjb25zdHJ1Y3RNYXRjaFsxXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gJ25vbmUnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2hhZGVyRm9yVHlwZVZhckluTGluZShjbSwgc1R5cGUsIHNWYXJpYWJsZSwgbkxpbmUpIHtcbiAgICBsZXQgZnJhZyA9ICcnO1xuICAgIGxldCBvZmZzZXQgPSAxO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbkxpbmUgKyAxICYmIGkgPCBjbS5nZXREb2MoKS5zaXplOyBpKyspIHtcbiAgICAgICAgaWYgKGNtLmdldExpbmUoaSkpIHtcbiAgICAgICAgICAgIGZyYWcgKz0gY20uZ2V0TGluZShpKSArICdcXG4nO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnJhZyArPSAnXFx0Z2xfRnJhZ0NvbG9yID0gJztcbiAgICBpZiAoc1R5cGUgPT09ICdmbG9hdCcpIHtcbiAgICAgICAgZnJhZyArPSAndmVjNCh2ZWMzKCcgKyBzVmFyaWFibGUgKyAnKSwxLiknO1xuICAgIH1cbiAgICBlbHNlIGlmIChzVHlwZSA9PT0gJ3ZlYzInKSB7XG4gICAgICAgIGZyYWcgKz0gJ3ZlYzQodmVjMygnICsgc1ZhcmlhYmxlICsgJywwLiksMS4pJztcbiAgICB9XG4gICAgZWxzZSBpZiAoc1R5cGUgPT09ICd2ZWMzJykge1xuICAgICAgICBmcmFnICs9ICd2ZWM0KCcgKyBzVmFyaWFibGUgKyAnLDEuKSc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHNUeXBlID09PSAndmVjNCcpIHtcbiAgICAgICAgZnJhZyArPSBzVmFyaWFibGU7XG4gICAgfVxuICAgIGZyYWcgKz0gJztcXG59XFxuJztcblxuICAgIHJldHVybiBmcmFnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVzdWx0UmFuZ2UodGVzdFJlc3VsdHMpIHtcbiAgICBsZXQgbWluTVMgPSAnMTAwMDAwMDAuMCc7XG4gICAgbGV0IG1pbkxpbmUgPSAwO1xuICAgIGxldCBtYXhNUyA9ICcwLjAnO1xuICAgIGxldCBtYXhMaW5lID0gMDtcbiAgICBmb3IgKGxldCBpIGluIHRlc3RSZXN1bHRzKSB7XG4gICAgICAgIGlmICh0ZXN0UmVzdWx0c1tpXS5tcyA8IG1pbk1TKSB7XG4gICAgICAgICAgICBtaW5NUyA9IHRlc3RSZXN1bHRzW2ldLm1zO1xuICAgICAgICAgICAgbWluTGluZSA9IHRlc3RSZXN1bHRzW2ldLmxpbmU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRlc3RSZXN1bHRzW2ldLm1zID4gbWF4TVMpIHtcbiAgICAgICAgICAgIG1heE1TID0gdGVzdFJlc3VsdHNbaV0ubXM7XG4gICAgICAgICAgICBtYXhMaW5lID0gdGVzdFJlc3VsdHNbaV0ubGluZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyBtaW46e2xpbmU6IG1pbkxpbmUsIG1zOiBtaW5NU30sIG1heDp7bGluZTogbWF4TGluZSwgbXM6IG1heE1TfSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWVkaWFuKHZhbHVlcykge1xuICAgIHZhbHVlcy5zb3J0KGZ1bmN0aW9uKGEsYikge3JldHVybiBhIC0gYjt9KTtcblxuICAgIHZhciBoYWxmID0gTWF0aC5mbG9vcih2YWx1ZXMubGVuZ3RoIC8gMik7XG5cbiAgICBpZih2YWx1ZXMubGVuZ3RoICUgMikge3JldHVybiB2YWx1ZXNbaGFsZl07fVxuICAgIGVsc2Uge3JldHVybiAodmFsdWVzW2hhbGYgLSAxXSArIHZhbHVlc1toYWxmXSkgLyAyLjA7fVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVsdGFTdW0odGVzdFJlc3VsdHMpIHtcbiAgICBsZXQgdG90YWwgPSAwLjA7XG4gICAgZm9yIChsZXQgaSBpbiB0ZXN0UmVzdWx0cykge1xuICAgICAgICBpZiAodGVzdFJlc3VsdHNbaV0uZGVsdGEgPiAwKSB7XG4gICAgICAgICAgICB0b3RhbCArPSB0ZXN0UmVzdWx0c1tpXS5kZWx0YTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdG90YWw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRIaXRzKHRlc3RSZXN1bHRzKSB7XG4gICAgbGV0IHRvdGFsID0gMDtcbiAgICBmb3IgKGxldCBpIGluIHRlc3RSZXN1bHRzKSB7XG4gICAgICAgIGlmICh0ZXN0UmVzdWx0c1tpXS5kZWx0YSA+IDApIHtcbiAgICAgICAgICAgIHRvdGFsKys7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRvdGFsO1xufVxuIiwiZXhwb3J0IGZ1bmN0aW9uIHNhdmVBcyhibG9iLCBmaWxlbmFtZSkge1xuICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xuICAgIGxpbmsuc2V0QXR0cmlidXRlKFwiZG93bmxvYWRcIiwgZmlsZW5hbWUpO1xuICAgIGxpbmsuc2V0QXR0cmlidXRlKFwiaHJlZlwiLCB1cmwpO1xuICAgIGxpbmsuY2xpY2soKTtcbn0iLCIvKlxuICogT3JpZ2luYWwgY29kZSBmcm9tOiBodHRwczovL3R3aXR0ZXIuY29tL2JsdXJzcGxpbmUgLyBodHRwczovL2dpdGh1Yi5jb20veno4NVxuICogU2VlIHBvc3QgQCBodHRwOi8vd3d3LmxhYjRnYW1lcy5uZXQveno4NS9ibG9nLzIwMTQvMTEvMTUvcmVzaXppbmctbW92aW5nLXNuYXBwaW5nLXdpbmRvd3Mtd2l0aC1qcy1jc3MvXG4gKi9cblxuaW1wb3J0IHsgc3Vic2NyaWJlTWl4aW4gfSBmcm9tICcuL21peGluJztcblxuLy8gVGhyZXNob2xkc1xudmFyIEZVTExTQ1JFRU5fTUFSR0lOUyA9IC0zMDtcbnZhciBNQVJHSU5TID0gMTA7XG5cbmZ1bmN0aW9uIHNldEJvdW5kcyhlbGVtZW50LCB4LCB5LCB3LCBoKSB7XG4gICAgZWxlbWVudC5zdHlsZS5sZWZ0ID0geCArICdweCc7XG4gICAgZWxlbWVudC5zdHlsZS50b3AgPSB5ICsgJ3B4JztcbiAgICBlbGVtZW50LnN0eWxlLndpZHRoID0gdyArICdweCc7XG4gICAgZWxlbWVudC5zdHlsZS5oZWlnaHQgPSBoICsgJ3B4Jztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN1YnNjcmliZUludGVyYWN0aXZlRG9tIChkb20sIG9wdGlvbnMpIHtcbiAgICBzdWJzY3JpYmVNaXhpbihkb20pO1xuXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgb3B0aW9ucy5yZXNpemUgPSBvcHRpb25zLnJlc2l6ZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5yZXNpemUgOiBmYWxzZTtcbiAgICBvcHRpb25zLm1vdmUgPSBvcHRpb25zLm1vdmUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubW92ZSA6IGZhbHNlO1xuICAgIG9wdGlvbnMuc25hcCA9IG9wdGlvbnMuc25hcCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zbmFwIDogZmFsc2U7XG5cbiAgICAvLyBNaW5pbXVtIHJlc2l6YWJsZSBhcmVhXG4gICAgdmFyIG1pbldpZHRoID0gMTAwO1xuICAgIHZhciBtaW5IZWlnaHQgPSAxMDA7XG5cbiAgICAvLyBFbmQgb2Ygd2hhdCdzIGNvbmZpZ3VyYWJsZS5cbiAgICB2YXIgY2xpY2tlZCA9IG51bGw7XG4gICAgdmFyIG9uUmlnaHRFZGdlLCBvbkJvdHRvbUVkZ2UsIG9uTGVmdEVkZ2UsIG9uVG9wRWRnZTtcblxuICAgI
23459HZhciByaWdodFNjcmVlbkVkZ2UsIGJvdHRvbVNjcmVlbkVkZ2U7XG5cbiAgICB2YXIgcHJlU25hcHBlZDtcblxuICAgIHZhciBiLCB4LCB5O1xuXG4gICAgdmFyIHJlZHJhdyA9IGZhbHNlO1xuXG4gICAgdmFyIGdob3N0ZG9tID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZ2hvc3Rkb20uY2xhc3NOYW1lID0gJ2dob3N0ZG9tJztcblxuICAgIGlmIChvcHRpb25zLnNuYXApIHtcbiAgICAgICAgZG9tLnBhcmVudEVsZW1lbnQuYXBwZW5kQ2hpbGQoZ2hvc3Rkb20pO1xuICAgIH1cblxuICAgIC8vIE1vdXNlIGV2ZW50c1xuICAgIGRvbS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBvbk1vdXNlRG93bik7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgb25Nb3VzZU1vdmUpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBvbk1vdXNlVXApO1xuXG4gICAgLy8gVG91Y2ggZXZlbnRzXG4gICAgZG9tLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCBvblRvdWNoRG93biwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBvblRvdWNoTW92ZSwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIG9uVG91Y2hFbmQsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG5cbiAgICBmdW5jdGlvbiBoaW50SGlkZSgpIHtcbiAgICAgICAgc2V0Qm91bmRzKGdob3N0ZG9tLCBiLmxlZnQsIGIudG9wLCBiLndpZHRoLCBiLmhlaWdodCk7XG4gICAgICAgIGdob3N0ZG9tLnN0eWxlLm9wYWNpdHkgPSAwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG9uVG91Y2hEb3duIChldmVudCkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICBvbkRvd24oZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gb25Ub3VjaE1vdmUgKGV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBpZiAoZXZlbnQudG91Y2hlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIG9uTW92ZShldmVudC5jaGFuZ2VkVG91Y2hlc1swXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvblRvdWNoRW5kIChldmVudCkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgaWYgKGV2ZW50LnRvdWNoZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBvblVwKGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG9uTW91c2VEb3duIChldmVudCkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgb25Eb3duKGV2ZW50KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvbk1vdXNlTW92ZSAoZXZlbnQpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIG9uTW92ZShldmVudCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gb25Nb3VzZVVwIChldmVudCkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgb25VcChldmVudCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gb25Eb3duIChldmVudCkge1xuICAgICAgICBjYWxjKGV2ZW50KTtcbiAgICAgICAgdmFyIGlzUmVzaXppbmcgPSBvcHRpb25zLnJlc2l6ZSAmJiAob25SaWdodEVkZ2UgfHwgb25Cb3R0b21FZGdlIHx8IG9uVG9wRWRnZSB8fCBvbkxlZnRFZGdlKTtcbiAgICAgICAgY2xpY2tlZCA9IHtcbiAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICB5OiB5LFxuICAgICAgICAgICAgY3g6IGV2ZW50LmNsaWVudFgsXG4gICAgICAgICAgICBjeTogZXZlbnQuY2xpZW50WSxcbiAgICAgICAgICAgIHc6IGIud2lkdGgsXG4gICAgICAgICAgICBoOiBiLmhlaWdodCxcbiAgICAgICAgICAgIGlzUmVzaXppbmc6IGlzUmVzaXppbmcsXG4gICAgICAgICAgICBpc01vdmluZzogIWlzUmVzaXppbmcgJiYgY2FuTW92ZSgpLFxuICAgICAgICAgICAgb25Ub3BFZGdlOiBvblRvcEVkZ2UsXG4gICAgICAgICAgICBvbkxlZnRFZGdlOiBvbkxlZnRFZGdlLFxuICAgICAgICAgICAgb25SaWdodEVkZ2U6IG9uUmlnaHRFZGdlLFxuICAgICAgICAgICAgb25Cb3R0b21FZGdlOiBvbkJvdHRvbUVkZ2VcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYW5Nb3ZlKCkge1xuICAgICAgICByZXR1cm4gb3B0aW9ucy5tb3ZlICYmICh4ID4gMCAmJiB4IDwgYi53aWR0aCAmJi
23459B5ID4gMCAmJiB5IDwgYi5oZWlnaHQpOy8vICYmIHkgPCAzMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYWxjIChldmVudCkge1xuICAgICAgICBiID0gZG9tLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICB4ID0gZXZlbnQuY2xpZW50WCAtIGIubGVmdDtcbiAgICAgICAgeSA9IGV2ZW50LmNsaWVudFkgLSBiLnRvcDtcblxuICAgICAgICBvblRvcEVkZ2UgPSB5IDwgTUFSR0lOUztcbiAgICAgICAgb25MZWZ0RWRnZSA9IHggPCBNQVJHSU5TO1xuICAgICAgICBvblJpZ2h0RWRnZSA9IHggPj0gYi53aWR0aCAtIE1BUkdJTlM7XG4gICAgICAgIG9uQm90dG9tRWRnZSA9IHkgPj0gYi5oZWlnaHQgLSBNQVJHSU5TO1xuXG4gICAgICAgIHJpZ2h0U2NyZWVuRWRnZSA9IHdpbmRvdy5pbm5lcldpZHRoIC0gTUFSR0lOUztcbiAgICAgICAgYm90dG9tU2NyZWVuRWRnZSA9IHdpbmRvdy5pbm5lckhlaWdodCAtIE1BUkdJTlM7XG4gICAgfVxuXG4gICAgdmFyIGU7XG5cbiAgICBmdW5jdGlvbiBvbk1vdmUoZXZlbnQpIHtcbiAgICAgICAgY2FsYyhldmVudCk7XG4gICAgICAgIGUgPSBldmVudDtcbiAgICAgICAgcmVkcmF3ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhbmltYXRlKCkge1xuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoYW5pbWF0ZSk7XG5cbiAgICAgICAgaWYgKCFyZWRyYXcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICByZWRyYXcgPSBmYWxzZTtcblxuICAgICAgICBpZiAoY2xpY2tlZCAmJiBjbGlja2VkLmlzUmVzaXppbmcpIHtcbiAgICAgICAgICAgIGlmIChjbGlja2VkLm9uUmlnaHRFZGdlKSB7XG4gICAgICAgICAgICAgICAgZG9tLnN0eWxlLndpZHRoID0gTWF0aC5tYXgoeCwgbWluV2lkdGgpICsgJ3B4JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjbGlja2VkLm9uQm90dG9tRWRnZSkge1xuICAgICAgICAgICAgICAgIGRvbS5zdHlsZS5oZWlnaHQgPSBNYXRoLm1heCh5LCBtaW5IZWlnaHQpICsgJ3B4JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNsaWNrZWQub25MZWZ0RWRnZSkge1xuICAgICAgICAgICAgICAgIHZhciBjdXJyZW50V2lkdGggPSBNYXRoLm1heChjbGlja2VkLmN4IC0gZS5jbGllbnRYICsgY2xpY2tlZC53LCBtaW5XaWR0aCk7XG4gICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRXaWR0aCA+IG1pbldpZHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbS5zdHlsZS53aWR0aCA9IGN1cnJlbnRXaWR0aCArICdweCc7XG4gICAgICAgICAgICAgICAgICAgIGRvbS5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgncmlnaHQnKTtcbiAgICAgICAgICAgICAgICAgICAgZG9tLnN0eWxlLmxlZnQgPSBlLmNsaWVudFggKyAncHgnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNsaWNrZWQub25Ub3BFZGdlKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1cnJlbnRIZWlnaHQgPSBNYXRoLm1heChjbGlja2VkLmN5IC0gZS5jbGllbnRZICsgY2xpY2tlZC5oLCBtaW5IZWlnaHQpO1xuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50SGVpZ2h0ID4gbWluSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbS5zdHlsZS5oZWlnaHQgPSBjdXJyZW50SGVpZ2h0ICsgJ3B4JztcbiAgICAgICAgICAgICAgICAgICAgZG9tLnN0eWxlLnJlbW92ZVByb3BlcnR5KCdib3R0b20nKTtcbiAgICAgICAgICAgICAgICAgICAgZG9tLnN0eWxlLnRvcCA9IGUuY2xpZW50WSArICdweCc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBoaW50SGlkZSgpO1xuICAgICAgICAgICAgZG9tLnRyaWdnZXIoJ3Jlc2l6ZScsIHsgZmluaXNoOiBmYWxzZSwgZWw6IGRvbSB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjbGlja2VkICYmIGNsaWNrZWQuaXNNb3ZpbmcpIHtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNuYXApIHtcbiAgICAgICAgICAgICAgICBpZiAoYi50b3AgPCBGVUxMU0NSRUVOX01BUkdJTlMgfHwgYi5sZWZ0IDwgRlVMTFNDUkVFTl9NQVJHSU5TIHx8IGIucmlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aCAtIEZVTExTQ1JFRU5fTUFSR0lOUyB8fCBiLmJvdHRvbSA+IHdpbmRvdy5pbm5lckhlaWdodCAtIEZVTExTQ1JFRU5fTUFSR0lOUykge1xuICAgICAgICAgICAgICAgICAgICBzZXRCb3VuZHMoZ2hvc3Rkb20sIDAsIDAsIHdpbmRvdy5pbm5lcldpZHRoLCB3aW5kb3cuaW5uZXJIZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgICBnaG9zdGRvbS5zdHlsZS5vcGFjaXR5ID0gMC4yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChiLnRvcCA8IE1BUkdJTlMpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0Qm91bmRzKGdob3N0ZG9tLCAwLCAwLCB3aW5kb3cuaW5uZXJXaWR0aCwgd2luZG93LmlubmVySGVpZ2h0IC8gMik7XG4gICAgICAgICAgICAgICAgICAgIGdob3N0ZG9tLnN0eWxlLm9wYWNpdHkgPSAwLjI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGIubGVmdCA8IE1BUkdJTlMpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0Qm91bmRzKGdob3N0ZG9tLCAwLCAwLCB3aW5kb3cuaW5uZXJXaWR0aCAvIDIsIHdpbmRvdy5pbm5lckhlaWdodCk7XG4gICAgICAgICAgICAgICAgICAgIGdob3N0ZG9tLnN0eWxlLm9wYWNpdHkgPSAwLjI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGIucmlnaHQgPiByaWdodFNjcmVlbkVkZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0Qm91bmRzKGdob3N0ZG9tLCB3aW5kb3cuaW5uZXJXaWR0aCAvIDIsIDAsIHdpbmRvdy5pbm5lcldpZHRoIC8gMiwgd2luZG93LmlubmVySGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgZ2hvc3Rkb20uc3R5bGUub3BhY2l0eSA9IDAuMjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYi5ib3R0b20gPiBib3R0b21TY3JlZW5FZGdlKSB7XG4gICAgICAgICAgICAgICAgICAgI
23459HNldEJvdW5kcyhnaG9zdGRvbSwgMCwgd2luZG93LmlubmVySGVpZ2h0IC8gMiwgd2luZG93LmlubmVyV2lkdGgsIHdpbmRvdy5pbm5lcldpZHRoIC8gMik7XG4gICAgICAgICAgICAgICAgICAgIGdob3N0ZG9tLnN0eWxlLm9wYWNpdHkgPSAwLjI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBoaW50SGlkZSgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChwcmVTbmFwcGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldEJvdW5kcyhkb20sXG4gICAgICAgICAgICAgICAgICAgICAgICBlLmNsaWVudFggLSBwcmVTbmFwcGVkLndpZHRoIC8gMixcbiAgICAgICAgICAgICAgICAgICAgICAgIGUuY2xpZW50WSAtIE1hdGgubWluKGNsaWNrZWQueSwgcHJlU25hcHBlZC5oZWlnaHQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJlU25hcHBlZC53aWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZVNuYXBwZWQuaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIG1vdmluZ1xuICAgICAgICAgICAgICAgIGRvbS5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgncmlnaHQnKTtcbiAgICAgICAgICAgICAgICBkb20uc3R5bGUucmVtb3ZlUHJvcGVydHkoJ2JvdHRvbScpO1xuICAgICAgICAgICAgICAgIGRvbS5zdHlsZS50b3AgPSAoZS5jbGllbnRZIC0gY2xpY2tlZC55KSArICdweCc7XG4gICAgICAgICAgICAgICAgZG9tLnN0eWxlLmxlZnQgPSAoZS5jbGllbnRYIC0gY2xpY2tlZC54KSArICdweCc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgeCA9IChlLmNsaWVudFggLSBjbGlja2VkLngpO1xuICAgICAgICAgICAgICAgIGxldCB5ID0gKGUuY2xpZW50WSAtIGNsaWNrZWQueSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoeCA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgeCA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHkgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHkgPSAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICh4ICsgZG9tLm9mZnNldFdpZHRoID4gd2luZG93LmlubmVyV2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgeCA9IHdpbmRvdy5pbm5lcldpZHRoIC0gZG9tLm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICh5ICsgZG9tLm9mZnNldEhlaWdodCA+IHdpbmRvdy5pbm5lckhlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICB5ID0gd2luZG93LmlubmVySGVpZ2h0IC0gZG9tLm9mZnNldEhlaWdodDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBkb20uc3R5bGUucmVtb3ZlUHJvcGVydHkoJ3JpZ2h0Jyk7XG4gICAgICAgICAgICAgICAgZG9tLnN0eWxlLnJlbW92ZVByb3BlcnR5KCdib3R0b20nKTtcbiAgICAgICAgICAgICAgICBkb20uc3R5bGUubGVmdCA9IHggKyAncHgnO1xuICAgICAgICAgICAgICAgIGRvbS5zdHlsZS50b3AgPSB5ICsgJ3B4JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZG9tLnRyaWdnZXIoJ21vdmUnLCB7IGZpbmlzaDogZmFsc2UsIGVsOiBkb20gfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGhpcyBjb2RlIGV4ZWN1dGVzIHdoZW4gbW91c2UgbW92ZXMgd2l0aG91dCBjbGlja2luZ1xuXG4gICAgICAgIC8vIHN0eWxlIGN1cnNvclxuICAgICAgICBpZiAob3B0aW9ucy5yZXNpemUgJiYgKG9uUmlnaHRFZGdlICYmIG9uQm90dG9tRWRnZSB8fCBvbkxlZnRFZGdlICYmIG9uVG9wRWRnZSkpIHtcbiAgICAgICAgICAgIGRvbS5zdHlsZS5jdXJzb3IgPSAnbndzZS1yZXNpemUnO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG9wdGlvbnMucmVzaXplICYmIChvblJpZ2h0RWRnZSAmJiBvblRvcEVkZ2UgfHwgb25Cb3R0b21FZGdlICYmIG9uTGVmdEVkZ2UpKSB7XG4gICAgICAgICAgICBkb20uc3R5bGUuY3Vyc29yID0gJ25lc3ctcmVzaXplJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChvcHRpb25zLnJlc2l6ZSAmJiAob25SaWdodEVkZ2UgfHwgb25MZWZ0RWRnZSkpIHtcbiAgICAgICAgICAgIGRvbS5zdHlsZS5jdXJzb3IgPSAnZXctcmVzaXplJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChvcHRpb25zLnJlc2l6ZSAmJiAob25Cb3R0b21FZGdlIHx8IG9uVG9wRWRnZSkpIHtcbiAgICAgICAgICAgIGRvbS5zdHlsZS5jdXJzb3IgPSAnbnMtcmVzaXplJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjYW5Nb3ZlKCkpIHtcbiAgICAgICAgICAgIGRvbS5zdHlsZS5jdXJzb3IgPSAnbW92ZSc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkb20uc3R5bGUuY3Vyc29yID0gJ2RlZmF1bHQnO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFuaW1hdGUoKTtcblxuICAgIGZ1bmN0aW9uIG9uVXAoZSkge1xuICAgICAgICBjYWxjKGUpO1xuXG4gICAgICAgIGlmIChjbGlja2VkICYmIGNsaWNrZWQuaXNSZXNpemluZykge1xuICAgICAgICAgICAgZG9tLnRyaWdnZXIoJ3Jlc2l6ZScsIHsgZmluaXNoOiB0cnVlLCBlbDogZG9tIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9wdGlvbnMuc25hcCAmJiBjbGlja2VkICYmIGNsaWNrZWQuaXNNb3ZpbmcpIHtcbiAgICAgICAgICAgIC8vIFNuYXBcbiAgICAgICAgICAgIHZhciBzbmFwcGVkID0ge1xuICAgICAgICAgICAgICAgIHdpZHRoOiBiLndpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogYi5oZWlnaHRcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmIChiLnRvcCA8IEZVTExTQ1JFRU5fTUFSR0lOUyB8fCBiLmxlZnQgPCBGVUxMU0NSRUVOX01BUkdJTlMgfHwgYi5yaWdodCA+IHdpbmRvdy5pbm5lcldpZHRoIC0gRlVMTFNDUkVFTl9NQVJHSU5TIHx8IGIuYm90dG9tID4gd2luZG93LmlubmVySGVpZ2h0IC0gRlVMTFNDUkVFTl9NQVJHSU5TKSB7XG4gICAgICAgICAgICAgICAgc2V0Qm91bmRzKGRvbSwgMCwgMCwgd2luZG93LmlubmVyV2lkdGgsIHdpbmRvdy5pbm5lckhlaWdodCk7XG4gICAgICAgICAgICAgICAgcHJlU25hcHBlZCA9IHNuYXBwZWQ
234597XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChiLnRvcCA8IE1BUkdJTlMpIHtcbiAgICAgICAgICAgICAgICBzZXRCb3VuZHMoZG9tLCAwLCAwLCB3aW5kb3cuaW5uZXJXaWR0aCwgd2luZG93LmlubmVySGVpZ2h0IC8gMik7XG4gICAgICAgICAgICAgICAgcHJlU25hcHBlZCA9IHNuYXBwZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChiLmxlZnQgPCBNQVJHSU5TKSB7XG4gICAgICAgICAgICAgICAgc2V0Qm91bmRzKGRvbSwgMCwgMCwgd2luZG93LmlubmVyV2lkdGggLyAyLCB3aW5kb3cuaW5uZXJIZWlnaHQpO1xuICAgICAgICAgICAgICAgIHByZVNuYXBwZWQgPSBzbmFwcGVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYi5yaWdodCA+IHJpZ2h0U2NyZWVuRWRnZSkge1xuICAgICAgICAgICAgICAgIHNldEJvdW5kcyhkb20sIHdpbmRvdy5pbm5lcldpZHRoIC8gMiwgMCwgd2luZG93LmlubmVyV2lkdGggLyAyLCB3aW5kb3cuaW5uZXJIZWlnaHQpO1xuICAgICAgICAgICAgICAgIHByZVNuYXBwZWQgPSBzbmFwcGVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYi5ib3R0b20gPiBib3R0b21TY3JlZW5FZGdlKSB7XG4gICAgICAgICAgICAgICAgc2V0Qm91bmRzKGRvbSwgMCwgd2luZG93LmlubmVySGVpZ2h0IC8gMiwgd2luZG93LmlubmVyV2lkdGgsIHdpbmRvdy5pbm5lcldpZHRoIC8gMik7XG4gICAgICAgICAgICAgICAgcHJlU25hcHBlZCA9IHNuYXBwZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcmVTbmFwcGVkID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhpbnRIaWRlKCk7XG4gICAgICAgICAgICBkb20udHJpZ2dlcignbW92ZScsIHsgZmluaXNoOiB0cnVlLCBlbDogZG9tIH0pO1xuICAgICAgICAgICAgZG9tLnRyaWdnZXIoJ3Jlc2l6ZScsIHsgZmluaXNoOiB0cnVlLCBlbDogZG9tIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNsaWNrZWQgPSBudWxsO1xuICAgIH1cblxuICAgIGRvbS5zbmFwUmlnaHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzbmFwcGVkID0ge1xuICAgICAgICAgICAgd2lkdGg6IGRvbS53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogZG9tLmhlaWdodFxuICAgICAgICB9O1xuXG4gICAgICAgIHNldEJvdW5kcyhkb20sIHdpbmRvdy5pbm5lcldpZHRoIC8gMiwgMCwgd2luZG93LmlubmVyV2lkdGggLyAyLCB3aW5kb3cuaW5uZXJIZWlnaHQpO1xuICAgICAgICBwcmVTbmFwcGVkID0gc25hcHBlZDtcbiAgICAgICAgLy8gaGludEhpZGUoKTtcbiAgICAgICAgZG9tLnRyaWdnZXIoJ21vdmUnLCB7IGZpbmlzaDogdHJ1ZSwgZWw6IGRvbSB9KTtcbiAgICAgICAgZG9tLnRyaWdnZXIoJ3Jlc2l6ZScsIHsgZmluaXNoOiB0cnVlLCBlbDogZG9tIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4gZG9tO1xufVxuIiwiLyogZ2xvYmFsIE1lZGlhUmVjb3JkZXJcbkF1dGhvcjogQnJldHQgQ2FtcGVyIChAcHJvZmVzc29ybGVtZXphKVxuVVJMOiBodHRwczovL2dpdGh1Yi5jb20vdGFuZ3JhbXMvdGFuZ3JhbS9ibG9iL21hc3Rlci9zcmMvdXRpbHMvbWVkaWFfY2FwdHVyZS5qc1xuKi9cbmltcG9ydCB7Y3JlYXRlT2JqZWN0VVJMfSBmcm9tICcuL3VybHMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZWRpYUNhcHR1cmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnF1ZXVlU2NyZWVuc2hvdCA9IG51bGw7XG4gICAgICAgIHRoaXMudmlkZW9DYXB0dXJlID0gbnVsbDtcbiAgICB9XG5cbiAgICBzZXRDYW52YXMgKGNhbnZhcykge1xuICAgICAgICB0aGlzLmNhbnZhcyA9IGNhbnZhcztcbiAgICB9XG5cbiAgICAvLyBUYWtlIGEgc2NyZWVuc2hvdCwgcmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBzY3JlZW5zaG90IGRhdGEgd2hlbiBhdmFpbGFibGVcbiAgICBzY3JlZW5zaG90ICgpIHtcbiAgICAgICAgaWYgKHRoaXMucXVldWVTY3JlZW5zaG90ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnF1ZXVlU2NyZWVuc2hvdC5wcm9taXNlOyAvLyBvbmx5IGNhcHR1cmUgb25lIHNjcmVlbnNob3QgYXQgYSB0aW1lXG4gICAgICAgIH1cblxuICAgICAgICAvLyBXaWxsIHJlc29sdmUgb25jZSByZW5kZXJpbmcgaXMgY29tcGxldGUgYW5kIHJlbmRlciBidWZmZXIgaXMgY2FwdHVyZWRcbiAgICAgICAgdGhpcy5xdWV1ZVNjcmVlbnNob3QgPSB7fTtcbiAgICAgICAgdGhpcy5xdWV1ZVNjcmVlbnNob3QucHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMucXVldWVTY3JlZW5zaG90LnJlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICAgICAgdGhpcy5xdWV1ZVNjcmVlbnNob3QucmVqZWN0ID0gcmVqZWN0O1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMucXVldWVTY3JlZW5zaG90LnByb21pc2U7XG4gICAgfVxuXG4gICAgLy8gQ2FsbGVkIGFmdGVyIHJlbmRlcmluZywgY2FwdHVyZXMgcmVuZGVyIGJ1ZmZlciBhbmQgcmVzb2x2ZXMgcHJvbWlzZSB3aXRoIHRoZSBpbWFnZSBkYXRhXG4gICAgY29tcGxldGVTY3JlZW5zaG90ICgpIHtcbiAgICAgICAgaWYgKHRoaXMucXVldWVTY3JlZW5zaG90ICE9IG51bGwpIHtcbiAgICAgICAgICAgIC8vIEdldCBkYXRhIFVSTCwgY29udmVydCB0byBibG9iXG4gICAgICAgICAgICAvLyBTdHJpcCBob3N0L21pbWV0eXBlL2V0Yy4sIGNvbnZlcnQgYmFzZTY0IHRvIGJpbmFyeSB3aXRob3V0IFVURi04IG1hbmdsaW5nXG4gICAgICAgICAgICAvLyBBZGFwdGVkIGZyb206IGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL3VuY29uZWQvNDM3MDgyMlxuICAgICAgICAgICAgY29uc3QgdXJsID0gdGhpcy5jYW52YXMudG9EYXRhVVJMKCdpbWFnZS9wbmcnKTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBhdG9iKHVybC5zbGljZSgyMikpO1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoZGF0YS5sZW5ndGgpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgYnVmZmVyW2ldID0gZGF0YS5jaGFyQ29kZUF0KGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtidWZmZXJdLCB7IHR5cGU6ICdpbWFnZS9wbmcnIH0pO1xuXG4gICAgICAgICAgICAvLyBSZXNvbHZlIHdpdGggc2NyZWVuc2hvdCBkYXRhXG4gICAgICAgICAgICB0aGlzLnF1ZXVlU2NyZWVuc2hvdC5yZXNvbHZlKHsgdXJsLCBibG9iLCB0eXBlOiAncG5nJyB9KTtcbiAgICAgICAgICAgI
23459HRoaXMucXVldWVTY3JlZW5zaG90ID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFN0YXJ0cyBjYXB0dXJpbmcgYSB2aWRlbyBzdHJlYW0gZnJvbSB0aGUgY2FudmFzXG4gICAgc3RhcnRWaWRlb0NhcHR1cmUgKCkge1xuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5NZWRpYVJlY29yZGVyICE9PSAnZnVuY3Rpb24nIHx8ICF0aGlzLmNhbnZhcyB8fCB0eXBlb2YgdGhpcy5jYW52YXMuY2FwdHVyZVN0cmVhbSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ3dhcm46IFZpZGVvIGNhcHR1cmUgKENhbnZhcy5jYXB0dXJlU3RyZWFtIGFuZC9vciBNZWRpYVJlY29yZGVyIEFQSXMpIG5vdCBzdXBwb3J0ZWQgYnkgYnJvd3NlcicpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMudmlkZW9DYXB0dXJlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnd2FybjogVmlkZW8gY2FwdHVyZSBhbHJlYWR5IGluIHByb2dyZXNzLCBjYWxsIFNjZW5lLnN0b3BWaWRlb0NhcHR1cmUoKSBmaXJzdCcpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3RhcnQgYSBuZXcgY2FwdHVyZVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IGNhcCA9IHRoaXMudmlkZW9DYXB0dXJlID0ge307XG4gICAgICAgICAgICBjYXAuY2h1bmtzID0gW107XG4gICAgICAgICAgICBjYXAuc3RyZWFtID0gdGhpcy5jYW52YXMuY2FwdHVyZVN0cmVhbSgpO1xuICAgICAgICAgICAgY2FwLm9wdGlvbnMgPSB7IG1pbWVUeXBlOiAndmlkZW8vd2VibScgfTsgLy8gVE9ETzogc3VwcG9ydCBvdGhlciBmb3JtYXQgb3B0aW9uc1xuICAgICAgICAgICAgY2FwLm1lZGlhUmVjb3JkZXIgPSBuZXcgTWVkaWFSZWNvcmRlcihjYXAuc3RyZWFtLCBjYXAub3B0aW9ucyk7XG4gICAgICAgICAgICBjYXAubWVkaWFSZWNvcmRlci5vbmRhdGFhdmFpbGFibGUgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQuZGF0YS5zaXplID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBjYXAuY2h1bmtzLnB1c2goZXZlbnQuZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gU3RvcHBlZCByZWNvcmRpbmc/IENyZWF0ZSB0aGUgZmluYWwgY2FwdHVyZSBmaWxlIGJsb2JcbiAgICAgICAgICAgICAgICBpZiAoY2FwLnJlc29sdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGJsb2IgPSBuZXcgQmxvYihjYXAuY2h1bmtzLCB7IHR5cGU6IGNhcC5vcHRpb25zLm1pbWVUeXBlIH0pO1xuICAgICAgICAgICAgICAgICAgICBsZXQgdXJsID0gY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIEV4cGxpY2l0bHkgcmVtb3ZlIGFsbCBzdHJlYW0gdHJhY2tzLCBhbmQgc2V0IG9iamVjdHMgdG8gbnVsbFxuICAgICAgICAgICAgICAgICAgICBpZiAoY2FwLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRyYWNrcyA9IGNhcC5zdHJlYW0uZ2V0VHJhY2tzKCkgfHwgW107XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFja3MuZm9yRWFjaCh0cmFjayA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcC5zdHJlYW0ucmVtb3ZlVHJhY2sodHJhY2spO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FwLnN0cmVhbSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIGNhcC5tZWRpYVJlY29yZGVyID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52aWRlb0NhcHR1cmUgPSBudWxsO1xuXG4gICAgICAgICAgICAgICAgICAgIGNhcC5yZXNvbHZlKHsgdXJsLCBibG9iLCB0eXBlOiAnd2VibScgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNhcC5tZWRpYVJlY29yZGVyLnN0YXJ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRoaXMudmlkZW9DYXB0dXJlID0gbnVsbDtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdlcnJvcjogU2NlbmUgdmlkZW8gY2FwdHVyZSBmYWlsZWQnLCBlKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBTdG9wcyBjYXB0dXJpbmcgYSB2aWRlbyBzdHJlYW0gZnJvbSB0aGUgY2FudmFzLCByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHZpZGVvIHdoZW4gYXZhaWxhYmxlXG4gICAgc3RvcFZpZGVvQ2FwdHVyZSAoKSB7XG4gICAgICAgIGlmICghdGhpcy52aWRlb0NhcHR1cmUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCd3YXJuOiBObyBzY2VuZSB2aWRlbyBjYXB0dXJlIGluIHByb2dyZXNzLCBjYWxsIFNjZW5lLnN0YXJ0VmlkZW9DYXB0dXJlKCkgZmlyc3QnKTtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvbWlzZSB0aGF0IHdpbGwgcmVzb2x2ZSB3aGVuIGZpbmFsIHN0cmVhbSBpcyBhdmFpbGFibGVcbiAgICAgICAgdGhpcy52aWRlb0NhcHR1cmUucHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMudmlkZW9DYXB0dXJlLnJlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICAgICAgdGhpcy52aWRlb0NhcHR1cmUucmVqZWN0ID0gcmVqZWN0O1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTdG9wIHJlY29yZGluZ1xuICAgICAgICB0aGlzLnZpZGVvQ2FwdHVyZS5tZWRpYVJlY29yZGVyLnN0b3AoKTtcblxuICAgICAgICByZXR1cm4gdGhpcy52aWRlb0NhcHR1cmUucHJvbWlzZTtcbiAgICB9XG59XG4iLCIvKlxuQWRkIGV2ZW50cyB0byBhIGNsYXNzIG9yIG9iamVjdDpcbiAgICBjbGFzcyBNeUNsYXNzIHtcbiAgICAgICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgICAgICBzdWJzY3JpYmVNaXhpbih0aGlzKTsgLy8gQWRkIHRoZSBtaXhpbmcgZnVuY3Rpb25zIHRvIHRoZSBjbGFzc1xuICAgICAgICAgICAgLi4uXG4gICAgICAgICAgICB0aGlzLnRyaWdnZXIoJ3NvbWV0aGluZycsIHsgb3duZXI6IHRoaXMsIGNvbnRlbnQ6ICd0aGF0J30pOyAvLyB0cmlnZ2VyIGFuIGV2ZW50IHBhc3Npbmcgc29tZSBhcmd1bWVudHNcblxuU3Vic2NyaWJlIHRvIGV2ZW50cyBieSBkb2luZzpcbiAgICBteUNsYXNzLm9uKCdzb21ldGhpbmcnLCAoYXJncykgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhhcmdzKTtcbiAgICB9KTtcblxuVW5zdWJzY3JpYmUgdG8gZXZlbnRzIGJ5IGRvaW5nOlxuICAgIG15Q2xhc3Mub2ZmKCdzb21ldGhpbmcnKTtcblxub3IgbW9yZSBwcmVzaWNlbGx5OlxuICAgIG15Q2xhc3Mub2ZmKCdzb21ldGhpbmcnLCAoYXJncykgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhhcmdzKTtcbiAgICB9KTtcblxuVW5zdWJzY3JpYmUgdG8gYWxsIGV2ZW50cyBieTpcbiAgICBteUNsYXNzLm9mZkFsbCgpO1xuKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHN1YnNjcmliZU1peGluICh0YXJnZXQpIHtcbiAgICB2YXIgbGlzdGVuZXJzID0gbmV3IFNldCgpO1xuXG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24odGFyZ2V0LCB7XG5cbiAgICAgICAgb24gKHR5cGUsIGYpIHtcbiAgICAgICAgICAgIGxldCBsaXN0ZW5lciA9IHt9O1xuICAgICAgICAgICAgbGlzdGVuZXJbdHlwZV0gPSBmO1xuICAgICAgICAgICAgbGlzdGVuZXJzLmFkZChsaXN0ZW5lcik7XG4gICAgICAgI
23459H0sXG5cbiAgICAgICAgb2ZmICh0eXBlLCBmKSB7XG4gICAgICAgICAgICBpZiAoZikge1xuICAgICAgICAgICAgICAgIGxldCBsaXN0ZW5lciA9IHt9O1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyW3R5cGVdID0gZjtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuZGVsZXRlKGxpc3RlbmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGl0ZW0gb2YgbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGtleSBvZiBPYmplY3Qua2V5cyhpdGVtKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gdHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5kZWxldGUoaXRlbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIG9mZkFsbCAoKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnMuY2xlYXIoKTtcbiAgICAgICAgfSxcblxuICAgICAgICB0cmlnZ2VyIChldmVudCwgLi4uZGF0YSkge1xuICAgICAgICAgICAgZm9yICh2YXIgbGlzdGVuZXIgb2YgbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcltldmVudF0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJbZXZlbnRdKC4uLmRhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBsaXN0U3Vic2NyaXB0aW9ucyAoKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpdGVtIG9mIGxpc3RlbmVycykge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGl0ZW0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG59XG4iLCJsZXQgX2NyZWF0ZU9iamVjdFVSTDtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVPYmplY3RVUkwgKHVybCkge1xuICAgIGlmIChfY3JlYXRlT2JqZWN0VVJMID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgX2NyZWF0ZU9iamVjdFVSTCA9ICh3aW5kb3cuVVJMICYmIHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKSB8fCAod2luZG93LndlYmtpdFVSTCAmJiB3aW5kb3cud2Via2l0VVJMLmNyZWF0ZU9iamVjdFVSTCk7XG4gICAgICAgIGlmICh0eXBlb2YgX2NyZWF0ZU9iamVjdFVSTCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgX2NyZWF0ZU9iamVjdFVSTCA9IG51bGw7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwgKG9yIHZlbmRvciBwcmVmaXgpIG5vdCBmb3VuZCwgdW5hYmxlIHRvIGNyZWF0ZSBsb2NhbCBibG9iIFVSTHMnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmIChfY3JlYXRlT2JqZWN0VVJMKSB7XG4gICAgICAgIHJldHVybiBfY3JlYXRlT2JqZWN0VVJMKHVybCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gdXJsO1xuICAgIH1cbn1cbiIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIEVycm9yc0Rpc3BsYXkge1xuICAgIGNvbnN0cnVjdG9yKG1haW4pIHtcbiAgICAgICAgdGhpcy5tYWluID0gbWFpbjtcblxuICAgICAgICAvLyAgcHJpdmF0ZSB2YXJpYWJsZXNcbiAgICAgICAgdGhpcy53aWRnZXRzID0gW107XG5cbiAgICAgICAgLy8gRVZFTlRTXG4gICAgICAgIHRoaXMubWFpbi5zaGFkZXIuY2FudmFzLm9uKCdlcnJvcicsIChhcmcpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLm1haW4udmlzdWFsRGVidWdnZXIgJiYgdGhpcy5tYWluLnZpc3VhbERlYnVnZ2VyLnRlc3RpbmcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFuKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRFcnJvcihhcmcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLm1haW4uZWRpdG9yLm9uKCdjaGFuZ2VzJywgKGNtLCBjaGFuZ2VzT2JqcykgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMubWFpbi5zaGFkZXIuY2FudmFzLmlzVmFsaWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGNsZWFuKCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMud2lkZ2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy5tYWluLmVkaXRvci5yZW1vdmVMaW5lV2lkZ2V0KHRoaXMud2lkZ2V0c1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy53aWRnZXRzLmxlbmd0aCA9IDA7XG4gICAgfVxuXG4gICAgYWRkRXJyb3IoYXJncykge1xuICAgICAgICBsZXQgcmUgPSAvRVJST1I6XFxzK1xcZCs6KFxcZCspOlxccysoJy4qKS9nO1xuICAgICAgICBsZXQgbWF0Y2hlcyA9IHJlLmV4ZWMoYXJncy5lcnJvcik7XG4gICAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgICAgICBsZXQgbnVtTGluZXMgPSAwO1xuICAgICAgICAgICAgaWYgKHRoaXMubWFpbi5vcHRpb25zLmZyYWdfaGVhZGVyLmxlbmd0aCA+IDApXG4gICAgICAgICAgICAgICAgbnVtTGluZXMgKz0gKHRoaXMubWFpbi5vcHRpb25zLmZyYWdfaGVhZGVyLm1hdGNoKC9cXHI/XFxuL2cpIHx8ICcnKS5sZW5ndGg7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGxldCBsaW5lID0gcGFyc2VJbnQobWF0Y2hlc1sxXSkgLSBudW1MaW5lcztcbiAgICAgICAgICAgIGxldCBlciA9IG1hdGNoZXNbMl07XG4gICAgICAgICAgICBsZXQgbXNnID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG5cbiAgICAgICAgICAgIGxldCBpY29uID0gbXNnLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKSk7XG4gICAgICAgICAgICBpY29uLmNsYXNzTmFtZSA9ICdnZS1lcnJvci1pY29uJztcbiAgICAgICAgICAgIGljb24uaW5uZXJIVE1MID0gJ3gnO1xuICAgICAgICAgICAgbXNnLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGVyKSk7XG4gICAgICAgICAgICBtc2cuY2xhc3NOYW1lID0gJ2dlLWVycm9yJztcbiAgICAgICAgICAgI
23459HRoaXMud2lkZ2V0cy5wdXNoKHRoaXMubWFpbi5lZGl0b3IuYWRkTGluZVdpZGdldChsaW5lLCBtc2cpKTsvLywgeyBjb3Zlckd1dHRlcjogZmFsc2UsIG5vSFNjcm9sbDogdHJ1ZSB9KSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJpbXBvcnQgRXhwb3J0TW9kYWwgZnJvbSAnLi9tb2RhbHMvRXhwb3J0TW9kYWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFeHBvcnRJY29uIHtcbiAgICBjb25zdHJ1Y3RvciAobWFpbikge1xuICAgICAgICB0aGlzLm1haW4gPSBtYWluO1xuXG4gICAgICAgIHRoaXMuZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgdGhpcy5lbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ2dlX2V4cG9ydF9pY29uJyk7XG4gICAgICAgIHRoaXMuZWwuaW5uZXJIVE1MID0gJ+KWsyc7XG4gICAgICAgIC8vIHRoaXMuZWwuaW5uZXJIVE1MID0gJzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj5tb3JlX3ZlcnQ8L2k+JztcbiAgICAgICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKG1haW4uY2hhbmdlIHx8ICF0aGlzLm1vZGFsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tb2RhbCA9IG5ldyBFeHBvcnRNb2RhbCgnZ2VfZXhwb3J0JywgeyBtYWluOiBtYWluIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5tb2RhbC5wcmVzZW50TW9kYWwoZXZlbnQudGFyZ2V0Lm9mZnNldExlZnQsIGV2ZW50LnRhcmdldC5vZmZzZXRUb3ApO1xuICAgICAgICB9LCB0cnVlKTtcblxuICAgICAgICB0aGlzLm1haW4uY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMuZWwpO1xuICAgIH1cbn1cbiIsImltcG9ydCBDb2xvclBpY2tlciBmcm9tICcuL3BpY2tlcnMvQ29sb3JQaWNrZXInO1xuaW1wb3J0IFZlYzNQaWNrZXIgZnJvbSAnLi9waWNrZXJzL1ZlYzNQaWNrZXInO1xuaW1wb3J0IFZlYzJQaWNrZXIgZnJvbSAnLi9waWNrZXJzL1ZlYzJQaWNrZXInO1xuaW1wb3J0IEZsb2F0UGlja2VyIGZyb20gJy4vcGlja2Vycy9GbG9hdFBpY2tlcic7XG5cbmltcG9ydCBDb2xvciBmcm9tICcuL3BpY2tlcnMvdHlwZXMvQ29sb3InO1xuXG5pbXBvcnQgTW9kYWwgZnJvbSAnLi9tb2RhbHMvTW9kYWwnO1xuXG4vLyBSZXR1cm4gYWxsIHBhdHRlcm4gbWF0Y2hlcyB3aXRoIGNhcHR1cmVkIGdyb3Vwc1xuUmVnRXhwLnByb3RvdHlwZS5leGVjQWxsID0gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgbGV0IG1hdGNoID0gbnVsbDtcbiAgICBsZXQgbWF0Y2hlcyA9IFtdO1xuICAgIHdoaWxlIChtYXRjaCA9IHRoaXMuZXhlYyhzdHJpbmcpKSB7XG4gICAgICAgIGxldCBtYXRjaEFycmF
234595ID0gW107XG4gICAgICAgIGZvciAobGV0IGkgaW4gbWF0Y2gpIHtcbiAgICAgICAgICAgIGlmIChwYXJzZUludChpKSA9PSBpKSB7XG4gICAgICAgICAgICAgICAgbWF0Y2hBcnJheS5wdXNoKG1hdGNoW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBtYXRjaEFycmF5LmluZGV4ID0gbWF0Y2guaW5kZXg7XG4gICAgICAgIG1hdGNoZXMucHVzaChtYXRjaEFycmF5KTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXM7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIZWxwZXJzIHtcbiAgICBjb25zdHJ1Y3RvciAobWFpbikge1xuICAgICAgICB0aGlzLm1haW4gPSBtYWluO1xuICAgICAgICB0aGlzLm1haW4uZGVidWdnaW5nID0gZmFsc2U7XG5cbiAgICAgICAgbGV0IHN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUobWFpbi5lZGl0b3IuZ2V0V3JhcHBlckVsZW1lbnQoKSwgbnVsbCk7XG4gICAgICAgIGxldCBiZ0NvbG9yID0gbmV3IENvbG9yKHN0eWxlLmJhY2tncm91bmQgIT09ICcnID8gc3R5bGUuYmFja2dyb3VuZCA6IHN0eWxlLmJhY2tncm91bmRDb2xvcik7XG4gICAgICAgIGxldCBmZ0NvbG9yID0gbmV3IENvbG9yKHN0eWxlLmNvbG9yKTtcblxuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSB7XG4gICAgICAgICAgICBiZ0NvbG9yOiBiZ0NvbG9yLmdldFN0cmluZygncmdiJyksXG4gICAgICAgICAgICBmbkNvbG9yOiBmZ0NvbG9yLmdldFN0cmluZygncmdiJyksXG4gICAgICAgICAgICBkaW1Db2xvcjogJ3JnYigxMjcsIDEyNywgMTI3KScsXG4gICAgICAgICAgICBzZWxDb2xvcjogJ3JnYig0MCwgMTY4LCAxMDcpJyxcbiAgICAgICAgICAgIGxpbmtCdXR0b246IHRydWVcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBFVkVOVFNcbiAgICAgICAgbGV0IHdyYXBwZXIgPSB0aGlzLm1haW4uZWRpdG9yLmdldFdyYXBwZXJFbGVtZW50KCk7XG4gICAgICAgIHdyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGxldCBjdXJzb3IgPSB0aGlzLm1haW4uZWRpdG9yLmdldEN1cnNvcih0cnVlKTtcbiAgICAgICAgICAgIGxldCB0b2tlbiA9IHRoaXMubWFpbi5lZGl0b3IuZ2V0VG9rZW5BdChjdXJzb3IpO1xuICAgICAgICAgICAgaWYgKHRva2VuLnR5cGUgPT09ICd2YXJpYWJsZScpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1haW4udmlzdWFsRGVidWdnZXIuZGVidWcodG9rZW4uc3RyaW5nLCBjdXJzb3IubGluZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1haW4udXBkYXRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHdyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgLy8gYmFpbCBvdXQgaWYgd2Ugd2VyZSBkb2luZyBhIHNlbGVjdGlvbiBhbmQgbm90IGEgY2xpY2tcbiAgICAgICAgICAgIGlmICh0aGlzLm1haW4uZWRpdG9yLnNvbWV0aGluZ1NlbGVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBjdXJzb3IgPSB0aGlzLm1haW4uZWRpdG9yLmdldEN1cnNvcih0cnVlKTtcblxuICAgICAgICAgICAgLy8gc2VlIGlmIHRoZXJlIGlzIGEgbWF0Y2ggb24gdGhlIGN1cnNvciBjbGlja1xuICAgICAgICAgICAgbGV0IG1hdGNoID0gdGhpcy5nZXRNYXRjaChjdXJzb3IpO1xuICAgICAgICAgICAgbGV0IHRva2VuID0gdGhpcy5tYWluLmVkaXRvci5nZXRUb2tlbkF0KGN1cnNvcik7XG4gICAgICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1haW4udmlzdWFsRGVidWdnZXIuY2xlYW4oZXZlbnQpO1xuICAgICAgICAgICAgICAgIHRoaXMubWFpbi51cGRhdGUoKTtcblxuICAgICAgICAgICAgICAgIC8vIFRvZ2dsZXMgdGhlIHRyYWNrcGFkIHRvIGJlIG9mZiBpZiBpdCdzIGFscmVhZHkgcHJlc2VudC5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5hY3RpdmVNb2RhbCAmJiB0aGlzLmFjdGl2ZU1vZGFsLmlzVmlzaWJsZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLnJlbW92ZU1vZGFsKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAobWF0Y2gudHlwZSA9PT0gJ2NvbG9yJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsID0gbmV3IENvbG9yUGlja2VyKG1hdGNoLnN0cmluZywgdGhpcy5wcm9wZXJ0aWVzKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5zaG93QXQodGhpcy5tYWluLmVkaXRvcik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlTW9kYWwub24oJ2NoYW5nZWQnLCAoY29sb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBuZXdDb2xvciA9IGNvbG9yLmdldFN0cmluZygndmVjJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgc3RhcnQgPSB7IGxpbmU6IGN1cnNvci5saW5lLCBjaDogbWF0Y2guc3RhcnQgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlbmQgPSB7IGxpbmU6IGN1cnNvci5saW5lLCBjaDogbWF0Y2guZW5kIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXRjaC5lbmQgPSBtYXRjaC5zdGFydCArIG5ld0NvbG9yLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWFpbi5lZGl0b3IucmVwbGFjZVJhbmdlKG5ld0NvbG9yLCBzdGFydCwgZW5kLCBgKyR7bWF0Y2gudHlwZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5vbignbGlua0J1dHRvbicsIChjb2xvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbCA9IG5ldyBWZWMzUGlja2VyKGNvbG9yLmdldFN0cmluZygndmVjJyksIHRoaXMucHJvcGVydGllcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLnNob3dBdCh0aGlzLm1haW4uZWRpdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgI
23459HRoaXMuYWN0aXZlTW9kYWwub24oJ2NoYW5nZWQnLCAoZGlyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG5ld0RpciA9IGRpci5nZXRTdHJpbmcoJ3ZlYzMnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgc3RhcnQgPSB7IGxpbmU6IGN1cnNvci5saW5lLCBjaDogbWF0Y2guc3RhcnQgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZW5kID0geyBsaW5lOiBjdXJzb3IubGluZSwgY2g6IG1hdGNoLmVuZCB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoLmVuZCA9IG1hdGNoLnN0YXJ0ICsgbmV3RGlyLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1haW4uZWRpdG9yLnJlcGxhY2VSYW5nZShuZXdEaXIsIHN0YXJ0LCBlbmQsIGArJHttYXRjaC50eXBlfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobWF0Y2gudHlwZSA9PT0gJ3ZlYzMnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlTW9kYWwgPSBuZXcgVmVjM1BpY2tlcihtYXRjaC5zdHJpbmcsIHRoaXMucHJvcGVydGllcyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlTW9kYWwuc2hvd0F0KHRoaXMubWFpbi5lZGl0b3IpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLm9uKCdjaGFuZ2VkJywgKGRpcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG5ld0RpciA9IGRpci5nZXRTdHJpbmcoJ3ZlYzMnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzdGFydCA9IHsgbGluZTogY3Vyc29yLmxpbmUsIGNoOiBtYXRjaC5zdGFydCB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGVuZCA9IHsgbGluZTogY3Vyc29yLmxpbmUsIGNoOiBtYXRjaC5lbmQgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoLmVuZCA9IG1hdGNoLnN0YXJ0ICsgbmV3RGlyLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWFpbi5lZGl0b3IucmVwbGFjZVJhbmdlKG5ld0Rpciwgc3RhcnQsIGVuZCwgYCske21hdGNoLnR5cGV9YCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChtYXRjaC50eXBlID09PSAndmVjMicpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbCA9IG5ldyBWZWMyUGlja2VyKG1hdGNoLnN0cmluZywgdGhpcy5wcm9wZXJ0aWVzKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5zaG93QXQodGhpcy5tYWluLmVkaXRvcik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlTW9kYWwub24oJ2NoYW5nZWQnLCAocG9zKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbmV3cG9zID0gcG9zLmdldFN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHN0YXJ0ID0geyBsaW5lOiBjdXJzb3IubGluZSwgY2g6IG1hdGNoLnN0YXJ0IH07XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZW5kID0geyBsaW5lOiBjdXJzb3IubGluZSwgY2g6IG1hdGNoLmVuZCB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2guZW5kID0gbWF0Y2guc3RhcnQgKyBuZXdwb3MubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYWluLmVkaXRvci5yZXBsYWNlUmFuZ2UobmV3cG9zLCBzdGFydCwgZW5kLCBgKyR7bWF0Y2gudHlwZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKG1hdGNoLnR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZlTW9kYWwgPSBuZXcgRmxvYXRQaWNrZXIobWF0Y2guc3RyaW5nLCB0aGlzLnByb3BlcnRpZXMpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLnNob3dBdCh0aGlzLm1haW4uZWRpdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5vbignY2hhbmdlZCcsIChudW1iZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBuZXdOdW1iZXIgPSBudW1iZXIuZ2V0U3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgc3RhcnQgPSB7IGxpbmU6IGN1cnNvci5saW5lLCBjaDogbWF0Y2guc3RhcnQgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlbmQgPSB7IGxpbmU6IGN1cnNvci5saW5lLCBjaDogbWF0Y2guZW5kIH07XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXRjaC5lbmQgPSBtYXRjaC5zdGFydCArIG5ld051bWJlci5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1haW4uZWRpdG9yLnJlcGxhY2VSYW5nZShuZXdOdW1iZXIsIHN0YXJ0LCBlbmQsIGArJHttYXRjaC50eXBlfWApO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLm1haW4ub3B0aW9ucy50b29sdGlwcyAmJiAodG9rZW4udHlwZSA9PT0gJ2J1aWx0aW4nIHx8IHRva2VuLnR5cGUgPT09ICd2YXJpYWJsZS0zJykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1haW4udmlzdWFsRGVidWdnZXIuY2xlYW4oZXZlbnQpO1xuICAgICAgICAgICAgICAgIGxldCBodG1sID0gJzxwPkxlYXJuIG1vcmUgYWJvdXQ6IDxhIGhyZWY9XCJodHRwczovL3RoZWJvb2tvZnNoYWRlcnMuY29tL2dsb3NzYXJ5Lz9zZWFyY2g9JyArIHRva2VuLnN0cmluZyArICdcIiB0YXJnZXQ9XCJfYmxhbmtcIj4nICsgdG9rZW4uc3RyaW5nICsgJzwvYT48L3A+JztcbiAgICAgICAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsID0gbmV3IE1vZGFsKCdnZV90b29sdGlwJywgeyBpbm5lckhUTUw6IGh0bWwgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5zaG93QXQodGhpcy5tYWluLmVkaXRvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0b2tlbi50eXBlID09PSAndmFyaWFibGUnKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubWFpbi52aXN1YWxEZWJ1Z2dlcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1haW4udmlzdWFsRGVidWdnZXIuY2xlYW4oZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1haW4udmlzdWFsRGVidWdnZXIuaWx1bWluYXRlKHRva2VuLnN0cmluZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBnZXRNYXRjaCAoY3Vyc29yKSB7XG4gICAgICAgIGxldCB0eXBlcyA9IFsnY29sb3InLCAndmVjMycgLCd2ZWMyJywgJ251bWJlciddO1xuICAgICAgICBsZXQgcnRhO1xuICAgICAgICBmb3IgKGxldCBpIGluIHR5cGVzKSB7XG4gICAgICAgICAgICBydGEgPSB0aGlzLmdldFR5cGVNYXRjaChjdXJzb3IsIHR5cGVzW2ldKTtcbiAgICAgICAgICAgIGlmIChydGEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcnRhO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgI
23459HJldHVybjtcbiAgICB9XG5cbiAgICBnZXRUeXBlTWF0Y2ggKGN1cnNvciwgdHlwZSkge1xuICAgICAgICBpZiAoIXR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmU7XG4gICAgICAgIHN3aXRjaCh0eXBlLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgJ2NvbG9yJzpcbiAgICAgICAgICAgICAgICByZSA9IC92ZWNbM3w0XVxcKFtcXGR8LnwsXFxzXSpcXCkvZztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3ZlYzMnOlxuICAgICAgICAgICAgICAgIHJlID0gL3ZlYzNcXChbLXxcXGR8LnwsXFxzXSpcXCkvZztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3ZlYzInOlxuICAgICAgICAgICAgICAgIHJlID0gL3ZlYzJcXChbLXxcXGR8LnwsXFxzXSpcXCkvZztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ251bWJlcic6XG4gICAgICAgICAgICAgICAgcmUgPSAvWy1dP1xcZCtcXC5cXGQrfFxcZCtcXC58XFwuXFxkKy9nO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdpbnZhbGlkIG1hdGNoIHNlbGVjdGlvbicpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbGluZSA9IHRoaXMubWFpbi5lZGl0b3IuZ2V0TGluZShjdXJzb3IubGluZSk7XG4gICAgICAgIGxldCBtYXRjaGVzID0gcmUuZXhlY0FsbChsaW5lKTtcblxuICAgICAgICBpZiAobWF0Y2hlcykge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXRjaGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHZhbCA9IG1hdGNoZXNbaV1bMF07XG4gICAgICAgICAgICAgICAgbGV0IGxlbiA9IHZhbC5sZW5ndGg7XG4gICAgICAgICAgICAgICAgbGV0IHN0YXJ0ID0gbWF0Y2hlc1tpXS5pbmRleDtcbiAgICAgICAgICAgICAgICBsZXQgZW5kID0gbWF0Y2hlc1tpXS5pbmRleCArIGxlbjtcbiAgICAgICAgICAgICAgICBpZiAoY3Vyc29yLmNoID49IHN0YXJ0ICYmIGN1cnNvci5jaCA8PSBlbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydDogc3RhcnQsXG4gICAgICAgICAgICAgICAgICAgICAgICBlbmQ6IGVuZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZzogdmFsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG59XG4iLCJpbXBvcnQgTWVudUl0ZW0gZnJvbSAnLi9NZW51SXRlbSc7XG5pbXBvcnQgRXhwb3J0TW9kYWwgZnJvbSAnLi9tb2RhbHMvRXhwb3J0TW9kYWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZW51IHtcbiAgICBjb25zdHJ1Y3RvciAobWFpbikge1xuICAgICAgICB0aGlzLm1haW4gPSBtYWluO1xuICAgICAgICB0aGlzLm1lbnVzID0ge307XG5cbiAgICAgICAgLy8gQ1JFQVRFIE1FTlUgQ29udGFpbmVyXG4gICAgICAgIHRoaXMuZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpO1xuICAgICAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnZ2VfbWVudV9iYXInKTtcblxuICAgICAgICAvLyBORVdcbiAgICAgICAgdGhpcy5tZW51cy5uZXcgPSBuZXcgTWVudUl0ZW0odGhpcy5lbCwgJ2dlX21lbnUnLCAnPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPmFkZDwvaT4gTmV3JywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBtYWluLm5ldygpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBPUEVOXG4gICAgICAgIHRoaXMuZmlsZUlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICAgICAgdGhpcy5maWxlSW5wdXQuc2V0QXR0cmlidXRlKCd0eXBlJywgJ2ZpbGUnKTtcbiAgICAgICAgdGhpcy5maWxlSW5wdXQuc2V0QXR0cmlidXRlKCdhY2NlcHQnLCAndGV4dC94LXlhbWwnKTtcbiAgICAgICAgdGhpcy5maWxlSW5wdXQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgdGhpcy5maWxlSW5wdXQuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBtYWluLm9wZW4oZXZlbnQudGFyZ2V0LmZpbGVzWzBdKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubWVudXMub3BlbiA9IG5ldyBNZW51SXRlbSh0aGlzLmVsLCAnZ2VfbWVudScsICc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+Zm9sZGVyX29wZW48L2k+ICBPcGVuJywgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZpbGVJbnB1dC5jbGljaygpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyB0aGlzLm1lbnVzLmF1dG91cGRhdGUuYnV0dG9uLnN0eWxlLmNvbG9yID0gbWFpbi5hdXRvdXBkYXRlID8gJ3doaXRlJyA6ICdncmF5JztcblxuICAgICAgICAvLyBURVNUXG4gICAgICAgIHRoaXMubWVudXMudGVzdCA9IG5ldyBNZW51SXRlbSh0aGlzLmVsLCAnZ2VfbWVudScsICc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+dGltZWxpbmU8L2k+IFRlc3QnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIG1haW4udmlzdWFsRGVidWdnZXIuY2hlY2soKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU0hBUkVcbiAgICAgICAgdGhpcy5tZW51cy5zaGFyZSA9IG5ldyBNZW51SXRlbSh0aGlzLmVsLCAnZ2VfbWVudScsICc8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+YXJyb3dfdXB3YXJkPC9pPiBFeHBvcnQnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChtYWluLmNoYW5nZSB8fCAhdGhpcy5leHBvcnRNb2RhbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZXhwb3J0TW9kYWwgPSBuZXcgRXhwb3J0TW9kYWwoJ2dlX2V4cG9ydCcsIHsgbWFpbjogbWFpbiwgcG9zaXRpb246ICdmaXhlZCcgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBiYm94ID0gdGhpcy5tZW51cy5zaGFyZS5lbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICAgI
23459HRoaXMuZXhwb3J0TW9kYWwucHJlc2VudE1vZGFsKGJib3gubGVmdCAtIDUsIGJib3gudG9wICsgYmJveC5oZWlnaHQgKyA1KTtcbiAgICAgICAgfSk7XG5cblxuICAgICAgICAvLyBBVVRPVVBEQVRFXG4gICAgICAgIHRoaXMubWVudXMuYXV0b3VwZGF0ZSA9IG5ldyBNZW51SXRlbSh0aGlzLmVsLCAnZ2VfbWVudScsICcgPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPmF1dG9yZW5ldzwvaT4gVXBkYXRlOiBPTicsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKG1haW4uYXV0b3VwZGF0ZSkge1xuICAgICAgICAgICAgICAgIG1haW4uYXV0b3VwZGF0ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMubWVudXMuYXV0b3VwZGF0ZS5uYW1lID0gJzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj5hdXRvcmVuZXc8L2k+IFVwZGF0ZTogT0ZGJztcbiAgICAgICAgICAgICAgICAvLyB0aGlzLm1lbnVzLmF1dG91cGRhdGUuYnV0dG9uLnN0eWxlLmNvbG9yID0gJ2dyYXknO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbWFpbi5hdXRvdXBkYXRlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBtYWluLnVwZGF0ZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMubWVudXMuYXV0b3VwZGF0ZS5uYW1lID0gJzxpIGNsYXNzPVwibWF0ZXJpYWwtaWNvbnNcIj5hdXRvcmVuZXc8L2k+IFVwZGF0ZTogT04nO1xuICAgICAgICAgICAgICAgIC8vIHRoaXMubWVudXMuYXV0b3VwZGF0ZS5idXR0b24uc3R5bGUuY29sb3IgPSAnd2hpdGUnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBtYWluLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLmVsKTtcbiAgICB9XG59XG4iLCJleHBvcnQgZGVmYXVsdCBjbGFzcyBNZW51SXRlbSB7XG4gICAgY29uc3RydWN0b3IgKGNvbnRhaW5lciwgY2xhc3NOYW1lLCBuYW1lLCBvbkNsaWNrKSB7XG4gICAgICAgIHRoaXMuZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaScpO1xuICAgICAgICB0aGlzLmJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICAgICAgICB0aGlzLmJ1dHRvbi5jbGFzc05hbWUgPSBjbGFzc05hbWUgKyAnX2J1dHRvbic7XG4gICAgICAgIHRoaXMuZWwuYXBwZW5kQ2hpbGQodGhpcy5idXR0b24pO1xuICAgICAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCBjbGFzc05hbWUpO1xuICAgICAgICB0aGlzLmJ1dHRvbi5pbm5lckhUTUwgPSBuYW1lO1xuICAgICAgICB0aGlzLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgICAgICAgdGhpcy5oaWRkZW5DbGFzcyA9IGNsYXNzTmFtZSArICctLWhpZGRlbic7XG5cbiAgICAgICAgLy8gQXR0YWNoIGxpc3RlbmVycywgaW5jbHVkaW5nIHRob3NlIGZvciB0b29sdGlwIGJlaGF2aW9yXG4gICAgICAgIHRoaXMuYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgb25DbGljaywgdHJ1ZSk7XG5cbiAgICAgICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMuZWwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0IG5hbWUgKG5hbWUpIHtcbiAgICAgICAgdGhpcy5idXR0b24uaW5uZXJIVE1MID0gbmFtZTtcbiAgICB9XG5cbiAgICBoaWRlICgpIHtcbiAgICAgICAgdGhpcy5lbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgdGhpcy5jbGFzc05hbWUgKyAnICcgKyB0aGlzLmhpZGRlbkNsYXNzKTtcbiAgICB9XG5cbiAgICBzaG93ICgpIHtcbiAgICAgICAgdGhpcy5lbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgdGhpcy5jbGFzc05hbWUpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7IGlzQ29tbWVudGVkLCBpc0xpbmVBZnRlck1haW4sIGdldFZhcmlhYmxlVHlwZSwgZ2V0U2hhZGVyRm9yVHlwZVZhckluTGluZSwgZ2V0UmVzdWx0UmFuZ2UsIGdldERlbHRhU3VtLCBnZXRIaXRzLCBnZXRNZWRpYW4gfSBmcm9tICcuLi90b29scy9kZWJ1Z2dpbmcnO1xuaW1wb3J0IHsgdW5mb2N1c0xpbmUsIGZvY3VzTGluZSwgdW5mb2N1c0FsbCwgZm9jdXNBbGwgfSBmcm9tICcuLi9jb3JlL0VkaXRvci5qcyc7XG5cbnZhciBtYWluR0UgPSB7fTtcbnZhciBOX1NBTVBMRVMgPSAzMDtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmlzdWFsRGVidWdnZXIge1xuICAgIGNvbnN0cnVjdG9yIChtYWluKSB7XG4gICAgICAgIHRoaXMubWFpbiA9IG1haW47XG4gICAgICAgIHRoaXMuYnJlYWtwb2ludCA9IG51bGw7XG4gICAgICAgIG1haW5HRSA9IG1haW47XG5cbiAgICAgICAgdGhpcy50ZXN0aW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMudGVzdGluZ0ZyYWcgPSAnJztcbiAgICAgICAgdGhpcy50ZXN0aW5nTGluZSA9IDA7XG4gICAgICAgIHRoaXMudGVzdGluZ1Jlc3VsdHMgPSBbXTtcbiAgICAgICAgdGhpcy50ZXN0aW5nU2FtcGxlcyA9IFtdO1xuXG4gICAgICAgIHRoaXMubWFpbi5lZGl0b3Iub24oJ2d1dHRlckNsaWNrJywgKGNtLCBuKSA9PiB7XG4gICAgICAgICAgICBsZXQgaW5mbyA9IGNtLmxpbmVJbmZvKG4pO1xuICAgICAgICAgICAgaWYgKGluZm8gJiYgaW5mby5ndXR0ZXJNYXJrZXJzICYmIGluZm8uZ3V0dGVyTWFya2Vycy5icmVha3BvaW50cykge1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIGZvciBhbiBhY3RpdmUgdmFyaWFibGUgKGEgdmFyaWFibGUgdGhhdCBoYXZlIGJlZW4gZGVjbGFyZSBvciBtb2RpZnkgaW4gdGhpcyBsaW5lKVxuICAgICAgICAgICAgICAgIGxldCB2YXJpYWJsZVJFID0gbmV3IFJlZ0V4cCgnXFxcXHMqW2Zsb2F0fHZlYzJ8dmVjM3x2ZWM0XT9cXFxccysoW1xcXFx3fFxcXFxfXSopW1xcXFwuXFxcXHddKj9cXFxccytbXFxcXCt8XFxcXC18XFxcXFxcXFx8XFxcXCpdP1xcXFw9JywgJ2knKTtcbiAgICAgICAgICAgICAgICBsZXQgbWF0Y2ggPSB2YXJpYWJsZVJFLmV4ZWMoaW5mby50ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWJ1ZyhtYXRjaFsxXSwgaW5mby5saW5lKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5icmVha3BvaW50ID0gaW5mby5saW5lO1xuICAgICAgICAgICAgICAgI
23459H1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgY2hlY2soKSB7XG4gICAgICAgIC8vIENsZWFuIHByZXZpdXMgcmVjb3Jkc1xuICAgICAgICB0aGlzLnRlc3RpbmdSZXN1bHRzID0gW107XG5cbiAgICAgICAgbGV0IGNtID0gdGhpcy5tYWluLmVkaXRvcjtcbiAgICAgICAgbGV0IG5MaW5lcyA9IGNtLmdldERvYygpLnNpemU7XG5cbiAgICAgICAgbGV0IG1haW5TdGFydHNBdCA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbkxpbmVzOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChpc0xpbmVBZnRlck1haW4oY20sIGkpKSB7XG4gICAgICAgICAgICAgICAgbWFpblN0YXJ0c0F0ID0gaTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRlc3RMaW5lKG1haW5TdGFydHNBdCk7XG4gICAgfVxuXG4gICAgdGVzdExpbmUobkxpbmUpIHtcbiAgICAgICAgbGV0IGNtID0gbWFpbkdFLmVkaXRvcjtcbiAgICAgICAgbGV0IHZpc3VhbERlYnVnZ2VyID0gbWFpbkdFLnZpc3VhbERlYnVnZ2VyO1xuXG4gICAgICAgIC8vIElmIGlzIGRvbmUgdGVzdGluZy4uLlxuICAgICAgICBpZiAobkxpbmUgPj0gY20uZ2V0RG9jKCkuc2l6ZSkge1xuICAgICAgICAgICAgdmlzdWFsRGVidWdnZXIudGVzdGluZ0xpbmUgPSAwO1xuICAgICAgICAgICAgdmlzdWFsRGVidWdnZXIudGVzdGluZyA9IGZhbHNlO1xuXG4gICAgICAgICAgICBsZXQgcmVzdWx0cyA9IHZpc3VhbERlYnVnZ2VyLnRlc3RpbmdSZXN1bHRzO1xuICAgICAgICAgICAgbGV0IHJhbmdlID0gZ2V0UmVzdWx0UmFuZ2UocmVzdWx0cyk7XG4gICAgICAgICAgICBsZXQgc3VtID0gZ2V0RGVsdGFTdW0ocmVzdWx0cyk7XG4gICAgICAgICAgICBsZXQgaGl0cyA9IGdldEhpdHMocmVzdWx0cyk7XG5cbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdUZXN0OiAnLHJhbmdlLm1heC5tcyArICdtcycsIHJlc3VsdHMpO1xuICAgICAgICAgICAgY20uY2xlYXJHdXR0ZXIoJ2JyZWFrcG9pbnRzJyk7XG4gICAgICAgICAgICBmb3IgKGxldCBpIGluIHJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgICBsZXQgcGN0ID0gKHJlc3VsdHNbaV0uZGVsdGEgLyBzdW0pICogMTAwO1xuICAgICAgICAgICAgICAgIGxldCBzaXplID0gKHJlc3VsdHNbaV0uZGVsdGEgLyBzdW0pICogMzA7XG4gICAgICAgICAgICAgICAgbGV0IG1hcmtlckhUTUwgPSAnPGRpdj4nICsgcmVzdWx0c1tpXS5tcy50b0ZpeGVkKDIpO1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHRzW2ldLmRlbHRhID4gMC4pIHtcbiAgICAgICAgICAgICAgICAgICAgbWFya2VySFRNTCArPSAnPHNwYW4gY2xhc3M9XCJnZV9hc3NpbmdfbWFya2VyX3BjdCAnO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGN0ID4gKDEwMC4wIC8gaGl0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcmtlckhUTUwgKz0gJ2dlX2Fzc2luZ19tYXJrZXJfc2xvd2VyJztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBtYXJrZXJIVE1MICs9ICdcIiBzdHlsZT1cIndpZHRoOiAnICsgc2l6ZS50b0ZpeGVkKDApICsgJ3B4O1wiIGRhdGE9XCInICsgcGN0LnRvRml4ZWQoMCkgKyAnJVwiPjwvc3Bhbj4nO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNtLnNldEd1dHRlck1hcmtlcihyZXN1bHRzW2ldLmxpbmUsICdicmVha3BvaW50cycsIG1ha2VNYXJrZXIobWFya2VySFRNTCArICc8L2Rpdj4nKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNMaW5lQWZ0ZXJNYWluKGNtLCBuTGluZSkpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBsaW5lIGlzIGluc2lkZSB0aGUgbWFpbiBmdW5jdGlvblxuICAgICAgICAgICAgbGV0IHNoYWRlciA9IG1haW5HRS5zaGFkZXIuY2FudmFzO1xuXG4gICAgICAgICAgICAvLyBDaGVjayBmb3IgYW4gYWN0aXZlIHZhcmlhYmxlIChhIHZhcmlhYmxlIHRoYXQgaGF2ZSBiZWVuIGRlY2xhcmUgb3IgbW9kaWZ5IGluIHRoaXMgbGluZSlcbiAgICAgICAgICAgIGxldCB2YXJpYWJsZVJFID0gbmV3IFJlZ0V4cCgnXFxcXHMqW2Zsb2F0fHZlYzJ8dmVjM3x2ZWM0XT9cXFxccysoW1xcXFx3fFxcXFxfXSopW1xcXFwuXFxcXHddKj9cXFxccytbXFxcXCt8XFxcXC18XFxcXFxcXFx8XFxcXCpdP1xcXFw9JywgJ2knKTtcbiAgICAgICAgICAgIGxldCBtYXRjaCA9IHZhcmlhYmxlUkUuZXhlYyhjbS5nZXRMaW5lKG5MaW5lKSk7XG4gICAgICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBhY3RpdmUgdmFyaWFibGUsIGdldCB3aGF0IHR5cGUgaXNcbiAgICAgICAgICAgICAgICBsZXQgdmFyaWFibGUgPSBtYXRjaFsxXTtcbiAgICAgICAgICAgICAgICBsZXQgdHlwZSA9IGdldFZhcmlhYmxlVHlwZShjbSwgdmFyaWFibGUpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlID09PSAnbm9uZScpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgaXQgZmFpbHMgb24gZmluZGluZyB0aGUgdHlwZSBrZWVwIGdvaW5nIHdpdGggdGhlIHRlc3Qgb24gYW5vdGhlciBsaW5lXG4gICAgICAgICAgICAgICAgICAgIHZpc3VhbERlYnVnZ2VyLnRlc3RMaW5lKG5MaW5lICsgMSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBQcmVwYXJlXG4gICAgICAgICAgICAgICAgdmlzdWFsRGVidWdnZXIudGVzdGluZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgdmlzdWFsRGVidWdnZXIudGVzdGluZ0xpbmUgPSBuTGluZTtcbiAgICAgICAgICAgICAgICB2aXN1YWxEZWJ1Z2dlci50ZXN0aW5nRnJhZyA9IGdldFNoYWRlckZvclR5cGVWYXJJbkxpbmUoY20sIHR5cGUsIHZhcmlhYmxlLCBuTGluZSk7XG4gICAgICAgICAgICAgICAgdmlzdWFsRGVidWdnZXIudGVzdGluZ1NhbXBsZXMgPSBbXTtcblxuICAgICAgICAgICAgICAgIHVuZm9jdXNBbGwoY20pO1xuICAgICAgICAgICAgICAgIGZvY3VzTGluZShjbSwgbkxpbmUpO1xuICAgICAgICAgICAgICAgIG1haW5HRS5kZWJ1Z2dpbmcgPSB0cnVlO1xuXG4gICAgICAgICAgICAgICAgc2hhZGVyLnRlc3QodGhpcy5vblRlc3QsIHZpc3VhbERlYnVnZ2VyLnRlc3RpbmdGcmFnKTtcbiAgICAgICAgICAgI
23459H1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZpc3VhbERlYnVnZ2VyLnRlc3RMaW5lKG5MaW5lICsgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBJZiB0aGUgbGluZSBpcyBub3QgaW5zaWRlIG1haW4gZnVuY3Rpb24sIHRlc3QgdGhlIG5leHQgb25lLi4uXG4gICAgICAgICAgICB2aXN1YWxEZWJ1Z2dlci50ZXN0TGluZShuTGluZSArIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25UZXN0ICh0YXJnZXQpIHtcbiAgICAgICAgbGV0IGNtID0gbWFpbkdFLmVkaXRvcjtcbiAgICAgICAgbGV0IHNoYWRlciA9IG1haW5HRS5zaGFkZXIuY2FudmFzO1xuICAgICAgICBsZXQgdmlzdWFsRGVidWdnZXIgPSBtYWluR0UudmlzdWFsRGVidWdnZXI7XG5cbiAgICAgICAgLy8gSWYgdGhlIHRlc3Qgc2hhZGVyIGNvbXBpbGVkLi4uXG4gICAgICAgIGlmICh0YXJnZXQud2FzVmFsaWQpIHtcbiAgICAgICAgICAgIC8vIGdldCBkYXRhLCBwcm9jZXNzIGFuZCBzdG9yZS5cbiAgICAgICAgICAgIGxldCBlbGFwc2VkTXMgPSB0YXJnZXQudGltZUVsYXBzZWRNcztcblxuICAgICAgICAgICAgaWYgKHZpc3VhbERlYnVnZ2VyLnRlc3RpbmdTYW1wbGVzLmxlbmd0aCA8IE5fU0FNUExFUyAtIDEpIHtcbiAgICAgICAgICAgICAgICB2aXN1YWxEZWJ1Z2dlci50ZXN0aW5nU2FtcGxlcy5wdXNoKGVsYXBzZWRNcyk7XG4gICAgICAgICAgICAgICAgc2hhZGVyLnRlc3QodmlzdWFsRGVidWdnZXIub25UZXN0LCB2aXN1YWxEZWJ1Z2dlci50ZXN0aW5nRnJhZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb2N1c0FsbChjbSk7XG4gICAgICAgICAgICAgICAgbWFpbkdFLmRlYnVnZ2luZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHZpc3VhbERlYnVnZ2VyLnRlc3RpbmdTYW1wbGVzLnB1c2goZWxhcHNlZE1zKTtcbiAgICAgICAgICAgICAgICBlbGFwc2VkTXMgPSBnZXRNZWRpYW4odmlzdWFsRGVidWdnZXIudGVzdGluZ1NhbXBsZXMpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHJhbmdlID0gZ2V0UmVzdWx0UmFuZ2UodmlzdWFsRGVidWdnZXIudGVzdGluZ1Jlc3VsdHMpO1xuICAgICAgICAgICAgICAgIGxldCBkZWx0YSA9IGVsYXBzZWRNcyAtIHJhbmdlLm1heC5tcztcbiAgICAgICAgICAgICAgICBpZiAodmlzdWFsRGVidWdnZXIudGVzdGluZ1Jlc3VsdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbHRhID0gMC4wO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2aXN1YWxEZWJ1Z2dlci50ZXN0aW5nUmVzdWx0cy5wdXNoKHtsaW5lOnZpc3VhbERlYnVnZ2VyLnRlc3RpbmdMaW5lLCBtczp0YXJnZXQudGltZUVsYXBzZWRNcywgZGVsdGE6ZGVsdGF9KTtcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnVGVzdGluZyBsaW5lOicsIHZpc3VhbERlYnVnZ2VyLnRlc3RpbmdMaW5lLCBlbGFwc2VkTXMsIGRlbHRhLCByYW5nZSk7XG5cbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgZ3V0dGVyIG1hcmtlclxuICAgICAgICAgICAgICAgIGNtLnNldEd1dHRlck1hcmtlcih2aXN1YWxEZWJ1Z2dlci50ZXN0aW5nTGluZSxcbiAgICAgICAgICAgICAgICAgICAgJ2JyZWFrcG9pbnRzJyxcbiAgICAgICAgICAgICAgICAgICAgbWFrZU1hcmtlcihlbGFwc2VkTXMudG9GaXhlZCgyKSkpO1xuXG4gICAgICAgICAgICAgICAgLy8gVGVzdCBuZXh0IGxpbmVcbiAgICAgICAgICAgICAgICB2aXN1YWxEZWJ1Z2dlci50ZXN0TGluZSh2aXN1YWxEZWJ1Z2dlci50ZXN0aW5nTGluZSArIDEpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRhcmdldCk7XG4gICAgICAgICAgICAvLyBUZXN0IG5leHQgbGluZVxuICAgICAgICAgICAgdmlzdWFsRGVidWdnZXIudGVzdExpbmUodmlzdWFsRGVidWdnZXIudGVzdGluZ0xpbmUgKyAxKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRlYnVnICh2YXJpYWJsZSwgbkxpbmUpIHtcbiAgICAgICAgZm9jdXNBbGwodGhpcy5tYWluLmVkaXRvcik7XG4gICAgICAgIHRoaXMubWFpbi5kZWJ1Z2dpbmcgPSBmYWxzZTtcblxuICAgICAgICBpZiAoaXNMaW5lQWZ0ZXJNYWluKHRoaXMubWFpbi5lZGl0b3IsIG5MaW5lKSkge1xuICAgICAgICAgICAgdmFyIHR5cGUgPSBnZXRWYXJpYWJsZVR5cGUodGhpcy5tYWluLmVkaXRvciwgdmFyaWFibGUpO1xuICAgICAgICAgICAgaWYgKHR5cGUgIT09ICdub25lJykge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5tYWluLnNoYWRlci5jYW52YXMubG9hZChnZXRTaGFkZXJGb3JUeXBlVmFySW5MaW5lKHRoaXMubWFpbi5lZGl0b3IsIHR5cGUsIHZhcmlhYmxlLCBuTGluZSkpO1xuICAgICAgICAgICAgICAgIHVuZm9jdXNBbGwodGhpcy5tYWluLmVkaXRvcik7XG4gICAgICAgICAgICAgICAgZm9jdXNMaW5lKHRoaXMubWFpbi5lZGl0b3IsIG5MaW5lKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1haW4uZGVidWdnaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubWFpbi51cGRhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlsdW1pbmF0ZSAodmFyaWFibGUpIHtcbiAgICAgICAgaWYgKHRoaXMubWFpbi5kZWJidWdpbmcgJiYgdGhpcy52YXJpYWJsZSA9PT0gdGhpcy52YXJpYWJsZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRoaXMuY2xlYW4oKTtcblxuICAgICAgICBsZXQgY20gPSB0aGlzLm1haW4uZWRpdG9yO1xuXG4gICAgICAgIC8vIEhpZ2hsaWdodCBhbGwgY2FsbHMgdG8gYSB2YXJpYWJsZVxuICAgICAgICB0aGlzLm92ZXJsYXkgPSBzZWFyY2hPdmVybGF5KHZhcmlhYmxlLCB0cnVlKTtcbiAgICAgICAgY20uYWRkT3ZlcmxheSh0aGlzLm92ZXJsYXkpO1xuICAgICAgICBpZiAoY20uc2hvd01hdGNoZXNPblNjcm9sbGJhcikge1xuICAgICAgICAgICAgaWYgKHRoaXMuYW5ub3RhdGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFubm90YXRlLmNsZWFyKCk7IHRoaXMuYW5ub3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5hbm5vdGF0ZSA9IGNtLnNob3dNYXRjaGVzT25TY3JvbGxiYXIodmFyaWFibGUsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2xlYW4gKGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudCAmJiBldmVudC50YXJnZXQgJiYgZXZlbnQudGFyZ2V0LmNsYXNzTmFtZSA9PT0gJ2dlX2Fzc2luZ19tYXJrZXInKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgI
23459H1cblxuICAgICAgICBsZXQgY20gPSB0aGlzLm1haW4uZWRpdG9yO1xuICAgICAgICBjbS5jbGVhckd1dHRlcignYnJlYWtwb2ludHMnKTtcbiAgICAgICAgaWYgKHRoaXMub3ZlcmxheSkge1xuICAgICAgICAgICAgY20ucmVtb3ZlT3ZlcmxheSh0aGlzLm92ZXJsYXksIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudHlwZSA9IG51bGw7XG4gICAgICAgIGlmICh0aGlzLm1haW4uZGViYnVnaW5nKSB7XG4gICAgICAgICAgICB0aGlzLm1haW4uc2hhZGVyLmNhbnZhcy5sb2FkKHRoaXMubWFpbi5vcHRpb25zLmZyYWdfaGVhZGVyICsgdGhpcy5tYWluLmVkaXRvci5nZXRWYWx1ZSgpICsgdGhpcy5tYWluLm9wdGlvbnMuZnJhZ19mb290ZXIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubWFpbi5kZWJidWdpbmcgPSBmYWxzZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIG1ha2VNYXJrZXIoaHRtbCwgZXh0cmFDbGFzcykge1xuICAgIGxldCBtYXJrZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBtYXJrZXIuc2V0QXR0cmlidXRlKCdjbGFzcycsICdnZV9hc3NpbmdfbWFya2VyJyk7XG4gICAgbWFya2VyLmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIG1hcmtlcjtcbn1cblxuZnVuY3Rpb24gc2VhcmNoT3ZlcmxheShxdWVyeSwgY2FzZUluc2Vuc2l0aXZlKSB7XG4gICAgaWYgKHR5cGVvZiBxdWVyeSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcXVlcnkgPSBuZXcgUmVnRXhwKHF1ZXJ5LnJlcGxhY2UoL1tcXC1cXFtcXF1cXC9cXHtcXH1cXChcXClcXCpcXCtcXD9cXC5cXFxcXFxeXFwkXFx8XS9nLCAnXFxcXCQmJyksIGNhc2VJbnNlbnNpdGl2ZSA/ICdnaScgOiAnZycpO1xuICAgIH1cbiAgICBlbHNlIGlmICghcXVlcnkuZ2xvYmFsKSB7XG4gICAgICAgIHF1ZXJ5ID0gbmV3IFJlZ0V4cChxdWVyeS5zb3VyY2UsIHF1ZXJ5Lmlnbm9yZUNhc2UgPyAnZ2knIDogJ2cnKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICB0b2tlbjogZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICAgICAgICBxdWVyeS5sYXN0SW5kZXggPSBzdHJlYW0ucG9zO1xuICAgICAgICAgICAgdmFyIG1hdGNoID0gcXVlcnkuZXhlYyhzdHJlYW0uc3RyaW5nKTtcbiAgICAgICAgICAgIGlmIChtYXRjaCAmJiBtYXRjaC5pbmRleCA9PT0gc3RyZWFtLnBvcykge1xuICAgICAgICAgICAgICAgIHN0cmVhbS5wb3MgKz0gbWF0Y2hbMF0ubGVuZ3RoIHx8IDE7XG4gICAgICAgICAgICAgICAgcmV0dXJuICdzZWFyY2hpbmcnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICBzdHJlYW0ucG9zID0gbWF0Y2guaW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdHJlYW0uc2tpcFRvRW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufVxuIiwiaW1wb3J0IE1lbnVJdGVtIGZyb20gJy4uL01lbnVJdGVtJztcbmltcG9ydCBNb2RhbCBmcm9tICcuL01vZGFsJztcbi8vIGltcG9ydCB7IHNhdmVPblNlcnZlciwgY3JlYXRlT3BlbkZyYW1lQXJ0d29yayB9IGZyb20gJy4uLy4uL2lvL3NoYXJlJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXhwb3J0TW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG4gICAgY29uc3RydWN0b3IgKENTU19QUkVGSVgsIHByb3BlcnRpZXMpIHtcbiAgICAgICAgc3VwZXIoQ1NTX1BSRUZJWCwgcHJvcGVydGllcyk7XG4gICAgICAgIHRoaXMubWFpbiA9IHByb3BlcnRpZXMubWFpbjtcblxuICAgICAgICB0aGlzLnNhdmUgPSBuZXcgTWVudUl0ZW0odGhpcy5lbCwgJ2dlX3N1Yl9tZW51JywgJ0Rvd25sb2FkIGZpbGUnLCAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIHByb3BlcnRpZXMubWFpbi5kb3dubG9hZCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyB0aGlzLmNvZGVVUkwgPSBuZXcgTWVudUl0ZW0odGhpcy5lbCwgJ2dlX3N1Yl9tZW51JywgJ0NvZGUgVVJMLi4uJywgKGV2ZW50KSA9PiB7XG4gICAgICAgIC8vICAgICBzYXZlT25TZXJ2ZXIodGhpcy5tYWluLCAoZXZlbnQpID0+IHtcbiAgICAgICAgLy8gICAgICAgICBwcm9tcHQoJ1VzZSB0aGlzIHVybCB0byBzaGFyZSB5b3VyIGNvZGUnLCAnaHR0cDovL3RoZWJvb2tvZnNoYWRlcnMuY29tL2VkaXQucGhwP2xvZz0nICsgZXZlbnQubmFtZSk7XG4gICAgICAgIC8vICAgICAgICAgdGhpcy5yZW1vdmVNb2RhbCgpO1xuICAgICAgICAvLyAgICAgfSk7XG4gICAgICAgIC8vIH0pO1xuXG4gICAgICAgIC8vIHRoaXMuc2hhZGVyVVJMID0gbmV3IE1lbnVJdGVtKHRoaXMuZWwsICdnZV9zdWJfbWVudScsICdBcnR3b3JrIFVSTC4uLicsIChldmVudCkgPT4ge1xuICAgICAgICAvLyAgICAgc2F2ZU9uU2VydmVyKHRoaXMubWFpbiwgKGV2ZW50KSA9PiB7XG4gICAgICAgIC8vICAgICAgICAgcHJvbXB0KCdVc2UgdGhpcyB1cmwgdG8gc2hhcmUgeW91ciBhcnR3b3JrJywgJ2h0dHA6Ly9wbGF5ZXIudGhlYm9va29mc2hhZGVycy5jb20vP2xvZz0nICsgZXZlbnQubmFtZSk7XG4gICAgICAgIC8vICAgICAgICAgdGhpcy5yZW1vdmVNb2RhbCgpO1xuICAgICAgICAvLyAgICAgfSk7XG4gICAgICAgIC8vIH0pO1xuXG4gICAgICAgIC8vIGxldCBzaGFyZU9GID0gbmV3IE1lbnVJdGVtKHRoaXMuZWwsICdnZV9zdWJfbWVudScsICdBcnR3b3JrIHRvIFtvXScsIChldmVudCkgPT4ge1xuICAgICAgICAvLyAgICAgc2hhcmVPRi5lbC5pbm5lckhUTUwgPSAnQXJ0d29yayB0byBbb106IGFkZGluZyB0byBjb2xsZWN0aW9uJztcbiAgICAgICAgLy8gICAgIHNhdmVPblNlcnZlcih0aGlzLm1haW4sIChldmVudCkgPT4ge1xuICAgICAgICAvLyAgICAgICAgIGNyZWF0ZU9wZW5GcmFtZUFydHdvcmsodGhpcy5tYWluLCBldmVudC5uYW1lLCBldmVudC51cmwsIChzdWNjZXNzKSA9PiB7XG4gICAgICAgIC8vICAgICAgICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgIC8vICAgICAgICAgICAgICAgICBzaGFyZU9GLmVsLmlubmVySFRNTCA9ICdBcnR3b3JrIHRvIFtvXTogYWRkZWQhJztcbiAgICAgICAgLy8gICAgICAgICAgICAgfVxuICAgICAgICAvLyAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgI
23459HNoYXJlT0YuZWwuaW5uZXJIVE1MID0gJ0FydHdvcmsgdG8gW29dOiBmYWlsZWQgOignO1xuICAgICAgICAvLyAgICAgICAgICAgICB9XG4gICAgICAgIC8vICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAvLyAgICAgICAgICAgICAgICAgc2hhcmVPRi5lbC5pbm5lckhUTUwgPSAnW29dJztcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTW9kYWwoKTtcbiAgICAgICAgLy8gICAgICAgICAgICAgfSwgNDAwMCk7XG4gICAgICAgIC8vICAgICAgICAgfSk7XG4gICAgICAgIC8vICAgICB9KTtcbiAgICAgICAgLy8gfSk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgc3Vic2NyaWJlTWl4aW4gfSBmcm9tICcuLi8uLi90b29scy9taXhpbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1vZGFsIHtcbiAgICBjb25zdHJ1Y3RvciAoQ1NTX1BSRUZJWCwgcHJvcGVydGllcykge1xuICAgICAgICBzdWJzY3JpYmVNaXhpbih0aGlzKTtcbiAgICAgICAgdGhpcy5DU1NfUFJFRklYID0gQ1NTX1BSRUZJWDtcblxuICAgICAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyB8fCB7fTtcbiAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICB0aGlzW3Byb3BdID0gcHJvcGVydGllc1twcm9wXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgdGhpcy5lbC5jbGFzc05hbWUgPSB0aGlzLkNTU19QUkVGSVggKyAnX21vZGFsIGdlX21vZGFsJztcbiAgICAgICAgdGhpcy5lbC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmJnQ29sb3I7XG4gICAgICAgIHRoaXMuZWwuaW5uZXJIVE1MID0gdGhpcy5pbm5lckhUTUwgfHwgJyc7XG5cbiAgICAgICAgaWYgKHRoaXMuZWxlbWVudHMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5lbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMuZWwuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50c1tpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmlzVmlzaWJsZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIGNsb3NlICgpIHtcbiAgICAgICAgdGhpcy50cmlnZ2VyKCdjbG9zZScpO1xuICAgIH1cblxuICAgIHNob3dBdCAoY20pIHtcbiAgICAgICAgbGV0IGN1cnNvciA9IGNtLmN1cnNvckNvb3Jkcyh0cnVlLCAncGFnZScpO1xuICAgICAgICBsZXQgeCA9IGN1cnNvci5sZWZ0O1xuICAgICAgICBsZXQgeSA9IGN1cnNvci50b3A7XG5cbiAgICAgICAgeSArPSAzMDtcblxuICAgICAgICB0aGlzLnByZXNlbnRNb2RhbCh4LCB5KTtcbiAgICB9XG5cbiAgICBwcmVzZW50TW9kYWwgKHgsIHkpIHtcbiAgICAgICAgLy8gTGlzdGVuIGZvciBpbnRlcmFjdGlvbiBvdXRzaWRlIG9mIHRoZSBtb2RhbFxuICAgICAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9uQ2xpY2tPdXRzaWRlSGFuZGxlciA9IGFkZEV2ZW50KGRvY3VtZW50LmJvZHksICdjbGljaycsIHRoaXMub25DbGlja091dHNpZGUsIHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5vbktleVByZXNzSGFuZGxlciA9IGFkZEV2ZW50KHdpbmRvdywgJ2tleWRvd24nLCB0aGlzLm9uS2V5UHJlc3MsIHRoaXMpO1xuICAgICAgICB9LCAwKTtcbiAgICAgICAgdGhpcy5pc1Zpc2libGUgPSB0cnVlO1xuXG4gICAgICAgIHRoaXMuZWwuc3R5bGUubGVmdCA9IHggKyAncHgnO1xuICAgICAgICB0aGlzLmVsLnN0eWxlLnRvcCA9IHkgKyAncHgnO1xuICAgICAgICB0aGlzLmVsLnN0eWxlLndpZHRoID0gdGhpcy53aWR0aCArICdweCc7XG4gICAgICAgIHRoaXMuZWwuc3R5bGUuaGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyAncHgnO1xuXG4gICAgICAgIGlmICh0aGlzLnBvc2l0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmVsLnN0eWxlLnBvc2l0aW9uID0gdGhpcy5wb3NpdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5lbCk7XG5cbiAgICAgICAgdGhpcy50cmlnZ2VyKCdzaG93Jyk7XG4gICAgfVxuXG4gICAgZ2V0TW9kYWxDbGFzcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuQ1NTX1BSRUZJWCArICdtb2RhbCc7XG4gICAgfVxuXG4gICAgb25LZXlQcmVzcyAoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVNb2RhbCgpO1xuICAgIH1cblxuICAgIG9uQ2xpY2tPdXRzaWRlIChldmVudCkge1xuICAgICAgICAvLyBIQUNLWSEhXG4gICAgICAgIC8vIEEgY2xpY2sgZXZlbnQgZmlyZXMgb24gdGhlIGJvZHkgYWZ0ZXIgbW91c2Vkb3duIC0gbW91c2Vtb3ZlLCBzaW11bHRhbmVvdXNseSB3aXRoXG4gICAgICAgIC8vIG1vdXNldXAuIFNvIGlmIHNvbWVvbmUgc3RhcnRlZCBhIG1vdXNlIGFjdGlvbiBpbnNpZGUgdGhlIG1vZGFsIGFuZCB0aGVuXG4gICAgICAgIC8vIG1vdXNldXAnZCBvdXRzaWRlIG9mIGl0LCBpdCBmaXJlcyBhIGNsaWNrIGV2ZW50IG9uIHRoZSBib2R5LCB0aHVzLCBjYXVzaW5nIHRoZVxuICAgICAgICAvLyBtb2RhbCB0byBkaXNhcHBlYXIgd2hlbiB0aGUgdXNlciBkb2VzIG5vdCBleHBlY3QgaXQgdG8sIHNpbmNlIHRoZSBtb3VzZSBkb3duIGV2ZW50XG4gICAgICAgIC8vIGRpZCBub3Qgc3RhcnQgb3V0c2lkZSB0aGUgbW9kYWwuXG4gICAgICAgIC8vIFRoZXJlIG1pZ2h0IGJlIChvciBzaG91bGQgYmUpIGEgYmV0dGVyIHdheSB0byB0cmFjayB0aGlzLCBidXQgcmlnaHQgbm93LCBqdXN0IGNhbmNlbFxuICAgICAgICAvLyB0aGUgZXZlbnQgaWYgdGhlIHRhcmdldCBlbmRzIHVwIGJlaW5nIG9uIHRoZSBib2R5IGRpcmVjdGx5IHJhdGhlciB0aGFuIG9uIG9uZSBvZiB0aGVcbiAgICAgICAgLy8gb3RoZXIgY2hpbGQgZWxlbWVudHMuXG4gICAgICAgIGlmIChldmVudC50YXJnZXQgPT09IGRvY3VtZW50LmJvZHkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBlbmQgdGhpcyBzcGVjaWZpYyBoYWNreSBwYXJ0XG4gICAgICAgIGxldCB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgICAgI
23459HdoaWxlICh0YXJnZXQgIT09IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJiAhdGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucyh0aGlzLmdldE1vZGFsQ2xhc3MoKSkpIHtcbiAgICAgICAgICAgICAgICB0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF0YXJnZXQuY2xhc3NMaXN0LmNvbnRhaW5zKHRoaXMuZ2V0TW9kYWxDbGFzcygpKSkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTW9kYWwoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqICBSZW1vdmVzIG1vZGFsIGZyb20gRE9NIGFuZCBkZXN0cm95cyByZWxhdGVkIGV2ZW50IGxpc3RlbmVyc1xuICAgICAqL1xuICAgIHJlbW92ZU1vZGFsICgpIHtcbiAgICAgICAgaWYgKHRoaXMuZWwgJiYgdGhpcy5lbC5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5lbCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVtb3ZlRXZlbnQoZG9jdW1lbnQuYm9keSwgJ2NsaWNrJywgdGhpcy5vbkNsaWNrT3V0c2lkZUhhbmRsZXIpO1xuICAgICAgICB0aGlzLm9uQ2xpY2tPdXRzaWRlSGFuZGxlciA9IG51bGw7XG4gICAgICAgIHJlbW92ZUV2ZW50KHdpbmRvdywgJ2tleWRvd24nLCB0aGlzLm9uS2V5UHJlc3NIYW5kbGVyKTtcbiAgICAgICAgdGhpcy5vbktleVByZXNzSGFuZGxlciA9IG51bGw7XG5cbiAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICB0aGlzLmlzVmlzaWJsZSA9IGZhbHNlO1xuICAgIH1cbn1cblxuLyogRXZlbnQgaGFuZGxpbmcgKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRFdmVudCAoZWxlbWVudCwgZXZlbnQsIGNhbGxiYWNrLCBjYWxsZXIpIHtcbiAgICBsZXQgaGFuZGxlcjtcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGhhbmRsZXIgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICBjYWxsYmFjay5jYWxsKGNhbGxlciwgZSk7XG4gICAgfSwgZmFsc2UpO1xuICAgIHJldHVybiBoYW5kbGVyO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlRXZlbnQgKGVsZW1lbnQsIGV2ZW50LCBjYWxsYmFjaykge1xuICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgY2FsbGJhY2ssIGZhbHNlKTtcbn1cbiIsIi8qXG5PcmlnaW5hbDogaHR0cHM6Ly9naXRodWIuY29tL3RhbmdyYW1zL3RhbmdyYW0tcGxheS9ibG9iL2doLXBhZ2VzL3NyYy9qcy9hZGRvbnMvdWkvd2lkZ2V0cy9Db2xvclBpY2tlck1vZGFsLmpzXG5BdXRob3I6IExvdSBIdWFuZyAoQHNhaWtvZmlzaClcbiovXG5cbmltcG9ydCBQaWNrZXIgZnJvbSAnLi9QaWNrZXInO1xuaW1wb3J0IENvbG9yIGZyb20gJy4vdHlwZXMvQ29sb3InO1xuaW1wb3J0IHsgYWRkRXZlbnQsIHJlbW92ZUV2ZW50IH0gZnJvbSAnLi9QaWNrZXInO1xuaW1wb3J0IHsgZ2V0RGV2aWNlUGl4ZWxSYXRpbyB9IGZyb20gJy4uLy4uL3Rvb2xzL2NvbW1vbic7XG5cbmltcG9ydCB7IHN1YnNjcmliZUludGVyYWN0aXZlRG9tIH0gZnJvbSAnLi4vLi4vdG9vbHMvaW50ZXJhY3RpdmVEb20nO1xuXG4vLyBTb21lIGNvbW1vbiB1c2UgdmFyaWFibGVzXG5sZXQgY3VycmVudFRhcmdldDtcbmxldCBjdXJyZW50VGFyZ2V0SGVpZ2h0ID0gMDtcbmxldCBkb21DYWNoZTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29sb3JQaWNrZXIgZXh0ZW5kcyBQaWNrZXIge1xuICAgIGNvbnN0cnVjdG9yIChjb2xvciA9ICd2ZWMzKDEuMCwwLjAsMC4wKScsIHByb3BlcnRpZXMgPSB7fSkge1xuICAgICAgICBzdXBlcignZ2VfY29sb3JwaWNrZXJfJywgcHJvcGVydGllcyk7XG5cbiAgICAgICAgdGhpcy53aWR0aCA9IDI1MDsgLy8gaW4gcGl4ZWxzXG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gMjUwOyAvLyBpbiBwaXhlbHNcblxuICAgICAgICB0aGlzLmRpc2MgPSB7IHdpZHRoOiAyMDAsIGhlaWdodDogMjAwIH07XG4gICAgICAgIHRoaXMuYmFybHVtID0geyB3aWR0aDogMjUsIGhlaWdodDogMjAwIH07XG5cbiAgICAgICAgdGhpcy5zZXRWYWx1ZShjb2xvcik7XG4gICAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cblxuICAgIGluaXQoKSB7XG4gICAgICAgIGlmICghZG9tQ2FjaGUpIHtcbiAgICAgICAgICAgIGxldCBtb2RhbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgbGV0IHBhdGNoID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBsZXQgbWFwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBsZXQgZGlzYyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgICAgICAgbGV0IGNvdmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBsZXQgY3Vyc29yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBsZXQgYmFyYmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGxldCBiYXJ3aGl0ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICAgICAgbGV0IGJhcmx1bSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgICAgICAgbGV0IGJhcmN1cnNvcnMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICAgIGxldCBsZWZ0Y3Vyc29yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBsZXQgcmlnaHRjdXJzb3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblxuICAgICAgICAgICAgbW9kYWwuY2xhc3NOYW1lID0gdGhpcy5DU1NfUFJFRklYICsgJ21vZGFsIGdlX3BpY2tlcl9tb2RhbCc7XG4gICAgICAgICAgICBtb2RhbC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmJnQ29sb3I7XG4gICAgICAgICAgICBwYXRjaC5jbGFzc05hbWUgPSB0aGlzLkNTU19QUkVGSVggKyAncGF0Y2gnO1xuICAgICAgICAgICAgcGF0Y2guc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5iZ0NvbG9yO1xuICAgICAgICAgICAgbWFwLmNsYXNzTmFtZSA9IHRoaXMuQ1NTX1BSRUZJWCArICdoc3YtbWFwJztcbiAgICAgICAgICAgIGRpc2MuY2xhc3NOYW1lID0gdGhpcy5DU1NfUFJFRklYICsgJ2Rpc2MnO1xuICAgICAgICAgICAgZGlzYy5zdHlsZS5iYWNrZ3JvdW5k
23459Q29sb3IgPSB0aGlzLmJnQ29sb3I7XG4gICAgICAgICAgICBjb3Zlci5jbGFzc05hbWUgPSB0aGlzLkNTU19QUkVGSVggKyAnZGlzYy1jb3Zlcic7XG4gICAgICAgICAgICBjdXJzb3IuY2xhc3NOYW1lID0gdGhpcy5DU1NfUFJFRklYICsgJ2Rpc2MtY3Vyc29yJztcbiAgICAgICAgICAgIGJhcmJnLmNsYXNzTmFtZSA9IHRoaXMuQ1NTX1BSRUZJWCArICdiYXItYmcnO1xuICAgICAgICAgICAgYmFyd2hpdGUuY2xhc3NOYW1lID0gdGhpcy5DU1NfUFJFRklYICsgJ2Jhci13aGl0ZSc7XG4gICAgICAgICAgICBiYXJsdW0uY2xhc3NOYW1lID0gdGhpcy5DU1NfUFJFRklYICsgJ2Jhci1sdW1pbmFuY2UnO1xuICAgICAgICAgICAgYmFyY3Vyc29ycy5jbGFzc05hbWUgPSB0aGlzLkNTU19QUkVGSVggKyAnYmFyLWN1cnNvcnMnO1xuICAgICAgICAgICAgbGVmdGN1cnNvci5jbGFzc05hbWUgPSB0aGlzLkNTU19QUkVGSVggKyAnYmFyLWN1cnNvci1sZWZ0JztcbiAgICAgICAgICAgIHJpZ2h0Y3Vyc29yLmNsYXNzTmFtZSA9IHRoaXMuQ1NTX1BSRUZJWCArICdiYXItY3Vyc29yLXJpZ2h0JztcblxuICAgICAgICAgICAgbWFwLmlkID0gJ2NwLW1hcCc7XG4gICAgICAgICAgICBiYXJjdXJzb3JzLmlkID0gJ2NwLWJhcic7XG5cbiAgICAgICAgICAgIG1vZGFsLmFwcGVuZENoaWxkKHBhdGNoKTtcbiAgICAgICAgICAgIG1vZGFsLmFwcGVuZENoaWxkKG1hcCk7XG5cbiAgICAgICAgICAgIG1hcC5hcHBlbmRDaGlsZChkaXNjKTtcbiAgICAgICAgICAgIG1hcC5hcHBlbmRDaGlsZChjb3Zlcik7XG4gICAgICAgICAgICBtYXAuYXBwZW5kQ2hpbGQoY3Vyc29yKTtcbiAgICAgICAgICAgIG1hcC5hcHBlbmRDaGlsZChiYXJiZyk7XG4gICAgICAgICAgICBtYXAuYXBwZW5kQ2hpbGQoYmFyd2hpdGUpO1xuICAgICAgICAgICAgbWFwLmFwcGVuZENoaWxkKGJhcmx1bSk7XG4gICAgICAgICAgICBtYXAuYXBwZW5kQ2hpbGQoYmFyY3Vyc29ycyk7XG4gICAgICAgICAgICBiYXJjdXJzb3JzLmFwcGVuZENoaWxkKGxlZnRjdXJzb3IpO1xuICAgICAgICAgICAgYmFyY3Vyc29ycy5hcHBlbmRDaGlsZChyaWdodGN1cnNvcik7XG5cbiAgICAgICAgICAgIGRvbUNhY2hlID0gbW9kYWw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZXR1cm5zIGEgY2xvbmUgb2YgdGhlIGNhY2hlZCBkb2N1bWVudCBmcmFnbWVudFxuICAgICAgICB0aGlzLmVsID0gZG9tQ2FjaGUuY2xvbmVOb2RlKHRydWUpO1xuICAgICAgICBzdWJzY3JpYmVJbnRlcmFjdGl2ZURvbSh0aGlzLmVsLCB7IG1vdmU6IHRydWUsIHJlc2l6ZTogZmFsc2UsIHNuYXA6IGZhbHNlIH0pO1xuXG4gICAgICAgIC8vIFRPRE86IEltcHJvdmUgdGhlc2UgcmVmZXJlbmNlc1xuICAgICAgICAvLyBUaGUgY2FjaGluZyBvZiByZWZlcmVuY2VzIGlzIGxpa2VseSB0byBiZSBpbXBvcnRhbnQgZm9yIHNwZWVkXG4gICAgICAgIHRoaXMuZG9tID0ge307XG4gICAgICAgIHRoaXMuZG9tLmhzdk1hcCA9IHRoaXMuZWwucXVlcnlTZWxlY3RvcignLmdlX2NvbG9ycGlja2VyX2hzdi1tYXAnKTtcbiAgICAgICAgdGhpcy5kb20uaHN2TWFwQ292ZXIgPSB0aGlzLmRvbS5oc3ZNYXAuY2hpbGRyZW5bMV07IC8vIHdlbGwuLi5cbiAgICAgICAgdGhpcy5kb20uaHN2TWFwQ3Vyc29yID0gdGhpcy5kb20uaHN2TWFwLmNoaWxkcmVuWzJdO1xuICAgICAgICB0aGlzLmRvbS5oc3ZCYXJCR0xheWVyID0gdGhpcy5kb20uaHN2TWFwLmNoaWxkcmVuWzNdO1xuICAgICAgICB0aGlzLmRvbS5oc3ZCYXJXaGl0ZUxheWVyID0gdGhpcy5kb20uaHN2TWFwLmNoaWxkcmVuWzRdO1xuICAgICAgICB0aGlzLmRvbS5oc3ZCYXJDdXJzb3JzID0gdGhpcy5kb20uaHN2TWFwLmNoaWxkcmVuWzZdO1xuICAgICAgICB0aGlzLmRvbS5oc3ZMZWZ0Q3Vyc29yID0gdGhpcy5kb20uaHN2QmFyQ3Vyc29ycy5jaGlsZHJlblswXTtcbiAgICAgICAgdGhpcy5kb20uaHN2UmlnaHRDdXJzb3IgPSB0aGlzLmRvbS5oc3ZCYXJDdXJzb3JzLmNoaWxkcmVuWzFdO1xuXG4gICAgICAgIHRoaXMuZG9tLmNvbG9yRGlzYyA9IHRoaXMuZWwucXVlcnlTZWxlY3RvcignLmdlX2NvbG9ycGlja2VyX2Rpc2MnKTtcbiAgICAgICAgdGhpcy5kb20ubHVtaW5hbmNlQmFyID0gdGhpcy5lbC5xdWVyeVNlbGVjdG9yKCcuZ2VfY29sb3JwaWNrZXJfYmFyLWx1bWluYW5jZScpO1xuXG4gICAgICAgIGlmICh0aGlzLmxpbmtCdXR0b24pIHtcbiAgICAgICAgICAgIGxldCBsYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgICAgICBsYnV0dG9uLmlubmVySFRNTCA9ICcrJztcbiAgICAgICAgICAgIGxidXR0b24uY2xhc3NOYW1lID0gdGhpcy5DU1NfUFJFRklYICsgJ2xpbmstYnV0dG9uJztcbiAgICAgICAgICAgIGxidXR0b24uc3R5bGUuY29sb3IgPSB0aGlzLmZnQ29sb3I7XG4gICAgICAgICAgICB0aGlzLmVsLmFwcGVuZENoaWxkKGxidXR0b24pO1xuXG4gICAgICAgICAgICBsYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlcignbGlua0J1dHRvbicsIHRoaXMudmFsdWUpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5saW5rQnV0dG9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGlua0J1dHRvbih0aGlzLnZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVNb2RhbCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkcmF3ICgpIHtcbiAgICAgICAgLy8gIFJlbmRlciBjb2xvciBwYXRjaFxuICAgICAgICBsZXQgcGF0Y2ggPSB0aGlzLmVsLnF1ZXJ5U2VsZWN0b3IoJy5nZV9jb2xvcnBpY2tlcl9wYXRjaCcpO1xuICAgICAgICBwYXRjaC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLnZhbHVlLmdldFN0cmluZygncmdiJyk7XG5cbiAgICAgICAgLy8gIFJlbmRlciBIU1YgcGlja2VyXG4gICAgICAgIGxldCBjb2xvciA9IHRoaXMudmFsdWUuY29sb3JzO1xuICAgICAgICBsZXQgY29sb3JEaXNjUmFkaXVzID0gdGhpcy5kb20uY29sb3JEaXNjLm9mZnNldEhlaWdodCAvID
23459I7XG4gICAgICAgIGxldCBwaTIgPSBNYXRoLlBJICogMjtcbiAgICAgICAgbGV0IHggPSBNYXRoLmNvcyhwaTIgLSBjb2xvci5oc3YuaCAqIHBpMik7XG4gICAgICAgIGxldCB5ID0gTWF0aC5zaW4ocGkyIC0gY29sb3IuaHN2LmggKiBwaTIpO1xuICAgICAgICBsZXQgciA9IGNvbG9yLmhzdi5zICogKGNvbG9yRGlzY1JhZGl1cyAtIDUpO1xuXG4gICAgICAgIHRoaXMuZG9tLmhzdk1hcENvdmVyLnN0eWxlLm9wYWNpdHkgPSAxIC0gY29sb3IuaHN2LnYgLyAyNTU7XG4gICAgICAgIC8vIHRoaXMgaXMgdGhlIGZhc3RlciB2ZXJzaW9uLi4uXG4gICAgICAgIHRoaXMuZG9tLmhzdkJhcldoaXRlTGF5ZXIuc3R5bGUub3BhY2l0eSA9IDEgLSBjb2xvci5oc3YucztcbiAgICAgICAgdGhpcy5kb20uaHN2QmFyQkdMYXllci5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAncmdiKCcgK1xuICAgICAgICAgICAgY29sb3IuaHVlUkdCLnIgKyAnLCcgK1xuICAgICAgICAgICAgY29sb3IuaHVlUkdCLmcgKyAnLCcgK1xuICAgICAgICAgICAgY29sb3IuaHVlUkdCLmIgKyAnKSc7XG5cbiAgICAgICAgdGhpcy5kb20uaHN2TWFwQ3Vyc29yLnN0eWxlLmNzc1RleHQgPVxuICAgICAgICAgICAgJ2xlZnQ6ICcgKyAoeCAqIHIgKyBjb2xvckRpc2NSYWRpdXMpICsgJ3B4OycgK1xuICAgICAgICAgICAgJ3RvcDogJyArICh5ICogciArIGNvbG9yRGlzY1JhZGl1cykgKyAncHg7JyArXG4gICAgICAgICAgICAnYm9yZGVyLWNvbG9yOiAnICsgKGNvbG9yLmx1bWluYW5jZSA+IDAuMjIgPyAnIzMzMzsnIDogJyNkZGQnKTtcblxuICAgICAgICBpZiAoY29sb3IubHVtaW5hbmNlID4gMC4yMikge1xuICAgICAgICAgICAgdGhpcy5kb20uaHN2QmFyQ3Vyc29ycy5jbGFzc0xpc3QuYWRkKCdnZV9jb2xvcnBpY2tlcl9kYXJrJyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmRvbS5oc3ZCYXJDdXJzb3JzLmNsYXNzTGlzdC5yZW1vdmUoJ2dlX2NvbG9ycGlja2VyX2RhcmsnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmRvbS5oc3ZMZWZ0Q3Vyc29yKSB7XG4gICAgICAgICAgICB0aGlzLmRvbS5oc3ZMZWZ0Q3Vyc29yLnN0eWxlLnRvcCA9IHRoaXMuZG9tLmhzdlJpZ2h0Q3Vyc29yLnN0eWxlLnRvcCA9ICgoMSAtIGNvbG9yLmhzdi52IC8gMjU1KSAqIGNvbG9yRGlzY1JhZGl1cyAqIDIpICsgJ3B4JztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByZXNlbnRNb2RhbCAoeCwgeSkge1xuICAgICAgICBzdXBlci5wcmVzZW50TW9kYWwoeCwgeSk7XG5cbiAgICAgICAgLy8gLy8gTGlzdGVuIGZvciBpbnRlcmFjdGlvbiBvbiB0aGUgSFNWIG1hcFxuICAgICAgICB0aGlzLm9uSHN2RG93bkhhbmRsZXIgPSBhZGRFdmVudCh0aGlzLmRvbS5oc3ZNYXAsICdtb3VzZWRvd24nLCB0aGlzLm9uSHN2RG93biwgdGhpcyk7XG5cbiAgICAgICAgbGV0IGNvbG9yRGlzYyA9IHRoaXMuZG9tLmNvbG9yRGlzYztcblxuICAgICAgICBpZiAoY29sb3JEaXNjLmdldENvbnRleHQpIHtcbiAgICAgICAgICAgIC8vIEhTViBjb2xvciB3aGVlbCB3aXRoIHdoaXRlIGNlbnRlclxuICAgICAgICAgICAgbGV0IGRpc2tDb250ZXh0ID0gY29sb3JEaXNjLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgICAgICBsZXQgcmF0aW8gPSBnZXREZXZpY2VQaXhlbFJhdGlvKGRpc2tDb250ZXh0KTtcbiAgICAgICAgICAgIGxldCB3aWR0aCA9IHRoaXMuZGlzYy53aWR0aCAvIHJhdGlvO1xuICAgICAgICAgICAgbGV0IGhlaWdodCA9IHRoaXMuZGlzYy5oZWlnaHQgLyByYXRpbztcbiAgICAgICAgICAgIHRoaXMuZG9tLmNvbG9yRGlzYy53aWR0aCA9IHdpZHRoICogcmF0aW87XG4gICAgICAgICAgICB0aGlzLmRvbS5jb2xvckRpc2MuaGVpZ2h0ID0gaGVpZ2h0ICogcmF0aW87XG4gICAgICAgICAgICBkaXNrQ29udGV4dC5zY2FsZShyYXRpbywgcmF0aW8pO1xuXG4gICAgICAgICAgICBkcmF3RGlzayhcbiAgICAgICAgICAgICAgICBkaXNrQ29udGV4dCxcbiAgICAgICAgICAgICAgICBbd2lkdGggLyAyLCBoZWlnaHQgLyAyXSxcbiAgICAgICAgICAgICAgICBbd2lkdGggLyAyIC0gMSwgaGVpZ2h0IC8gMiAtIDFdLFxuICAgICAgICAgICAgICAgIDM2MCxcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoY3R4LCBhbmdsZSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgZ3JhZGllbnQgPSBjdHguY3JlYXRlUmFkaWFsR3JhZGllbnQoMSwgMSwgMSwgMSwgMSwgMCk7XG4gICAgICAgICAgICAgICAgICAgIGdyYWRpZW50LmFkZENvbG9yU3RvcCgwLCAnaHNsKCcgKyAoMzYwIC0gYW5nbG
23459UgKyAwKSArICcsIDEwMCUsIDUwJSknKTtcbiAgICAgICAgICAgICAgICAgICAgZ3JhZGllbnQuYWRkQ29sb3JTdG9wKDEsICcjZmZmJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgY3R4LmZpbGxTdHlsZSA9IGdyYWRpZW50O1xuICAgICAgICAgICAgICAgICAgICBjdHguZmlsbCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIGdyYXkgYm9yZGVyXG4gICAgICAgICAgICBkcmF3Q2lyY2xlKFxuICAgICAgICAgICAgICAgIGRpc2tDb250ZXh0LFxuICAgICAgICAgICAgICAgIFt3aWR0aCAvIDIsIGhlaWdodCAvIDJdLFxuICAgICAgICAgICAgICAgIFt3aWR0aCAvIDIsIGhlaWdodCAvIDJdLFxuICAgICAgICAgICAgICAgIHRoaXMuYmdDb2xvciwvLyAnIzMwMzAzMCcsXG4gICAgICAgICAgICAgICAgMiAvIHJhdGlvXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyBkcmF3IHRoZSBsdW1pbmFuY2VCYXIgYmFyXG4gICAgICAgICAgICBsZXQgY3R4ID0gdGhpcy5kb20ubHVtaW5hbmNlQmFyLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgICAgICB0aGlzLmRvbS5sdW1pbmFuY2VCYXIud2lkdGggPSB0aGlzLmJhcmx1bS53aWR0aDtcbiAgICAgICAgICAgIHRoaXMuZG9tLmx1bWluYW5jZUJhci5oZWlnaHQgPSB0aGlzLmJhcmx1bS5oZWlnaHQgKiByYXRpbztcbiAgICAgICAgICAgIGN0eC5zY2FsZShyYXRpbywgcmF0aW8pO1xuICAgICAgICAgICAgbGV0IGdyYWRpZW50ID0gY3R4LmNyZWF0ZUxpbmVhckdyYWRpZW50KDAsIDAsIDAsIHRoaXMuYmFybHVtLmhlaWdodCAvIHJhdGlvKTtcblxuICAgICAgICAgICAgZ3JhZGllbnQuYWRkQ29sb3JTdG9wKDAsICd0cmFuc3BhcmVudCcpO1xuICAgICAgICAgICAgZ3JhZGllbnQuYWRkQ29sb3JTdG9wKDEsICdibGFjaycpO1xuXG4gICAgICAgICAgICBjdHguZmlsbFN0eWxlID0gZ3JhZGllbnQ7XG4gICAgICAgICAgICBjdHguZmlsbFJlY3QoMCwgMCwgMzAsIDIwMCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kcmF3KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogIFVwZGF0ZXMgb25seSB0aGUgY29sb3IgdmFsdWUgb2YgdGhlIGNvbG9yIHBpY2tlclxuICAgICAqICBhbmQgdGhlIHZpZXcuIERlc2lnbmVkIHRvIGJlIGNhbGxlZCBieSBleHRlcm5hbCBtb2R1bGVzXG4gICAgICogIHNvIHRoYXQgaXQgY2FuIHVwZGF0ZSBpdHMgaW50ZXJuYWwgdmFsdWUgZnJvbSBhbiBvdXRzaWRlIHNvdXJjZS5cbiAgICAgKiAgRG9lcyBubyBET00gY3JlYXRpb24gJiBvdGhlciBpbml0aWFsaXphdGlvbiB3b3JrLlxuICAgICAqL1xuICAgIHNldFZhbHVlIChjb2xvcikge1xuICAgICAgICB0aGlzLnZhbHVlID0gbmV3IENvbG9yKGNvbG9yKTtcbiAgICB9XG5cbiAgICAvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG4gICAgLyogLS0tLSBIU1YtY2lyY2xlIGNvbG9yIHBpY2tlciAtLS0tLSAqL1xuICAgIC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuICAgIC8vIEFjdGlvbnMgd2hlbiB1c2VyIG1vdXNlcyBkb3duIG9uIEhTViBjb2xvciBtYXBcbiAgICBvbkhzdkRvd24gKGV2ZW50KSB7XG4gICAgICAgIGxldCB0YXJnZXQgPSBldmVudC50YXJnZXQgfHwgZXZlbnQuc3JjRWxlbWVudDtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICBjdXJyZW50VGFyZ2V0ID0gdGFyZ2V0LmlkID8gdGFyZ2V0IDogdGFyZ2V0LnBhcmVudE5vZGU7XG4gICAgICAgIGN1cnJlbnRUYXJnZXRIZWlnaHQgPSBjdXJyZW50VGFyZ2V0Lm9mZnNldEhlaWdodDsgLy8gYXMgZGlhbWV0ZXIgb2YgY2lyY2xlXG5cbiAgICAgICAgLy8gU3RhcnRzIGxpc3RlbmluZyBmb3IgbW91c2Vtb3ZlIGFuZCBtb3VzZXVwIGV2ZW50c1xuICAgICAgICB0aGlzLm9uSHN2TW92ZUhhbmRsZXIgPSBhZGRFdmVudCh0aGlzLmVsLCAnbW91c2Vtb3ZlJywgdGhpcy5vbkhzdk1vdmUsIHRoaXMpO1xuICAgICAgICB0aGlzLm9uSHN2VXBIYW5kbGVyID0gYWRkRXZlbnQod2luZG93LCAnbW91c2V1cCcsIHRoaXMub25Ic3ZVcCwgdGhpcyk7XG5cbiAgICAgICAgdGhpcy5vbkhzdk1vdmUoZXZlbnQpO1xuXG4gICAgICAgIC8vIEhpZGVzIG1vdXNlIGN1cnNvciBhbmQgYmVnaW5zIHJlbmRlcmluZyBsb29wXG4gICAgICAgIHRoaXMuZG9tLmhzdk1hcC5jbGFzc0xpc3QuYWRkKCdnZV9jb2xvcnBpY2tlcl9uby1jdXJzb3InKTtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zdGFydCgpO1xuICAgIH1cblxuICAgIC8vIEFjdGlvbnMgd2hlbiB1c2VyIG1vdmVzIGFyb3VuZCBvbiBIU1YgY29sb3IgbWFwXG4gICAgb25Ic3ZNb3ZlIChldmVudCkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICBsZXQgciwgeCwgeSwgaCwgcztcbiAgICAgICAgaWYgKGV2ZW50LnRhcmdldCA9PT0gdGhpcy5kb20uaHN2TWFwQ292ZXIgJiYgY3VycmVudFRhcmdldCA9PT0gdGhpcy5kb20uaHN2TWFwKSB7IC8vIHRoZSBjaXJjbGVcbiAgICAgICAgICAgIHIgPSBjdXJyZW50VGFyZ2V0SGVpZ2h0IC8gMixcbiAgICAgICAgICAgIHggPSBldmVudC5vZmZzZXRYIC0gcixcbiAgICAgICAgICAgIHkgPSBldmVudC5vZmZzZXRZIC0gcixcbiAgICAgICAgICAgIGggPSAoMzYwIC0gKChNYXRoLmF0YW4yKHksIHgpICogMTgwIC8gTWF0aC5QSSkgKyAoeSA8IDAgPyAzNjAgOiAwKSkpIC8gMzYwLFxuICAgICAgICAgICAgcyA9IChNYXRoLnNxcnQoKHggKiB4KSArICh5ICogeSkpIC8gcik7XG4gICAgICAgICAgICB0aGlzLnZhbHVlLnNldCh7IGgsIHMgfSwgJ2hzdicpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2ZW50LnRhcmdldCA9PT0gdGhpcy5kb20uaHN2QmFyQ3Vyc29ycyAmJiBjdXJyZW50VGFyZ2V0ID09PSB0aGlzLmRvbS5oc3ZCYXJDdXJzb3JzKSB7IC8vIHRoZSBsdW1pbmFuY2VCYXJcbiAgICAgICAgICAgIGxldCB2ID0gKGN1cnJlbnRUYXJnZXRIZWlnaHQgLSAoZXZlbnQub2Zmc2V0WSkpIC8gY3VycmVudFRhcmdldEhlaWdodDtcbiAgICAgICAgICAgI
23459HYgPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCB2KSkgKiAyNTU7XG4gICAgICAgICAgICB0aGlzLnZhbHVlLnNldCh7IHY6IHYgfSwgJ2hzdicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy50cmlnZ2VyKCdjaGFuZ2VkJywgdGhpcy52YWx1ZSk7XG4gICAgfVxuXG4gICAgLy8gQWN0aW9ucyB3aGVuIHVzZXIgbW91c2VzIHVwIG9uIEhTViBjb2xvciBtYXBcbiAgICBvbkhzdlVwIChldmVudCkge1xuICAgICAgICAvLyBTdG9wcyByZW5kZXJpbmcgYW5kIHJldHVybnMgbW91c2UgY3Vyc29yXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc3RvcCgpO1xuICAgICAgICB0aGlzLmRvbS5oc3ZNYXAuY2xhc3NMaXN0LnJlbW92ZSgnZ2VfY29sb3JwaWNrZXJfbm8tY3Vyc29yJyk7XG4gICAgICAgIHRoaXMuZGVzdHJveUV2ZW50cygpO1xuICAgIH1cblxuICAgIC8vIERlc3Ryb3kgZXZlbnQgbGlzdGVuZXJzIHRoYXQgZXhpc3QgZHVyaW5nIG1vdXNlZG93biBjb2xvcnBpY2tlciBpbnRlcmFjdGlvblxuICAgIGRlc3Ryb3lFdmVudHMgKCkge1xuICAgICAgICByZW1vdmVFdmVudCh0aGlzLmVsLCAnbW91c2Vtb3ZlJywgdGhpcy5vbkhzdk1vdmVIYW5kbGVyKTtcbiAgICAgICAgdGhpcy5vbkhzdk1vdmVIYW5kbGVyID0gbnVsbDtcbiAgICAgICAgcmVtb3ZlRXZlbnQod2luZG93LCAnbW91c2V1cCcsIHRoaXMub25Ic3ZVcEhhbmRsZXIpO1xuICAgICAgICB0aGlzLm9uSHN2VXBIYW5kbGVyID0gbnVsbDtcbiAgICB9XG5cbiAgICBjbG9zZSAoKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveUV2ZW50cygpO1xuICAgICAgICByZW1vdmVFdmVudCh0aGlzLmRvbS5oc3ZNYXAsICdtb3VzZWRvd24nLCB0aGlzLm9uSHN2RG93bkhhbmRsZXIpO1xuICAgICAgICB0aGlzLm9uSHN2RG93bkhhbmRsZXIgPSBudWxsO1xuICAgIH1cbn1cblxuLy8gZ2VuZXJpYyBmdW5jdGlvbiBmb3IgZHJhd2luZyBhIGNhbnZhcyBkaXNjXG5mdW5jdGlvbiBkcmF3RGlzayAoY3R4LCBjb29yZHMsIHJhZGl1cywgc3RlcHMsIGNvbG9yQ2FsbGJhY2spIHtcbiAgICBsZXQgeCA9IGNvb3Jkc1swXSB8fCBjb29yZHM7IC8vIGNvb3JkaW5hdGUgb24geC1heGlzXG4gICAgbGV0IHkgPSBjb29yZHNbMV0gfHwgY29vcmRzOyAvLyBjb29yZGluYXRlIG9uIHktYXhpc1xuICAgIGxldCBhID0gcmFkaXVzWzBdIHx8IHJhZGl1czsgLy8gcmFkaXVzIG9uIHgtYXhpc1xuICAgIGxldCBiID0gcmFkaXVzWzFdIHx8IHJhZGl1czsgLy8gcmFkaXVzIG9uIHktYXhpc1xuICAgIGxldCBhbmdsZSA9IDM2MDtcbiAgICBsZXQgY29lZiA9IE1hdGguUEkgLyAxODA7XG5cbiAgICBjdHguc2F2ZSgpO1xuICAgIGN0eC50cmFuc2xhdGUoeCAtIGEsIHkgLSBiKTtcbiAgICBjdHguc2NhbGUoYSwgYik7XG5cbiAgICBzdGVwcyA9IChhbmdsZSAvIHN0ZXBzKSB8fCAzNjA7XG5cbiAgICBmb3IgKDsgYW5nbGUgPiAwIDsgYW5nbGUgLT0gc3RlcHMpIHtcbiAgICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBpZiAoc3RlcHMgIT09IDM2MCkge1xuICAgICAgICAgICAgY3R4Lm1vdmVUbygxLCAxKTsgLy8gc3Ryb2tlXG4gICAgICAgIH1cbiAgICAgICAgY3R4LmFyYygxLCAxLCAxLFxuICAgICAgICAgICAgKGFuZ2xlIC0gKHN0ZXBzIC8gMikgLSAxKSAqIGNvZWYsXG4gICAgICAgICAgICAoYW5nbGUgKyAoc3RlcHMgLyAyKSArIDEpICogY29lZik7XG5cbiAgICAgICAgaWYgKGNvbG9yQ2FsbGJhY2spIHtcbiAgICAgICAgICAgIGNvbG9yQ2FsbGJhY2soY3R4LCBhbmdsZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjdHguZmlsbFN0eWxlID0gJ2JsYWNrJztcbiAgICAgICAgICAgIGN0eC5maWxsKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY3R4LnJlc3RvcmUoKTtcbn1cblxuZnVuY3Rpb24gZHJhd0NpcmNsZSAoY3R4LCBjb29yZHMsIHJhZGl1cywgY29sb3IsIHdpZHRoKSB7IC8vIHVzZXMgZHJhd0Rpc2tcbiAgICB3aWR0aCA9IHdpZHRoIHx8IDE7XG4gICAgcmFkaXVzID0gW1xuICAgICAgICAocmFkaXVzWzBdIHx8IHJhZGl1cykgLSB3aWR0aCAvIDIsXG4gICAgICAgIChyYWRpdXNbMV0gfHwgcmFkaXVzKSAtIHdpZHRoIC8gMlxuICAgIF07XG4gICAgZHJhd0Rpc2soY3R4LCBjb29yZHMsIHJhZGl1cywgMSwgZnVuY3Rpb24gKGN0eCwgYW5nbG
23459UpIHtcbiAgICAgICAgY3R4LnJlc3RvcmUoKTtcbiAgICAgICAgY3R4LmxpbmVXaWR0aCA9IHdpZHRoO1xuICAgICAgICBjdHguc3Ryb2tlU3R5bGUgPSBjb2xvciB8fCAnIzAwMCc7XG4gICAgICAgIGN0eC5zdHJva2UoKTtcbiAgICB9KTtcbn1cbiIsImltcG9ydCBQaWNrZXIgZnJvbSAnLi9QaWNrZXInO1xuaW1wb3J0IEZsb2F0IGZyb20gJy4vdHlwZXMvRmxvYXQnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGbG9hdFBpY2tlciBleHRlbmRzIFBpY2tlciB7XG4gICAgY29uc3RydWN0b3IgKG51bWJlciwgcHJvcGVydGllcykge1xuICAgICAgICBzdXBlcignZ2VfZmxvYXRwaWNrZXJfJywgcHJvcGVydGllcyk7XG5cbiAgICAgICAgdGhpcy53aWR0aCA9IHRoaXMud2lkdGggfHwgMjUwO1xuICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMuaGVpZ2h0IHx8IDQwO1xuXG4gICAgICAgIHRoaXMucHJldk9mZnNldCA9IDA7XG4gICAgICAgIHRoaXMuc2NhbGUgPSAyO1xuXG4gICAgICAgIHRoaXMuc2V0VmFsdWUobnVtYmVyIHx8IDEpO1xuICAgICAgICB0aGlzLmNyZWF0ZSgpO1xuICAgIH1cblxuICAgIGRyYXcgKCkge1xuICAgICAgICB0aGlzLmN0eC5jbGVhclJlY3QoMCwgMCwgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xuXG4gICAgICAgIC8vIGhvcml6b250YWwgbGluZVxuICAgICAgICB0aGlzLmN0eC5zdHJva2VTdHlsZSA9IHRoaXMuZGltQ29sb3I7XG4gICAgICAgIHRoaXMuY3R4LmxpbmVXaWR0aCA9IDE7XG4gICAgICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICB0aGlzLmN0eC5tb3ZlVG8oMCwgMC41ICsgdGhpcy5oZWlnaHQgKiAwLjUpO1xuICAgICAgICB0aGlzLmN0eC5saW5lVG8oMCArIHRoaXMud2lkdGgsIDAuNSArIHRoaXMuaGVpZ2h0ICogMC41KTtcbiAgICAgICAgdGhpcy5jdHguY2xvc2VQYXRoKCk7XG4gICAgICAgIHRoaXMuY3R4LnN0cm9rZSgpO1xuXG4gICAgICAgIC8vIHZlcnRpY2FsIGxpbmVcbiAgICAgICAgdGhpcy5jdHguc3Ryb2tlU3R5bGUgPSB0aGlzLmZuQ29sb3I7XG4gICAgICAgIHRoaXMuY3R4LmxpbmVXaWR0aCA9IDE7XG4gICAgICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICB0aGlzLmN0eC5tb3ZlVG8odGhpcy53aWR0aCAqIDAuNSwgMCk7XG4gICAgICAgIHRoaXMuY3R4LmxpbmVUbyh0aGlzLndpZHRoICogMC41LCB0aGlzLmhlaWdodCk7XG4gICAgICAgIHRoaXMuY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICB0aGlzLmN0eC5zdHJva2UoKTtcblxuICAgICAgICAvLyBUcmlhbmdsZSBsaW5lXG4gICAgICAgIHRoaXMuY3R4LmZpbGxTdHlsZSA9IHRoaXMub3ZlclBvaW50ID8gdGhpcy5zZWxDb2xvciA6IHRoaXMuZm5Db2xvcjtcbiAgICAgICAgdGhpcy5jdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIHRoaXMuY3R4Lm1vdmVUbyh0aGlzLndpZHRoICogMC41LCA1KTtcbiAgICAgICAgdGhpcy5jdHgubGluZVRvKHRoaXMud2lkdGggKiAwLjQ4LCAwKTtcbiAgICAgICAgdGhpcy5jdHgubGluZVRvKHRoaXMud2lkdGggKiAwLjUyLCAwKTtcbiAgICAgICAgdGhpcy5jdHguY2xvc2VQYXRoKCk7XG4gICAgICAgIHRoaXMuY3R4LmZpbGwoKTtcblxuICAgICAgICBsZXQgdGltZXMgPSAzO1xuICAgICAgICBsZXQgdW5pdCA9IDQwO1xuICAgICAgICBsZXQgc3RlcCA9IHRoaXMud2lkdGggLyB1bml0O1xuICAgICAgICBsZXQgc2VjdGlvbnMgPSB1bml0ICogdGltZXM7XG5cbiAgICAgICAgbGV0IG9mZnNldFggPSB0aGlzLm9mZnNldFg7XG5cbiAgICAgICAgaWYgKE1hdGguYWJzKHRoaXMub2Zmc2V0WCAtIHRoaXMud2lkdGggKiAwLjUpID4gdGhpcy53aWR0aCAqIDAuNSkge1xuICAgICAgICAgICAgb2Zmc2V0WCA9ICh0aGlzLm9mZnNldFggLSB0aGlzLndpZHRoICogMC41KSAlICh0aGlzLndpZHRoICogMC41KSArIHRoaXMud2lkdGg7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmN0eC5zdHJva2VTdHlsZSA9IHRoaXMuZGltQ29sb3I7XG4gICAgICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlY3Rpb25zOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBsID0gKGkgJSAodW5pdCAvIDIpID09PSAwKSA/IHRoaXMuaGVpZ2h0ICogMC4zNSA6IChpICUgKHVuaXQgLyA0KSA9PT0gMCkgPyB0aGlzLmhlaWdodCAqIDAuMiA6IHRoaXMuaGVpZ2h0ICogMC4xO1xuICAgICAgICAgICAgdGhpcy5jdHgubW92ZVRvKGkgKiBzdGVwIC0gb2Zmc2V0WCwgdGhpcy5oZWlnaHQgKiAwLjUgLSBsKTtcbiAgICAgICAgICAgIHRoaXMuY3R4LmxpbmVUbyhpICogc3RlcCAtIG9mZnNldFgsIHRoaXMuaGVpZ2h0ICogMC41ICsgbCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jdHguc3Ryb2tlKCk7XG5cbiAgICAgICAgbGV0IHZhbCA9IE1hdGgucm91bmQoKCh0aGlzLnZhbHVlIC0gdGhpcy5taW4pIC8gdGhpcy5yYW5nZSkgKiB0aGlzLndpZHRoKTtcblxuICAgICAgICAvLyBwb2ludFxuICAgICAgICB0aGlzLmN0eC5zdHJva2VTdHlsZSA9IHRoaXMub3ZlclBvaW50ID8gdGhpcy5zZWxDb2xvciA6IHRoaXMuZm5Db2xvcjtcbiAgICAgICAgdGhpcy5jdHgubGluZVdpZHRoID0gMTtcbiAgICAgICAgdGhpcy5jdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIHRoaXMuY3R4Lm1vdmVUbyh0aGlzLm9mZnNldFggKyB2YWwsIHRoaXMuaGVpZ2h0ICogMC41KTtcbiAgICAgICAgdGhpcy5jdHgubGluZVRvKHRoaXMub2Zmc2V0WCArIHZhbCwgdGhpcy5oZWlnaHQpO1xuICAgICAgICB0aGlzLmN0eC5jbG9zZVBhdGgoKTtcbiAgICAgICAgdGhpcy5jdHguc3Ryb2tlKCk7XG5cbiAgICAgICAgdGhpcy5vdmVyUG9pbnQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBvbk1vdXNlRG93biAoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5wcmV2T2Zmc2V0ID0gZXZlbnQub2Zmc2V0WDtcbiAgICAgICAgc3VwZXIub25Nb3VzZURvd24oZXZlbnQpO1xuICAgIH1cblxuICAgIC8vIEFjdGlvbnMgd2hlbiB1c2VyIG1vdmVzIGFyb3VuZCBvbiBIU1YgY29sb3IgbWFwXG4gICAgb25Nb3VzZU1vdmUgKGV2ZW50KSB7XG4gICAgICAgIGxldCB4ID0gZXZlbnQub2Zmc2V0WDtcblxuICAgICAgICBsZXQgdmVsID0geCAtI
23459HRoaXMucHJldk9mZnNldDtcbiAgICAgICAgbGV0IG9mZnNldCA9IHRoaXMub2Zmc2V0WCAtIHZlbDtcblxuICAgICAgICBsZXQgY2VudGVyID0gdGhpcy53aWR0aCAvIHRoaXMuc2NhbGU7XG4gICAgICAgIHRoaXMuc2V0VmFsdWUob2Zmc2V0IC8gY2VudGVyKTtcbiAgICAgICAgdGhpcy5wcmV2T2Zmc2V0ID0geDtcblxuICAgICAgICAvLyBmaXJlICdjaGFuZ2VkJ1xuICAgICAgICB2YXIgbnVtYmVyID0gbmV3IEZsb2F0KHRoaXMuZ2V0VmFsdWUoKSk7XG4gICAgICAgIHRoaXMudHJpZ2dlcignY2hhbmdlZCcsIG51bWJlcik7XG4gICAgICAgIHRoaXMub3ZlclBvaW50ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBzZXRWYWx1ZSAodmFsdWUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBwYXJzZUZsb2F0KHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGNlbnRlciA9ICh0aGlzLndpZHRoIC8gdGhpcy5zY2FsZSk7XG4gICAgICAgIHRoaXMub2Zmc2V0WCA9IHRoaXMudmFsdWUgKiBjZW50ZXI7XG4gICAgfVxufVxuXG4iLCIvKlxuT3JpZ2luYWw6IGh0dHBzOi8vZ2l0aHViLmNvbS90YW5ncmFtcy90YW5ncmFtLXBsYXkvYmxvYi9naC1wYWdlcy9zcmMvanMvYWRkb25zL3VpL3dpZGdldHMvQ29sb3JQaWNrZXJNb2RhbC5qc1xuQXV0aG9yOiBMb3UgSHVhbmcgKEBzYWlrb2Zpc2gpXG4qL1xuXG5pbXBvcnQgeyBnZXREZXZpY2VQaXhlbFJhdGlvIH0gZnJvbSAnLi4vLi4vdG9vbHMvY29tbW9uJztcbmltcG9ydCB7IHN1YnNjcmliZU1peGluIH0gZnJvbSAnLi4vLi4vdG9vbHMvbWl4aW4nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQaWNrZXIge1xuICAgIGNvbnN0cnVjdG9yIChDU1NfUFJFRklYLCBwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHN1YnNjcmliZU1peGluKHRoaXMpO1xuICAgICAgICB0aGlzLkNTU19QUkVGSVggPSBDU1NfUFJFRklYO1xuXG4gICAgICAgIHRoaXMuYmdDb2xvciA9ICdyZ2IoNDYsIDQ4LCA1MSknO1xuICAgICAgICB0aGlzLmRpbUNvbG9yID0gJ3JnYigxMDAsIDEwMCwgMTAwKSc7XG4gICAgICAgIHRoaXMuZm5Db2xvciA9ICdyZ2IoMjMwLCAyMzAsIDIzMCknO1xuICAgICAgICB0aGlzLnNlbENvbG9yID0gJ3JnYigxMzMsIDIwNCwgMTk2KSc7XG5cbiAgICAgICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgfHwge307XG4gICAgICAgIGZvciAobGV0IHByb3AgaW4gcHJvcGVydGllcykge1xuICAgICAgICAgICAgdGhpc1twcm9wXSA9IHByb3BlcnRpZXNbcHJvcF07XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogIFRoaXMgaW5pdGlhbGl6ZXMgdGhlIHJlbmRlcmVyLiBJdCB1c2VzIHJlcXVlc3RBbmltYXRpb25GcmFtZSgpIHRvXG4gICAgICAgICAqICBzbW9vdGhseSByZW5kZXIgY2hhbmdlcyBpbiB0aGUgY29sb3IgcGlja2VyIGFzIHVzZXIgaW50ZXJhY3RzIHdpdGggaXQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnJlbmRlcmVyID0ge1xuICAgICAgICAgICAgLy8gU3RvcmVzIGEgcmVmZXJlbmNlIHRvIHRoZSBhbmltYXRpb24gcmVuZGVyaW5nIGxvb3AuXG4gICAgICAgICAgICBmcmFtZTogbnVsbCxcblxuICAgICAgICAgICAgZHJhd0ZyYW1lOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmVsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5kcmF3KCk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvLyBTdGFydHMgYW5pbWF0aW9uIHJlbmRlcmluZyBsb29wXG4gICAgICAgICAgICBzdGFydDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuZHJhd0ZyYW1lKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5mcmFtZSA9IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5yZW5kZXJlci5zdGFydCk7XG4gICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAvLyBTdG9wcyBhbmltYXRpb24gcmVuZGVyaW5nIGxvb3BcbiAgICAgICAgICAgIHN0b3A6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5yZW5kZXJlci5mcmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaXNWaXNpYmxlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgY3JlYXRlICgpIHtcbiAgICAgICAgdGhpcy5lbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICB0aGlzLmVsLmNsYXNzTmFtZSA9IHRoaXMuQ1NTX1BSRUZJWCArICdtb2RhbCBnZV9waWNrZXJfbW9kYWwnO1xuICAgICAgICB0aGlzLmVsLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHRoaXMuYmdDb2xvcjtcblxuICAgICAgICB0aGlzLmNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgICB0aGlzLmNhbnZhcy5jbGFzc05hbWUgPSB0aGlzLkNTU19QUkVGSVggKyAnY2FudmFzIGdlX3BpY2tlcl9jYW52YXMnO1xuICAgICAgICB0aGlzLmNhbnZhcy5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLmJnQ29sb3I7XG5cbiAgICAgICAgdGhpcy5lbC5hcHBlbmRDaGlsZCh0aGlzLmNhbnZhcyk7XG4gICAgICAgIHRoaXMuY3R4ID0gdGhpcy5jYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcblxuICAgICAgICBsZXQgcmF0aW8gPSBnZXREZXZpY2VQaXhlbFJhdGlvKHRoaXMuY3R4KTtcbiAgICAgICAgdGhpcy5jYW52YXMud2lkdGggPSB0aGlzLndpZHRoICogcmF0aW87XG4gICAgICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IHRoaXMuaGVpZ2h0ICogcmF0aW87XG4gICAgICAgIHRoaXMuY3R4LnNjYWxlKHJhdGlvLCByYXRpbyk7XG4gICAgfVxuXG4gICAgZHJhdyAoKSB7XG4gICAgICAgIC8vIHJlbmRlciBydXRpbmVcbiAgICB9XG5cbiAgICBjbG9zZSAoKSB7XG4gICAgICAgIC8vIENsb3NlIHJ1dGluZVxuICAgICAgICB0aGlzLmRlc3Ryb3lFdmVudHMoKTtcbiAgICAgICAgcmVtb3ZlRXZlbnQodGhpcy5lbCwgJ21vdXNlZG93bicsIHRoaXMub25Nb3VzZURvd25IYW5kbGVyKTtcbiAgICAgICAgdGhpcy5vbk1vdXNlRG93bkhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIGRlc3Ryb3lFdmVudHMgKCkge1xuICAgICAgICByZW1vdmVFdmVudCh0aGlzLmVsLCAnbW91c2Vtb3ZlJywgdGhpcy5vbk1vdXNlTW92ZUhhbmRsZXIpO1xuICAgICAgICB0aGlzLm9uTW91c2VNb3ZlSGFuZGxlciA9IG51bGw7XG4gICAgICAgI
23459HJlbW92ZUV2ZW50KHdpbmRvdywgJ21vdXNldXAnLCB0aGlzLm9uTW91c2VVcEhhbmRsZXIpO1xuICAgICAgICB0aGlzLm9uTW91c2VVcEhhbmRsZXIgPSBudWxsO1xuICAgIH1cblxuICAgIHNldFZhbHVlICh2YWx1ZSkge1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgZ2V0VmFsdWUgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICB9XG5cbiAgICBzaG93QXQgKGNtKSB7XG4gICAgICAgIGxldCBjdXJzb3IgPSBjbS5jdXJzb3JDb29yZHModHJ1ZSwgJ3BhZ2UnKTtcbiAgICAgICAgbGV0IHggPSBjdXJzb3IubGVmdDtcbiAgICAgICAgbGV0IHkgPSBjdXJzb3IudG9wO1xuXG4gICAgICAgIHggLT0gdGhpcy53aWR0aCAqIDAuNTtcbiAgICAgICAgeSArPSAzMDtcblxuICAgICAgICAvLyAvLyBDaGVjayBpZiBkZXNpcmVkIHgsIHkgd2lsbCBiZSBvdXRzaWRlIHRoZSB2aWV3cG9ydC5cbiAgICAgICAgLy8gLy8gRG8gbm90IGFsbG93IHRoZSBtb2RhbCB0byBkaXNhcHBlYXIgb2ZmIHRoZSBlZGdlIG9mIHRoZSB3aW5kb3cuXG4gICAgICAgIC8vIHggPSAoeCArIHRoaXMud2lkdGggPCB3aW5kb3cuaW5uZXJXaWR0aCkgPyB4IDogKHdpbmRvdy5pbm5lcldpZHRoIC0gMjAgLSB0aGlzLndpZHRoKTtcbiAgICAgICAgLy8geSA9ICh5ICsgdGhpcy5oZWlnaHQgPCB3aW5kb3cuaW5uZXJIZWlnaHQpID8geSA6ICh3aW5kb3cuaW5uZXJIZWlnaHQgLSAyMCAtIHRoaXMuaGVpZ2h0KTtcblxuICAgICAgICB0aGlzLnByZXNlbnRNb2RhbCh4LCB5KTtcbiAgICB9XG5cbiAgICBwcmVzZW50TW9kYWwgKHgsIHkpIHtcbiAgICAgICAgLy8gTGlzdGVuIGZvciBpbnRlcmFjdGlvbiBvdXRzaWRlIG9mIHRoZSBtb2RhbFxuICAgICAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9uQ2xpY2tPdXRzaWRlSGFuZGxlciA9IGFkZEV2ZW50KGRvY3VtZW50LmJvZHksICdjbGljaycsIHRoaXMub25DbGlja091dHNpZGUsIHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5vbktleVByZXNzSGFuZGxlciA9IGFkZEV2ZW50KHdpbmRvdywgJ2tleWRvd24nLCB0aGlzLm9uS2V5UHJlc3MsIHRoaXMpO1xuICAgICAgICB9LCAwKTtcbiAgICAgICAgdGhpcy5pc1Zpc2libGUgPSB0cnVlO1xuXG4gICAgICAgIHRoaXMuZWwuc3R5bGUubGVmdCA9IHggKyAncHgnO1xuICAgICAgICB0aGlzLmVsLnN0eWxlLnRvcCA9IHkgKyAncHgnO1xuICAgICAgICB0aGlzLmVsLnN0eWxlLndpZHRoID0gdGhpcy53aWR0aCArICdweCc7XG4gICAgICAgIHRoaXMuZWwuc3R5bGUuaGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyAncHgnO1xuICAgICAgICBkb2
23459N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMuZWwpO1xuXG4gICAgICAgIHRoaXMub25Nb3VzZURvd25IYW5kbGVyID0gYWRkRXZlbnQodGhpcy5lbCwgJ21vdXNlZG93bicsIHRoaXMub25Nb3VzZURvd24sIHRoaXMpO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIuZHJhd0ZyYW1lKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogIFJlbW92ZXMgbW9kYWwgZnJvbSBET00gYW5kIGRlc3Ryb3lzIHJlbGF0ZWQgZXZlbnQgbGlzdGVuZXJzXG4gICAgICovXG4gICAgcmVtb3ZlTW9kYWwgKCkge1xuICAgICAgICBpZiAodGhpcy5lbCAmJiB0aGlzLmVsLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgIHRoaXMuZWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLmVsKTtcbiAgICAgICAgfVxuICAgICAgICByZW1vdmVFdmVudChkb2N1bWVudC5ib2R5LCAnY2xpY2snLCB0aGlzLm9uQ2xpY2tPdXRzaWRlSGFuZGxlcik7XG4gICAgICAgIHRoaXMub25DbGlja091dHNpZGVIYW5kbGVyID0gbnVsbDtcbiAgICAgICAgcmVtb3ZlRXZlbnQod2luZG93LCAna2V5ZG93bicsIHRoaXMub25LZXlQcmVzc0hhbmRsZXIpO1xuICAgICAgICB0aGlzLm9uS2V5UHJlc3NIYW5kbGVyID0gbnVsbDtcblxuICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIHRoaXMuaXNWaXNpYmxlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgb25LZXlQcmVzcyAoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVNb2RhbCgpO1xuICAgIH1cblxuICAgIG9uQ2xpY2tPdXRzaWRlIChldmVudCkge1xuICAgICAgICAvLyBIQUNLWSEhXG4gICAgICAgIC8vIEEgY2xpY2sgZXZlbnQgZmlyZXMgb24gdGhlIGJvZHkgYWZ0ZXIgbW91c2Vkb3duIC0gbW91c2Vtb3ZlLCBzaW11bHRhbmVvdXNseSB3aXRoXG4gICAgICAgIC8vIG1vdXNldXAuIFNvIGlmIHNvbWVvbmUgc3RhcnRlZCBhIG1vdXNlIGFjdGlvbiBpbnNpZGUgdGhlIG1vZGFsIGFuZCB0aGVuXG4gICAgICAgIC8vIG1vdXNldXAnZCBvdXRzaWRlIG9mIGl0LCBpdCBmaXJlcyBhIGNsaWNrIGV2ZW50IG9uIHRoZSBib2R5LCB0aHVzLCBjYXVzaW5nIHRoZVxuICAgICAgICAvLyBtb2RhbCB0byBkaXNhcHBlYXIgd2hlbiB0aGUgdXNlciBkb2VzIG5vdCBleHBlY3QgaXQgdG8sIHNpbmNlIHRoZSBtb3VzZSBkb3duIGV2ZW50XG4gICAgICAgIC8vIGRpZCBub3Qgc3RhcnQgb3V0c2lkZSB0aGUgbW9kYWwuXG4gICAgICAgIC8vIFRoZXJlIG1pZ2h0IGJlIChvciBzaG91bGQgYmUpIGEgYmV0dGVyIHdheSB0byB0cmFjayB0aGlzLCBidXQgcmlnaHQgbm93LCBqdXN0IGNhbmNlbFxuICAgICAgICAvLyB0aGUgZXZlbnQgaWYgdGhlIHRhcmdldCBlbmRzIHVwIGJlaW5nIG9uIHRoZSBib2R5IGRpcmVjdGx5IHJhdGhlciB0aGFuIG9uIG9uZSBvZiB0aGVcbiAgICAgICAgLy8gb3RoZXIgY2hpbGQgZWxlbWVudHMuXG4gICAgICAgIGlmIChldmVudC50YXJnZXQgPT09IGRvY3VtZW50LmJvZHkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBlbmQgdGhpcyBzcGVjaWZpYyBoYWNreSBwYXJ0XG5cbiAgICAgICAgbGV0IHRhcmdldCA9IGV2ZW50LnRhcmdldDtcblxuICAgICAgICB3aGlsZSAodGFyZ2V0ICE9PSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgJiYgIXRhcmdldC5jbGFzc0xpc3QuY29udGFpbnModGhpcy5DU1NfUFJFRklYICsgJ21vZGFsJykpIHtcbiAgICAgICAgICAgIHRhcmdldCA9IHRhcmdldC5wYXJlbnROb2RlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0YXJnZXQuY2xhc3NMaXN0LmNvbnRhaW5zKHRoaXMuQ1NTX1BSRUZJWCArICdtb2RhbCcpKSB7XG4gICAgICAgICAgICB0aGlzLnJlbW92ZU1vZGFsKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbk1vdXNlRG93biAoZXZlbnQpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAvLyBTdGFydHMgbGlzdGVuaW5nIGZvciBtb3VzZW1vdmUgYW5kIG1vdXNldXAgZXZlbnRzXG4gICAgICAgIHRoaXMub25Nb3VzZU1vdmVIYW5kbGVyID0gYWRkRXZlbnQodGhpcy5lbCwgJ21vdXNlbW92ZScsIHRoaXMub25Nb3VzZU1vdmUsIHRoaXMpO1xuICAgICAgICB0aGlzLm9uTW91c2VVcEhhbmRsZXIgPSBhZGRFdmVudCh3aW5kb3csICdtb3VzZXVwJywgdGhpcy5vbk1vdXNlVXAsIHRoaXMpO1xuXG4gICAgICAgIHRoaXMub25Nb3VzZU1vdmUoZXZlbnQpO1xuXG4gICAgICAgIHRoaXMucmVuZGVyZXIuc3RhcnQoKTtcbiAgICB9XG5cbiAgICBvbk1vdXNlTW92ZSAoZXZlbnQpIHtcbiAgICB9XG5cbiAgICBvbk1vdXNlVXAgKGV2ZW50KSB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc3RvcCgpO1xuICAgICAgICB0aGlzLmRlc3Ryb3lFdmVudHMoKTtcbiAgICB9XG59XG5cbi8qIEV2ZW50IGhhbmRsaW5nICovXG5leHBvcnQgZnVuY3Rpb24gYWRkRXZlbnQgKGVsZW1lbnQsIGV2ZW50LCBjYWxsYmFjaywgY2FsbGVyKSB7XG4gICAgbGV0IGhhbmRsZXI7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBoYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgY2FsbGJhY2suY2FsbChjYWxsZXIsIGUpO1xuICAgIH0sIGZhbHNlKTtcbiAgICByZXR1cm4gaGFuZGxlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUV2ZW50IChlbGVtZW50LCBldmVudCwgY2FsbGJhY2spIHtcbiAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGNhbGxiYWNrLCBmYWxzZSk7XG59XG4iLCJpbXBvcnQgUGlja2VyIGZyb20gJy4vUGlja2VyJztcbmltcG9ydCBWZWN0b3IgZnJvbSAnLi90eXBlcy9WZWN0b3InO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWMyUGlja2VyIGV4dGVuZHMgUGlja2VyIHtcbiAgICBjb25zdHJ1Y3RvciAocG9zLCBwcm9wZXJ0aWVzKSB7XG4gICAgICAgIHN1cGVyKCdnZV92ZWMycGlja2VyXycsIHByb3BlcnRpZXMpO1xuXG4gICAgICAgIHRoaXMud2lkdGggPSB0aGlzLndpZHRoIHx8IDIwMDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLmhlaWdodCB8fCAyMDA7XG5cbiAgICAgICAgdGhpcy5taW4gPSB0aGlzLm1pbiB8fCAtMTtcbiAgICAgICAgdGhpcy5tYXggPSB0aGlzLm1heCB8fCAxO1xuICAgICAgICB0aGlzLnNpemUgPSB0aGlzLnNpemUgfHwgNjtcbiAgICAgICAgdGhpcy5yYW5nZSA9IHRoaXMubWF4IC0gdGhpcy5taW47XG4gICAgICAgI
23459HRoaXMub3ZlclBvaW50ID0gZmFsc2U7XG5cbiAgICAgICAgbGV0IGNlbnRlciA9ICgodGhpcy5yYW5nZSAvIDIpIC0gdGhpcy5tYXgpICogLTE7XG4gICAgICAgIHRoaXMuc2V0VmFsdWUocG9zIHx8IFtjZW50ZXIsY2VudGVyXSk7XG4gICAgICAgIHRoaXMuY3JlYXRlKCk7XG4gICAgfVxuXG4gICAgZHJhdyAoKSB7XG4gICAgICAgIHRoaXMuY3R4LmNsZWFyUmVjdCgwLCAwLCB0aGlzLndpZHRoLCB0aGlzLmhlaWdodCk7XG5cbiAgICAgICAgLy8gZnJhbWVcbiAgICAgICAgdGhpcy5jdHguc3Ryb2tlU3R5bGUgPSB0aGlzLmRpbUNvbG9yO1xuICAgICAgICB0aGlzLmN0eC5saW5lV2lkdGggPSAyO1xuICAgICAgICB0aGlzLmN0eC5zdHJva2VSZWN0KDAsIDAsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTtcblxuICAgICAgICB0aGlzLmN0eC5iZWdpblBhdGgoKTtcbiAgICAgICAgdGhpcy5jdHgubGluZVdpZHRoID0gMC4yNTtcbiAgICAgICAgbGV0IHNlY3Rpb25zID0gMjA7XG4gICAgICAgIGxldCBzdGVwID0gdGhpcy53aWR0aCAvIHNlY3Rpb25zO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlY3Rpb25zOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMuY3R4Lm1vdmVUbyhpICogc3RlcCwgMCk7XG4gICAgICAgICAgICB0aGlzLmN0eC5saW5lVG8oaSAqIHN0ZXAsIHRoaXMuaGVpZ2h0KTtcbiAgICAgICAgICAgIHRoaXMuY3R4Lm1vdmVUbygwLCBpICogc3RlcCk7XG4gICAgICAgICAgICB0aGlzLmN0eC5saW5lVG8odGhpcy53aWR0aCwgaSAqIHN0ZXApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY3R4LnN0cm9rZSgpO1xuXG4gICAgICAgIC8vIGhvcml6b250YWwgbGluZVxuICAgICAgICB0aGlzLmN0eC5zdHJva2VTdHlsZSA9IHRoaXMuZGltQ29sb3I7XG4gICAgICAgIHRoaXMuY3R4LmxpbmVXaWR0aCA9IDEuMDtcbiAgICAgICAgdGhpcy5jdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIHRoaXMuY3R4Lm1vdmVUbygwLCAwLjUgKyB0aGlzLmhlaWdodCAqIDAuNSk7XG4gICAgICAgIHRoaXMuY3R4LmxpbmVUbyh0aGlzLndpZHRoLCAwLjUgKyB0aGlzLmhlaWdodCAqIDAuNSk7XG4gICAgICAgIHRoaXMuY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICB0aGlzLmN0eC5zdHJva2UoKTtcblxuICAgICAgICAvLyB2ZXJ0aWNhbCBsaW5lXG4gICAgICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICB0aGlzLmN0eC5tb3ZlVG8oMC41ICsgdGhpcy53aWR0aCAqIDAuNSwgMCk7XG4gICAgICAgIHRoaXMuY3R4LmxpbmVUbygwLjUgKyB0aGlzLndpZHRoICogMC41LCB0aGlzLmhlaWdodCk7XG4gICAgICAgIHRoaXMuY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICB0aGlzLmN0eC5zdHJva2UoKTtcblxuICAgICAgICAvLyAvLyBUcmlhbmdsZSBsaW5lXG4gICAgICAgIC8vIHRoaXMuY3R4LmZpbGxTdHlsZSA9IHRoaXMuZGltQ29sb3I7XG4gICAgICAgIC8vIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICAvLyB0aGlzLmN0eC5tb3ZlVG8odGhpcy53aWR0aCAqIDAuNSwgNSk7XG4gICAgICAgIC8vIHRoaXMuY3R4LmxpbmVUbyh0aGlzLndpZHRoICogMC40OCwgMCk7XG4gICAgICAgIC8vIHRoaXMuY3R4LmxpbmVUbyh0aGlzLndpZHRoICogMC41MiwgMCk7XG4gICAgICAgIC8vIHRoaXMuY3R4LmNsb3NlUGF0aCgpO1xuICAgICAgICAvLyB0aGlzLmN0eC5maWxsKCk7XG5cbiAgICAgICAgbGV0IHggPSBNYXRoLnJvdW5kKCgodGhpcy52YWx1ZS54IC0gdGhpcy5taW4pIC8gdGhpcy5yYW5nZSkgKiB0aGlzLndpZHRoKTtcbiAgICAgICAgbGV0IHkgPSBNYXRoLnJvdW5kKCgoMSAtICh0aGlzLnZhbHVlLnkgLSB0aGlzLm1pbikgLyB0aGlzLnJhbmdlKSkgKiB0aGlzLmhlaWdodCk7XG5cbiAgICAgICAgbGV0IGhhbGYgPSB0aGlzLnNpemUgLyAyO1xuXG4gICAgICAgIGlmICh4IDwgaGFsZikge1xuICAgICAgICAgICAgeCA9IGhhbGY7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHggPiB0aGlzLndpZHRoIC0gaGFsZikge1xuICAgICAgICAgICAgeCA9IHRoaXMud2lkdGggLSBoYWxmO1xuICAgICAgICB9XG4gICAgICAgIGlmICh5IDwgaGFsZikge1xuICAgICAgICAgICAgeSA9IGhhbGY7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHkgPiB0aGlzLmhlaWdodCAtIGhhbGYpIHtcbiAgICAgICAgICAgIHkgPSB0aGlzLmhlaWdodCAtIGhhbGY7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBwb2ludFxuICAgICAgICB0aGlzLmN0eC5maWxsU3R5bGUgPSB0aGlzLm92ZXJQb2ludCA/IHRoaXMuc2VsQ29sb3IgOiB0aGlzLmZuQ29sb3I7XG4gICAgICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICBsZXQgcmFkaXVzID0gdGhpcy5vdmVyUG9pbnQgPyA0IDogMjtcbiAgICAgICAgdGhpcy5jdHguYXJjKHgsIHksIHJhZGl1cywgMCwgMiAqIE1hdGguUEksIGZhbHNlKTtcbiAgICAgICAgdGhpcy5jdHguZmlsbCgpO1xuXG4gICAgICAgIHRoaXMuY3R4LnJlc3RvcmUoKTtcbiAgICAgICAgdGhpcy5vdmVyUG9pbnQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBBY3Rpb25zIHdoZW4gdXNlciBtb3ZlcyBhcm91bmQgb24gSFNWIGNvbG9yIG1hcFxuICAgIG9uTW91c2VNb3ZlIChldmVudCkge1xuICAgICAgICBsZXQgeCA9IGV2ZW50Lm9mZnNldFg7XG4gICAgICAgIGxldCB5ID0gZXZlbnQub2Zmc2V0WTtcblxuICAgICAgICB0aGlzLnZhbHVlLnggPSAoKHRoaXMucmFuZ2UgLyB0aGlzLndpZHRoKSAqIHgpIC0gKHRoaXMucmFuZ2UgLSB0aGlzLm1heCk7XG4gICAgICAgIHRoaXMudmFsdWUueSA9ICgoKHRoaXMucmFuZ2UgLyB0aGlzLmhlaWdodCkgKiB5KSAtICh0aGlzLnJhbmdlIC0gdGhpcy5tYXgpKSAqIC0xO1xuXG4gICAgICAgIC8vIGZpcmUgJ2NoYW5nZWQnXG4gICAgICAgIHRoaXMudHJpZ2dlcignY2hhbmdlZCcsIHRoaXMudmFsdWUpO1xuICAgICAgICB0aGlzLm92ZXJQb2ludCA9IHRydWU7XG4gICAgfVxuXG4gICAgc2V0VmFsdWUgKHBvcykge1xuICAgICAgICB0aGlzLnZhbHVlID0gbmV3IFZlY3Rvcihwb3MpO1xuICAgIH1cbn1cbiIsImltcG9ydCBQaWNrZXIgZnJvbSAnLi9QaWNrZXInO1xuaW1wb3J0IFZlY3RvciBmcm9tICcuL3R5cGVzL1ZlY3Rvcic7XG5pbXBvcnQgTWF0cml4IGZyb20gJy4vdHlwZXMvTWF0cml4JztcbmltcG9ydCB7
23459IGFkZEV2ZW50LCByZW1vdmVFdmVudCB9IGZyb20gJy4vUGlja2VyJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmVjM1BpY2tlciBleHRlbmRzIFBpY2tlciB7XG4gICAgY29uc3RydWN0b3IgKGRpciwgcHJvcGVydGllcykge1xuICAgICAgICBzdXBlcignZ2VfdmVjM3BpY2tlcl8nLCBwcm9wZXJ0aWVzKTtcblxuICAgICAgICB0aGlzLndpZHRoID0gdGhpcy53aWR0aCB8fCAyMDA7XG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy53aWR0aCB8fCAyMDA7XG4gICAgICAgIHRoaXMuc2NhbGUgPSA1MDtcblxuICAgICAgICB0aGlzLnNldFZhbHVlKGRpciB8fCBbMCwgMCwgMV0pO1xuICAgICAgICB0aGlzLmNyZWF0ZSgpO1xuXG4gICAgICAgIHRoaXMuY2FtZXJhID0gbmV3IE1hdHJpeCgpO1xuICAgICAgICB0aGlzLnNoYXBlcyA9IFtdO1xuICAgICAgICB0aGlzLmNlbnRlciA9IFswLCAwLCAwXTtcblxuICAgICAgICB0aGlzLnNoYXBlcy5wdXNoKHtcbiAgICAgICAgICAgIGVkZ2VDb2xvdXI6IHRoaXMuZGltQ29sb3IsXG4gICAgICAgICAgICBub2RlczogW1t0aGlzLndpZHRoIC8gMiAtIDUwLCB0aGlzLmhlaWdodCAvIDIsIDEwMF0sIFt0aGlzLndpZHRoIC8gMiArIDUwLCB0aGlzLmhlaWdodCAvIDIsIDEwMF0sXG4gICAgICAgICAgICAgICAgW3RoaXMud2lkdGggLyAyLCB0aGlzLmhlaWdodCAvIDIgLSA1MCwgMTAwXSwgW3RoaXMud2lkdGggLyAyLCB0aGlzLmhlaWdodCAvIDIgKyA1MCwgMTAwXSxcbiAgICAgICAgICAgICAgICBbdGhpcy53aWR0aCAvIDIsIHRoaXMuaGVpZ2h0IC8gMiwgNTBdLCBbdGhpcy53aWR0aCAvIDIsIHRoaXMuaGVpZ2h0IC8gMiwgMTUwXV0sXG4gICAgICAgICAgICBlZGdlczogW1swLDFdLCBbMiwzXSwgWzQsNV1dXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuc2hhcGVzLnB1c2goe1xuICAgICAgICAgICAgdGV4dENvbG91cjogdGhpcy5mbkNvbG9yLFxuICAgICAgICAgICAgbm9kZXM6IFtbdGhpcy53aWR0aCAvIDIgKyA2OCwgdGhpcy5oZWlnaHQgLyAyLCAxMDBdLCBbdGhpcy53aWR0aCAvIDIgLSA2OCwgdGhpcy5oZWlnaHQgLyAyLCAxMDBdLFxuICAgICAgICAgICAgICAgIFt0aGlzLndpZHRoIC8gMiwgdGhpcy5oZWlnaHQgLyAyICsgNjgsIDEwMF0sIFt0aGlzLndpZHRoIC8gMiwgdGhpcy5oZWlnaHQgLyAyIC0gNjgsIDEwMF0sXG4gICAgICAgICAgICAgICAgW3RoaXMud2lkdGggLyAyLCB0aGlzLmhlaWdodCAvIDIsIDE2OF0sIFt0aGlzLndpZHRoIC8gMiwgdGhpcy5oZWlnaHQgLyAyLCAzMl1dLFxuICAgICAgICAgICAgdGV4dDogWyd4JywgJy14JywgJ3knLCAnLXknLCAneicsICcteiddXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuc2V0Q2VudGVyKHRoaXMud2lkdGggLyAyLCB0aGlzLmhlaWdodCAvIDIsIDEwMCk7XG5cbiAgICAgICAgLy8gTW91c2UgZXZlbnRzXG4gICAgICAgIHRoaXMuZHJhZ09mZnNldCA9IFswLCAwXTtcbiAgICAgICAgdGhpcy5vdmVyUG9pbnQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBzZXRDZW50ZXIgKHgsIHksIHopIHtcbiAgICAgICAgZm9yIChsZXQgcyBpbiB0aGlzLnNoYXBlcykge1xuICAgICAgICAgICAgbGV0IHNoYXBlID0gdGhpcy5zaGFwZXNbc107XG5cbiAgICAgICAgICAgIGZvciAobGV0IG4gaW4gc2hhcGUubm9kZXMpIHtcbiAgICAgICAgICAgICAgICBzaGFwZS5ub2Rlc1tuXVswXSAtPSB4O1xuICAgICAgICAgICAgICAgIHNoYXBlLm5vZGVzW25dWzFdIC09IHk7XG4gICAgICAgICAgICAgICAgc2hhcGUubm9kZXNbbl1bMl0gLT0gejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNlbnRlciA9IFt4LCB5LCB6XTtcbiAgICB9XG5cbiAgICB2aWV3RnJvbUNhbWVyYSAobm9kZSkge1xuICAgICAgICBsZXQgQSA9IHRoaXMuY2FtZXJhLmdldE11bHQobm9kZSk7XG4gICAgICAgIEEuYWRkKHRoaXMuY2VudGVyKTtcbiAgICAgICAgcmV0dXJuIFtBLngsIHRoaXMuaGVpZ2h0IC0gQS55XTtcbiAgICB9XG5cbiAgICBkcmF3ICgpIHtcbiAgICAgICAgdGhpcy5jdHguY2xlYXJSZWN0KDAsIDAsIHRoaXMud2lkdGgsIHRoaXMuaGVpZ2h0KTtcblxuICAgICAgICBmb3IgKGxldCBzIGluIHRoaXMuc2hhcGVzKSB7XG4gICAgICAgICAgICBsZXQgc2hhcGUgPSB0aGlzLnNoYXBlc1tzXTtcbiAgICAgICAgICAgIGlmIChzaGFwZS5lZGdlQ29sb3VyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kcmF3U2hhcGVFZGdlcyhzaGFwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2hhcGUubm9kZUNvbG91cikge1xuICAgICAgICAgICAgICAgIHRoaXMuZHJhd1NoYXBlTm9kZXMoc2hhcGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHNoYXBlLnRleHQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRyYXdTaGFwZVRleHQoc2hhcGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kcmF3U2hhcGVFZGdlcyh7XG4gICAgICAgICAgICBlZGdlQ29sb3VyOiB0aGlzLmZuQ29sb3IsXG4gICAgICAgICAgICBub2RlczogW1swLDAsMF0sIHRoaXMucG9pbnRdLFxuICAgICAgICAgICAgZWRnZXM6IFtbMCwxXV1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5kcmF3U2hhcGVOb2Rlcyh7XG4gICAgICAgICAgICBub2RlQ29sb3VyOiB0aGlzLm92ZXJQb2ludCA/IHRoaXMuc2VsQ29sb3IgOiB0aGlzLmZuQ29sb3IsXG4gICAgICAgICAgICBub2RlUmFkaXVzOiB0aGlzLm92ZXJQb2ludCA/IDQgOiAyLFxuICAgICAgICAgICAgbm9kZXM6IFt0aGlzLnBvaW50XVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBkcmF3U2hhcGVFZGdlcyAoc2hhcGUpIHtcbiAgICAgICAgbGV0IG5vZGVzID0gc2hhcGUubm9kZXM7XG5cbiAgICAgICAgdGhpcy5jdHguc3Ryb2tlU3R5bGUgPSBzaGFwZS5lZGdlQ29sb3VyO1xuICAgICAgICBmb3IgKGxldCBlIGluIHNoYXBlLmVkZ2VzKSB7XG4gICAgICAgICAgICBsZXQgY29vcmQgPSB0aGlzLnZpZXdGcm9tQ2FtZXJhKG5vZGVzW3NoYXBlLmVkZ2VzW2VdWzBdXSk7XG4gICAgICAgICAgICB0aGlzLmN0eC5saW5lV2lkdGggPSAxO1xuICAgICAgICAgICAgdGhpcy5jdHguYmVnaW5QYXRoKCk7XG4gICAgICAgICAgICB0aGlzLmN0eC5tb3ZlVG8oY29vcmRbMF0sIGNvb3JkWzFdKTtcbiAgICAgICAgICAgIGNvb3JkID0gdGh
23459pcy52aWV3RnJvbUNhbWVyYShub2Rlc1tzaGFwZS5lZGdlc1tlXVsxXV0pO1xuICAgICAgICAgICAgdGhpcy5jdHgubGluZVRvKGNvb3JkWzBdLCBjb29yZFsxXSk7XG4gICAgICAgICAgICB0aGlzLmN0eC5zdHJva2UoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRyYXdTaGFwZU5vZGVzIChzaGFwZSkge1xuICAgICAgICBsZXQgcmFkaXVzID0gc2hhcGUubm9kZVJhZGl1cyB8fCA0O1xuICAgICAgICB0aGlzLmN0eC5maWxsU3R5bGUgPSBzaGFwZS5ub2RlQ29sb3VyO1xuICAgICAgICBmb3IgKGxldCBuIGluIHNoYXBlLm5vZGVzKSB7XG4gICAgICAgICAgICBsZXQgY29vcmQgPSB0aGlzLnZpZXdGcm9tQ2FtZXJhKHNoYXBlLm5vZGVzW25dKTtcbiAgICAgICAgICAgIHRoaXMuY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgICAgICAgdGhpcy5jdHguYXJjKGNvb3JkWzBdLCBjb29yZFsxXSwgcmFkaXVzLCAwICwgMiAqIE1hdGguUEksIGZhbHNlKTtcbiAgICAgICAgICAgIHRoaXMuY3R4LmZpbGwoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRyYXdTaGFwZVRleHQgKHNoYXBlKSB7XG4gICAgICAgIHRoaXMuY3R4LmZpbGxTdHlsZSA9IHNoYXBlLnRleHRDb2xvdXI7XG4gICAgICAgIGZvciAobGV0IG4gaW4gc2hhcGUubm9kZXMpIHtcbiAgICAgICAgICAgIGxldCBjb29yZCA9IHRoaXMudmlld0Zyb21DYW1lcmEoc2hhcGUubm9kZXNbbl0pO1xuICAgICAgICAgICAgdGhpcy5jdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG4gICAgICAgICAgICB0aGlzLmN0eC5maWxsVGV4dChzaGFwZS50ZXh0W25dLCBjb29yZFswXSwgY29vcmRbMV0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Nb3VzZURvd24gKGV2ZW50KSB7XG4gICAgICAgIGxldCBtb3VzZSA9IFtldmVudC5vZmZzZXRYLCBldmVudC5vZmZzZXRZXTtcbiAgICAgICAgdGhpcy5kcmFnT2Zmc2V0ID0gbW91c2U7XG5cbiAgICAgICAgbGV0IHBvcyA9IG5ldyBWZWN0b3IodGhpcy52aWV3RnJvbUNhbWVyYSh0aGlzLnBvaW50KSk7XG4gICAgICAgIGxldCBkaWZmID0gcG9zLmdldFN1Yihtb3VzZSk7XG4gICAgICAgIHRoaXMub3ZlclBvaW50ID0gZGlmZi5nZXRMZW5ndGgoKSA8IDEwO1xuXG4gICAgICAgIHN1cGVyLm9uTW91c2VEb3duKGV2ZW50KTtcbiAgICAgICAgdGhpcy5vbk1vdXNlVXBIYW5kbGVyID0gYWRkRXZlbnQodGhpcy5lbCwgJ2RibGNsaWNrJywgdGhpcy5vbkRiQ2xpY2ssIHRoaXMpO1xuICAgIH1cblxuICAgIC8vIEFjdGlvbnMgd2hlbiB1c2VyIG1vdmVzIGFyb3VuZCBvbiBIU1YgY29sb3IgbWFwXG4gICAgb25Nb3VzZU1vdmUgKGV2ZW50KSB7XG4gICAgICAgIGxldCB4ID0gZXZlbnQub2Zmc2V0WDtcbiAgICAgICAgbGV0IHkgPSBldmVudC5vZmZzZXRZO1xuXG4gICAgICAgIHZhciBkeCA9IDAuMDEgKiAoeCAtIHRoaXMuZHJhZ09mZnNldFswXSk7XG4gICAgICAgIHZhciBkeSA9IDAuMDEgKiAoeSAtIHRoaXMuZHJhZ09mZnNldFsxXSk7XG5cbiAgICAgICAgaWYgKHRoaXMub3ZlclBvaW50KSB7XG4gICAgICAgICAgICBsZXQgaW52TSA9IHRoaXMuY2FtZXJhLmdldEludigpO1xuICAgICAgICAgICAgbGV0IHZlbCA9IGludk0uZ2V0TXVsdChbZHgsIC1keSwgMC4wXSk7XG4gICAgICAgICAgICB2ZWwubXVsdCgyKTtcbiAgICAgICAgICAgIHRoaXMudmFsdWUuYWRkKHZlbCk7XG4gICAgICAgICAgICB0aGlzLnBvaW50ID0gW3RoaXMudmFsdWUueCAqIHRoaXMuc2NhbGUsIHRoaXMudmFsdWUueSAqIHRoaXMuc2NhbGUsIHRoaXMudmFsdWUueiAqIHRoaXMuc2NhbGVdO1xuICAgICAgICAgICAgLy8gZmlyZSAnY2hhbmdlZCdcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlcignY2hhbmdlZCcsIHRoaXMudmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYW1lcmEucm90YXRlWChkeSk7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS5yb3RhdGVZKGR4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZHJhZ09mZnNldCA9IFt4LCB5XTtcbiAgICB9XG5cbiAgICBvbkRiQ2xpY2sgKGV2ZW50KSB7XG4gICAgICAgIGxldCBtb3VzZSA9IG5ldyBWZWN0b3IoW2V2ZW50Lm9mZnNldFgsIGV2ZW50Lm9mZnNldFldKTtcbiAgICAgICAgbGV0IGF4aXMgPSB7XG4gICAgICAgICAgICB4OiBbNjgsIDAsIDBdLFxuICAgICAgICAgICAgbmVnWDogWy02OCwgMCwgMF0sXG4gICAgICAgICAgICB5OiBbMCwgNjgsIDEwMF0sXG4gICAgICAgICAgICBuZWdZOiBbMCwgLTY4LCAwXVxuICAgICAgICB9O1xuICAgICAgICBsZXQgc2VsZWN0ZWQgPSAnJztcbiAgICAgICAgZm9yIChsZXQgaSBpbiBheGlzKSB7XG4gICAgICAgICAgICBsZXQgcG9zID0gbmV3IFZlY3Rvcih0aGlzLnZpZXdGcm9tQ2FtZXJhKGF4aXNbaV0pKTtcbiAgICAgICAgICAgIGxldCBkaWZmID0gcG9zLmdldFN1Yihtb3VzZSk7XG4gICAgICAgICAgICBpZiAoZGlmZi5nZXRMZW5ndGgoKSA8IDEwKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWQgPSBpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2FtZXJhID0gbmV3IE1hdHJpeCgpO1xuXG4gICAgICAgIGlmIChzZWxlY3RlZCA9PT0gJ3gnKSB7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS5yb3RhdGVZKC0xLjU3MDc5NjMyNjc5KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzZWxlY3RlZCA9PT0gJ25lZ1gnKSB7XG4gICAgICAgICAgICB0aGlzLmNhbWVyYS5yb3RhdGVZKDEuNTcwNzk2MzI2NzkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNlbGVjdGVkID09PSAneScpIHtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhLnJvdGF0ZVgoLTEuNTcwNzk2MzI2NzkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNlbGVjdGVkID09PSAnbmVnWScpIHtcbiAgICAgICAgICAgIHRoaXMuY2FtZXJhLnJvdGF0ZVgoMS41NzA3OTYzMjY3OSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmRyYXcoKTtcbiAgICB9XG5cbiAgICBkZXN0cm95RXZlbnRzICgpIHtcbiAgICAgICAgc3VwZXIuZGVzdHJveUV2ZW50cygpO1xuICAgICAgICByZW1vdmVFdmVudCh0aGlzLmVsLCAnZGJsY2xpY2snLCB0aGlzLm9uRGJDbGljayk7XG4gICAgICAgI
23459HRoaXMub25Nb3VzZU1vdmVIYW5kbGVyID0gbnVsbDtcbiAgICB9XG5cbiAgICBzZXRWYWx1ZSAoZGlyKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBuZXcgVmVjdG9yKGRpcik7XG4gICAgICAgIHRoaXMucG9pbnQgPSBbdGhpcy52YWx1ZS54ICogdGhpcy5zY2FsZSwgdGhpcy52YWx1ZS55ICogdGhpcy5zY2FsZSwgdGhpcy52YWx1ZS56ICogdGhpcy5zY2FsZV07XG4gICAgfVxufVxuIiwiaW1wb3J0IENvbG9yQ29udmVydGVyIGZyb20gJy4vQ29sb3JDb252ZXJ0ZXInO1xuaW1wb3J0IHsgZ2V0Q29sb3JBc1JHQiwgZ2V0VmFsdWVSYW5nZXMsIGdldEx1bWluYW5jZSwgbGltaXRWYWx1ZSB9IGZyb20gJy4vQ29sb3JDb252ZXJ0ZXInO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb2xvciB7XG4gICAgY29uc3RydWN0b3IgKGNvbG9yKSB7XG4gICAgICAgIHRoaXMuY29sb3JzID0ge307XG4gICAgICAgIHRoaXMuc2V0KGNvbG9yKTtcbiAgICB9XG5cbiAgICBzZXQgKGNvbG9yLCB0eXBlKSB7IC8vIGNvbG9yIG9ubHkgZnVsbCByYW5nZVxuICAgICAgICBpZiAodHlwZW9mIGNvbG9yID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdHlwZSA9IHR5cGUgPyB0eXBlIDogJ3JnYic7XG4gICAgICAgICAgICB0aGlzLmNvbG9yc1t0eXBlXSA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgbiA9IDM7IG4tLTspIHtcbiAgICAgICAgICAgICAgICBsZXQgbSA9IHR5cGVbbl0gfHwgdHlwZS5jaGFyQXQobik7IC8vIElFN1xuICAgICAgICAgICAgICAgIHRoaXMuY29sb3JzW3R5cGVdW21dID0gY29sb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGNvbG9yID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgbGV0IHBhcnRzID0gY29sb3IucmVwbGFjZSgvKD86I3xcXCl8JSkvZywgJycpLnNwbGl0KCcoJyk7XG4gICAgICAgICAgICBpZiAocGFydHNbMV0pIHtcbiAgICAgICAgICAgICAgICBsZXQgdmFsdWVzID0gKHBhcnRzWzFdIHx8ICcnKS5zcGxpdCgvLFxccyovKTtcbiAgICAgICAgICAgICAgICB0eXBlID0gdHlwZSA/IHR5cGUgOiAocGFydHNbMV0gPyBwYXJ0c1swXS5zdWJzdHIoMCwgMykgOiAncmdiJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXQodmFsdWVzLCB0eXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0KGdldENvbG9yQXNSR0IoY29sb3IpLCAncmdiJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY29sb3IpIHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGNvbG9yKSkge1xuICAgICAgICAgICAgICAgIGxldCBtID0gJyc7XG4gICAgICAgICAgICAgICAgdHlwZSA9IHR5cGUgfHwgJ3JnYic7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmNvbG9yc1t0eXBlXSA9IHRoaXMuY29sb3JzW3R5cGVdIHx8IHt9O1xuICAgICAgICAgICAgICAgIGZvciAobGV0IG4gPSAzOyBuLS07KSB7XG4gICAgICAgICAgICAgICAgICAgIG0gPSB0eXBlW25dIHx8IHR5cGUuY2hhckF0KG4pOyAvLyBJRTdcbiAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSBjb2xvci5sZW5ndGggPj0gMyA/IG4gOiAwO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbG9yc1t0eXBlXVttXSA9IHBhcnNlRmxvYXQoY29sb3JbaV0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChjb2xvci5sZW5ndGggPT09IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2xvcnMuYWxwaGEgPSBwYXJzZUZsb2F0KGNvbG9yWzNdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgbiBpbiBjb2xvcikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbG9yc1t0eXBlXVtuXSA9IGxpbWl0VmFsdWUoY29sb3Jbbl0gLyBnZXRWYWx1ZVJhbmdlcyh0eXBlKVtuXVsxXSwgMCwgMSkgKiBnZXRWYWx1ZVJhbmdlcyh0eXBlKVtuXVsxXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlICE9PSAncmdiJykge1xuICAgICAgICAgICAgdmFyIGNvbnZlcnQgPSBDb2xvckNvbnZlcnRlcjtcbiAgICAgICAgICAgIHRoaXMuY29sb3JzLnJnYiA9IGNvbnZlcnRbdHlwZSArICcycmdiJ10odGhpcy5jb2xvcnNbdHlwZV0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29udmVydCh0eXBlKTtcbiAgICAgICAgdGhpcy5jb2xvcnMuaHVlUkdCID0gQ29sb3JDb252ZXJ0ZXIuaHVlMlJHQih0aGlzLmNvbG9ycy5oc3YuaCk7XG4gICAgICAgIHRoaXMuY29sb3JzLmx1bWluYW5jZSA9IGdldEx1bWluYW5jZSh0aGlzLmNvbG9ycy5yZ2IpO1xuICAgIH1cblxuICAgIGNvbnZlcnQgKHR5cGUpIHtcbiAgICAgICAgbGV0IGNvbnZlcnQgPSBDb2xvckNvbnZlcnRlcixcbiAgICAgICAgICAgIHJhbmdlcyA9IGdldFZhbHVlUmFuZ2VzKCksXG4gICAgICAgICAgICBleGNlcHRpb25zID0geyBoc2w6ICdoc3YnLCBjbXlrOiAnY215JywgcmdiOiB0eXBlIH07XG5cbiAgICAgICAgaWYgKHR5cGUgIT09ICdhbHBoYScpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHR5cCBpbiByYW5nZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXJhbmdlc1t0eXBdW3R5cF0pIHsgLy8gbm8gYWxwaGF8SEVYXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlICE9PSB0eXAgJiYgdHlwICE9PSAnWFlaJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGZyb20gPSBleGNlcHRpb25zW3R5cF0gfHwgJ3JnYic7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbG9yc1t0eXBdID0gY29udmVydFtmcm9tICsgJzInICsgdHlwXSh0aGlzLmNvbG9yc1tmcm9tXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgKHR5cGUpIHtcbiAgICAgICAgaWYgKHR5cGUgIT09ICdyZ2InKSB7XG4gICAgICAgICAgICB2Y
23459XIgY29udmVydCA9IENvbG9yQ29udmVydGVyO1xuICAgICAgICAgICAgdGhpcy5jb2xvcnNbdHlwZV0gPSBjb252ZXJ0WydyZ2IyJyArIHR5cGVdKHRoaXMuY29sb3JzWydyZ2InXSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb2xvcnNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb2xvcnNbJ3JnYiddO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0U3RyaW5nICh0eXBlKSB7XG4gICAgICAgIGlmICh0eXBlID09PSAnSEVYJykge1xuICAgICAgICAgICAgdmFyIGNvbnZlcnQgPSBDb2xvckNvbnZlcnRlcjtcbiAgICAgICAgICAgIHJldHVybiBjb252ZXJ0WydyZ2IyJyArIHR5cGVdKHRoaXMuY29sb3JzWydyZ2InXSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgY29sb3IgPSB0aGlzLmdldCh0eXBlKTtcbiAgICAgICAgICAgIGxldCBzdHIgPSB0eXBlLFxuICAgICAgICAgICAgICAgIG0gPSAnJztcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAndmVjJykge1xuICAgICAgICAgICAgICAgIHN0ciArPSB0aGlzLmNvbG9ycy5hbHBoYSA/IDQgOiAzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RyICs9ICcoJztcbiAgICAgICAgICAgIGZvciAobGV0IG4gPSAwOyBuIDwgMzsgbisrKSB7XG4gICAgICAgICAgICAgICAgbSA9IHR5cGVbbl0gfHwgdHlwZS5jaGFyQXQobik7IC8vIElFN1xuICAgICAgICAgICAgICAgIGlmICh0eXBlID09PSAndmVjJykge1xuICAgICAgICAgICAgICAgICAgICBzdHIgKz0gKGNvbG9yW21dKS50b0ZpeGVkKDMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyICs9IE1hdGguZmxvb3IoY29sb3JbbV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobiAhPT0gMikge1xuICAgICAgICAgICAgICAgICAgICBzdHIgKz0gJywnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuY29sb3JzLmFscGhhKSB7XG4gICAgICAgICAgICAgICAgc3RyICs9ICcsJyArICh0aGlzLmNvbG9ycy5hbHBoYSkudG9GaXhlZCgzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdHIgKz0gJyknO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdW5pZm9ybVR5cGUgKCkge1xuICAgICAgICBpZiAodGhpcy5jb2xvcnMuYWxwaGEpIHtcbiAgICAgICAgICAgIHJldHVybiAndmVjNCc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICd2ZWMzJztcbiAgICB9XG5cbiAgICB1bmlmb3JtVmFsdWUgKCkge1xuICAgICAgICB2Y
23459XIgdmVjID0gdGhpcy5nZXQoJ3ZlYycpO1xuICAgICAgICB2YXIgYXJyID0gW3ZlYy52LCB2ZWMuZSwgdmVjLmNdO1xuICAgICAgICBpZiAodGhpcy5jb2xvcnMuYWxwaGEpIHtcbiAgICAgICAgICAgIGFyci5wdXNoKHRoaXMuY29sb3JzLmFscGhhKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXJyO1xuICAgIH1cblxuICAgIHVuaWZvcm1NZXRob2QgKHR5cGUpIHtcbiAgICAgICAgaWYgKHRoaXMuY29sb3JzLmFscGhhKSB7XG4gICAgICAgICAgICByZXR1cm4gJzRmJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJzNmJztcbiAgICB9XG59XG4iLCJ2YXIgdmFsdWVSYW5nZXMgPSB7XG4gICAgcmdiOiB7IHI6IFswLCAyNTVdLCBnOiBbMCwgMjU1XSwgYjogWzAsIDI1NV0gfSxcbiAgICBoc3Y6IHsgaDogWzAsIDFdLCBzOiBbMCwgMV0sIHY6IFswLCAyNTVdIH0sXG4gICAgaHNsOiB7IGg6IFswLCAzNjBdLCBzOiBbMCwgMTAwXSwgbDogWzAsIDEwMF0gfSxcbiAgICBjbXk6IHsgYzogWzAsIDEwMF0sIG06IFswLCAxMDBdLCB5OiBbMCwgMTAwXSB9LFxuICAgIGNteWs6IHsgYzogWzAsIDEwMF0sIG06IFswLCAxMDBdLCB5OiBbMCwgMTAwXSwgazogWzAsIDEwMF0gfSxcbiAgICBMYWI6IHsgTDogWzAsIDEwMF0sIGE6IFstMTI4LCAxMjddLCBiOiBbLTEyOCwgMTI3XSB9LFxuICAgIFhZWjogeyBYOiBbMCwgMTAwXSwgWTogWzAsIDEwMF0sIFo6IFswLCAxMDBdIH0sXG4gICAgdmVjOiB7IHY6IFswLCAxXSwgZTogWzAsIDFdLCBjOiBbMCwgMV0gfSxcbiAgICBhbHBoYTogeyBhbHBoYTogWzAsIDFdIH0sXG4gICAgSEVYOiB7IEhFWDogWzAsIDE2Nzc3MjE1XSB9IC8vIG1heWJlIHdlIGRvbid0IG5lZWQgdGhpc1xufTtcblxuLy8gaHR0cDovL3d3dy5icnVjZWxpbmRibG9vbS5jb20vaW5kZXguaHRtbD9FcW5fUkdCX1hZWl9NYXRyaXguaHRtbCBmb3IgbW9yZVxudmFyIFhZWk1hdHJpeCA9IHsgLy8gT2JzZXJ2ZXIgPSAywrAgKENJRSAxOTMxKSwgSWxsdW1pbmFudCA9IEQ2NVxuICAgIFg6IFswLjQxMjQ1NjQsIDAuMzU3NTc2MSwgMC4xODA0Mzc1XSxcbiAgICBZOiBbMC4yMTI2NzI5LCAwLjcxNTE1MjIsIDAuMDcyMTc1MF0sXG4gICAgWjogWzAuMDE5MzMzOSwgMC4xMTkxOTIwLCAwLjk1MDMwNDFdLFxuICAgIFI6IFszLjI0MDQ1NDIsIC0xLjUzNzEzODUsIC0wLjQ5ODUzMTRdLFxuICAgIEc6IFstMC45NjkyNjYwLCAxLjg3NjAxMDgsIDAuMDQxNTU2MF0sXG4gICAgQjogWzAuMDU1NjQzNCwgLTAuMjA0MDI1OSwgMS4wNTcyMjUyXVxufTtcblxudmFyIFhZWlJlZmVyZW5jZSA9IHtcbiAgICBYOiBYWVpNYXRyaXguWFswXSArIFhZWk1hdHJpeC5YWzFdICsgWFlaTWF0cml4LlhbMl0sXG4gICAgWTogWFlaTWF0cml4LllbMF0gKyBYWVpNYXRyaXguWVsxXSArIFhZWk1hdHJpeC5ZWzJdLFxuICAgIFo6IFhZWk1hdHJpeC5aWzBdICsgWFlaTWF0cml4LlpbMV0gKyBYWVpNYXRyaXguWlsyXVxufTtcblxudmFyIGx1bWluYW5jZSA9IHsgcjogMC4yMTI2LCBnOiAwLjcxNTIsIGI6IDAuMDcyMiB9OyAvLyBXM0MgMi4wXG5cbnZhciBfY29sb3JzO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb2xvckNvbnZlcnRlciB7XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFZFQyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy9cbiAgICBzdGF0aWMgdmVjMnJnYiAodmVjKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByOiB2ZWMudiAqIHZhbHVlUmFuZ2VzWydyZ2InXVsnciddWzFdLFxuICAgICAgICAgICAgZzogdmVjLmUgKiB2YWx1ZVJhbmdlc1sncmdiJ11bJ2cnXVsxXSxcbiAgICAgICAgICAgIGI6IHZlYy5jICogdmFsdWVSYW5nZXNbJ3JnYiddWydiJ11bMV1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBzdGF0aWMgcmdiMnZlYyAocmdiKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2OiByZ2IuciAvIHZhbHVlUmFuZ2VzWydyZ2InXVsnciddWzFdLFxuICAgICAgICAgICAgZTogcmdiLmcgLyB2YWx1ZVJhbmdlc1sncmdiJ11bJ2cnXVsxXSxcbiAgICAgICAgICAgIGM6IHJnYi5iIC8gdmFsdWVSYW5nZXNbJ3JnYiddWydiJ11bMV1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSEVYIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAvL1xuXG4gICAgc3RhdGljIFJHQjJIRVggKHJnYikge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgKHJnYi5yIDwgMTYgPyAnMCcgOiAnJykgKyByZ2Iuci50b1N0cmluZygxNikgK1xuICAgICAgICAgICAgKHJnYi5nIDwgMTYgPyAnMCcgOiAnJykgKyByZ2IuZy50b1N0cmluZygxNikgK1xuICAgICAgICAgICAgKHJnYi5iIDwgMTYgPyAnMCcgOiAnJykgKyByZ2IuYi50b1N0cmluZygxNilcbiAgICAgICAgKS50b1VwcGVyQ2FzZSgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBIRVgycmdiIChIRVgpIHtcbiAgICAgICAgSEVYID0gSEVYLnNwbGl0KCcnKTsgLy8gSUU3XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByOiBwYXJzZUludChIRVhbMF0gKyBIRVhbSEVYWzNdID8gMSA6IDBdLCAxNikgLyAyNTUsXG4gICAgICAgICAgICBnOiBwYXJzZUludChIRVhbSEVYWzNdID8gMiA6IDFdICsgKEhFWFszXSB8fCBIRVhbMV0pLCAxNikgLyAyNTUsXG4gICAgICAgICAgICBiOiBwYXJzZUludCgoSEVYWzRdIHx8IEhFWFsyXSkgKyAoSEVYWzVdIHx8IEhFWFsyXSksIDE2KSAvIDI1NVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBIVUUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIC8vXG5cbiAgICBzdGF0aWMgaHVlMlJHQiAoaHVlKSB7XG4gICAgICAgIHZhciBoID0gaHVlICogNixcbiAgICAgICAgICAgIC8vIG1vZCA9IH5+aCAlIDYsIC8vIE1hdGguZmxvb3IoaCkgLT4gZmFzdGVyIGluIG1vc3QgYnJvd3NlcnNcbiAgICAgICAgICAgIG1vZCA9IE1hdGguZmxvb3IoaCksXG4gICAgICAgICAgICBpID0gaCA9PT0gNiA/IDAgOiAoaCAtIG1vZCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByOiBNYXRoLnJvdW5kKFsxLCAxIC0gaSwgMCwgMCwgaSwgMV1bbW9kXSAqIDI1NSksXG4gICAgICAgICAgICBnOiBNYXRoLnJvdW5kKFtpLCAxLCAxLCAxIC0gaSwgMCwgMF1bbW9kXSAqIDI1NSksXG4gICAgICAgICAgICBiOiBNYXRoLnJvdW5kKFswLCAwLCBpLCAxLCAxLCAxIC0gaV1bbW9kXSAqIDI1NSlcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gSFNWIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAvL1xuXG4gICAgc3RhdGljIHJnYjJoc3YgKHJnYikgeyAvLyBmYXN0ZXJcbiAgICAgICAgdmFyIHIgPSByZ2IucixcbiAgICAgICAgICAgIGcgPSByZ2IuZyxcbiAgICAgICAgICAgIGIgPSByZ2IuYi
23459xcbiAgICAgICAgICAgIGsgPSAwLFxuICAgICAgICAgICAgY2hyb21hLFxuICAgICAgICAgICAgbWluLFxuICAgICAgICAgICAgcztcblxuICAgICAgICBpZiAoZyA8IGIpIHtcbiAgICAgICAgICAgIGcgPSBiICsgKGIgPSBnLCAwKTtcbiAgICAgICAgICAgIGsgPSAtMTtcbiAgICAgICAgfVxuICAgICAgICBtaW4gPSBiO1xuICAgICAgICBpZiAociA8IGcpIHtcbiAgICAgICAgICAgIHIgPSBnICsgKGcgPSByLCAwKTtcbiAgICAgICAgICAgIGsgPSAtMiAvIDYgLSBrO1xuICAgICAgICAgICAgbWluID0gTWF0aC5taW4oZywgYik7IC8vIGcgPCBiID8gZyA6IGI7ID8/P1xuICAgICAgICB9XG4gICAgICAgIGNocm9tYSA9IHIgLSBtaW47XG4gICAgICAgIHMgPSByID8gKGNocm9tYSAvIHIpIDogMDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGg6IHMgPCAxZS0xNSA/ICgoX2NvbG9ycyAmJiBfY29sb3JzLmhzbCAmJiBfY29sb3JzLmhzbC5oKSB8fCAwKSA6XG4gICAgICAgICAgICAgICAgY2hyb21hID8gTWF0aC5hYnMoayArIChnIC0gYikgLyAoNiAqIGNocm9tYSkpIDogMCxcbiAgICAgICAgICAgIHM6IHIgPyAoY2hyb21hIC8gcikgOiAoKF9jb2xvcnMgJiYgX2NvbG9ycy5oc3YgJiYgX2NvbG9ycy5oc3YucykgfHwgMCksIC8vID8/X2NvbG9ycy5oc3YucyB8fCAwXG4gICAgICAgICAgICB2OiByXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc3RhdGljIGhzdjJyZ2IgKGhzdikge1xuICAgICAgICB2YXIgaCA9IGhzdi5oICogNixcbiAgICAgICAgICAgIHMgPSBoc3YucyxcbiAgICAgICAgICAgIHYgPSBoc3YudixcbiAgICAgICAgICAgIC8vIGkgPSB+fmgsIC8vIE1hdGguZmxvb3IoaCkgLT4gZmFzdGVyIGluIG1vc3QgYnJvd3NlcnNcbiAgICAgICAgICAgIGkgPSBNYXRoLmZsb29yKGgpLFxuICAgICAgICAgICAgZiA9IGggLSBpLFxuICAgICAgICAgICAgcCA9IHYgKiAoMSAtIHMpLFxuICAgICAgICAgICAgcSA9IHYgKiAoMSAtIGYgKiBzKSxcbiAgICAgICAgICAgIHQgPSB2ICogKDEgLSAoMSAtIGYpICogcyksXG4gICAgICAgICAgICBtb2QgPSBpICUgNjtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcjogW3YsIHEsIHAsIHAsIHQsIHZdW21vZF0sXG4gICAgICAgICAgICBnOiBbdCwgdiwgdiwgcSwgcCwgcF1bbW9kXSxcbiAgICAgICAgICAgIGI6IFtwLCBwLCB0LCB2LCB2LCBxXVttb2RdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEhTTCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLy9cblxuICAgIHN0YXRpYyBoc3YyaHNsIChoc3YpIHtcbiAgICAgICAgdmFyIGwgPSAoMiAtIGhzdi5zKSAqIGhzdi52LFxuICAgICAgICAgICAgcyA9IGhzdi5zICogaHN2LnY7XG5cbiAgICAgICAgcyA9ICFoc3YucyA/IDAgOiBsIDwgMSA/IChsID8gcyAvIGwgOiAwKSA6IHMgLyAoMiAtIGwpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBoOiBoc3YuaCxcbiAgICAgICAgICAgIHM6ICFoc3YudiAmJiAhcyA/ICgoX2NvbG9ycyAmJiBfY29sb3JzLmhzbCAmJiBfY29sb3JzLmhzbC5zKSB8fCAwKSA6IHMsIC8vID8/P1xuICAgICAgICAgICAgbDogbCAvIDJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBzdGF0aWMgcmdiMmhzbCAocmdiLCBkZXBlbmRlbnQpIHsgLy8gbm90IHVzZWQgaW4gQ29sb3JcbiAgICAgICAgdmFyIGhzdiA9IENvbG9yQ29udmVydGVyLnJnYjJoc3YocmdiKTtcblxuICAgICAgICByZXR1cm4gQ29sb3JDb252ZXJ0ZXIuaHN2MmhzbChkZXBlbmRlbnQgPyBoc3YgOiAoX2NvbG9ycy5oc3YgPSBoc3YpKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgaHNsMnJnYiAoaHNsKSB7XG4gICAgICAgIHZhciBoID0gaHNsLmggKiA2LFxuICAgICAgICAgICAgcyA9IGhzbC5zLFxuICAgICAgICAgICAgbCA9IGhzbC5sLFxuICAgICAgICAgICAgdiA9IGwgPCAwLjUgPyBsICogKDEgKyBzKSA6IChsICsgcykgLSAocyAqIGwpLFxuICAgICAgICAgICAgbSA9IGwgKyBsIC0gdixcbiAgICAgICAgICAgIHN2ID0gdiA/ICgodiAtIG0pIC8gdikgOiAwLFxuICAgICAgICAgICAgLy8gc2V4dGFudCA9IH5+aCwgLy8gTWF0aC5mbG9vcihoKSAtPiBmYXN0ZXIgaW4gbW9zdCBicm93c2Vyc1xuICAgICAgICAgICAgc2V4dGFudCA9IE1hdGguZmxvb3IoaCksXG4gICAgICAgICAgICBmcmFjdCA9IGggLSBzZXh0YW50LFxuICAgICAgICAgICAgdnNmID0gdiAqIHN2ICogZnJhY3QsXG4gICAgICAgICAgICB0ID0gbSArIHZzZixcbiAgICAgICAgICAgIHEgPSB2IC0gdnNmLFxuICAgICAgICAgICAgbW9kID0gc2V4dGFudCAlIDY7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHI6IFt2LCBxLCBtLCBtLCB0LCB2XVttb2RdLFxuICAgICAgICAgICAgZzogW3QsIHYsIHYsIHEsIG0sIG1dW21vZF0sXG4gICAgICAgICAgICBiOiBbbSwgbSwgdCwgdiwgdiwgcV1bbW9kXVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBDTVlLIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAvL1xuICAgIC8vIFF1b3RlIGZyb20gV2lraXBlZGlhOlxuICAgIC8vICdTaW5jZSBSR0IgYW5kIENNWUsgc3BhY2VzIGFyZSBib3RoIGRldmljZS1kZXBlbmRlbnQgc3BhY2VzLCB0aGVyZSBpcyBub1xuICAgIC8vIHNpbXBsZSBvciBnZW5lcmFsIGNvbnZlcnNpb24gZm9ybXVsYSB0aGF0IGNvbnZlcnRzIGJldHdlZW4gdGhlbS5cbiAgICAvLyBDb252ZXJzaW9ucyBhcmUgZ2VuZXJhbGx5IGRvbmUgdGhyb3VnaCBjb2xvciBtYW5hZ2VtZW50IHN5c3RlbXMsIHVzaW5nXG4gICAgLy8gY29sb3IgcHJvZmlsZXMgdGhhdCBkZXNjcmliZSB0aGUgc3BhY2VzIGJlaW5nIGNvbnZlcnRlZC4gTmV2ZXJ0aGVsZXNzLCB0aGVcbiAgICAvLyBjb252ZXJzaW9ucyBjYW5ub3QgYmUgZXhhY3QsIHNpbmNlIHRoZXNlIHNwYWNlcyBoYXZlIHZlcnkgZGlmZmVyZW50IGdhbXV0cy4nXG4gICAgLy8gVHJhbnNsYXRpb246IHRoZSBmb2xsb3dpbmcgYXJlIGp1c3Qgc2ltcGxlIFJHQiB0byBDTVkoSykgYW5kIHZpc2EgdmVyc2EgY29udmVyc2lvbiBmdW5jdGlvbnMuXG5cbiAgICBzdGF0aWMgcmdiMmNteSAocmdiKSB7XG4gICAgICAgI
23459HJldHVybiB7XG4gICAgICAgICAgICBjOiAxIC0gcmdiLnIsXG4gICAgICAgICAgICBtOiAxIC0gcmdiLmcsXG4gICAgICAgICAgICB5OiAxIC0gcmdiLmJcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBzdGF0aWMgY215MmNteWsgKGNteSkge1xuICAgICAgICB2YXIgayA9IE1hdGgubWluKE1hdGgubWluKGNteS5jLCBjbXkubSksIGNteS55KSxcbiAgICAgICAgICAgIHQgPSAxIC0gayB8fCAxZS0yMDtcblxuICAgICAgICByZXR1cm4geyAvLyByZWd1bGFyXG4gICAgICAgICAgICBjOiAoY215LmMgLSBrKSAvIHQsXG4gICAgICAgICAgICBtOiAoY215Lm0gLSBrKSAvIHQsXG4gICAgICAgICAgICB5OiAoY215LnkgLSBrKSAvIHQsXG4gICAgICAgICAgICBrOiBrXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc3RhdGljIGNteWsyY215IChjbXlrKSB7XG4gICAgICAgIHZhciBrID0gY215ay5rO1xuXG4gICAgICAgIHJldHVybiB7IC8vIHJlZ3VsYXJcbiAgICAgICAgICAgIGM6IGNteWsuYyAqICgxIC0gaykgKyBrLFxuICAgICAgICAgICAgbTogY215ay5tICogKDEgLSBrKSArIGssXG4gICAgICAgICAgICB5OiBjbXlrLnkgKiAoMSAtIGspICsga1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHN0YXRpYyBjbXkycmdiIChjbXkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHI6IDEgLSBjbXkuYyxcbiAgICAgICAgICAgIGc6IDEgLSBjbXkubSxcbiAgICAgICAgICAgIGI6IDEgLSBjbXkueVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHN0YXRpYyByZ2IyY215ayAocmdiKSB7XG4gICAgICAgIHZhciBjbXkgPSBDb2xvckNvbnZlcnRlci5yZ2IyY215KHJnYik7IC8vIGRvcHBlbHQ/P1xuICAgICAgICByZXR1cm4gQ29sb3JDb252ZXJ0ZXIuY215MmNteWsoY215KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgY215azJyZ2IgKGNteWspIHtcbiAgICAgICAgdmFyIGNteSA9IENvbG9yQ29udmVydGVyLmNteWsyY215KGNteWspOyAvLyBkb3BwZWx0Pz9cbiAgICAgICAgcmV0dXJuIENvbG9yQ29udmVydGVyLmNteTJyZ2IoY215KTtcbiAgICB9XG5cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gTEFCIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAvL1xuXG4gICAgc3RhdGljIFhZWjJyZ2IgKFhZWikge1xuICAgICAgICB2Y
23459XIgTSA9IFhZWk1hdHJpeCxcbiAgICAgICAgICAgIFggPSBYWVouWCxcbiAgICAgICAgICAgIFkgPSBYWVouWSxcbiAgICAgICAgICAgIFogPSBYWVouWixcbiAgICAgICAgICAgIHIgPSBYICogTS5SWzBdICsgWSAqIE0uUlsxXSArIFogKiBNLlJbMl0sXG4gICAgICAgICAgICBnID0gWCAqIE0uR1swXSArIFkgKiBNLkdbMV0gKyBaICogTS5HWzJdLFxuICAgICAgICAgICAgYiA9IFggKiBNLkJbMF0gKyBZICogTS5CWzFdICsgWiAqIE0uQlsyXSxcbiAgICAgICAgICAgIE4gPSAxIC8gMi40O1xuXG4gICAgICAgIE0gPSAwLjAwMzEzMDg7XG5cbiAgICAgICAgciA9IChyID4gTSA/IDEuMDU1ICogTWF0aC5wb3cociwgTikgLSAwLjA1NSA6IDEyLjkyICogcik7XG4gICAgICAgIGcgPSAoZyA+IE0gPyAxLjA1NSAqIE1hdGgucG93KGcsIE4pIC0gMC4wNTUgOiAxMi45MiAqIGcpO1xuICAgICAgICBiID0gKGIgPiBNID8gMS4wNTUgKiBNYXRoLnBvdyhiLCBOKSAtIDAuMDU1IDogMTIuOTIgKiBiKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcjogbGltaXRWYWx1ZShyLCAwLCAxKSxcbiAgICAgICAgICAgIGc6IGxpbWl0VmFsdWUoZywgMCwgMSksXG4gICAgICAgICAgICBiOiBsaW1pdFZhbHVlKGIsIDAsIDEpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc3RhdGljIHJnYjJYWVogKHJnYikge1xuICAgICAgICB2YXIgTSA9IFhZWk1hdHJpeCxcbiAgICAgICAgICAgIHIgPSByZ2IucixcbiAgICAgICAgICAgIGcgPSByZ2IuZyxcbiAgICAgICAgICAgIGIgPSByZ2IuYixcbiAgICAgICAgICAgIE4gPSAwLjA0MDQ1O1xuXG4gICAgICAgIHIgPSAociA+IE4gPyBNYXRoLnBvdygociArIDAuMDU1KSAvIDEuMDU1LCAyLjQpIDogciAvIDEyLjkyKTtcbiAgICAgICAgZyA9IChnID4gTiA/IE1hdGgucG93KChnICsgMC4wNTUpIC8gMS4wNTUsIDIuNCkgOiBnIC8gMTIuOTIpO1xuICAgICAgICBiID0gKGIgPiBOID8gTWF0aC5wb3coKGIgKyAwLjA1NSkgLyAxLjA1NSwgMi40KSA6IGIgLyAxMi45Mik7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIFg6IHIgKiBNLlhbMF0gKyBnICogTS5YWzFdICsgYiAqIE0uWFsyXSxcbiAgICAgICAgICAgIFk6IHIgKiBNLllbMF0gKyBnICogTS5ZWzFdICsgYiAqIE0uWVsyXSxcbiAgICAgICAgICAgIFo6IHIgKiBNLlpbMF0gKyBnICogTS5aWzFdICsgYiAqIE0uWlsyXVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHN0YXRpYyBYWVoyTGFiIChYWVopIHtcbiAgICAgICAgdmFyIFIgPSBYWVpSZWZlcmVuY2UsXG4gICAgICAgICAgICBYID0gWFlaLlggLyBSLlgsXG4gICAgICAgICAgICBZID0gWFlaLlkgLyBSLlksXG4gICAgICAgICAgICBaID0gWFlaLlogLyBSLlosXG4gICAgICAgICAgICBOID0gMTYgLyAxMTYsXG4gICAgICAgICAgICBNID0gMSAvIDMsXG4gICAgICAgICAgICBLID0gMC4wMDg4NTYsXG4gICAgICAgICAgICBMID0gNy43ODcwMzc7XG5cbiAgICAgICAgWCA9IFggPiBLID8gTWF0aC5wb3coWCwgTSkgOiAoTCAqIFgpICsgTjtcbiAgICAgICAgWSA9IFkgPiBLID8gTWF0aC5wb3coWSwgTSkgOiAoTCAqIFkpICsgTjtcbiAgICAgICAgWiA9IFogPiBLID8gTWF0aC5wb3coWiwgTSkgOiAoTCAqIFopICsgTjtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgTDogKDExNiAqIFkpIC0gMTYsXG4gICAgICAgICAgICBhOiA1MDAgKiAoWCAtIFkpLFxuICAgICAgICAgICAgYjogMjAwICogKFkgLSBaKVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHN0YXRpYyBMYWIyWFlaIChMYWIpIHtcbiAgICAgICAgdmFyIFIgPSBYWVpSZWZlcmVuY2UsXG4gICAgICAgICAgICBZID0gKExhYi5MICsgMTYpIC8gMTE2LFxuICAgICAgICAgICAgWCA9IExhYi5hIC8gNTAwICsgWSxcbiAgICAgICAgICAgIFogPSBZIC0gTGFiLmIgLyAyMDAsXG4gICAgICAgICAgICBYMyA9IE1hdGgucG93KFgsIDMpLFxuICAgICAgICAgICAgWTMgPSBNYXRoLnBvdyhZLCAzKSxcbiAgICAgICAgICAgIFozID0gTWF0aC5wb3coWiwgMyksXG4gICAgICAgICAgICBOID0gMTYgLyAxMTYsXG4gICAgICAgICAgICBLID0gMC4wMDg4NTYsXG4gICAgICAgICAgICBMID0gNy43ODcwMzc7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIFg6IChYMyA+IEsgPyBYMyA6IChYIC0gTikgLyBMKSAqIFIuWCxcbiAgICAgICAgICAgIFk6IChZMyA+IEsgPyBZMyA6IChZIC0gTikgLyBMKSAqIFIuWSxcbiAgICAgICAgICAgIFo6IChaMyA+IEsgPyBaMyA6IChaIC0gTikgLyBMKSAqIFIuWlxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHN0YXRpYyByZ2IyTGFiIChyZ2IpIHtcbiAgICAgICAgdmFyIFhZWiA9IENvbG9yQ29udmVydGVyLnJnYjJYWVoocmdiKTtcblxuICAgICAgICByZXR1cm4gQ29sb3JDb252ZXJ0ZXIuWFlaMkxhYihYWVopO1xuICAgIH1cblxuICAgIHN0YXRpYyBMYWIycmdiIChMYWIpIHtcbiAgICAgICAgdmFyIFhZWiA9IENvbG9yQ29udmVydGVyLkxhYjJYWVooTGFiKTtcblxuICAgICAgICByZXR1cm4gQ29sb3JDb252ZXJ0ZXIuWFlaMnJnYihYWVopO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbWl0VmFsdWUodmFsdWUsIG1pbiwgbWF4KSB7XG4gICAgLy8gcmV0dXJuIE1hdGgubWF4KG1pbiwgTWF0aC5taW4obWF4LCB2YWx1ZSkpOyAvLyBmYXN0ZXI/P1xuICAgIHJldHVybiAodmFsdWUgPiBtYXggPyBtYXggOiB2YWx1ZSA8IG1pbiA/IG1pbiA6IHZhbHVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEx1bWluYW5jZShyZ2IsIG5vcm1hbGl6ZWQpIHtcbiAgICB2YXIgZGl2ID0gbm9ybWFsaXplZCA/IDEgOiAyNTUsXG4gICAgICAgIFJHQiA9IFtyZ2IuciAvIGRpdiwgcmdiLmcgLyBkaXYsIHJnYi5iIC8gZGl2XTtcblxuICAgIGZvciAodmFyIGkgPSBSR0IubGVuZ3RoOyBpLS07KSB7XG4gICAgICAgIFJHQltpXSA9IFJHQltpXSA8PSAwLjAzOTI4ID8gUkdCW2ldIC8gMTIuOTIgOiBNYXRoLnBvdygoKFJHQltpXSArIDAuMDU1KSAvIDEuMDU1KSwgMi40KTtcbiAgICB9XG4gICAgcmV0dXJuICgobHVtaW5hbmNlLnIgKiBSR0JbMF0pICsgKGx1bWluYW5jZS5nICogUkdCWzFdKSArIChsdW1pbmFuY2UuYiAqIFJHQlsyXSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29sb3JBc1JHQiAoY29sb3IpIHtcbiAgICAvLyBDcmVhdGUgYSB0ZXN0IGVsZW1lbnQgdG8gYXBwbHkgYSBDU1MgY29sb3IgYW5kIHJldHJpZXZlXG4gICAgLy8gYSBub3JtYWxpem
23459VkIHZhbHVlIGZyb20uXG4gICAgbGV0IHRlc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0ZXN0LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGNvbG9yO1xuXG4gICAgLy8gQ2hyb21lIHJlcXVpcmVzIHRoZSBlbGVtZW50IHRvIGJlIGluIERPTSBmb3Igc3R5bGVzIHRvIGJlIGNvbXB1dGVkLlxuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGVzdCk7XG5cbiAgICAvLyBHZXQgdGhlIGNvbXB1dGVkIHN0eWxlIGZyb20gdGhlIGJyb3dzZXIsIGluIHRoZSBmb3JtYXQgb2ZcbiAgICAvLyByZ2IoeCwgeCwgeClcbiAgICBsZXQgbm9ybWFsaXplZCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRlc3QpLmJhY2tncm91bmRDb2xvcjtcblxuICAgIC8vIEluIGNlcnRhaW4gY2FzZXMgZ2V0Q29tcHV0ZWRTdHlsZSgpIG1heSByZXR1cm5cbiAgICAvLyAndHJhbnNwYXJlbnQnIGFzIGEgdmFsdWUsIHdoaWNoIGlzIHVzZWxlc3MoPykgZm9yIHRoZSBjdXJyZW50XG4gICAgLy8gY29sb3IgcGlja2VyLiBBY2NvcmRpbmcgdG8gc3BlY2lmaWNhdGlvbnMsIHRyYW5zcGFyZW50XG4gICAgLy8gaXMgYSBibGFjayB3aXRoIDAgYWxwaGEgLSByZ2JhKDAsIDAsIDAsIDApIC0gYnV0IGJlY2F1c2VcbiAgICAvLyB0aGUgcGlja2VyIGRvZXMgbm90IGN1cnJlbnRseSBoYW5kbGUgYWxwaGEsIHdlIHJldHVybiB0aGVcbiAgICAvLyBibGFjayB2YWx1ZS5cbiAgICBpZiAobm9ybWFsaXplZCA9PT0gJ3RyYW5zcGFyZW50Jykge1xuICAgICAgICBub3JtYWxpemVkID0gJ3JnYigwLCAwLCAwKSc7XG4gICAgfVxuXG4gICAgLy8gR2FyYmFnZSBjb2xsZWN0aW9uXG4gICAgdGVzdC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRlc3QpO1xuXG4gICAgcmV0dXJuIG5vcm1hbGl6ZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRWYWx1ZVJhbmdlcyh0eXBlKSB7XG4gICAgaWYgKCF0eXBlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZVJhbmdlcztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiB2YWx1ZVJhbmdlc1t0eXBlXTtcbiAgICB9XG59XG4iLCJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZsb2F0IHtcbiAgICBjb25zdHJ1Y3RvciAodmFsdWUpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIGdldFN0cmluZyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlLnRvRml4ZWQoMyk7XG4gICAgfVxuXG4gICAgdW5pZm9ybVR5cGUgKCkge1xuICAgICAgICByZXR1cm4gJ2Zsb2F0JztcbiAgICB9XG5cbiAgICB1bmlmb3JtVmFsdWUgKCkge1xuICAgICAgICByZXR1cm4gW3RoaXMudmFsdWVdO1xuICAgIH1cblxuICAgIHVuaWZvcm1NZXRob2QgKCkge1xuICAgICAgICByZXR1cm4gJzFmJztcbiAgICB9XG59XG4iLCJpbXBvcnQgVmVjdG9yIGZyb20gJy4vVmVjdG9yJztcblxuLy8gVE9ETzpcbi8vICAgICAgLSBnZW5lcmFsaXplIHRoaXMgZm9yIG1hdDIsIG1hdDMgYW5kIG1hdDRcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWF0cml4IHtcbiAgICBjb25zdHJ1Y3RvcihtLCB0eXBlKSB7XG4gICAgICAgIHRoaXMuZGltID0gMztcbiAgICAgICAgdGhpcy52YWx1ZSA9IFtcbiAgICAgICAgICAgIFsxLCAwLCAwXSxcbiAgICAgICAgICAgIFswLCAxLCAwXSxcbiAgICAgICAgICAgIFswLCAwLCAxXV07XG4gICAgICAgIGlmIChtKSB7XG4gICAgICAgICAgICB0aGlzLnNldChtLCB0eXBlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldCAobSwgdHlwZSkge1xuICAgICAgICBpZiAobS52YWx1ZVswXVswXSkge1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IG0udmFsdWU7XG4gICAgICAgICAgICB0aGlzLmRpbSA9IG0uZGltO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG1bMF1bMF0pIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBtO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcm90YXRlWCAodGhldGEpIHtcbiAgICAgICAgbGV0IGMgPSBNYXRoLmNvcyh0aGV0YSk7XG4gICAgICAgIGxldCBzID0gTWF0aC5zaW4odGhldGEpO1xuICAgICAgICBsZXQgVCA9IFtcbiAgICAgICAgICAgIFsxLCAwLCAwXSxcbiAgICAgICAgICAgIFswLCBjLCAtc10sXG4gICAgICAgICAgICBbMCwgcywgY11dO1xuXG4gICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLmdldFRyYW5zZm9ybShUKTtcbiAgICB9XG5cbiAgICByb3RhdGVZICh0aGV0YSkge1xuICAgICAgICBsZXQgYyA9IE1hdGguY29zKHRoZXRhKTtcbiAgICAgICAgbGV0IHMgPSBNYXRoLnNpbih0aGV0YSk7XG4gICAgICAgIGxldCBUID0gW1xuICAgICAgICAgICAgW2MsIDAsIHNdLFxuICAgICAgICAgICAgWzAsIDEsIDBdLFxuICAgICAgICAgICAgWy1zLCAwLCBjXV07XG5cbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuZ2V0VHJhbnNmb3JtKFQpO1xuICAgIH1cblxuICAgIGdldE11bHQgKHYpIHtcbiAgICAgICAgaWYgKHZbMF1bMF0gfHwgKHYudmFsdWUgJiYgdi52YWx1ZVswXVswXSkpIHtcbiAgICAgICAgICAgIC8vIFRPRE86IHdoYXQgSWYgdiBpcyBhIG1hdHJpeFxuICAgICAgICAgICAgY29uc29sZS5sb2coJ1RPRE86IHdoYXQgSWYgdiBpcyBhIG1hdHJpeCcpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gSWYgdiBpcyBhIHZlY3RvclxuICAgICAgICAgICAgbGV0IEEgPSBuZXcgVmVjdG9yKHYpO1xuICAgICAgICAgICAgbGV0IEIgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQS5kaW07IGkrKykge1xuICAgICAgICAgICAgICAgIEIucHVzaChBLnZhbHVlWzBdICogdGhpcy52YWx1ZVtpXVswXSArIEEudmFsdWVbMV0gKiB0aGlzLnZhbHVlW2ldWzFdICsgQS52YWx1ZVsyXSAqIHRoaXMudmFsdWVbaV1bMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBWZWN0b3IoQik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRUcmFuc2Zvcm0gKG0pIHtcbiAgICAgICAgbGV0IG5ld01hdHJpeCA9IFtdO1xuICAgICAgICBmb3IgKGxldCByb3cgaW4gbSkge1xuICAgICAgICAgICAgbGV0IHQgPSBtW3Jvd107XG4gICAgICAgICAgICBsZXQgbm
23459V3Um93ID0gW107XG4gICAgICAgICAgICBuZXdSb3cucHVzaCh0WzBdICogdGhpcy52YWx1ZVswXVswXSArIHRbMV0gKiB0aGlzLnZhbHVlWzFdWzBdICsgdFsyXSAqIHRoaXMudmFsdWVbMl1bMF0pO1xuICAgICAgICAgICAgbmV3Um93LnB1c2godFswXSAqIHRoaXMudmFsdWVbMF1bMV0gKyB0WzFdICogdGhpcy52YWx1ZVsxXVsxXSArIHRbMl0gKiB0aGlzLnZhbHVlWzJdWzFdKTtcbiAgICAgICAgICAgIG5ld1Jvdy5wdXNoKHRbMF0gKiB0aGlzLnZhbHVlWzBdWzJdICsgdFsxXSAqIHRoaXMudmFsdWVbMV1bMl0gKyB0WzJdICogdGhpcy52YWx1ZVsyXVsyXSk7XG4gICAgICAgICAgICBuZXdNYXRyaXgucHVzaChuZXdSb3cpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXdNYXRyaXg7XG4gICAgfVxuXG4gICAgZ2V0SW52KCkge1xuICAgICAgICBsZXQgTSA9IG5ldyBNYXRyaXgoKTtcbiAgICAgICAgbGV0IGRldGVybWluYW50ID0gdGhpcy52YWx1ZVswXVswXSAqICh0aGlzLnZhbHVlWzFdWzFdICogdGhpcy52YWx1ZVsyXVsyXSAtIHRoaXMudmFsdWVbMl1bMV0gKiB0aGlzLnZhbHVlWzFdWzJdKSAtXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZVswXVsxXSAqICh0aGlzLnZhbHVlWzFdWzBdICogdGhpcy52YWx1ZVsyXVsyXSAtIHRoaXMudmFsdWVbMV1bMl0gKiB0aGlzLnZhbHVlWzJdWzBdKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZVswXVsyXSAqICh0aGlzLnZhbHVlWzFdWzBdICogdGhpcy52YWx1ZVsyXVsxXSAtIHRoaXMudmFsdWVbMV1bMV0gKiB0aGlzLnZhbHVlWzJdWzBdKTtcbiAgICAgICAgbGV0IGludmRldCA9IDEgLyBkZXRlcm1pbmFudDtcbiAgICAgICAgTS52YWx1ZVswXVswXSA9ICh0aGlzLnZhbHVlWzFdWzFdICogdGhpcy52YWx1ZVsyXVsyXSAtIHRoaXMudmFsdWVbMl1bMV0gKiB0aGlzLnZhbHVlWzFdWzJdKSAqIGludmRldDtcbiAgICAgICAgTS52YWx1ZVswXVsxXSA9IC0odGhpcy52YWx1ZVswXVsxXSAqIHRoaXMudmFsdWVbMl1bMl0gLSB0aGlzLnZhbHVlWzBdWzJdICogdGhpcy52YWx1ZVsyXVsxXSkgKiBpbnZkZXQ7XG4gICAgICAgIE0udmFsdWVbMF1bMl0gPSAodGhpcy52YWx1ZVswXVsxXSAqIHRoaXMudmFsdWVbMV1bMl0gLSB0aGlzLnZhbHVlWzBdWzJdICogdGhpcy52YWx1ZVsxXVsxXSkgKiBpbnZkZXQ7XG4gICAgICAgIE0udmFsdWVbMV1bMF0gPSAtKHRoaXMudmFsdWVbMV1bMF0gKiB0aGlzLnZhbHVlWzJdWzJdIC0gdGhpcy52YWx1ZVsxXVsyXSAqIHRoaXMudmFsdWVbMl1bMF0pICogaW52ZGV0O1xuICAgICAgICBNLnZhbHVlWzFdWzFdID0gKHRoaXMudmFsdWVbMF1bMF0gKiB0aGlzLnZhbHVlWzJdWzJdIC0gdGhpcy52YWx1ZVswXVsyXSAqIHRoaXMudmFsdWVbMl1bMF0pICogaW52ZGV0O1xuICAgICAgICBNLnZhbHVlWzFdWzJdID0gLSh0aGlzLnZhbHVlWzBdWzBdICogdGhpcy52YWx1ZVsxXVsyXSAtIHRoaXMudmFsdWVbMV1bMF0gKiB0aGlzLnZhbHVlWzBdWzJdKSAqIGludmRldDtcbiAgICAgICAgTS52YWx1ZVsyXVswXSA9ICh0aGlzLnZhbHVlWzFdWzBdICogdGhpcy52YWx1ZVsyXVsxXSAtIHRoaXMudmFsdWVbMl1bMF0gKiB0aGlzLnZhbHVlWzFdWzFdKSAqIGludmRldDtcbiAgICAgICAgTS52YWx1ZVsyXVsxXSA9IC0odGhpcy52YWx1ZVswXVswXSAqIHRoaXMudmFsdWVbMl1bMV0gLSB0aGlzLnZhbHVlWzJdWzBdICogdGhpcy52YWx1ZVswXVsxXSkgKiBpbnZkZXQ7XG4gICAgICAgIE0udmFsdWVbMl1bMl0gPSAodGhpcy52YWx1ZVswXVswXSAqIHRoaXMudmFsdWVbMV1bMV0gLSB0aGlzLnZhbHVlWzFdWzBdICogdGhpcy52YWx1ZVswXVsxXSkgKiBpbnZkZXQ7XG4gICAgICAgIHJldHVybiBNO1xuICAgIH1cbn1cbiIsImV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlY3RvciB7XG4gICAgY29uc3RydWN0b3IgKHZlYywgdHlwZSkge1xuICAgICAgICB0aGlzLnZhbHVlID0gWzAsMF07XG4gICAgICAgIHRoaXMuZGltID0gMjtcbiAgICAgICAgdGhpcy5zZXQodmVjLCB0eXBlKTtcbiAgICB9XG5cbiAgICBzZXQgKHZlYywgdHlwZSkge1xuICAgICAgICBpZiAodHlwZW9mIHZlYyA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHR5cGUgPSB0eXBlIHx8ICd2ZWMyJztcbiAgICAgICAgICAgIHRoaXMuc2V0KFt2ZWNdLCB0eXBlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgdmVjID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgbGV0IHBhcnRzID0gdmVjLnJlcGxhY2UoLyg/OiN8XFwpfFxcXXwlKS9nLCAnJykuc3BsaXQoJygnKTtcbiAgICAgICAgICAgIGxldCBzdHJWYWx1ZXMgPSAocGFydHNbMV0gfHwgcGFydHNbMF0ucmVwbGFjZSgvKFxcWykvZywgJycpKS5zcGxpdCgvLFxccyovKTtcbiAgICAgICAgICAgIHR5cGUgPSB0eXBlIHx8IChwYXJ0c1sxXSA/IHBhcnRzWzBdLnN1YnN0cigwLCA0KSA6ICd2ZWMnICsgc3RyVmFsdWVzLmxlbmd0aCk7XG4gICAgICAgICAgICBsZXQgdmFsdWVzID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBpIGluIHN0clZhbHVlcykge1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHBhcnNlRmxvYXQoc3RyVmFsdWVzW2ldKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldCh2YWx1ZXMsIHR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHZlYykge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmVjKSkge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBbXTtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlLmxlbmd0aCA9IDA7XG4gICAgICAgICAgICAgICAgdGhpcy5kaW0gPSB0eXBlID8gTnVtYmVyKHR5cGUuc3Vic3RyKDMsIDQpKSA6IHZlYy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgbGV0IGZpbGxlciA9IHZlYy5sZW5ndGggPT09IDEgPyB2ZWNbMF0gOiAwO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5kaW07IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlLnB1c2godmVjW2ldIHx8IGZpbGxlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodmVjLmRpbSkge1xuICAgICAgICAgICAgICAgI
23459HRoaXMudmFsdWUgPSB2ZWMudmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5kaW0gPSB2ZWMuZGltO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0IHggKHYpIHtcbiAgICAgICAgdGhpcy52YWx1ZVswXSA9IHY7XG4gICAgfVxuXG4gICAgc2V0IHkgKHYpIHtcbiAgICAgICAgdGhpcy52YWx1ZVsxXSA9IHY7XG4gICAgfVxuXG4gICAgc2V0IHogKHYpIHtcbiAgICAgICAgaWYgKHRoaXMuZGltIDwgMykge1xuICAgICAgICAgICAgd2hpbGUgKHRoaXMuZGltIDwgMykge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUucHVzaCgwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZGltID0gMztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZhbHVlWzJdID0gdjtcbiAgICB9XG5cbiAgICBzZXQgdyAodikge1xuICAgICAgICBpZiAodGhpcy5kaW0gPCA0KSB7XG4gICAgICAgICAgICB3aGlsZSAodGhpcy5kaW0gPCA0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZS5wdXNoKDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5kaW0gPSA0O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmFsdWVbM10gPSB2O1xuICAgIH1cblxuICAgIGdldCB4ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVbMF0gfHwgMC4wO1xuICAgIH1cblxuICAgIGdldCB5ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVbMV0gfHwgMC4wO1xuICAgIH1cblxuICAgIGdldCB6ICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVbMl0gfHwgMC4wIDtcbiAgICB9XG5cbiAgICBnZXQgdyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlWzNdIHx8IDAuMDtcbiAgICB9XG5cbiAgICBnZXRTdHJpbmcodHlwZSkge1xuICAgICAgICB0eXBlID0gdHlwZSB8fCAndmVjJyArIHRoaXMuZGltO1xuXG4gICAgICAgIGxldCBsZW4gPSB0aGlzLmRpbTtcbiAgICAgICAgbGV0IHN0ciA9ICcnO1xuICAgICAgICBsZXQgaGVhZCA9IHR5cGUgKyAnKCc7XG4gICAgICAgIGxldCBlbmQgPSAnKSc7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgICAgICAgIGhlYWQgPSAnWyc7XG4gICAgICAgICAgICBlbmQgPSAnXSc7XG4gICAgICAgICAgICBsZW4gPSB0aGlzLmRpbTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxlbiA9IE51bWJlcih0eXBlLnN1YnN0cigzLCA0KSk7XG4gICAgICAgIH1cblxuICAgICAgICBzdHIgPSBoZWFkO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBzdHIgKz0gdGhpcy52YWx1ZVtpXS50b0ZpeGVkKDMpO1xuICAgICAgICAgICAgaWYgKGkgIT09IGxlbiAtIDEpIHtcbiAgICAgICAgICAgICAgICBzdHIgKz0gJywnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdHIgKz0gZW5kO1xuICAgIH1cblxuICAgIHVuaWZvcm1UeXBlICgpIHtcbiAgICAgICAgcmV0dXJuICd2ZWMnICsgdGhpcy5kaW07XG4gICAgfVxuXG4gICAgdW5pZm9ybVZhbHVlICgpIHtcbiAgICAgICAgdmFyIGFyciA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGltOyBpKyspIHtcbiAgICAgICAgICAgIGFyci5wdXNoKHRoaXMudmFsdWVbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgfVxuXG4gICAgdW5pZm9ybU1ldGhvZCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRpbSArICdmJztcbiAgICB9XG5cbiAgICAvLyBWRUNUT1IgT1BFUkFUSU9OU1xuXG4gICAgYWRkICh2KSB7XG4gICAgICAgIGlmICh0eXBlb2YgdiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5kaW07IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWVbaV0gPSB0aGlzLnZhbHVlW2ldICsgdjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBBID0gbmV3IFZlY3Rvcih2KTtcbiAgICAgICAgICAgIGxldCBsaW0gPSBNYXRoLm1pbih0aGlzLmRpbSwgQS5kaW0pO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW07IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWVbaV0gPSB0aGlzLnZhbHVlW2ldICsgQS52YWx1ZVtpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN1YiAodikge1xuICAgICAgICBpZiAodHlwZW9mIHYgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGltOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlW2ldID0gdGhpcy52YWx1ZVtpXSAtIHY7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgQSA9IG5ldyBWZWN0b3Iodik7XG4gICAgICAgICAgICBsZXQgbGltID0gTWF0aC5taW4odGhpcy5kaW0sIEEuZGltKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGltOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlW2ldID0gdGhpcy52YWx1ZVtpXSAtIEEudmFsdWVbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBtdWx0ICh2KSB7XG4gICAgICAgIGlmICh0eXBlb2YgdiA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIC8vIE11bGl0cGx5IGJ5IHNjYWxhclxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmRpbTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZVtpXSA9IHRoaXMudmFsdWVbaV0gKiB2O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gTXVsdGlwbHkgdHdvIHZlY3RvcnNcbiAgICAgICAgICAgIGxldCBBID0gbmV3IFZlY3Rvcih2KTtcbiAgICAgICAgICAgIGxldCBsaW0gPSBNYXRoLm1pbih0aGlzLmRpbSwgQS5kaW0pO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW07IGkrKykge1xuICAgICAgICAgICAgICAgI
23459HRoaXMudmFsdWVbaV0gPSB0aGlzLnZhbHVlW2ldICogQS52YWx1ZVtpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRpdiAodikge1xuICAgICAgICBpZiAodHlwZW9mIHYgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAvLyBNdWxpdHBseSBieSBzY2FsYXJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5kaW07IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsdWVbaV0gPSB0aGlzLnZhbHVlW2ldIC8gdjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIE11bHRpcGx5IHR3byB2ZWN0b3JzXG4gICAgICAgICAgICBsZXQgQSA9IG5ldyBWZWN0b3Iodik7XG4gICAgICAgICAgICBsZXQgbGltID0gTWF0aC5taW4odGhpcy5kaW0sIEEuZGltKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGltOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlW2ldID0gdGhpcy52YWx1ZVtpXSAvIEEudmFsdWVbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBub3JtYWxpemUgKCkge1xuICAgICAgICBsZXQgbCA9IHRoaXMuZ2V0TGVuZ3RoKCk7XG4gICAgICAgIHRoaXMuZGl2KGwpO1xuICAgIH1cblxuICAgIGdldEFkZCAodikge1xuICAgICAgICB2YXIgQSA9IG5ldyBWZWN0b3IodGhpcyk7XG4gICAgICAgIEEuYWRkKHYpO1xuICAgICAgICByZXR1cm4gQTtcbiAgICB9XG5cbiAgICBnZXRTdWIgKHYpIHtcbiAgICAgICAgdmFyIEEgPSBuZXcgVmVjdG9yKHRoaXMpO1xuICAgICAgICBBLnN1Yih2KTtcbiAgICAgICAgcmV0dXJuIEE7XG4gICAgfVxuXG4gICAgZ2V0TXVsdCAodikge1xuICAgICAgICB2Y
23459XIgQSA9IG5ldyBWZWN0b3IodGhpcyk7XG4gICAgICAgIEEubXVsdCh2KTtcbiAgICAgICAgcmV0dXJuIEE7XG4gICAgfVxuXG4gICAgZ2V0RGl2ICh2KSB7XG4gICAgICAgIHZhciBBID0gbmV3IFZlY3Rvcih0aGlzKTtcbiAgICAgICAgQS5kaXYodik7XG4gICAgICAgIHJldHVybiBBO1xuICAgIH1cblxuICAgIGdldExlbmd0aFNxICgpIHtcbiAgICAgICAgaWYgKHRoaXMuZGltID09PSAyKSB7XG4gICAgICAgICAgICByZXR1cm4gKHRoaXMudmFsdWVbMF0gKiB0aGlzLnZhbHVlWzBdICsgdGhpcy52YWx1ZVsxXSAqIHRoaXMudmFsdWVbMV0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuICh0aGlzLnZhbHVlWzBdICogdGhpcy52YWx1ZVswXSArIHRoaXMudmFsdWVbMV0gKiB0aGlzLnZhbHVlWzFdICsgdGhpcy52YWx1ZVsyXSAqIHRoaXMudmFsdWVbMl0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0TGVuZ3RoICgpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguc3FydCh0aGlzLmdldExlbmd0aFNxKCkpO1xuICAgIH1cbn1cbiJdfQ==
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.