PageSourceSearch

https://www.learnpdc.org/IntermediatePDC/_static/runestone.0dcb9b7269d492ae.bundle.js?v=32D195FA

js learnpdc.org collected 2026-10-08 17:51:35 UTC 373,649 bytes, 4,060 lines download raw bytes

1(self["webpackChunkWebComponents"] = self["webpackChunkWebComponents"] || []).push([["runestone"],{
2
3/***/ 88288:
4/*!*************************************************!*\
5  !*** ./runestone/common/css/presenter_mode.css ***!
6  \*************************************************/
7/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8
9"use strict";
10__webpack_require__.r(__webpack_exports__);
11// extracted by mini-css-extract-plugin
12
13
14/***/ }),
15
16/***/ 64778:
17/*!********************************************************************!*\
18  !*** ./runestone/common/css/runestone-custom-sphinx-bootstrap.css ***!
19  \********************************************************************/
20/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
21
22"use strict";
23__webpack_require__.r(__webpack_exports__);
24// extracted by mini-css-extract-plugin
25
26
27/***/ }),
28
29/***/ 88874:
30/*!**************************************************!*\
31  !*** ./runestone/common/css/user-highlights.css ***!
32  \**************************************************/
33/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
34
35"use strict";
36__webpack_require__.r(__webpack_exports__);
37// extracted by mini-css-extract-plugin
38
39
40/***/ }),
41
42/***/ 23746:
43/*!*********************************************!*\
44  !*** ./runestone/matrixeq/css/matrixeq.css ***!
45  \*********************************************/
46/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
47
48"use strict";
49__webpack_require__.r(__webpack_exports__);
50// extracted by mini-css-extract-plugin
51
52
53/***/ }),
54
55/***/ 86324:
56/*!******************************************************!*\
57  !*** ./runestone/webgldemo/css/webglinteractive.css ***!
58  \******************************************************/
59/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
60
61"use strict";
62__webpack_require__.r(__webpack_exports__);
63// extracted by mini-css-extract-plugin
64
65
66/***/ }),
67
68/***/ 21294:
69/*!******************************************!*\
70  !*** ./runestone/common/js/bookfuncs.js ***!
71  \******************************************/
72/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
73
74"use strict";
75__webpack_require__.r(__webpack_exports__);
76/* harmony export */ __webpack_require__.d(__webpack_exports__, {
77/* harmony export */   "pageProgressTracker": () => (/* binding */ pageProgressTracker)
78/* harmony export */ });
79/**
80 *
81 * User: bmiller
82 * Original: 2011-04-20
83 * Date: 2019-06-14
84 * Time: 2:01 PM
85 * This change marks the beginning of version 4.0 of the runestone components
86 * Login/logout is no longer handled through javascript but rather server side.
87 * Many of the components depend on the runestone:login event so we will keep that
88 * for now to keep the churn fairly minimal.
89 */
90
91/*
92
93 Copyright (C) 2011  Brad Miller  [email protected]
94
95 This program is free software: you can redistribute it and/or modify
96 it under the terms of the GNU General Public License as published by
97 the Free Software Foundation, either version 3 of the License, or
98 (at your option) any later version.
99
100 This program is distributed in the hope that it will be useful,
101 but WITHOUT ANY WARRANTY; without even the implied warranty of
102 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
103 GNU General Public License for more details.
104
105 You should have received a copy of the GNU General Public License
106 along with this program.  If not, see <http://www.gnu.org/licenses/>.
107
108 */
109
110//
111// Page decoration functions
112//
113
114function addReadingList() {
115    if (eBookConfig.readings) {
116        var l, nxt, path_parts, nxt_link;
117        let cur_path_parts = window.location.pathname.split("/");
118        let name =
119            cur_path_parts[cur_path_parts.length - 2] +
120            "/" +
121            cur_path_parts[cur_path_parts.length - 1];
122        let position = eBookConfig.readings.indexOf(name);
123        let num_readings = eBookConfig.readings.length;
124        if (position == eBookConfig.readings.length - 1) {
125            // no more readings
126            l = $("<div />", {
127                text: `Finished reading assignment. Page ${num_readings} of ${num_readings}.`,
128            });
129        } else if (position >= 0) {
130            // get next name
131            nxt = eBookConfig.readings[position + 1];
132            path_parts = cur_path_parts.slice(0, cur_path_parts.length - 2);
133            path_parts.push(nxt);
134            nxt_link = path_parts.join("/");
135            l = $("<a />", {
136                name: "link",
137                class: "btn btn-lg ' + 'buttonConfirmCompletion'",
138                href: nxt_link,
139                text: `Continue to page ${
140                    position + 2
141                } of ${num_readings} in the reading assignment.`,
142            });
143        } else {
144            l = $("<div />", {
145                text: "This page is not part of the last reading assignment you visited.",
146            });
147        }
148        $("#main-content").append(l);
149    }
150}
151
152function timedRefresh() {
153    var timeoutPeriod = 900000; // 75 minutes
154    $(document).on("idle.idleTimer", function () {
155        // After timeout period send the user back to the index.  This will force a login
156        // if needed when they want to go to a particular page.  This may not be perfect
157        // but its an easy way to make sure laptop users are properly logged in when they
158        // take quizzes and save stuff.
159        if (location.href.indexOf("index.html") < 0) {
160            console.log("Idle timer - " + location.pathname);
161            location.href =
162                eBookConfig.app +
163                "/default/user/login?_next=" +
164                location.pathname +
165                location.search;
166        }
167    });
168    $.idleTimer(timeoutPeriod);
169}
170
171class PageProgressBar {
172    constructor(actDict) {
173        this.possible = 0;
174        this.total = 1;
175        if (actDict && Object.keys(actDict).length > 0) {
176            this.activities = actDict;
177        } else {
178            let activities = { page: 0 };
179            $(".runestone").each(function (idx, e) {
180                activities[e.firstElementChild.id] = 0;
181            });
182            this.activities = activities;
183        }
184        this.calculateProgress();
185        if (
186            window.location.pathname.match(
187                /.*(index.html|toctree.html|Exercises.html|search.html)$/i
188            )
189        ) {
190            $("#scprogresscontainer").hide();
191        }
192        this.renderProgress();
193    }
194
195    calculateProgress() {
196        for (let k in this.activities) {
197            if (k !== undefined) {
198                this.possible++;
199                if (this.activities[k] > 0) {
200                    this.total++;
201                }
202            }
203        }
204    }
205
206    renderProgress() {
207        let value = 0;
208        $("#scprogresstotal").text(this.total);
209        $("#scprogressposs").text(this.possible);
210        try {
211            value = (100 * this.total) / this.possible;
212        } catch (e) {
213            value = 0;
214        }
215        $("#subchapterprogress").progressbar({
216            value: value,
217        });
218        if (!eBookConfig.isLoggedIn) {
219            $("#subchapterprogress>div").addClass("loggedout");
220        }
221    }
222
223    updateProgress(div_id) {
224        this.activities[div_id]++;
225        // Only update the progress bar on the first interaction with an object.
226        if (this.activities[div_id] === 1) {
227            this.total++;
228            let val = (100 * this.total) / this.possible;
229            $("#scprogresstotal").text(this.total);
230            $("#scprogressposs").text(this.possible);
231            $("#subchapterprogress").progressbar("option", "value", val);
232            if (
233                val == 100.0 &&
234                $("#completionButton").text().toLowerCase() ===
235                    "mark as completed"
236            ) {
237                $("#completionButton").click();
238            }
239        }
240    }
241}
242
243var pageProgressTracker = {};
244
245async function handlePageSetup() {
246    var mess;
247    if (eBookConfig.useRunestoneServices) {
248        let headers = new Headers({
249            "Content-type": "application/json; charset=utf-8",
250            Accept: "application/json",
251        });
252        let data = { timezoneoffset: new Date().getTimezoneOffset() / 60 };
253        let request = new Request(
254            `${eBookConfig.new_server_prefix}/logger/set_tz_offset`,
255            {
256                method: "POST",
257                body: JSON.stringify(data),
258                headers: headers,
259            }
260        );
261        try {
262            let response = await fetch(request);
263            if (!response.ok) {
264                console.error(`Failed to set timezone! ${response.statusText}`);
265            }
266            data = await response.json();
267        } catch (e) {
268            console.error(`Error setting timezone ${e}`);
269        }
270    }
271    console.log(`This page served by ${eBookConfig.served_by}`);
272    if (eBookConfig.isLoggedIn) {
273        mess = `username: ${eBookConfig.username}`;
274        if (!eBookConfig.isInstructor) {
275            $("#ip_dropdown_link").remove();
276            $("#inst_peer_link").remove();
277        }
278        $(document).trigger("runestone:login");
279        addReadingList();
280        // Avoid the timedRefresh on the grading page.
281        if (
282            window.location.pathname.indexOf("/admin/grading") == -1 &&
283            window.location.pathname.indexOf("/peer/") == -1
284        ) {
285            timedRefresh();
286        }
287    } else {
288        mess = "Not logged in";
289        $(document).trigger("runestone:logout");
290        let bw = document.getElementById("browsing_warning");
291        if (bw) {
292            bw.innerHTML =
293                "<p class='navbar_message'>Saving and Logging are Disabled</p>";
294        }
295        let aw = document.getElementById("ad_warning");
296        if (aw) {
297            aw.innerHTML =
298                "<p class='navbar_message'>🚫 Log-in to Remove <a href='/runestone/default/ads'>Ads!</a> 🚫 &nbsp;</p>";
299        }
300    }
301    $(".loggedinuser").html(mess);
302
303    pageProgressTracker = new PageProgressBar(eBookConfig.activities);
304    notifyRunestoneComponents();
305}
306
307function setupNavbarLoggedIn() {
308    $("#profilelink").show();
309    $("#passwordlink").show();
310    $("#registerlink").hide();
311    $("li.loginout").html(
312        '<a href="' + eBookConfig.app + '/default/user/logout">Log Out</a>'
313    );
314}
315$(document).on("runestone:login", setupNavbarLoggedIn);
316
317function setupNavbarLoggedOut() {
318    if (eBookConfig.useRunestoneServices) {
319        console.log("setup navbar for logged out");
320        $("#registerlink").show();
321        $("#profilelink").hide();
322        $("#passwordlink").hide();
323        $("#ip_dropdown_link").hide();
324        $("#inst_peer_link").hide();
325        $("li.loginout").html(
326            '<a href="' + eBookConfig.app + '/default/user/login">Login</a>'
327        );
328        $(".footer").html("user not logged in");
329    }
330}
331$(document).on("runestone:logout", setupNavbarLoggedOut);
332
333function notifyRunestoneComponents() {
334    // Runestone components wait until login process is over to load components because of storage issues. This triggers the `dynamic import machinery`, which then sends the login complete signal when this and all dynamic imports are finished.
335    $(document).trigger("runestone:pre-login-complete");
336}
337
338function placeAdCopy() {
339    if (typeof showAd !== "undefined" && showAd) {
340        let adNum = Math.floor(Math.random() * 2) + 1;
341        let adBlock = document.getElementById(`adcopy_${adNum}`);
342        let rsElements = document.querySelectorAll(".runestone");
343        if (rsElements.length > 0) {
344            let randomIndex = Math.floor(Math.random() * rsElements.length);
345            rsElements[randomIndex].after(adBlock)
346            adBlock.style.display = "block";
347        }
348    }
349}
350
351// initialize stuff
352$(function () {
353    if (eBookConfig) {
354        handlePageSetup();
355        placeAdCopy();
356    } else {
357        if (typeof eBookConfig === "undefined") {
358            console.log(
359                "eBookConfig is not defined.  This page must not be set up for Runestone"
360            );
361        }
362    }
363});
364
365// misc stuff
366// todo:  This could be further distributed but making a video.js file just for one function seems dumb.
367window.addEventListener("load", function () {
368    // add the video play button overlay image
369    $(".video-play-overlay").each(function () {
370        $(this).css(
371            "background-image",
372            "url('{{pathto('_static/play_overlay_icon.png', 1)}}')"
373        );
374    });
375
376    // This function is needed to allow the dropdown search bar to work;
377    // The default behaviour is that the dropdown menu closes when something in
378    // it (like the search bar) is clicked
379    $(function () {
380        // Fix input element click problem
381        $(".dropdown input, .dropdown label").click(function (e) {
382            e.stopPropagation();
383        });
384    });
385
386    // re-write some urls
387    // This is tricker than it looks and you have to obey the rules for # anchors
388    // The #anchors must come after the query string as the server basically ignores any part
389    // of a url that comes after # - like a comment...
390    if (location.href.includes("mode=browsing")) {
391        let queryString = "?mode=browsing";
392        document.querySelectorAll("a").forEach((link) => {
393            let anchorText = "";
394            if (link.href.includes("books/published") && ! link.href.includes("?mode=browsing")) {
395                if (link.href.includes("#")) {
396                    let aPoint = link.href.indexOf("#");
397                    anchorText = link.href.substring(aPoint);
398                    link.href = link.href.substring(0,aPoint);
399                }
400                link.href = link.href.includes("?")
401                    ? link.href + queryString.replace("?", "&") + anchorText
402                    : link.href + queryString + anchorText;
403            }
404        });
405    }
406});
407
408
409/***/ }),
410
411/***/ 26886:
412/*!**************************************************!*\
413  !*** ./runestone/common/js/jquery.idle-timer.js ***!
414  \**************************************************/
415/***/ (() => {
416
417/*!
418 * jQuery idleTimer plugin
419 * version 0.9.100511
420 * by Paul Irish.
421 *   http://github.com/paulirish/yui-misc/tree/
422 * MIT license
423
424 * adapted from YUI idle timer by nzakas:
425 *   http://github.com/nzakas/yui-misc/
426*/
427/*
428 * Copyright (c) 2009 Nicholas C. Zakas
429 *
430 * Permission is hereby granted, free of charge, to any person obtaining a copy
431 * of this software and associated documentation files (the "Software"), to deal
432 * in the Software without restriction, including without limitation the rights
433 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
434 * copies of the Software, and to permit persons to whom the Software is
435 * furnished to do so, subject to the following conditions:
436 *
437 * The above copyright notice and this permission notice shall be included in
438 * all copies or substantial portions of the Software.
439 *
440 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
441 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
442 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
443 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
444 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
445 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
446 * THE SOFTWARE.
447 */
448
449/* updated to fix Chrome setTimeout issue by Zaid Zawaideh */
450
451 // API available in <= v0.8
452 /*******************************
453
454 // idleTimer() takes an optional argument that defines the idle timeout
455 // timeout is in milliseconds; defaults to 30000
456 $.idleTimer(10000);
457
458
459 $(document).bind("idle.idleTimer", function(){
460    // function you want to fire when the user goes idle
461 });
462
463
464 $(document).bind("active.idleTimer", function(){
465  // function you want to fire when the user becomes active again
466 });
467
468 // pass the string 'destroy' to stop the timer
469 $.idleTimer('destroy');
470
471 // you can query if the user is idle or not with data()
472 $.data(document,'idleTimer');  // 'idle'  or 'active'
473
474 // you can get time elapsed since user when idle/active
475 $.idleTimer('getElapsedTime'); // time since state change in ms
476
477 ********/
478
479
480
481 // API available in >= v0.9
482 /*************************
483
484 // bind to specific elements, allows for multiple timer instances
485 $(elem).idleTimer(timeout|'destroy'|'getElapsedTime');
486 $.data(elem,'idleTimer');  // 'idle'  or 'active'
487
488 // if you're using the old $.idleTimer api, you should not do $(document).idleTimer(...)
489
490 // element bound timers will only watch for events inside of them.
491 // you may just want page-level activity, in which case you may set up
492 //   your timers on document, document.documentElement, and document.body
493
494 // You can optionally provide a second argument to override certain options.
495 // Here are the defaults, so you can omit any or all of them.
496 $(elem).idleTimer(timeout, {
497   startImmediately: true, //starts a timeout as soon as the timer is set up; otherwise it waits for the first event.
498   idle:    false,         //indicates if the user is idle
499   enabled: true,          //indicates if the idle timer is enabled
500   events:  'mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove' // activity is one of these events
501 });
502
503 ********/
504
505(function($){
506
507$.idleTimer = function(newTimeout, elem, opts){
508
509    // defaults that are to be stored as instance props on the elem
510
511	opts = $.extend({
512		startImmediately: true, //starts a timeout as soon as the timer is set up
513		idle:    false,         //indicates if the user is idle
514		enabled: true,          //indicates if the idle timer is enabled
515		timeout: 30000,         //the amount of time (ms) before the user is considered idle
516		events:  'mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove' // activity is one of these events
517	}, opts);
518
519
520    elem = elem || document;
521
522    /* (intentionally not documented)
523     * Toggles the idle state and fires an appropriate event.
524     * @return {void}
525     */
526    var toggleIdleState = function(myelem){
527
528        // curse you, mozilla setTimeout lateness bug!
529        if (typeof myelem === 'number'){
530            myelem = undefined;
531        }
532
533        var obj = $.data(myelem || elem,'idleTimerObj');
534
535        //toggle the state
536        obj.idle = !obj.idle;
537
538        // reset timeout 
539        var elapsed = (+new Date()) - obj.olddate;
540        obj.olddate = +new Date();
541
542        // handle Chrome always triggering idle after js alert or comfirm popup
543        if (obj.idle && (elapsed < opts.timeout)) {
544                obj.idle = false;
545                clearTimeout($.idleTimer.tId);
546                if (opts.enabled)
547                  $.idleTimer.tId = setTimeout(toggleIdleState, opts.timeout);
548                return;
549        }
550        
551        //fire appropriate event
552
553        // create a custom event, but first, store the new state on the element
554        // and then append that string to a namespace
555        var event = jQuery.Event( $.data(elem,'idleTimer', obj.idle ? "idle" : "active" )  + '.idleTimer'   );
556
557        // we do want this to bubble, at least as a temporary fix for jQuery 1.7
558        // event.stopPropagation();
559        $(elem).trigger(event);
560    },
561
562    /**
563     * Stops the idle timer. This removes appropriate event handlers
564     * and cancels any pending timeouts.
565     * @return {void}
566     * @method stop
567     * @static
568     */
569    stop = function(elem){
570
571        var obj = $.data(elem,'idleTimerObj') || {};
572
573        //set to disabled
574        obj.enabled = false;
575
576        //clear any pending timeouts
577        clearTimeout(obj.tId);
578
579        //detach the event handlers
580        $(elem).off('.idleTimer');
581    },
582
583
584    /* (intentionally not documented)
585     * Handles a user event indicating that the user isn't idle.
586     * @param {Event} event A DOM2-normalized event object.
587     * @return {void}
588     */
589    handleUserEvent = function(){
590
591        var obj = $.data(this,'idleTimerObj');
592
593        //clear any existing timeout
594        clearTimeout(obj.tId);
595
596
597
598        //if the idle timer is enabled
599        if (obj.enabled){
600
601
602            //if it's idle, that means the user is no longer idle
603            if (obj.idle){
604                toggleIdleState(this);
605            }
606
607            //set a new timeout
608            obj.tId = setTimeout(toggleIdleState, obj.timeout);
609
610        }
611     };
612
613
614    /**
615     * Starts the idle timer. This adds appropriate event handlers
616     * and starts the first timeout.
617     * @param {int} newTimeout (Optional) A new value for the timeout period in ms.
618     * @return {void}
619     * @method $.idleTimer
620     * @static
621     */
622
623
624    var obj = $.data(elem,'idleTimerObj') || {};
625
626    obj.olddate = obj.olddate || +new Date();
627
628    //assign a new timeout if necessary
629    if (typeof newTimeout === "number"){
630        opts.timeout = newTimeout;
631    } else if (newTimeout === 'destroy') {
632        stop(elem);
633        return this;
634    } else if (newTimeout === 'getElapsedTime'){
635        return (+new Date()) - obj.olddate;
636    }
637
638    //assign appropriate event handlers
639    $(elem).on($.trim((opts.events+' ').split(' ').join('.idleTimer ')),handleUserEvent);
640
641
642    obj.idle    = opts.idle;
643    obj.enabled = opts.enabled;
644    obj.timeout = opts.timeout;
645
646
647    //set a timeout to toggle state. May wish to omit this in some situations
648	if (opts.startImmediately) {
649	    obj.tId = setTimeout(toggleIdleState, obj.timeout);
650	}
651
652    // assume the user is active for the first x seconds.
653    $.data(elem,'idleTimer',"active");
654
655    // store our instance on the object
656    $.data(elem,'idleTimerObj',obj);
657
658
659
660}; // end of $.idleTimer()
661
662
663// v0.9 API for defining multiple timers.
664$.fn.idleTimer = function(newTimeout,opts){
665	// Allow omission of opts for backward compatibility
666	if (!opts) {
667		opts = {};
668	}
669
670    if(this[0]){
671        $.idleTimer(newTimeout,this[0],opts);
672    }
673
674    return this;
675};
676
677
678})(jQuery);
679
680
681/***/ }),
682
683/***/ 43793:
684/*!*********************************************************************!*\
685  !*** ./runestone/common/js/jquery_i18n/jquery.i18n.emitter.bidi.js ***!
686  \*********************************************************************/
687/***/ (() => {
688
689/*!
690 * BIDI embedding support for jQuery.i18n
691 *
692 * Copyright (C) 2015, David Chan
693 *
694 * This code is dual licensed GPLv2 or later and MIT. You don't have to do
695 * anything special to choose one license or the other and you don't have to
696 * notify anyone which license you are using. You are free to use this code
697 * in commercial projects as long as the copyright header is left intact.
698 * See files GPL-LICENSE and MIT-LICENSE for details.
699 *
700 * @licence GNU General Public Licence 2.0 or later
701 * @licence MIT License
702 */
703
704( function ( $ ) {
705	'use strict';
706	var strongDirRegExp;
707
708	/**
709	 * Matches the first strong directionality codepoint:
710	 * - in group 1 if it is LTR
711	 * - in group 2 if it is RTL
712	 * Does not match if there is no strong directionality codepoint.
713	 *
714	 * Generated by UnicodeJS (see tools/strongDir) from the UCD; see
715	 * https://phabricator.wikimedia.org/diffusion/GUJS/ .
716	 */
717	strongDirRegExp = new RegExp(
718		'(?:' +
719			'(' +
720				'[\u0041-\u005a\u0061-\u007a\u00aa\u00b5\u00ba\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02b8\u02bb-\u02c1\u02d0\u02d1\u02e0-\u02e4\u02ee\u0370-\u0373\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0482\u048a-\u052f\u0531-\u0556\u0559-\u055f\u0561-\u0587\u0589\u0903-\u0939\u093b\u093d-\u0940\u0949-\u094c\u094e-\u0950\u0958-\u0961\u0964-\u0980\u0982\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd-\u09c0\u09c7\u09c8\u09cb\u09cc\u09ce\u09d7\u09dc\u09dd\u09df-\u09e1\u09e6-\u09f1\u09f4-\u09fa\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3e-\u0a40\u0a59-\u0a5c\u0a5e\u0a66-\u0a6f\u0a72-\u0a74\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd-\u0ac0\u0ac9\u0acb\u0acc\u0ad0\u0ae0\u0ae1\u0ae6-\u0af0\u0af9\u0b02\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b3e\u0b40\u0b47\u0b48\u0b4b\u0b4c\u0b57\u0b5c\u0b5d\u0b5f-\u0b61\u0b66-\u0b77\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe\u0bbf\u0bc1\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcc\u0bd0\u0bd7\u0be6-\u0bf2\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c41-\u0c44\u0c58-\u0c5a\u0c60\u0c61\u0c66-\u0c6f\u0c7f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd-\u0cc4\u0cc6-\u0cc8\u0cca\u0ccb\u0cd5\u0cd6\u0cde\u0ce0\u0ce1\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d40\u0d46-\u0d48\u0d4a-\u0d4c\u0d4e\u0d57\u0d5f-\u0d61\u0d66-\u0d75\u0d79-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dcf-\u0dd1\u0dd8-\u0ddf\u0de6-\u0def\u0df2-\u0df4\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e4f-\u0e5b\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0ed0-\u0ed9\u0edc-\u0edf\u0f00-\u0f17\u0f1a-\u0f34\u0f36\u0f38\u0f3e-\u0f47\u0f49-\u0f6c\u0f7f\u0f85\u0f88-\u0f8c\u0fbe-\u0fc5\u0fc7-\u0fcc\u0fce-\u0fda\u1000-\u102c\u1031\u1038\u103b\u103c\u103f-\u1057\u105a-\u105d\u1061-\u1070\u1075-\u1081\u1083\u1084\u1087-\u108c\u108e-\u109c\u109e-\u10c5\u10c7\u10cd\u10d0-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1360-\u137c\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u167f\u1681-\u169a\u16a0-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1735\u1736\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17b6\u17be-\u17c5\u17c7\u17c8\u17d4-\u17da\u17dc\u17e0-\u17e9\u1810-\u1819\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1923-\u1926\u1929-\u192b\u1930\u1931\u1933-\u1938\u
7201946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19da\u1a00-\u1a16\u1a19\u1a1a\u1a1e-\u1a55\u1a57\u1a61\u1a63\u1a64\u1a6d-\u1a72\u1a80-\u1a89\u1a90-\u1a99\u1aa0-\u1aad\u1b04-\u1b33\u1b35\u1b3b\u1b3d-\u1b41\u1b43-\u1b4b\u1b50-\u1b6a\u1b74-\u1b7c\u1b82-\u1ba1\u1ba6\u1ba7\u1baa\u1bae-\u1be5\u1be7\u1bea-\u1bec\u1bee\u1bf2\u1bf3\u1bfc-\u1c2b\u1c34\u1c35\u1c3b-\u1c49\u1c4d-\u1c7f\u1cc0-\u1cc7\u1cd3\u1ce1\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200e\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u214f\u2160-\u2188\u2336-\u237a\u2395\u249c-\u24e9\u26ac\u2800-\u28ff\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d70\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u302e\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u3190-\u31ba\u31f0-\u321c\u3220-\u324f\u3260-\u327b\u327f-\u32b0\u32c0-\u32cb\u32d0-\u32fe\u3300-\u3376\u337b-\u33dd\u33e0-\u33fe\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua60c\ua610-\ua62b\ua640-\ua66e\ua680-\ua69d\ua6a0-\ua6ef\ua6f2-\ua6f7\ua722-\ua787\ua789-\ua7ad\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua824\ua827\ua830-\ua837\ua840-\ua873\ua880-\ua8c3\ua8ce-\ua8d9\ua8f2-\ua8fd\ua900-\ua925\ua92e-\ua946\ua952\ua953\ua95f-\ua97c\ua983-\ua9b2\ua9b4\ua9b5\ua9ba\ua9bb\ua9bd-\ua9cd\ua9cf-\ua9d9\ua9de-\ua9e4\ua9e6-\ua9fe\uaa00-\uaa28\uaa2f\uaa30\uaa33\uaa34\uaa40-\uaa42\uaa44-\uaa4b\uaa4d\uaa50-\uaa59\uaa5c-\uaa7b\uaa7d-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaaeb\uaaee-\uaaf5\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab65\uab70-\uabe4\uabe6\uabe7\uabe9-\uabec\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\ue000-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]|\ud800[\udc00-\udc0b]|\ud800[\udc0d-\udc26]|\ud800[\udc28-\udc3a]|\ud800\udc3c|\ud800\udc3d|\ud800[\udc3f-\udc4d]|\ud800[\udc50-\udc5d]|\ud800[\udc80-\udcfa]|\ud800\udd00|\ud800\udd02|\ud800[\udd07-\udd33]|\ud800[\udd37-\udd3f]|\ud800[\uddd0-\uddfc]|\ud800[\ude80-\ude9c]|\ud800[\udea0-\uded0]|\ud800[\udf00-\udf23]|\ud800[\udf30-\udf4a]|\ud800[\udf50-\udf75]|\ud800[\udf80-\udf9d]|\ud800[\udf9f-\udfc3]|\ud800[\udfc8-\udfd5]|\ud801[\udc00-\udc9d]|\ud801[\udca0-\udca9]|\ud801[\udd00-\udd27]|\ud801[\udd30-\udd63]|\ud801\udd6f|\ud801[\ude00-\udf36]|\ud801[\udf40-\udf55]|\ud801[\udf60-\udf67]|\ud804\udc00|\ud804[\udc02-\udc37]|\ud804[\udc47-\udc4d]|\ud804[\udc66-\udc6f]|\ud804[\udc82-\udcb2]|\ud804\udcb7|\ud804\udcb8|\ud804[\udcbb-\udcc1]|\ud804[\udcd0-\udce8]|\ud804[\udcf0-\udcf9]|\ud804[\udd03-\udd26]|\ud804\udd2c|\ud804[\udd36-\udd43]|\ud804[\udd50-\udd72]|\ud804[\udd74-\udd76]|\ud804[\udd82-\uddb5]|\ud804[\uddbf-\uddc9]|\ud804\uddcd|\ud804[\uddd0-\udddf]|\ud804[\udde1-\uddf4]|\ud804[\ude00-\ude11]|\ud804[\ude13-\ude2e]|\ud804\ude32|\ud804\ude33|\ud804\ude35|\ud804[\ude38-\ude3d]|\ud804[\ude80-\ude86]|\ud804\ude88|\ud804[\ude8a-\ude8d]|\ud804[\ude8f-\ude9d]|\ud804[\ude9f-\udea9]|\ud804[\udeb0-\udede]|\ud804[\udee0-\udee2]|\ud804[\udef0-\udef9]|\ud804\udf02|\ud804\udf03|\ud804[\udf05-\udf0c]|\ud804\udf0f|\ud804\udf10|\ud804[\udf13-\udf28]|\ud804[\udf2a-\udf30]|\ud804\udf32|\ud804\udf33|\ud804[\udf35-\udf39]|\ud804[\udf3d-\udf3f]|\ud804[\udf41-\udf44]|\ud804\udf47|\ud804\udf48|\ud804[\udf4b-\udf4d]|\ud804\udf50|\ud804\udf57|\ud804[\udf5d-\udf63]|\ud805[\udc80-\udcb2]|\ud805\udcb9|\ud805[\udcbb-\udcbe]|\ud805\udcc1|\ud805[\udcc4-\udcc7]|\ud805[\udcd0-\udcd9]|\ud805[\udd80-\uddb1]|\ud805[\uddb8-\uddbb]|\ud805\uddbe|\ud805[\uddc1-\udddb]|\ud805[\ude00-\ude32]|\ud805\ude3b|\ud805\ude3c|\ud805\ude3e|\ud805[\ude41-\ude44]|\ud805[\ude50-\ude59]|\ud805[\ude80-\udeaa]|\ud805\udeac|\ud805\udeae|\ud805\udeaf|\ud805\udeb6|\ud805[\udec0-\udec9]|\ud805[\udf00-\udf19]|\ud805\udf20|\ud805\udf21|\ud805\udf26|\ud805[\udf30-\udf3f]|\ud806[\udca0-\udcf2]|\ud806\udcff|\ud806[\udec0-\udef8]|\ud808[\udc00-\udf99]|\ud809[\udc00-\udc6e]|\ud809[\udc70-\udc74]|\ud809[\udc80-\udd43]|\ud80c[\udc00-\udfff]|\ud80d[\udc00-\udc2e]|\ud811[\udc00-\ude46]|\ud81a[\udc00-\ude38]|\ud81a[\ude40-\ude5e]|\ud81a[\ude60-\ude69]|\ud81a\ude6e|\ud81a\ude6f|\ud81a[\uded0-\udeed]|\ud81a\udef5|\ud81a[\udf00-\udf2f]|\ud81a[\udf37-\udf45]|\ud81a[\udf50-\udf59]|\ud81a[\udf5b-\udf61]|\ud81a[\udf63-\udf77]|\ud81a[\udf7d-\udf8f]|\ud81b[\udf00-\udf44]|\ud81b[\udf50-\udf7e]|\ud81b[\udf93-\udf9f]|\ud82c\udc00|\ud82c\udc01|\ud82f[\udc00-\udc6a]|\ud82f[\udc70-\udc7c]|\ud82f[\udc80-\udc88]|\ud82f[\udc90-\udc99]|\ud82f\udc9c|\ud82f\udc9f|\ud834[\udc00-\udcf5]|\ud834[\udd00-\udd26]|\ud834[\udd29-\udd66]|\ud834[\udd6a-\udd72]|\ud834\udd83|\ud834\udd84|\ud834[\udd8c-\udda9]|\ud834[\uddae-\udde8]|\ud834[\udf60-\udf71]|\ud835[\udc00-\udc54]|\ud835[\udc56-\udc9c]|\ud835\udc9e|\ud835\udc9f|\ud835\udca2|\ud835\udca5|\ud835\udca6|\ud835[\udca9-\udcac]|\ud835[\udcae-\udcb9]|\ud835\udcbb|\ud835[\udcbd-\udcc3]|\ud835[\udcc5-\udd05]|\ud835[\udd07-\udd0a]|\ud835[\udd0d-\udd14]|\ud835[\udd16-\udd1c]|\ud835[\udd1e-\udd39]|\ud835[\udd3b-\udd3e]|\ud835[\udd40-\udd44]|\ud835\udd46|\ud835[\udd4a-\udd50
720]|\ud835[\udd52-\udea5]|\ud835[\udea8-\udeda]|\ud835[\udedc-\udf14]|\ud835[\udf16-\udf4e]|\ud835[\udf50-\udf88]|\ud835[\udf8a-\udfc2]|\ud835[\udfc4-\udfcb]|\ud836[\udc00-\uddff]|\ud836[\ude37-\ude3a]|\ud836[\ude6d-\ude74]|\ud836[\ude76-\ude83]|\ud836[\ude85-\ude8b]|\ud83c[\udd10-\udd2e]|\ud83c[\udd30-\udd69]|\ud83c[\udd70-\udd9a]|\ud83c[\udde6-\ude02]|\ud83c[\ude10-\ude3a]|\ud83c[\ude40-\ude48]|\ud83c\ude50|\ud83c\ude51|[\ud840-\ud868][\udc00-\udfff]|\ud869[\udc00-\uded6]|\ud869[\udf00-\udfff]|[\ud86a-\ud86c][\udc00-\udfff]|\ud86d[\udc00-\udf34]|\ud86d[\udf40-\udfff]|\ud86e[\udc00-\udc1d]|\ud86e[\udc20-\udfff]|[\ud86f-\ud872][\udc00-\udfff]|\ud873[\udc00-\udea1]|\ud87e[\udc00-\ude1d]|[\udb80-\udbbe][\udc00-\udfff]|\udbbf[\udc00-\udffd]|[\udbc0-\udbfe][\udc00-\udfff]|\udbff[\udc00-\udffd]' +
721			')|(' +
722				'[\u0590\u05be\u05c0\u05c3\u05c6\u05c8-\u05ff\u07c0-\u07ea\u07f4\u07f5\u07fa-\u0815\u081a\u0824\u0828\u082e-\u0858\u085c-\u089f\u200f\ufb1d\ufb1f-\ufb28\ufb2a-\ufb4f\u0608\u060b\u060d\u061b-\u064a\u066d-\u066f\u0671-\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u0710\u0712-\u072f\u074b-\u07a5\u07b1-\u07bf\u08a0-\u08e2\ufb50-\ufd3d\ufd40-\ufdcf\ufdf0-\ufdfc\ufdfe\ufdff\ufe70-\ufefe]|\ud802[\udc00-\udd1e]|\ud802[\udd20-\ude00]|\ud802\ude04|\ud802[\ude07-\ude0b]|\ud802[\ude10-\ude37]|\ud802[\ude3b-\ude3e]|\ud802[\ude40-\udee4]|\ud802[\udee7-\udf38]|\ud802[\udf40-\udfff]|\ud803[\udc00-\ude5f]|\ud803[\ude7f-\udfff]|\ud83a[\udc00-\udccf]|\ud83a[\udcd7-\udfff]|\ud83b[\udc00-\uddff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\udf00-\udfff]|\ud83b[\ude00-\udeef]|\ud83b[\udef2-\udeff]' +
723			')' +
724		')'
725	);
726
727	/**
728	 * Gets directionality of the first strongly directional codepoint
729	 *
730	 * This is the rule the BIDI algorithm uses to determine the directionality of
731	 * paragraphs ( http://unicode.org/reports/tr9/#The_Paragraph_Level ) and
732	 * FSI isolates ( http://unicode.org/reports/tr9/#Explicit_Directional_Isolates ).
733	 *
734	 * TODO: Does not handle BIDI control characters inside the text.
735	 * TODO: Does not handle unallocated characters.
736	 *
737	 * @param {string} text The text from which to extract initial directionality.
738	 * @return {string} Directionality (either 'ltr' or 'rtl')
739	 */
740	function strongDirFromContent( text ) {
741		var m = text.match( strongDirRegExp );
742		if ( !m ) {
743			return null;
744		}
745		if ( m[ 2 ] === undefined ) {
746			return 'ltr';
747		}
748		return 'rtl';
749	}
750
751	$.extend( $.i18n.parser.emitter, {
752		/**
753		 * Wraps argument with unicode control characters for directionality safety
754		 *
755		 * This solves the problem where directionality-neutral characters at the edge of
756		 * the argument string get interpreted with the wrong directionality from the
757		 * enclosing context, giving renderings that look corrupted like "(Ben_(WMF".
758		 *
759		 * The wrapping is LRE...PDF or RLE...PDF, depending on the detected
760		 * directionality of the argument string, using the BIDI algorithm's own "First
761		 * strong directional codepoint" rule. Essentially, this works round the fact that
762		 * there is no embedding equivalent of U+2068 FSI (isolation with heuristic
763		 * direction inference). The latter is cleaner but still not widely supported.
764		 *
765		 * @param {string[]} nodes The text nodes from which to take the first item.
766		 * @return {string} Wrapped String of content as needed.
767		 */
768		bidi: function ( nodes ) {
769			var dir = strongDirFromContent( nodes[ 0 ] );
770			if ( dir === 'ltr' ) {
771				// Wrap in LEFT-TO-RIGHT EMBEDDING ... POP DIRECTIONAL FORMATTING
772				return '\u202A' + nodes[ 0 ] + '\u202C';
773			}
774			if ( dir === 'rtl' ) {
775				// Wrap in RIGHT-TO-LEFT EMBEDDING ... POP DIRECTIONAL FORMATTING
776				return '\u202B' + nodes[ 0 ] + '\u202C';
777			}
778			// No strong directionality: do not wrap
779			return nodes[ 0 ];
780		}
781	} );
782}( jQuery ) );
783
784
785/***/ }),
786
787/***/ 30423:
788/*!****************************************************************!*\
789  !*** ./runestone/common/js/jquery_i18n/jquery.i18n.emitter.js ***!
790  \****************************************************************/
791/***/ (() => {
792
793/*!
794 * jQuery Internationalization library
795 *
796 * Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar
797 *
798 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
799 * anything special to choose one license or the other and you don't have to
800 * notify anyone which license you are using. You are free to use
801 * UniversalLanguageSelector in commercial projects as long as the copyright
802 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
803 *
804 * @licence GNU General Public Licence 2.0 or later
805 * @licence MIT License
806 */
807
808( function ( $ ) {
809	'use strict';
810
811	var MessageParserEmitter = function () {
812		this.language = $.i18n.languages[ String.locale ] || $.i18n.languages[ 'default' ];
813	};
814
815	MessageParserEmitter.prototype = {
816		constructor: MessageParserEmitter,
817
818		/**
819		 * (We put this method definition here, and not in prototype, to make
820		 * sure it's not overwritten by any magic.) Walk entire node structure,
821		 * applying replacements and template functions when appropriate
822		 *
823		 * @param {Mixed} node abstract syntax tree (top node or subnode)
824		 * @param {Array} replacements for $1, $2, ... $n
825		 * @return {Mixed} single-string node or array of nodes suitable for
826		 *  jQuery appending.
827		 */
828		emit: function ( node, replacements ) {
829			var ret, subnodes, operation,
830				messageParserEmitter = this;
831
832			switch ( typeof node ) {
833				case 'string':
834				case 'number':
835					ret = node;
836					break;
837				case 'object':
838				// node is an array of nodes
839					subnodes = $.map( node.slice( 1 ), function ( n ) {
840						return messageParserEmitter.emit( n, replacements );
841					} );
842
843					operation = node[ 0 ].toLowerCase();
844
845					if ( typeof messageParserEmitter[ operation ] === 'function' ) {
846						ret = messageParserEmitter[ operation ]( subnodes, replacements );
847					} else {
848						throw new Error( 'unknown operation "' + operation + '"' );
849					}
850
851					break;
852				case 'undefined':
853				// Parsing the empty string (as an entire expression, or as a
854				// paramExpression in a template) results in undefined
855				// Perhaps a more clever parser can detect this, and return the
856				// empty string? Or is that useful information?
857				// The logical thing is probably to return the empty string here
858				// when we encounter undefined.
859					ret = '';
860					break;
861				default:
862					throw new Error( 'unexpected type in AST: ' + typeof node );
863			}
864
865			return ret;
866		},
867
868		/**
869		 * Parsing has been applied depth-first we can assume that all nodes
870		 * here are single nodes Must return a single node to parents -- a
871		 * jQuery with synthetic span However, unwrap any other synthetic spans
872		 * in our children and pass them upwards
873		 *
874		 * @param {Array} nodes Mixed, some single nodes, some arrays of nodes.
875		 * @return {string}
876		 */
877		concat: function ( nodes ) {
878			var result = '';
879
880			$.each( nodes, function ( i, node ) {
881				// strings, integers, anything else
882				result += node;
883			} );
884
885			return result;
886		},
887
888		/**
889		 * Return escaped replacement of correct index, or string if
890		 * unavailable. Note that we expect the parsed parameter to be
891		 * zero-based. i.e. $1 should have become [ 0 ]. if the specified
892		 * parameter is not found return the same string (e.g. "$99" ->
893		 * parameter 98 -> not found -> return "$99" ) TODO throw error if
894		 * nodes.length > 1 ?
895		 *
896		 * @param {Array} nodes One element, integer, n >= 0
897		 * @param {Array} replacements for $1, $2, ... $n
898		 * @return {string} replacement
899		 */
900		replace: function ( nodes, replacements ) {
901			var index = parseInt( nodes[ 0 ], 10 );
902
903			if ( index < replacements.length ) {
904				// replacement is not a string, don't touch!
905				return replacements[ index ];
906			} else {
907				// index not found, fallback to displaying variable
908				return '$' + ( index + 1 );
909			}
910		},
911
912		/**
913		 * Transform parsed structure into pluralization n.b. The first node may
914		 * be a non-integer (for instance, a string representing an Arabic
915		 * number). So convert it back with the current language's
916		 * convertNumber.
917		 *
918		 * @param {Array} nodes List [ {String|Number}, {String}, {String} ... ]
919		 * @return {string} selected pluralized form according to current
920		 *  language.
921		 */
922		plural: function ( nodes ) {
923			var count = parseFloat( this.language.convertNumber( nodes[ 0 ], 10 ) ),
924				forms = nodes.slice( 1 );
925
926			return forms.length ? this.language.convertPlural( count, forms ) : '';
927		},
928
929		/**
930		 * Transform parsed structure into gender Usage
931		 * {{gender:gender|masculine|feminine|neutral}}.
932		 *
933		 * @param {Array} nodes List [ {String}, {String}, {String} , {String} ]
934		 * @return {string} selected gender form according to current language
935		 */
936		gender: function ( nodes ) {
937			var gender = nodes[ 0 ],
938				forms = nodes.slice( 1 );
939
940			return this.language.gender( gender, forms );
941		},
942
943		/**
944		 * Transform parsed structure into grammar conversion. Invoked by
945		 * putting {{grammar:form|word}} in a message
946		 *
947		 * @param {Array} nodes List [{Grammar case eg: genitive}, {String word}]
948		 * @return {string} selected grammatical form according to current
949		 *  language.
950		 */
951		grammar: function ( nodes ) {
952			var form = nodes[ 0 ],
953				word = nodes[ 1 ];
954
955			return word && form && this.language.convertGrammar( word, form );
956		}
957	};
958
959	$.extend( $.i18n.parser.emitter, new MessageParserEmitter() );
960}( jQuery ) );
961
962
963/***/ }),
964
965/***/ 9001:
966/*!******************************************************************!*\
967  !*** ./runestone/common/js/jquery_i18n/jquery.i18n.fallbacks.js ***!
968  \******************************************************************/
969/***/ (() => {
970
971/*!
972 * jQuery Internationalization library
973 *
974 * Copyright (C) 2012 Santhosh Thottingal
975 *
976 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do anything special to
977 * choose one license or the other and you don't have to notify anyone which license you are using.
978 * You are free to use UniversalLanguageSelector in commercial projects as long as the copyright
979 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
980 *
981 * @licence GNU General Public Licence 2.0 or later
982 * @licence MIT License
983 */
984( function ( $ ) {
985	'use strict';
986
987	$.i18n = $.i18n || {};
988	$.extend( $.i18n.fallbacks, {
989		ab: [ 'ru' ],
990		ace: [ 'id' ],
991		aln: [ 'sq' ],
992		// Not so standard - als is supposed to be Tosk Albanian,
993		// but in Wikipedia it's used for a Germanic language.
994		als: [ 'gsw', 'de' ],
995		an: [ 'es' ],
996		anp: [ 'hi' ],
997		arn: [ 'es' ],
998		arz: [ 'ar' ],
999		av: [ 'ru' ],
1000		ay: [ 'es' ],
1001		ba: [ 'ru' ],
1002		bar: [ 'de' ],
1003		'bat-smg': [ 'sgs', 'lt' ],
1004		bcc: [ 'fa' ],
1005		'be-x-old': [ 'be-tarask' ],
1006		bh: [ 'bho' ],
1007		bjn: [ 'id' ],
1008		bm: [ 'fr' ],
1009		bpy: [ 'bn' ],
1010		bqi: [ 'fa' ],
1011		bug: [ 'id' ],
1012		'cbk-zam': [ 'es' ],
1013		ce: [ 'ru' ],
1014		crh: [ 'crh-latn' ],
1015		'crh-cyrl': [ 'ru' ],
1016		csb: [ 'pl' ],
1017		cv: [ 'ru' ],
1018		'de-at': [ 'de' ],
1019		'de-ch': [ 'de' ],
1020		'de-formal': [ 'de' ],
1021		dsb: [ 'de' ],
1022		dtp: [ 'ms' ],
1023		egl: [ 'it' ],
1024		eml: [ 'it' ],
1025		ff: [ 'fr' ],
1026		fit: [ 'fi' ],
1027		'fiu-vro': [ 'vro', 'et' ],
1028		frc: [ 'fr' ],
1029		frp: [ 'fr' ],
1030		frr: [ 'de' ],
1031		fur: [ 'it' ],
1032		gag: [ 'tr' ],
1033		gan: [ 'gan-hant', 'zh-hant', 'zh-hans' ],
1034		'gan-hans': [ 'zh-hans' ],
1035		'gan-hant': [ 'zh-hant', 'zh-hans' ],
1036		gl: [ 'pt' ],
1037		glk: [ 'fa' ],
1038		gn: [ 'es' ],
1039		gsw: [ 'de' ],
1040		hif: [ 'hif-latn' ],
1041		hsb: [ 'de' ],
1042		ht: [ 'fr' ],
1043		ii: [ 'zh-cn', 'zh-hans' ],
1044		inh: [ 'ru' ],
1045		iu: [ 'ike-cans' ],
1046		jut: [ 'da' ],
1047		jv: [ 'id' ],
1048		kaa: [ 'kk-latn', 'kk-cyrl' ],
1049		kbd: [ 'kbd-cyrl' ],
1050		khw: [ 'ur' ],
1051		kiu: [ 'tr' ],
1052		kk: [ 'kk-cyrl' ],
1053		'kk-arab': [ 'kk-cyrl' ],
1054		'kk-latn': [ 'kk-cyrl' ],
1055		'kk-cn': [ 'kk-arab', 'kk-cyrl' ],
1056		'kk-kz': [ 'kk-cyrl' ],
1057		'kk-tr': [ 'kk-latn', 'kk-cyrl' ],
1058		kl: [ 'da' ],
1059		'ko-kp': [ 'ko' ],
1060		koi: [ 'ru' ],
1061		krc: [ 'ru' ],
1062		ks: [ 'ks-arab' ],
1063		ksh: [ 'de' ],
1064		ku: [ 'ku-latn' ],
1065		'ku-arab': [ 'ckb' ],
1066		kv: [ 'ru' ],
1067		lad: [ 'es' ],
1068		lb: [ 'de' ],
1069		lbe: [ 'ru' ],
1070		lez: [ 'ru' ],
1071		li: [ 'nl' ],
1072		lij: [ 'it' ],
1073		liv: [ 'et' ],
1074		lmo: [ 'it' ],
1075		ln: [ 'fr' ],
1076		ltg: [ 'lv' ],
1077		lzz: [ 'tr' ],
1078		mai: [ 'hi' ],
1079		'map-bms': [ 'jv', 'id' ],
1080		mg: [ 'fr' ],
1081		mhr: [ 'ru' ],
1082		min: [ 'id' ],
1083		mo: [ 'ro' ],
1084		mrj: [ 'ru' ],
1085		mwl: [ 'pt' ],
1086		myv: [ 'ru' ],
1087		mzn: [ 'fa' ],
1088		nah: [ 'es' ],
1089		nap: [ 'it' ],
1090		nds: [ 'de' ],
1091		'nds-nl': [ 'nl' ],
1092		'nl-informal': [ 'nl' ],
1093		no: [ 'nb' ],
1094		os: [ 'ru' ],
1095		pcd: [ 'fr' ],
1096		pdc: [ 'de' ],
1097		pdt: [ 'de' ],
1098		pfl: [ 'de' ],
1099		pms: [ 'it' ],
1100		pt: [ 'pt-br' ],
1101		'pt-br': [ 'pt' ],
1102		qu: [ 'es' ],
1103		qug: [ 'qu', 'es' ],
1104		rgn: [ 'it' ],
1105		rmy: [ 'ro' ],
1106		'roa-rup': [ 'rup' ],
1107		rue: [ 'uk', 'ru' ],
1108		ruq: [ 'ruq-latn', 'ro' ],
1109		'ruq-cyrl': [ 'mk' ],
1110		'ruq-latn': [ 'ro' ],
1111		sa: [ 'hi' ],
1112		sah: [ 'ru' ],
1113		scn: [ 'it' ],
1114		sg: [ 'fr' ],
1115		sgs: [ 'lt' ],
1116		sli: [ 'de' ],
1117		sr: [ 'sr-ec' ],
1118		srn: [ 'nl' ],
1119		stq: [ 'de' ],
1120		su: [ 'id' ],
1121		szl: [ 'pl' ],
1122		tcy: [ 'kn' ],
1123		tg: [ 'tg-cyrl' ],
1124		tt: [ 'tt-cyrl', 'ru' ],
1125		'tt-cyrl': [ 'ru' ],
1126		ty: [ 'fr' ],
1127		udm: [ 'ru' ],
1128		ug: [ 'ug-arab' ],
1129		uk: [ 'ru' ],
1130		vec: [ 'it' ],
1131		vep: [ 'et' ],
1132		vls: [ 'nl' ],
1133		vmf: [ 'de' ],
1134		vot: [ 'fi' ],
1135		vro: [ 'et' ],
1136		wa: [ 'fr' ],
1137		wo: [ 'fr' ],
1138		wuu: [ 'zh-hans' ],
1139		xal: [ 'ru' ],
1140		xmf: [ 'ka' ],
1141		yi: [ 'he' ],
1142		za: [ 'zh-hans' ],
1143		zea: [ 'nl' ],
1144		zh: [ 'zh-hans' ],
1145		'zh-classical': [ 'lzh' ],
1146		'zh-cn': [ 'zh-hans' ],
1147		'zh-hant': [ 'zh-hans' ],
1148		'zh-hk': [ 'zh-hant', 'zh-hans' ],
1149		'zh-min-nan': [ 'nan' ],
1150		'zh-mo': [ 'zh-hk', 'zh-hant', 'zh-hans' ],
1151		'zh-my': [ 'zh-sg', 'zh-hans' ],
1152		'zh-sg': [ 'zh-hans' ],
1153		'zh-tw': [ 'zh-hant', 'zh-hans' ],
1154		'zh-yue': [ 'yue' ]
1155	} );
1156}( jQuery ) );
1157
1158
1159/***/ }),
1160
1161/***/ 99283:
1162/*!********************************************************!*\
1163  !*** ./runestone/common/js/jquery_i18n/jquery.i18n.js ***!
1164  \********************************************************/
1165/***/ (() => {
1166
1167/*!
1168 * jQuery Internationalization library
1169 *
1170 * Copyright (C) 2012 Santhosh Thottingal
1171 *
1172 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
1173 * anything special to choose one license or the other and you don't have to
1174 * notify anyone which license you are using. You are free to use
1175 * UniversalLanguageSelector in commercial projects as long as the copyright
1176 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
1177 *
1178 * @licence GNU General Public Licence 2.0 or later
1179 * @licence MIT License
1180 */
1181
1182( function ( $ ) {
1183	'use strict';
1184
1185	var I18N,
1186		slice = Array.prototype.slice;
1187	/**
1188	 * @constructor
1189	 * @param {Object} options
1190	 */
1191	I18N = function ( options ) {
1192		// Load defaults
1193		this.options = $.extend( {}, I18N.defaults, options );
1194
1195		this.parser = this.options.parser;
1196		this.locale = this.options.locale;
1197		this.messageStore = this.options.messageStore;
1198		this.languages = {};
1199	};
1200
1201	I18N.prototype = {
1202		/**
1203		 * Localize a given messageKey to a locale.
1204		 * @param {String} messageKey
1205		 * @return {String} Localized message
1206		 */
1207		localize: function ( messageKey ) {
1208			var localeParts, localePartIndex, locale, fallbackIndex,
1209				tryingLocale, message;
1210
1211			locale = this.locale;
1212			fallbackIndex = 0;
1213
1214			while ( locale ) {
1215				// Iterate through locales starting at most-specific until
1216				// localization is found. As in fi-Latn-FI, fi-Latn and fi.
1217				localeParts = locale.split( '-' );
1218				localePartIndex = localeParts.length;
1219
1220				do {
1221					tryingLocale = localeParts.slice( 0, localePartIndex ).join( '-' );
1222					message = this.messageStore.get( tryingLocale, messageKey );
1223
1224					if ( message ) {
1225						return message;
1226					}
1227
1228					localePartIndex--;
1229				} while ( localePartIndex );
1230
1231				if ( locale === 'en' ) {
1232					break;
1233				}
1234
1235				locale = ( $.i18n.fallbacks[ this.locale ] &&
1236						$.i18n.fallbacks[ this.locale ][ fallbackIndex ] ) ||
1237						this.options.fallbackLocale;
1238				$.i18n.log( 'Trying fallback locale for ' + this.locale + ': ' + locale + ' (' + messageKey + ')' );
1239
1240				fallbackIndex++;
1241			}
1242
1243			// key not found
1244			return '';
1245		},
1246
1247		/*
1248		 * Destroy the i18n instance.
1249		 */
1250		destroy: function () {
1251			$.removeData( document, 'i18n' );
1252		},
1253
1254		/**
1255		 * General message loading API This can take a URL string for
1256		 * the json formatted messages. Example:
1257		 * <code>load('path/to/all_localizations.json');</code>
1258		 *
1259		 * To load a localization file for a locale:
1260		 * <code>
1261		 * load('path/to/de-messages.json', 'de' );
1262		 * </code>
1263		 *
1264		 * To load a localization file from a directory:
1265		 * <code>
1266		 * load('path/to/i18n/directory', 'de' );
1267		 * </code>
1268		 * The above method has the advantage of fallback resolution.
1269		 * ie, it will automatically load the fallback locales for de.
1270		 * For most usecases, this is the recommended method.
1271		 * It is optional to have trailing slash at end.
1272		 *
1273		 * A data object containing message key- message translation mappings
1274		 * can also be passed. Example:
1275		 * <code>
1276		 * load( { 'hello' : 'Hello' }, optionalLocale );
1277		 * </code>
1278		 *
1279		 * A source map containing key-value pair of languagename and locations
1280		 * can also be passed. Example:
1281		 * <code>
1282		 * load( {
1283		 * bn: 'i18n/bn.json',
1284		 * he: 'i18n/he.json',
1285		 * en: 'i18n/en.json'
1286		 * } )
1287		 * </code>
1288		 *
1289		 * If the data argument is null/undefined/false,
1290		 * all cached messages for the i18n instance will get reset.
1291		 *
1292		 * @param {string|Object} source
1293		 * @param {string} locale Language tag
1294		 * @return {jQuery.Promise}
1295		 */
1296		load: function ( source, locale ) {
1297			var fallbackLocales, locIndex, fallbackLocale, sourceMap = {};
1298			if ( !source && !locale ) {
1299				source = 'i18n/' + $.i18n().locale + '.json';
1300				locale = $.i18n().locale;
1301			}
1302			if ( typeof source === 'string' &&
1303				// source extension should be json, but can have query params after that.
1304				source.split( '?' )[ 0 ].split( '.' ).pop() !== 'json'
1305			) {
1306				// Load specified locale then check for fallbacks when directory is
1307				// specified in load()
1308				sourceMap[ locale ] = source + '/' + locale + '.json';
1309				fallbackLocales = ( $.i18n.fallbacks[ locale ] || [] )
1310					.concat( this.options.fallbackLocale );
1311				for ( locIndex = 0; locIndex < fallbackLocales.length; locIndex++ ) {
1312					fallbackLocale = fallbackLocales[ locIndex ];
1313					sourceMap[ fallbackLocale ] = source + '/' + fallbackLocale + '.json';
1314				}
1315				return this.load( sourceMap );
1316			} else {
1317				return this.messageStore.load( source, locale );
1318			}
1319
1320		},
1321
1322		/**
1323		 * Does parameter and magic word substitution.
1324		 *
1325		 * @param {string} key Message key
1326		 * @param {Array} parameters Message parameters
1327		 * @return {string}
1328		 */
1329		parse: function ( key, parameters ) {
1330			var message = this.localize( key );
1331			// FIXME: This changes the state of the I18N object,
1332			// should probably not change the 'this.parser' but just
1333			// pass it to the parser.
1334			this.parser.language = $.i18n.languages[ $.i18n().locale ] || $.i18n.languages[ 'default' ];
1335			if ( message === '' ) {
1336				message = key;
1337			}
1338			return this.parser.parse( message, parameters );
1339		}
1340	};
1341
1342	/**
1343	 * Process a message from the $.I18N instance
1344	 * for the current document, stored in jQuery.data(document).
1345	 *
1346	 * @param {string} key Key of the message.
1347	 * @param {string} param1 [param...] Variadic list of parameters for {key}.
1348	 * @return {string|$.I18N} Parsed message, or if no key was given
1349	 * the instance of $.I18N is returned.
1350	 */
1351	$.i18n = function ( key, param1 ) {
1352		var parameters,
1353			i18n = $.data( document, 'i18n' ),
1354			options = typeof key === 'object' && key;
1355
1356		// If the locale option for this call is different then the setup so far,
1357		// update it automatically. This doesn't just change the context for this
1358		// call but for all future call as well.
1359		// If there is no i18n setup yet, don't do this. It will be taken care of
1360		// by the `new I18N` construction below.
1361		// NOTE: It should only change language for this one call.
1362		// Then cache instances of I18N somewhere.
1363		if ( options && options.locale && i18n && i18n.locale !== options.locale ) {
1364			i18n.locale = options.locale;
1365		}
1366
1367		if ( !i18n ) {
1368			i18n = new I18N( options );
1369			$.data( document, 'i18n', i18n );
1370		}
1371
1372		if ( typeof key === 'string' ) {
1373			if ( param1 !== undefined ) {
1374				parameters = slice.call( arguments, 1 );
1375			} else {
1376				parameters = [];
1377			}
1378
1379			return i18n.parse( key, parameters );
1380		} else {
1381			// FIXME: remove this feature/bug.
1382			return i18n;
1383		}
1384	};
1385
1386	$.fn.i18n = function () {
1387		var i18n = $.data( document, 'i18n' );
1388
1389		if ( !i18n ) {
1390			i18n = new I18N();
1391			$.data( document, 'i18n', i18n );
1392		}
1393
1394		return this.each( function () {
1395			var $this = $( this ),
1396				messageKey = $this.data( 'i18n' ),
1397				lBracket, rBracket, type, key;
1398
1399			if ( messageKey ) {
1400				lBracket = messageKey.indexOf( '[' );
1401				rBracket = messageKey.indexOf( ']' );
1402				if ( lBracket !== -1 && rBracket !== -1 && lBracket < rBracket ) {
1403					type = messageKey.slice( lBracket + 1, rBracket );
1404					key = messageKey.slice( rBracket + 1 );
1405					if ( type === 'html' ) {
1406						$this.html( i18n.parse( key ) );
1407					} else {
1408						$this.attr( type, i18n.parse( key ) );
1409					}
1410				} else {
1411					$this.text( i18n.parse( messageKey ) );
1412				}
1413			} else {
1414				$this.find( '[data-i18n]' ).i18n();
1415			}
1416		} );
1417	};
1418
1419	function getDefaultLocale() {
1420		var nav, locale = $( 'html' ).attr( 'lang' );
1421
1422		if ( !locale ) {
1423			if ( typeof window.navigator !== undefined ) {
1424				nav = window.navigator;
1425				locale = nav.language || nav.userLanguage || '';
1426			} else {
1427				locale = '';
1428			}
1429		}
1430		return locale;
1431	}
1432
1433	$.i18n.languages = {};
1434	$.i18n.messageStore = $.i18n.messageStore || {};
1435	$.i18n.parser = {
1436		// The default parser only handles variable substitution
1437		parse: function ( message, parameters ) {
1438			return message.replace( /\$(\d+)/g, function ( str, match ) {
1439				var index = parseInt( match, 10 ) - 1;
1440				return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match;
1441			} );
1442		},
1443		emitter: {}
1444	};
1445	$.i18n.fallbacks = {};
1446	$.i18n.debug = false;
1447	$.i18n.log = function ( /* arguments */ ) {
1448		if ( window.console && $.i18n.debug ) {
1449			window.console.log.apply( window.console, arguments );
1450		}
1451	};
1452	/* Static members */
1453	I18N.defaults = {
1454		locale: getDefaultLocale(),
1455		fallbackLocale: 'en',
1456		parser: $.i18n.parser,
1457		messageStore: $.i18n.messageStore
1458	};
1459
1460	// Expose constructor
1461	$.i18n.constructor = I18N;
1462}( jQuery ) );
1463
1464/***/ }),
1465
1466/***/ 64793:
1467/*!*****************************************************************!*\
1468  !*** ./runestone/common/js/jquery_i18n/jquery.i18n.language.js ***!
1469  \*****************************************************************/
1470/***/ (() => {
1471
1472/* global pluralRuleParser */
1473( function ( $ ) {
1474	'use strict';
1475
1476	// jscs:disable
1477	var language = {
1478		// CLDR plural rules generated using
1479		// libs/CLDRPluralRuleParser/tools/PluralXML2JSON.html
1480		pluralRules: {
1481			ak: {
1482				one: 'n = 0..1'
1483			},
1484			am: {
1485				one: 'i = 0 or n = 1'
1486			},
1487			ar: {
1488				zero: 'n = 0',
1489				one: 'n = 1',
1490				two: 'n = 2',
1491				few: 'n % 100 = 3..10',
1492				many: 'n % 100 = 11..99'
1493			},
1494			ars: {
1495				zero: 'n = 0',
1496				one: 'n = 1',
1497				two: 'n = 2',
1498				few: 'n % 100 = 3..10',
1499				many: 'n % 100 = 11..99'
1500			},
1501			as: {
1502				one: 'i = 0 or n = 1'
1503			},
1504			be: {
1505				one: 'n % 10 = 1 and n % 100 != 11',
1506				few: 'n % 10 = 2..4 and n % 100 != 12..14',
1507				many: 'n % 10 = 0 or n % 10 = 5..9 or n % 100 = 11..14'
1508			},
1509			bh: {
1510				one: 'n = 0..1'
1511			},
1512			bn: {
1513				one: 'i = 0 or n = 1'
1514			},
1515			br: {
1516				one: 'n % 10 = 1 and n % 100 != 11,71,91',
1517				two: 'n % 10 = 2 and n % 100 != 12,72,92',
1518				few: 'n % 10 = 3..4,9 and n % 100 != 10..19,70..79,90..99',
1519				many: 'n != 0 and n % 1000000 = 0'
1520			},
1521			bs: {
1522				one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
1523				few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
1524			},
1525			cs: {
1526				one: 'i = 1 and v = 0',
1527				few: 'i = 2..4 and v = 0',
1528				many: 'v != 0'
1529			},
1530			cy: {
1531				zero: 'n = 0',
1532				one: 'n = 1',
1533				two: 'n = 2',
1534				few: 'n = 3',
1535				many: 'n = 6'
1536			},
1537			da: {
1538				one: 'n = 1 or t != 0 and i = 0,1'
1539			},
1540			dsb: {
1541				one: 'v = 0 and i % 100 = 1 or f % 100 = 1',
1542				two: 'v = 0 and i % 100 = 2 or f % 100 = 2',
1543				few: 'v = 0 and i % 100 = 3..4 or f % 100 = 3..4'
1544			},
1545			fa: {
1546				one: 'i = 0 or n = 1'
1547			},
1548			ff: {
1549				one: 'i = 0,1'
1550			},
1551			fil: {
1552				one: 'v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9'
1553			},
1554			fr: {
1555				one: 'i = 0,1'
1556			},
1557			ga: {
1558				one: 'n = 1',
1559				two: 'n = 2',
1560				few: 'n = 3..6',
1561				many: 'n = 7..10'
1562			},
1563			gd: {
1564				one: 'n = 1,11',
1565				two: 'n = 2,12',
1566				few: 'n = 3..10,13..19'
1567			},
1568			gu: {
1569				one: 'i = 0 or n = 1'
1570			},
1571			guw: {
1572				one: 'n = 0..1'
1573			},
1574			gv: {
1575				one: 'v = 0 and i % 10 = 1',
1576				two: 'v = 0 and i % 10 = 2',
1577				few: 'v = 0 and i % 100 = 0,20,40,60,80',
1578				many: 'v != 0'
1579			},
1580			he: {
1581				one: 'i = 1 and v = 0',
1582				two: 'i = 2 and v = 0',
1583				many: 'v = 0 and n != 0..10 and n % 10 = 0'
1584			},
1585			hi: {
1586				one: 'i = 0 or n = 1'
1587			},
1588			hr: {
1589				one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
1590				few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
1591			},
1592			hsb: {
1593				one: 'v = 0 and i % 100 = 1 or f % 100 = 1',
1594				two: 'v = 0 and i % 100 = 2 or f % 100 = 2',
1595				few: 'v = 0 and i % 100 = 3..4 or f % 100 = 3..4'
1596			},
1597			hy: {
1598				one: 'i = 0,1'
1599			},
1600			is: {
1601				one: 't = 0 and i % 10 = 1 and i % 100 != 11 or t != 0'
1602			},
1603			iu: {
1604				one: 'n = 1',
1605				two: 'n = 2'
1606			},
1607			iw: {
1608				one: 'i = 1 and v = 0',
1609				two: 'i = 2 and v = 0',
1610				many: 'v = 0 and n != 0..10 and n % 10 = 0'
1611			},
1612			kab: {
1613				one: 'i = 0,1'
1614			},
1615			kn: {
1616				one: 'i = 0 or n = 1'
1617			},
1618			kw: {
1619				one: 'n = 1',
1620				two: 'n = 2'
1621			},
1622			lag: {
1623				zero: 'n = 0',
1624				one: 'i = 0,1 and n != 0'
1625			},
1626			ln: {
1627				one: 'n = 0..1'
1628			},
1629			lt: {
1630				one: 'n % 10 = 1 and n % 100 != 11..19',
1631				few: 'n % 10 = 2..9 and n % 100 != 11..19',
1632				many: 'f != 0'
1633			},
1634			lv: {
1635				zero: 'n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19',
1636				one: 'n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1'
1637			},
1638			mg: {
1639				one: 'n = 0..1'
1640			},
1641			mk: {
1642				one: 'v = 0 and i % 10 = 1 or f % 10 = 1'
1643			},
1644			mo: {
1645				one: 'i = 1 and v = 0',
1646				few: 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19'
1647			},
1648			mr: {
1649				one: 'i = 0 or n = 1'
1650			},
1651			mt: {
1652				one: 'n = 1',
1653				few: 'n = 0 or n % 100 = 2..10',
1654				many: 'n % 100 = 11..19'
1655			},
1656			naq: {
1657				one: 'n = 1',
1658				two: 'n = 2'
1659			},
1660			nso: {
1661				one: 'n = 0..1'
1662			},
1663			pa: {
1664				one: 'n = 0..1'
1665			},
1666			pl: {
1667				one: 'i = 1 and v = 0',
1668				few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
1669				many: 'v = 0 and i != 1 and i % 10 = 0..1 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 12..14'
1670			},
1671			prg: {
1672				zero: 'n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19',
1673				one: 'n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1'
1674			},
1675			pt: {
1676				one: 'i = 0..1'
1677			},
1678			ro: {
1679				one: 'i = 1 and v = 0',
1680				few: 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19'
1681			},
1682			ru: {
1683				one: 'v = 0 and i % 10 = 1 and i % 100 != 11',
1684				few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
1685				many: 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14'
1686			},
1687			se: {
1688				one: 'n = 1',
1689				two: 'n = 2'
1690			},
1691			sh: {
1692				one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
1693				few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
1694			},
1695			shi: {
1696				one: 'i = 0 or n = 1',
1697				few: 'n = 2..10'
1698			},
1699			si: {
1700				one: 'n = 0,1 or i = 0 and f = 1'
1701			},
1702			sk: {
1703				one: 'i = 1 and v = 0',
1704				few: 'i = 2..4 and v = 0',
1705				many: 'v != 0'
1706			},
1707			sl: {
1708				one: 'v = 0 and i % 100 = 1',
1709				two: 'v = 0 and i % 100 = 2',
1710				few: 'v = 0 and i % 100 = 3..4 or v != 0'
1711			},
1712			sma: {
1713				one: 'n = 1',
1714				two: 'n = 2'
1715			},
1716			smi: {
1717				one: 'n = 1',
1718				two: 'n = 2'
1719			},
1720			smj: {
1721				one: 'n = 1',
1722				two: 'n = 2'
1723			},
1724			smn: {
1725				one: 'n = 1',
1726				two: 'n = 2'
1727			},
1728			sms: {
1729				one: 'n = 1',
1730				two: 'n = 2'
1731			},
1732			sr: {
1733				one: 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11',
1734				few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14'
1735			},
1736			ti: {
1737				one: 'n = 0..1'
1738			},
1739			tl: {
1740				one: 'v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9'
1741			},
1742			tzm: {
1743				one: 'n = 0..1 or n = 11..99'
1744			},
1745			uk: {
1746				one: 'v = 0 and i % 10 = 1 and i % 100 != 11',
1747				few: 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14',
1748				many: 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14'
1749			},
1750			wa: {
1751				one: 'n = 0..1'
1752			},
1753			zu: {
1754				one: 'i = 0 or n = 1'
1755			}
1756		},
1757		// jscs:enable
1758
1759		/**
1760		 * Plural form transformations, needed for some languages.
1761		 *
1762		 * @param {integer} count
1763		 *            Non-localized quantifier
1764		 * @param {Array} forms
1765		 *            List of plural forms
1766		 * @return {string} Correct form for quantifier in this language
1767		 */
1768		convertPlural: function ( count, forms ) {
1769			var pluralRules,
1770				pluralFormIndex,
1771				index,
1772				explicitPluralPattern = new RegExp( '\\d+=', 'i' ),
1773				formCount,
1774				form;
1775
1776			if ( !forms || forms.length === 0 ) {
1777				return '';
1778			}
1779
1780			// Handle for Explicit 0= & 1= values
1781			for ( index = 0; index < forms.length; index++ ) {
1782				form = forms[ index ];
1783				if ( explicitPluralPattern.test( form ) ) {
1784					formCount = parseInt( form.slice( 0, form.indexOf( '=' ) ), 10 );
1785					if ( formCount === count ) {
1786						return ( form.slice( form.indexOf( '=' ) + 1 ) );
1787					}
1788					forms[ index ] = undefined;
1789				}
1790			}
1791
1792			forms = $.map( forms, function ( form ) {
1793				if ( form !== undefined ) {
1794					return form;
1795				}
1796			} );
1797
1798			pluralRules = this.pluralRules[ $.i18n().locale ];
1799
1800			if ( !pluralRules ) {
1801				// default fallback.
1802				return ( count === 1 ) ? forms[ 0 ] : forms[ 1 ];
1803			}
1804
1805			pluralFormIndex = this.getPluralForm( count, pluralRules );
1806			pluralFormIndex = Math.min( pluralFormIndex, forms.length - 1 );
1807
1808			return forms[ pluralFormIndex ];
1809		},
1810
1811		/**
1812		 * For the number, get the plural for index
1813		 *
1814		 * @param {integer} number
1815		 * @param {Object} pluralRules
1816		 * @return {integer} plural form index
1817		 */
1818		getPluralForm: function ( number, pluralRules ) {
1819			var i,
1820				pluralForms = [ 'zero', 'one', 'two', 'few', 'many', 'other' ],
1821				pluralFormIndex = 0;
1822
1823			for ( i = 0; i < pluralForms.length; i++ ) {
1824				if ( pluralRules[ pluralForms[ i ] ] ) {
1825					if ( pluralRuleParser( pluralRules[ pluralForms[ i ] ], number ) ) {
1826						return pluralFormIndex;
1827					}
1828
1829					pluralFormIndex++;
1830				}
1831			}
1832
1833			return pluralFormIndex;
1834		},
1835
1836		/**
1837		 * Converts a number using digitTransformTable.
1838		 *
1839		 * @param {number} num Value to be converted
1840		 * @param {boolean} integer Convert the return value to an integer
1841		 * @return {string} The number converted into a String.
1842		 */
1843		convertNumber: function ( num, integer ) {
1844			var tmp, item, i,
1845				transformTable, numberString, convertedNumber;
1846
1847			// Set the target Transform table:
1848			transformTable = this.digitTransformTable( $.i18n().locale );
1849			numberString = String( num );
1850			convertedNumber = '';
1851
1852			if ( !transformTable ) {
1853				return num;
1854			}
1855
1856			// Check if the restore to Latin number flag is set:
1857			if ( integer ) {
1858				if ( parseFloat( num, 10 ) === num ) {
1859					return num;
1860				}
1861
1862				tmp = [];
1863
1864				for ( item in transformTable ) {
1865					tmp[ transformTable[ item ] ] = item;
1866				}
1867
1868				transformTable = tmp;
1869			}
1870
1871			for ( i = 0; i < numberString.length; i++ ) {
1872				if ( transformTable[ numberString[ i ] ] ) {
1873					convertedNumber += transformTable[ numberString[ i ] ];
1874				} else {
1875					convertedNumber += numberString[ i ];
1876				}
1877			}
1878
1879			return integer ? parseFloat( convertedNumber, 10 ) : convertedNumber;
1880		},
1881
1882		/**
1883		 * Grammatical transformations, needed for inflected languages.
1884		 * Invoked by putting {{grammar:form|word}} in a message.
1885		 * Override this method for languages that need special grammar rules
1886		 * applied dynamically.
1887		 *
1888		 * @param {string} word
1889		 * @param {string} form
1890		 * @return {string}
1891		 */
1892		// eslint-disable-next-line no-unused-vars
1893		convertGrammar: function ( word, form ) {
1894			return word;
1895		},
1896
1897		/**
1898		 * Provides an alternative text depending on specified gender. Usage
1899		 * {{gender:[gender|user object]|masculine|feminine|neutral}}. If second
1900		 * or third parameter are not specified, masculine is used.
1901		 *
1902		 * These details may be overriden per language.
1903		 *
1904		 * @param {string} gender
1905		 *      male, female, or anything else for neutral.
1906		 * @param {Array} forms
1907		 *      List of gender forms
1908		 *
1909		 * @return {string}
1910		 */
1911		gender: function ( gender, forms ) {
1912			if ( !forms || forms.length === 0 ) {
1913				return '';
1914			}
1915
1916			while ( forms.length < 2 ) {
1917				forms.push( forms[ forms.length - 1 ] );
1918			}
1919
1920			if ( gender === 'male' ) {
1921				return forms[ 0 ];
1922			}
1923
1924			if ( gender === 'female' ) {
1925				return forms[ 1 ];
1926			}
1927
1928			return ( forms.length === 3 ) ? forms[ 2 ] : forms[ 0 ];
1929		},
1930
1931		/**
1932		 * Get the digit transform table for the given language
1933		 * See http://cldr.unicode.org/translation/numbering-systems
1934		 *
1935		 * @param {string} language
1936		 * @return {Array|boolean} List of digits in the passed language or false
1937		 * representation, or boolean false if there is no information.
1938		 */
1939		digitTransformTable: function ( language ) {
1940			var tables = {
1941				ar: '٠١٢٣٤٥٦٧٨٩',
1942				fa: 'Û°Û±Û²Û³Û´ÛµÛ¶Û·Û¸Û¹',
1943				ml: '൦൧൨൩൪൫൬൭൮൯',
1944				kn: '೦೧೨೩೪೫೬೭೮೯',
1945				lo: '໐໑໒໓໔໕໖໗໘໙',
1946				or: '୦୧୨୩୪୫୬୭୮୯',
1947				kh: '០១២៣៤៥៦៧៨៩',
1948				pa: '੦੧੨੩੪੫੬੭੮੯',
1949				gu: '૦૧૨૩૪૫૬૭૮૯',
1950				hi: '०१२३४५६७८९',
1951				my: '၀၁၂၃၄၅၆၇၈၉',
1952				ta: '௦௧௨௩௪௫௬௭௮௯',
1953				te: '౦౧౨౩౪౫౬౭౮౯',
1954				th: '๐๑๒๓๔๕๖๗๘๙', // FIXME use iso 639 codes
1955				bo: '༠༡༢༣༤༥༦༧༨༩' // FIXME use iso 639 codes
1956			};
1957
1958			if ( !tables[ language ] ) {
1959				return false;
1960			}
1961
1962			return tables[ language ].split( '' );
1963		}
1964	};
1965
1966	$.extend( $.i18n.languages, {
1967		'default': language
1968	} );
1969}( jQuery ) );
1970
1971
1972/***/ }),
1973
1974/***/ 34517:
1975/*!*********************************************************************!*\
1976  !*** ./runestone/common/js/jquery_i18n/jquery.i18n.messagestore.js ***!
1977  \*********************************************************************/
1978/***/ (() => {
1979
1980/*!
1981 * jQuery Internationalization library - Message Store
1982 *
1983 * Copyright (C) 2012 Santhosh Thottingal
1984 *
1985 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do anything special to
1986 * choose one license or the other and you don't have to notify anyone which license you are using.
1987 * You are free to use UniversalLanguageSelector in commercial projects as long as the copyright
1988 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
1989 *
1990 * @licence GNU General Public Licence 2.0 or later
1991 * @licence MIT License
1992 */
1993
1994( function ( $ ) {
1995	'use strict';
1996
1997	var MessageStore = function () {
1998		this.messages = {};
1999		this.sources = {};
2000	};
2001
2002	function jsonMessageLoader( url ) {
2003		var deferred = $.Deferred();
2004
2005		$.getJSON( url )
2006			.done( deferred.resolve )
2007			.fail( function ( jqxhr, settings, exception ) {
2008				$.i18n.log( 'Error in loading messages from ' + url + ' Exception: ' + exception );
2009				// Ignore 404 exception, because we are handling fallabacks explicitly
2010				deferred.resolve();
2011			} );
2012
2013		return deferred.promise();
2014	}
2015
2016	/**
2017	 * See https://github.com/wikimedia/jquery.i18n/wiki/Specification#wiki-Message_File_Loading
2018	 */
2019	MessageStore.prototype = {
2020
2021		/**
2022		 * General message loading API This can take a URL string for
2023		 * the json formatted messages.
2024		 * <code>load('path/to/all_localizations.json');</code>
2025		 *
2026		 * This can also load a localization file for a locale <code>
2027		 * load( 'path/to/de-messages.json', 'de' );
2028		 * </code>
2029		 * A data object containing message key- message translation mappings
2030		 * can also be passed Eg:
2031		 * <code>
2032		 * load( { 'hello' : 'Hello' }, optionalLocale );
2033		 * </code> If the data argument is
2034		 * null/undefined/false,
2035		 * all cached messages for the i18n instance will get reset.
2036		 *
2037		 * @param {string|Object} source
2038		 * @param {string} locale Language tag
2039		 * @return {jQuery.Promise}
2040		 */
2041		load: function ( source, locale ) {
2042			var key = null,
2043				deferred = null,
2044				deferreds = [],
2045				messageStore = this;
2046
2047			if ( typeof source === 'string' ) {
2048				// This is a URL to the messages file.
2049				$.i18n.log( 'Loading messages from: ' + source );
2050				deferred = jsonMessageLoader( source )
2051					.done( function ( localization ) {
2052						messageStore.set( locale, localization );
2053					} );
2054
2055				return deferred.promise();
2056			}
2057
2058			if ( locale ) {
2059				// source is an key-value pair of messages for given locale
2060				messageStore.set( locale, source );
2061
2062				return $.Deferred().resolve();
2063			} else {
2064				// source is a key-value pair of locales and their source
2065				for ( key in source ) {
2066					if ( Object.prototype.hasOwnProperty.call( source, key ) ) {
2067						locale = key;
2068						// No {locale} given, assume data is a group of languages,
2069						// call this function again for each language.
2070						deferreds.push( messageStore.load( source[ key ], locale ) );
2071					}
2072				}
2073				return $.when.apply( $, deferreds );
2074			}
2075
2076		},
2077
2078		/**
2079		 * Set messages to the given locale.
2080		 * If locale exists, add messages to the locale.
2081		 *
2082		 * @param {string} locale
2083		 * @param {Object} messages
2084		 */
2085		set: function ( locale, messages ) {
2086			if ( !this.messages[ locale ] ) {
2087				this.messages[ locale ] = messages;
2088			} else {
2089				this.messages[ locale ] = $.extend( this.messages[ locale ], messages );
2090			}
2091		},
2092
2093		/**
2094		 *
2095		 * @param {string} locale
2096		 * @param {string} messageKey
2097		 * @return {boolean}
2098		 */
2099		get: function ( locale, messageKey ) {
2100			return this.messages[ locale ] && this.messages[ locale ][ messageKey ];
2101		}
2102	};
2103
2104	$.extend( $.i18n.messageStore, new MessageStore() );
2105}( jQuery ) );
2106
2107
2108/***/ }),
2109
2110/***/ 25252:
2111/*!***************************************************************!*\
2112  !*** ./runestone/common/js/jquery_i18n/jquery.i18n.parser.js ***!
2113  \***************************************************************/
2114/***/ (() => {
2115
2116/*!
2117 * jQuery Internationalization library
2118 *
2119 * Copyright (C) 2011-2013 Santhosh Thottingal, Neil Kandalgaonkar
2120 *
2121 * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do
2122 * anything special to choose one license or the other and you don't have to
2123 * notify anyone which license you are using. You are free to use
2124 * UniversalLanguageSelector in commercial projects as long as the copyright
2125 * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details.
2126 *
2127 * @licence GNU General Public Licence 2.0 or later
2128 * @licence MIT License
2129 */
2130
2131( function ( $ ) {
2132	'use strict';
2133
2134	var MessageParser = function ( options ) {
2135		this.options = $.extend( {}, $.i18n.parser.defaults, options );
2136		this.language = $.i18n.languages[ String.locale ] || $.i18n.languages[ 'default' ];
2137		this.emitter = $.i18n.parser.emitter;
2138	};
2139
2140	MessageParser.prototype = {
2141
2142		constructor: MessageParser,
2143
2144		simpleParse: function ( message, parameters ) {
2145			return message.replace( /\$(\d+)/g, function ( str, match ) {
2146				var index = parseInt( match, 10 ) - 1;
2147
2148				return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match;
2149			} );
2150		},
2151
2152		parse: function ( message, replacements ) {
2153			if ( message.indexOf( '{{' ) < 0 ) {
2154				return this.simpleParse( message, replacements );
2155			}
2156
2157			this.emitter.language = $.i18n.languages[ $.i18n().locale ] ||
2158				$.i18n.languages[ 'default' ];
2159
2160			return this.emitter.emit( this.ast( message ), replacements );
2161		},
2162
2163		ast: function ( message ) {
2164			var pipe, colon, backslash, anyCharacter, dollar, digits, regularLiteral,
2165				regularLiteralWithoutBar, regularLiteralWithoutSpace, escapedOrLiteralWithoutBar,
2166				escapedOrRegularLiteral, templateContents, templateName, openTemplate,
2167				closeTemplate, expression, paramExpression, result,
2168				pos = 0;
2169
2170			// Try parsers until one works, if none work return null
2171			function choice( parserSyntax ) {
2172				return function () {
2173					var i, result;
2174
2175					for ( i = 0; i < parserSyntax.length; i++ ) {
2176						result = parserSyntax[ i ]();
2177
2178						if ( result !== null ) {
2179							return result;
2180						}
2181					}
2182
2183					return null;
2184				};
2185			}
2186
2187			// Try several parserSyntax-es in a row.
2188			// All must succeed; otherwise, return null.
2189			// This is the only eager one.
2190			function sequence( parserSyntax ) {
2191				var i, res,
2192					originalPos = pos,
2193					result = [];
2194
2195				for ( i = 0; i < parserSyntax.length; i++ ) {
2196					res = parserSyntax[ i ]();
2197
2198					if ( res === null ) {
2199						pos = originalPos;
2200
2201						return null;
2202					}
2203
2204					result.push( res );
2205				}
2206
2207				return result;
2208			}
2209
2210			// Run the same parser over and over until it fails.
2211			// Must succeed a minimum of n times; otherwise, return null.
2212			function nOrMore( n, p ) {
2213				return function () {
2214					var originalPos = pos,
2215						result = [],
2216						parsed = p();
2217
2218					while ( parsed !== null ) {
2219						result.push( parsed );
2220						parsed = p();
2221					}
2222
2223					if ( result.length < n ) {
2224						pos = originalPos;
2225
2226						return null;
2227					}
2228
2229					return result;
2230				};
2231			}
2232
2233			// Helpers -- just make parserSyntax out of simpler JS builtin types
2234
2235			function makeStringParser( s ) {
2236				var len = s.length;
2237
2238				return function () {
2239					var result = null;
2240
2241					if ( message.slice( pos, pos + len ) === s ) {
2242						result = s;
2243						pos += len;
2244					}
2245
2246					return result;
2247				};
2248			}
2249
2250			function makeRegexParser( regex ) {
2251				return function () {
2252					var matches = message.slice( pos ).match( regex );
2253
2254					if ( matches === null ) {
2255						return null;
2256					}
2257
2258					pos += matches[ 0 ].length;
2259
2260					return matches[ 0 ];
2261				};
2262			}
2263
2264			pipe = makeStringParser( '|' );
2265			colon = makeStringParser( ':' );
2266			backslash = makeStringParser( '\\' );
2267			anyCharacter = makeRegexParser( /^./ );
2268			dollar = makeStringParser( '$' );
2269			digits = makeRegexParser( /^\d+/ );
2270			regularLiteral = makeRegexParser( /^[^{}[\]$\\]/ );
2271			regularLiteralWithoutBar = makeRegexParser( /^[^{}[\]$\\|]/ );
2272			regularLiteralWithoutSpace = makeRegexParser( /^[^{}[\]$\s]/ );
2273
2274			// There is a general pattern:
2275			// parse a thing;
2276			// if it worked, apply transform,
2277			// otherwise return null.
2278			// But using this as a combinator seems to cause problems
2279			// when combined with nOrMore().
2280			// May be some scoping issue.
2281			function transform( p, fn ) {
2282				return function () {
2283					var result = p();
2284
2285					return result === null ? null : fn( result );
2286				};
2287			}
2288
2289			// Used to define "literals" within template parameters. The pipe
2290			// character is the parameter delimeter, so by default
2291			// it is not a literal in the parameter
2292			function literalWithoutBar() {
2293				var result = nOrMore( 1, escapedOrLiteralWithoutBar )();
2294
2295				return result === null ? null : result.join( '' );
2296			}
2297
2298			function literal() {
2299				var result = nOrMore( 1, escapedOrRegularLiteral )();
2300
2301				return result === null ? null : result.join( '' );
2302			}
2303
2304			function escapedLiteral() {
2305				var result = sequence( [ backslash, anyCharacter ] );
2306
2307				return result === null ? null : result[ 1 ];
2308			}
2309
2310			choice( [ escapedLiteral, regularLiteralWithoutSpace ] );
2311			escapedOrLiteralWithoutBar = choice( [ escapedLiteral, regularLiteralWithoutBar ] );
2312			escapedOrRegularLiteral = choice( [ escapedLiteral, regularLiteral ] );
2313
2314			function replacement() {
2315				var result = sequence( [ dollar, digits ] );
2316
2317				if ( result === null ) {
2318					return null;
2319				}
2320
2321				return [ 'REPLACE', parseInt( result[ 1 ], 10 ) - 1 ];
2322			}
2323
2324			templateName = transform(
2325				// see $wgLegalTitleChars
2326				// not allowing : due to the need to catch "PLURAL:$1"
2327				makeRegexParser( /^[ !"$&'()*,./0-9;=?@A-Z^_`a-z~\x80-\xFF+-]+/ ),
2328
2329				function ( result ) {
2330					return result.toString();
2331				}
2332			);
2333
2334			function templateParam() {
2335				var expr,
2336					result = sequence( [ pipe, nOrMore( 0, paramExpression ) ] );
2337
2338				if ( result === null ) {
2339					return null;
2340				}
2341
2342				expr = result[ 1 ];
2343
2344				// use a "CONCAT" operator if there are multiple nodes,
2345				// otherwise return the first node, raw.
2346				return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[ 0 ];
2347			}
2348
2349			function templateWithReplacement() {
2350				var result = sequence( [ templateName, colon, replacement ] );
2351
2352				return result === null ? null : [ result[ 0 ], result[ 2 ] ];
2353			}
2354
2355			function templateWithOutReplacement() {
2356				var result = sequence( [ templateName, colon, paramExpression ] );
2357
2358				return result === null ? null : [ result[ 0 ], result[ 2 ] ];
2359			}
2360
2361			templateContents = choice( [
2362				function () {
2363					var res = sequence( [
2364						// templates can have placeholders for dynamic
2365						// replacement eg: {{PLURAL:$1|one car|$1 cars}}
2366						// or no placeholders eg:
2367						// {{GRAMMAR:genitive|{{SITENAME}}}
2368						choice( [ templateWithReplacement, templateWithOutReplacement ] ),
2369						nOrMore( 0, templateParam )
2370					] );
2371
2372					return res === null ? null : res[ 0 ].concat( res[ 1 ] );
2373				},
2374				function () {
2375					var res = sequence( [ templateName, nOrMore( 0, templateParam ) ] );
2376
2377					if ( res === null ) {
2378						return null;
2379					}
2380
2381					return [ res[ 0 ] ].concat( res[ 1 ] );
2382				}
2383			] );
2384
2385			openTemplate = makeStringParser( '{{' );
2386			closeTemplate = makeStringParser( '}}' );
2387
2388			function template() {
2389				var result = sequence( [ openTemplate, templateContents, closeTemplate ] );
2390
2391				return result === null ? null : result[ 1 ];
2392			}
2393
2394			expression = choice( [ template, replacement, literal ] );
2395			paramExpression = choice( [ template, replacement, literalWithoutBar ] );
2396
2397			function start() {
2398				var result = nOrMore( 0, expression )();
2399
2400				if ( result === null ) {
2401					return null;
2402				}
2403
2404				return [ 'CONCAT' ].concat( result );
2405			}
2406
2407			result = start();
2408
2409			/*
2410			 * For success, the pos must have gotten to the end of the input
2411			 * and returned a non-null.
2412			 * n.b. This is part of language infrastructure, so we do not throw an
2413			 * internationalizable message.
2414			 */
2415			if ( result === null || pos !== message.length ) {
2416				throw new Error( 'Parse error at position ' + pos.toString() + ' in input: ' + message );
2417			}
2418
2419			return result;
2420		}
2421
2422	};
2423
2424	$.extend( $.i18n.parser, new MessageParser() );
2425}( jQuery ) );
2426
2427/***/ }),
2428
2429/***/ 66563:
2430/*!***********************************************!*\
2431  !*** ./runestone/common/js/presenter_mode.js ***!
2432  \***********************************************/
2433/***/ (() => {
2434
2435var codeExercises;
2436var presenterCssLink;
2437var presentModeInitialized = false;
2438
2439function presentToggle() {
2440    if (!presentModeInitialized) {
2441        presentModeSetup();
2442        presentModeInitialized = true;
2443    }
2444    let bod = $("body");
2445    let presentClass = "present";
2446    let fullHeightClass = "full-height";
2447    let bottomClass = "bottom";
2448    if (bod.hasClass(presentClass)) {
2449        $("section *")
2450            .not(
2451                "h1, .presentation-title, .btn-presenter, .runestone, .runestone *, section, .pre, code"
2452            )
2453            .removeClass("hidden"); //show everything
2454        $("#completionButton").removeClass("hidden");
2455        bod.removeClass(presentClass);
2456        $("." + fullHeightClass).removeClass(fullHeightClass);
2457        $("." + bottomClass).removeClass(bottomClass);
2458        localStorage.setItem("presentMode", "text");
2459        codeExercises.removeClass("hidden");
2460        presenterCssLink.disabled = true; // disable present_mode.css
2461    } else {
2462        $("section *")
2463            .not(
2464                "h1, .presentation-title, .btn-presenter, .runestone, .runestone *, section, .pre, code"
2465            )
2466            .addClass("hidden"); // hide extraneous stuff
2467        $("#completionButton").addClass("hidden");
2468        bod.addClass(presentClass);
2469        bod.addClass(fullHeightClass);
2470        $("html").addClass(fullHeightClass);
2471        $("section .runestone").addClass(fullHeightClass);
2472        $(".ac-caption").addClass(bottomClass);
2473        localStorage.setItem("presentMode", presentClass);
2474        // presenter_mode.css is loaded by webpack
2475        //loadPresenterCss(); // present_mode.css should only apply when in presenter mode.
2476        activateExercise();
2477    }
2478}
2479
2480function loadPresenterCss() {
2481    presenterCssLink = document.createElement("link");
2482    presenterCssLink.type = "text/css";
2483    presenterCssLink.href = "../_static/presenter_mode.css";
2484    presenterCssLink.rel = "stylesheet";
2485    document.getElementsByTagName("head")[0].appendChild(presenterCssLink);
2486}
2487
2488function presentModeSetup() {
2489    // moved this out of configure
2490    let dataComponent = $("[data-childcomponent]");
2491
2492    // this still leaves some things semi-messed up when you exit presenter mode.
2493    // but instructors will probably just learn to refresh the page.
2494    dataComponent.addClass("runestone");
2495    dataComponent.parent().closest("div").not("section").addClass("runestone");
2496    dataComponent.parent().closest("div").css("max-width", "none");
2497
2498    dataComponent.each(function (index) {
2499        let me = $(this);
2500        $(this)
2501            .find(".ac_code_div, .ac_output")
2502            .wrapAll("<div class='ac-block' style='width: 100%;'></div>");
2503    });
2504
2505    codelensListener(500);
2506    $("section img").wrap('<div class="runestone">');
2507    codeExercises = $(".runestone").not(".runestone .runestone");
2508    // codeExercises.each(function(){
2509    $("h1").before(
2510        "<div class='presentation-title'> \
2511        <button class='prev-exercise btn-presenter btn-grey-outline' onclick='prevExercise()'>Back</button> \
2512        <button class='next-exercise btn-presenter btn-grey-solid' onclick='nextExercise()'>Next</button> \
2513      </div>"
2514    );
2515}
2516function getActiveExercise() {
2517    return (active = codeExercises.filter(".active"));
2518}
2519
2520function activateExercise(index) {
2521    if (typeof index == "undefined") {
2522        index = 0;
2523    }
2524
2525    let active = getActiveExercise();
2526
2527    if (codeExercises.length) {
2528        active.removeClass("active");
2529        active = $(codeExercises[index]).addClass("active");
2530        active.removeClass("hidden");
2531        codeExercises.not(codeExercises.filter(".active")).addClass("hidden");
2532    }
2533}
2534
2535window.nextExercise = function() {
2536    let active = getActiveExercise();
2537    let nextIndex = codeExercises.index(active) + 1;
2538    if (nextIndex < codeExercises.length) {
2539        activateExercise(nextIndex);
2540    }
2541}
2542
2543window.prevExercise = function() {
2544    let active = getActiveExercise();
2545    let prevIndex = codeExercises.index(active) - 1;
2546    if (prevIndex >= 0) {
2547        activateExercise(prevIndex);
2548    }
2549}
2550
2551function configure() {
2552    let rightNav = $(".navbar-right");
2553    rightNav.prepend(
2554        "<li class='dropdown view-toggle'> \
2555      <label>View: \
2556        <select class='mode-select'> \
2557          <option value='text'>Textbook</option> \
2558          <option value='present'>Code Presenter</option> \
2559        </select> \
2560      </label> \
2561    </li>"
2562    );
2563
2564    let modeSelect = $(".mode-select").change(presentToggle);
2565}
2566
2567function codelensListener(duration) {
2568    // $(".ExecutionVisualizer").length ? configureCodelens() : setTimeout(codelensListener, duration);
2569    // configureCodelens();
2570}
2571
2572function configureCodelens() {
2573    let acCodeTitle = document.createElement("h4");
2574    acCodeTitle.textContent = "Active Code Window";
2575    let acCode = $(".ac_code_div");
2576    $(".ac_code_div").addClass("col-md-6");
2577    acCode.prepend(acCodeTitle);
2578
2579    acOutTitle = document.createElement("h4");
2580    acOutTitle.textContent = "Output Window";
2581    let acOut = $(".ac_output").addClass("col-md-6");
2582    $(".ac_output").prepend(acOutTitle);
2583
2584    let sketchpadTitle = document.createElement("h4");
2585    sketchpadTitle.textContent = "Sketchpad";
2586    let sketchpad = document.createElement("span");
2587    $(sketchpad).addClass("sketchpad");
2588    let sketchpadContainer = document.createElement("div");
2589    $(sketchpadContainer).addClass("sketchpad-container");
2590    sketchpadContainer.appendChild(sketchpadTitle);
2591    sketchpadContainer.appendChild(sketchpad);
2592    //$('.ac_output').append(sketchpadContainer);
2593
2594    let visualizers = $(".ExecutionVisualizer");
2595
2596    console.log("Econtainer: ", this.eContainer);
2597
2598    $("[data-childcomponent]").on("click", "button.row-mode", function () {
2599        $(this).closest("[data-childcomponent]").removeClass("card-mode");
2600        $(this).closest("[data-childcomponent]").addClass("row-mode");
2601        $(this).next(".card-mode").removeClass("active-layout");
2602        $(this).addClass("active-layout");
2603    });
2604
2605    $("[data-childcomponent]").on("click", "button.card-mode", function () {
2606        $(this).closest("[data-childcomponent]").removeClass("row-mode");
2607        $(this).closest("[data-childcomponent]").addClass("card-mode");
2608        $(this).prev(".row-mode").removeClass("active-layout");
2609        $(this).addClass("active-layout");
2610    });
2611
2612    $("[data-childcomponent] .ac_section").each(function () {
2613        $(this).prepend(
2614            '<div class="presentation-options"><button class="row-mode layout-btn"><img src="../_images/row-btn-content.png" alt="Rows"></button><button class="card-mode layout-btn"><img src="../_images/card-btn-content.png" alt="Card"></button></div>'
2615        );
2616    });
2617
2618    visualizers.each(function (index) {
2619        let me = $(this);
2620        let col1 = me.find("#vizLayoutTdFirst");
2621        let col2 = me.find("#vizLayoutTdSecond");
2622        let dataVis = me.find("#dataViz");
2623        let stackHeapTable = me.find("#stackHeapTable");
2624        let output = me.find("#progOutputs");
2625        output.css("display", "block");
2626        me.parent().prepend(
2627            "<div class='presentation-title'><div class='title-text'> Example " +
2628                (Number(index) + 1) +
2629                "</div></div>"
2630        );
2631    });
2632
2633    acCode.each(function () {
2634        let section = $(this).closest(".ac-block").parent();
2635        console.log(section, section.length);
2636        section.append(sketchpadContainer);
2637    });
2638
2639    $("button.card-mode").click();
2640
2641    let modeSelect = $(".mode-select");
2642    let mode = localStorage.getItem("presentMode");
2643    if (mode == "present") {
2644        modeSelect.val("present");
2645        modeSelect.change();
2646    }
2647}
2648
2649$(document).on("runestone:login-complete", function () {
2650    // if user is instructor, enable presenter mode
2651    if (eBookConfig.isInstructor) {
2652        configure();
2653    }
2654});
2655
2656
2657/***/ }),
2658
2659/***/ 22538:
2660/*!****************************************!*\
2661  !*** ./runestone/common/js/pretext.js ***!
2662  \****************************************/
2663/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2664
2665"use strict";
2666__webpack_require__.r(__webpack_exports__);
2667/* harmony import */ var _runestonebase_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./runestonebase.js */ 2568);
2668/*
2669    Support functions for PreTeXt books running on Runestone
2670
2671*/
2672
2673
2674
2675function setupPTXEvents() {
2676    let rb = new _runestonebase_js__WEBPACK_IMPORTED_MODULE_0__["default"]();
2677    // log an event when a knowl is opened.
2678    $("[data-knowl").on("click", function () {
2679        let div_id = $(this).data("refid");
2680        rb.logBookEvent({ event: "knowl", act: "click", div_id: div_id });
2681    });
2682    // log an event when a sage cell is evaluated
2683    $(".sagecell_evalButton").on("click", function () {
2684        // find parents
2685        let container = $(this).closest(".sagecell-sage");
2686        let code = $(container[0]).find(".sagecell_input")[0].textContent;
2687        rb.logBookEvent({ event: "sage", act: "run", div_id: container[0].id });
2688    });
2689    if (!eBookConfig.isInstructor) {
2690        $(".commentary").hide();
2691    }
2692}
2693
2694window.addEventListener("load", function () {
2695    console.log("setting up pretext");
2696    setupPTXEvents();
2697    let wrap = document.getElementById("primary-navbar-sticky-wrapper");
2698    if (wrap) {
2699        wrap.style.overflow="visible";
2700    }
2701});
2702
2703
2704/***/ }),
2705
2706/***/ 2568:
2707/*!**********************************************!*\
2708  !*** ./runestone/common/js/runestonebase.js ***!
2709  \**********************************************/
2710/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
2711
2712"use strict";
2713__webpack_require__.r(__webpack_exports__);
2714/* harmony export */ __webpack_require__.d(__webpack_exports__, {
2715/* harmony export */   "default": () => (/* binding */ RunestoneBase)
2716/* harmony export */ });
2717/* harmony import */ var _bookfuncs_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./bookfuncs.js */ 21294);
2718/* ********************************
2719 * |docname| - Runestone Base Class
2720 * ********************************
2721 * All runestone components should inherit from RunestoneBase. In addition all runestone components should do the following things:
2722 *
2723 * 1.   Ensure that they are wrapped in a div with the class runestone
2724 * 2.   Write their source AND their generated html to the database if the database is configured
2725 * 3.   Properly save and restore their answers using the checkServer mechanism in this base class. Each component must provide an implementation of:
2726 *
2727 *      -    checkLocalStorage
2728 *      -    setLocalStorage
2729 *      -    restoreAnswers
2730 *      -    disableInteraction
2731 *
2732 * 4.   provide a Selenium based unit test
2733 */
2734
2735
2736//import "./../styles/runestone-custom-sphinx-bootstrap.css";
2737
2738class RunestoneBase {
2739    constructor(opts) {
2740        this.component_ready_promise = new Promise(
2741            (resolve) => (this._component_ready_resolve_fn = resolve)
2742        );
2743        this.optional = false;
2744        if (typeof window.allComponents === "undefined") {
2745            window.allComponents = [];
2746        }
2747        window.allComponents.push(this);
2748        if (opts) {
2749            this.sid = opts.sid;
2750            this.graderactive = opts.graderactive;
2751            this.showfeedback = true;
2752            if (opts.timed) {
2753                this.isTimed = true;
2754            }
2755            if (opts.enforceDeadline) {
2756                this.deadline = opts.deadline;
2757            }
2758            if ($(opts.orig).data("optional")) {
2759                this.optional = true;
2760            } else {
2761                this.optional = false;
2762            }
2763            if (opts.selector_id) {
2764                this.selector_id = opts.selector_id;
2765            }
2766            if (typeof opts.assessmentTaken !== "undefined") {
2767                this.assessmentTaken = opts.assessmentTaken;
2768            } else {
2769                // default to true as this opt is only provided from a timedAssessment
2770                this.assessmentTaken = true;
2771            }
2772            // This is for the selectquestion points
2773            // If a selectquestion is part of a timed exam it will get
2774            // the timedWrapper options.
2775            if (typeof opts.timedWrapper !== "undefined") {
2776                this.timedWrapper = opts.timedWrapper;
2777            } else {
2778                // However sometimes selectquestions
2779                // are used in regular assignments.  The hacky way to detect this
2780                // is to look for doAssignment in the URL and then grab
2781                // the assignment name from the heading.
2782                if (location.href.indexOf("doAssignment") >= 0) {
2783                    this.timedWrapper = $("h1#assignment_name").text();
2784                } else {
2785                    this.timedWrapper = null;
2786                }
2787            }
2788            if ($(opts.orig).data("question_label")) {
2789                this.question_label = $(opts.orig).data("question_label");
2790            }
2791            this.is_toggle =  true ? opts.is_toggle : 0;
2792            this.is_select =  true ? opts.is_select : 0;
2793
2794        }
2795        this.mjelements = [];
2796        let self = this;
2797        this.mjReady = new Promise(function(resolve, reject) {
2798            self.mjresolver = resolve;
2799        });
2800        this.aQueue = new AutoQueue();
2801        this.jsonHeaders = new Headers({
2802            "Content-type": "application/json; charset=utf-8",
2803            Accept: "application/json",
2804        });
2805    }
2806
2807    // _`logBookEvent`
2808    //----------------
2809    // This function sends the provided ``eventInfo`` to the `hsblog endpoint` of the server. Awaiting this function returns either ``undefined`` (if Runestone services are not available) or the data returned by the server as a JavaScript object (already JSON-decoded).
2810    async logBookEvent(eventInfo) {
2811        if (this.graderactive) {
2812            return;
2813        }
2814        let post_return;
2815        eventInfo.course_name = eBookConfig.course;
2816        eventInfo.clientLoginStatus = eBookConfig.isLoggedIn;
2817        eventInfo.timezoneoffset = new Date().getTimezoneOffset() / 60;
2818        if (typeof(this.percent) === "number") {
2819            eventInfo.percent = this.percent;
2820        }
2821        if (
2822            eBookConfig.isLoggedIn &&
2823            eBookConfig.useRunestoneServices &&
2824            eBookConfig.logLevel > 0
2825        ) {
2826            post_return = this.postLogMessage(eventInfo);
2827        }
2828        if (!this.isTimed || eBookConfig.debug) {
2829            let prefix = eBookConfig.isLoggedIn ? "Save" : "Not";
2830            console.log(`${prefix} logging event ` + JSON.stringify(eventInfo));
2831        }
2832        // When selectquestions are part of an assignment especially toggle questions
2833        // we need to count using the selector_id of the select question.
2834        // We  also need to log an event for that selector so that we will know
2835        // that interaction has taken place.  This is **independent** of how the
2836        // autograder will ultimately grade the question!
2837        if (this.selector_id) {
2838            eventInfo.div_id = this.selector_id.replace(
2839                "-toggleSelectedQuestion",
2840                ""
2841            );
2842            eventInfo.event = "selectquestion";
2843            eventInfo.act = "interaction";
2844            this.postLogMessage(eventInfo);
2845        }
2846        if (
2847            typeof _bookfuncs_js__WEBPACK_IMPORTED_MODULE_0__.pageProgressTracker.updateProgress === "function" &&
2848            eventInfo.act != "edit" &&
2849            this.optional == false
2850        ) {
2851            _bookfuncs_js__WEBPACK_IMPORTED_MODULE_0__.pageProgressTracker.updateProgress(eventInfo.div_id);
2852        }
2853        return post_return;
2854    }
2855
2856    async postLogMessage(eventInfo) {
2857        var post_return;
2858        let request = new Request(
2859            `${eBookConfig.new_server_prefix}/logger/bookevent`, {
2860                method: "POST",
2861                headers: this.jsonHeaders,
2862                body: JSON.stringify(eventInfo),
2863            }
2864        );
2865        try {
2866            var response = await fetch(request);
2867            if (!response.ok) {
2868                if (response.status === 422) {
2869                    // Get details about why this is unprocesable.
2870                    post_return = await response.json();
2871                    console.log(post_return.detail);
2872                    throw new Error("Unprocessable Request");
2873                } else if (response.status == 401) {
2874                    post_return = await response.json();
2875                    console.log(
2876                        `Missing authentication token ${post_return.detail}`
2877                    );
2878                    throw new Error("Missing authentication token");
2879                }
2880                throw new Error(`Failed to save the log entry
2881                    Status: ${response.status}`);
2882            }
2883            post_return = await response.json();
2884        } catch (e) {
2885            let detail = "none";
2886            if (post_return && post_return.detail) {
2887                detail = post_return.detail;
2888            }
2889            if (eBookConfig.loginRequired) {
2890                alert(`Error: Your action was not saved!
2891                    The error was ${e}
2892                    Status Code: ${response.status}
2893                    Detail: ${detail}.
2894                    Please report this error!`);
2895            }
2896            // send a request to save this error
2897            console.log(`Error: ${e} Detail: ${detail} Status Code: ${response.status}`);
2898        }
2899        return post_return;
2900    }
2901    // .. _logRunEvent:
2902    //
2903    // logRunEvent
2904    // -----------
2905    // This function sends the provided ``eventInfo`` to the `runlog endpoint`. When awaited, this function returns the data (decoded from JSON) the server sent back.
2906    async logRunEvent(eventInfo) {
2907        let post_promise = "done";
2908        if (this.graderactive) {
2909            return;
2910        }
2911        eventInfo.course = eBookConfig.course;
2912        eventInfo.clientLoginStatus = eBookConfig.isLoggedIn;
2913        eventInfo.timezoneoffset = new Date().getTimezoneOffset() / 60;
2914        if (this.forceSave || "to_save" in eventInfo === false) {
2915            eventInfo.save_code = "True";
2916        }
2917        if (
2918            eBookConfig.isLoggedIn &&
2919            eBookConfig.useRunestoneServices &&
2920            eBookConfig.logLevel > 0
2921        ) {
2922            let request = new Request(
2923                `${eBookConfig.new_server_prefix}/logger/runlog`, {
2924                    method: "POST",
2925                    headers: this.jsonHeaders,
2926                    body: JSON.stringify(eventInfo),
2927                }
2928            );
2929            let response = await fetch(request);
2930            if (!response.ok) {
2931                post_promise = await response.json();
2932                if (eBookConfig.loginRequired) {
2933                    alert(`Failed to save your code
2934                        Status is ${response.status}
2935                        Detail: ${post_promise.detail}`);
2936                } else {
2937                    console.log(
2938                        `Did not save the code. Status: ${response.status}`
2939                    );
2940                }
2941            } else {
2942                post_promise = await response.json();
2943            }
2944        }
2945        if (!this.isTimed || eBookConfig.debug) {
2946            console.log("running " + JSON.stringify(eventInfo));
2947        }
2948        if (
2949            typeof _bookfuncs_js__WEBPACK_IMPORTED_MODULE_0__.pageProgressTracker.updateProgress === "function" &&
2950            this.optional == false
2951        ) {
2952            _bookfuncs_js__WEBPACK_IMPORTED_MODULE_0__.pageProgressTracker.updateProgress(eventInfo.div_id);
2953        }
2954        return post_promise;
2955    }
2956    /* Checking/loading from storage
2957    **WARNING:**  DO NOT `await` this function!
2958    This function, although async, does not explicitly resolve its promise by returning a value.  The reason for this is because it is called by the constructor for nearly every component.  In Javascript constructors cannot be async!
2959
2960    One of the recommended ways to handle the async requirements from within a constructor is to use an attribute as a promise and resolve that attribute at the appropriate time.
2961    */
2962    async checkServer(
2963        // A string specifying the event name to use for querying the :ref:`getAssessResults` endpoint.
2964        eventInfo,
2965        // If true, this function will invoke ``indicate_component_ready()`` just before it returns. This is provided since most components are ready after this function completes its work.
2966        //
2967        // TODO: This defaults to false, to avoid causing problems with any components that haven't been updated and tested. After all Runestone components have been updated, default this to true and remove the extra parameter from most calls to this function.
2968        will_be_ready = false
2969    ) {
2970        // Check if the server has stored answer
2971        let self = this;
2972        this.checkServerComplete = new Promise(function(resolve, reject) {
2973            self.csresolver = resolve;
2974        });
2975        if (
2976            eBookConfig.isLoggedIn &&
2977            (this.useRunestoneServices || this.graderactive)
2978        ) {
2979            let data = {};
2980            data.div_id = this.divid;
2981            data.course = eBookConfig.course;
2982            data.event = eventInfo;
2983            if (this.graderactive && this.deadline) {
2984                data.deadline = this.deadline;
2985                data.rawdeadline = this.rawdeadline;
2986                data.tzoff = this.tzoff;
2987            }
2988            if (this.sid) {
2989                data.sid = this.sid;
2990            }
2991            if (!(data.div_id && data.course && data.event)) {
2992                console.log(
2993                    `A required field is missing data ${data.div_id}:${data.course}:${data.event}`
2994                );
2995            }
2996            // If we are NOT in practice mode and we are not in a peer exercise
2997            // and assessmentTaken is true
2998            if (
2999                !eBookConfig.practice_mode &&
3000                !eBookConfig.peer &&
3001                this.assessmentTaken
3002            ) {
3003                let request = new Request(
3004                    `${eBookConfig.new_server_prefix}/assessment/results`, {
3005                        method: "POST",
3006                        body: JSON.stringify(data),
3007                        headers: this.jsonHeaders,
3008                    }
3009                );
3010                try {
3011                    let response = await fetch(request);
3012                    if (response.ok) {
3013                        data = await response.json();
3014                        data = data.detail;
3015                        this.repopulateFromStorage(data);
3016                        this.attempted = true;
3017                        if (typeof(data.correct) !== "undefined") {
3018                            this.correct = data.correct;
3019                        } else {
3020                            this.correct = null;
3021                        }
3022                        this.csresolver("server");
3023                    } else {
3024                        console.log(
3025                            `HTTP Error getting results: ${response.statusText}`
3026                        );
3027                        this.checkLocalStorage(); // just go right to local storage
3028                        this.csresolver("local");
3029                    }
3030                } catch (err) {
3031                    try {
3032                        this.checkLocalStorage();
3033                    } catch (err) {
3034                        console.log(err);
3035                    }
3036                }
3037            } else {
3038                this.loadData({});
3039                this.csresolver("not taken");
3040            }
3041        } else {
3042            this.checkLocalStorage(); // just go right to local storage
3043            this.csresolver("local");
3044        }
3045
3046        if (will_be_ready) {
3047            this.indicate_component_ready();
3048        }
3049    }
3050
3051    // This method assumes that ``this.componentDiv`` refers to the ``div`` containing the component, and that this component's ID is set.
3052    indicate_component_ready() {
3053        // Add a class to indicate the component is now ready.
3054        this.containerDiv.classList.add("runestone-component-ready");
3055        // Resolve the ``this.component_ready_promise``.
3056        this._component_ready_resolve_fn();
3057    }
3058
3059    loadData(data) {
3060        // for most classes, loadData doesn't do anything. But for Parsons, and perhaps others in the future,
3061        // initialization can happen even when there's no history to be loaded
3062        return null;
3063    }
3064
3065    /**
3066     * repopulateFromStorage is called after a successful API call is made to ``getAssessResults`` in
3067     * the checkServer method in this class
3068     *
3069     * ``restoreAnswers,`` ``setLocalStorage`` and ``checkLocalStorage`` are defined in the child classes.
3070     *
3071     * @param {*} data - a JSON object representing the data needed to restore a previous answer for a component
3072     * @param {*} status - the http status
3073     * @param {*} whatever - ignored
3074     */
3075    repopulateFromStorage(data) {
3076        // decide whether to use the server's answer (if there is one) or to load from storage
3077        if (data !== null && data !== "no data" && this.shouldUseServer(data)) {
3078            this.restoreAnswers(data);
3079            this.setLocalStorage(data);
3080        } else {
3081            this.checkLocalStorage();
3082        }
3083    }
3084    shouldUseServer(data) {
3085        // returns true if server data is more recent than local storage or if server storage is correct
3086        if (
3087            data.correct === "T" ||
3088            localStorage.length === 0 ||
3089            this.graderactive === true ||
3090            this.isTimed
3091        ) {
3092            return true;
3093        }
3094        let ex = localStorage.getItem(this.localStorageKey());
3095        if (ex === null) {
3096            return true;
3097        }
3098        let storedData;
3099        try {
3100            storedData = JSON.parse(ex);
3101        } catch (err) {
3102            // error while parsing; likely due to bad value stored in storage
3103            console.log(err.message);
3104            localStorage.removeItem(this.localStorageKey());
3105            // definitely don't want to use local storage here
3106            return true;
3107        }
3108        if (data.answer == storedData.answer) return true;
3109        let storageDate = new Date(storedData.timestamp);
3110        let serverDate = new Date(data.timestamp);
3111        return serverDate >= storageDate;
3112    }
3113    // Return the key which to be used when accessing local storage.
3114    localStorageKey() {
3115        return (
3116            eBookConfig.email +
3117            ":" +
3118            eBookConfig.course +
3119            ":" +
3120            this.divid +
3121            "-given"
3122        );
3123    }
3124    addCaption(elType) {
3125        //someElement.parentNode.insertBefore(newElement, someElement.nextSibling);
3126        if (!this.isTimed) {
3127            var capDiv = document.createElement("p");
3128            if (this.question_label) {
3129                this.caption = `Activity: ${this.question_label} ${this.caption}
3129  <span class="runestone_caption_divid">(${this.divid})</span>`;
3130                $(capDiv).html(this.caption);
3131                $(capDiv).addClass(`${elType}_caption`);
3132            } else {
3133                $(capDiv).html(this.caption + " (" + this.divid + ")");
3134                $(capDiv).addClass(`${elType}_caption`);
3135                $(capDiv).addClass(`${elType}_caption_text`);
3136            }
3137            this.capDiv = capDiv;
3138            //this.outerDiv.parentNode.insertBefore(capDiv, this.outerDiv.nextSibling);
3139            this.containerDiv.appendChild(capDiv);
3140        }
3141    }
3142
3143    hasUserActivity() {
3144        return this.isAnswered;
3145    }
3146
3147    checkCurrentAnswer() {
3148        console.log(
3149            "Each component should provide an implementation of checkCurrentAnswer"
3150        );
3151    }
3152
3153    async logCurrentAnswer() {
3154        console.log(
3155            "Each component should provide an implementation of logCurrentAnswer"
3156        );
3157    }
3158    renderFeedback() {
3159        console.log(
3160            "Each component should provide an implementation of renderFeedback"
3161        );
3162    }
3163    disableInteraction() {
3164        console.log(
3165            "Each component should provide an implementation of disableInteraction"
3166        );
3167    }
3168
3169    toString() {
3170        return `${this.constructor.name}: ${this.divid}`;
3171    }
3172
3173    queueMathJax(component) {
3174        if (typeof(MathJax) === "undefined") {
3175            console.log("Error -- MathJax is not loaded")
3176            return Promise.resolve(null);
3177        } else {
3178            // See - https://docs.mathjax.org/en/latest/advanced/typeset.html
3179            // Per the above we should keep track of the promises and only call this
3180            // a second time if all previous promises have resolved.
3181            // Create a queue of components
3182            // should wait until defaultPageReady is defined
3183            // If defaultPageReady is not defined then just enqueue the components.
3184            // Once defaultPageReady is defined
3185            // the window.runestoneMathReady promise will be fulfilled when the
3186            // initial typesetting is complete.
3187            if (MathJax.typesetPromise) {
3188                if (typeof(window.runestoneMathReady) !== "undefined") {
3189                    return window.runestoneMathReady.then(
3190                        () => this.mjresolver(this.aQueue.enqueue(component))
3191                    )
3192                } else {
3193                    return this.mjresolver(this.aQueue.enqueue(component))
3194                }
3195            } else {
3196                console.log(`Waiting on MathJax!! ${MathJax.typesetPromise}`);
3197                setTimeout(() => this.queueMathJax(component), 200);
3198                console.log(`Returning mjready promise: ${this.mjReady}
3198`)
3199                return this.mjReady;
3200            }
3201        }
3202    }
3203
3204    decorateStatus() {
3205        let rsDiv = $(this.containerDiv).closest("div.runestone")[0];
3206        if (this.correct) {
3207            rsDiv.classList.add("isCorrect");
3208        } else {
3209            if (this.correct === null) {
3210                rsDiv.classList.add("notAnswered");
3211            } else {
3212                rsDiv.classList.add("isInCorrect");
3213            }
3214        }
3215    }
3216
3217}
3218
3219
3220// Inspiration and lots of code for this solution come from
3221// https://stackoverflow.com/questions/53540348/js-async-await-tasks-queue
3222// The idea here is that until MathJax is ready we can just enqueue things
3223// once mathjax becomes ready then we can drain the queue and continue as usual.
3224
3225class Queue {
3226    constructor() { this._items = []; }
3227    enqueue(item) { this._items.push(item); }
3228    dequeue() { return this._items.shift(); }
3229    get size() { return this._items.length; }
3230}
3231
3232class AutoQueue extends Queue {
3233    constructor() {
3234        super();
3235        this._pendingPromise = false;
3236    }
3237
3238    enqueue(component) {
3239        return new Promise((resolve, reject) => {
3240            super.enqueue({ component, resolve, reject });
3241            this.dequeue();
3242        });
3243    }
3244
3245    async dequeue() {
3246        if (this._pendingPromise) return false;
3247
3248        let item = super.dequeue();
3249
3250        if (!item) return false;
3251
3252        try {
3253            this._pendingPromise = true;
3254
3255            let payload = await MathJax.startup.defaultPageReady().then(
3256                async function() {
3257                    console.log(`MathJax Ready -- dequeing a typesetting run for ${item.component.id}`)
3258                    return await MathJax.typesetPromise([item.component])
3259                }
3260            );
3261
3262                this._pendingPromise = false; item.resolve(payload);
3263            }
3264            catch (e) {
3265                this._pendingPromise = false;
3266                item.reject(e);
3267            } finally {
3268                this.dequeue();
3269            }
3270
3271            return true;
3272        }
3273    }
3274
3275
3276    window.RunestoneBase = RunestoneBase;
3277
3278
3279/***/ }),
3280
3281/***/ 75106:
3282/*!**************************************!*\
3283  !*** ./runestone/common/js/theme.js ***!
3284  \**************************************/
3285/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3286
3287"use strict";
3288__webpack_require__.r(__webpack_exports__);
3289/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3290/* harmony export */   "getSwitch": () => (/* binding */ getSwitch),
3291/* harmony export */   "switchTheme": () => (/* binding */ switchTheme)
3292/* harmony export */ });
3293function getSwitch() {
3294    const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
3295    const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
3296
3297    if (currentTheme) {
3298        document.documentElement.setAttribute('data-theme', currentTheme);
3299
3300        if (currentTheme === 'dark') {
3301            toggleSwitch.checked = true;
3302        }
3303    }
3304}
3305
3306function switchTheme() {
3307
3308	var checkBox = document.getElementById("checkbox");
3309    if (checkBox.checked == true) {
3310        document.documentElement.setAttribute('data-theme', 'dark');
3311        localStorage.setItem('theme', 'dark'); //add this
3312    }
3313    else {
3314        document.documentElement.setAttribute('data-theme', 'light');
3315        localStorage.setItem('theme', 'light'); //add this
3316    }
3317}
3318
3319
3320/***/ }),
3321
3322/***/ 70114:
3323/*!************************************************!*\
3324  !*** ./runestone/common/js/user-highlights.js ***!
3325  \************************************************/
3326/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3327
3328"use strict";
3329__webpack_require__.r(__webpack_exports__);
3330/* harmony import */ var _css_user_highlights_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../css/user-highlights.css */ 88874);
3331/*global variable declarations*/
3332
3333
3334
3335
3336
3337function getCompletions() {
3338    // Get the completion status
3339    if (
3340        window.location.href.match(
3341            /(index.html|toctree.html|genindex.html|navhelp.html|toc.html|assignments.html|Exercises.html)/
3342        )
3343    ) {
3344        return;
3345    }
3346
3347    var currentPathname = window.location.pathname;
3348    if (currentPathname.indexOf("?") !== -1) {
3349        currentPathname = currentPathname.substring(
3350            0,
3351            currentPathname.lastIndexOf("?")
3352        );
3353    }
3354    var data = {
3355        lastPageUrl: currentPathname,
3356        isPtxBook: isPreTeXt()
3357     };
3358    jQuery
3359        .ajax({
3360            url: `${eBookConfig.new_server_prefix}/logger/getCompletionStatus`,
3361            data: data,
3362            async: false,
3363        })
3364        .done(function (data) {
3365            if (data != "None") {
3366                var completionData = data.detail;
3367                var completionClass, completionMsg;
3368                if (completionData[0].completionStatus == 1) {
3369                    completionClass = "buttonConfirmCompletion";
3370                    completionMsg =
3371                        "<i class='glyphicon glyphicon-ok'></i> Completed. Well Done!";
3372                } else {
3373                    completionClass = "buttonAskCompletion";
3374                    completionMsg = "Mark as Completed";
3375                }
3376                $("#scprogresscontainer").append(
3377                    '<div style="text-align:center"><button class="btn btn-lg ' +
3378                        completionClass +
3379                        '" id="completionButton">' +
3380                        completionMsg +
3381                        "</button></div>"
3382                );
3383            }
3384        });
3385}
3386
3387function showLastPositionBanner() {
3388    var lastPositionVal = $.getUrlVar("lastPosition");
3389    if (typeof lastPositionVal !== "undefined") {
3390        $("body").append(
3391            '<img src="../_static/last-point.png" style="position:absolute; padding-top:55px; left: 10px; top: ' +
3392                parseInt(lastPositionVal) +
3393                'px;"/>'
3394        );
3395        $("html, body").animate({ scrollTop: parseInt(lastPositionVal) }, 1000);
3396    }
3397}
3398
3399function addNavigationAndCompletionButtons() {
3400    if (
3401        window.location.href.match(
3402            /(index.html|genindex.html|navhelp.html|toc.html|assignments.html|Exercises.html|toctree.html)/
3403        )
3404    ) {
3405        return;
3406    }
3407    var navLinkBgRightHiddenPosition = -$("#navLinkBgRight").outerWidth() - 5;
3408    var navLinkBgRightHalfOpen;
3409    var navLinkBgRightFullOpen = 0;
3410
3411    if ($("#completionButton").hasClass("buttonAskCompletion")) {
3412        navLinkBgRightHalfOpen = navLinkBgRightHiddenPosition + 70;
3413    } else if ($("#completionButton").hasClass("buttonConfirmCompletion")) {
3414        navLinkBgRightHalfOpen = 0;
3415    }
3416    var relationsNextIconInitialPosition = $("#relations-next").css("right");
3417    var relationsNextIconNewPosition = -(navLinkBgRightHiddenPosition + 35);
3418
3419    $("#navLinkBgRight").css("right", navLinkBgRightHiddenPosition).show();
3420    var navBgShown = false;
3421    $(window).scroll(function () {
3422        if (
3423            $(window).scrollTop() + $(window).height() ==
3424            $(document).height()
3425        ) {
3426            $("#navLinkBgRight").animate(
3427                { right: navLinkBgRightHalfOpen },
3428                200
3429            );
3430            $("#navLinkBgLeft").animate({ left: "0px" }, 200);
3431            if ($("#completionButton").hasClass("buttonConfirmCompletion")) {
3432                $("#relations-next").animate(
3433                    { right: relationsNextIconNewPosition },
3434                    200
3435                );
3436            }
3437            navBgShown = true;
3438        } else if (navBgShown) {
3439            $("#navLinkBgRight").animate(
3440                { right: navLinkBgRightHiddenPosition },
3441                200
3442            );
3443            $("#navLinkBgLeft").animate({ left: "-65px" }, 200);
3444            $("#relations-next").animate({
3445                right: relationsNextIconInitialPosition,
3446            });
3447            navBgShown = false;
3448        }
3449    });
3450
3451    var completionFlag = 0;
3452    if ($("#completionButton").hasClass("buttonAskCompletion")) {
3453        completionFlag = 0;
3454    } else {
3455        completionFlag = 1;
3456    }
3457    // Make sure we mark this page as visited regardless of how flakey
3458    // the onunload handlers become.
3459    processPageState(completionFlag);
3460    $("#completionButton").on("click", function () {
3461        if ($(this).hasClass("buttonAskCompletion")) {
3462            $(this)
3463                .removeClass("buttonAskCompletion")
3464                .addClass("buttonConfirmCompletion")
3465                .html(
3466                    "<i class='glyphicon glyphicon-ok'></i> Completed. Well Done!"
3467                );
3468            $("#navLinkBgRight").animate({ right: navLinkBgRightFullOpen });
3469            $("#relations-next").animate({
3470                right: relationsNextIconNewPosition,
3471            });
3472            navLinkBgRightHalfOpen = 0;
3473            completionFlag = 1;
3474        } else if ($(this).hasClass("buttonConfirmCompletion")) {
3475            $(this)
3476                .removeClass("buttonConfirmCompletion")
3477                .addClass("buttonAskCompletion")
3478                .html("Mark as Completed");
3479            navLinkBgRightHalfOpen = navLinkBgRightHiddenPosition + 70;
3480            $("#navLinkBgRight").animate({ right: navLinkBgRightHalfOpen });
3481            $("#relations-next").animate({
3482                right: relationsNextIconInitialPosition,
3483            });
3484            completionFlag = 0;
3485        }
3486        processPageState(completionFlag);
3487    });
3488
3489    $(window).on("beforeunload", function (e) {
3490        if (completionFlag == 0) {
3491            processPageState(completionFlag);
3492        }
3493    });
3494}
3495
3496// _ decorateTableOfContents
3497// -------------------------
3498function decorateTableOfContents() {
3499    if (
3500        window.location.href.toLowerCase().indexOf("toc.html") != -1 ||
3501        window.location.href.toLowerCase().indexOf("index.html") != -1
3502    ) {
3503        jQuery.get(
3504            `${eBookConfig.new_server_prefix}/logger/getAllCompletionStatus`,
3505            function (data) {
3506                var subChapterList;
3507                if (data != "None") {
3508                    subChapterList = data.detail;
3509
3510                    var allSubChapterURLs = $("#main-content div li a");
3511                    $.each(subChapterList, function (index, item) {
3512                        for (var s = 0; s < allSubChapterURLs.length; s++) {
3513                            if (
3514                                allSubChapterURLs[s].href.indexOf(
3515                                    item.chapterName + "/" + item.subChapterName
3516                                ) != -1
3517                            ) {
3518                                if (item.completionStatus == 1) {
3519                                    $(allSubChapterURLs[s].parentElement)
3520                                        .addClass("completed")
3521                                        .append(
3522                                            '<span class="infoTextCompleted">- Completed this topic on ' +
3523                                                item.endDate +
3524                                                "</span>"
3525                                        )
3526                                        .children()
3527                                        .first()
3528                                        .hover(
3529                                            function () {
3530                                                $(this)
3531                                                    .next(".infoTextCompleted")
3532                                                    .show();
3533                                            },
3534                                            function () {
3535                                                $(this)
3536                                                    .next(".infoTextCompleted")
3537                                                    .hide();
3538                                            }
3539                                        );
3540                                } else if (item.completionStatus == 0) {
3541                                    $(allSubChapterURLs[s].parentElement)
3542                                        .addClass("active")
3543                                        .append(
3544                                            '<span class="infoTextActive">Last read this topic on ' +
3545                                                item.endDate +
3546                                                "</span>"
3547                                        )
3548                                        .children()
3549                                        .first()
3550                                        .hover(
3551                                            function () {
3552                                                $(this)
3553                                                    .next(".infoTextActive")
3554                                                    .show();
3555                                            },
3556                                            function () {
3557                                                $(this)
3558                                                    .next(".infoTextActive")
3559                                                    .hide();
3560                                            }
3561                                        );
3562                                }
3563                            }
3564                        }
3565                    });
3566                }
3567            }
3568        );
3569        var data = { course: eBookConfig.course };
3570        jQuery.get(
3571            `${eBookConfig.new_server_prefix}/logger/getlastpage`,
3572            data,
3573            function (data) {
3574                var lastPageData;
3575                if (data != "None") {
3576                    lastPageData = data.detail;
3577                    if (lastPageData.lastPageChapter != null) {
3578                        $("#continue-reading")
3579                            .show()
3580                            .html(
3581                                '<div id="jump-to-chapter" class="alert alert-info" ><strong>You were Last Reading:</strong> ' +
3582                                    lastPageData.lastPageChapter +
3583                                    (lastPageData.lastPageSubchapter
3584                                        ? " &gt; " +
3585                                          lastPageData.lastPageSubchapter
3586                                        : "") +
3587                                    ' <a href="' +
3588                                    lastPageData.lastPageUrl +
3589                                    "?lastPosition=" +
3590                                    lastPageData.lastPageScrollLocation +
3591                                    '">Continue Reading</a></div>'
3592                            );
3593                    }
3594                }
3595            }
3596        );
3597    }
3598}
3599
3600function enableCompletions() {
3601    getCompletions();
3602    showLastPositionBanner();
3603    addNavigationAndCompletionButtons();
3604    decorateTableOfContents();
3605}
3606
3607// call enable user highlights after login
3608$(document).on("runestone:login", enableCompletions);
3609
3610function isPreTeXt() {
3611    let ptxMarker = document.querySelector("body.pretext");
3612    if (ptxMarker) {
3613        return true;
3614    } else {
3615        return false;
3616    }
3617}
3618// _ processPageState
3619// -------------------------
3620function processPageState(completionFlag) {
3621    /*Log last page visited*/
3622    var currentPathname = window.location.pathname;
3623    if (currentPathname.indexOf("?") !== -1) {
3624        currentPathname = currentPathname.substring(
3625            0,
3626            currentPathname.lastIndexOf("?")
3627        );
3628    }
3629    // Is this a ptx book?
3630    let isPtxBook = isPreTeXt()
3631    var data = {
3632        lastPageUrl: currentPathname,
3633        lastPageScrollLocation: $(window).scrollTop(),
3634        completionFlag: completionFlag,
3635        course: eBookConfig.course,
3636        isPtxBook: isPtxBook,
3637    };
3638    $(document).ajaxError(function (e, jqhxr, settings, exception) {
3639        console.log("Request Failed for " + settings.url);
3640        console.log(e);
3641    });
3642    jQuery.ajax({
3643        url: `${eBookConfig.new_server_prefix}/logger/updatelastpage`,
3644        contentType: "application/json; charset=utf-8",
3645        dataType: "json",
3646        data: JSON.stringify(data),
3647        method: "POST",
3648        async: true,
3649    });
3650}
3651
3652$.extend({
3653    getUrlVars: function () {
3654        var vars = [],
3655            hash;
3656        var hashes = window.location.search
3657            .slice(window.location.search.indexOf("?") + 1)
3658            .split("&");
3659        for (var i = 0; i < hashes.length; i++) {
3660            hash = hashes[i].split("=");
3661            vars.push(hash[0]);
3662            vars[hash[0]] = hash[1];
3663        }
3664        return vars;
3665    },
3666    getUrlVar: function (name) {
3667        return $.getUrlVars()[name];
3668    },
3669});
3670
3671
3672/***/ }),
3673
3674/***/ 11968:
3675/*!*****************************************************************************************************************!*\
3676  !*** ./runestone/common/project_template/_templates/plugin_layouts/sphinx_bootstrap/static/bootstrap-sphinx.js ***!
3677  \*****************************************************************************************************************/
3678/***/ (() => {
3679
3680(function ($) {
3681  /**
3682   * Patch TOC list.
3683   *
3684   * Will mutate the underlying span to have a correct ul for nav.
3685   *
3686   * @param $span: Span containing nested UL's to mutate.
3687   * @param minLevel: Starting level for nested lists. (1: global, 2: local).
3688   */
3689  var patchToc = function ($ul, minLevel) {
3690    var findA,
3691      patchTables,
3692      $localLi;
3693
3694    // Find all a "internal" tags, traversing recursively.
3695    findA = function ($elem, level) {
3696      level = level || 0;
3697      var $items = $elem.find("> li > a.internal, > ul, > li > ul");
3698
3699      // Iterate everything in order.
3700      $items.each(function (index, item) {
3701        var $item = $(item),
3702          tag = item.tagName.toLowerCase(),
3703          $childrenLi = $item.children('li'),
3704          $parentLi = $($item.parent('li'), $item.parent().parent('li'));
3705
3706        // Add dropdowns if more children and above minimum level.
3707        if (tag === 'ul' && level >= minLevel && $childrenLi.length > 0) {
3708          $parentLi
3709            .addClass('dropdown-submenu')
3710            .children('a').first().attr('tabindex', -1);
3711
3712          $item.addClass('dropdown-menu');
3713        }
3714
3715        findA($item, level + 1);
3716      });
3717    };
3718
3719    findA($ul);
3720  };
3721
3722  /**
3723   * Patch all tables to remove ``docutils`` class and add Bootstrap base
3724   * ``table`` class.
3725   */
3726  patchTables = function () {
3727    $("table.docutils")
3728      .removeClass("docutils")
3729      .addClass("table")
3730      .attr("border", 0);
3731  };
3732
3733$(function () {
3734
3735    /*
3736     * Scroll the window to avoid the topnav bar
3737     * https://github.com/twitter/bootstrap/issues/1768
3738     */
3739    if ($("#navbar.navbar-fixed-top").length > 0) {
3740      var navHeight = $("#navbar").height(),
3741        shiftWindow = function() { scrollBy(0, -navHeight - 10); };
3742
3743      if (location.hash) {
3744        shiftWindow();
3745      }
3746
3747      window.addEventListener("hashchange", shiftWindow);
3748    }
3749
3750    // Add styling, structure to TOC's.
3751    $(".dropdown-menu").each(function () {
3752      $(this).find("ul").each(function (index, item){
3753        var $item = $(item);
3754        $item.addClass('unstyled');
3755      });
3756    });
3757
3758    // Global TOC.
3759    if ($("ul.globaltoc li").length) {
3760      patchToc($("ul.globaltoc"), 1);
3761    } else {
3762      // Remove Global TOC.
3763      $(".globaltoc-container").remove();
3764    }
3765
3766    // Local TOC.
3767    patchToc($("ul.localtoc"), 2);
3768
3769    // Mutate sub-lists (for bs-2.3.0).
3770    $(".dropdown-menu ul").not(".dropdown-menu").each(function () {
3771      var $ul = $(this),
3772        $parent = $ul.parent(),
3773        tag = $parent[0].tagName.toLowerCase(),
3774        $kids = $ul.children().detach();
3775
3776      // Replace list with items if submenu header.
3777      if (tag === "ul") {
3778        $ul.replaceWith($kids);
3779      } else if (tag === "li") {
3780        // Insert into previous list.
3781        $parent.after($kids);
3782        $ul.remove();
3783      }
3784    });
3785
3786    // Add divider in page TOC.
3787    $localLi = $("ul.localtoc li");
3788    if ($localLi.length > 2) {
3789      $localLi.first().after('<li class="divider"></li>');
3790    }
3791
3792    // Enable dropdown.
3793    $('.dropdown-toggle').dropdown();
3794
3795    // Patch tables.
3796    patchTables();
3797
3798    // Add Note, Warning styles.
3799    $('div.note').addClass('alert').addClass('alert-info');
3800    $('div.warning').addClass('alert').addClass('alert-warning');
3801
3802    // Inline code styles to Bootstrap style.
3803    $('tt.docutils.literal').not(".xref").each(function (i, e) {
3804      // ignore references
3805      if (!$(e).parent().hasClass("reference")) {
3806        $(e).replaceWith(function () {
3807          return $("<code />").text($(this).text());
3808        });
3809      }});
3810  });
3811}(window.jQuery));
3812
3813
3814/***/ }),
3815
3816/***/ 36350:
3817/*!**************************!*\
3818  !*** ./webpack.index.js ***!
3819  \**************************/
3820/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3821
3822"use strict";
3823__webpack_require__.r(__webpack_exports__);
3824/* harmony export */ __webpack_require__.d(__webpack_exports__, {
3825/* harmony export */   "runestone_auto_import": () => (/* binding */ runestone_auto_import),
3826/* harmony export */   "runestone_import": () => (/* binding */ runestone_import)
3827/* harmony export */ });
3828/* harmony import */ var jquery_ui_jquery_ui_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery-ui/jquery-ui.js */ 86301);
3829/* harmony import */ var jquery_ui_jquery_ui_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery_ui_jquery_ui_js__WEBPACK_IMPORTED_MODULE_0__);
3830/* harmony import */ var jquery_ui_themes_base_jquery_ui_all_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! jquery-ui/themes/base/jquery.ui.all.css */ 47581);
3831/* harmony import */ var _runestone_common_js_jquery_idle_timer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./runestone/common/js/jquery.idle-timer.js */ 26886);
3832/* harmony import */ var _runestone_common_js_jquery_idle_timer_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_idle_timer_js__WEBPACK_IMPORTED_MODULE_2__);
3833/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.js */ 99283);
3834/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_js__WEBPACK_IMPORTED_MODULE_3__);
3835/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_emitter_bidi_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.emitter.bidi.js */ 43793);
3836/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_emitter_bidi_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_emitter_bidi_js__WEBPACK_IMPORTED_MODULE_4__);
3837/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_emitter_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.emitter.js */ 30423);
3838/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_emitter_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_emitter_js__WEBPACK_IMPORTED_MODULE_5__);
3839/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_fallbacks_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.fallbacks.js */ 9001);
3840/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_fallbacks_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_fallbacks_js__WEBPACK_IMPORTED_MODULE_6__);
3841/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_messagestore_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.messagestore.js */ 34517);
3842/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_messagestore_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_messagestore_js__WEBPACK_IMPORTED_MODULE_7__);
3843/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_parser_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.parser.js */ 25252);
3844/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_parser_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_parser_js__WEBPACK_IMPORTED_MODULE_8__);
3845/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_language_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./runestone/common/js/jquery_i18n/jquery.i18n.language.js */ 64793);
3846/* harmony import */ var _runestone_common_js_jquery_i18n_jquery_i18n_language_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_jquery_i18n_jquery_i18n_language_js__WEBPACK_IMPORTED_MODULE_9__);
3847/* harmony import */ var bootstrap_dist_js_bootstrap_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! bootstrap/dist/js/bootstrap.js */ 43734);
3848/* harmony import */ var bootstrap_dist_js_bootstrap_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(bootstrap_dist_js_bootstrap_js__WEBPACK_IMPORTED_MODULE_10__);
3849/* harmony import */ var bootstrap_dist_css_bootstrap_css__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! bootstrap/dist/css/bootstrap.css */ 97318);
3850/* harmony import */ var _runestone_common_project_template_templates_plugin_layouts_sphinx_bootstrap_static_bootstrap_sphinx_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./runestone/common/project_template/_templates/plugin_layouts/sphinx_bootstrap/static/bootstrap-sphinx.js */ 11968);
3851/* harmony import */ var _runestone_common_project_template_templates_plugin_layouts_sphinx_bootstrap_static_bootstrap_sphinx_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_project_template_templates_plugin_layouts_sphinx_bootstrap_static_bootstrap_sphinx_js__WEBPACK_IMPORTED_MODULE_12__);
3852/* harmony import */ var _runestone_common_css_runestone_custom_sphinx_bootstrap_css__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./runestone/common/css/runestone-custom-sphinx-bootstrap.css */ 64778);
3853/* harmony import */ var _runestone_common_js_bookfuncs_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./runestone/common/js/bookfuncs.js */ 21294);
3854/* harmony import */ var _runestone_common_js_user_highlights_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./runestone/common/js/user-highlights.js */ 70114);
3855/* harmony import */ var _runestone_common_js_pretext_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./runestone/common/js/pretext.js */ 22538);
3856/* harmony import */ var _runestone_matrixeq_css_matrixeq_css__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./runestone/matrixeq/css/matrixeq.css */ 23746);
3857/* harmony import */ var _runestone_webgldemo_css_webglinteractive_css__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./runestone/webgldemo/css/webglinteractive.css */ 86324);
3858/* harmony import */ var _runestone_common_js_theme_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./runestone/common/js/theme.js */ 75106);
3859/* harmony import */ var _runestone_common_js_presenter_mode_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./runestone/common/js/presenter_mode.js */ 66563);
3860/* harmony import */ var _runestone_common_js_presenter_mode_js__WEBPACK_IMPORTED_MODULE_20___default = /*#__PURE__*/__webpack_require__.n(_runestone_common_js_presenter_mode_js__WEBPACK_IMPORTED_MODULE_20__);
3861/* harmony import */ var _runestone_common_css_presenter_mode_css__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./runestone/common/css/presenter_mode.css */ 88288);
3862// ***********************************************************************************
3863// |docname| - A framework allowing a Runestone component to load only the JS it needs
3864// ***********************************************************************************
3865// The JavaScript required by all Runestone components is quite large and results in slow page loads. This approach enables a Runestone component to load only the JavaScript it needs, rather than loading JavaScript for all the components regardless of which are actually used.
3866//
3867// To accomplish this, webpack's split-chunks ability analyzes all JS, starting from this file. The dynamic imports below are transformed by webpack into the dynamic fetches of just the JS required by each file and all its dependencies. (If using static imports, webpack will assume that all files are already statically loaded via script tags, defeating the purpose of this framework.)
3868//
3869// However, this approach leads to complexity:
3870//
3871// -    The ``data-component`` attribute of each component must be kept in sync with the keys of the ``module_map`` below.
3872// -    The values in the ``module_map`` must be kept in sync with the JavaScript files which implement each of the components.
3873
3874
3875
3876// Static imports
3877// ==============
3878// These imports are (we assume) needed by all pages. However, it would be much better to load these in the modules that actually use them.
3879//
3880// These are static imports; code in `dynamically loaded components`_ deals with dynamic imports.
3881//
3882// jQuery-related imports.
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894// Bootstrap
3895
3896
3897
3898
3899
3900// Misc
3901
3902
3903
3904
3905// These belong in dynamic imports for the obvious component; however, these components don't include a ``data-component`` attribute.
3906
3907
3908
3909// These are only needed for the Runestone book, but not in a library mode (such as pretext). I would prefer to dynamically load them. However, these scripts are so small I haven't bothered to do so.
3910
3911
3912
3913
3914// Dynamically loaded components
3915// =============================
3916// This provides a list of modules that components can dynamically import. Webpack will create a list of imports for each based on its analysis.
3917const module_map = {
3918    // Wrap each import in a function, so that it won't occur until the function is called. While something cleaner would be nice, webpack can't analyze things like ``import(expression)``.
3919    //
3920    // The keys must match the value of each component's ``data-component`` attribute -- the ``runestone_import`` and ``runestone_auto_import`` functions assume this.
3921    activecode: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_handsontable_es_index_js-node_modules_handsontable_dist_handsontable_ful-dcc440"), __webpack_require__.e("vendors-node_modules_codemirror_mode_clike_clike_js-node_modules_codemirror_mode_javascript_j-f062af"), __webpack_require__.e("vendors-node_modules_codemirror_addon_edit_matchbrackets_js-node_modules_codemirror_addon_hin-ab90ac"), __webpack_require__.e("runestone_codelens_js_pytutor-embed_bundle_js"), __webpack_require__.e("node_modules_moment_locale_sync_recursive_-runestone_activecode_js_acfactory_js-node_modules_-ef73b3")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/activecode/js/acfactory.js */ 86902)),
3922    ble: () => __webpack_require__.e(/*! import() */ "runestone_cellbotics_js_ble_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/cellbotics/js/ble.js */ 14818)),
3923    // Always import the timed version of a component if available, since the timed components also define the component's factory and include the component as well. Note that ``acfactory`` imports the timed components of ActiveCode, so it follows this pattern.
3924    clickablearea: () =>
3925        Promise.all(/*! import() */[__webpack_require__.e("runestone_clickableArea_js_timedclickable_js"), __webpack_require__.e("runestone_clickableArea_css_clickable_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/clickableArea/js/timedclickable.js */ 61581)),
3926    codelens: () => Promise.all(/*! import() */[__webpack_require__.e("runestone_codelens_js_pytutor-embed_bundle_js"), __webpack_require__.e("runestone_codelens_js_codelens_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/codelens/js/codelens.js */ 12882)),
3927    datafile: () => __webpack_require__.e(/*! import() */ "runestone_datafile_js_datafile_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/datafile/js/datafile.js */ 55789)),
3928    dragndrop: () => Promise.all(/*! import() */[__webpack_require__.e("runestone_dragndrop_js_timeddnd_js"), __webpack_require__.e("runestone_dragndrop_css_dragndrop_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/dragndrop/js/timeddnd.js */ 47496)),
3929    fillintheblank: () => Promise.all(/*! import() */[__webpack_require__.e("runestone_fitb_js_timedfitb_js"), __webpack_require__.e("runestone_fitb_css_fitb_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/fitb/js/timedfitb.js */ 74309)),
3930    groupsub: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_select2_dist_css_select2_css-node_modules_select2_dist_js_select2_min_js"), __webpack_require__.e("runestone_groupsub_js_groupsub_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/groupsub/js/groupsub.js */ 45280)),
3931    khanex: () => __webpack_require__.e(/*! import() */ "runestone_khanex_js_khanex_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/khanex/js/khanex.js */ 13435)),
3932    lp_build: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_codemirror_mode_clike_clike_js-node_modules_codemirror_mode_javascript_j-f062af"), __webpack_require__.e("runestone_lp_js_lp_js-node_modules_codemirror_lib_codemirror_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/lp/js/lp.js */ 2013)),
3933    multiplechoice: () => Promise.all(/*! import() */[__webpack_require__.e("runestone_mchoice_js_timedmc_js"), __webpack_require__.e("runestone_mchoice_css_mchoice_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/mchoice/js/timedmc.js */ 95983)),
3934    hparsons: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_handsontable_es_index_js-node_modules_handsontable_dist_handsontable_ful-dcc440"), __webpack_require__.e("vendors-node_modules_micro-parsons_micro-parsons_micro-parsons_js-node_modules_micro-parsons_-974bff"), __webpack_require__.e("node_modules_moment_locale_sync_recursive_-runestone_hparsons_js_hp
3934arsons_js-node_modules_mic-5ea6d2")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/hparsons/js/hparsons.js */ 58722)),
3935    parsons: () => __webpack_require__.e(/*! import() */ "runestone_parsons_js_timedparsons_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/parsons/js/timedparsons.js */ 79661)),
3936    poll: () => __webpack_require__.e(/*! import() */ "runestone_poll_js_poll_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/poll/js/poll.js */ 37350)),
3937    quizly: () => __webpack_require__.e(/*! import() */ "runestone_quizly_js_quizly_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/quizly/js/quizly.js */ 16207)),
3938    reveal: () => __webpack_require__.e(/*! import() */ "runestone_reveal_js_reveal_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/reveal/js/reveal.js */ 12632)),
3939    selectquestion: () => Promise.all(/*! import() */[__webpack_require__.e("runestone_selectquestion_js_selectone_js"), __webpack_require__.e("runestone_selectquestion_css_selectquestion_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/selectquestion/js/selectone.js */ 63931)),
3940    shortanswer: () =>
3941        Promise.all(/*! import() */[__webpack_require__.e("runestone_shortanswer_js_timed_shortanswer_js"), __webpack_require__.e("runestone_shortanswer_css_shortanswer_css")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/shortanswer/js/timed_shortanswer.js */ 87483)),
3942    showeval: () => __webpack_require__.e(/*! import() */ "runestone_showeval_js_showEval_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/showeval/js/showEval.js */ 6224)),
3943    simple_sensor: () => __webpack_require__.e(/*! import() */ "runestone_cellbotics_js_simple_sensor_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/cellbotics/js/simple_sensor.js */ 72389)),
3944    spreadsheet: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_jexcel_dist_jexcel_js-node_modules_jexcel_dist_jexcel_css"), __webpack_require__.e("runestone_spreadsheet_js_spreadsheet_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/spreadsheet/js/spreadsheet.js */ 60611)),
3945    tabbedStuff: () => __webpack_require__.e(/*! import() */ "runestone_tabbedStuff_js_tabbedstuff_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/tabbedStuff/js/tabbedstuff.js */ 97887)),
3946    timedAssessment: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_handsontable_es_index_js-node_modules_handsontable_dist_handsontable_ful-dcc440"), __webpack_require__.e("vendors-node_modules_codemirror_mode_clike_clike_js-node_modules_codemirror_mode_javascript_j-f062af"), __webpack_require__.e("vendors-node_modules_codemirror_addon_edit_matchbrackets_js-node_modules_codemirror_addon_hin-ab90ac"), __webpack_require__.e("runestone_codelens_js_pytutor-embed_bundle_js"), __webpack_require__.e("node_modules_moment_locale_sync_recursive_-runestone_activecode_js_acfactory_js-node_modules_-ef73b3"), __webpack_require__.e("runestone_parsons_js_timedparsons_js"), __webpack_require__.e("runestone_dragndrop_js_timeddnd_js"), __webpack_require__.e("runestone_mchoice_js_timedmc_js"), __webpack_require__.e("runestone_selectquestion_js_selectone_js"), __webpack_require__.e("runestone_clickableArea_js_timedclickable_js"), __webpack_require__.e("runestone_fitb_js_timedfitb_js"), __webpack_require__.e("runestone_shortanswer_js_timed_shortanswer_js"), __webpack_require__.e("runestone_timed_js_timed_js-runestone_clickableArea_css_clickable_css-runestone_dragndrop_css-8bfd54")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/timed/js/timed.js */ 58707)),
3947    wavedrom: () => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_wavedrom_skins_default_js-node_modules_wavedrom_wavedrom_min_js"), __webpack_require__.e("runestone_wavedrom_js_wavedrom_js")]).then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/wavedrom/js/wavedrom.js */ 32405)),
3948    // TODO: since this isn't in a ``data-component``, need to trigger an import of this code manually.
3949    webwork: () => __webpack_require__.e(/*! import() */ "runestone_webwork_js_webwork_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/webwork/js/webwork.js */ 66142)),
3950    youtube: () => __webpack_require__.e(/*! import() */ "runestone_video_js_runestonevideo_js").then(__webpack_require__.bind(__webpack_require__, /*! ./runestone/video/js/runestonevideo.js */ 48657)),
3951};
3952
3953// .. _dynamic import machinery:
3954//
3955// Dynamic import machinery
3956// ========================
3957// Fulfill a promise when the Runestone pre-login complete event occurs.
3958let pre_login_complete_promise = new Promise((resolve) =>
3959    $(document).on("runestone:pre-login-complete", resolve)
3960);
3961let loadedComponents;
3962// Provide a simple function to import the JS for all components on the page.
3963function runestone_auto_import() {
3964    // Create a set of ``data-component`` values, to avoid duplication.
3965    const s = new Set(
3966        // All Runestone components have a ``data-component`` attribute.
3967        $("[data-component]")
3968            .map(
3969                // Extract the value of the data-component attribute.
3970                (index, element) => $(element).attr("data-component")
3971                // Switch from a jQuery object back to an array, passing that to the Set constructor.
3972            )
3973            .get()
3974    );
3975    // webwork questions are not wrapped in div with a data-component so we have to check a different way
3976    if (document.querySelector(".webwork-button")) {
3977        s.add("webwork");
3978    }
3979
3980    // Load JS for each of the components found.
3981    const a = [...s].map((value) =>
3982        // If there's no JS for this component, return an empty Promise.
3983        (module_map[value] || (() => Promise.resolve()))()
3984    );
3985
3986    // Send the Runestone login complete event when all JS is loaded and the pre-login is also complete.
3987    Promise.all([pre_login_complete_promise, ...a]).then(() =>
3988        $(document).trigger("runestone:login-complete")
3989    );
3990}
3991
3992// Load component JS when the document is ready.
3993$(document).ready(runestone_auto_import);
3994
3995// Provide a function to import one specific Runestone component.
3996// the import function inside module_map is async -- runestone_import
3997// should be awaited when necessary to ensure the import completes
3998async function runestone_import(component_name) {
3999    return module_map[component_name]();
4000}
4001
4002async function popupScratchAC() {
4003    // load the activecode bundle
4004    await runestone_import("activecode");
4005    // scratchDiv will be defined if we have already created a scratch
4006    // activecode.  If its not defined then we need to get it ready to toggle
4007    if (!eBookConfig.scratchDiv) {
4008        window.ACFactory.createScratchActivecode();
4009        let divid = eBookConfig.scratchDiv;
4010        window.edList[divid] = ACFactory.createActiveCode(
4011            $(`#${divid}`)[0],
4012            eBookConfig.acDefaultLanguage
4013        );
4014        if (eBookConfig.isLoggedIn) {
4015            window.edList[divid].enableSaveLoad();
4016        }
4017    }
4018    window.ACFactory.toggleScratchActivecode();
4019}
4020
4021// Set the directory containing this script as the `path <https://webpack.js.org/guides/public-path/#on-the-fly>`_ for all webpacked scripts.
4022const script_src = document.currentScript.src;
4023__webpack_require__.p = script_src.substring(
4024    0,
4025    script_src.lastIndexOf("/") + 1
4026);
4027
4028// Manual exports
4029// ==============
4030// Webpack's ``output.library`` setting doesn't seem to work with the split chunks plugin; do all exports manually through the ``window`` object instead.
4031const rc = {};
4032rc.runestone_import = runestone_import;
4033rc.runestone_auto_import = runestone_auto_import;
4034rc.getSwitch = _runestone_common_js_theme_js__WEBPACK_IMPORTED_MODULE_19__.getSwitch;
4035rc.switchTheme = _runestone_common_js_theme_js__WEBPACK_IMPORTED_MODULE_19__.switchTheme;
4036rc.popupScratchAC = popupScratchAC;
4037window.runestoneComponents = rc;
4038
4039
4040/***/ }),
4041
4042/***/ 65311:
4043/*!*************************!*\
4044  !*** external "jQuery" ***!
4045  \*************************/
4046/***/ ((module) => {
4047
4048"use strict";
4049module.exports = jQuery;
4050
4051/***/ })
4052
4053},
4054/******/ __webpack_require__ => { // webpackRuntimeModules
4055/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
4056/******/ __webpack_require__.O(0, ["vendors-node_modules_bootstrap_dist_js_bootstrap_js-node_modules_jquery-ui_jquery-ui_js-node_-72cd89"], () => (__webpack_exec__(36350)));
4057/******/ var __webpack_exports__ = __webpack_require__.O();
4058/******/ }
4059]);
4060//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuZXN0b25lLjBkY2I5YjcyNjlkNDkyYWUuYnVuZGxlLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7Ozs7O0FDQUE7Ozs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7Ozs7Ozs7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBOztBQUVBO0FBQ0E7O0F
4060BRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJELGNBQWMsS0FBSyxhQUFhO0FBQzNGLGFBQWE7QUFDYixVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixLQUFLLGNBQWM7QUFDckMsYUFBYTtBQUNiLFVBQVU7QUFDVjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWLCtCQUErQjtBQUMvQjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRU87O0FBRVA7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0M7QUFDL0M7QUFDQSxTQUFTO0FBQ1QscUJBQXFCO0FBQ3JCO0FBQ0EsZUFBZSw4QkFBOEI7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELG9CQUFvQjtBQUM3RTtBQUNBO0FBQ0EsVUFBVTtBQUNWLG9EQUFvRCxFQUFFO0FBQ3REO0FBQ0E7QUFDQSx1Q0FBdUMsc0JBQXNCO0FBQzdEO0FBQ0EsNEJBQTRCLHFCQUFxQjtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtIQUFrSDtBQUNsSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0RBQXdELE1BQU07QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsNENBQTRDO0FBQ2hFO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLENBQUM7Ozs7Ozs7Ozs7O0FDdlVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGdDQUFnQztBQUNoQzs7O0FBR0E7QUFDQTtBQUNBLEVBQUU7OztBQUdGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQSxnQ0FBZ0M7O0FBRWhDO0FBQ0EsZ0NBQWdDOztBQUVoQzs7OztBQUlBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDRCQUE0Qjs7QUFFNUI7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDhFQUE4RTtBQUM5RTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7OztBQUdGOztBQUVBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLOzs7QUFHTDtBQUNBO0FBQ0EsZUFBZSxPQUFPO0FBQ3RCLGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7Ozs7QUFJQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQixnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7O0FBSUEsR0FBRzs7O0FBR0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQSxDQUFDOzs7Ozs7Ozs7OztBQ3JRRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrREFBK0Q7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksUUFBUTtBQUNwQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxVQUFVO0FBQ3ZCLGNBQWMsUUFBUTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUM7Ozs7Ozs7Ozs7O0FDN0ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0F
4060BRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCLGFBQWEsT0FBTztBQUNwQixjQUFjLE9BQU87QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOztBQUVQOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCLGNBQWM7QUFDZDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQixhQUFhLE9BQU87QUFDcEIsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLE9BQU8sY0FBYyxjQUFjLEdBQUcsT0FBTyxHQUFHLFFBQVE7QUFDckUsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQSxPQUFPLDBDQUEwQztBQUNqRDtBQUNBLGFBQWEsT0FBTyxjQUFjLE9BQU8sR0FBRyxPQUFPLEdBQUcsUUFBUSxHQUFHLFFBQVE7QUFDekUsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsZUFBZSxvQkFBb0I7QUFDbkM7QUFDQSxhQUFhLE9BQU8sYUFBYSwwQkFBMEIsR0FBRyxZQUFZO0FBQzFFLGNBQWMsUUFBUTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLENBQUM7Ozs7Ozs7Ozs7O0FDdktEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTt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O0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNB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OztBQUV4QztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsQ0FBQzs7Ozs7Ozs7OztBQ3JURDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUMsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEI7QUFDOUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0RBQStEO0FBQy9ELEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7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PQUEwQztBQUNwRSxvQkFBb0Isc1RBQTZDO0FBQ2pFLGtCQUFrQix3S0FBeUM7QUFDM0Qsb0JBQW9CLCtVQUFpQztBQUNyRCwwQkFBMEIsc1BBQTJDO0FBQ3JFLG9CQUFvQiwrZkFBNkM7QUFDakUsbUJBQW1CLHNMQUFnRDtBQUNuRSxnQkFBZ0IsZ0tBQXFDO0FBQ3JELGtCQUFrQix3S0FBeUM7QUFDM0Qsa0JBQWtCLHdLQUF5QztBQUMzRCwwQkFBMEIsc1JBQW9EO0FBQzlFO0FBQ0EsUUFBUSwwUkFBeUQ7QUFDakUsb0JBQW9CLCtLQUE2QztBQUNqRSx5QkFBeUIsOExBQW9EO0FBQzdFLHVCQUF1QixtVEFBbUQ7QUFDMUUsdUJBQXVCLDRMQUFtRDtBQUMxRSwyQkFBMkIsZ3dDQUF1QztBQUNsRSxvQkFBb0IsNlNBQTZDO0FBQ2pFO0FBQ0EsbUJBQW1CLDRLQUEyQztBQUM5RCxtQkFBbUIsc0x
4060BQWdEO0FBQ25FOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixNQUFNO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHFCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJGQUEyRjtBQUMzRjtBQUNBO0FBQ0E7QUFDQSxlQUFlLHFFQUFTO0FBQ3hCLGlCQUFpQix1RUFBVztBQUM1QjtBQUNBOzs7Ozs7Ozs7Ozs7QUMvS0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9jc3MvcHJlc2VudGVyX21vZGUuY3NzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2Nzcy9ydW5lc3RvbmUtY3VzdG9tLXNwaGlueC1ib290c3RyYXAuY3NzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2Nzcy91c2VyLWhpZ2hsaWdodHMuY3NzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvbWF0cml4ZXEvY3NzL21hdHJpeGVxLmNzcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL3dlYmdsZGVtby9jc3Mvd2ViZ2xpbnRlcmFjdGl2ZS5jc3MiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy8uL3J1bmVzdG9uZS9jb21tb24vanMvYm9va2Z1bmNzLmpzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2pzL2pxdWVyeS5pZGxlLXRpbWVyLmpzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2pzL2pxdWVyeV9pMThuL2pxdWVyeS5pMThuLmVtaXR0ZXIuYmlkaS5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5lbWl0dGVyLmpzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2pzL2pxdWVyeV9pMThuL2pxdWVyeS5pMThuLmZhbGxiYWNrcy5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5sYW5ndWFnZS5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5tZXNzYWdlc3RvcmUuanMiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy8uL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4ucGFyc2VyLmpzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2pzL3ByZXNlbnRlcl9tb2RlLmpzIiwid2VicGFjazovL1dlYkNvbXBvbmVudHMvLi9ydW5lc3RvbmUvY29tbW9uL2pzL3ByZXRleHQuanMiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy8uL3J1bmVzdG9uZS9jb21tb24vanMvcnVuZXN0b25lYmFzZS5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy90aGVtZS5qcyIsIndlYnBhY2s6Ly9XZWJDb21wb25lbnRzLy4vcnVuZXN0b25lL2NvbW1vbi9qcy91c2VyLWhpZ2hsaWdodHMuanMiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy8uL3J1bmVzdG9uZS9jb21tb24vcHJvamVjdF90ZW1wbGF0ZS9fdGVtcGxhdGVzL3BsdWdpbl9sYXlvdXRzL3NwaGlueF9ib290c3RyYXAvc3RhdGljL2Jvb3RzdHJhcC1zcGhpbnguanMiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy8uL3dlYnBhY2suaW5kZXguanMiLCJ3ZWJwYWNrOi8vV2ViQ29tcG9uZW50cy9leHRlcm5hbCB2YXIgXCJqUXVlcnlcIiJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB7fTsiLCIvKipcbiAqXG4gKiBVc2VyOiBibWlsbGVyXG4gKiBPcmlnaW5hbDogMjAxMS0wNC0yMFxuICogRGF0ZTogMjAxOS0wNi0xNFxuICogVGltZTogMjowMSBQTVxuICogVGhpcyBjaGFuZ2UgbWFya3MgdGhlIGJlZ2lubmluZyBvZiB2ZXJzaW9uIDQuMCBvZiB0aGUgcnVuZXN0b25lIGNvbXBvbmVudHNcbiAqIExvZ2luL2xvZ291dCBpcyBubyBsb25nZXIgaGFuZGxlZCB0aHJvdWdoIGphdmFzY3JpcHQgYnV0IHJhdGhlciBzZXJ2ZXIgc2lkZS5cbiAqIE1hbnkgb2YgdGhlIGNvbXBvbmVudHMgZGVwZW5kIG9uIHRoZSBydW5lc3RvbmU6bG9naW4gZXZlbnQgc28gd2Ugd2lsbCBrZWVwIHRoYXRcbiAqIGZvciBub3cgdG8ga2VlcCB0aGUgY2h1cm4gZmFpcmx5IG1pbmltYWwuXG4gKi9cblxuLypcblxuIENvcHlyaWdodCAoQykgMjAxMSAgQnJhZCBNaWxsZXIgIGJvbmVsYWtlQGdtYWlsLmNvbVxuXG4gVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cblxuIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG5cbiBZb3Ugc2hvdWxkIGhh
4060dmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuXG4gKi9cblxuLy9cbi8vIFBhZ2UgZGVjb3JhdGlvbiBmdW5jdGlvbnNcbi8vXG5cbmZ1bmN0aW9uIGFkZFJlYWRpbmdMaXN0KCkge1xuICAgIGlmIChlQm9va0NvbmZpZy5yZWFkaW5ncykge1xuICAgICAgICB2YXIgbCwgbnh0LCBwYXRoX3BhcnRzLCBueHRfbGluaztcbiAgICAgICAgbGV0IGN1cl9wYXRoX3BhcnRzID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLnNwbGl0KFwiL1wiKTtcbiAgICAgICAgbGV0IG5hbWUgPVxuICAgICAgICAgICAgY3VyX3BhdGhfcGFydHNbY3VyX3BhdGhfcGFydHMubGVuZ3RoIC0gMl0gK1xuICAgICAgICAgICAgXCIvXCIgK1xuICAgICAgICAgICAgY3VyX3BhdGhfcGFydHNbY3VyX3BhdGhfcGFydHMubGVuZ3RoIC0gMV07XG4gICAgICAgIGxldCBwb3NpdGlvbiA9IGVCb29rQ29uZmlnLnJlYWRpbmdzLmluZGV4T2YobmFtZSk7XG4gICAgICAgIGxldCBudW1fcmVhZGluZ3MgPSBlQm9va0NvbmZpZy5yZWFkaW5ncy5sZW5ndGg7XG4gICAgICAgIGlmIChwb3NpdGlvbiA9PSBlQm9va0NvbmZpZy5yZWFkaW5ncy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAvLyBubyBtb3JlIHJlYWRpbmdzXG4gICAgICAgICAgICBsID0gJChcIjxkaXYgLz5cIiwge1xuICAgICAgICAgICAgICAgIHRleHQ6IGBGaW5pc2hlZCByZWFkaW5nIGFzc2lnbm1lbnQuIFBhZ2UgJHtudW1fcmVhZGluZ3N9IG9mICR7bnVtX3JlYWRpbmdzfS5gLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPj0gMCkge1xuICAgICAgICAgICAgLy8gZ2V0IG5leHQgbmFtZVxuICAgICAgICAgICAgbnh0ID0gZUJvb2tDb25maWcucmVhZGluZ3NbcG9zaXRpb24gKyAxXTtcbiAgICAgICAgICAgIHBhdGhfcGFydHMgPSBjdXJfcGF0aF9wYXJ0cy5zbGljZSgwLCBjdXJfcGF0aF9wYXJ0cy5sZW5ndGggLSAyKTtcbiAgICAgICAgICAgIHBhdGhfcGFydHMucHVzaChueHQpO1xuICAgICAgICAgICAgbnh0X2xpbmsgPSBwYXRoX3BhcnRzLmpvaW4oXCIvXCIpO1xuICAgICAgICAgICAgbCA9ICQoXCI8YSAvPlwiLCB7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJsaW5rXCIsXG4gICAgICAgICAgICAgICAgY2xhc3M6IFwiYnRuIGJ0bi1sZyAnICsgJ2J1dHRvbkNvbmZpcm1Db21wbGV0aW9uJ1wiLFxuICAgICAgICAgICAgICAgIGhyZWY6IG54dF9saW5rLFxuICAgICAgICAgICAgICAgIHRleHQ6IGBDb250aW51ZSB0byBwYWdlICR7XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uICsgMlxuICAgICAgICAgICAgICAgIH0gb2YgJHtudW1fcmVhZGluZ3N9IGluIHRoZSByZWFkaW5nIGFzc2lnbm1lbnQuYCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbCA9ICQoXCI8ZGl2IC8+XCIsIHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBcIlRoaXMgcGFnZSBpcyBub3QgcGFydCBvZiB0aGUgbGFzdCByZWFkaW5nIGFzc2lnbm1lbnQgeW91IHZpc2l0ZWQuXCIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAkKFwiI21haW4tY29udGVudFwiKS5hcHBlbmQobCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiB0aW1lZFJlZnJlc2goKSB7XG4gICAgdmFyIHRpbWVvdXRQZXJpb2QgPSA5MDAwMDA7IC8vIDc1IG1pbnV0ZXNcbiAgICAkKGRvY3VtZW50KS5vbihcImlkbGUuaWRsZVRpbWVyXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gQWZ0ZXIgdGltZW91dCBwZXJpb2Qgc2VuZCB0aGUgdXNlciBiYWNrIHRvIHRoZSBpbmRleC4gIFRoaXMgd2lsbCBmb3JjZSBhIGxvZ2luXG4gICAgICAgIC8vIGlmIG5lZWRlZCB3aGVuIHRoZXkgd2FudCB0byBnbyB0byBhIHBhcnRpY3VsYXIgcGFnZS4gIFRoaXMgbWF5IG5vdCBiZSBwZXJmZWN0XG4gICAgICAgIC8vIGJ1dCBpdHMgYW4gZWFzeSB3YXkgdG8gbWFrZSBzdXJlIGxhcHRvcCB1c2VycyBhcmUgcHJvcGVybHkgbG9nZ2VkIGluIHdoZW4gdGhleVxuICAgICAgICAvLyB0YWtlIHF1aXp6ZXMgYW5kIHNhdmUgc3R1ZmYuXG4gICAgICAgIGlmIChsb2NhdGlvbi5ocmVmLmluZGV4T2YoXCJpbmRleC5odG1sXCIpIDwgMCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJJZGxlIHRpbWVyIC0gXCIgKyBsb2NhdGlvbi5wYXRobmFtZSk7XG4gICAgICAgICAgICBsb2NhdGlvbi5ocmVmID1cbiAgICAgICAgICAgICAgICBlQm9va0NvbmZpZy5hcHAgK1xuICAgICAgICAgICAgICAgIFwiL2RlZmF1bHQvdXNlci9sb2dpbj9fbmV4dD1cIiArXG4gICAgICAgICAgICAgICAgbG9jYXRpb24ucGF0aG5hbWUgK1xuICAgICAgICAgICAgICAgIGxvY2F0aW9uLnNlYXJjaDtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgICQuaWRsZVRpbWVyKHRpbWVvdXRQZXJpb2QpO1xufVxuXG5jbGFzcyBQYWdlUHJvZ3Jlc3NCYXIge1xuICAgIGNvbnN0cnVjdG9yKGFjdERpY3QpIHtcbiAgICAgICAgdGhpcy5wb3NzaWJsZSA9IDA7XG4gICAgICAgIHRoaXMudG90YWwgPSAxO1xuICAgICAgICBpZiAoYWN0RGljdCAmJiBPYmplY3Qua2V5cyhhY3REaWN0KS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2aXRpZXMgPSBhY3REaWN0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGFjdGl2aXRpZXMgPSB7IHBhZ2U6IDAgfTtcbiAgICAgICAgICAgICQoXCIucnVuZXN0b25lXCIpLmVhY2goZnVuY3Rpb24gKGlkeCwgZSkge1xuICAgICAgICAgICAgICAgIGFjdGl2aXRpZXNbZS5maXJzdEVsZW1lbnRDaGlsZC5pZF0gPSAwO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmFjdGl2aXRpZXMgPSBhY3Rpdml0aWVzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2FsY3VsYXRlUHJvZ3Jlc3MoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLm1hdGNoKFxuICAgICAgICAgICAgICAgIC8uKihpbmRleC5odG1sfHRvY3RyZWUuaHRtbHxFeGVyY2lzZXMuaHRtbHxzZWFyY2guaHRtbCkkL2lcbiAgICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgICAkKFwiI3NjcHJvZ3Jlc3Njb250YWluZXJcIikuaGlkZSgpO1xuICAgICAgICB9XG4gICAgICAgI
4060HRoaXMucmVuZGVyUHJvZ3Jlc3MoKTtcbiAgICB9XG5cbiAgICBjYWxjdWxhdGVQcm9ncmVzcygpIHtcbiAgICAgICAgZm9yIChsZXQgayBpbiB0aGlzLmFjdGl2aXRpZXMpIHtcbiAgICAgICAgICAgIGlmIChrICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBvc3NpYmxlKys7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuYWN0aXZpdGllc1trXSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b3RhbCsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbmRlclByb2dyZXNzKCkge1xuICAgICAgICBsZXQgdmFsdWUgPSAwO1xuICAgICAgICAkKFwiI3NjcHJvZ3Jlc3N0b3RhbFwiKS50ZXh0KHRoaXMudG90YWwpO1xuICAgICAgICAkKFwiI3NjcHJvZ3Jlc3Nwb3NzXCIpLnRleHQodGhpcy5wb3NzaWJsZSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YWx1ZSA9ICgxMDAgKiB0aGlzLnRvdGFsKSAvIHRoaXMucG9zc2libGU7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHZhbHVlID0gMDtcbiAgICAgICAgfVxuICAgICAgICAkKFwiI3N1YmNoYXB0ZXJwcm9ncmVzc1wiKS5wcm9ncmVzc2Jhcih7XG4gICAgICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIWVCb29rQ29uZmlnLmlzTG9nZ2VkSW4pIHtcbiAgICAgICAgICAgICQoXCIjc3ViY2hhcHRlcnByb2dyZXNzPmRpdlwiKS5hZGRDbGFzcyhcImxvZ2dlZG91dFwiKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZVByb2dyZXNzKGRpdl9pZCkge1xuICAgICAgICB0aGlzLmFjdGl2aXRpZXNbZGl2X2lkXSsrO1xuICAgICAgICAvLyBPbmx5IHVwZGF0ZSB0aGUgcHJvZ3Jlc3MgYmFyIG9uIHRoZSBmaXJzdCBpbnRlcmFjdGlvbiB3aXRoIGFuIG9iamVjdC5cbiAgICAgICAgaWYgKHRoaXMuYWN0aXZpdGllc1tkaXZfaWRdID09PSAxKSB7XG4gICAgICAgICAgICB0aGlzLnRvdGFsKys7XG4gICAgICAgICAgICBsZXQgdmFsID0gKDEwMCAqIHRoaXMudG90YWwpIC8gdGhpcy5wb3NzaWJsZTtcbiAgICAgICAgICAgICQoXCIjc2Nwcm9ncmVzc3RvdGFsXCIpLnRleHQodGhpcy50b3RhbCk7XG4gICAgICAgICAgICAkKFwiI3NjcHJvZ3Jlc3Nwb3NzXCIpLnRleHQodGhpcy5wb3NzaWJsZSk7XG4gICAgICAgICAgICAkKFwiI3N1YmNoYXB0ZXJwcm9ncmVzc1wiKS5wcm9ncmVzc2JhcihcIm9wdGlvblwiLCBcInZhbHVlXCIsIHZhbCk7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgdmFsID09IDEwMC4wICYmXG4gICAgICAgICAgICAgICAgJChcIiNjb21wbGV0aW9uQnV0dG9uXCIpLnRleHQoKS50b0xvd2VyQ2FzZSgpID09PVxuICAgICAgICAgICAgICAgICAgICBcIm1hcmsgYXMgY29tcGxldGVkXCJcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICQoXCIjY29tcGxldGlvbkJ1dHRvblwiKS5jbGljaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgdmFyIHBhZ2VQcm9ncmVzc1RyYWNrZXIgPSB7fTtcblxuYXN5bmMgZnVuY3Rpb24gaGFuZGxlUGFnZVNldHVwKCkge1xuICAgIHZhciBtZXNzO1xuICAgIGlmIChlQm9va0NvbmZpZy51c2VSdW5lc3RvbmVTZXJ2aWNlcykge1xuICAgICAgICBsZXQgaGVhZGVycyA9IG5ldyBIZWFkZXJzKHtcbiAgICAgICAgICAgIFwiQ29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOFwiLFxuICAgICAgICAgICAgQWNjZXB0OiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgICAgfSk7XG4gICAgICAgIGxldCBkYXRhID0geyB0aW1lem9uZW9mZnNldDogbmV3IERhdGUoKS5nZXRUaW1lem9uZU9mZnNldCgpIC8gNjAgfTtcbiAgICAgICAgbGV0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdChcbiAgICAgICAgICAgIGAke2VCb29rQ29uZmlnLm5ld19zZXJ2ZXJfcHJlZml4fS9sb2dnZXIvc2V0X3R6X29mZnNldGAsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShkYXRhKSxcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gocmVxdWVzdCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHNldCB0aW1lem9uZSEgJHtyZXNwb25zZS5zdGF0dXNUZXh0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3Igc2V0dGluZyB0aW1lem9uZSAke2V9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc29sZS5sb2coYFRoaXMgcGFnZSBzZXJ2ZWQgYnkgJHtlQm9va0NvbmZpZy5zZXJ2ZWRfYnl9YCk7XG4gICAgaWYgKGVCb29rQ29uZmlnLmlzTG9nZ2VkSW4pIHtcbiAgICAgICAgbWVzcyA9IGB1c2VybmFtZTogJHtlQm9va0NvbmZpZy51c2VybmFtZX1gO1xuICAgICAgICBpZiAoIWVCb29rQ29uZmlnLmlzSW5zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgJChcIiNpcF9kcm9wZG93bl9saW5rXCIpLnJlbW92ZSgpO1xuICAgICAgICAgICAgJChcIiNpbnN0X3BlZXJfbGlua1wiKS5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgICAkKGRvY3VtZW50KS50cmlnZ2VyKFwicnVuZXN0b25lOmxvZ2luXCIpO1xuICAgICAgICBhZGRSZWFkaW5nTGlzdCgpO1xuICAgICAgICAvLyBBdm9pZCB0aGUgdGltZWRSZWZyZXNoIG9uIHRoZSBncmFkaW5nIHBhZ2UuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZS5pbmRleE9mKFwiL2FkbWluL2dyYWRpbmdcIikgPT0gLTEgJiZcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZS5pbmRleE9mKFwiL3BlZXIvXCIpID09IC0xXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGltZWRSZWZyZXNoKCk7XG4gICAgICAgI
4060H1cbiAgICB9IGVsc2Uge1xuICAgICAgICBtZXNzID0gXCJOb3QgbG9nZ2VkIGluXCI7XG4gICAgICAgICQoZG9jdW1lbnQpLnRyaWdnZXIoXCJydW5lc3RvbmU6bG9nb3V0XCIpO1xuICAgICAgICBsZXQgYncgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImJyb3dzaW5nX3dhcm5pbmdcIik7XG4gICAgICAgIGlmIChidykge1xuICAgICAgICAgICAgYncuaW5uZXJIVE1MID1cbiAgICAgICAgICAgICAgICBcIjxwIGNsYXNzPSduYXZiYXJfbWVzc2FnZSc+U2F2aW5nIGFuZCBMb2dnaW5nIGFyZSBEaXNhYmxlZDwvcD5cIjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYXcgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImFkX3dhcm5pbmdcIik7XG4gICAgICAgIGlmIChhdykge1xuICAgICAgICAgICAgYXcuaW5uZXJIVE1MID1cbiAgICAgICAgICAgICAgICBcIjxwIGNsYXNzPSduYXZiYXJfbWVzc2FnZSc+8J+aqyBMb2ctaW4gdG8gUmVtb3ZlIDxhIGhyZWY9Jy9ydW5lc3RvbmUvZGVmYXVsdC9hZHMnPkFkcyE8L2E+IPCfmqsgJm5ic3A7PC9wPlwiO1xuICAgICAgICB9XG4gICAgfVxuICAgICQoXCIubG9nZ2VkaW51c2VyXCIpLmh0bWwobWVzcyk7XG5cbiAgICBwYWdlUHJvZ3Jlc3NUcmFja2VyID0gbmV3IFBhZ2VQcm9ncmVzc0JhcihlQm9va0NvbmZpZy5hY3Rpdml0aWVzKTtcbiAgICBub3RpZnlSdW5lc3RvbmVDb21wb25lbnRzKCk7XG59XG5cbmZ1bmN0aW9uIHNldHVwTmF2YmFyTG9nZ2VkSW4oKSB7XG4gICAgJChcIiNwcm9maWxlbGlua1wiKS5zaG93KCk7XG4gICAgJChcIiNwYXNzd29yZGxpbmtcIikuc2hvdygpO1xuICAgICQoXCIjcmVnaXN0ZXJsaW5rXCIpLmhpZGUoKTtcbiAgICAkKFwibGkubG9naW5vdXRcIikuaHRtbChcbiAgICAgICAgJzxhIGhyZWY9XCInICsgZUJvb2tDb25maWcuYXBwICsgJy9kZWZhdWx0L3VzZXIvbG9nb3V0XCI+TG9nIE91dDwvYT4nXG4gICAgKTtcbn1cbiQoZG9jdW1lbnQpLm9uKFwicnVuZXN0b25lOmxvZ2luXCIsIHNldHVwTmF2YmFyTG9nZ2VkSW4pO1xuXG5mdW5jdGlvbiBzZXR1cE5hdmJhckxvZ2dlZE91dCgpIHtcbiAgICBpZiAoZUJvb2tDb25maWcudXNlUnVuZXN0b25lU2VydmljZXMpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJzZXR1cCBuYXZiYXIgZm9yIGxvZ2dlZCBvdXRcIik7XG4gICAgICAgICQoXCIjcmVnaXN0ZXJsaW5rXCIpLnNob3coKTtcbiAgICAgICAgJChcIiNwcm9maWxlbGlua1wiKS5oaWRlKCk7XG4gICAgICAgICQoXCIjcGFzc3dvcmRsaW5rXCIpLmhpZGUoKTtcbiAgICAgICAgJChcIiNpcF9kcm9wZG93bl9saW5rXCIpLmhpZGUoKTtcbiAgICAgICAgJChcIiNpbnN0X3BlZXJfbGlua1wiKS5oaWRlKCk7XG4gICAgICAgICQoXCJsaS5sb2dpbm91dFwiKS5odG1sKFxuICAgICAgICAgICAgJzxhIGhyZWY9XCInICsgZUJvb2tDb25maWcuYXBwICsgJy9kZWZhdWx0L3VzZXIvbG9naW5cIj5Mb2dpbjwvYT4nXG4gICAgICAgICk7XG4gICAgICAgICQoXCIuZm9vdGVyXCIpLmh0bWwoXCJ1c2VyIG5vdCBsb2dnZWQgaW5cIik7XG4gICAgfVxufVxuJChkb2N1bWVudCkub24oXCJydW5lc3RvbmU6bG9nb3V0XCIsIHNldHVwTmF2YmFyTG9nZ2VkT3V0KTtcblxuZnVuY3Rpb24gbm90aWZ5UnVuZXN0b25lQ29tcG9uZW50cygpIHtcbiAgICAvLyBSdW5lc3RvbmUgY29tcG9uZW50cyB3YWl0IHVudGlsIGxvZ2luIHByb2Nlc3MgaXMgb3ZlciB0byBsb2FkIGNvbXBvbmVudHMgYmVjYXVzZSBvZiBzdG9yYWdlIGlzc3Vlcy4gVGhpcyB0cmlnZ2VycyB0aGUgYGR5bmFtaWMgaW1wb3J0IG1hY2hpbmVyeWAsIHdoaWNoIHRoZW4gc2VuZHMgdGhlIGxvZ2luIGNvbXBsZXRlIHNpZ25hbCB3aGVuIHRoaXMgYW5kIGFsbCBkeW5hbWljIGltcG9ydHMgYXJlIGZpbmlzaGVkLlxuICAgICQoZG9jdW1lbnQpLnRyaWdnZXIoXCJydW5lc3RvbmU6cHJlLWxvZ2luLWNvbXBsZXRlXCIpO1xufVxuXG5mdW5jdGlvbiBwbGFjZUFkQ29weSgpIHtcbiAgICBpZiAodHlwZW9mIHNob3dBZCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzaG93QWQpIHtcbiAgICAgICAgbGV0IGFkTnVtID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMikgKyAxO1xuICAgICAgICBsZXQgYWRCbG9jayA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBhZGNvcHlfJHthZE51bX1gKTtcbiAgICAgICAgbGV0IHJzRWxlbWVudHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLnJ1bmVzdG9uZVwiKTtcbiAgICAgICAgaWYgKHJzRWxlbWVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbGV0IHJhbmRvbUluZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogcnNFbGVtZW50cy5sZW5ndGgpO1xuICAgICAgICAgICAgcnNFbGVtZW50c1tyYW5kb21JbmRleF0uYWZ0ZXIoYWRCbG9jaylcbiAgICAgICAgICAgIGFkQmxvY2suc3R5bGUuZGlzcGxheSA9IFwiYmxvY2tcIjtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gaW5pdGlhbGl6ZSBzdHVmZlxuJChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGVCb29rQ29uZmlnKSB7XG4gICAgICAgIGhhbmRsZVBhZ2VTZXR1cCgpO1xuICAgICAgICBwbGFjZUFkQ29weSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0eXBlb2YgZUJvb2tDb25maWcgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgIFwiZUJvb2tDb25maWcgaXMgbm90IGRlZmluZWQuICBUaGlzIHBhZ2UgbXVzdCBub3QgYmUgc2V0IHVwIGZvciBSdW5lc3RvbmVcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cbn0pO1xuXG4vLyBtaXNjIHN0dWZmXG4vLyB0b2RvOiAgVGhpcyBjb3VsZCBiZSBmdXJ0aGVyIGRpc3RyaWJ1dGVkIGJ1dCBtYWtpbmcgYSB2aWRlby5qcyBmaWxlIGp1c3QgZm9yIG9uZSBmdW5jdGlvbiBzZWVtcyBkdW1iLlxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBhZGQgdGhlIHZpZGVvIHBsYXkgYnV0dG9uIG92ZXJsYXkgaW1hZ2VcbiAgICAkKFwiLnZpZGVvLXBsYXktb3ZlcmxheVwiKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJCh0aGlzKS5jc3MoXG4gICAgICAgICAgICBcImJhY2tncm91bmQtaW1hZ2VcIixcbiAgICAgICAgICAgIFwidXJsKCd7e3BhdGh0bygnX3N0YXRpYy9wbGF5X292ZXJsYXlfaWNvb
4060i5wbmcnLCAxKX19JylcIlxuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBuZWVkZWQgdG8gYWxsb3cgdGhlIGRyb3Bkb3duIHNlYXJjaCBiYXIgdG8gd29yaztcbiAgICAvLyBUaGUgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdGhhdCB0aGUgZHJvcGRvd24gbWVudSBjbG9zZXMgd2hlbiBzb21ldGhpbmcgaW5cbiAgICAvLyBpdCAobGlrZSB0aGUgc2VhcmNoIGJhcikgaXMgY2xpY2tlZFxuICAgICQoZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBGaXggaW5wdXQgZWxlbWVudCBjbGljayBwcm9ibGVtXG4gICAgICAgICQoXCIuZHJvcGRvd24gaW5wdXQsIC5kcm9wZG93biBsYWJlbFwiKS5jbGljayhmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyByZS13cml0ZSBzb21lIHVybHNcbiAgICAvLyBUaGlzIGlzIHRyaWNrZXIgdGhhbiBpdCBsb29rcyBhbmQgeW91IGhhdmUgdG8gb2JleSB0aGUgcnVsZXMgZm9yICMgYW5jaG9yc1xuICAgIC8vIFRoZSAjYW5jaG9ycyBtdXN0IGNvbWUgYWZ0ZXIgdGhlIHF1ZXJ5IHN0cmluZyBhcyB0aGUgc2VydmVyIGJhc2ljYWxseSBpZ25vcmVzIGFueSBwYXJ0XG4gICAgLy8gb2YgYSB1cmwgdGhhdCBjb21lcyBhZnRlciAjIC0gbGlrZSBhIGNvbW1lbnQuLi5cbiAgICBpZiAobG9jYXRpb24uaHJlZi5pbmNsdWRlcyhcIm1vZGU9YnJvd3NpbmdcIikpIHtcbiAgICAgICAgbGV0IHF1ZXJ5U3RyaW5nID0gXCI/bW9kZT1icm93c2luZ1wiO1xuICAgICAgICBkb2
4060N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiYVwiKS5mb3JFYWNoKChsaW5rKSA9PiB7XG4gICAgICAgICAgICBsZXQgYW5jaG9yVGV4dCA9IFwiXCI7XG4gICAgICAgICAgICBpZiAobGluay5ocmVmLmluY2x1ZGVzKFwiYm9va3MvcHVibGlzaGVkXCIpICYmICEgbGluay5ocmVmLmluY2x1ZGVzKFwiP21vZGU9YnJvd3NpbmdcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAobGluay5ocmVmLmluY2x1ZGVzKFwiI1wiKSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgYVBvaW50ID0gbGluay5ocmVmLmluZGV4T2YoXCIjXCIpO1xuICAgICAgICAgICAgICAgICAgICBhbmNob3JUZXh0ID0gbGluay5ocmVmLnN1YnN0cmluZyhhUG9pbnQpO1xuICAgICAgICAgICAgICAgICAgICBsaW5rLmhyZWYgPSBsaW5rLmhyZWYuc3Vic3RyaW5nKDAsYVBvaW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGluay5ocmVmID0gbGluay5ocmVmLmluY2x1ZGVzKFwiP1wiKVxuICAgICAgICAgICAgICAgICAgICA/IGxpbmsuaHJlZiArIHF1ZXJ5U3RyaW5nLnJlcGxhY2UoXCI/XCIsIFwiJlwiKSArIGFuY2hvclRleHRcbiAgICAgICAgICAgICAgICAgICAgOiBsaW5rLmhyZWYgKyBxdWVyeVN0cmluZyArIGFuY2hvclRleHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn0pO1xuIiwiLyohXG4gKiBqUXVlcnkgaWRsZVRpbWVyIHBsdWdpblxuICogdmVyc2lvbiAwLjkuMTAwNTExXG4gKiBieSBQYXVsIElyaXNoLlxuICogICBodHRwOi8vZ2l0aHViLmNvbS9wYXVsaXJpc2gveXVpLW1pc2MvdHJlZS9cbiAqIE1JVCBsaWNlbnNlXG5cbiAqIGFkYXB0ZWQgZnJvbSBZVUkgaWRsZSB0aW1lciBieSBuemFrYXM6XG4gKiAgIGh0dHA6Ly9naXRodWIuY29tL256YWthcy95dWktbWlzYy9cbiovXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDA5IE5pY2hvbGFzIEMuIFpha2FzXG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbiAqIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG4vKiB1cGRhdGVkIHRvIGZpeCBDaHJvbWUgc2V0VGltZW91dCBpc3N1ZSBieSBaYWlkIFphd2FpZGVoICovXG5cbiAvLyBBUEkgYXZhaWxhYmxlIGluIDw9IHYwLjhcbiAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG4gLy8gaWRsZVRpbWVyKCkgdGFrZXMgYW4gb3B0aW9uYWwgYXJndW1lbnQgdGhhdCBkZWZpbmVzIHRoZSBpZGxlIHRpbWVvdXRcbiAvLyB0aW1lb3V0IGlzIGluIG1pbGxpc2Vjb25kczsgZGVmYXVsdHMgdG8gMzAwMDBcbiAkLmlkbGVUaW1lcigxMDAwMCk7XG5cblxuICQoZG9jdW1lbnQpLmJpbmQoXCJpZGxlLmlkbGVUaW1lclwiLCBmdW5jdGlvbigpe1xuICAgIC8vIGZ1bmN0aW9uIHlvdSB3YW50IHRvIGZpcmUgd2hlbiB0aGUgdXNlciBnb2VzIGlkbGVcbiB9KTtcblxuXG4gJChkb2N1bWVudCkuYmluZChcImFjdGl2ZS5pZGxlVGltZXJcIiwgZnVuY3Rpb24oKXtcbiAgLy8gZnVuY3Rpb24geW91IHdhbnQgdG8gZmlyZSB3aGVuIHRoZSB1c2VyIGJlY29tZXMgYWN0aXZlIGFnYWluXG4gfSk7XG5cbiAvLyBwYXNzIHRoZSBzdHJpbmcgJ2Rlc3Ryb3knIHRvIHN0b3AgdGhlIHRpbWVyXG4gJC5pZGxlVGltZXIoJ2Rlc3Ryb3knKTtcblxuIC8vIHlvdSBjYW4gcXVlcnkgaWYgdGhlIHVzZXIgaXMgaWRsZSBvciBub3Qgd2l0aCBkYXRhKClcbiAkLmRhdGEoZG9jdW1lbnQsJ2lkbGVUaW1lcicpOyAgLy8gJ2lkbGUnICBvciAnYWN0aXZlJ1xuXG4gLy8geW91IGNhbiBnZXQgdGltZSBlbGFwc2VkIHNpbmNlIHVzZXIgd2hlbiBpZGxlL2FjdGl2ZVxuICQuaWRsZVRpbWVyKCdnZXRFbGFwc2VkVGltZScpOyAvLyB0aW1lIHNpbmNlIHN0YXRlIGNoYW5nZSBpbiBtc1xuXG4gKioqKioqKiovXG5cblxuXG4gLy8gQVBJIGF2YWlsYWJsZSBpbiA+PSB2MC45XG4gLyoqKioqKioqKioqKioqKioqKioqKioqKipcblxuIC8vIGJpbmQgdG8gc3BlY2lmaWMgZWxlbWVudHMsIGFsbG93cyBmb3IgbXVsdGlwbGUgdGltZXIgaW5zdGFuY2VzXG4gJChlbGVtKS5pZGxlVGltZXIodGltZW91dHwnZGVzdHJveSd8J2dldEVsYXBzZWRUaW1lJyk7XG4gJC5kYXRhKGVsZW0sJ2lkbGVUaW
40601lcicpOyAgLy8gJ2lkbGUnICBvciAnYWN0aXZlJ1xuXG4gLy8gaWYgeW91J3JlIHVzaW5nIHRoZSBvbGQgJC5pZGxlVGltZXIgYXBpLCB5b3Ugc2hvdWxkIG5vdCBkbyAkKGRvY3VtZW50KS5pZGxlVGltZXIoLi4uKVxuXG4gLy8gZWxlbWVudCBib3VuZCB0aW1lcnMgd2lsbCBvbmx5IHdhdGNoIGZvciBldmVudHMgaW5zaWRlIG9mIHRoZW0uXG4gLy8geW91IG1heSBqdXN0IHdhbnQgcGFnZS1sZXZlbCBhY3Rpdml0eSwgaW4gd2hpY2ggY2FzZSB5b3UgbWF5IHNldCB1cFxuIC8vICAgeW91ciB0aW1lcnMgb24gZG9jdW1lbnQsIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgYW5kIGRvY3VtZW50LmJvZHlcblxuIC8vIFlvdSBjYW4gb3B0aW9uYWxseSBwcm92aWRlIGEgc2Vjb25kIGFyZ3VtZW50IHRvIG92ZXJyaWRlIGNlcnRhaW4gb3B0aW9ucy5cbiAvLyBIZXJlIGFyZSB0aGUgZGVmYXVsdHMsIHNvIHlvdSBjYW4gb21pdCBhbnkgb3IgYWxsIG9mIHRoZW0uXG4gJChlbGVtKS5pZGxlVGltZXIodGltZW91dCwge1xuICAgc3RhcnRJbW1lZGlhdGVseTogdHJ1ZSwgLy9zdGFydHMgYSB0aW1lb3V0IGFzIHNvb24gYXMgdGhlIHRpbWVyIGlzIHNldCB1cDsgb3RoZXJ3aXNlIGl0IHdhaXRzIGZvciB0aGUgZmlyc3QgZXZlbnQuXG4gICBpZGxlOiAgICBmYWxzZSwgICAgICAgICAvL2luZGljYXRlcyBpZiB0aGUgdXNlciBpcyBpZGxlXG4gICBlbmFibGVkOiB0cnVlLCAgICAgICAgICAvL2luZGljYXRlcyBpZiB0aGUgaWRsZSB0aW1lciBpcyBlbmFibGVkXG4gICBldmVudHM6ICAnbW91c2Vtb3ZlIGtleWRvd24gRE9NTW91c2VTY3JvbGwgbW91c2V3aGVlbCBtb3VzZWRvd24gdG91Y2hzdGFydCB0b3VjaG1vdmUnIC8vIGFjdGl2aXR5IGlzIG9uZSBvZiB0aGVzZSBldmVudHNcbiB9KTtcblxuICoqKioqKioqL1xuXG4oZnVuY3Rpb24oJCl7XG5cbiQuaWRsZVRpbWVyID0gZnVuY3Rpb24obmV3VGltZW91dCwgZWxlbSwgb3B0cyl7XG5cbiAgICAvLyBkZWZhdWx0cyB0aGF0IGFyZSB0byBiZSBzdG9yZWQgYXMgaW5zdGFuY2UgcHJvcHMgb24gdGhlIGVsZW1cblxuXHRvcHRzID0gJC5leHRlbmQoe1xuXHRcdHN0YXJ0SW1tZWRpYXRlbHk6IHRydWUsIC8vc3RhcnRzIGEgdGltZW91dCBhcyBzb29uIGFzIHRoZSB0aW1lciBpcyBzZXQgdXBcblx0XHRpZGxlOiAgICBmYWxzZSwgICAgICAgICAvL2luZGljYXRlcyBpZiB0aGUgdXNlciBpcyBpZGxlXG5cdFx0ZW5hYmxlZDogdHJ1ZSwgICAgICAgICAgLy9pbmRpY2F0ZXMgaWYgdGhlIGlkbGUgdGltZXIgaXMgZW5hYmxlZFxuXHRcdHRpbWVvdXQ6IDMwMDAwLCAgICAgICAgIC8vdGhlIGFtb3VudCBvZiB0aW1lIChtcykgYmVmb3JlIHRoZSB1c2VyIGlzIGNvbnNpZGVyZWQgaWRsZVxuXHRcdGV2ZW50czogICdtb3VzZW1vdmUga2V5ZG93biBET01Nb3VzZVNjcm9sbCBtb3VzZXdoZWVsIG1vdXNlZG93biB0b3VjaHN0YXJ0IHRvdWNobW92ZScgLy8gYWN0aXZpdHkgaXMgb25lIG9mIHRoZXNlIGV2ZW50c1xuXHR9LCBvcHRzKTtcblxuXG4gICAgZWxlbSA9IGVsZW0gfHwgZG9jdW1lbnQ7XG5cbiAgICAvKiAoaW50ZW50aW9uYWxseSBub3QgZG9jdW1lbnRlZClcbiAgICAgKiBUb2dnbGVzIHRoZSBpZGxlIHN0YXRlIGFuZCBmaXJlcyBhbiBhcHByb3ByaWF0ZSBldmVudC5cbiAgICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgICAqL1xuICAgIHZhciB0b2dnbGVJZGxlU3RhdGUgPSBmdW5jdGlvbihteWVsZW0pe1xuXG4gICAgICAgIC8vIGN1cnNlIHlvdSwgbW96aWxsYSBzZXRUaW1lb3V0IGxhdGVuZXNzIGJ1ZyFcbiAgICAgICAgaWYgKHR5cGVvZiBteWVsZW0gPT09ICdudW1iZXInKXtcbiAgICAgICAgICAgIG15ZWxlbSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBvYmogPSAkLmRhdGEobXllbGVtIHx8IGVsZW0sJ2lkbGVUaW1lck9iaicpO1xuXG4gICAgICAgIC8vdG9nZ2xlIHRoZSBzdGF0ZVxuICAgICAgICBvYmouaWRsZSA9ICFvYmouaWRsZTtcblxuICAgICAgICAvLyByZXNldCB0aW1lb3V0IFxuICAgICAgICB2Y
4060XIgZWxhcHNlZCA9ICgrbmV3IERhdGUoKSkgLSBvYmoub2xkZGF0ZTtcbiAgICAgICAgb2JqLm9sZGRhdGUgPSArbmV3IERhdGUoKTtcblxuICAgICAgICAvLyBoYW5kbGUgQ2hyb21lIGFsd2F5cyB0cmlnZ2VyaW5nIGlkbGUgYWZ0ZXIganMgYWxlcnQgb3IgY29tZmlybSBwb3B1cFxuICAgICAgICBpZiAob2JqLmlkbGUgJiYgKGVsYXBzZWQgPCBvcHRzLnRpbWVvdXQpKSB7XG4gICAgICAgICAgICAgICAgb2JqLmlkbGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoJC5pZGxlVGltZXIudElkKTtcbiAgICAgICAgICAgICAgICBpZiAob3B0cy5lbmFibGVkKVxuICAgICAgICAgICAgICAgICAgJC5pZGxlVGltZXIudElkID0gc2V0VGltZW91dCh0b2dnbGVJZGxlU3RhdGUsIG9wdHMudGltZW91dCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvL2ZpcmUgYXBwcm9wcmlhdGUgZXZlbnRcblxuICAgICAgICAvLyBjcmVhdGUgYSBjdXN0b20gZXZlbnQsIGJ1dCBmaXJzdCwgc3RvcmUgdGhlIG5ldyBzdGF0ZSBvbiB0aGUgZWxlbWVudFxuICAgICAgICAvLyBhbmQgdGhlbiBhcHBlbmQgdGhhdCBzdHJpbmcgdG8gYSBuYW1lc3BhY2VcbiAgICAgICAgdmFyIGV2ZW50ID0galF1ZXJ5LkV2ZW50KCAkLmRhdGEoZWxlbSwnaWRsZVRpbWVyJywgb2JqLmlkbGUgPyBcImlkbGVcIiA6IFwiYWN0aXZlXCIgKSAgKyAnLmlkbGVUaW1lcicgICApO1xuXG4gICAgICAgIC8vIHdlIGRvIHdhbnQgdGhpcyB0byBidWJibGUsIGF0IGxlYXN0IGFzIGEgdGVtcG9yYXJ5IGZpeCBmb3IgalF1ZXJ5IDEuN1xuICAgICAgICAvLyBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgJChlbGVtKS50cmlnZ2VyKGV2ZW50KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogU3RvcHMgdGhlIGlkbGUgdGltZXIuIFRoaXMgcmVtb3ZlcyBhcHByb3ByaWF0ZSBldmVudCBoYW5kbGVyc1xuICAgICAqIGFuZCBjYW5jZWxzIGFueSBwZW5kaW5nIHRpbWVvdXRzLlxuICAgICAqIEByZXR1cm4ge3ZvaWR9XG4gICAgICogQG1ldGhvZCBzdG9wXG4gICAgICogQHN0YXRpY1xuICAgICAqL1xuICAgIHN0b3AgPSBmdW5jdGlvbihlbGVtKXtcblxuICAgICAgICB2Y
4060XIgb2JqID0gJC5kYXRhKGVsZW0sJ2lkbGVUaW1lck9iaicpIHx8IHt9O1xuXG4gICAgICAgIC8vc2V0IHRvIGRpc2FibGVkXG4gICAgICAgIG9iai5lbmFibGVkID0gZmFsc2U7XG5cbiAgICAgICAgLy9jbGVhciBhbnkgcGVuZGluZyB0aW1lb3V0c1xuICAgICAgICBjbGVhclRpbWVvdXQob2JqLnRJZCk7XG5cbiAgICAgICAgLy9kZXRhY2ggdGhlIGV2ZW50IGhhbmRsZXJzXG4gICAgICAgICQoZWxlbSkub2ZmKCcuaWRsZVRpbWVyJyk7XG4gICAgfSxcblxuXG4gICAgLyogKGludGVudGlvbmFsbHkgbm90IGRvY3VtZW50ZWQpXG4gICAgICogSGFuZGxlcyBhIHVzZXIgZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSB1c2VyIGlzbid0IGlkbGUuXG4gICAgICogQHBhcmFtIHtFdmVudH0gZXZlbnQgQSBET00yLW5vcm1hbGl6ZWQgZXZlbnQgb2JqZWN0LlxuICAgICAqIEByZXR1cm4ge3ZvaWR9XG4gICAgICovXG4gICAgaGFuZGxlVXNlckV2ZW50ID0gZnVuY3Rpb24oKXtcblxuICAgICAgICB2YXIgb2JqID0gJC5kYXRhKHRoaXMsJ2lkbGVUaW1lck9iaicpO1xuXG4gICAgICAgIC8vY2xlYXIgYW55IGV4aXN0aW5nIHRpbWVvdXRcbiAgICAgICAgY2xlYXJUaW1lb3V0KG9iai50SWQpO1xuXG5cblxuICAgICAgICAvL2lmIHRoZSBpZGxlIHRpbWVyIGlzIGVuYWJsZWRcbiAgICAgICAgaWYgKG9iai5lbmFibGVkKXtcblxuXG4gICAgICAgICAgICAvL2lmIGl0J3MgaWRsZSwgdGhhdCBtZWFucyB0aGUgdXNlciBpcyBubyBsb25nZXIgaWRsZVxuICAgICAgICAgICAgaWYgKG9iai5pZGxlKXtcbiAgICAgICAgICAgICAgICB0b2dnbGVJZGxlU3RhdGUodGhpcyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vc2V0IGEgbmV3IHRpbWVvdXRcbiAgICAgICAgICAgIG9iai50SWQgPSBzZXRUaW1lb3V0KHRvZ2dsZUlkbGVTdGF0ZSwgb2JqLnRpbWVvdXQpO1xuXG4gICAgICAgIH1cbiAgICAgfTtcblxuXG4gICAgLyoqXG4gICAgICogU3RhcnRzIHRoZSBpZGxlIHRpbWVyLiBUaGlzIGFkZHMgYXBwcm9wcmlhdGUgZXZlbnQgaGFuZGxlcnNcbiAgICAgKiBhbmQgc3RhcnRzIHRoZSBmaXJzdCB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7aW50fSBuZXdUaW1lb3V0IChPcHRpb25hbCkgQSBuZXcgdmFsdWUgZm9yIHRoZSB0aW1lb3V0IHBlcmlvZCBpbiBtcy5cbiAgICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgICAqIEBtZXRob2QgJC5pZGxlVGltZXJcbiAgICAgKiBAc3RhdGljXG4gICAgICovXG5cblxuICAgIHZhciBvYmogPSAkLmRhdGEoZWxlbSwnaWRsZVRpbWVyT2JqJykgfHwge307XG5cbiAgICBvYmoub2xkZGF0ZSA9IG9iai5vbGRkYXRlIHx8ICtuZXcgRGF0ZSgpO1xuXG4gICAgLy9hc3NpZ24gYSBuZXcgdGltZW91dCBpZiBuZWNlc3NhcnlcbiAgICBpZiAodHlwZW9mIG5ld1RpbWVvdXQgPT09IFwibnVtYmVyXCIpe1xuICAgICAgICBvcHRzLnRpbWVvdXQgPSBuZXdUaW1lb3V0O1xuICAgIH0gZWxzZSBpZiAobmV3VGltZW91dCA9PT0gJ2Rlc3Ryb3knKSB7XG4gICAgICAgIHN0b3AoZWxlbSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0gZWxzZSBpZiAobmV3VGltZW91dCA9PT0gJ2dldEVsYXBzZWRUaW1lJyl7XG4gICAgICAgIHJldHVybiAoK25ldyBEYXRlKCkpIC0gb2JqLm9sZGRhdGU7XG4gICAgfVxuXG4gICAgLy9hc3NpZ24gYXBwcm9wcmlhdGUgZXZlbnQgaGFuZGxlcnNcbiAgICAkKGVsZW0pLm9uKCQudHJpbSgob3B0cy5ldmVudHMrJyAnKS5zcGxpdCgnICcpLmpvaW4oJy5pZGxlVGltZXIgJykpLGhhbmRsZVVzZXJFdmVudCk7XG5cblxuICAgIG9iai5pZGxlICAgID0gb3B0cy5pZGxlO1xuICAgIG9iai5lbmFibGVkID0gb3B0cy5lbmFibGVkO1xuICAgIG9iai50aW1lb3V0ID0gb3B0cy50aW1lb3V0O1xuXG5cbiAgICAvL3NldCBhIHRpbWVvdXQgdG8gdG9nZ2xlIHN0YXRlLiBNYXkgd2lzaCB0byBvbWl0IHRoaXMgaW4gc29tZSBzaXR1YXRpb25zXG5cdGlmIChvcHRzLnN0YXJ0SW1tZWRpYXRlbHkpIHtcblx0ICAgIG9iai50SWQgPSBzZXRUaW1lb3V0KHRvZ2dsZUlkbGVTdGF0ZSwgb2JqLnRpbWVvdXQpO1xuXHR9XG5cbiAgICAvLyBhc3N1bWUgdGhlIHVzZXIgaXMgYWN0aXZlIGZvciB0aGUgZmlyc3QgeCBzZWNvbmRzLlxuICAgICQuZGF0YShlbGVtLCdpZGxlVGltZXInLFwiYWN0aXZlXCIpO1xuXG4gICAgLy8gc3RvcmUgb3VyIGluc3RhbmNlIG9uIHRoZSBvYmplY3RcbiAgICAkLmRhdGEoZWxlbSwnaWRsZVRpbWVyT2JqJyxvYmopO1xuXG5cblxufTsgLy8gZW5kIG9mICQuaWRsZVRpbWVyKClcblxuXG4vLyB2MC45IEFQSSBmb3IgZGVmaW5pbmcgbXVsdGlwbGUgdGltZXJzLlxuJC5mbi5pZGxlVGltZXIgPSBmdW5jdGlvbihuZXdUaW1lb3V0LG9wdHMpe1xuXHQvLyBBbGxvdyBvbWlzc2lvbiBvZiBvcHRzIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG5cdGlmICghb3B0cykge1xuXHRcdG9wdHMgPSB7fTtcblx0fVxuXG4gICAgaWYodGhpc1swXSl7XG4gICAgICAgICQuaWRsZVRpbWVyKG5ld1RpbWVvdXQsdGhpc1swXSxvcHRzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbn07XG5cblxufSkoalF1ZXJ5KTtcbiIsIi8qIVxuICogQklESSBlbWJlZGRpbmcgc3VwcG9ydCBmb3IgalF1ZXJ5LmkxOG5cbiAqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTUsIERhdmlkIENoYW5cbiAqXG4gKiBUaGlzIGNvZGUgaXMgZHVhbCBsaWNlbnNlZCBHUEx2MiBvciBsYXRlciBhbmQgTUlULiBZb3UgZG9uJ3QgaGF2ZSB0byBkb1xuICogYW55dGhpbmcgc3BlY2lhbCB0byBjaG9vc2Ugb25lIGxpY2Vuc2Ugb3IgdGhlIG90aGVyIGFuZCB5b3UgZG9uJ3QgaGF2ZSB0b1xuICogbm90aWZ5IGFueW9uZSB3aGljaCBsaWNlbnNlIHlvdSBhcmUgdXNpbmcuIFlvdSBhcmUgZnJlZSB0byB1c2UgdGhpcyBjb2RlXG4gKiBpbiBjb21tZXJjaWFsIHByb2plY3RzIGFzIGxvbmcgYXMgdGhlIGNvcHlyaWdodCBoZWFkZXIgaXMgbGVmdCBpbnRhY3QuXG4gKiBTZWUgZmlsZXMgR1BMLUxJQ0VOU0UgYW5kIE1JVC1MSUNFTlNFIGZvciBkZXRhaWxzLlxuICpcbiAqIEBsaWNlbmNlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbmNlIDIuMCBvciBsYXRlclxuICogQGxpY2VuY2UgTUlUIExpY2Vuc2VcbiAqL1xuXG4oIGZ1bmN0aW9uICggJCApIHtcblx0J3VzZSBzdHJpY3QnO1xuXHR2YXIgc3Ryb25nRGlyUmVnRXhwO1xuXG5cdC8qKlxuXHQgKiBNYXRjaGVzIHRoZSBmaXJzdCBzdHJvbmcgZGlyZWN0aW9uYWxpdHkgY29kZXBvaW50OlxuXHQgKiAtIGluIGdyb3VwIDEgaWYgaXQgaXMgTFRSXG5cdCAqIC0gaW4gZ3JvdXAgMiBpZiBpdCBpcyBSVExcblx0ICogRG9lcyBub3QgbWF0Y2ggaWYgdGhlcmUgaXMgbm8gc3Ryb25nIGRpcmVjdGlvbmFsaXR5IGNvZGVwb2ludC5cblx0ICpcblx0ICogR2VuZXJhdGVkIGJ5IFVuaWNvZGVKUyAoc2VlIHRvb2xzL3N0cm9uZ0RpcikgZnJvbSB0aGUgVUNEOyBzZWVcblx0ICogaHR0cHM6Ly9waGFicmljYXRvci53aWtpbWVkaWEub3JnL2RpZmZ1c2lvbi9HVUpTLyAuXG5cdCAqL1xuXHRzdHJvbmdEaXJSZWdFeHAgPSBuZXcgUmVnRXhwKFxuXHRcdCcoPzonICtcblx0XHRcdCcoJyArXG5cdFx0XHRcdCdb
4060XFx1MDA0MS1cXHUwMDVhXFx1MDA2MS1cXHUwMDdhXFx1MDBhYVxcdTAwYjVcXHUwMGJhXFx1MDBjMC1cXHUwMGQ2XFx1MDBkOC1cXHUwMGY2XFx1MDBmOC1cXHUwMmI4XFx1MDJiYi1cXHUwMmMxXFx1MDJkMFxcdTAyZDFcXHUwMmUwLVxcdTAyZTRcXHUwMmVlXFx1MDM3MC1cXHUwMzczXFx1MDM3NlxcdTAzNzdcXHUwMzdhLVxcdTAzN2RcXHUwMzdmXFx1MDM4NlxcdTAzODgtXFx1MDM4YVxcdTAzOGNcXHUwMzhlLVxcdTAzYTFcXHUwM2EzLVxcdTAzZjVcXHUwM2Y3LVxcdTA0ODJcXHUwNDhhLVxcdTA1MmZcXHUwNTMxLVxcdTA1NTZcXHUwNTU5LVxcdTA1NWZcXHUwNTYxLVxcdTA1ODdcXHUwNTg5XFx1MDkwMy1cXHUwOTM5XFx1MDkzYlxcdTA5M2QtXFx1MDk0MFxcdTA5NDktXFx1MDk0Y1xcdTA5NGUtXFx1MDk1MFxcdTA5NTgtXFx1MDk2MVxcdTA5NjQtXFx1MDk4MFxcdTA5ODJcXHUwOTgzXFx1MDk4NS1cXHUwOThjXFx1MDk4ZlxcdTA5OTBcXHUwOTkzLVxcdTA5YThcXHUwOWFhLVxcdTA5YjBcXHUwOWIyXFx1MDliNi1cXHUwOWI5XFx1MDliZC1cXHUwOWMwXFx1MDljN1xcdTA5YzhcXHUwOWNiXFx1MDljY1xcdTA5Y2VcXHUwOWQ3XFx1MDlkY1xcdTA5ZGRcXHUwOWRmLVxcdTA5ZTFcXHUwOWU2LVxcdTA5ZjFcXHUwOWY0LVxcdTA5ZmFcXHUwYTAzXFx1MGEwNS1cXHUwYTBhXFx1MGEwZlxcdTBhMTBcXHUwYTEzLVxcdTBhMjhcXHUwYTJhLVxcdTBhMzBcXHUwYTMyXFx1MGEzM1xcdTBhMzVcXHUwYTM2XFx1MGEzOFxcdTBhMzlcXHUwYTNlLVxcdTBhNDBcXHUwYTU5LVxcdTBhNWNcXHUwYTVlXFx1MGE2Ni1cXHUwYTZmXFx1MGE3Mi1cXHUwYTc0XFx1MGE4M1xcdTBhODUtXFx1MGE4ZFxcdTBhOGYtXFx1MGE5MVxcdTBhOTMtXFx1MGFhOFxcdTBhYWEtXFx1MGFiMFxcdTBhYjJcXHUwYWIzXFx1MGFiNS1cXHUwYWI5XFx1MGFiZC1cXHUwYWMwXFx1MGFjOVxcdTBhY2JcXHUwYWNjXFx1MGFkMFxcdTBhZTBcXHUwYWUxXFx1MGFlNi1cXHUwYWYwXFx1MGFmOVxcdTBiMDJcXHUwYjAzXFx1MGIwNS1cXHUwYjBjXFx1MGIwZlxcdTBiMTBcXHUwYjEzLVxcdTBiMjhcXHUwYjJhLVxcdTBiMzBcXHUwYjMyXFx1MGIzM1xcdTBiMzUtXFx1MGIzOVxcdTBiM2RcXHUwYjNlXFx1MGI0MFxcdTBiNDdcXHUwYjQ4XFx1MGI0YlxcdTBiNGNcXHUwYjU3XFx1MGI1Y1xcdTBiNWRcXHUwYjVmLVxcdTBiNjFcXHUwYjY2LVxcdTBiNzdcXHUwYjgzXFx1MGI4NS1cXHUwYjhhXFx1MGI4ZS1cXHUwYjkwXFx1MGI5Mi1cXHUwYjk1XFx1MGI5OVxcdTBiOWFcXHUwYjljXFx1MGI5ZVxcdTBiOWZcXHUwYmEzXFx1MGJhNFxcdTBiYTgtXFx1MGJhYVxcdTBiYWUtXFx1MGJiOVxcdTBiYmVcXHUwYmJmXFx1MGJjMVxcdTBiYzJcXHUwYmM2LVxcdTBiYzhcXHUwYmNhLVxcdTBiY2NcXHUwYmQwXFx1MGJkN1xcdTBiZTYtXFx1MGJmMlxcdTBjMDEtXFx1MGMwM1xcdTBjMDUtXFx1MGMwY1xcdTBjMGUtXFx1MGMxMFxcdTBjMTItXFx1MGMyOFxcdTBjMmEtXFx1MGMzOVxcdTBjM2RcXHUwYzQxLVxcdTBjNDRcXHUwYzU4LVxcdTBjNWFcXHUwYzYwXFx1MGM2MVxcdTBjNjYtXFx1MGM2ZlxcdTBjN2ZcXHUwYzgyXFx1MGM4M1xcdTBjODUtXFx1MGM4Y1xcdTBjOGUtXFx1MGM5MFxcdTBjOTItXFx1MGNhOFxcdTBjYWEtXFx1MGNiM1xcdTBjYjUtXFx1MGNiOVxcdTBjYmQtXFx1MGNjNFxcdTBjYzYtXFx1MGNjOFxcdTBjY2FcXHUwY2NiXFx1MGNkNVxcdTBjZDZcXHUwY2RlXFx1MGNlMFxcdTBjZTFcXHUwY2U2LVxcdTBjZWZcXHUwY2YxXFx1MGNmMlxcdTBkMDJcXHUwZDAzXFx1MGQwNS1cXHUwZDBjXFx1MGQwZS1cXHUwZDEwXFx1MGQxMi1cXHUwZDNhXFx1MGQzZC1cXHUwZDQwXFx1MGQ0Ni1cXHUwZDQ4XFx1MGQ0YS1cXHUwZDRjXFx1MGQ0ZVxcdTBkNTdcXHUwZDVmLVxcdTBkNjFcXHUwZDY2LVxcdTBkNzVcXHUwZDc5LVxcdTBkN2ZcXHUwZDgyXFx1MGQ4M1xcdTBkODUtXFx1MGQ5NlxcdTBkOWEtXFx1MGRiMVxcdTBkYjMtXFx1MGRiYlxcdTBkYmRcXHUwZGMwLVxcdTBkYzZcXHUwZGNmLVxcdTBkZDFcXHUwZGQ4LVxcdTBkZGZcXHUwZGU2LVxcdTBkZWZcXHUwZGYyLVxcdTBkZjRcXHUwZTAxLVxcdTBlMzBcXHUwZTMyXFx1MGUzM1xcdTBlNDAtXFx1MGU0NlxcdTBlNGYtXFx1MGU1YlxcdTBlODFcXHUwZTgyXFx1MGU4NFxcdTBlODdcXHUwZTg4XFx1MGU4YVxcdTBlOGRcXHUwZTk0LVxcdTBlOTdcXHUwZTk5LVxcdTBlOWZcXHUwZWExLVxcdTBlYTNcXHUwZWE1XFx1MGVhN1xcdTBlYWFcXHUwZWFiXFx1MGVhZC1cXHUwZWIwXFx1MGViMlxcdTBlYjNcXHUwZWJkXFx1MGVjMC1cXHUwZWM0XFx1MGVjNlxcdTBlZDAtXFx1MGVkOVxcdTBlZGMtXFx1MGVkZlxcdTBmMDAtXFx1MGYxN1xcdTBmMWEtXFx1MGYzNFxcdTBmMzZcXHUwZjM4XFx1MGYzZS1cXHUwZjQ3XFx1MGY0OS1cXHUwZjZjXFx1MGY3ZlxcdTBmODVcXHUwZjg4LVxcdTBmOGNcXHUwZmJlLVxcdTBmYzVcXHUwZmM3LVxcdTBmY2NcXHUwZmNlLVxcdTBmZGFcXHUxMDAwLVxcdTEwMmNcXHUxMDMxXFx1MTAzOFxcdTEwM2JcXHUxMDNjXFx1MTAzZi1cXHUxMDU3XFx1MTA1YS1cXHUxMDVkXFx1MTA2MS1cXHUxMDcwXFx1MTA3NS1cXHUxMDgxXFx1MTA4M1xcdTEwODRcXHUxMDg3LVxcdTEwOGNcXHUxMDhlLVxcdTEwOWNcXHUxMDllLVxcdTEwYzVcXHUxMGM3XFx1MTBjZFxcdTEwZDAtXFx1MTI0OFxcdTEyNGEtXFx1MTI0ZFxcdTEyNTAtXFx1MTI1NlxcdTEyNThcXHUxMjVhLVxcdTEyNWRcXHUxMjYwLVxcdTEyODhcXHUxMjhhLVxcdTEyOGRcXHUxMjkwLVxcdTEyYjBcXHUxMmIyLVxcdTEyYjVcXHUxMmI4LVxcdTEyYmVcXHUxMmMwXFx1MTJjMi1cXHUxMmM1XFx1MTJjOC1cXHUxMmQ2XFx1MTJkOC1cXHUxMzEwXFx1MTMxMi1cXHUxMzE1XFx1MTMxOC1cXHUxMzVhXFx1MTM2MC1cXHUxMzdjXFx1MTM4MC1cXHUxMzhmXFx1MTNhMC1cXHUxM2Y1XFx1MTNmOC1cXHUxM2ZkXFx1MTQwMS1cXHUxNjdmXFx1MTY4MS1cXHUxNjlhXFx1MTZhMC1cXHUxNmY4XFx1MTcwMC1cXHUxNzBjXFx1MTcwZS1cXHUxNzExXFx1MTcyMC1cXHUxNzMxXFx1MTczNVxcdTE3MzZcXHUxNzQwLVxcdTE3NTFcXHUxNzYwLVxcdTE3NmNcXHUxNzZlLVxcdTE3NzBcXHUxNzgwLVxcdTE3YjNcXHUxN2I2XFx1MTdiZS1cXHUxN2M1XFx1MTdjN1xcdTE3YzhcXHUxN2Q0LVxcdTE3ZGFcXHUxN2RjXFx1MTdlMC1cXHUxN2U5XFx1MTgxMC1cXHUxODE5XFx1MTgyMC1cXHUxODc3XFx1MTg4MC1cXHUxOGE4XFx1MThhYVxcdTE4YjAtXFx1MThmNVxcdTE5MDAtXFx1MTkxZVxcdTE5MjMtXFx1MTkyNlxcdTE5MjktXFx1MTkyYlxcdTE5MzBcXHUxOTMxXFx1MTkzMy1cXHUxOTM4XFx1MTk0Ni1cXHUxOTZkXFx1MTk3MC1cXHUxOTc0XFx1MTk4MC1cXHUxOWFiXFx1MTliMC1cXHUxOWM5XFx1MTlkMC1cXHUxOWRhXFx1MWEwMC1cXHUxYTE2XFx1MWExOVxcdTFhMWFcXHUxYTFlLVxcdTFhNTVcXHUxYTU3XFx1MWE2MVxcdTFhNjNcXHUxYTY0XFx1MWE2ZC1cXHUxYTcyXFx1MWE4MC1cXHUxYTg5XFx1MWE5MC1cXHUxYTk5XFx1MWFhMC1cXHUxYWFkXFx1MWIwNC1cXHUxYjMzXFx1MWIzNVxcdTFiM2JcXHUxYjNkLVxcdTFiNDFcXHUxYjQzLVxcdTFiNGJcXHUxYjUwLVxcdTFiNmFcXHUxYjc0LVxcdTFiN2NcXHUxYjgyLVxcdTFiYTFcXHUxYmE2XFx1MWJhN1xcdTFiYWFcXHUxYmFlLVxcdTFiZTVcXHUxYmU3XFx1MWJlYS1cXHUxYmVjXFx1MWJlZVxcdTFiZjJcXHUxYmYzXFx1MWJmYy1cXHUxYzJiXFx1MWMzNFxcdTFjMzVcXHUxYzNiLVxcdTFjNDlcXHUxYzRkLVxcdTFjN2ZcXHUxY2MwLVxcdTFjYzdcXHUxY2QzXFx1MWNlMVxcdTFjZTktXFx1MWNlY1xcdTFjZWUtXFx1MWNmM1xcdTFjZjVcXHUxY2Y2XFx1MWQwMC1cXHUxZGJmXFx1MWUwMC1cXHUxZjE1XFx1MWYxOC1cXHUxZjFkXFx1MWYyMC1cXHUxZjQ1XFx1MWY0OC1cXHUxZjRkXFx1MWY
40601MC1cXHUxZjU3XFx1MWY1OVxcdTFmNWJcXHUxZjVkXFx1MWY1Zi1cXHUxZjdkXFx1MWY4MC1cXHUxZmI0XFx1MWZiNi1cXHUxZmJjXFx1MWZiZVxcdTFmYzItXFx1MWZjNFxcdTFmYzYtXFx1MWZjY1xcdTFmZDAtXFx1MWZkM1xcdTFmZDYtXFx1MWZkYlxcdTFmZTAtXFx1MWZlY1xcdTFmZjItXFx1MWZmNFxcdTFmZjYtXFx1MWZmY1xcdTIwMGVcXHUyMDcxXFx1MjA3ZlxcdTIwOTAtXFx1MjA5Y1xcdTIxMDJcXHUyMTA3XFx1MjEwYS1cXHUyMTEzXFx1MjExNVxcdTIxMTktXFx1MjExZFxcdTIxMjRcXHUyMTI2XFx1MjEyOFxcdTIxMmEtXFx1MjEyZFxcdTIxMmYtXFx1MjEzOVxcdTIxM2MtXFx1MjEzZlxcdTIxNDUtXFx1MjE0OVxcdTIxNGVcXHUyMTRmXFx1MjE2MC1cXHUyMTg4XFx1MjMzNi1cXHUyMzdhXFx1MjM5NVxcdTI0OWMtXFx1MjRlOVxcdTI2YWNcXHUyODAwLVxcdTI4ZmZcXHUyYzAwLVxcdTJjMmVcXHUyYzMwLVxcdTJjNWVcXHUyYzYwLVxcdTJjZTRcXHUyY2ViLVxcdTJjZWVcXHUyY2YyXFx1MmNmM1xcdTJkMDAtXFx1MmQyNVxcdTJkMjdcXHUyZDJkXFx1MmQzMC1cXHUyZDY3XFx1MmQ2ZlxcdTJkNzBcXHUyZDgwLVxcdTJkOTZcXHUyZGEwLVxcdTJkYTZcXHUyZGE4LVxcdTJkYWVcXHUyZGIwLVxcdTJkYjZcXHUyZGI4LVxcdTJkYmVcXHUyZGMwLVxcdTJkYzZcXHUyZGM4LVxcdTJkY2VcXHUyZGQwLVxcdTJkZDZcXHUyZGQ4LVxcdTJkZGVcXHUzMDA1LVxcdTMwMDdcXHUzMDIxLVxcdTMwMjlcXHUzMDJlXFx1MzAyZlxcdTMwMzEtXFx1MzAzNVxcdTMwMzgtXFx1MzAzY1xcdTMwNDEtXFx1MzA5NlxcdTMwOWQtXFx1MzA5ZlxcdTMwYTEtXFx1MzBmYVxcdTMwZmMtXFx1MzBmZlxcdTMxMDUtXFx1MzEyZFxcdTMxMzEtXFx1MzE4ZVxcdTMxOTAtXFx1MzFiYVxcdTMxZjAtXFx1MzIxY1xcdTMyMjAtXFx1MzI0ZlxcdTMyNjAtXFx1MzI3YlxcdTMyN2YtXFx1MzJiMFxcdTMyYzAtXFx1MzJjYlxcdTMyZDAtXFx1MzJmZVxcdTMzMDAtXFx1MzM3NlxcdTMzN2ItXFx1MzNkZFxcdTMzZTAtXFx1MzNmZVxcdTM0MDAtXFx1NGRiNVxcdTRlMDAtXFx1OWZkNVxcdWEwMDAtXFx1YTQ4Y1xcdWE0ZDAtXFx1YTYwY1xcdWE2MTAtXFx1YTYyYlxcdWE2NDAtXFx1YTY2ZVxcdWE2ODAtXFx1YTY5ZFxcdWE2YTAtXFx1YTZlZlxcdWE2ZjItXFx1YTZmN1xcdWE3MjItXFx1YTc4N1xcdWE3ODktXFx1YTdhZFxcdWE3YjAtXFx1YTdiN1xcdWE3ZjctXFx1YTgwMVxcdWE4MDMtXFx1YTgwNVxcdWE4MDctXFx1YTgwYVxcdWE4MGMtXFx1YTgyNFxcdWE4MjdcXHVhODMwLVxcdWE4MzdcXHVhODQwLVxcdWE4NzNcXHVhODgwLVxcdWE4YzNcXHVhOGNlLVxcdWE4ZDlcXHVhOGYyLVxcdWE4ZmRcXHVhOTAwLVxcdWE5MjVcXHVhOTJlLVxcdWE5NDZcXHVhOTUyXFx1YTk1M1xcdWE5NWYtXFx1YTk3Y1xcdWE5ODMtXFx1YTliMlxcdWE5YjRcXHVhOWI1XFx1YTliYVxcdWE5YmJcXHVhOWJkLVxcdWE5Y2RcXHVhOWNmLVxcdWE5ZDlcXHVhOWRlLVxcdWE5ZTRcXHVhOWU2LVxcdWE5ZmVcXHVhYTAwLVxcdWFhMjhcXHVhYTJmXFx1YWEzMFxcdWFhMzNcXHVhYTM0XFx1YWE0MC1cXHVhYTQyXFx1YWE0NC1cXHVhYTRiXFx1YWE0ZFxcdWFhNTAtXFx1YWE1OVxcdWFhNWMtXFx1YWE3YlxcdWFhN2QtXFx1YWFhZlxcdWFhYjFcXHVhYWI1XFx1YWFiNlxcdWFhYjktXFx1YWFiZFxcdWFhYzBcXHVhYWMyXFx1YWFkYi1cXHVhYWViXFx1YWFlZS1cXHVhYWY1XFx1YWIwMS1cXHVhYjA2XFx1YWIwOS1cXHVhYjBlXFx1YWIxMS1cXHVhYjE2XFx1YWIyMC1cXHVhYjI2XFx1YWIyOC1cXHVhYjJlXFx1YWIzMC1cXHVhYjY1XFx1YWI3MC1cXHVhYmU0XFx1YWJlNlxcdWFiZTdcXHVhYmU5LVxcdWFiZWNcXHVhYmYwLVxcdWFiZjlcXHVhYzAwLVxcdWQ3YTNcXHVkN2IwLVxcdWQ3YzZcXHVkN2NiLVxcdWQ3ZmJcXHVlMDAwLVxcdWZhNmRcXHVmYTcwLVxcdWZhZDlcXHVmYjAwLVxcdWZiMDZcXHVmYjEzLVxcdWZiMTdcXHVmZjIxLVxcdWZmM2FcXHVmZjQxLVxcdWZmNWFcXHVmZjY2LVxcdWZmYmVcXHVmZmMyLVxcdWZmYzdcXHVmZmNhLVxcdWZmY2ZcXHVmZmQyLVxcdWZmZDdcXHVmZmR
4060hLVxcdWZmZGNdfFxcdWQ4MDBbXFx1ZGMwMC1cXHVkYzBiXXxcXHVkODAwW1xcdWRjMGQtXFx1ZGMyNl18XFx1ZDgwMFtcXHVkYzI4LVxcdWRjM2FdfFxcdWQ4MDBcXHVkYzNjfFxcdWQ4MDBcXHVkYzNkfFxcdWQ4MDBbXFx1ZGMzZi1cXHVkYzRkXXxcXHVkODAwW1xcdWRjNTAtXFx1ZGM1ZF18XFx1ZDgwMFtcXHVkYzgwLVxcdWRjZmFdfFxcdWQ4MDBcXHVkZDAwfFxcdWQ4MDBcXHVkZDAyfFxcdWQ4MDBbXFx1ZGQwNy1cXHVkZDMzXXxcXHVkODAwW1xcdWRkMzctXFx1ZGQzZl18XFx1ZDgwMFtcXHVkZGQwLVxcdWRkZmNdfFxcdWQ4MDBbXFx1ZGU4MC1cXHVkZTljXXxcXHVkODAwW1xcdWRlYTAtXFx1ZGVkMF18XFx1ZDgwMFtcXHVkZjAwLVxcdWRmMjNdfFxcdWQ4MDBbXFx1ZGYzMC1cXHVkZjRhXXxcXHVkODAwW1xcdWRmNTAtXFx1ZGY3NV18XFx1ZDgwMFtcXHVkZjgwLVxcdWRmOWRdfFxcdWQ4MDBbXFx1ZGY5Zi1cXHVkZmMzXXxcXHVkODAwW1xcdWRmYzgtXFx1ZGZkNV18XFx1ZDgwMVtcXHVkYzAwLVxcdWRjOWRdfFxcdWQ4MDFbXFx1ZGNhMC1cXHVkY2E5XXxcXHVkODAxW1xcdWRkMDAtXFx1ZGQyN118XFx1ZDgwMVtcXHVkZDMwLVxcdWRkNjNdfFxcdWQ4MDFcXHVkZDZmfFxcdWQ4MDFbXFx1ZGUwMC1cXHVkZjM2XXxcXHVkODAxW1xcdWRmNDAtXFx1ZGY1NV18XFx1ZDgwMVtcXHVkZjYwLVxcdWRmNjddfFxcdWQ4MDRcXHVkYzAwfFxcdWQ4MDRbXFx1ZGMwMi1cXHVkYzM3XXxcXHVkODA0W1xcdWRjNDctXFx1ZGM0ZF18XFx1ZDgwNFtcXHVkYzY2LVxcdWRjNmZdfFxcdWQ4MDRbXFx1ZGM4Mi1cXHVkY2IyXXxcXHVkODA0XFx1ZGNiN3xcXHVkODA0XFx1ZGNiOHxcXHVkODA0W1xcdWRjYmItXFx1ZGNjMV18XFx1ZDgwNFtcXHVkY2QwLVxcdWRjZThdfFxcdWQ4MDRbXFx1ZGNmMC1cXHVkY2Y5XXxcXHVkODA0W1xcdWRkMDMtXFx1ZGQyNl18XFx1ZDgwNFxcdWRkMmN8XFx1ZDgwNFtcXHVkZDM2LVxcdWRkNDNdfFxcdWQ4MDRbXFx1ZGQ1MC1cXHVkZDcyXXxcXHVkODA0W1xcdWRkNzQtXFx1ZGQ3Nl18XFx1ZDgwNFtcXHVkZDgyLVxcdWRkYjVdfFxcdWQ4MDRbXFx1ZGRiZi1cXHVkZGM5XXxcXHVkODA0XFx1ZGRjZHxcXHVkODA0W1xcdWRkZDAtXFx1ZGRkZl18XFx1ZDgwNFtcXHVkZGUxLVxcdWRkZjRdfFxcdWQ4MDRbXFx1ZGUwMC1cXHVkZTExXXxcXHVkODA0W1xcdWRlMTMtXFx1ZGUyZV18XFx1ZDgwNFxcdWRlMzJ8XFx1ZDgwNFxcdWRlMzN8XFx1ZDgwNFxcdWRlMzV8XFx1ZDgwNFtcXHVkZTM4LVxcdWRlM2RdfFxcdWQ4MDRbXFx1ZGU4MC1cXHVkZTg2XXxcXHVkODA0XFx1ZGU4OHxcXHVkODA0W1xcdWRlOGEtXFx1ZGU4ZF18XFx1ZDgwNFtcXHVkZThmLVxcdWRlOWRdfFxcdWQ4MDRbXFx1ZGU5Zi1cXHVkZWE5XXxcXHVkODA0W1xcdWRlYjAtXFx1ZGVkZV18XFx1ZDgwNFtcXHVkZWUwLVxcdWRlZTJdfFxcdWQ4MDRbXFx1ZGVmMC1cXHVkZWY5XXxcXHVkODA0XFx1ZGYwMnxcXHVkODA0XFx1ZGYwM3xcXHVkODA0W1xcdWRmMDUtXFx1ZGYwY118XFx1ZDgwNFxcdWRmMGZ8XFx1ZDgwNFxcdWRmMTB8XFx1ZDgwNFtcXHVkZjEzLVxcdWRmMjhdfFxcdWQ4MDRbXFx1ZGYyYS1cXHVkZjMwXXxcXHVkODA0XFx1ZGYzMnxcXHVkODA0XFx1ZGYzM3xcXHVkODA0W1xcdWRmMzUtXFx1ZGYzOV18XFx1ZDgwNFtcXHVkZjNkLVxcdWRmM2ZdfFxcdWQ4MDRbXFx1ZGY0MS1cXHVkZjQ0XXxcXHVkODA0XFx1ZGY0N3xcXHVkODA0XFx1ZGY0OHxcXHVkODA0W1xcdWRmNGItXFx1ZGY0ZF18XFx1ZDgwNFxcdWRmNTB8XFx1ZDgwNFxcdWRmNTd8XFx1ZDgwNFtcXHVkZjVkLVxcdWRmNjNdfFxcdWQ4MDVbXFx1ZGM4MC1cXHVkY2IyXXxcXHVkODA1XFx1ZGNiOXxcXHVkODA1W1xcdWRjYmItXFx1ZGNiZV18XFx1ZDgwNVxcdWRjYzF8XFx1ZDgwNVtcXHVkY2M0LVxcdWRjYzddfFxcdWQ4MDVbXFx1ZGNkMC1cXHVkY2Q5XXxcXHVkODA1W1xcdWRkODAtXFx1ZGRiMV18XFx1ZDgwNVtcXHVkZGI4LVxcdWRkYmJdfFxcdWQ4MDVcXHVkZGJlfFxcdWQ4MDVbXFx1ZGRjMS1cXHVkZGRiXXxcXHVkODA1W1xcdWRlMDAtXFx1ZGUzMl18XFx1ZDgwNVxcdWRlM2J8XFx1ZDgwNVxcdWRlM2N8XFx1ZDgwNVxcdWRlM2V8XFx1ZDgwNVtcXHVkZTQxLVxcdWRlNDRdfFxcdWQ4MDVbXFx1ZGU1MC1cXHVkZTU5XXxcXHVkODA1W1xcdWRlODAtXFx1ZGVhYV18XFx1ZDgwNVxcdWRlYWN8XFx1ZDgwNVxcdWRlYWV8XFx1ZDgwNVxcdWRlYWZ8XFx1ZDgwNVxcdWRlYjZ8XFx1ZDgwNVtcXHVkZWMwLVxcdWRlYzldfFxcdWQ4MDVbXFx1ZGYwMC1cXHVkZjE5XXxcXHVkODA1XFx1ZGYyMHxcXHVkODA1XFx1ZGYyMXxcXHVkODA1XFx1ZGYyNnxcXHVkODA1W1xcdWRmMzAtXFx1ZGYzZl18XFx1ZDgwNltcXHVkY2EwLVxcdWRjZjJdfFxcdWQ4MDZcXHVkY2ZmfFxcdWQ4MDZbXFx1ZGVjMC1cXHVkZWY4XXxcXHVkODA4W1xcdWRjMDAtXFx1ZGY5OV18XFx1ZDgwOVtcXHVkYzAwLVxcdWRjNmVdfFxcdWQ4MDlbXFx1ZGM3MC1cXHVkYzc0XXxcXHVkODA5W1xcdWRjODAtXFx1ZGQ0M118XFx1ZDgwY1tcXHVkYzAwLVxcdWRmZmZdfFxcdWQ4MGRbXFx1ZGMwMC1cXHVkYzJlXXxcXHVkODExW1xcdWRjMDAtXFx1ZGU0Nl18XFx1ZDgxYVtcXHVkYzAwLVxcdWRlMzhdfFxcdWQ4MWFbXFx1ZGU0MC1cXHVkZTVlXXxcXHVkODFhW1xcdWRlNjAtXFx1ZGU2OV18XFx1ZDgxYVxcdWRlNmV8XFx1ZDgxYVxcdWRlNmZ8XFx1ZDgxYVtcXHVkZWQwLVxcdWRlZWRdfFxcdWQ4MWFcXHVkZWY1fFxcdWQ4MWFbXFx1ZGYwMC1cXHVkZjJmXXxcXHVkODFhW1xcdWRmMzctXFx1ZGY0NV18XFx1ZDgxYVtcXHVkZjUwLVxcdWRmNTldfFxcdWQ4MWFbXFx1ZGY1Yi1cXHVkZjYxXXxcXHVkODFhW1xcdWRmNjMtXFx1ZGY3N118XFx1ZDgxYVtcXHVkZjdkLVxcdWRmOGZdfFxcdWQ4MWJbXFx1ZGYwMC1cXHVkZjQ0XXxcXHVkODFiW1xcdWRmNTAtXFx1ZGY3ZV18XFx1ZDgxYltcXHVkZjkzLVxcdWRmOWZdfFxcdWQ4MmNcXHVkYzAwfFxcdWQ4MmNcXHVkYzAxfFxcdWQ4MmZbXFx1ZGMwMC1cXHVkYzZhXXxcXHVkODJmW1xcdWRjNzAtXFx1ZGM3Y118XFx1ZDgyZltcXHVkYzgwLVxcdWRjODhdfFxcdWQ4MmZbXFx1ZGM5MC1cXHVkYzk5XXxcXHVkODJmXFx1ZGM5Y3xcXHVkODJmXFx1ZGM5ZnxcXHVkODM0W1xcdWRjMDAtXFx1ZGNmNV18XFx1ZDgzNFtcXHVkZDAwLVxcdWRkMjZdfFxcdWQ4MzRbXFx1ZGQyOS1cXHVkZDY2XXxcXHVkODM0W1xcdWRkNmEtXFx1ZGQ3Ml18XFx1ZDgzNFxcdWRkODN8XFx1ZDgzNFxcdWRkODR8XFx1ZDgzNFtcXHVkZDhjLVxcdWRkYTldfFxcdWQ4MzRbXFx1ZGRhZS1cXHVkZGU4XXxcXHVkODM0W1xcdWRmNjAtXFx1ZGY3MV18XFx1ZDgzNVtcXHVkYzAwLVxcdWRjNTRdfFxcdWQ4MzVbXFx1ZGM1Ni1cXHVkYzljXXxcXHVkODM1XFx1ZGM5ZXxcXHVkODM1XFx1ZGM5ZnxcXHVkODM1XFx1ZGNhMnxcXHVkODM1XFx1ZGNhNXxcXHVkODM1XFx1ZGNhNnxcXHVkODM1W1xcdWRjYTktXFx1ZGNhY118XFx1ZDgzNVtcXHVkY2FlLVxcdWRjYjldfFxcdWQ4MzVcXHVkY2JifFxcdWQ4MzVbXFx1ZGNiZC1cXHVkY2MzXXxcXHVkODM1W1xcdWRjYzUt
4060XFx1ZGQwNV18XFx1ZDgzNVtcXHVkZDA3LVxcdWRkMGFdfFxcdWQ4MzVbXFx1ZGQwZC1cXHVkZDE0XXxcXHVkODM1W1xcdWRkMTYtXFx1ZGQxY118XFx1ZDgzNVtcXHVkZDFlLVxcdWRkMzldfFxcdWQ4MzVbXFx1ZGQzYi1cXHVkZDNlXXxcXHVkODM1W1xcdWRkNDAtXFx1ZGQ0NF18XFx1ZDgzNVxcdWRkNDZ8XFx1ZDgzNVtcXHVkZDRhLVxcdWRkNTBdfFxcdWQ4MzVbXFx1ZGQ1Mi1cXHVkZWE1XXxcXHVkODM1W1xcdWRlYTgtXFx1ZGVkYV18XFx1ZDgzNVtcXHVkZWRjLVxcdWRmMTRdfFxcdWQ4MzVbXFx1ZGYxNi1cXHVkZjRlXXxcXHVkODM1W1xcdWRmNTAtXFx1ZGY4OF18XFx1ZDgzNVtcXHVkZjhhLVxcdWRmYzJdfFxcdWQ4MzVbXFx1ZGZjNC1cXHVkZmNiXXxcXHVkODM2W1xcdWRjMDAtXFx1ZGRmZl18XFx1ZDgzNltcXHVkZTM3LVxcdWRlM2FdfFxcdWQ4MzZbXFx1ZGU2ZC1cXHVkZTc0XXxcXHVkODM2W1xcdWRlNzYtXFx1ZGU4M118XFx1ZDgzNltcXHVkZTg1LVxcdWRlOGJdfFxcdWQ4M2NbXFx1ZGQxMC1cXHVkZDJlXXxcXHVkODNjW1xcdWRkMzAtXFx1ZGQ2OV18XFx1ZDgzY1tcXHVkZDcwLVxcdWRkOWFdfFxcdWQ4M2NbXFx1ZGRlNi1cXHVkZTAyXXxcXHVkODNjW1xcdWRlMTAtXFx1ZGUzYV18XFx1ZDgzY1tcXHVkZTQwLVxcdWRlNDhdfFxcdWQ4M2NcXHVkZTUwfFxcdWQ4M2NcXHVkZTUxfFtcXHVkODQwLVxcdWQ4NjhdW1xcdWRjMDAtXFx1ZGZmZl18XFx1ZDg2OVtcXHVkYzAwLVxcdWRlZDZdfFxcdWQ4NjlbXFx1ZGYwMC1cXHVkZmZmXXxbXFx1ZDg2YS1cXHVkODZjXVtcXHVkYzAwLVxcdWRmZmZdfFxcdWQ4NmRbXFx1ZGMwMC1cXHVkZjM0XXxcXHVkODZkW1xcdWRmNDAtXFx1ZGZmZl18XFx1ZDg2ZVtcXHVkYzAwLVxcdWRjMWRdfFxcdWQ4NmVbXFx1ZGMyMC1cXHVkZmZmXXxbXFx1ZDg2Zi1cXHVkODcyXVtcXHVkYzAwLVxcdWRmZmZdfFxcdWQ4NzNbXFx1ZGMwMC1cXHVkZWExXXxcXHVkODdlW1xcdWRjMDAtXFx1ZGUxZF18W1xcdWRiODAtXFx1ZGJiZV1bXFx1ZGMwMC1cXHVkZmZmXXxcXHVkYmJmW1xcdWRjMDAtXFx1ZGZmZF18W1xcdWRiYzAtXFx1ZGJmZV1bXFx1ZGMwMC1cXHVkZmZmXXxcXHVkYmZmW1xcdWRjMDAtXFx1ZGZmZF0nICtcblx0XHRcdCcpfCgnICtcblx0XHRcdFx0J1tcXHUwNTkwXFx1MDViZVxcdTA1YzBcXHUwNWMzXFx1MDVjNlxcdTA1YzgtXFx1MDVmZlxcdTA3YzAtXFx1MDdlYVxcdTA3ZjRcXHUwN2Y1XFx1MDdmYS1cXHUwODE1XFx1MDgxYVxcdTA4MjRcXHUwODI4XFx1MDgyZS1cXHUwODU4XFx1MDg1Yy1cXHUwODlmXFx1MjAwZlxcdWZiMWRcXHVmYjFmLVxcdWZiMjhcXHVmYjJhLVxcdWZiNGZcXHUwNjA4XFx1MDYwYlxcdTA2MGRcXHUwNjFiLVxcdTA2NGFcXHUwNjZkLVxcdTA2NmZcXHUwNjcxLVxcdTA2ZDVcXHUwNmU1XFx1MDZlNlxcdTA2ZWVcXHUwNmVmXFx1MDZmYS1cXHUwNzEwXFx1MDcxMi1cXHUwNzJmXFx1MDc0Yi1cXHUwN2E1XFx1MDdiMS1cXHUwN2JmXFx1MDhhMC1cXHUwOGUyXFx1ZmI1MC1cXHVmZDNkXFx1ZmQ0MC1cXHVmZGNmXFx1ZmRmMC1cXHVmZGZjXFx1ZmRmZVxcdWZkZmZcXHVmZTcwLVxcdWZlZmVdfFxcdWQ4MDJbXFx1ZGMwMC1cXHVkZDFlXXxcXHVkODAyW1xcdWRkMjAtXFx1ZGUwMF18XFx1ZDgwMlxcdWRlMDR8XFx1ZDgwMltcXHVkZTA3LVxcdWRlMGJdfFxcdWQ4MDJbXFx1ZGUxMC1cXHVkZTM3XXxcXHVkODAyW1xcdWRlM2ItXFx1ZGUzZV18XFx1ZDgwMltcXHVkZTQwLVxcdWRlZTRdfFxcdWQ4MDJbXFx1ZGVlNy1cXHVkZjM4XXxcXHVkODAyW1xcdWRmNDAtXFx1ZGZmZl18XFx1ZDgwM1tcXHVkYzAwLVxcdWRlNWZdfFxcdWQ4MDNbXFx1ZGU3Zi1cXHVkZmZmXXxcXHVkODNhW1xcdWRjMDAtXFx1ZGNjZl18XFx1ZDgzYVtcXHVkY2Q3LVxcdWRmZmZdfFxcdWQ4M2JbXFx1ZGMwMC1cXHVkZGZmXXxcXHVkODNiW1xcdWRmMDAtXFx1ZGZmZl18XFx1ZDgzYltcXHVkZjAwLVxcdWRmZmZdfFxcdWQ4M2JbXFx1ZGYwMC1cXHVkZmZmXXxcXHVkODNiW1xcdWRmMDAtXFx1ZGZmZl18XFx1ZDgzYltcXHVkZjAwLVxcdWRmZmZdfFxcdWQ4M2JbXFx1ZGYwMC1cXHVkZmZmXXxcXHVkODNiW1xcdWRmMDAtXFx1ZGZmZl18XFx1ZDgzYltcXHVkZjAwLVxcdWRmZmZdfFxcdWQ4M2JbXFx1ZGYwMC1cXHVkZmZmXXxcXHVkODNiW1xcdWRmMDAtXFx1ZGZmZl18XFx1ZDgzYltcXHVkZjAwLVxcdWRmZmZdfFxcdWQ4M2JbXFx1ZGYwMC1cXHVkZmZmXXxcXHVkODNiW1xcdWRmMDAtXFx1ZGZmZl18XFx1ZDgzYltcXHVkZTAwLVxcdWRlZWZdfFxcdWQ4M2JbXFx1ZGVmMi1cXHVkZWZmXScgK1xuXHRcdFx0JyknICtcblx0XHQnKSdcblx0KTtcblxuXHQvKipcblx0ICogR2V0cyBkaXJlY3Rpb25hbGl0eSBvZiB0aGUgZmlyc3Qgc3Ryb25nbHkgZGlyZWN0aW9uYWwgY29kZXBvaW50XG5cdCAqXG5cdCAqIFRoaXMgaXMgdGhlIHJ1bGUgdGhlIEJJREkgYWxnb3JpdGhtIHVzZXMgdG8gZGV0ZXJtaW5lIHRoZSBkaXJlY3Rpb25hbGl0eSBvZlxuXHQgKiBwYXJhZ3JhcGhzICggaHR0cDovL3VuaWNvZGUub3JnL3JlcG9ydHMvdHI5LyNUaGVfUGFyYWdyYXBoX0xldmVsICkgYW5kXG5cdCAqIEZTSSBpc29sYXRlcyAoIGh0dHA6Ly91bmljb2RlLm9yZy9yZXBvcnRzL3RyOS8jRXhwbGljaXRfRGlyZWN0aW9uYWxfSXNvbGF0ZXMgKS5cblx0ICpcblx0ICogVE9ETzogRG9lcyBub3QgaGFuZGxlIEJJREkgY29udHJvbCBjaGFyYWN0ZXJzIGluc2lkZSB0aGUgdGV4dC5cblx0ICogVE9ETzogRG9lcyBub3QgaGFuZGxlIHVuYWxsb2NhdGVkIGNoYXJhY3RlcnMuXG5cdCAqXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRoZSB0ZXh0IGZyb20gd2hpY2ggdG8gZXh0cmFjdCBpbml0aWFsIGRpcmVjdGlvbmFsaXR5LlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd9IERpcmVjdGlvbmFsaXR5IChlaXRoZXIgJ2x0cicgb3IgJ3J0bCcpXG5cdCAqL1xuXHRmdW5jdGlvbiBzdHJvbmdEaXJGcm9tQ29udGVudCggdGV4dCApIHtcblx0XHR2YXIgbSA9IHRleHQubWF0Y2goIHN0cm9uZ0RpclJlZ0V4cCApO1xuXHRcdGlmICggIW0gKSB7XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9XG5cdFx0aWYgKCBtWyAyIF0gPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHJldHVybiAnbHRyJztcblx0XHR9XG5cdFx0cmV0dXJuICdydGwnO1xuXHR9XG5cblx0JC5leHRlbmQoICQuaTE4bi5wYXJzZXIuZW1pdHRlciwge1xuXHRcdC8qKlxuXHRcdCAqIFdyYXBzIGFyZ3VtZW50IHdpdGggdW5pY29kZSBjb250cm9sIGNoYXJhY3RlcnMgZm9yIGRpcmVjdGlvbmFsaXR5IHNhZmV0eVxuXHRcdCAqXG5cdFx0ICogVGhpcyBzb2x2ZXMgdGhlIHByb2JsZW0gd2hlcmUgZGlyZWN0aW9uYWxpdHktbmV1dHJhbCBjaGFyYWN0ZXJzIGF0IHRoZSBlZGdlIG9mXG5cdFx0ICogdGhlIGFyZ3VtZW50IHN0cmluZyBnZXQgaW50ZXJwcmV0ZWQgd2l0aCB0aGUgd3JvbmcgZGlyZWN0aW9uYWxpdHkgZnJvbSB0aGVcblx0XHQgKiBlbmNsb3NpbmcgY29udGV4dCwgZ2l2aW5nIHJlbmRlcmluZ3MgdGhhdCBsb29rIGNvcnJ1cHRlZCBsaWtlIFwiKEJlbl8oV01GXCIuXG5cdFx0ICpcblx0XHQgKiBUaGUgd3JhcHBpbmcgaXMgTFJFLi4uUERGIG9yIFJMRS4uLlBERiwgZGVwZW5kaW5nIG9uIHRoZSBkZXRlY3RlZFxuXHRcdCAqIGRpcmVjdGlvbmFsaXR5IG9mIHRoZSBhcmd1bWVudCBzdHJpbmcsIHVzaW5nIHRoZSBCSURJIGFsZ29yaXRobSdzIG93biBcIkZpcnN0XG5cdFx0ICogc3Ryb25nIGRpcmVjdGlvbmFsIGNvZGVwb2ludFwiIHJ1bGUuIEVzc2VudGlhbGx5LCB0aGlzIHdvcmtzIHJvdW5kIHRoZSBmYWN0IHRoYXRcblx0XHQgKiB0aGVyZSBpcyBubyBlbWJlZGRpbmcgZXF1aXZhbGVudCBvZiBVKzIwNjggRlNJIChpc29sYXRpb24gd2l0aCBoZXVyaXN0aWNcblx0XHQgKiBkaXJlY3Rpb24gaW5mZXJlbmNlKS4gVGhlIGxhdHRlciBpcyBjbGVhbmVyIGJ1dCBzdGlsbCBub3Qgd2lkZWx5IHN1cHBvcnRlZC5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nW119IG5vZGVzIFRoZSB0ZXh0IG5vZGVzIGZyb20gd2h
4060pY2ggdG8gdGFrZSB0aGUgZmlyc3QgaXRlbS5cblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9IFdyYXBwZWQgU3RyaW5nIG9mIGNvbnRlbnQgYXMgbmVlZGVkLlxuXHRcdCAqL1xuXHRcdGJpZGk6IGZ1bmN0aW9uICggbm9kZXMgKSB7XG5cdFx0XHR2YXIgZGlyID0gc3Ryb25nRGlyRnJvbUNvbnRlbnQoIG5vZGVzWyAwIF0gKTtcblx0XHRcdGlmICggZGlyID09PSAnbHRyJyApIHtcblx0XHRcdFx0Ly8gV3JhcCBpbiBMRUZULVRPLVJJR0hUIEVNQkVERElORyAuLi4gUE9QIERJUkVDVElPTkFMIEZPUk1BVFRJTkdcblx0XHRcdFx0cmV0dXJuICdcXHUyMDJBJyArIG5vZGVzWyAwIF0gKyAnXFx1MjAyQyc7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIGRpciA9PT0gJ3J0bCcgKSB7XG5cdFx0XHRcdC8vIFdyYXAgaW4gUklHSFQtVE8tTEVGVCBFTUJFRERJTkcgLi4uIFBPUCBESVJFQ1RJT05BTCBGT1JNQVRUSU5HXG5cdFx0XHRcdHJldHVybiAnXFx1MjAyQicgKyBub2Rlc1sgMCBdICsgJ1xcdTIwMkMnO1xuXHRcdFx0fVxuXHRcdFx0Ly8gTm8gc3Ryb25nIGRpcmVjdGlvbmFsaXR5OiBkbyBub3Qgd3JhcFxuXHRcdFx0cmV0dXJuIG5vZGVzWyAwIF07XG5cdFx0fVxuXHR9ICk7XG59KCBqUXVlcnkgKSApO1xuIiwiLyohXG4gKiBqUXVlcnkgSW50ZXJuYXRpb25hbGl6YXRpb24gbGlicmFyeVxuICpcbiAqIENvcHlyaWdodCAoQykgMjAxMS0yMDEzIFNhbnRob3NoIFRob3R0aW5nYWwsIE5laWwgS2FuZGFsZ2FvbmthclxuICpcbiAqIGpxdWVyeS5pMThuIGlzIGR1YWwgbGljZW5zZWQgR1BMdjIgb3IgbGF0ZXIgYW5kIE1JVC4gWW91IGRvbid0IGhhdmUgdG8gZG9cbiAqIGFueXRoaW5nIHNwZWNpYWwgdG8gY2hvb3NlIG9uZSBsaWNlbnNlIG9yIHRoZSBvdGhlciBhbmQgeW91IGRvbid0IGhhdmUgdG9cbiAqIG5vdGlmeSBhbnlvbmUgd2hpY2ggbGljZW5zZSB5b3UgYXJlIHVzaW5nLiBZb3UgYXJlIGZyZWUgdG8gdXNlXG4gKiBVbml2ZXJzYWxMYW5ndWFnZVNlbGVjdG9yIGluIGNvbW1lcmNpYWwgcHJvamVjdHMgYXMgbG9uZyBhcyB0aGUgY29weXJpZ2h0XG4gKiBoZWFkZXIgaXMgbGVmdCBpbnRhY3QuIFNlZSBmaWxlcyBHUEwtTElDRU5TRSBhbmQgTUlULUxJQ0VOU0UgZm9yIGRldGFpbHMuXG4gKlxuICogQGxpY2VuY2UgR05VIEdlbmVyYWwgUHVibGljIExpY2VuY2UgMi4wIG9yIGxhdGVyXG4gKiBAbGljZW5jZSBNSVQgTGljZW5zZVxuICovXG5cbiggZnVuY3Rpb24gKCAkICkge1xuXHQndXNlIHN0cmljdCc7XG5cblx0dmFyIE1lc3NhZ2VQYXJzZXJFbWl0dGVyID0gZnVuY3Rpb24gKCkge1xuXHRcdHRoaXMubGFuZ3VhZ2UgPSAkLmkxOG4ubGFuZ3VhZ2VzWyBTdHJpbmcubG9jYWxlIF0gfHwgJC5pMThuLmxhbmd1YWdlc1sgJ2RlZmF1bHQnIF07XG5cdH07XG5cblx0TWVzc2FnZVBhcnNlckVtaXR0ZXIucHJvdG90eXBlID0ge1xuXHRcdGNvbnN0cnVjdG9yOiBNZXNzYWdlUGFyc2VyRW1pdHRlcixcblxuXHRcdC8qKlxuXHRcdCAqIChXZSBwdXQgdGhpcyBtZXRob2QgZGVmaW5pdGlvbiBoZXJlLCBhbmQgbm90IGluIHByb3RvdHlwZSwgdG8gbWFrZVxuXHRcdCAqIHN1cmUgaXQncyBub3Qgb3ZlcndyaXR0ZW4gYnkgYW55IG1hZ2ljLikgV2FsayBlbnRpcmUgbm9kZSBzdHJ1Y3R1cmUsXG5cdFx0ICogYXBwbHlpbmcgcmVwbGFjZW1lbnRzIGFuZCB0ZW1wbGF0ZSBmdW5jdGlvbnMgd2hlbiBhcHByb3ByaWF0ZVxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtNaXhlZH0gbm9kZSBhYnN0cmFjdCBzeW50YXggdHJlZSAodG9wIG5vZGUgb3Igc3Vibm9kZSlcblx0XHQgKiBAcGFyYW0ge0FycmF5fSByZXBsYWNlbWVudHMgZm9yICQxLCAkMiwgLi4uICRuXG5cdFx0ICogQHJldHVybiB7TWl4ZWR9IHNpbmdsZS1zdHJpbmcgbm9kZSBvciBhcnJheSBvZiBub2RlcyBzdWl0YWJsZSBmb3Jcblx0XHQgKiAgalF1ZXJ5IGFwcGVuZGluZy5cblx0XHQgKi9cblx0XHRlbWl0OiBmdW5jdGlvbiAoIG5vZGUsIHJlcGxhY2VtZW50cyApIHtcblx0XHRcdHZhciByZXQsIHN1Ym5vZGVzLCBvcGVyYXRpb24sXG5cdFx0XHRcdG1lc3NhZ2VQYXJzZXJFbWl0dGVyID0gdGhpcztcblxuXHRcdFx0c3dpdGNoICggdHlwZW9mIG5vZGUgKSB7XG5cdFx0XHRcdGNhc2UgJ3N0cmluZyc6XG5cdFx0XHRcdGNhc2UgJ251bWJlcic6XG5cdFx0XHRcdFx0cmV0ID0gbm9kZTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAnb2JqZWN0Jzpcblx0XHRcdFx0Ly8gbm9kZSBpcyBhbiBhcnJheSBvZiBub2Rlc1xuXHRcdFx0XHRcdHN1Ym5vZGVzID0gJC5tYXAoIG5vZGUuc2xpY2UoIDEgKSwgZnVuY3Rpb24gKCBuICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIG1lc3NhZ2VQYXJzZXJFbWl0dGVyLmVtaXQoIG4sIHJlcGxhY2VtZW50cyApO1xuXHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHRcdG9wZXJhdGlvbiA9IG5vZGVbIDAgXS50b0xvd2VyQ2FzZSgpO1xuXG5cdFx0XHRcdFx0aWYgKCB0eXBlb2YgbWVzc2FnZVBhcnNlckVtaXR0ZXJbIG9wZXJhdGlvbiBdID09PSAnZnVuY3Rpb24nICkge1xuXHRcdFx0XHRcdFx0cmV0ID0gbWVzc2FnZVBhcnNlckVtaXR0ZXJbIG9wZXJhdGlvbiBdKCBzdWJub2RlcywgcmVwbGFjZW1lbnRzICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBFcnJvciggJ3Vua25vd24gb3BlcmF0aW9uIFwiJyArIG9wZXJhdGlvbiArICdcIicgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSAndW5kZWZpbmVkJzpcblx0XHRcdFx0Ly8gUGFyc2luZyB0aGUgZW1wdHkgc3RyaW5nIChhcyBhbiBlbnRpcmUgZXhwcmVzc2lvbiwgb3IgYXMgYVxuXHRcdFx0XHQvLyBwYXJhbUV4cHJlc3Npb24gaW4gYSB0ZW1wbGF0ZSkgcmVzdWx0cyBpbiB1bmRlZmluZWRcblx0XHRcdFx0Ly8gUGVyaGFwcyBhIG1vcmUgY2xldmVyIHBhcnNlciBjYW4gZGV0ZWN0IHRoaXMsIGFuZCByZXR1cm4gdGhlXG5cdFx0XHRcdC8vIGVtcHR5IHN0cmluZz8gT3IgaXMgdGhhdCB1c2VmdWwgaW5mb3JtYXRpb24/XG5cdFx0XHRcdC8vIFRoZSBsb2dpY2FsIHRoaW5nIGlzIHByb2JhYmx5IHRvIHJldHVybi
4060B0aGUgZW1wdHkgc3RyaW5nIGhlcmVcblx0XHRcdFx0Ly8gd2hlbiB3ZSBlbmNvdW50ZXIgdW5kZWZpbmVkLlxuXHRcdFx0XHRcdHJldCA9ICcnO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdHRocm93IG5ldyBFcnJvciggJ3VuZXhwZWN0ZWQgdHlwZSBpbiBBU1Q6ICcgKyB0eXBlb2Ygbm9kZSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBQYXJzaW5nIGhhcyBiZWVuIGFwcGxpZWQgZGVwdGgtZmlyc3Qgd2UgY2FuIGFzc3VtZSB0aGF0IGFsbCBub2Rlc1xuXHRcdCAqIGhlcmUgYXJlIHNpbmdsZSBub2RlcyBNdXN0IHJldHVybiBhIHNpbmdsZSBub2RlIHRvIHBhcmVudHMgLS0gYVxuXHRcdCAqIGpRdWVyeSB3aXRoIHN5bnRoZXRpYyBzcGFuIEhvd2V2ZXIsIHVud3JhcCBhbnkgb3RoZXIgc3ludGhldGljIHNwYW5zXG5cdFx0ICogaW4gb3VyIGNoaWxkcmVuIGFuZCBwYXNzIHRoZW0gdXB3YXJkc1xuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtBcnJheX0gbm9kZXMgTWl4ZWQsIHNvbWUgc2luZ2xlIG5vZGVzLCBzb21lIGFycmF5cyBvZiBub2Rlcy5cblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdFx0ICovXG5cdFx0Y29uY2F0OiBmdW5jdGlvbiAoIG5vZGVzICkge1xuXHRcdFx0dmFyIHJlc3VsdCA9ICcnO1xuXG5cdFx0XHQkLmVhY2goIG5vZGVzLCBmdW5jdGlvbiAoIGksIG5vZGUgKSB7XG5cdFx0XHRcdC8vIHN0cmluZ3MsIGludGVnZXJzLCBhbnl0aGluZyBlbHNlXG5cdFx0XHRcdHJlc3VsdCArPSBub2RlO1xuXHRcdFx0fSApO1xuXG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBSZXR1cm4gZXNjYXBlZCByZXBsYWNlbWVudCBvZiBjb3JyZWN0IGluZGV4LCBvciBzdHJpbmcgaWZcblx0XHQgKiB1bmF2YWlsYWJsZS4gTm90ZSB0aGF0IHdlIGV4cGVjdCB0aGUgcGFyc2VkIHBhcmFtZXRlciB0byBiZVxuXHRcdCAqIHplcm8tYmFzZWQuIGkuZS4gJDEgc2hvdWxkIGhhdmUgYmVjb21lIFsgMCBdLiBpZiB0aGUgc3BlY2lmaWVkXG5cdFx0ICogcGFyYW1ldGVyIGlzIG5vdCBmb3VuZCByZXR1cm4gdGhlIHNhbWUgc3RyaW5nIChlLmcuIFwiJDk5XCIgLT5cblx0XHQgKiBwYXJhbWV0ZXIgOTggLT4gbm90IGZvdW5kIC0+IHJldHVybiBcIiQ5OVwiICkgVE9ETyB0aHJvdyBlcnJvciBpZlxuXHRcdCAqIG5vZGVzLmxlbmd0aCA+IDEgP1xuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtBcnJheX0gbm9kZXMgT25lIGVsZW1lbnQsIGludGVnZXIsIG4gPj0gMFxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IHJlcGxhY2VtZW50cyBmb3IgJDEsICQyLCAuLi4gJG5cblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9IHJlcGxhY2VtZW50XG5cdFx0ICovXG5cdFx0cmVwbGFjZTogZnVuY3Rpb24gKCBub2RlcywgcmVwbGFjZW1lbnRzICkge1xuXHRcdFx0dmFyIGluZGV4ID0gcGFyc2VJbnQoIG5vZGVzWyAwIF0sIDEwICk7XG5cblx0XHRcdGlmICggaW5kZXggPCByZXBsYWNlbWVudHMubGVuZ3RoICkge1xuXHRcdFx0XHQvLyByZXBsYWNlbWVudCBpcyBub3QgYSBzdHJpbmcsIGRvbid0IHRvdWNoIVxuXHRcdFx0XHRyZXR1cm4gcmVwbGFjZW1lbnRzWyBpbmRleCBdO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gaW5kZXggbm90IGZvdW5kLCBmYWxsYmFjayB0byBkaXNwbGF5aW5nIHZhcmlhYmxlXG5cdFx0XHRcdHJldHVybiAnJCcgKyAoIGluZGV4ICsgMSApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBUcmFuc2Zvcm0gcGFyc2VkIHN0cnVjdHVyZSBpbnRvIHBsdXJhbGl6YXRpb24gbi5iLiBUaGUgZmlyc3Qgbm9kZSBtYXlcblx0XHQgKiBiZSBhIG5vbi1pbnRlZ2VyIChmb3IgaW5zdGFuY2UsIGEgc3RyaW5nIHJlcHJlc2VudGluZyBhbiBBcmFiaWNcblx0XHQgKiBudW1iZXIpLiBTbyBjb252ZXJ0IGl0IGJhY2sgd2l0aCB0aGUgY3VycmVudCBsYW5ndWFnZSdzXG5cdFx0ICogY29udmVydE51bWJlci5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IG5vZGVzIExpc3QgWyB7U3RyaW5nfE51bWJlcn0sIHtTdHJpbmd9LCB7U3RyaW5nfSAuLi4gXVxuXHRcdCAqIEByZXR1cm4ge3N0cmluZ30gc2VsZWN0ZWQgcGx1cmFsaXplZCBmb3JtIGFjY29yZGluZyB0byBjdXJyZW50XG5cdFx0ICogIGxhbmd1YWdlLlxuXHRcdCAqL1xuXHRcdHBsdXJhbDogZnVuY3Rpb24gKCBub2RlcyApIHtcblx0XHRcdHZhciBjb3VudCA9IHBhcnNlRmxvYXQoIHRoaXMubGFuZ3VhZ2UuY29udmVydE51bWJlciggbm9kZXNbIDAgXSwgMTAgKSApLFxuXHRcdFx0XHRmb3JtcyA9IG5vZGVzLnNsaWNlKCAxICk7XG5cblx0XHRcdHJldHVybiBmb3Jtcy5sZW5ndGggPyB0aGlzLmxhbmd1YWdlLmNvbnZlcnRQbHVyYWwoIGNvdW50LCBmb3JtcyApIDogJyc7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFRyYW5zZm9ybSBwYXJzZWQgc3RydWN0dXJlIGludG8gZ2VuZGVyIFVzYWdlXG5cdFx0ICoge3tnZW5kZXI6Z2VuZGVyfG1hc2N1bGluZXxmZW1pbmluZXxuZXV0cmFsfX0uXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge0FycmF5fSBub2RlcyBMaXN0IFsge1N0cmluZ30sIHtTdHJpbmd9LCB7U3RyaW5nfSAsIHtTdHJpbmd9IF1cblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9IHNlbGVjdGVkIGdlbmRlciBmb3JtIGFjY29yZGluZyB0byBjdXJyZW50IGxhbmd1YWdlXG5cdFx0ICovXG5cdFx0Z2VuZGVyOiBmdW5jdGlvbiAoIG5vZGVzICkge1xuXHRcdFx0dmFyIGdlbmRlciA9IG5vZGVzWyAwIF0sXG5cdFx0XHRcdGZvcm1zID0gbm9kZXMuc2xpY2UoIDEgKTtcblxuXHRcdFx0cmV0dXJuIHRoaXMubGFuZ3VhZ2UuZ2VuZGVyKCBnZW5kZXIsIGZvcm1zICk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFRyYW5zZm9ybSBwYXJzZWQgc3RydWN0dXJlIGludG8gZ3JhbW1hciBjb252ZXJzaW9uLiBJbnZva2VkIGJ5XG5cdFx0ICogcHV0dGluZyB7e2dyYW1tYXI6Zm9ybXx3b3JkfX0gaW4gYSBtZXNzYWdlXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge0FycmF5fSBub2RlcyBMaXN0IFt7R3JhbW1hciBjYXNlIGVnOiBnZW5pdGl2ZX0sIHtTdHJpbmcgd29yZH1dXG5cdFx0ICogQHJldHVybi
4060B7c3RyaW5nfSBzZWxlY3RlZCBncmFtbWF0aWNhbCBmb3JtIGFjY29yZGluZyB0byBjdXJyZW50XG5cdFx0ICogIGxhbmd1YWdlLlxuXHRcdCAqL1xuXHRcdGdyYW1tYXI6IGZ1bmN0aW9uICggbm9kZXMgKSB7XG5cdFx0XHR2YXIgZm9ybSA9IG5vZGVzWyAwIF0sXG5cdFx0XHRcdHdvcmQgPSBub2Rlc1sgMSBdO1xuXG5cdFx0XHRyZXR1cm4gd29yZCAmJiBmb3JtICYmIHRoaXMubGFuZ3VhZ2UuY29udmVydEdyYW1tYXIoIHdvcmQsIGZvcm0gKTtcblx0XHR9XG5cdH07XG5cblx0JC5leHRlbmQoICQuaTE4bi5wYXJzZXIuZW1pdHRlciwgbmV3IE1lc3NhZ2VQYXJzZXJFbWl0dGVyKCkgKTtcbn0oIGpRdWVyeSApICk7XG4iLCIvKiFcbiAqIGpRdWVyeSBJbnRlcm5hdGlvbmFsaXphdGlvbiBsaWJyYXJ5XG4gKlxuICogQ29weXJpZ2h0IChDKSAyMDEyIFNhbnRob3NoIFRob3R0aW5nYWxcbiAqXG4gKiBqcXVlcnkuaTE4biBpcyBkdWFsIGxpY2Vuc2VkIEdQTHYyIG9yIGxhdGVyIGFuZCBNSVQuIFlvdSBkb24ndCBoYXZlIHRvIGRvIGFueXRoaW5nIHNwZWNpYWwgdG9cbiAqIGNob29zZSBvbmUgbGljZW5zZSBvciB0aGUgb3RoZXIgYW5kIHlvdSBkb24ndCBoYXZlIHRvIG5vdGlmeSBhbnlvbmUgd2hpY2ggbGljZW5zZSB5b3UgYXJlIHVzaW5nLlxuICogWW91IGFyZSBmcmVlIHRvIHVzZSBVbml2ZXJzYWxMYW5ndWFnZVNlbGVjdG9yIGluIGNvbW1lcmNpYWwgcHJvamVjdHMgYXMgbG9uZyBhcyB0aGUgY29weXJpZ2h0XG4gKiBoZWFkZXIgaXMgbGVmdCBpbnRhY3QuIFNlZSBmaWxlcyBHUEwtTElDRU5TRSBhbmQgTUlULUxJQ0VOU0UgZm9yIGRldGFpbHMuXG4gKlxuICogQGxpY2VuY2UgR05VIEdlbmVyYWwgUHVibGljIExpY2VuY2UgMi4wIG9yIGxhdGVyXG4gKiBAbGljZW5jZSBNSVQgTGljZW5zZVxuICovXG4oIGZ1bmN0aW9uICggJCApIHtcblx0J3VzZSBzdHJpY3QnO1xuXG5cdCQuaTE4biA9ICQuaTE4biB8fCB7fTtcblx0JC5leHRlbmQoICQuaTE4bi5mYWxsYmFja3MsIHtcblx0XHRhYjogWyAncnUnIF0sXG5cdFx0YWNlOiBbICdpZCcgXSxcblx0XHRhbG46IFsgJ3NxJyBdLFxuXHRcdC8vIE5vdCBzbyBzdGFuZGFyZCAtIGFscyBpcyBzdXBwb3NlZCB0byBiZSBUb3NrIEFsYmFuaWFuLFxuXHRcdC8vIGJ1dCBpbiBXaWtpcGVkaWEgaXQncyB1c2VkIGZvciBhIEdlcm1hbmljIGxhbmd1YWdlLlxuXHRcdGFsczogWyAnZ3N3JywgJ2RlJyBdLFxuXHRcdGFuOiBbICdlcycgXSxcblx0XHRhbnA6IFsgJ2hpJyBdLFxuXHRcdGFybjogWyAnZXMnIF0sXG5cdFx0YXJ6OiBbICdhcicgXSxcblx0XHRhdjogWyAncnUnIF0sXG5cdFx0YXk6IFsgJ2VzJyBdLFxuXHRcdGJhOiBbICdydScgXSxcblx0XHRiYXI6IFsgJ2RlJyBdLFxuXHRcdCdiYXQtc21nJzogWyAnc2dzJywgJ2x0JyBdLFxuXHRcdGJjYzogWyAnZmEnIF0sXG5cdFx0J2JlLXgtb2xkJzogWyAnYmUtdGFyYXNrJyBdLFxuXHRcdGJoOiBbICdiaG8nIF0sXG5cdFx0YmpuOiBbICdpZCcgXSxcblx0XHRibTogWyAnZnInIF0sXG5cdFx0YnB5OiBbICdibicgXSxcblx0XHRicWk6IFsgJ2ZhJyBdLFxuXHRcdGJ1ZzogWyAnaWQnIF0sXG5cdFx0J2Niay16YW0nOiBbICdlcycgXSxcblx0XHRjZTogWyAncnUnIF0sXG5cdFx0Y3JoOiBbICdjcmgtbGF0bicgXSxcblx0XHQnY3JoLWN5cmwnOiBbICdydScgXSxcblx0XHRjc2I6IFsgJ3BsJyBdLFxuXHRcdGN2OiBbICdydScgXSxcblx0XHQnZGUtYXQnOiBbICdkZScgXSxcblx0XHQnZGUtY2gnOiBbICdkZScgXSxcblx0XHQnZGUtZm9ybWFsJzogWyAnZGUnIF0sXG5cdFx0ZHNiOiBbICdkZScgXSxcblx0XHRkdHA6IFsgJ21zJyBdLFxuXHRcdGVnbDogWyAnaXQnIF0sXG5cdFx0ZW1sOiBbICdpdCcgXSxcblx0XHRmZjogWyAnZnInIF0sXG5cdFx0Zml0OiBbICdmaScgXSxcblx0XHQnZml1LXZybyc6IFsgJ3ZybycsICdldCcgXSxcblx0XHRmcmM6IFsgJ2ZyJyBdLFxuXHRcdGZycDogWyAnZnInIF0sXG5cdFx0ZnJyOiBbICdkZScgXSxcblx0XHRmdXI6IFsgJ2l0JyBdLFxuXHRcdGdhZzogWyAndHInIF0sXG5cdFx0Z2FuOiBbICdnYW4taGFudCcsICd6aC1oYW50JywgJ3poLWhhbnMnIF0sXG5cdFx0J2dhbi1oYW5zJzogWyAnemgtaGFucycgXSxcblx0XHQnZ2FuLWhhbnQnOiBbICd6aC1oYW50JywgJ3poLWhhbnMnIF0sXG5cdFx0Z2w6IFsgJ3B0JyBdLFxuXHRcdGdsazogWyAnZmEnIF0sXG5cdFx0Z246IFsgJ2VzJyBdLFxuXHRcdGdzdzogWyAnZGUnIF0sXG5cdFx0aGlmOiBbICdoaWYtbGF0bicgXSxcblx0XHRoc2I6IFsgJ2RlJyBdLFxuXHRcdGh0OiBbICdmcicgXSxcblx0XHRpaTogWyAnemgtY24nLCAnemgtaGFucycgXSxcblx0XHRpbmg6IFsgJ3J1JyBdLFxuXHRcdGl1OiBbICdpa2UtY2FucycgXSxcblx0XHRqdXQ6IFsgJ2RhJyBdLFxuXHRcdGp2OiBbICdpZCcgXSxcblx0XHRrYWE6IFsgJ2trLWxhdG4nLCAna2stY3lybCcgXSxcblx0XHRrYmQ6IFsgJ2tiZC1jeXJsJyBdLFxuXHRcdGtodzogWyAndXInIF0sXG5cdFx0a2l1OiBbICd0cicgXSxcblx0XHRrazogWyAna2stY3lybCcgXSxcblx0XHQna2stYXJhYic6IFsgJ2trLWN5cmwnIF0sXG5cdFx0J2trLWxhdG4nOiBbICdray1jeXJsJyBdLFxuXHRcdCdray1jbic6IFsgJ2trLWFyYWInLCAna2stY3lybCcgXSxcblx0XHQna2sta3onOiBbICdray1jeXJsJyBdLFxuXHRcdCdray10cic6IFsgJ2trLWxhdG4nLCAna2stY3lybCcgXSxcblx0XHRrbDogWyAnZGEnIF0sXG5cdFx0J2tvLWtwJzogWyAna28nIF0sXG5cdFx0a29pOiBbICdydScgXSxcblx0XHRrcmM6IFsgJ3J1JyBdLFxuXHRcdGtzOiBbICdrcy1hcmFiJyBdLFxuXHRcdGtzaDogWyAnZGUnIF0sXG5cdFx0a3U6IFsgJ2t1LWxhdG4nIF0sXG5cdFx0J2t1LWFyYWInOiBbICdja2InIF0sXG5cdFx0a3Y6IFsgJ3J1JyBdLFxuXHRcdGxhZDogWyAnZXMnIF0sXG5cdFx0bGI6IFsgJ2RlJyBdLFxuXHRcdGxiZTogWyAncnUnIF0sXG5cdFx0bGV6OiBbICdydScgXSxcblx0XHRsaTogWyAnbmwnIF0sXG5cdFx0bGlqOiBbICdpdCcgXSxcblx0XHRsaXY6IFsgJ2V0JyBdLFxuXHRcdGxtbzogWyAnaXQnIF0sXG5cdFx0bG46IFsgJ2ZyJyBdLFxuXHRcdGx0ZzogWyAnbHYnIF0sXG5cdFx0bHp6OiBbICd0cicgXSxcblx0XHRtYWk6IFsgJ2hpJyBdLFxuXHRcdCdtYXAtYm1zJzogW
4060yAnanYnLCAnaWQnIF0sXG5cdFx0bWc6IFsgJ2ZyJyBdLFxuXHRcdG1ocjogWyAncnUnIF0sXG5cdFx0bWluOiBbICdpZCcgXSxcblx0XHRtbzogWyAncm8nIF0sXG5cdFx0bXJqOiBbICdydScgXSxcblx0XHRtd2w6IFsgJ3B0JyBdLFxuXHRcdG15djogWyAncnUnIF0sXG5cdFx0bXpuOiBbICdmYScgXSxcblx0XHRuYWg6IFsgJ2VzJyBdLFxuXHRcdG5hcDogWyAnaXQnIF0sXG5cdFx0bmRzOiBbICdkZScgXSxcblx0XHQnbmRzLW5sJzogWyAnbmwnIF0sXG5cdFx0J25sLWluZm9ybWFsJzogWyAnbmwnIF0sXG5cdFx0bm86IFsgJ25iJyBdLFxuXHRcdG9zOiBbICdydScgXSxcblx0XHRwY2Q6IFsgJ2ZyJyBdLFxuXHRcdHBkYzogWyAnZGUnIF0sXG5cdFx0cGR0OiBbICdkZScgXSxcblx0XHRwZmw6IFsgJ2RlJyBdLFxuXHRcdHBtczogWyAnaXQnIF0sXG5cdFx0cHQ6IFsgJ3B0LWJyJyBdLFxuXHRcdCdwdC1icic6IFsgJ3B0JyBdLFxuXHRcdHF1OiBbICdlcycgXSxcblx0XHRxdWc6IFsgJ3F1JywgJ2VzJyBdLFxuXHRcdHJnbjogWyAnaXQnIF0sXG5cdFx0cm15OiBbICdybycgXSxcblx0XHQncm9hLXJ1cCc6IFsgJ3J1cCcgXSxcblx0XHRydWU6IFsgJ3VrJywgJ3J1JyBdLFxuXHRcdHJ1cTogWyAncnVxLWxhdG4nLCAncm8nIF0sXG5cdFx0J3J1cS1jeXJsJzogWyAnbWsnIF0sXG5cdFx0J3J1cS1sYXRuJzogWyAncm8nIF0sXG5cdFx0c2E6IFsgJ2hpJyBdLFxuXHRcdHNhaDogWyAncnUnIF0sXG5cdFx0c2NuOiBbICdpdCcgXSxcblx0XHRzZzogWyAnZnInIF0sXG5cdFx0c2dzOiBbICdsdCcgXSxcblx0XHRzbGk6IFsgJ2RlJyBdLFxuXHRcdHNyOiBbICdzci1lYycgXSxcblx0XHRzcm46IFsgJ25sJyBdLFxuXHRcdHN0cTogWyAnZGUnIF0sXG5cdFx0c3U6IFsgJ2lkJyBdLFxuXHRcdHN6bDogWyAncGwnIF0sXG5cdFx0dGN5OiBbICdrbicgXSxcblx0XHR0ZzogWyAndGctY3lybCcgXSxcblx0XHR0dDogWyAndHQtY3lybCcsICdydScgXSxcblx0XHQndHQtY3lybCc6IFsgJ3J1JyBdLFxuXHRcdHR5OiBbICdmcicgXSxcblx0XHR1ZG06IFsgJ3J1JyBdLFxuXHRcdHVnOiBbICd1Zy1hcmFiJyBdLFxuXHRcdHVrOiBbICdydScgXSxcblx0XHR2ZWM6IFsgJ2l0JyBdLFxuXHRcdHZlcDogWyAnZXQnIF0sXG5cdFx0dmxzOiBbICdubCcgXSxcblx0XHR2bWY6IFsgJ2RlJyBdLFxuXHRcdHZvdDogWyAnZmknIF0sXG5cdFx0dnJvOiBbICdldCcgXSxcblx0XHR3YTogWyAnZnInIF0sXG5cdFx0d286IFsgJ2ZyJyBdLFxuXHRcdHd1dTogWyAnemgtaGFucycgXSxcblx0XHR4YWw6IFsgJ3J1JyBdLFxuXHRcdHhtZjogWyAna2EnIF0sXG5cdFx0eWk6IFsgJ2hlJyBdLFxuXHRcdHphOiBbICd6aC1oYW5zJyBdLFxuXHRcdHplYTogWyAnbmwnIF0sXG5cdFx0emg6IFsgJ3poLWhhbnMnIF0sXG5cdFx0J3poLWNsYXNzaWNhbCc6IFsgJ2x6aCcgXSxcblx0XHQnemgtY24nOiBbICd6aC1oYW5zJyBdLFxuXHRcdCd6aC1oYW50JzogWyAnemgtaGFucycgXSxcblx0XHQnemgtaGsnOiBbICd6aC1oYW50JywgJ3poLWhhbnMnIF0sXG5cdFx0J3poLW1pbi1uYW4nOiBbICduYW4nIF0sXG5cdFx0J3poLW1vJzogWyAnemgtaGsnLCAnemgtaGFudCcsICd6aC1oYW5zJyBdLFxuXHRcdCd6aC1teSc6IFsgJ3poLXNnJywgJ3poLWhhbnMnIF0sXG5cdFx0J3poLXNnJzogWyAnemgtaGFucycgXSxcblx0XHQnemgtdHcnOiBbICd6aC1oYW50JywgJ3poLWhhbnMnIF0sXG5cdFx0J3poLXl1ZSc6IFsgJ3l1ZScgXVxuXHR9ICk7XG59KCBqUXVlcnkgKSApO1xuIiwiLyohXG4gKiBqUXVlcnkgSW50ZXJuYXRpb25hbGl6YXRpb24gbGlicmFyeVxuICpcbiAqIENvcHlyaWdodCAoQykgMjAxMiBTYW50aG9zaCBUaG90dGluZ2FsXG4gKlxuICoganF1ZXJ5LmkxOG4gaXMgZHVhbCBsaWNlbnNlZCBHUEx2MiBvciBsYXRlciBhbmQgTUlULiBZb3UgZG9uJ3QgaGF2ZSB0byBkb1xuICogYW55dGhpbmcgc3BlY2lhbCB0byBjaG9vc2Ugb25lIGxpY2Vuc2Ugb3IgdGhlIG90aGVyIGFuZCB5b3UgZG9uJ3QgaGF2ZSB0b1xuICogbm90aWZ5IGFueW9uZSB3aGljaCBsaWNlbnNlIHlvdSBhcmUgdXNpbmcuIFlvdSBhcmUgZnJlZSB0byB1c2VcbiAqIFVuaXZlcnNhbExhbmd1YWdlU2VsZWN0b3IgaW4gY29tbWVyY2lhbCBwcm9qZWN0cyBhcyBsb25nIGFzIHRoZSBjb3B5cmlnaHRcbiAqIGhlYWRlciBpcyBsZWZ0IGludGFjdC4gU2VlIGZpbGVzIEdQTC1MSUNFTlNFIGFuZCBNSVQtTElDRU5TRSBmb3IgZGV0YWlscy5cbiAqXG4gKiBAbGljZW5jZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5jZSAyLjAgb3IgbGF0ZXJcbiAqIEBsaWNlbmNlIE1JVCBMaWNlbnNlXG4gKi9cblxuKCBmdW5jdGlvbiAoICQgKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuXHR2YXIgSTE4Tixcblx0XHRzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcblx0LyoqXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuXHQgKi9cblx0STE4TiA9IGZ1bmN0aW9uICggb3B0aW9ucyApIHtcblx0XHQvLyBMb2FkIGRlZmF1bHRzXG5cdFx0dGhpcy5vcHRpb25zID0gJC5leHRlbmQoIHt9LCBJMThOLmRlZmF1bHRzLCBvcHRpb25zICk7XG5cblx0XHR0aGlzLnBhcnNlciA9IHRoaXMub3B0aW9ucy5wYXJzZXI7XG5cdFx0dGhpcy5sb2NhbGUgPSB0aGlzLm9wdGlvbnMubG9jYWxlO1xuXHRcdHRoaXMubWVzc2FnZVN0b3JlID0gdGhpcy5vcHRpb25zLm1lc3NhZ2VTdG9yZTtcblx0XHR0aGlzLmxhbmd1YWdlcyA9IHt9O1xuXHR9O1xuXG5cdEkxOE4ucHJvdG90eXBlID0ge1xuXHRcdC8qKlxuXHRcdCAqIExvY2FsaXplIGEgZ2l2ZW4gbWVzc2FnZUtleSB0byBhIGxvY2FsZS5cblx0XHQgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZUtleVxuXHRcdCAqIEByZXR1cm4ge1N0cmluZ30gTG9jYWxpemVkIG1lc3NhZ2Vcblx0XHQgKi9cblx0XHRsb2NhbGl6ZTogZnVuY3Rpb24gKCBtZXNzYWdlS2V5ICkge1xuXHRcdFx0dmFyIGxvY2FsZVBhcnRzLCBsb2NhbGVQYXJ0SW5kZXgsIGxvY2FsZSwgZmFsbGJhY2tJbmRleCxcblx0XHRcdFx0dHJ5aW5nTG9jYWxlLCBtZXNzYWdlO1xuXG5cdFx0XHRsb2NhbGUgPSB0aGlzLmxvY2FsZTtcblx0XHRcdGZhbGxiYWNrSW5kZXggPSAwO1xuXG5cdFx0XHR3aGlsZSAoIGxvY2FsZSApIHtcblx0XHRcdFx0Ly8gSXRlcmF0ZSB0aHJvdWdoIGxvY2FsZXMgc3RhcnRpbmcgYXQgbW9zdC1zcGVjaWZpYyB1bnRpbFxuXHRcdFx0XHQvLyBsb2NhbGl6YXRpb24gaXMgZm91bmQuIEFzIGluIGZpLUxhdG4tRkksIGZpLUxhdG4gYW5kIGZpLlxuXHRcdFx0XHRsb2NhbGVQYXJ0cyA9IGxvY2FsZS5zcGxpdCggJy0nICk7XG5cdFx0XHRcdGxvY2FsZVBhcnRJbmRleCA9IGxvY2FsZVBhcnRzLmxlbmd0aDtcblxuXHRcdFx0XHRkbyB7XG5cdFx0XHRcdFx0dHJ5aW5nTG9jYWxlID0gbG9jYWxlUGFydHMuc2xpY2UoIDAsIGxvY2FsZVBhcnRJbmRleCApLmpvaW4oICctJyApO1xuXHRcdFx0XHRcdG1lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VTdG9yZS5nZXQoIHRyeWluZ0xvY2FsZSwgbWVzc2FnZUtleSApO1xuXG5cdFx0XHRcdFx0aWYgKCBtZXNzYWdlICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIG1lc3NhZ2U7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0bG9jYWxlUGFydEluZGV4LS07XG5cdFx0XHRcdH0gd2hpbGUgKCBsb2NhbGVQYXJ0SW5kZXggKTtcblxuXHRcdFx0XHRpZiAoIGxvY2FsZSA9PT0gJ2VuJyApIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGxvY2FsZSA9ICggJC5pMThuLmZhbGxiYWNrc1sgdGh
4060pcy5sb2NhbGUgXSAmJlxuXHRcdFx0XHRcdFx0JC5pMThuLmZhbGxiYWNrc1sgdGhpcy5sb2NhbGUgXVsgZmFsbGJhY2tJbmRleCBdICkgfHxcblx0XHRcdFx0XHRcdHRoaXMub3B0aW9ucy5mYWxsYmFja0xvY2FsZTtcblx0XHRcdFx0JC5pMThuLmxvZyggJ1RyeWluZyBmYWxsYmFjayBsb2NhbGUgZm9yICcgKyB0aGlzLmxvY2FsZSArICc6ICcgKyBsb2NhbGUgKyAnICgnICsgbWVzc2FnZUtleSArICcpJyApO1xuXG5cdFx0XHRcdGZhbGxiYWNrSW5kZXgrKztcblx0XHRcdH1cblxuXHRcdFx0Ly8ga2V5IG5vdCBmb3VuZFxuXHRcdFx0cmV0dXJuICcnO1xuXHRcdH0sXG5cblx0XHQvKlxuXHRcdCAqIERlc3Ryb3kgdGhlIGkxOG4gaW5zdGFuY2UuXG5cdFx0ICovXG5cdFx0ZGVzdHJveTogZnVuY3Rpb24gKCkge1xuXHRcdFx0JC5yZW1vdmVEYXRhKCBkb2N1bWVudCwgJ2kxOG4nICk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEdlbmVyYWwgbWVzc2FnZSBsb2FkaW5nIEFQSSBUaGlzIGNhbiB0YWtlIGEgVVJMIHN0cmluZyBmb3Jcblx0XHQgKiB0aGUganNvbiBmb3JtYXR0ZWQgbWVzc2FnZXMuIEV4YW1wbGU6XG5cdFx0ICogPGNvZGU+bG9hZCgncGF0aC90by9hbGxfbG9jYWxpemF0aW9ucy5qc29uJyk7PC9jb2RlPlxuXHRcdCAqXG5cdFx0ICogVG8gbG9hZCBhIGxvY2FsaXphdGlvbiBmaWxlIGZvciBhIGxvY2FsZTpcblx0XHQgKiA8Y29kZT5cblx0XHQgKiBsb2FkKCdwYXRoL3RvL2RlLW1lc3NhZ2VzLmpzb24nLCAnZGUnICk7XG5cdFx0ICogPC9jb2RlPlxuXHRcdCAqXG5cdFx0ICogVG8gbG9hZCBhIGxvY2FsaXphdGlvbiBmaWxlIGZyb20gYSBkaXJlY3Rvcnk6XG5cdFx0ICogPGNvZGU+XG5cdFx0ICogbG9hZCgncGF0aC90by9pMThuL2RpcmVjdG9yeScsICdkZScgKTtcblx0XHQgKiA8L2NvZGU+XG5cdFx0ICogVGhlIGFib3ZlIG1ldGhvZCBoYXMgdGhlIGFkdmFudGFnZSBvZiBmYWxsYmFjayByZXNvbHV0aW9uLlxuXHRcdCAqIGllLCBpdCB3aWxsIGF1dG9tYXRpY2FsbHkgbG9hZCB0aGUgZmFsbGJhY2sgbG9jYWxlcyBmb3IgZGUuXG5cdFx0ICogRm9yIG1vc3QgdXNlY2FzZXMsIHRoaXMgaXMgdGhlIHJlY29tbWVuZGVkIG1ldGhvZC5cblx0XHQgKiBJdCBpcyBvcHRpb25hbCB0byBoYXZlIHRyYWlsaW5nIHNsYXNoIGF0IGVuZC5cblx0XHQgKlxuXHRcdCAqIEEgZGF0YSBvYmplY3QgY29udGFpbmluZyBtZXNzYWdlIGtleS0gbWVzc2FnZSB0cmFuc2xhdGlvbiBtYXBwaW5nc1xuXHRcdCAqIGNhbiBhbHNvIGJlIHBhc3NlZC4gRXhhbXBsZTpcblx0XHQgKiA8Y29kZT5cblx0XHQgKiBsb2FkKCB7ICdoZWxsbycgOiAnSGVsbG8nIH0sIG9wdGlvbmFsTG9jYWxlICk7XG5cdFx0ICogPC9jb2RlPlxuXHRcdCAqXG5cdFx0ICogQSBzb3VyY2UgbWFwIGNvbnRhaW5pbmcga2V5LXZhbHVlIHBhaXIgb2YgbGFuZ3VhZ2VuYW1lIGFuZCBsb2NhdGlvbnNcblx0XHQgKiBjYW4gYWxzbyBiZSBwYXNzZWQuIEV4YW1wbGU6XG5cdFx0ICogPGNvZGU+XG5cdFx0ICogbG9hZCgge1xuXHRcdCAqIGJuOiAnaTE4bi9ibi5qc29uJyxcblx0XHQgKiBoZTogJ2kxOG4vaGUuanNvbicsXG5cdFx0ICogZW46ICdpMThuL2VuLmpzb24nXG5cdFx0ICogfSApXG5cdFx0ICogPC9jb2RlPlxuXHRcdCAqXG5cdFx0ICogSWYgdGhlIGRhdGEgYXJndW1lbnQgaXMgbnVsbC91bmRlZmluZWQvZmFsc2UsXG5cdFx0ICogYWxsIGNhY2hlZCBtZXNzYWdlcyBmb3IgdGhlIGkxOG4gaW5zdGFuY2Ugd2lsbCBnZXQgcmVzZXQuXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge3N0cmluZ3xPYmplY3R9IHNvdXJjZVxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhbGUgTGFuZ3VhZ2UgdGFnXG5cdFx0ICogQHJldHVybiB7alF1ZXJ5LlByb21pc2V9XG5cdFx0ICovXG5cdFx0bG9hZDogZnVuY3Rpb24gKCBzb3VyY2UsIGxvY2FsZSApIHtcblx0XHRcdHZhciBmYWxsYmFja0xvY2FsZXMsIGxvY0luZGV4LCBmYWxsYmFja0xvY2FsZSwgc291cmNlTWFwID0ge307XG5cdFx0XHRpZiAoICFzb3VyY2UgJiYgIWxvY2FsZSApIHtcblx0XHRcdFx0c291cmNlID0gJ2kxOG4vJyArICQuaTE4bigpLmxvY2FsZSArICcuanNvbic7XG5cdFx0XHRcdGxvY2FsZSA9ICQuaTE4bigpLmxvY2FsZTtcblx0XHRcdH1cblx0XHRcdGlmICggdHlwZW9mIHNvdXJjZSA9PT0gJ3N0cmluZycgJiZcblx0XHRcdFx0Ly8gc291cmNlIGV4dGVuc2lvbiBzaG91bGQgYmUganNvbiwgYnV0IGNhbiBoYXZlIHF1ZXJ5IHBhcmFtcyBhZnRlciB0aGF0LlxuXHRcdFx0XHRzb3VyY2Uuc3BsaXQoICc/JyApWyAwIF0uc3BsaXQoICcuJyApLnBvcCgpICE9PSAnanNvbidcblx0XHRcdCkge1xuXHRcdFx0XHQvLyBMb2FkIHNwZWNpZmllZCBsb2NhbGUgdGhlbiBjaGVjayBmb3IgZmFsbGJhY2tzIHdoZW4gZGlyZWN0b3J5IGlzXG5cdFx0XHRcdC8vIHNwZWNpZmllZCBpbiBsb2FkKClcblx0XHRcdFx0c291cmNlTWFwWyBsb2NhbGUgXSA9IHNvdXJjZSArICcvJyArIGxvY2FsZSArICcuanNvbic7XG5cdFx0XHRcdGZhbGxiYWNrTG9jYWxlcyA9ICggJC5pMThuLmZhbGxiYWNrc1sgbG9jYWxlIF0gfHwgW10gKVxuXHRcdFx0XHRcdC5jb25jYXQoIHRoaXMub3B0aW9ucy5mYWxsYmFja0xvY2FsZSApO1xuXHRcdFx0XHRmb3IgKCBsb2NJbmRleCA9IDA7IGxvY0luZGV4IDwgZmFsbGJhY2tMb2NhbGVzLmxlbmd0aDsgbG9jSW5kZXgrKyApIHtcblx0XHRcdFx0XHRmYWxsYmFja0xvY2FsZSA9IGZhbGxiYWNrTG9jYWxlc1sgbG9jSW5kZXggXTtcblx0XHRcdFx0XHRzb3VyY2VNYXBbIGZhbGxiYWNrTG9jYWxlIF0gPSBzb3VyY2UgKyAnLycgKyBmYWxsYmFja0xvY2FsZSArICcuanNvbic7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXMubG9hZCggc291cmNlTWFwICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5tZXNzYWdlU3RvcmUubG9hZCggc291cmNlLCBsb2NhbGUgKTtcblx0XHRcdH1cblxuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBEb2VzIHBhcmFtZXRlciBhbmQgbWFnaWMgd29yZCBzdWJzdGl0dXRpb24uXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge3N0cmluZ30ga2V5IE1lc3NhZ2Uga2V5XG5cdFx0ICogQHBhcmFtIHtBcnJheX0gcGFyYW1ldGVycyBNZXNzYWdlIHBhcmFtZXRlcnNcblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdFx0ICovXG5cdFx0cGFyc2U6IGZ1bmN0aW9uICgga2V5LCBwYXJhbWV0ZXJzICkge1xuXHRcdFx0dmFyIG1lc3NhZ2UgPSB0aGlzLmxvY2FsaXplKCBrZXkgKTtcblx0XHRcdC8vIEZJWE1FOiBUaGlzIGNoYW5nZXMgdGhlIHN0YXRlIG9mIHRoZSBJMThOIG9iamVjdCxcblx0XHRcdC8vIHNob3VsZCBwcm9iYWJseSBub3QgY2hhbmdlIHRoZSAndGhpcy5wYXJzZXInIGJ1dCBqdXN0XG5cdFx0XHQvLyBwYXNzIGl0IHRvIHRoZSBwYXJzZXIuXG5cdFx0XHR0aGlzLnBhcnNlci5sYW5ndWFnZSA9ICQuaTE4bi5sYW5ndWFnZXNbICQuaTE4bigpLmxvY2FsZSBdIHx8ICQuaTE4bi5sYW5ndWFnZXNbICdkZWZhdWx0JyBdO1xuXHRcdFx0aWYgKCBtZXNzYWdlID09PSAnJyApIHtcblx0XHRcdFx0bWVzc2FnZSA9IGtleTtcblx0XHRcdH1cblx0XHRcdHJldHVybi
4060B0aGlzLnBhcnNlci5wYXJzZSggbWVzc2FnZSwgcGFyYW1ldGVycyApO1xuXHRcdH1cblx0fTtcblxuXHQvKipcblx0ICogUHJvY2VzcyBhIG1lc3NhZ2UgZnJvbSB0aGUgJC5JMThOIGluc3RhbmNlXG5cdCAqIGZvciB0aGUgY3VycmVudCBkb2N1bWVudCwgc3RvcmVkIGluIGpRdWVyeS5kYXRhKGRvY3VtZW50KS5cblx0ICpcblx0ICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkgb2YgdGhlIG1lc3NhZ2UuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbTEgW3BhcmFtLi4uXSBWYXJpYWRpYyBsaXN0IG9mIHBhcmFtZXRlcnMgZm9yIHtrZXl9LlxuXHQgKiBAcmV0dXJuIHtzdHJpbmd8JC5JMThOfSBQYXJzZWQgbWVzc2FnZSwgb3IgaWYgbm8ga2V5IHdhcyBnaXZlblxuXHQgKiB0aGUgaW5zdGFuY2Ugb2YgJC5JMThOIGlzIHJldHVybmVkLlxuXHQgKi9cblx0JC5pMThuID0gZnVuY3Rpb24gKCBrZXksIHBhcmFtMSApIHtcblx0XHR2YXIgcGFyYW1ldGVycyxcblx0XHRcdGkxOG4gPSAkLmRhdGEoIGRvY3VtZW50LCAnaTE4bicgKSxcblx0XHRcdG9wdGlvbnMgPSB0eXBlb2Yga2V5ID09PSAnb2JqZWN0JyAmJiBrZXk7XG5cblx0XHQvLyBJZiB0aGUgbG9jYWxlIG9wdGlvbiBmb3IgdGhpcyBjYWxsIGlzIGRpZmZlcmVudCB0aGVuIHRoZSBzZXR1cCBzbyBmYXIsXG5cdFx0Ly8gdXBkYXRlIGl0IGF1dG9tYXRpY2FsbHkuIFRoaXMgZG9lc24ndCBqdXN0IGNoYW5nZSB0aGUgY29udGV4dCBmb3IgdGhpc1xuXHRcdC8vIGNhbGwgYnV0IGZvciBhbGwgZnV0dXJlIGNhbGwgYXMgd2VsbC5cblx0XHQvLyBJZiB0aGVyZSBpcyBubyBpMThuIHNldHVwIHlldCwgZG9uJ3QgZG8gdGhpcy4gSXQgd2lsbCBiZSB0YWtlbiBjYXJlIG9mXG5cdFx0Ly8gYnkgdGhlIGBuZXcgSTE4TmAgY29uc3RydWN0aW9uIGJlbG93LlxuXHRcdC8vIE5PVEU6IEl0IHNob3VsZCBvbmx5IGNoYW5nZSBsYW5ndWFnZSBmb3IgdGhpcyBvbmUgY2FsbC5cblx0XHQvLyBUaGVuIGNhY2hlIGluc3RhbmNlcyBvZiBJMThOIHNvbWV3aGVyZS5cblx0XHRpZiAoIG9wdGlvbnMgJiYgb3B0aW9ucy5sb2NhbGUgJiYgaTE4biAmJiBpMThuLmxvY2FsZSAhPT0gb3B0aW9ucy5sb2NhbGUgKSB7XG5cdFx0XHRpMThuLmxvY2FsZSA9IG9wdGlvbnMubG9jYWxlO1xuXHRcdH1cblxuXHRcdGlmICggIWkxOG4gKSB7XG5cdFx0XHRpMThuID0gbmV3IEkxOE4oIG9wdGlvbnMgKTtcblx0XHRcdCQuZGF0YSggZG9jdW1lbnQsICdpMThuJywgaTE4biApO1xuXHRcdH1cblxuXHRcdGlmICggdHlwZW9mIGtleSA9PT0gJ3N0cmluZycgKSB7XG5cdFx0XHRpZiAoIHBhcmFtMSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRwYXJhbWV0ZXJzID0gc2xpY2UuY2FsbCggYXJndW1lbnRzLCAxICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwYXJhbWV0ZXJzID0gW107XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBpMThuLnBhcnNlKCBrZXksIHBhcmFtZXRlcnMgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gRklYTUU6IHJlbW92ZSB0aGlzIGZlYXR1cmUvYnVnLlxuXHRcdFx0cmV0dXJuIGkxOG47XG5cdFx0fVxuXHR9O1xuXG5cdCQuZm4uaTE4biA9IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgaTE4biA9ICQuZGF0YSggZG9jdW1lbnQsICdpMThuJyApO1xuXG5cdFx0aWYgKCAhaTE4biApIHtcblx0XHRcdGkxOG4gPSBuZXcgSTE4TigpO1xuXHRcdFx0JC5kYXRhKCBkb2N1bWVudCwgJ2kxOG4nLCBpMThuICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24gKCkge1xuXHRcdFx0dmFyICR0aGlzID0gJCggdGhpcyApLFxuXHRcdFx0XHRtZXNzYWdlS2V5ID0gJHRoaXMuZGF0YSggJ2kxOG4nICksXG5cdFx0XHRcdGxCcmFja2V0LCByQnJhY2tldCwgdHlwZSwga2V5O1xuXG5cdFx0XHRpZiAoIG1lc3NhZ2VLZXkgKSB7XG5cdFx0XHRcdGxCcmFja2V0ID0gbWVzc2FnZUtleS5pbmRleE9mKCAnWycgKTtcblx0XHRcdFx0ckJyYWNrZXQgPSBtZXNzYWdlS2V5LmluZGV4T2YoICddJyApO1xuXHRcdFx0XHRpZiAoIGxCcmFja2V0ICE9PSAtMSAmJiByQnJhY2tldCAhPT0gLTEgJiYgbEJyYWNrZXQgPCByQnJhY2tldCApIHtcblx0XHRcdFx0XHR0eXBlID0gbWVzc2FnZUtleS5zbGljZSggbEJyYWNrZXQgKyAxLCByQnJhY2tldCApO1xuXHRcdFx0XHRcdGtleSA9IG1lc3NhZ2VLZXkuc2xpY2UoIHJCcmFja2V0ICsgMSApO1xuXHRcdFx0XHRcdGlmICggdHlwZSA9PT0gJ2h0bWwnICkge1xuXHRcdFx0XHRcdFx0JHRoaXMuaHRtbCggaTE4bi5wYXJzZSgga2V5ICkgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0JHRoaXMuYXR0ciggdHlwZSwgaTE4bi5wYXJzZSgga2V5ICkgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0JHRoaXMudGV4dCggaTE4bi5wYXJzZSggbWVzc2FnZUtleSApICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdCR0aGlzLmZpbmQoICdbZGF0YS1pMThuXScgKS5pMThuKCk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9O1xuXG5cdGZ1bmN0aW9uIGdldERlZmF1bHRMb2NhbGUoKSB7XG5cdFx0dmFyIG5hdiwgbG9jYWxlID0gJCggJ2h0bWwnICkuYXR0ciggJ2xhbmcnICk7XG5cblx0XHRpZiAoICFsb2NhbGUgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiB3aW5kb3cubmF2aWdhdG9yICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdG5hdiA9IHdpbmRvdy5uYXZpZ2F0b3I7XG5cdFx0XHRcdGxvY2FsZSA9IG5hdi5sYW5ndWFnZSB8fCBuYXYudXNlckxhbmd1YWdlIHx8ICcnO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bG9jYWxlID0gJyc7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBsb2NhbGU7XG5cdH1cblxuXHQkLmkxOG4ubGFuZ3VhZ2VzID0ge307XG5cdCQuaTE4bi5tZXNzYWdlU3RvcmUgPSAkLmkxOG4ubWVzc2FnZVN0b3JlIHx8IHt9O1xuXHQkLmkxOG4ucGFyc2VyID0ge1xuXHRcdC8vIFRoZSBkZWZhdWx0IHBhcnNlciBvbmx5IGhhbmRsZXMgdmFyaWFibGUgc3Vic3RpdHV0aW9uXG5cdFx0cGFyc2U6IGZ1bmN0aW9uICggbWVzc2FnZSwgcGFyYW1ldGVycyApIHtcblx0XHRcdHJldHVybi
4060BtZXNzYWdlLnJlcGxhY2UoIC9cXCQoXFxkKykvZywgZnVuY3Rpb24gKCBzdHIsIG1hdGNoICkge1xuXHRcdFx0XHR2YXIgaW5kZXggPSBwYXJzZUludCggbWF0Y2gsIDEwICkgLSAxO1xuXHRcdFx0XHRyZXR1cm4gcGFyYW1ldGVyc1sgaW5kZXggXSAhPT0gdW5kZWZpbmVkID8gcGFyYW1ldGVyc1sgaW5kZXggXSA6ICckJyArIG1hdGNoO1xuXHRcdFx0fSApO1xuXHRcdH0sXG5cdFx0ZW1pdHRlcjoge31cblx0fTtcblx0JC5pMThuLmZhbGxiYWNrcyA9IHt9O1xuXHQkLmkxOG4uZGVidWcgPSBmYWxzZTtcblx0JC5pMThuLmxvZyA9IGZ1bmN0aW9uICggLyogYXJndW1lbnRzICovICkge1xuXHRcdGlmICggd2luZG93LmNvbnNvbGUgJiYgJC5pMThuLmRlYnVnICkge1xuXHRcdFx0d2luZG93LmNvbnNvbGUubG9nLmFwcGx5KCB3aW5kb3cuY29uc29sZSwgYXJndW1lbnRzICk7XG5cdFx0fVxuXHR9O1xuXHQvKiBTdGF0aWMgbWVtYmVycyAqL1xuXHRJMThOLmRlZmF1bHRzID0ge1xuXHRcdGxvY2FsZTogZ2V0RGVmYXVsdExvY2FsZSgpLFxuXHRcdGZhbGxiYWNrTG9jYWxlOiAnZW4nLFxuXHRcdHBhcnNlcjogJC5pMThuLnBhcnNlcixcblx0XHRtZXNzYWdlU3RvcmU6ICQuaTE4bi5tZXNzYWdlU3RvcmVcblx0fTtcblxuXHQvLyBFeHBvc2UgY29uc3RydWN0b3Jcblx0JC5pMThuLmNvbnN0cnVjdG9yID0gSTE4Tjtcbn0oIGpRdWVyeSApICk7IiwiLyogZ2xvYmFsIHBsdXJhbFJ1bGVQYXJzZXIgKi9cbiggZnVuY3Rpb24gKCAkICkge1xuXHQndXNlIHN0cmljdCc7XG5cblx0Ly8ganNjczpkaXNhYmxlXG5cdHZhciBsYW5ndWFnZSA9IHtcblx0XHQvLyBDTERSIHBsdXJhbCBydWxlcyBnZW5lcmF0ZWQgdXNpbmdcblx0XHQvLyBsaWJzL0NMRFJQbHVyYWxSdWxlUGFyc2VyL3Rvb2xzL1BsdXJhbFhNTDJKU09OLmh0bWxcblx0XHRwbHVyYWxSdWxlczoge1xuXHRcdFx0YWs6IHtcblx0XHRcdFx0b25lOiAnbiA9IDAuLjEnXG5cdFx0XHR9LFxuXHRcdFx0YW06IHtcblx0XHRcdFx0b25lOiAnaSA9IDAgb3IgbiA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0YXI6IHtcblx0XHRcdFx0emVybzogJ24gPSAwJyxcblx0XHRcdFx0b25lOiAnbiA9IDEnLFxuXHRcdFx0XHR0d286ICduID0gMicsXG5cdFx0XHRcdGZldzogJ24gJSAxMDAgPSAzLi4xMCcsXG5cdFx0XHRcdG1hbnk6ICduICUgMTAwID0gMTEuLjk5J1xuXHRcdFx0fSxcblx0XHRcdGFyczoge1xuXHRcdFx0XHR6ZXJvOiAnbiA9IDAnLFxuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJyxcblx0XHRcdFx0ZmV3OiAnbiAlIDEwMCA9IDMuLjEwJyxcblx0XHRcdFx0bWFueTogJ24gJSAxMDAgPSAxMS4uOTknXG5cdFx0XHR9LFxuXHRcdFx0YXM6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAgb3IgbiA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0YmU6IHtcblx0XHRcdFx0b25lOiAnbiAlIDEwID0gMSBhbmQgbiAlIDEwMCAhPSAxMScsXG5cdFx0XHRcdGZldzogJ24gJSAxMCA9IDIuLjQgYW5kIG4gJSAxMDAgIT0gMTIuLjE0Jyxcblx0XHRcdFx0bWFueTogJ24gJSAxMCA9IDAgb3IgbiAlIDEwID0gNS4uOSBvciBuICUgMTAwID0gMTEuLjE0J1xuXHRcdFx0fSxcblx0XHRcdGJoOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAwLi4xJ1xuXHRcdFx0fSxcblx0XHRcdGJuOiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAwIG9yIG4gPSAxJ1xuXHRcdFx0fSxcblx0XHRcdGJyOiB7XG5cdFx0XHRcdG9uZTogJ24gJSAxMCA9IDEgYW5kIG4gJSAxMDAgIT0gMTEsNzEsOTEnLFxuXHRcdFx0XHR0d286ICduICUgMTAgPSAyIGFuZCBuICUgMTAwICE9IDEyLDcyLDkyJyxcblx0XHRcdFx0ZmV3OiAnbiAlIDEwID0gMy4uNCw5IGFuZCBuICUgMTAwICE9IDEwLi4xOSw3MC4uNzksOTAuLjk5Jyxcblx0XHRcdFx0bWFueTogJ24gIT0gMCBhbmQgbiAlIDEwMDAwMDAgPSAwJ1xuXHRcdFx0fSxcblx0XHRcdGJzOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExIG9yIGYgJSAxMCA9IDEgYW5kIGYgJSAxMDAgIT0gMTEnLFxuXHRcdFx0XHRmZXc6ICd2ID0gMCBhbmQgaSAlIDEwID0gMi4uNCBhbmQgaSAlIDEwMCAhPSAxMi4uMTQgb3IgZiAlIDEwID0gMi4uNCBhbmQgZiAlIDEwMCAhPSAxMi4uMTQnXG5cdFx0XHR9LFxuXHRcdFx0Y3M6IHtcblx0XHRcdFx0b25lOiAnaSA9IDEgYW5kIHYgPSAwJyxcblx0XHRcdFx0ZmV3OiAnaSA9IDIuLjQgYW5kIHYgPSAwJyxcblx0XHRcdFx0bWFueTogJ3YgIT0gMCdcblx0XHRcdH0sXG5cdFx0XHRjeToge1xuXHRcdFx0XHR6ZXJvOiAnbiA9IDAnLFxuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJyxcblx0XHRcdFx0ZmV3OiAnbiA9IDMnLFxuXHRcdFx0XHRtYW55OiAnbiA9IDYnXG5cdFx0XHR9LFxuXHRcdFx0ZGE6IHtcblx0XHRcdFx0b25lOiAnbiA9IDEgb3IgdCAhPSAwIGFuZCBpID0gMCwxJ1xuXHRcdFx0fSxcblx0XHRcdGRzYjoge1xuXHRcdFx0XHRvbmU6ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDEgb3IgZiAlIDEwMCA9IDEnLFxuXHRcdFx0XHR0d286ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDIgb3IgZiAlIDEwMCA9IDInLFxuXHRcdFx0XHRmZXc6ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDMuLjQgb3IgZiAlIDEwMCA9IDMuLjQnXG5cdFx0XHR9LFxuXHRcdFx0ZmE6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAgb3IgbiA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0ZmY6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAsMSdcblx0XHRcdH0sXG5cdFx0XHRmaWw6IHtcblx0XHRcdFx0b25lOiAndiA9IDAgYW5kIGkgPSAxLDIsMyBvciB2ID0gMCBhbmQgaSAlIDEwICE9IDQsNiw5IG9yIHYgIT0gMCBhbmQgZiAlIDEwICE9IDQsNiw5J1xuXHRcdFx0fSxcblx0XHRcdGZyOiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAwLDEnXG5cdFx0XHR9LFxuXHRcdFx0Z2E6IHtcblx0XHRcdFx0b25lOiAnbiA9IDEnLFxuXHRcdFx0XHR0d286ICduID0gMicsXG5cdFx0XHRcdGZldzogJ24gPSAzLi42Jyxcblx0XHRcdFx0bWFueTogJ24gPSA3Li4xMCdcblx0XHRcdH0sXG5cdFx0XHRnZDoge1xuXHRcdFx0XHRvbmU6ICduID0gMSwxMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyLDEyJyxcblx0XHRcdFx0ZmV3OiAnbiA9IDMuLjEwLDEzLi4xOSdcblx0XHRcdH0sXG5cdFx0XHRndToge1xuXHRcdFx0XHRvbmU6ICdpID0gMCBvciBuID0gMSdcblx0XHRcdH0sXG5cdFx0XHRndXc6IHtcblx0XHRcdFx0b25lOiAnbiA9IDAuLjEnXG5cdFx0XHR9LFxuXHRcdFx0Z3Y6IHtcblx0XHRcdFx0b25lOiAndiA9IDAgYW5kIGkgJSAxMCA9IDEnLFxuXHRcdFx0XHR0d286ICd2ID0gMCBhbmQgaSAlIDEwID0gMicsXG5cdFx0XHRcdGZldzogJ3YgPSAwIGFuZCBpICUgMTAwID0gMCwyMCw0MCw2MCw4MCcsXG5cdFx0XHRcdG1hbnk6ICd2ICE9IDAnXG5cdFx0XHR9LFxuXHRcdFx0aGU6IHtcblx0XHRcdFx0b25lOiAnaSA9IDEgYW5kIHYgPSAwJyxcblx0XHRcdFx0dHdvOiAnaSA9IDIgYW5kIHYgPSAwJyxcblx0XHRcdFx0bWFueTogJ3YgPSAwIGFuZCBuICE9IDAuLjEwIGFuZCBuICUgMTAgPSAwJ1xuXHRcdFx0fSxcblx0XHRcdGhpOiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAwIG9yIG4gPSAxJ1xuXHRcdFx0fSxcblx0XHRcdGhyOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExIG9yIGYgJSAxMCA9IDEgYW5kIGYgJSAxMDAgIT0gMTEnLFxuXHRcdFx0XHRmZXc6ICd2ID0gMCBhbmQgaSAlIDEwID0gMi4uNCBhbmQgaSAlIDEwMCAhPSAxMi4uMTQgb3IgZiAlIDEwID0gMi4uNCBhbmQgZiAlIDEwMCAhPSAxMi4uMTQnXG5cdFx0XHR9LFxuXHRcdFx0aHNiOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAwID0gMSBvciBmICUgMTAwID0gMScsXG5cdFx0XHRcdHR3bzogJ3YgPSAwIGFuZCBpICUgMTAwID0gMiBvciBmICUgMTAwID0gMicsXG5cdFx0XHRcdGZldzogJ3YgPSAwIGFuZCBpICUgMTAwID0gMy4uNCBvciBmICUgMTAwID0gMy4uNCdcblx0XHRcdH0sXG5cdFx0XHRoeToge1xuXHRcdFx0XHRvbmU6ICdpID0gMCwxJ1xuXHRcdFx0fSxcblx0XHRcdGlzOiB7XG5cdFx0XHRcdG9uZTogJ3QgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExIG9yIHQgIT0gMCdcblx0XHRcdH0sXG5cdFx0XHRpdToge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdGl3OiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAxIGFuZCB2ID0gMCcsXG5cdFx0XHRcdHR3bzogJ2kgPSAyIGFuZCB2ID0gMCcsXG5cdFx0XHRcdG1hbnk6ICd2ID0gMCBhbmQgbiAhPSAwLi4xMCBhbmQgbiAlIDEwID0gMCdcblx0XHRcdH0sXG5cdFx0XHRrYWI6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAsMSdcblx0XHRcdH0sXG5cdFx0XHRrbjoge1xuXHRcdFx0XHRvbmU6ICdpID0gMCBvciBuID0gMSdcblx0XHRcdH0sXG5cdFx0XHRrdzoge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdGxhZzoge1xuXHRcdFx0XHR6ZXJvOiAnbiA9IDAnLFxuXHRcdFx0XHRvbmU6ICdpID0gMCwxIGFuZCBuICE9IDAnXG5cdFx0XHR9LFxuXHRcdFx0bG46IHtcblx0XHRcdFx0b25lOiAnbiA9IDAuLjEnXG5cdFx0XHR9LFxuXHRcdFx0bHQ6IHtcblx0XHRcdFx0b25lOiAnbiAlIDEwID0gMSBhbmQgbiAlIDEwMCAhPSAxMS4uMTknLFxuXHRcdFx0XHRmZXc6ICduICUgMTAgPSAyLi45IGFuZCBuICUgMTAwICE9IDExLi4xOScsXG5cdFx0XHRcdG1hbnk6ICdmICE9IDAnXG5cdFx0XHR9LFxuXHRcdFx0bHY6IHtcblx0XHRcdFx0emVybzogJ24gJSAxMCA9IDAgb3IgbiAlIDEwMCA9IDExLi4xOSBvciB2ID0gMiBhbmQgZiAlIDEwMCA9IDExLi4xOScsXG5cdFx0XHRcdG9uZTogJ24gJSAxMCA9IDEgYW5kIG4gJSAxMDAgIT0gMTEgb3IgdiA9IDIgYW5kIGYgJSAxMCA9IDEgYW5kIGYgJSAxMDAgIT0gMTEgb3IgdiAhPSAyIGFuZCBmICUgMTAgPSAxJ1xuXHRcdFx0fSxcblx0XHRcdG1nOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAwLi4xJ1xuXHRcdFx0fSxcblx0XHRcdG1rOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIG9yIGYgJSAxMCA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0bW86IHtcblx0XHRcdFx0b25lOiAnaSA9IDEgYW5kIHYgPSAwJyxcblx0XHRcdFx0ZmV3OiAndiAhPSAwIG9yIG4gPSAwIG9yIG4gIT0gMSBhbmQgbiAlIDEwMCA9IDEuLjE5J1xuXHRcdFx0fSxcblx0XHRcdG1yOiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAwIG9yIG4gPSAxJ1xuXHRcdFx0fSxcblx0XHRcdG10OiB7XG5cdFx0XHRcdG9uZTogJ24gPSAxJyxcblx0XHRcdFx0ZmV3OiAnbiA9IDAgb3IgbiAlIDEwMCA9IDIuLjEwJyxcblx0XHRcdFx0bWFueTogJ24gJSAxMDAgPSAxMS4uMTknXG5cdFx0XHR9LFxuXHRcdFx0bmFxOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAxJyxcblx0XHRcdFx0dHdvOiAnbiA9IDInXG5cdFx0XHR9LFxuXHRcdFx0bnNvOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAwLi4xJ1xuXHRcdFx0fSxcblx0XHRcdHBhOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAwLi4xJ1xuXHRcdFx0fSxcblx0XHRcdHBsOiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAxIGFuZCB2ID0gMCcsXG5cdFx0XHRcdGZldzogJ3YgPSAwIGFuZCBpICUgMTAgPSAyLi40IGFuZCBpICUgMTAwICE9IDEyLi4xNCcsXG5cdFx0XHRcdG1hbnk6ICd2ID0gMCBhbmQgaSAhPSAxIGFuZCBpICUgMTAgPSAwLi4xIG9yIHYgPSAwIGFuZCBpICUgMTAgPSA1Li45IG9yIHYgPSAwIGFuZCBpICUgMTAwID0gMTIuLjE0J1xuXHRcdFx0fSxcblx0XHRcdHByZzoge1xuXHRcdFx0XHR6ZXJvOiAnbiAlIDEwID0gMCBvciBuICUgMTAwID0gMTEuLjE5IG9yIHYgPSAyIGFuZCBmICUgMTAwID0gMTEuLjE5Jyxcblx0XHRcdFx0b25lOiAnbiAlIDEwID0gMSBhbmQgbiAlIDEwMCAhPSAxMSBvciB2ID0gMiBhbmQgZiAlIDEwID0gMSBhbmQgZiAlIDEwMCAhPSAxMSBvciB2ICE9IDIgYW5kIGYgJSAxMCA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0cHQ6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAuLjEnXG5cdFx0XHR9LFxuXHRcdFx0cm86IHtcblx0XHRcdFx0b25lOiAnaSA9IDEgYW5kIHYgPSAwJyxcblx0XHRcdFx0ZmV3OiAndiAhPSAwIG9yIG4gPSAwIG9yIG4gIT0gMSBhbmQgbiAlIDEwMCA9IDEuLjE5J1xuXHRcdFx0fSxcblx0XHRcdHJ1OiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExJyxcblx0XHRcdFx0ZmV3OiAndiA9IDAgYW5kIGkgJSAxMCA9IDIuLjQgYW5kIGkgJSAxMDAgIT0gMTIuLjE0Jyxcblx0XHRcdFx0bWFueTogJ3YgPSAwIGFuZCBpICUgMTAgPSAwIG9yIHYgPSAwIGFuZCBpICUgMTAgPSA1Li45IG9yIHYgPSAwIGFuZCBpICUgMTAwID0gMTEuLjE0J1xuXHRcdFx0fSxcblx0XHRcdHNlOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAxJyxcblx0XHRcdFx0dHdvOiAnbiA9IDInXG5cdFx0XHR9LFxuXHRcdFx0c2g6IHtcblx0XHRcdFx0b25lOiAndiA9IDAgYW5kIGkgJSAxMCA9IDEgYW5kIGkgJSAxMDAgIT0gMTEgb3IgZiAlIDEwID0gMSBhbmQgZiAlIDEwMCAhPSAxMScsXG5cdFx0XHRcdGZldzogJ3YgPSAwIGFuZCBpICUgMTAgPSAyLi40IGFuZCBpICUgMTAwICE9IDEyLi4xNCBvciBmICUgMTAgPSAyLi40IGFuZCBmICUgMTAwICE9IDEyLi4xNCdcblx0XHRcdH0sXG5cdFx0XHRzaGk6IHtcblx0XHRcdFx0b25lOiAnaSA9IDAgb3IgbiA9IDEnLFxuXHRcdFx0XHRmZXc6ICduID0gMi4uMTAnXG5cdFx0XHR9LFxuXHRcdFx0c2k6IHtcblx0XHRcdFx0b25lOiAnbiA9IDAsMSBvciBpID0gMCBhbmQgZiA9IDEnXG5cdFx0XHR9LFxuXHRcdFx0c2s6IHtcblx0XHRcdFx0b25lOiAnaSA9IDEgYW5kIHYgPSAwJyxcblx0XHRcdFx0ZmV3OiAnaSA9IDIuLjQgYW5kIHYgPSAwJyxcblx0XHRcdFx0bWFueTogJ3YgIT0gMCdcblx0XHRcdH0sXG5cdFx0XHRzbDoge1xuXHRcdFx0XHRvbmU6ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDEnLFxuXHRcdFx0XHR0d286ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDInLFxuXHRcdFx0XHRmZXc6ICd2ID0gMCBhbmQgaSAlIDEwMCA9IDMuLjQgb3IgdiAhPSAwJ1xuXHRcdFx0fSxcblx0XHRcdHNtYToge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdHNtaToge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdHNtajoge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdHNtbjoge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdHNtczoge1xuXHRcdFx0XHRvbmU6ICduID0gMScsXG5cdFx0XHRcdHR3bzogJ24gPSAyJ1xuXHRcdFx0fSxcblx0XHRcdHNyOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExIG9yIGYgJSAxMCA9IDEgYW5kIGYgJSAxMDAgIT0gMTEnLFxuXHRcdFx0XHRmZXc6ICd2ID0gMCBhbmQgaSAlIDEwID0gMi4uNCBhbmQgaSAlIDEwMCAhPSAxMi4uMTQgb3IgZiAlIDEwID0gMi4uNCBhbmQgZiAlIDEwMCAhPSAxMi4uMTQnXG5cdFx0XHR9LFxuXHRcdFx0dGk6IHtcblx0XHRcdFx0b25lOiAnbiA9IDAuLjEnXG5cdFx0XHR9LFxuXHRcdFx0dGw6IHtcblx0XHRcdFx0b25lOiAndiA9IDAgYW5kIGkgPSAxLDIsMyBvciB2ID0gMCBhbmQgaSAlIDEwICE9IDQsNiw5IG9yIHYgIT0gMCBhbmQgZiAlIDEwICE9IDQsNiw5J1xuXHRcdFx0fSxcblx0XHRcdHR6bToge1xuXHRcdFx0XHRvbmU6ICduID0gMC4uMSBvciBuID0gMTEuLjk5J1xuXHRcdFx0fSxcblx0XHRcdHVrOiB7XG5cdFx0XHRcdG9uZTogJ3YgPSAwIGFuZCBpICUgMTAgPSAxIGFuZCBpICUgMTAwICE9IDExJyxcblx0XHRcdFx0ZmV3OiAndiA9IDAgYW5kIGkgJSAxMCA9IDIuLjQgYW5kIGkgJSAxMDAgIT0gMTIuLjE0Jyxcblx0XHRcdFx0bWFueTogJ3YgPSAwIGFuZCBpICUgMTAgPSAwIG9yIHYgPSAwIGFuZCBpICUgMTAgPSA1Li45IG9yIHYgPSAwIGFuZCBpICUgMTAwID0gMTEuLjE0J1xuXHRcdFx0fSxcblx0XHRcdHdhOiB7XG5cdFx0XHRcdG9uZTogJ24gPSAwLi4xJ1xuXHRcdFx0fSxcblx0XHRcdHp1OiB7XG5cdFx0XHRcdG9uZTogJ2kgPSAwIG9yIG4gPSAxJ1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0Ly8ganNjczplbmFibGVcblxuXHRcdC8qKlxuXHRcdCAqIFBsdXJhbCBmb3JtIHRyYW5zZm9ybWF0aW9ucywgbmVlZGVkIGZvciBzb21lIGxhbmd1YWdlcy5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7aW50ZWdlcn0gY291bnRcblx0XHQgKiAgICAgICAgICAgIE5vbi1sb2NhbGl6ZWQgcXVhbnRpZmllclxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IGZvcm1zXG5cdFx0ICogICAgICAgICAgICBMaXN0IG9mIHBsdXJhbCBmb3Jtc1xuXHRcdCAqIEByZXR1cm4ge3N0cmluZ30gQ29ycmVjdCBmb3JtIGZvciBxdWFudGlmaWVyIGluIHRoaXMgbGFuZ3VhZ2Vcblx0XHQgKi9cblx0XHRjb252ZXJ0UGx1cmFsOiBmdW5jdGlvbiAoIGNvdW50LCBmb3JtcyApIHtcblx0XHRcdHZhciBwbHVyYWxSdWxlcyxcblx0XHRcdFx0cGx1cmFsRm9ybUluZGV4LFxuXHRcdFx0XHRpbmRleCxcblx0XHRcdFx0ZXhwbGljaXRQbHVyYWxQYXR0ZXJuID0gbmV3IFJlZ0V4cCggJ1xcXFxkKz0nLCAnaScgKSxcblx0XHRcdFx0Zm9ybUNvdW50LFxuXHRcdFx0XHRmb3JtO1xuXG5cdFx0XHRpZiAoICFmb3JtcyB8fCBmb3Jtcy5sZW5ndGggPT09IDAgKSB7XG5cdFx0XHRcdHJldHVybiAnJztcblx0XHRcdH1cblxuXHRcdFx0Ly8gSGFuZGxlIGZvciBFeHBsaWNpdCAwPSAmIDE9IHZhbHVlc1xuXHRcdFx0Zm9yICggaW5kZXggPSAwOyBpbmRleCA8IGZvcm1zLmxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0Zm9ybSA9IGZvcm1zWyBpbmRleCBdO1xuXHRcdFx0XHRpZiAoIGV4cGxpY2l0UGx1cmFsUGF0dGVybi50ZXN0KCBmb3JtICkgKSB7XG5cdFx0XHRcdFx0Zm9ybUNvdW50ID0gcGFyc2VJbnQoIGZvcm0uc2xpY2UoIDAsIGZvcm0uaW5kZXhPZiggJz0nICkgKSwgMTAgKTtcblx0XHRcdFx0XHRpZiAoIGZvcm1Db3VudCA9PT0gY291bnQgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gKCBmb3JtLnNsaWNlKCBmb3JtLmluZGV4T2YoICc9JyApICsgMSApICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGZvcm1zWyBpbmRleCBdID0gdW5kZWZpbmVkO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGZvcm1zID0gJC5tYXAoIGZvcm1zLCBmdW5jdGlvbiAoIGZvcm0gKSB7XG5cdFx0XHRcdGlmICggZm9ybSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybi
4060Bmb3JtO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cblx0XHRcdHBsdXJhbFJ1bGVzID0gdGhpcy5wbHVyYWxSdWxlc1sgJC5pMThuKCkubG9jYWxlIF07XG5cblx0XHRcdGlmICggIXBsdXJhbFJ1bGVzICkge1xuXHRcdFx0XHQvLyBkZWZhdWx0IGZhbGxiYWNrLlxuXHRcdFx0XHRyZXR1cm4gKCBjb3VudCA9PT0gMSApID8gZm9ybXNbIDAgXSA6IGZvcm1zWyAxIF07XG5cdFx0XHR9XG5cblx0XHRcdHBsdXJhbEZvcm1JbmRleCA9IHRoaXMuZ2V0UGx1cmFsRm9ybSggY291bnQsIHBsdXJhbFJ1bGVzICk7XG5cdFx0XHRwbHVyYWxGb3JtSW5kZXggPSBNYXRoLm1pbiggcGx1cmFsRm9ybUluZGV4LCBmb3Jtcy5sZW5ndGggLSAxICk7XG5cblx0XHRcdHJldHVybiBmb3Jtc1sgcGx1cmFsRm9ybUluZGV4IF07XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEZvciB0aGUgbnVtYmVyLCBnZXQgdGhlIHBsdXJhbCBmb3IgaW5kZXhcblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7aW50ZWdlcn0gbnVtYmVyXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IHBsdXJhbFJ1bGVzXG5cdFx0ICogQHJldHVybiB7aW50ZWdlcn0gcGx1cmFsIGZvcm0gaW5kZXhcblx0XHQgKi9cblx0XHRnZXRQbHVyYWxGb3JtOiBmdW5jdGlvbiAoIG51bWJlciwgcGx1cmFsUnVsZXMgKSB7XG5cdFx0XHR2YXIgaSxcblx0XHRcdFx0cGx1cmFsRm9ybXMgPSBbICd6ZXJvJywgJ29uZScsICd0d28nLCAnZmV3JywgJ21hbnknLCAnb3RoZXInIF0sXG5cdFx0XHRcdHBsdXJhbEZvcm1JbmRleCA9IDA7XG5cblx0XHRcdGZvciAoIGkgPSAwOyBpIDwgcGx1cmFsRm9ybXMubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdGlmICggcGx1cmFsUnVsZXNbIHBsdXJhbEZvcm1zWyBpIF0gXSApIHtcblx0XHRcdFx0XHRpZiAoIHBsdXJhbFJ1bGVQYXJzZXIoIHBsdXJhbFJ1bGVzWyBwbHVyYWxGb3Jtc1sgaSBdIF0sIG51bWJlciApICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHBsdXJhbEZvcm1JbmRleDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRwbHVyYWxGb3JtSW5kZXgrKztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcGx1cmFsRm9ybUluZGV4O1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBDb252ZXJ0cyBhIG51bWJlciB1c2luZyBkaWdpdFRyYW5zZm9ybVRhYmxlLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtudW1iZXJ9IG51bSBWYWx1ZSB0byBiZSBjb252ZXJ0ZWRcblx0XHQgKiBAcGFyYW0ge2Jvb2xlYW59IGludGVnZXIgQ29udmVydCB0aGUgcmV0dXJuIHZhbHVlIHRvIGFuIGludGVnZXJcblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBudW1iZXIgY29udmVydGVkIGludG8gYSBTdHJpbmcuXG5cdFx0ICovXG5cdFx0Y29udmVydE51bWJlcjogZnVuY3Rpb24gKCBudW0sIGludGVnZXIgKSB7XG5cdFx0XHR2YXIgdG1wLCBpdGVtLCBpLFxuXHRcdFx0XHR0cmFuc2Zvcm1UYWJsZSwgbnVtYmVyU3RyaW5nLCBjb252ZXJ0ZWROdW1iZXI7XG5cblx0XHRcdC8vIFNldCB0aGUgdGFyZ2V0IFRyYW5zZm9ybSB0YWJsZTpcblx0XHRcdHRyYW5zZm9ybVRhYmxlID0gdGhpcy5kaWdpdFRyYW5zZm9ybVRhYmxlKCAkLmkxOG4oKS5sb2NhbGUgKTtcblx0XHRcdG51bWJlclN0cmluZyA9IFN0cmluZyggbnVtICk7XG5cdFx0XHRjb252ZXJ0ZWROdW1iZXIgPSAnJztcblxuXHRcdFx0aWYgKCAhdHJhbnNmb3JtVGFibGUgKSB7XG5cdFx0XHRcdHJldHVybiBudW07XG5cdFx0XHR9XG5cblx0XHRcdC8vIENoZWNrIGlmIHRoZSByZXN0b3JlIHRvIExhdGluIG51bWJlciBmbGFnIGlzIHNldDpcblx0XHRcdGlmICggaW50ZWdlciApIHtcblx0XHRcdFx0aWYgKCBwYXJzZUZsb2F0KCBudW0sIDEwICkgPT09IG51bSApIHtcblx0XHRcdFx0XHRyZXR1cm4gbnVtO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dG1wID0gW107XG5cblx0XHRcdFx0Zm9yICggaXRlbSBpbiB0cmFuc2Zvcm1UYWJsZSApIHtcblx0XHRcdFx0XHR0bXBbIHRyYW5zZm9ybVRhYmxlWyBpdGVtIF0gXSA9IGl0ZW07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0cmFuc2Zvcm1UYWJsZSA9IHRtcDtcblx0XHRcdH1cblxuXHRcdFx0Zm9yICggaSA9IDA7IGkgPCBudW1iZXJTdHJpbmcubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdGlmICggdHJhbnNmb3JtVGFibGVbIG51bWJlclN0cmluZ1sgaSBdIF0gKSB7XG5cdFx0XHRcdFx0Y29udmVydGVkTnVtYmVyICs9IHRyYW5zZm9ybVRhYmxlWyBudW1iZXJTdHJpbmdbIGkgXSBdO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNvbnZlcnRlZE51bWJlciArPSBudW1iZXJTdHJpbmdbIGkgXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gaW50ZWdlciA/IHBhcnNlRmxvYXQoIGNvbnZlcnRlZE51bWJlciwgMTAgKSA6IGNvbnZlcnRlZE51bWJlcjtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogR3JhbW1hdGljYWwgdHJhbnNmb3JtYXRpb25zLCBuZWVkZWQgZm9yIGluZmxlY3RlZCBsYW5ndWFnZXMuXG5cdFx0ICogSW52b2tlZCBieSBwdXR0aW5nIHt7Z3JhbW1hcjpmb3JtfHdvcmR9fSBpbiBhIG1lc3NhZ2UuXG5cdFx0ICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgZm9yIGxhbmd1YWdlcyB0aGF0IG5lZWQgc3BlY2lhbCBncmFtbWFyIHJ1bGVzXG5cdFx0ICogYXBwbGllZCBkeW5hbWljYWxseS5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSB3b3JkXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGZvcm1cblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9XG5cdFx0ICovXG5cdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG5cdFx0Y29udmVydEdyYW1tYXI6IGZ1bmN0aW9uICggd29yZCwgZm9ybSApIHtcblx0XHRcdHJldHVybiB3b3JkO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBQcm92aWRlcyBhbiBhbHRlcm5hdGl2ZSB0ZXh0IGRlcGVuZGluZyBvbiBzcGVjaWZpZWQgZ2VuZGVyLiBVc2FnZVxuXHRcdCAqIHt7Z2VuZGVyOltnZW5kZXJ8dXNlciBvYmplY3RdfG1hc2N1bGluZXxmZW1pbmluZXxuZXV0cmFsfX0uIElmIHNlY29uZFxuXHRcdCAqIG9yIHRoaXJkIHBhcmFtZXRlciBhcmUgbm90IHNwZWNpZmllZCwgbWFzY3VsaW5lIGlzIHVzZWQuXG5cdFx0ICpcblx0XHQgKiBUaGVzZSBkZXRhaWxzIG1heSBiZSBvdmVycmlkZW4gcGVyIGxhbmd1YWdlLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGdlbmRlclxuXHRcdCAqICAgICAgbWFsZSwgZmVtYWxl
4060LCBvciBhbnl0aGluZyBlbHNlIGZvciBuZXV0cmFsLlxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IGZvcm1zXG5cdFx0ICogICAgICBMaXN0IG9mIGdlbmRlciBmb3Jtc1xuXHRcdCAqXG5cdFx0ICogQHJldHVybiB7c3RyaW5nfVxuXHRcdCAqL1xuXHRcdGdlbmRlcjogZnVuY3Rpb24gKCBnZW5kZXIsIGZvcm1zICkge1xuXHRcdFx0aWYgKCAhZm9ybXMgfHwgZm9ybXMubGVuZ3RoID09PSAwICkge1xuXHRcdFx0XHRyZXR1cm4gJyc7XG5cdFx0XHR9XG5cblx0XHRcdHdoaWxlICggZm9ybXMubGVuZ3RoIDwgMiApIHtcblx0XHRcdFx0Zm9ybXMucHVzaCggZm9ybXNbIGZvcm1zLmxlbmd0aCAtIDEgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGdlbmRlciA9PT0gJ21hbGUnICkge1xuXHRcdFx0XHRyZXR1cm4gZm9ybXNbIDAgXTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBnZW5kZXIgPT09ICdmZW1hbGUnICkge1xuXHRcdFx0XHRyZXR1cm4gZm9ybXNbIDEgXTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuICggZm9ybXMubGVuZ3RoID09PSAzICkgPyBmb3Jtc1sgMiBdIDogZm9ybXNbIDAgXTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogR2V0IHRoZSBkaWdpdCB0cmFuc2Zvcm0gdGFibGUgZm9yIHRoZSBnaXZlbiBsYW5ndWFnZVxuXHRcdCAqIFNlZSBodHRwOi8vY2xkci51bmljb2RlLm9yZy90cmFuc2xhdGlvbi9udW1iZXJpbmctc3lzdGVtc1xuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGxhbmd1YWdlXG5cdFx0ICogQHJldHVybiB7QXJyYXl8Ym9vbGVhbn0gTGlzdCBvZiBkaWdpdHMgaW4gdGhlIHBhc3NlZCBsYW5ndWFnZSBvciBmYWxzZVxuXHRcdCAqIHJlcHJlc2VudGF0aW9uLCBvciBib29sZWFuIGZhbHNlIGlmIHRoZXJlIGlzIG5vIGluZm9ybWF0aW9uLlxuXHRcdCAqL1xuXHRcdGRpZ2l0VHJhbnNmb3JtVGFibGU6IGZ1bmN0aW9uICggbGFuZ3VhZ2UgKSB7XG5cdFx0XHR2YXIgdGFibGVzID0ge1xuXHRcdFx0XHRhcjogJ9mg2aHZotmj2aTZpdmm2afZqNmpJyxcblx0XHRcdFx0ZmE6ICfbsNux27Lbs9u027Xbttu327jbuScsXG5cdFx0XHRcdG1sOiAn4LWm4LWn4LWo4LWp4LWq4LWr4LWs4LWt4LWu4LWvJyxcblx0XHRcdFx0a246ICfgs6bgs6fgs6jgs6ngs6rgs6vgs6zgs63gs67gs68nLFxuXHRcdFx0XHRsbzogJ+C7kOC7keC7kuC7k+C7lOC7leC7luC7l+C7mOC7mScsXG5cdFx0XHRcdG9yOiAn4K2m4K2n4K2o4K2p4K2q4K2r4K2s4K2t4K2u4K2vJyxcblx0XHRcdFx0a2g6ICfhn6Dhn6Hhn6Lhn6Phn6Thn6Xhn6bhn6fhn6jhn6knLFxuXHRcdFx0XHRwYTogJ+CppuCpp+CpqOCpqeCpquCpq+CprOCpreCpruCprycsXG5cdFx0XHRcdGd1OiAn4Kum4Kun4Kuo4Kup4Kuq4Kur4Kus4Kut4Kuu4KuvJyxcblx0XHRcdFx0aGk6ICfgpabgpafgpajgpangpargpavgpazgpa3gpa7gpa8nLFxuXHRcdFx0XHRteTogJ+GBgOGBgeGBguGBg+GBhOGBheGBhuGBh+GBiOGBiScsXG5cdFx0XHRcdHRhOiAn4K+m4K+n4K+o4K+p4K+q4K+r4K+s4K+t4K+u4K+vJyxcblx0XHRcdFx0dGU6ICfgsabgsafgsajgsangsargsavgsazgsa3gsa7gsa8nLFxuXHRcdFx0XHR0aDogJ+C5kOC5keC5kuC5k+C5lOC5leC5luC5l+C5mOC5mScsIC8vIEZJWE1FIHVzZSBpc28gNjM5IGNvZGVzXG5cdFx0XHRcdGJvOiAn4Lyg4Lyh4Lyi4Lyj4Lyk4Lyl4Lym4Lyn4Lyo4LypJyAvLyBGSVhNRSB1c2UgaXNvIDYzOSBjb2Rlc1xuXHRcdFx0fTtcblxuXHRcdFx0aWYgKCAhdGFibGVzWyBsYW5ndWFnZSBdICkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0YWJsZXNbIGxhbmd1YWdlIF0uc3BsaXQoICcnICk7XG5cdFx0fVxuXHR9O1xuXG5cdCQuZXh0ZW5kKCAkLmkxOG4ubGFuZ3VhZ2VzLCB7XG5cdFx0J2RlZmF1bHQnOiBsYW5ndWFnZVxuXHR9ICk7XG59KCBqUXVlcnkgKSApO1xuIiwiLyohXG4gKiBqUXVlcnkgSW50ZXJuYXRpb25hbGl6YXRpb24gbGlicmFyeSAtIE1lc3NhZ2UgU3RvcmVcbiAqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTIgU2FudGhvc2ggVGhvdHRpbmdhbFxuICpcbiAqIGpxdWVyeS5pMThuIGlzIGR1YWwgbGljZW5zZWQgR1BMdjIgb3IgbGF0ZXIgYW5kIE1JVC4gWW91IGRvbid0IGhhdmUgdG8gZG8gYW55dGhpbmcgc3BlY2lhbCB0b1xuICogY2hvb3NlIG9uZSBsaWNlbnNlIG9yIHRoZSBvdGhlciBhbmQgeW91IGRvbid0IGhhdmUgdG8gbm90aWZ5IGFueW9uZSB3aGljaCBsaWNlbnNlIHlvdSBhcmUgdXNpbmcuXG4gKiBZb3UgYXJlIGZyZWUgdG8gdXNlIFVuaXZlcnNhbExhbmd1YWdlU2VsZWN0b3IgaW4gY29tbWVyY2lhbCBwcm9qZWN0cyBhcyBsb25nIGFzIHRoZSBjb3B5cmlnaHRcbiAqIGhlYWRlciBpcyBsZWZ0IGludGFjdC4gU2VlIGZpbGVzIEdQTC1MSUNFTlNFIGFuZCBNSVQtTElDRU5TRSBmb3IgZGV0YWlscy5cbiAqXG4gKiBAbGljZW5jZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5jZSAyLjAgb3IgbGF0ZXJcbiAqIEBsaWNlbmNlIE1JVCBMaWNlbnNlXG4gKi9cblxuKCBmdW5jdGlvbiAoICQgKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuXHR2YXIgTWVzc2FnZVN0b3JlID0gZnVuY3Rpb24gKCkge1xuXHRcdHRoaXMubWVzc2FnZXMgPSB7fTtcblx0XHR0aGlzLnNvdXJjZXMgPSB7fTtcblx0fTtcblxuXHRmdW5jdGlvbiBqc29uTWVzc2FnZUxvYWRlciggdXJsICkge1xuXHRcdHZhciBkZWZlcnJlZCA9ICQuRGVmZXJyZWQoKTtcblxuXHRcdCQuZ2V0SlNPTiggdXJsIClcblx0XHRcdC5kb25lKCBkZWZlcnJlZC5yZXNvbHZlIClcblx0XHRcdC5mYWlsKCBmdW5jdGlvbiAoIGpxeGhyLCBzZXR0aW5ncywgZXhjZXB0aW9uICkge1xuXHRcdFx0XHQkLmkxOG4ubG9nKCAnRXJyb3IgaW4gbG9hZGluZyBtZXNzYWdlcyBmcm9tICcgKyB1cmwgKyAnIEV4Y2VwdGlvbj
4060ogJyArIGV4Y2VwdGlvbiApO1xuXHRcdFx0XHQvLyBJZ25vcmUgNDA0IGV4Y2VwdGlvbiwgYmVjYXVzZSB3ZSBhcmUgaGFuZGxpbmcgZmFsbGFiYWNrcyBleHBsaWNpdGx5XG5cdFx0XHRcdGRlZmVycmVkLnJlc29sdmUoKTtcblx0XHRcdH0gKTtcblxuXHRcdHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCk7XG5cdH1cblxuXHQvKipcblx0ICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS93aWtpbWVkaWEvanF1ZXJ5LmkxOG4vd2lraS9TcGVjaWZpY2F0aW9uI3dpa2ktTWVzc2FnZV9GaWxlX0xvYWRpbmdcblx0ICovXG5cdE1lc3NhZ2VTdG9yZS5wcm90b3R5cGUgPSB7XG5cblx0XHQvKipcblx0XHQgKiBHZW5lcmFsIG1lc3NhZ2UgbG9hZGluZyBBUEkgVGhpcyBjYW4gdGFrZSBhIFVSTCBzdHJpbmcgZm9yXG5cdFx0ICogdGhlIGpzb24gZm9ybWF0dGVkIG1lc3NhZ2VzLlxuXHRcdCAqIDxjb2RlPmxvYWQoJ3BhdGgvdG8vYWxsX2xvY2FsaXphdGlvbnMuanNvbicpOzwvY29kZT5cblx0XHQgKlxuXHRcdCAqIFRoaXMgY2FuIGFsc28gbG9hZCBhIGxvY2FsaXphdGlvbiBmaWxlIGZvciBhIGxvY2FsZSA8Y29kZT5cblx0XHQgKiBsb2FkKCAncGF0aC90by9kZS1tZXNzYWdlcy5qc29uJywgJ2RlJyApO1xuXHRcdCAqIDwvY29kZT5cblx0XHQgKiBBIGRhdGEgb2JqZWN0IGNvbnRhaW5pbmcgbWVzc2FnZSBrZXktIG1lc3NhZ2UgdHJhbnNsYXRpb24gbWFwcGluZ3Ncblx0XHQgKiBjYW4gYWxzbyBiZSBwYXNzZWQgRWc6XG5cdFx0ICogPGNvZGU+XG5cdFx0ICogbG9hZCggeyAnaGVsbG8nIDogJ0hlbGxvJyB9LCBvcHRpb25hbExvY2FsZSApO1xuXHRcdCAqIDwvY29kZT4gSWYgdGhlIGRhdGEgYXJndW1lbnQgaXNcblx0XHQgKiBudWxsL3VuZGVmaW5lZC9mYWxzZSxcblx0XHQgKiBhbGwgY2FjaGVkIG1lc3NhZ2VzIGZvciB0aGUgaTE4biBpbnN0YW5jZSB3aWxsIGdldCByZXNldC5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfE9iamVjdH0gc291cmNlXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGxvY2FsZSBMYW5ndWFnZSB0YWdcblx0XHQgKiBAcmV0dXJuIHtqUXVlcnkuUHJvbWlzZX1cblx0XHQgKi9cblx0XHRsb2FkOiBmdW5jdGlvbiAoIHNvdXJjZSwgbG9jYWxlICkge1xuXHRcdFx0dmFyIGtleSA9IG51bGwsXG5cdFx0XHRcdGRlZmVycmVkID0gbnVsbCxcblx0XHRcdFx0ZGVmZXJyZWRzID0gW10sXG5cdFx0XHRcdG1lc3NhZ2VTdG9yZSA9IHRoaXM7XG5cblx0XHRcdGlmICggdHlwZW9mIHNvdXJjZSA9PT0gJ3N0cmluZycgKSB7XG5cdFx0XHRcdC8vIFRoaXMgaXMgYSBVUkwgdG8gdGhlIG1lc3NhZ2VzIGZpbGUuXG5cdFx0XHRcdCQuaTE4bi5sb2coICdMb2FkaW5nIG1lc3NhZ2VzIGZyb206ICcgKyBzb3VyY2UgKTtcblx0XHRcdFx0ZGVmZXJyZWQgPSBqc29uTWVzc2FnZUxvYWRlciggc291cmNlIClcblx0XHRcdFx0XHQuZG9uZSggZnVuY3Rpb24gKCBsb2NhbGl6YXRpb24gKSB7XG5cdFx0XHRcdFx0XHRtZXNzYWdlU3RvcmUuc2V0KCBsb2NhbGUsIGxvY2FsaXphdGlvbiApO1xuXHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHRyZXR1cm4gZGVmZXJyZWQucHJvbWlzZSgpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGxvY2FsZSApIHtcblx0XHRcdFx0Ly8gc291cmNlIGlzIGFuIGtleS12YWx1ZSBwYWlyIG9mIG1lc3NhZ2VzIGZvciBnaXZlbiBsb2NhbGVcblx0XHRcdFx0bWVzc2FnZVN0b3JlLnNldCggbG9jYWxlLCBzb3VyY2UgKTtcblxuXHRcdFx0XHRyZXR1cm4gJC5EZWZlcnJlZCgpLnJlc29sdmUoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIHNvdXJjZSBpcyBhIGtleS12YWx1ZSBwYWlyIG9mIGxvY2FsZXMgYW5kIHRoZWlyIHNvdXJjZVxuXHRcdFx0XHRmb3IgKCBrZXkgaW4gc291cmNlICkge1xuXHRcdFx0XHRcdGlmICggT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKCBzb3VyY2UsIGtleSApICkge1xuXHRcdFx0XHRcdFx0bG9jYWxlID0ga2V5O1xuXHRcdFx0XHRcdFx0Ly8gTm8ge2xvY2FsZX0gZ2l2ZW4sIGFzc3VtZSBkYXRhIGlzIGEgZ3JvdXAgb2YgbGFuZ3VhZ2VzLFxuXHRcdFx0XHRcdFx0Ly8gY2FsbCB0aGlzIGZ1bmN0aW9uIGFnYWluIGZvciBlYWNoIGxhbmd1YWdlLlxuXHRcdFx0XHRcdFx0ZGVmZXJyZWRzLnB1c2goIG1lc3NhZ2VTdG9yZS5sb2FkKCBzb3VyY2VbIGtleSBdLCBsb2NhbGUgKSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gJC53aGVuLmFwcGx5KCAkLCBkZWZlcnJlZHMgKTtcblx0XHRcdH1cblxuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBTZXQgbWVzc2FnZXMgdG8gdGhlIGdpdmVuIGxvY2FsZS5cblx0XHQgKiBJZiBsb2NhbGUgZXhpc3RzLCBhZGQgbWVzc2FnZXMgdG8gdGhlIGxvY2FsZS5cblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBsb2NhbGVcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZXNcblx0XHQgKi9cblx0XHRzZXQ6IGZ1bmN0aW9uICggbG9jYWxlLCBtZXNzYWdlcyApIHtcblx0XHRcdGlmICggIXRoaXMubWVzc2FnZXNbIGxvY2FsZSBdICkge1xuXHRcdFx0XHR0aGlzLm1lc3NhZ2VzWyBsb2NhbGUgXSA9IG1lc3NhZ2VzO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5tZXNzYWdlc1sgbG9jYWxlIF0gPSAkLmV4dGVuZCggdGhpcy5tZXNzYWdlc1sgbG9jYWxlIF0sIG1lc3NhZ2VzICk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtzdHJpbmd9IGxvY2FsZVxuXHRcdCAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlS2V5XG5cdFx0ICogQHJldHVybiB7Ym9vbGVhbn1cblx0XHQgKi9cblx0XHRnZXQ6IGZ1bmN0aW9uICggbG9jYWxlLCBtZXNzYWdlS2V5ICkge1xuXHRcdFx0cmV0dXJuIHRoaXMubWVzc2FnZXNbIGxvY2FsZSBdICYmIHRoaXMubWVzc2FnZXNbIGxvY2FsZSBdWyBtZXNzYWdlS2V5IF07XG5cdFx0fVxuXHR9O1xuXG5cdCQuZXh0ZW5kKCAkLmkxOG4ubWVzc2FnZVN0b3JlLCBuZXcgTWVzc2FnZVN0b3JlKCkgKTtcbn0oIGpRdWVyeSApICk7XG4iLCIvKiFcbiAqIGpRdWVyeSBJbnRlcm5hdGlvbmFsaXphdGlvbiBsaWJyYXJ5XG4gKlxuICogQ29weXJpZ2h0IChDKSAyMDExLTIwMTMgU2FudGhvc2ggVGhvdHRpbmdhbCwgTmVpbCBLYW5kYWxnYW9ua2FyXG4gKlxuICoganF1ZXJ5LmkxOG4gaXMgZHVhbCBsaWNlbnNlZCBHUEx2MiBvciBsYXRlciBhbmQgTUlULiBZb3UgZG9uJ3QgaGF2ZSB0byBkb1xuICogYW55dGhpbmcgc3BlY2lhbCB0byBjaG9vc2Ugb25lIGxpY2Vuc2Ugb3IgdGhlIG90aGVyIGFuZCB5b3UgZG9uJ3QgaGF2ZSB0b1xuICogbm90aWZ5IGFueW9uZSB3aGljaCBsaWNlbnNlIHlvdSBhcmUgdXNpbmcuIFlvdSBhcmUgZnJlZSB0byB1c2VcbiAqIFVuaXZlcnNhbExhbmd1YWdlU2VsZWN0b3IgaW4gY29tbWVyY2lhbCBwcm9qZWN0cyBhcyBsb25nIGFzIHRoZSBjb3B5cmlnaHRcbiAqIGhlYWRlciBpcyBsZWZ0IGludGFjdC4gU2VlIGZpbGVzIEdQTC1MSUNFTlNFIGFuZCBNSVQtTElDRU5TRSBmb3IgZGV0YWlscy5cbiAqXG4gKiBAbGljZW5jZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5jZSAyLjAgb3IgbGF0ZXJcbiAqIEBsaWNlbmNlIE1JVCBMaWNlbnNlXG4gKi9cblxuKCBmdW5jdGlvbiAoICQgKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuXHR2YXIgTWVzc2FnZVBhcnNlciA9IGZ1bmN0aW9uICggb3B0aW9ucyApIHtcblx0XHR0aGlzLm9wdGlvbnMgPSAkLmV4dGVuZCgge30sICQuaTE4bi5wYXJzZXIuZGVmYXVsdHMsIG9wdGlvbnMgKTtcblx0XHR0aGlzLmxhbmd1YWdlID0gJC5pMThuLmxhbmd1YWdlc1sgU3RyaW5nLmxvY2FsZSBdIHx8ICQuaTE4bi5sYW5ndWFnZXNbICdkZWZhdWx0JyBdO1xuXHRcdHRoaXMuZW1pdHRlciA9ICQuaTE4bi5wYXJzZXIuZW1pdHRlcjtcblx0fTtcblxuXHRNZXNzYWdlUGFyc2VyLnByb3RvdHlwZSA9IHtcblxuXHRcdGNvbnN0cnVjdG9yOiBNZXNzYWdlUGFyc2VyLFxuXG5cdFx0c2ltcGxlUGFyc2U6IGZ1bmN0aW9uICggbWVzc2FnZSwgcGFyYW1ldGVycyApIHtcblx0XHRcdHJldHVybi
4060BtZXNzYWdlLnJlcGxhY2UoIC9cXCQoXFxkKykvZywgZnVuY3Rpb24gKCBzdHIsIG1hdGNoICkge1xuXHRcdFx0XHR2YXIgaW5kZXggPSBwYXJzZUludCggbWF0Y2gsIDEwICkgLSAxO1xuXG5cdFx0XHRcdHJldHVybiBwYXJhbWV0ZXJzWyBpbmRleCBdICE9PSB1bmRlZmluZWQgPyBwYXJhbWV0ZXJzWyBpbmRleCBdIDogJyQnICsgbWF0Y2g7XG5cdFx0XHR9ICk7XG5cdFx0fSxcblxuXHRcdHBhcnNlOiBmdW5jdGlvbiAoIG1lc3NhZ2UsIHJlcGxhY2VtZW50cyApIHtcblx0XHRcdGlmICggbWVzc2FnZS5pbmRleE9mKCAne3snICkgPCAwICkge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5zaW1wbGVQYXJzZSggbWVzc2FnZSwgcmVwbGFjZW1lbnRzICk7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuZW1pdHRlci5sYW5ndWFnZSA9ICQuaTE4bi5sYW5ndWFnZXNbICQuaTE4bigpLmxvY2FsZSBdIHx8XG5cdFx0XHRcdCQuaTE4bi5sYW5ndWFnZXNbICdkZWZhdWx0JyBdO1xuXG5cdFx0XHRyZXR1cm4gdGhpcy5lbWl0dGVyLmVtaXQoIHRoaXMuYXN0KCBtZXNzYWdlICksIHJlcGxhY2VtZW50cyApO1xuXHRcdH0sXG5cblx0XHRhc3Q6IGZ1bmN0aW9uICggbWVzc2FnZSApIHtcblx0XHRcdHZhciBwaXBlLCBjb2xvbiwgYmFja3NsYXNoLCBhbnlDaGFyYWN0ZXIsIGRvbGxhciwgZGlnaXRzLCByZWd1bGFyTGl0ZXJhbCxcblx0XHRcdFx0cmVndWxhckxpdGVyYWxXaXRob3V0QmFyLCByZWd1bGFyTGl0ZXJhbFdpdGhvdXRTcGFjZSwgZXNjYXBlZE9yTGl0ZXJhbFdpdGhvdXRCYXIsXG5cdFx0XHRcdGVzY2FwZWRPclJlZ3VsYXJMaXRlcmFsLCB0ZW1wbGF0ZUNvbnRlbnRzLCB0ZW1wbGF0ZU5hbWUsIG9wZW5UZW1wbGF0ZSxcblx0XHRcdFx0Y2xvc2VUZW1wbGF0ZSwgZXhwcmVzc2lvbiwgcGFyYW1FeHByZXNzaW9uLCByZXN1bHQsXG5cdFx0XHRcdHBvcyA9IDA7XG5cblx0XHRcdC8vIFRyeSBwYXJzZXJzIHVudGlsIG9uZSB3b3JrcywgaWYgbm9uZSB3b3JrIHJldHVybiBudWxsXG5cdFx0XHRmdW5jdGlvbiBjaG9pY2UoIHBhcnNlclN5bnRheCApIHtcblx0XHRcdFx0cmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHR2YXIgaSwgcmVzdWx0O1xuXG5cdFx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBwYXJzZXJTeW50YXgubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRyZXN1bHQgPSBwYXJzZXJTeW50YXhbIGkgXSgpO1xuXG5cdFx0XHRcdFx0XHRpZiAoIHJlc3VsdCAhPT0gbnVsbCApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVHJ5IHNldmVyYWwgcGFyc2VyU3ludGF4LWVzIGluIGEgcm93LlxuXHRcdFx0Ly8gQWxsIG11c3Qgc3VjY2VlZDsgb3RoZXJ3aXNlLCByZXR1cm4gbnVsbC5cblx0XHRcdC8vIFRoaXMgaXMgdGhlIG9ubHkgZWFnZXIgb25lLlxuXHRcdFx0ZnVuY3Rpb24gc2VxdWVuY2UoIHBhcnNlclN5bnRheCApIHtcblx0XHRcdFx0dmFyIGksIHJlcyxcblx0XHRcdFx0XHRvcmlnaW5hbFBvcyA9IHBvcyxcblx0XHRcdFx0XHRyZXN1bHQgPSBbXTtcblxuXHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IHBhcnNlclN5bnRheC5sZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0XHRyZXMgPSBwYXJzZXJTeW50YXhbIGkgXSgpO1xuXG5cdFx0XHRcdFx0aWYgKCByZXMgPT09IG51bGwgKSB7XG5cdFx0XHRcdFx0XHRwb3MgPSBvcmlnaW5hbFBvcztcblxuXHRcdFx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmVzdWx0LnB1c2goIHJlcyApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUnVuIHRoZSBzYW1lIHBhcnNlciBvdmVyIGFuZCBvdmVyIHVudGlsIGl0IGZhaWxzLlxuXHRcdFx0Ly8gTXVzdCBzdWNjZWVkIGEgbWluaW11bSBvZiBuIHRpbWVzOyBvdGhlcndpc2UsIHJldHVybiBudWxsLlxuXHRcdFx0ZnVuY3Rpb24gbk9yTW9yZSggbiwgcCApIHtcblx0XHRcdFx0cmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHR2YXIgb3JpZ2luYWxQb3MgPSBwb3MsXG5cdFx0XHRcdFx0XHRyZXN1bHQgPSBbXSxcblx0XHRcdFx0XHRcdHBhcnNlZCA9IHAoKTtcblxuXHRcdFx0XHRcdHdoaWxlICggcGFyc2VkICE9PSBudWxsICkge1xuXHRcdFx0XHRcdFx0cmVzdWx0LnB1c2goIHBhcnNlZCApO1xuXHRcdFx0XHRcdFx0cGFyc2VkID0gcCgpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmICggcmVzdWx0Lmxlbmd0aCA8IG4gKSB7XG5cdFx0XHRcdFx0XHRwb3MgPSBvcmlnaW5hbFBvcztcblxuXHRcdFx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSGVscGVycyAtLSBqdXN0IG1ha2UgcGFyc2VyU3ludGF4IG91dCBvZiBzaW1wbGVyIEpTIGJ1aWx0aW4gdHlwZXNcblxuXHRcdFx0ZnVuY3Rpb24gbWFrZVN0cmluZ1BhcnNlciggcyApIHtcblx0XHRcdFx0dmFyIGxlbiA9IHMubGVuZ3RoO1xuXG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dmFyIHJlc3VsdCA9IG51bGw7XG5cblx0XHRcdFx0XHRpZiAoIG1lc3NhZ2Uuc2xpY2UoIHBvcywgcG9zICsgbGVuICkgPT09IHMgKSB7XG5cdFx0XHRcdFx0XHRyZXN1bHQgPSBzO1xuXHRcdFx0XHRcdFx0cG9zICs9IGxlbjtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRmdW5jdGlvbiBtYWtlUmVnZXhQYXJzZXIoIHJlZ2V4ICkge1xuXHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdHZhciBtYXRjaGVzID0gbWVzc2FnZS5zbGljZSggcG9zICkubWF0Y2goIHJlZ2V4ICk7XG5cblx0XHRcdFx0XHRpZiAoIG1hdGNoZXMgPT09IG51bGwgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRwb3MgKz0gbWF0Y2hlc1sgMCBdLmxlbmd0aDtcblxuXHRcdFx0XHRcdHJldHVybi
4060BtYXRjaGVzWyAwIF07XG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdHBpcGUgPSBtYWtlU3RyaW5nUGFyc2VyKCAnfCcgKTtcblx0XHRcdGNvbG9uID0gbWFrZVN0cmluZ1BhcnNlciggJzonICk7XG5cdFx0XHRiYWNrc2xhc2ggPSBtYWtlU3RyaW5nUGFyc2VyKCAnXFxcXCcgKTtcblx0XHRcdGFueUNoYXJhY3RlciA9IG1ha2VSZWdleFBhcnNlciggL14uLyApO1xuXHRcdFx0ZG9sbGFyID0gbWFrZVN0cmluZ1BhcnNlciggJyQnICk7XG5cdFx0XHRkaWdpdHMgPSBtYWtlUmVnZXhQYXJzZXIoIC9eXFxkKy8gKTtcblx0XHRcdHJlZ3VsYXJMaXRlcmFsID0gbWFrZVJlZ2V4UGFyc2VyKCAvXltee31bXFxdJFxcXFxdLyApO1xuXHRcdFx0cmVndWxhckxpdGVyYWxXaXRob3V0QmFyID0gbWFrZVJlZ2V4UGFyc2VyKCAvXltee31bXFxdJFxcXFx8XS8gKTtcblx0XHRcdHJlZ3VsYXJMaXRlcmFsV2l0aG91dFNwYWNlID0gbWFrZVJlZ2V4UGFyc2VyKCAvXltee31bXFxdJFxcc10vICk7XG5cblx0XHRcdC8vIFRoZXJlIGlzIGEgZ2VuZXJhbCBwYXR0ZXJuOlxuXHRcdFx0Ly8gcGFyc2UgYSB0aGluZztcblx0XHRcdC8vIGlmIGl0IHdvcmtlZCwgYXBwbHkgdHJhbnNmb3JtLFxuXHRcdFx0Ly8gb3RoZXJ3aXNlIHJldHVybiBudWxsLlxuXHRcdFx0Ly8gQnV0IHVzaW5nIHRoaXMgYXMgYSBjb21iaW5hdG9yIHNlZW1zIHRvIGNhdXNlIHByb2JsZW1zXG5cdFx0XHQvLyB3aGVuIGNvbWJpbmVkIHdpdGggbk9yTW9yZSgpLlxuXHRcdFx0Ly8gTWF5IGJlIHNvbWUgc2NvcGluZyBpc3N1ZS5cblx0XHRcdGZ1bmN0aW9uIHRyYW5zZm9ybSggcCwgZm4gKSB7XG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dmFyIHJlc3VsdCA9IHAoKTtcblxuXHRcdFx0XHRcdHJldHVybiByZXN1bHQgPT09IG51bGwgPyBudWxsIDogZm4oIHJlc3VsdCApO1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBVc2VkIHRvIGRlZmluZSBcImxpdGVyYWxzXCIgd2l0aGluIHRlbXBsYXRlIHBhcmFtZXRlcnMuIFRoZSBwaXBlXG5cdFx0XHQvLyBjaGFyYWN0ZXIgaXMgdGhlIHBhcmFtZXRlciBkZWxpbWV0ZXIsIHNvIGJ5IGRlZmF1bHRcblx0XHRcdC8vIGl0IGlzIG5vdCBhIGxpdGVyYWwgaW4gdGhlIHBhcmFtZXRlclxuXHRcdFx0ZnVuY3Rpb24gbGl0ZXJhbFdpdGhvdXRCYXIoKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBuT3JNb3JlKCAxLCBlc2NhcGVkT3JMaXRlcmFsV2l0aG91dEJhciApKCk7XG5cblx0XHRcdFx0cmV0dXJuIHJlc3VsdCA9PT0gbnVsbCA/IG51bGwgOiByZXN1bHQuam9pbiggJycgKTtcblx0XHRcdH1cblxuXHRcdFx0ZnVuY3Rpb24gbGl0ZXJhbCgpIHtcblx0XHRcdFx0dmFyIHJlc3VsdCA9IG5Pck1vcmUoIDEsIGVzY2FwZWRPclJlZ3VsYXJMaXRlcmFsICkoKTtcblxuXHRcdFx0XHRyZXR1cm4gcmVzdWx0ID09PSBudWxsID8gbnVsbCA6IHJlc3VsdC5qb2luKCAnJyApO1xuXHRcdFx0fVxuXG5cdFx0XHRmdW5jdGlvbiBlc2NhcGVkTGl0ZXJhbCgpIHtcblx0XHRcdFx0dmFyIHJlc3VsdCA9IHNlcXVlbmNlKCBbIGJhY2tzbGFzaCwgYW55Q2hhcmFjdGVyIF0gKTtcblxuXHRcdFx0XHRyZXR1cm4gcmVzdWx0ID09PSBudWxsID8gbnVsbCA6IHJlc3VsdFsgMSBdO1xuXHRcdFx0fVxuXG5cdFx0XHRjaG9pY2UoIFsgZXNjYXBlZExpdGVyYWwsIHJlZ3VsYXJMaXRlcmFsV2l0aG91dFNwYWNlIF0gKTtcblx0XHRcdGVzY2FwZWRPckxpdGVyYWxXaXRob3V0QmFyID0gY2hvaWNlKCBbIGVzY2FwZWRMaXRlcmFsLCByZWd1bGFyTGl0ZXJhbFdpdGhvdXRCYXIgXSApO1xuXHRcdFx0ZXNjYXBlZE9yUmVndWxhckxpdGVyYWwgPSBjaG9pY2UoIFsgZXNjYXBlZExpdGVyYWwsIHJlZ3VsYXJMaXRlcmFsIF0gKTtcblxuXHRcdFx0ZnVuY3Rpb24gcmVwbGFjZW1lbnQoKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBzZXF1ZW5jZSggWyBkb2xsYXIsIGRpZ2l0cyBdICk7XG5cblx0XHRcdFx0aWYgKCByZXN1bHQgPT09IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gWyAnUkVQTEFDRScsIHBhcnNlSW50KCByZXN1bHRbIDEgXSwgMTAgKSAtIDEgXTtcblx0XHRcdH1cblxuXHRcdFx0dGVtcGxhdGVOYW1lID0gdHJhbnNmb3JtKFxuXHRcdFx0XHQvLyBzZWUgJHdnTGVnYWxUaXRsZUNoYXJzXG5cdFx0XHRcdC8vIG5vdCBhbGxvd2luZyA6IGR1ZSB0byB0aGUgbmVlZCB0byBjYXRjaCBcIlBMVVJBTDokMVwiXG5cdFx0XHRcdG1ha2VSZWdleFBhcnNlciggL15bICFcIiQmJygpKiwuLzAtOTs9P0BBLVpeX2BhLXp+XFx4ODAtXFx4RkYrLV0rLyApLFxuXG5cdFx0XHRcdGZ1bmN0aW9uICggcmVzdWx0ICkge1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHQudG9TdHJpbmcoKTtcblx0XHRcdFx0fVxuXHRcdFx0KTtcblxuXHRcdFx0ZnVuY3Rpb24gdGVtcGxhdGVQYXJhbSgpIHtcblx0XHRcdFx0dmFyIGV4cHIsXG5cdFx0XHRcdFx0cmVzdWx0ID0gc2VxdWVuY2UoIFsgcGlwZSwgbk9yTW9yZSggMCwgcGFyYW1FeHByZXNzaW9uICkgXSApO1xuXG5cdFx0XHRcdGlmICggcmVzdWx0ID09PSBudWxsICkge1xuXHRcdFx0XHRcdHJldHVybiBudWxsO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZXhwciA9IHJlc3VsdFsgMSBdO1xuXG5cdFx0XHRcdC8vIHVzZSBhIFwiQ09OQ0FUXCIgb3BlcmF0b3IgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG5vZGVzLFxuXHRcdFx0XHQvLyBvdGhlcndpc2UgcmV0dXJuIHRoZSBmaXJzdCBub2RlLCByYXcuXG5cdFx0XHRcdHJldHVybiBleHByLmxlbmd0aCA+IDEgPyBbICdDT05DQVQnIF0uY29uY2F0KCBleHByICkgOiBleHByWyAwIF07XG5cdFx0XHR9XG5cblx0XHRcdGZ1bmN0aW9uIHRlbXBsYXRlV2l0aFJlcGxhY2VtZW50KCkge1xuXHRcdFx0XHR2YXIgcmVzdWx0ID0gc2VxdWVuY2UoIFsgdGVtcGxhdGVOYW1lLCBjb2xvbiwgcmVwbGFjZW1lbnQgXSApO1xuXG5cdFx0XHRcdHJldHVybiByZXN1bHQgPT09IG51bGwgPyBudWxsIDogWyByZXN1bHRbIDAgXSwgcmVzdWx0WyAyIF0gXTtcblx0XHRcdH1cblxuXHRcdFx0ZnVuY3Rpb24gdGVtcGxhdGVXaXRoT3V0UmVwbGFjZW1lbnQoKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBzZXF1ZW5jZSggWyB0ZW1wbGF0ZU5hbWUsIGNvbG9uLCBwYXJhbUV4cHJlc3Npb24gXSApO
40601xuXG5cdFx0XHRcdHJldHVybiByZXN1bHQgPT09IG51bGwgPyBudWxsIDogWyByZXN1bHRbIDAgXSwgcmVzdWx0WyAyIF0gXTtcblx0XHRcdH1cblxuXHRcdFx0dGVtcGxhdGVDb250ZW50cyA9IGNob2ljZSggW1xuXHRcdFx0XHRmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dmFyIHJlcyA9IHNlcXVlbmNlKCBbXG5cdFx0XHRcdFx0XHQvLyB0ZW1wbGF0ZXMgY2FuIGhhdmUgcGxhY2Vob2xkZXJzIGZvciBkeW5hbWljXG5cdFx0XHRcdFx0XHQvLyByZXBsYWNlbWVudCBlZzoge3tQTFVSQUw6JDF8b25lIGNhcnwkMSBjYXJzfX1cblx0XHRcdFx0XHRcdC8vIG9yIG5vIHBsYWNlaG9sZGVycyBlZzpcblx0XHRcdFx0XHRcdC8vIHt7R1JBTU1BUjpnZW5pdGl2ZXx7e1NJVEVOQU1FfX19XG5cdFx0XHRcdFx0XHRjaG9pY2UoIFsgdGVtcGxhdGVXaXRoUmVwbGFjZW1lbnQsIHRlbXBsYXRlV2l0aE91dFJlcGxhY2VtZW50IF0gKSxcblx0XHRcdFx0XHRcdG5Pck1vcmUoIDAsIHRlbXBsYXRlUGFyYW0gKVxuXHRcdFx0XHRcdF0gKTtcblxuXHRcdFx0XHRcdHJldHVybiByZXMgPT09IG51bGwgPyBudWxsIDogcmVzWyAwIF0uY29uY2F0KCByZXNbIDEgXSApO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dmFyIHJlcyA9IHNlcXVlbmNlKCBbIHRlbXBsYXRlTmFtZSwgbk9yTW9yZSggMCwgdGVtcGxhdGVQYXJhbSApIF0gKTtcblxuXHRcdFx0XHRcdGlmICggcmVzID09PSBudWxsICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIFsgcmVzWyAwIF0gXS5jb25jYXQoIHJlc1sgMSBdICk7XG5cdFx0XHRcdH1cblx0XHRcdF0gKTtcblxuXHRcdFx0b3BlblRlbXBsYXRlID0gbWFrZVN0cmluZ1BhcnNlciggJ3t7JyApO1xuXHRcdFx0Y2xvc2VUZW1wbGF0ZSA9IG1ha2VTdHJpbmdQYXJzZXIoICd9fScgKTtcblxuXHRcdFx0ZnVuY3Rpb24gdGVtcGxhdGUoKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBzZXF1ZW5jZSggWyBvcGVuVGVtcGxhdGUsIHRlbXBsYXRlQ29udGVudHMsIGNsb3NlVGVtcGxhdGUgXSApO1xuXG5cdFx0XHRcdHJldHVybiByZXN1bHQgPT09IG51bGwgPyBudWxsIDogcmVzdWx0WyAxIF07XG5cdFx0XHR9XG5cblx0XHRcdGV4cHJlc3Npb24gPSBjaG9pY2UoIFsgdGVtcGxhdGUsIHJlcGxhY2VtZW50LCBsaXRlcmFsIF0gKTtcblx0XHRcdHBhcmFtRXhwcmVzc2lvbiA9IGNob2ljZSggWyB0ZW1wbGF0ZSwgcmVwbGFjZW1lbnQsIGxpdGVyYWxXaXRob3V0QmFyIF0gKTtcblxuXHRcdFx0ZnVuY3Rpb24gc3RhcnQoKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBuT3JNb3JlKCAwLCBleHByZXNzaW9uICkoKTtcblxuXHRcdFx0XHRpZiAoIHJlc3VsdCA9PT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBbICdDT05DQVQnIF0uY29uY2F0KCByZXN1bHQgKTtcblx0XHRcdH1cblxuXHRcdFx0cmVzdWx0ID0gc3RhcnQoKTtcblxuXHRcdFx0Lypcblx0XHRcdCAqIEZvciBzdWNjZXNzLCB0aGUgcG9zIG11c3QgaGF2ZSBnb3R0ZW4gdG8gdGhlIGVuZCBvZiB0aGUgaW5wdXRcblx0XHRcdCAqIGFuZCByZXR1cm5lZCBhIG5vbi1udWxsLlxuXHRcdFx0ICogbi5iLiBUaGlzIGlzIHBhcnQgb2YgbGFuZ3VhZ2UgaW5mcmFzdHJ1Y3R1cmUsIHNvIHdlIGRvIG5vdCB0aHJvdyBhblxuXHRcdFx0ICogaW50ZXJuYXRpb25hbGl6YWJsZSBtZXNzYWdlLlxuXHRcdFx0ICovXG5cdFx0XHRpZiAoIHJlc3VsdCA9PT0gbnVsbCB8fCBwb3MgIT09IG1lc3NhZ2UubGVuZ3RoICkge1xuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoICdQYXJzZSBlcnJvciBhdCBwb3NpdGlvbiAnICsgcG9zLnRvU3RyaW5nKCkgKyAnIGluIGlucHV0OiAnICsgbWVzc2FnZSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcmVzdWx0O1xuXHRcdH1cblxuXHR9O1xuXG5cdCQuZXh0ZW5kKCAkLmkxOG4ucGFyc2VyLCBuZXcgTWVzc2FnZVBhcnNlcigpICk7XG59KCBqUXVlcnkgKSApOyIsInZhciBjb2RlRXhlcmNpc2VzO1xudmFyIHByZXNlbnRlckNzc0xpbms7XG52YXIgcHJlc2VudE1vZGVJbml0aWFsaXplZCA9IGZhbHNlO1xuXG5mdW5jdGlvbiBwcmVzZW50VG9nZ2xlKCkge1xuICAgIGlmICghcHJlc2VudE1vZGVJbml0aWFsaXplZCkge1xuICAgICAgICBwcmVzZW50TW9kZVNldHVwKCk7XG4gICAgICAgIHByZXNlbnRNb2RlSW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIH1cbiAgICBsZXQgYm9kID0gJChcImJvZHlcIik7XG4gICAgbGV0IHByZXNlbnRDbGFzcyA9IFwicHJlc2VudFwiO1xuICAgIGxldCBmdWxsSGVpZ2h0Q2xhc3MgPSBcImZ1bGwtaGVpZ2h0XCI7XG4gICAgbGV0IGJvdHRvbUNsYXNzID0gXCJib3R0b21cIjtcbiAgICBpZiAoYm9kLmhhc0NsYXNzKHByZXNlbnRDbGFzcykpIHtcbiAgICAgICAgJChcInNlY3Rpb24gKlwiKVxuICAgICAgICAgICAgLm5vdChcbiAgICAgICAgICAgICAgICBcImgxLCAucHJlc2VudGF0aW9uLXRpdGxlLCAuYnRuLXByZXNlbnRlciwgLnJ1bmVzdG9uZSwgLnJ1bmVzdG9uZSAqLCBzZWN0aW9uLCAucHJlLCBjb2RlXCJcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhcImhpZGRlblwiKTsgLy9zaG93IGV2ZXJ5dGhpbmdcbiAgICAgICAgJChcIiNjb21wbGV0aW9uQnV0dG9uXCIpLnJlbW92ZUNsYXNzKFwiaGlkZGVuXCIpO1xuICAgICAgICBib2QucmVtb3ZlQ2xhc3MocHJlc2VudENsYXNzKTtcbiAgICAgICAgJChcIi5cIiArIGZ1bGxIZWlnaHRDbGFzcykucmVtb3ZlQ2xhc3MoZnVsbEhlaWdodENsYXNzKTtcbiAgICAgICAgJChcIi5cIiArIGJvdHRvbUNsYXNzKS5yZW1vdmVDbGFzcyhib3R0b21DbGFzcyk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKFwicHJlc2VudE1vZGVcIiwgXCJ0ZXh0XCIpO1xuICAgICAgICBjb2RlRXhlcmNpc2VzLnJlbW92ZUNsYXNzKFwiaGlkZGVuXCIpO1xuICAgICAgICBwcmVzZW50ZXJDc3NMaW5rLmRpc2FibGVkID0gdHJ1ZTsgLy8gZGlzYWJsZSBwcmVzZW50X21vZGUuY3NzXG4gICAgfSBlbHNlIHtcbiAgICAgICAgJChcInNlY3Rpb24gKlwiKVxuICAgICAgICAgICAgLm5vdChcbiAgICAgICAgICAgICAgICBcImgxLCAucHJlc2VudGF0aW9uLXRpdGxlLCAuYnRuLXByZXNlbnRlciwgLnJ1bmVzdG9uZSwgLnJ1bmVzdG9uZSAqLCBzZWN0aW9uLCAucHJlLCBjb2RlXCJcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5hZGRDbGFzcyhcImhpZGRlblwiKTsgLy8gaGlkZSBleHRyYW5lb3VzIHN0dWZmXG4gICAgICAgICQoXCIjY29tcGxldGlvbkJ1dHRvblwiKS5hZGRDbGFzcyhcImhpZGRlblwiKTtcbiAgICAgICAgYm9kLmFkZENsYXNzKHByZXNlbnRDbGFzcyk7XG4gICAgICAgIGJvZC5hZGRDbGFzcyhmdWxsSGVpZ2h0Q2xhc3MpO1xuICAgICAgICAkKFwiaHRtbFwiKS5hZGRDbGFzcyhmdWxsSGVpZ2h0Q2xhc3MpO1xuICAgICAgICAkKFwic2VjdGlvbiAucnVuZXN0b25lXCIpLmFkZENsYXNzKGZ1bGxIZWlnaHRDbGFzcyk7XG4gICAgICAgICQoXCIuYWMtY2FwdGlvblwiKS5hZGRDbGFzcyhib3R0b21DbGFzcyk7XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKFwicHJlc2VudE1vZGVcIiwgcHJlc2VudENsYXNzKTtcbiAgICAgICAgLy8gcHJlc2VudGVyX21vZGUuY3NzIGlzIGxvYWRlZCBieSB3ZWJwYWNrXG4gICAgICAgIC8vbG9hZFByZXNlbnRlckNzcygpOyAvLyBwcmVzZW50X21vZGUuY3NzIHNob3VsZCBvbmx5IGFwcGx5IHdoZW4gaW4gcHJlc2VudGVyIG1vZGUuXG4gICAgICAgIGFjdGl2YXRlRXhlcmNpc2UoKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxvYWRQcmVzZW50ZXJDc3MoKSB7XG4gICAgcHJlc2VudGVyQ3NzTGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJsaW5rXCIpO1xuICAgIHByZXNlbnRlckNzc0xpbmsudHlwZSA9IFwidGV4dC9jc3NcIjtcbiAgICBwcmVzZW50ZXJDc3NMaW5rLmhyZWYgPSBcIi4uL19zdGF0aWMvcHJlc2VudGVyX21vZGUuY3NzXCI7XG4gICAgcHJlc2VudGVyQ3NzTGluay5yZWwgPSBcInN0eWxlc2hlZXRcIjtcbiAgICBkb2
4060N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF0uYXBwZW5kQ2hpbGQocHJlc2VudGVyQ3NzTGluayk7XG59XG5cbmZ1bmN0aW9uIHByZXNlbnRNb2RlU2V0dXAoKSB7XG4gICAgLy8gbW92ZWQgdGhpcyBvdXQgb2YgY29uZmlndXJlXG4gICAgbGV0IGRhdGFDb21wb25lbnQgPSAkKFwiW2RhdGEtY2hpbGRjb21wb25lbnRdXCIpO1xuXG4gICAgLy8gdGhpcyBzdGlsbCBsZWF2ZXMgc29tZSB0aGluZ3Mgc2VtaS1tZXNzZWQgdXAgd2hlbiB5b3UgZXhpdCBwcmVzZW50ZXIgbW9kZS5cbiAgICAvLyBidXQgaW5zdHJ1Y3RvcnMgd2lsbCBwcm9iYWJseSBqdXN0IGxlYXJuIHRvIHJlZnJlc2ggdGhlIHBhZ2UuXG4gICAgZGF0YUNvbXBvbmVudC5hZGRDbGFzcyhcInJ1bmVzdG9uZVwiKTtcbiAgICBkYXRhQ29tcG9uZW50LnBhcmVudCgpLmNsb3Nlc3QoXCJkaXZcIikubm90KFwic2VjdGlvblwiKS5hZGRDbGFzcyhcInJ1bmVzdG9uZVwiKTtcbiAgICBkYXRhQ29tcG9uZW50LnBhcmVudCgpLmNsb3Nlc3QoXCJkaXZcIikuY3NzKFwibWF4LXdpZHRoXCIsIFwibm9uZVwiKTtcblxuICAgIGRhdGFDb21wb25lbnQuZWFjaChmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICAgICAgbGV0IG1lID0gJCh0aGlzKTtcbiAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgLmZpbmQoXCIuYWNfY29kZV9kaXYsIC5hY19vdXRwdXRcIilcbiAgICAgICAgICAgIC53cmFwQWxsKFwiPGRpdiBjbGFzcz0nYWMtYmxvY2snIHN0eWxlPSd3aWR0aDogMTAwJTsnPjwvZGl2PlwiKTtcbiAgICB9KTtcblxuICAgIGNvZGVsZW5zTGlzdGVuZXIoNTAwKTtcbiAgICAkKFwic2VjdGlvbiBpbWdcIikud3JhcCgnPGRpdiBjbGFzcz1cInJ1bmVzdG9uZVwiPicpO1xuICAgIGNvZGVFeGVyY2lzZXMgPSAkKFwiLnJ1bmVzdG9uZVwiKS5ub3QoXCIucnVuZXN0b25lIC5ydW5lc3RvbmVcIik7XG4gICAgLy8gY29
4060kZUV4ZXJjaXNlcy5lYWNoKGZ1bmN0aW9uKCl7XG4gICAgJChcImgxXCIpLmJlZm9yZShcbiAgICAgICAgXCI8ZGl2IGNsYXNzPSdwcmVzZW50YXRpb24tdGl0bGUnPiBcXFxuICAgICAgICA8YnV0dG9uIGNsYXNzPSdwcmV2LWV4ZXJjaXNlIGJ0bi1wcmVzZW50ZXIgYnRuLWdyZXktb3V0bGluZScgb25jbGljaz0ncHJldkV4ZXJjaXNlKCknPkJhY2s8L2J1dHRvbj4gXFxcbiAgICAgICAgPGJ1dHRvbiBjbGFzcz0nbmV4dC1leGVyY2lzZSBidG4tcHJlc2VudGVyIGJ0bi1ncmV5LXNvbGlkJyBvbmNsaWNrPSduZXh0RXhlcmNpc2UoKSc+TmV4dDwvYnV0dG9uPiBcXFxuICAgICAgPC9kaXY+XCJcbiAgICApO1xufVxuZnVuY3Rpb24gZ2V0QWN0aXZlRXhlcmNpc2UoKSB7XG4gICAgcmV0dXJuIChhY3RpdmUgPSBjb2RlRXhlcmNpc2VzLmZpbHRlcihcIi5hY3RpdmVcIikpO1xufVxuXG5mdW5jdGlvbiBhY3RpdmF0ZUV4ZXJjaXNlKGluZGV4KSB7XG4gICAgaWYgKHR5cGVvZiBpbmRleCA9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIGluZGV4ID0gMDtcbiAgICB9XG5cbiAgICBsZXQgYWN0aXZlID0gZ2V0QWN0aXZlRXhlcmNpc2UoKTtcblxuICAgIGlmIChjb2RlRXhlcmNpc2VzLmxlbmd0aCkge1xuICAgICAgICBhY3RpdmUucmVtb3ZlQ2xhc3MoXCJhY3RpdmVcIik7XG4gICAgICAgIGFjdGl2ZSA9ICQoY29kZUV4ZXJjaXNlc1tpbmRleF0pLmFkZENsYXNzKFwiYWN0aXZlXCIpO1xuICAgICAgICBhY3RpdmUucmVtb3ZlQ2xhc3MoXCJoaWRkZW5cIik7XG4gICAgICAgIGNvZGVFeGVyY2lzZXMubm90KGNvZGVFeGVyY2lzZXMuZmlsdGVyKFwiLmFjdGl2ZVwiKSkuYWRkQ2xhc3MoXCJoaWRkZW5cIik7XG4gICAgfVxufVxuXG53aW5kb3cubmV4dEV4ZXJjaXNlID0gZnVuY3Rpb24oKSB7XG4gICAgbGV0IGFjdGl2ZSA9IGdldEFjdGl2ZUV4ZXJjaXNlKCk7XG4gICAgbGV0IG5leHRJbmRleCA9IGNvZGVFeGVyY2lzZXMuaW5kZXgoYWN0aXZlKSArIDE7XG4gICAgaWYgKG5leHRJbmRleCA8IGNvZGVFeGVyY2lzZXMubGVuZ3RoKSB7XG4gICAgICAgIGFjdGl2YXRlRXhlcmNpc2UobmV4dEluZGV4KTtcbiAgICB9XG59XG5cbndpbmRvdy5wcmV2RXhlcmNpc2UgPSBmdW5jdGlvbigpIHtcbiAgICBsZXQgYWN0aXZlID0gZ2V0QWN0aXZlRXhlcmNpc2UoKTtcbiAgICBsZXQgcHJldkluZGV4ID0gY29kZUV4ZXJjaXNlcy5pbmRleChhY3RpdmUpIC0gMTtcbiAgICBpZiAocHJldkluZGV4ID49IDApIHtcbiAgICAgICAgYWN0aXZhdGVFeGVyY2lzZShwcmV2SW5kZXgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY29uZmlndXJlKCkge1xuICAgIGxldCByaWdodE5hdiA9ICQoXCIubmF2YmFyLXJpZ2h0XCIpO1xuICAgIHJpZ2h0TmF2LnByZXBlbmQoXG4gICAgICAgIFwiPGxpIGNsYXNzPSdkcm9wZG93biB2aWV3LXRvZ2dsZSc+IFxcXG4gICAgICA8bGFiZWw+VmlldzogXFxcbiAgICAgICAgPHNlbGVjdCBjbGFzcz0nbW9kZS1zZWxlY3QnPiBcXFxuICAgICAgICAgIDxvcHRpb24gdmFsdWU9J3RleHQnPlRleHRib29rPC9vcHRpb24+IFxcXG4gICAgICAgICAgPG9wdGlvbiB2YWx1ZT0ncHJlc2VudCc+Q29kZSBQcmVzZW50ZXI8L29wdGlvbj4gXFxcbiAgICAgICAgPC9zZWxlY3Q+IFxcXG4gICAgICA8L2xhYmVsPiBcXFxuICAgIDwvbGk+XCJcbiAgICApO1xuXG4gICAgbGV0IG1vZGVTZWxlY3QgPSAkKFwiLm1vZGUtc2VsZWN0XCIpLmNoYW5nZShwcmVzZW50VG9nZ2xlKTtcbn1cblxuZnVuY3Rpb24gY29kZWxlbnNMaXN0ZW5lcihkdXJhdGlvbikge1xuICAgIC8vICQoXCIuRXhlY3V0aW9uVmlzdWFsaXplclwiKS5sZW5ndGggPyBjb25maWd1cmVDb2RlbGVucygpIDogc2V0VGltZW91dChjb2RlbGVuc0xpc3RlbmVyLCBkdXJhdGlvbik7XG4gICAgLy8gY29uZmlndXJlQ29kZWxlbnMoKTtcbn1cblxuZnVuY3Rpb24gY29uZmlndXJlQ29kZWxlbnMoKSB7XG4gICAgbGV0IGFjQ29kZVRpdGxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImg0XCIpO1xuICAgIGFjQ29kZVRpdGxlLnRleHRDb250ZW50ID0gXCJBY3RpdmUgQ29kZSBXaW5kb3dcIjtcbiAgICBsZXQgYWNDb2RlID0gJChcIi5hY19jb2RlX2RpdlwiKTtcbiAgICAkKFwiLmFjX2NvZGVfZGl2XCIpLmFkZENsYXNzKFwiY29sLW1kLTZcIik7XG4gICAgYWNDb2RlLnByZXBlbmQoYWNDb2RlVGl0bGUpO1xuXG4gICAgYWNPdXRUaXRsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJoNFwiKTtcbiAgICBhY091dFRpdGxlLnRleHRDb250ZW50ID0gXCJPdXRwdXQgV2luZG93XCI7XG4gICAgbGV0IGFjT3V0ID0gJChcIi5hY19vdXRwdXRcIikuYWRkQ2xhc3MoXCJjb2wtbWQtNlwiKTtcbiAgICAkKFwiLmFjX291dHB1dFwiKS5wcmVwZW5kKGFjT3V0VGl0bGUpO1xuXG4gICAgbGV0IHNrZXRjaHBhZFRpdGxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImg0XCIpO1xuICAgIHNrZXRjaHBhZFRpdGxlLnRleHRDb250ZW50ID0gXCJTa2V0Y2hwYWRcIjtcbiAgICBsZXQgc2tldGNocGFkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNwYW5cIik7XG4gICAgJChza2V0Y2hwYWQpLmFkZENsYXNzKFwic2tldGNocGFkXCIpO1xuICAgIGxldCBza2V0Y2hwYWRDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICQoc2tldGNocGFkQ29udGFpbmVyKS5hZGRDbGFzcyhcInNrZXRjaHBhZC1jb250YWluZXJcIik7XG4gICAgc2tldGNocGFkQ29udGFpbmVyLmFwcGVuZENoaWxkKHNrZXRjaHBhZFRpdGxlKTtcbiAgICBza2V0Y2hwYWRDb250YWluZXIuYXBwZW5kQ2hpbGQoc2tldGNocGFkKTtcbiAgICAvLyQoJ
4060y5hY19vdXRwdXQnKS5hcHBlbmQoc2tldGNocGFkQ29udGFpbmVyKTtcblxuICAgIGxldCB2aXN1YWxpemVycyA9ICQoXCIuRXhlY3V0aW9uVmlzdWFsaXplclwiKTtcblxuICAgIGNvbnNvbGUubG9nKFwiRWNvbnRhaW5lcjogXCIsIHRoaXMuZUNvbnRhaW5lcik7XG5cbiAgICAkKFwiW2RhdGEtY2hpbGRjb21wb25lbnRdXCIpLm9uKFwiY2xpY2tcIiwgXCJidXR0b24ucm93LW1vZGVcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAkKHRoaXMpLmNsb3Nlc3QoXCJbZGF0YS1jaGlsZGNvbXBvbmVudF1cIikucmVtb3ZlQ2xhc3MoXCJjYXJkLW1vZGVcIik7XG4gICAgICAgICQodGhpcykuY2xvc2VzdChcIltkYXRhLWNoaWxkY29tcG9uZW50XVwiKS5hZGRDbGFzcyhcInJvdy1tb2RlXCIpO1xuICAgICAgICAkKHRoaXMpLm5leHQoXCIuY2FyZC1tb2RlXCIpLnJlbW92ZUNsYXNzKFwiYWN0aXZlLWxheW91dFwiKTtcbiAgICAgICAgJCh0aGlzKS5hZGRDbGFzcyhcImFjdGl2ZS1sYXlvdXRcIik7XG4gICAgfSk7XG5cbiAgICAkKFwiW2RhdGEtY2hpbGRjb21wb25lbnRdXCIpLm9uKFwiY2xpY2tcIiwgXCJidXR0b24uY2FyZC1tb2RlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJCh0aGlzKS5jbG9zZXN0KFwiW2RhdGEtY2hpbGRjb21wb25lbnRdXCIpLnJlbW92ZUNsYXNzKFwicm93LW1vZGVcIik7XG4gICAgICAgICQodGhpcykuY2xvc2VzdChcIltkYXRhLWNoaWxkY29tcG9uZW50XVwiKS5hZGRDbGFzcyhcImNhcmQtbW9kZVwiKTtcbiAgICAgICAgJCh0aGlzKS5wcmV2KFwiLnJvdy1tb2RlXCIpLnJlbW92ZUNsYXNzKFwiYWN0aXZlLWxheW91dFwiKTtcbiAgICAgICAgJCh0aGlzKS5hZGRDbGFzcyhcImFjdGl2ZS1sYXlvdXRcIik7XG4gICAgfSk7XG5cbiAgICAkK
4060FwiW2RhdGEtY2hpbGRjb21wb25lbnRdIC5hY19zZWN0aW9uXCIpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAkKHRoaXMpLnByZXBlbmQoXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cInByZXNlbnRhdGlvbi1vcHRpb25zXCI+PGJ1dHRvbiBjbGFzcz1cInJvdy1tb2RlIGxheW91dC1idG5cIj48aW1nIHNyYz1cIi4uL19pbWFnZXMvcm93LWJ0bi1jb250ZW50LnBuZ1wiIGFsdD1cIlJvd3NcIj48L2J1dHRvbj48YnV0dG9uIGNsYXNzPVwiY2FyZC1tb2RlIGxheW91dC1idG5cIj48aW1nIHNyYz1cIi4uL19pbWFnZXMvY2FyZC1idG4tY29udGVudC5wbmdcIiBhbHQ9XCJDYXJkXCI+PC9idXR0b24+PC9kaXY+J1xuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgdmlzdWFsaXplcnMuZWFjaChmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICAgICAgbGV0IG1lID0gJCh0aGlzKTtcbiAgICAgICAgbGV0IGNvbDEgPSBtZS5maW5kKFwiI3ZpekxheW91dFRkRmlyc3RcIik7XG4gICAgICAgIGxldCBjb2wyID0gbWUuZmluZChcIiN2aXpMYXlvdXRUZFNlY29uZFwiKTtcbiAgICAgICAgbGV0IGRhdGFWaXMgPSBtZS5maW5kKFwiI2RhdGFWaXpcIik7XG4gICAgICAgIGxldCBzdGFja0hlYXBUYWJsZSA9IG1lLmZpbmQoXCIjc3RhY2tIZWFwVGFibGVcIik7XG4gICAgICAgIGxldCBvdXRwdXQgPSBtZS5maW5kKFwiI3Byb2dPdXRwdXRzXCIpO1xuICAgICAgICBvdXRwdXQuY3NzKFwiZGlzcGxheVwiLCBcImJsb2NrXCIpO1xuICAgICAgICBtZS5wYXJlbnQoKS5wcmVwZW5kKFxuICAgICAgICAgICAgXCI8ZGl2IGNsYXNzPSdwcmVzZW50YXRpb24tdGl0bGUnPjxkaXYgY2xhc3M9J3RpdGxlLXRleHQnPiBFeGFtcGxlIFwiICtcbiAgICAgICAgICAgICAgICAoTnVtYmVyKGluZGV4KSArIDEpICtcbiAgICAgICAgICAgICAgICBcIjwvZGl2PjwvZGl2PlwiXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBhY0NvZGUuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCBzZWN0aW9uID0gJCh0aGlzKS5jbG9zZXN0KFwiLmFjLWJsb2NrXCIpLnBhcmVudCgpO1xuICAgICAgICBjb25zb2xlLmxvZyhzZWN0aW9uLCBzZWN0aW9uLmxlbmd0aCk7XG4gICAgICAgIHNlY3Rpb24uYXBwZW5kKHNrZXRjaHBhZENvbnRhaW5lcik7XG4gICAgfSk7XG5cbiAgICAkK
4060FwiYnV0dG9uLmNhcmQtbW9kZVwiKS5jbGljaygpO1xuXG4gICAgbGV0IG1vZGVTZWxlY3QgPSAkKFwiLm1vZGUtc2VsZWN0XCIpO1xuICAgIGxldCBtb2RlID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJwcmVzZW50TW9kZVwiKTtcbiAgICBpZiAobW9kZSA9PSBcInByZXNlbnRcIikge1xuICAgICAgICBtb2RlU2VsZWN0LnZhbChcInByZXNlbnRcIik7XG4gICAgICAgIG1vZGVTZWxlY3QuY2hhbmdlKCk7XG4gICAgfVxufVxuXG4kKGRvY3VtZW50KS5vbihcInJ1bmVzdG9uZTpsb2dpbi1jb21wbGV0ZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgLy8gaWYgdXNlciBpcyBpbnN0cnVjdG9yLCBlbmFibGUgcHJlc2VudGVyIG1vZGVcbiAgICBpZiAoZUJvb2tDb25maWcuaXNJbnN0cnVjdG9yKSB7XG4gICAgICAgIGNvbmZpZ3VyZSgpO1xuICAgIH1cbn0pO1xuIiwiLypcbiAgICBTdXBwb3J0IGZ1bmN0aW9ucyBmb3IgUHJlVGVYdCBib29rcyBydW5uaW5nIG9uIFJ1bmVzdG9uZVxuXG4qL1xuXG5pbXBvcnQgUnVuZXN0b25lQmFzZSBmcm9tIFwiLi9ydW5lc3RvbmViYXNlLmpzXCI7XG5cbmZ1bmN0aW9uIHNldHVwUFRYRXZlbnRzKCkge1xuICAgIGxldCByYiA9IG5ldyBSdW5lc3RvbmVCYXNlKCk7XG4gICAgLy8gbG9nIGFuIGV2ZW50IHdoZW4gYSBrbm93bCBpcyBvcGVuZWQuXG4gICAgJChcIltkYXRhLWtub3dsXCIpLm9uKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgZGl2X2lkID0gJCh0aGlzKS5kYXRhKFwicmVmaWRcIik7XG4gICAgICAgIHJiLmxvZ0Jvb2tFdmVudCh7IGV2ZW50OiBcImtub3dsXCIsIGFjdDogXCJjbGlja1wiLCBkaXZfaWQ6IGRpdl9pZCB9KTtcbiAgICB9KTtcbiAgICAvLyBsb2cgYW4gZXZlbnQgd2hlbiBhIHNhZ2UgY2VsbCBpcyBldmFsdWF0ZWRcbiAgICAkKFwiLnNhZ2VjZWxsX2V2YWxCdXR0b25cIikub24oXCJjbGlja1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIGZpbmQgcGFyZW50c1xuICAgICAgICBsZXQgY29udGFpbmVyID0gJCh0aGlzKS5jbG9zZXN0KFwiLnNhZ2VjZWxsLXNhZ2VcIik7XG4gICAgICAgIGxldCBjb2RlID0gJChjb250YWluZXJbMF0pLmZpbmQoXCIuc2FnZWNlbGxfaW5wdXRcIilbMF0udGV4dENvbnRlbnQ7XG4gICAgICAgIHJiLmxvZ0Jvb2tFdmVudCh7IGV2ZW50OiBcInNhZ2VcIiwgYWN0OiBcInJ1blwiLCBkaXZfaWQ6IGNvbnRhaW5lclswXS5pZCB9KTtcbiAgICB9KTtcbiAgICBpZiAoIWVCb29rQ29uZmlnLmlzSW5zdHJ1Y3Rvcikge1xuICAgICAgICAkKFwiLmNvbW1lbnRhcnlcIikuaGlkZSgpO1xuICAgIH1cbn1cblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zb2xlLmxvZyhcInNldHRpbmcgdXAgcHJldGV4dFwiKTtcbiAgICBzZXR1cFBUWEV2ZW50cygpO1xuICAgIGxldCB3cmFwID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJwcmltYXJ5LW5hdmJhci1zdGlja3ktd3JhcHBlclwiKTtcbiAgICBpZiAod3JhcCkge1xuICAgICAgICB3cmFwLnN0eWxlLm92ZXJmbG93PVwidmlzaWJsZVwiO1xuICAgIH1cbn0pO1xuIiwiLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIHxkb2NuYW1lfCAtIFJ1bmVzdG9uZSBCYXNlIENsYXNzXG4gKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogQWxsIHJ1bmVzdG9uZSBjb21wb25lbnRzIHNob3VsZCBpbmhlcml0IGZyb20gUnVuZXN0b25lQmFzZS4gSW4gYWRkaXRpb24gYWxsIHJ1bmVzdG9uZSBjb21wb25lbnRzIHNob3VsZCBkbyB0aGUgZm9sbG93aW5nIHRoaW5nczpcbiAqXG4gKiAxLiAgIEVuc3VyZSB0aGF0IHRoZXkgYXJlIHdyYXBwZWQgaW4gYSBkaXYgd2l0aCB0aGUgY2xhc3MgcnVuZXN0b25lXG4gKiAyLiAgIFdyaXRlIHRoZWlyIHNvdXJjZSBBTkQgdGhlaXIgZ2VuZXJhdGVkIGh0bWwgdG8gdGhlIGRhdGFiYXNlIGlmIHRoZSBkYXRhYmFzZSBpcyBjb25maWd1cmVkXG4gKiAzLiAgIFByb3Blcmx5IHNhdmUgYW5kIHJlc3RvcmUgdGhlaXIgYW5zd2VycyB1c2luZyB0aGUgY2hlY2tTZXJ2ZXIgbWVjaGFuaXNtIGluIHRoaXMgYmFzZSBjbGFzcy4gRWFjaCBjb21wb25lbnQgbXVzdCBwcm92aWRlIGFuIGltcGxlbWVudGF0aW9uIG9mOlxuICpcbiAqICAgICAgLSAgICBjaGVja0xvY2FsU3RvcmFnZVxuICogICAgICAtICAgIHNldExvY2FsU3RvcmFnZVxuICogICAgICAtICAgIHJlc3RvcmVBbnN3ZXJzXG4gKiAgICAgIC0gICAgZGlzYWJsZUludGVyYWN0aW9uXG4gKlxuICogNC4gICBwcm92aWRlIGEgU2VsZW5pdW0gYmFzZWQgdW5pdCB0ZXN0XG4gKi9cblxuaW1wb3J0IHsgcGFnZVByb2dyZXNzVHJhY2tlciB9IGZyb20gXCIuL2Jvb2tmdW5jcy5qc1wiO1xuLy9pbXBvcnQgXCIuLy4uL3N0eWxlcy9ydW5lc3RvbmUtY3VzdG9tLXNwaGlueC1ib290c3RyYXAuY3NzXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJ1bmVzdG9uZUJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKG9wdHMpIHtcbiAgICAgICAgdGhpcy5jb21wb25lbnRfcmVhZHlfcHJvbWlzZSA9IG5ldyBQcm9taXNlKFxuICAgICAgICAgICAgKHJlc29sdmUpID0+ICh0aGlzLl9jb21wb25lbnRfcmVhZHlfcmVzb2x2ZV9mbiA9IHJlc29sdmUpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMub3B0aW9uYWwgPSBmYWxzZTtcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cuYWxsQ29tcG9uZW50cyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgd2luZG93LmFsbENvbXBvbmVudHMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB3aW5kb3cuYWxsQ29tcG9uZW50cy5wdXNoKHRoaXMpO1xuICAgICAgICBpZiAob3B0cykge1xuICAgICAgICAgICAgdGhpcy5zaWQgPSBvcHRzLnNpZDtcbiAgICAgICAgICAgIHRoaXMuZ3JhZGVyYWN0aXZlID0gb3B0cy5ncmFkZXJhY3RpdmU7XG4gICAgICAgICAgICB0aGlzLnNob3dmZWVkYmFjayA9IHRydWU7XG4gICAgICAgICAgICBpZiAob3B0cy50aW1lZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaXNUaW1lZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob3B0cy5lbmZvcmNlRGVhZGxpbmUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRlYWRsaW5lID0gb3B0cy5kZWFkbGluZTtcbiAgICAgICAgICAgI
4060H1cbiAgICAgICAgICAgIGlmICgkKG9wdHMub3JpZykuZGF0YShcIm9wdGlvbmFsXCIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25hbCA9IHRydWU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9uYWwgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvcHRzLnNlbGVjdG9yX2lkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rvcl9pZCA9IG9wdHMuc2VsZWN0b3JfaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdHMuYXNzZXNzbWVudFRha2VuICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hc3Nlc3NtZW50VGFrZW4gPSBvcHRzLmFzc2Vzc21lbnRUYWtlbjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gZGVmYXVsdCB0byB0cnVlIGFzIHRoaXMgb3B0IGlzIG9ubHkgcHJvdmlkZWQgZnJvbSBhIHRpbWVkQXNzZXNzbWVudFxuICAgICAgICAgICAgICAgIHRoaXMuYXNzZXNzbWVudFRha2VuID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRoaXMgaXMgZm9yIHRoZSBzZWxlY3RxdWVzdGlvbiBwb2ludHNcbiAgICAgICAgICAgIC8vIElmIGEgc2VsZWN0cXVlc3Rpb24gaXMgcGFydCBvZiBhIHRpbWVkIGV4YW0gaXQgd2lsbCBnZXRcbiAgICAgICAgICAgIC8vIHRoZSB0aW1lZFdyYXBwZXIgb3B0aW9ucy5cbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb3B0cy50aW1lZFdyYXBwZXIgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRpbWVkV3JhcHBlciA9IG9wdHMudGltZWRXcmFwcGVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBIb3dldmVyIHNvbWV0aW1lcyBzZWxlY3RxdWVzdGlvbnNcbiAgICAgICAgICAgICAgICAvLyBhcmUgdXNlZCBpbiByZWd1bGFyIGFzc2lnbm1lbnRzLiAgVGhlIGhhY2t5IHdheSB0byBkZXRlY3QgdGhpc1xuICAgICAgICAgICAgICAgIC8vIGlzIHRvIGxvb2sgZm9yIGRvQXNzaWdubWVudCBpbiB0aGUgVVJMIGFuZCB0aGVuIGdyYWJcbiAgICAgICAgICAgICAgICAvLyB0aGUgYXNzaWdubWVudCBuYW1lIGZyb20gdGhlIGhlYWRpbmcuXG4gICAgICAgICAgICAgICAgaWYgKGxvY2F0aW9uLmhyZWYuaW5kZXhPZihcImRvQXNzaWdubWVudFwiKSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudGltZWRXcmFwcGVyID0gJChcImgxI2Fzc2lnbm1lbnRfbmFtZVwiKS50ZXh0KCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50aW1lZFdyYXBwZXIgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICgkKG9wdHMub3JpZykuZGF0YShcInF1ZXN0aW9uX2xhYmVsXCIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5xdWVzdGlvbl9sYWJlbCA9ICQob3B0cy5vcmlnKS5kYXRhKFwicXVlc3Rpb25fbGFiZWxcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmlzX3RvZ2dsZSA9IHRydWUgPyBvcHRzLmlzX3RvZ2dsZSA6IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5pc19zZWxlY3QgPSB0cnVlID8gb3B0cy5pc19zZWxlY3QgOiBmYWxzZTtcblxuICAgICAgICB9XG4gICAgICAgIHRoaXMubWplbGVtZW50cyA9IFtdO1xuICAgICAgICBsZXQgc2VsZiA9IHRoaXM7XG4gICAgICAgIHRoaXMubWpSZWFkeSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgICAgc2VsZi5tanJlc29sdmVyID0gcmVzb2x2ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYVF1ZXVlID0gbmV3IEF1dG9RdWV1ZSgpO1xuICAgICAgICB0aGlzLmpzb25IZWFkZXJzID0gbmV3IEhlYWRlcnMoe1xuICAgICAgICAgICAgXCJDb250ZW50LXR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04XCIsXG4gICAgICAgICAgICBBY2NlcHQ6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBfYGxvZ0Jvb2tFdmVudGBcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHNlbmRzIHRoZSBwcm92aWRlZCBgYGV2ZW50SW5mb2BgIHRvIHRoZSBgaHNibG9nIGVuZHBvaW50YCBvZiB0aGUgc2VydmVyLiBBd2FpdGluZyB0aGlzIGZ1bmN0aW9uIHJldHVybnMgZWl0aGVyIGBgdW5kZWZpbmVkYGAgKGlmIFJ1bmVzdG9uZSBzZXJ2aWNlcyBhcmUgbm90IGF2YWlsYWJsZSkgb3IgdGhlIGRhdGEgcmV0dXJuZWQgYnkgdGhlIHNlcnZlciBhcyBhIEphdmFTY3JpcHQgb2JqZWN0IChhbHJlYWR5IEpTT04tZGVjb2RlZCkuXG4gICAgYXN5bmMgbG9nQm9va0V2ZW50KGV2ZW50SW5mbykge1xuICAgICAgICBpZiAodGhpcy5ncmFkZXJhY3RpdmUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcG9zdF9yZXR1cm47XG4gICAgICAgIGV2ZW50SW5mby5jb3Vyc2VfbmFtZSA9IGVCb29rQ29uZmlnLmNvdXJzZTtcbiAgICAgICAgZXZlbnRJbmZvLmNsaWVudExvZ2luU3RhdHVzID0gZUJvb2tDb25maWcuaXNMb2dnZWRJb
4060jtcbiAgICAgICAgZXZlbnRJbmZvLnRpbWV6b25lb2Zmc2V0ID0gbmV3IERhdGUoKS5nZXRUaW1lem9uZU9mZnNldCgpIC8gNjA7XG4gICAgICAgIGlmICh0eXBlb2YodGhpcy5wZXJjZW50KSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgZXZlbnRJbmZvLnBlcmNlbnQgPSB0aGlzLnBlcmNlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgZUJvb2tDb25maWcuaXNMb2dnZWRJbiAmJlxuICAgICAgICAgICAgZUJvb2tDb25maWcudXNlUnVuZXN0b25lU2VydmljZXMgJiZcbiAgICAgICAgICAgIGVCb29rQ29uZmlnLmxvZ0xldmVsID4gMFxuICAgICAgICApIHtcbiAgICAgICAgICAgIHBvc3RfcmV0dXJuID0gdGhpcy5wb3N0TG9nTWVzc2FnZShldmVudEluZm8pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5pc1RpbWVkIHx8IGVCb29rQ29uZmlnLmRlYnVnKSB7XG4gICAgICAgICAgICBsZXQgcHJlZml4ID0gZUJvb2tDb25maWcuaXNMb2dnZWRJbiA/IFwiU2F2ZVwiIDogXCJOb3RcIjtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGAke3ByZWZpeH0gbG9nZ2luZyBldmVudCBgICsgSlNPTi5zdHJpbmdpZnkoZXZlbnRJbmZvKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gV2hlbiBzZWxlY3RxdWVzdGlvbnMgYXJlIHBhcnQgb2YgYW4gYXNzaWdubWVudCBlc3BlY2lhbGx5IHRvZ2dsZSBxdWVzdGlvbnNcbiAgICAgICAgLy8gd2UgbmVlZCB0byBjb3VudCB1c2luZyB0aGUgc2VsZWN0b3JfaWQgb2YgdGhlIHNlbGVjdCBxdWVzdGlvbi5cbiAgICAgICAgLy8gV2UgIGFsc28gbmVlZCB0byBsb2cgYW4gZXZlbnQgZm9yIHRoYXQgc2VsZWN0b3Igc28gdGhhdCB3ZSB3aWxsIGtub3dcbiAgICAgICAgLy8gdGhhdCBpbnRlcmFjdGlvbiBoYXMgdGFrZW4gcGxhY2UuICBUaGlzIGlzICoqaW5kZXBlbmRlbnQqKiBvZiBob3cgdGhlXG4gICAgICAgIC8vIGF1dG9ncmFkZXIgd2lsbCB1bHRpbWF0ZWx5IGdyYWRlIHRoZSBxdWVzdGlvbiFcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0b3JfaWQpIHtcbiAgICAgICAgICAgIGV2ZW50SW5mby5kaXZfaWQgPSB0aGlzLnNlbGVjdG9yX2lkLnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgXCItdG9nZ2xlU2VsZWN0ZWRRdWVzdGlvblwiLFxuICAgICAgICAgICAgICAgIFwiXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBldmVudEluZm8uZXZlbnQgPSBcInNlbGVjdHF1ZXN0aW9uXCI7XG4gICAgICAgICAgICBldmVudEluZm8uYWN0ID0gXCJpbnRlcmFjdGlvblwiO1xuICAgICAgICAgICAgdGhpcy5wb3N0TG9nTWVzc2FnZShldmVudEluZm8pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBwYWdlUHJvZ3Jlc3NUcmFja2VyLnVwZGF0ZVByb2dyZXNzID09PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgICAgIGV2ZW50SW5mby5hY3QgIT0gXCJlZGl0XCIgJiZcbiAgICAgICAgICAgIHRoaXMub3B0aW9uYWwgPT0gZmFsc2VcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBwYWdlUHJvZ3Jlc3NUcmFja2VyLnVwZGF0ZVByb2dyZXNzKGV2ZW50SW5mby5kaXZfaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb3N0X3JldHVybjtcbiAgICB9XG5cbiAgICBhc3luYyBwb3N0TG9nTWVzc2FnZShldmVudEluZm8pIHtcbiAgICAgICAgdmFyIHBvc3RfcmV0dXJuO1xuICAgICAgICBsZXQgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KFxuICAgICAgICAgICAgYCR7ZUJvb2tDb25maWcubmV3X3NlcnZlcl9wcmVmaXh9L2xvZ2dlci9ib29rZXZlbnRgLCB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLmpzb25IZWFkZXJzLFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGV2ZW50SW5mbyksXG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2Y
4060XIgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChyZXF1ZXN0KTtcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MjIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gR2V0IGRldGFpbHMgYWJvdXQgd2h5IHRoaXMgaXMgdW5wcm9jZXNhYmxlLlxuICAgICAgICAgICAgICAgICAgICBwb3N0X3JldHVybiA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2cocG9zdF9yZXR1cm4uZGV0YWlsKTtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5wcm9jZXNzYWJsZSBSZXF1ZXN0XCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2Uuc3RhdHVzID09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICBwb3N0X3JldHVybiA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICBgTWlzc2luZyBhdXRoZW50aWNhdGlvbiB0b2tlbiAke3Bvc3RfcmV0dXJuLmRldGFpbH1gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgYXV0aGVudGljYXRpb24gdG9rZW5cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHNhdmUgdGhlIGxvZyBlbnRyeVxuICAgICAgICAgICAgICAgICAgICBTdGF0dXM6ICR7cmVzcG9uc2Uuc3RhdHVzfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcG9zdF9yZXR1cm4gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGxldCBkZXRhaWwgPSBcIm5vbmVcIjtcbiAgICAgICAgICAgIGlmIChwb3N0X3JldHVybiAmJiBwb3N0X3JldHVybi5kZXRhaWwpIHtcbiAgICAgICAgICAgICAgICBkZXRhaWwgPSBwb3N0X3JldHVybi5kZXRhaWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZUJvb2tDb25maWcubG9naW5SZXF1aXJlZCkge1xuICAgICAgICAgICAgICAgIGFsZXJ0KGBFcnJvcjogWW91ciBhY3Rpb24gd2FzIG5vdCBzYXZlZCFcbiAgICAgICAgICAgICAgICAgICAgVGhlIGVycm9yIHdhcyAke2V9XG4gICAgICAgICAgICAgICAgICAgIFN0YXR1cyBDb2RlOiAke3Jlc3BvbnNlLnN0YXR1c31cbiAgICAgICAgICAgICAgICAgICAgRGV0YWlsOiAke2RldGFpbH0uXG4gICAgICAgICAgICAgICAgICAgIFBsZWFzZSByZXBvcnQgdGhpcyBlcnJvciFgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHNlbmQgYSByZXF1ZXN0IHRvIHNhdmUgdGhpcyBlcnJvclxuICAgICAgICAgICAgY29uc29sZS5sb2coYEVycm9yOiAke2V9IERldGFpbDogJHtkZXRhaWx9IFN0YXR1cyBDb2RlOiAke3Jlc3BvbnNlLnN0YXR1c31gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcG9zdF9yZXR1cm47XG4gICAgfVxuICAgIC8vIC4uIF9sb2dSdW5FdmVudDpcbiAgICAvL1xuICAgIC8vIGxvZ1J1bkV2ZW50XG4gICAgLy8gLS0tLS0tLS0tLS1cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHNlbmRzIHRoZSBwcm92aWRlZCBgYGV2ZW50SW5mb2BgIHRvIHRoZSBgcnVubG9nIGVuZHBvaW50YC4gV2hlbiBhd2FpdGVkLCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIGRhdGEgKGRlY29kZWQgZnJvbSBKU09OKSB0aGUgc2VydmVyIHNlbnQgYmFjay5cbiAgICBhc3luYyBsb2dSdW5FdmVudChldmVudEluZm8pIHtcbiAgICAgICAgbGV0IHBvc3RfcHJvbWlzZSA9IFwiZG9uZVwiO1xuICAgICAgICBpZiAodGhpcy5ncmFkZXJhY3RpdmUpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBldmVudEluZm8uY291cnNlID0gZUJvb2tDb25maWcuY291cnNlO1xuICAgICAgICBldmVudEluZm8uY2xpZW50TG9naW5TdGF0dXMgPSBlQm9va0NvbmZpZy5pc0xvZ2dlZEluO1xuICAgICAgICBldmVudEluZm8udGltZXpvbmVvZmZzZXQgPSBuZXcgRGF0ZSgpLmdldFRpbWV6b25lT2Zmc2V0KCkgLyA2MDtcbiAgICAgICAgaWYgKHRoaXMuZm9yY2VTYXZlIHx8IFwidG9fc2F2ZVwiIGluIGV2ZW50SW5mbyA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGV2ZW50SW5mby5zYXZlX2NvZGUgPSBcIlRydWVcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBlQm9va0NvbmZpZy5pc0xvZ2dlZEluICYmXG4gICAgICAgICAgICBlQm9va0NvbmZpZy51c2VSdW5lc3RvbmVTZXJ2aWNlcyAmJlxuICAgICAgICAgICAgZUJvb2tDb25maWcubG9nTGV2ZWwgPiAwXG4gICAgICAgICkge1xuICAgICAgICAgICAgbGV0IHJlcXVlc3QgPSBuZXcgUmVxdWVzdChcbiAgICAgICAgICAgICAgICBgJHtlQm9va0NvbmZpZy5uZXdfc2VydmVyX3ByZWZpeH0vbG9nZ2VyL3J1bmxvZ2AsIHtcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5qc29uSGVhZGVycyxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoZXZlbnRJbmZvKSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gocmVxdWVzdCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgcG9zdF9wcm9taXNlID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgICAgICAgIGlmIChlQm9va0NvbmZpZy5sb2dpblJlcXVpcmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KGBGYWlsZWQgdG8gc2F2ZSB5b3VyIGNvZGVcbiAgICAgICAgICAgICAgICAgICAgICAgIFN0YXR1cyBpcyAke3Jlc3BvbnNlLnN0YXR1c31cbiAgICAgICAgICAgICAgICAgICAgICAgIERldGFpbDogJHtwb3N0X3Byb21pc2UuZGV0YWlsfWApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgYERpZCBub3Qgc2F2ZSB0aGUgY29kZS4gU3RhdHVzOiAke3Jlc3BvbnNlLnN0YXR1c31gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwb3N0X3Byb21pc2UgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgI
4060H1cbiAgICAgICAgaWYgKCF0aGlzLmlzVGltZWQgfHwgZUJvb2tDb25maWcuZGVidWcpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwicnVubmluZyBcIiArIEpTT04uc3RyaW5naWZ5KGV2ZW50SW5mbykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBwYWdlUHJvZ3Jlc3NUcmFja2VyLnVwZGF0ZVByb2dyZXNzID09PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgICAgIHRoaXMub3B0aW9uYWwgPT0gZmFsc2VcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBwYWdlUHJvZ3Jlc3NUcmFja2VyLnVwZGF0ZVByb2dyZXNzKGV2ZW50SW5mby5kaXZfaWQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb3N0X3Byb21pc2U7XG4gICAgfVxuICAgIC8qIENoZWNraW5nL2xvYWRpbmcgZnJvbSBzdG9yYWdlXG4gICAgKipXQVJOSU5HOioqICBETyBOT1QgYGF3YWl0YCB0aGlzIGZ1bmN0aW9uIVxuICAgIFRoaXMgZnVuY3Rpb24sIGFsdGhvdWdoIGFzeW5jLCBkb2VzIG5vdCBleHBsaWNpdGx5IHJlc29sdmUgaXRzIHByb21pc2UgYnkgcmV0dXJuaW5nIGEgdmFsdWUuICBUaGUgcmVhc29uIGZvciB0aGlzIGlzIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGJ5IHRoZSBjb25zdHJ1Y3RvciBmb3IgbmVhcmx5IGV2ZXJ5IGNvbXBvbmVudC4gIEluIEphdmFzY3JpcHQgY29uc3RydWN0b3JzIGNhbm5vdCBiZSBhc3luYyFcblxuICAgIE9uZSBvZiB0aGUgcmVjb21tZW5kZWQgd2F5cyB0byBoYW5kbGUgdGhlIGFzeW5jIHJlcXVpcmVtZW50cyBmcm9tIHdpdGhpbiBhIGNvbnN0cnVjdG9yIGlzIHRvIHVzZSBhbiBhdHRyaWJ1dGUgYXMgYSBwcm9taXNlIGFuZCByZXNvbHZlIHRoYXQgYXR0cmlidXRlIGF0IHRoZSBhcHByb3ByaWF0ZSB0aW1lLlxuICAgICovXG4gICAgYXN5bmMgY2hlY2tTZXJ2ZXIoXG4gICAgICAgIC8vIEEgc3RyaW5nIHNwZWNpZnlpbmcgdGhlIGV2ZW50IG5hbWUgdG8gdXNlIGZvciBxdWVyeWluZyB0aGUgOnJlZjpgZ2V0QXNzZXNzUmVzdWx0c2AgZW5kcG9pbnQuXG4gICAgICAgIGV2ZW50SW5mbyxcbiAgICAgICAgLy8gSWYgdHJ1ZSwgdGhpcyBmdW5jdGlvbiB3aWxsIGludm9rZSBgYGluZGljYXRlX2NvbXBvbmVudF9yZWFkeSgpYGAganVzdCBiZWZvcmUgaXQgcmV0dXJucy4gVGhpcyBpcyBwcm92aWRlZCBzaW5jZSBtb3N0IGNvbXBvbmVudHMgYXJlIHJlYWR5IGFmdGVyIHRoaXMgZnVuY3Rpb24gY29tcGxldGVzIGl0cyB3b3JrLlxuICAgICAgICAvL1xuICAgICAgICAvLyBUT0RPOiBUaGlzIGRlZmF1bHRzIHRvIGZhbHNlLCB0byBhdm9pZCBjYXVzaW5nIHByb2JsZW1zIHdpdGggYW55IGNvbXBvbmVudHMgdGhhdCBoYXZlbid0IGJlZW4gdXBkYXRlZCBhbmQgdGVzdGVkLiBBZnRlciBhbGwgUnVuZXN0b25lIGNvbXBvbmVudHMgaGF2ZSBiZWVuIHVwZGF0ZWQsIGRlZmF1bHQgdGhpcyB0byB0cnVlIGFuZCByZW1vdmUgdGhlIGV4dHJhIHBhcmFtZXRlciBmcm9tIG1vc3QgY2FsbHMgdG8gdGhpcyBmdW5jdGlvbi5cbiAgICAgICAgd2lsbF9iZV9yZWFkeSA9IGZhbHNlXG4gICAgKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIHRoZSBzZXJ2ZXIgaGFzIHN0b3JlZCBhbnN3ZXJcbiAgICAgICAgbGV0IHNlbGYgPSB0aGlzO1xuICAgICAgICB0aGlzLmNoZWNrU2VydmVyQ29tcGxldGUgPSBuZXcgUHJvbWlzZS
4060hmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIHNlbGYuY3NyZXNvbHZlciA9IHJlc29sdmU7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICBlQm9va0NvbmZpZy5pc0xvZ2dlZEluICYmXG4gICAgICAgICAgICAodGhpcy51c2VSdW5lc3RvbmVTZXJ2aWNlcyB8fCB0aGlzLmdyYWRlcmFjdGl2ZSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBsZXQgZGF0YSA9IHt9O1xuICAgICAgICAgICAgZGF0YS5kaXZfaWQgPSB0aGlzLmRpdmlkO1xuICAgICAgICAgICAgZGF0YS5jb3Vyc2UgPSBlQm9va0NvbmZpZy5jb3Vyc2U7XG4gICAgICAgICAgICBkYXRhLmV2ZW50ID0gZXZlbnRJbmZvO1xuICAgICAgICAgICAgaWYgKHRoaXMuZ3JhZGVyYWN0aXZlICYmIHRoaXMuZGVhZGxpbmUpIHtcbiAgICAgICAgICAgICAgICBkYXRhLmRlYWRsaW5lID0gdGhpcy5kZWFkbGluZTtcbiAgICAgICAgICAgICAgICBkYXRhLnJhd2RlYWRsaW5lID0gdGhpcy5yYXdkZWFkbGluZTtcbiAgICAgICAgICAgICAgICBkYXRhLnR6b2ZmID0gdGhpcy50em9mZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnNpZCkge1xuICAgICAgICAgICAgICAgIGRhdGEuc2lkID0gdGhpcy5zaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIShkYXRhLmRpdl9pZCAmJiBkYXRhLmNvdXJzZSAmJiBkYXRhLmV2ZW50KSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgICBgQSByZXF1aXJlZCBmaWVsZCBpcyBtaXNzaW5nIGRhdGEgJHtkYXRhLmRpdl9pZH06JHtkYXRhLmNvdXJzZX06JHtkYXRhLmV2ZW50fWBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gSWYgd2UgYXJlIE5PVCBpbiBwcmFjdGljZSBtb2RlIGFuZCB3ZSBhcmUgbm90IGluIGEgcGVlciBleGVyY2lzZVxuICAgICAgICAgICAgLy8gYW5kIGFzc2Vzc21lbnRUYWtlbiBpcyB0cnVlXG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgIWVCb29rQ29uZmlnLnByYWN0aWNlX21vZGUgJiZcbiAgICAgICAgICAgICAgICAhZUJvb2tDb25maWcucGVlciAmJlxuICAgICAgICAgICAgICAgIHRoaXMuYXNzZXNzbWVudFRha2VuXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBsZXQgcmVxdWVzdCA9IG5ldyBSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICBgJHtlQm9va0NvbmZpZy5uZXdfc2VydmVyX3ByZWZpeH0vYXNzZXNzbWVudC9yZXN1bHRzYCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGRhdGEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5qc29uSGVhZGVycyxcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gocmVxdWVzdCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLmRldGFpbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVwb3B1bGF0ZUZyb21TdG9yYWdlKGRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hdHRlbXB0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZihkYXRhLmNvcnJlY3QpICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3JyZWN0ID0gZGF0YS5jb3JyZWN0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvcnJlY3QgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jc3Jlc29sdmVyKFwic2VydmVyXCIpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYEhUVFAgRXJyb3IgZ2V0dGluZyByZXN1bHRzOiAke3Jlc3BvbnNlLnN0YXR1c1RleHR9YFxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tMb2NhbFN0b3JhZ2UoKTsgLy8ganVzdCBnbyByaWdodCB0byBsb2NhbCBzdG9yYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNzcmVzb2x2ZXIoXCJsb2NhbFwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGVja0xvY2FsU3RvcmFnZSgpO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZERhdGEoe30pO1xuICAgICAgICAgICAgICAgIHRoaXMuY3NyZXNvbHZlcihcIm5vdCB0YWtlblwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tMb2NhbFN0b3JhZ2UoKTsgLy8ganVzdCBnbyByaWdodCB0byBsb2NhbCBzdG9yYWdlXG4gICAgICAgICAgICB0aGlzLmNzcmVzb2x2ZXIoXCJsb2NhbFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh3aWxsX2JlX3JlYWR5KSB7XG4gICAgICAgICAgICB0aGlzLmluZGljYXRlX2NvbXBvbmVudF9yZWFkeSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVGhpcyBtZXRob2QgYXNzdW1lcyB0aGF0IGBgdGhpcy5jb21wb25lbnREaXZgYCByZWZlcnMgdG8gdGhlIGBgZGl2YGAgY29udGFpbmluZyB0aGUgY29tcG9uZW50LCBhbmQgdGhhdCB0aGlzIGNvbXBvbmVudCdzIElEIGlzIHNldC5cbiAgICBpbmRpY2F0ZV9jb21wb25lbnRfcmVhZHkoKSB7XG4gICAgICAgIC8vIEFkZCBhIGNsYXNzIHRvIGluZGljYXRlIHRoZSBjb21wb25lbnQgaXMgbm93IHJlYWR5LlxuICAgICAgICB0aGlzLmNvbnRhaW5lckRpdi5jbGFzc0xpc3QuYWRkKFwicnVuZXN0b25lLWNvbXBvbmVudC1yZWFkeVwiKTtcbiAgICAgICAgLy8gUmVzb2x2ZSB0aGUgYGB0aGlzLmNvbXBvbmVudF9yZWFkeV9wcm9taXNlYGAuXG4gICAgICAgI
4060HRoaXMuX2NvbXBvbmVudF9yZWFkeV9yZXNvbHZlX2ZuKCk7XG4gICAgfVxuXG4gICAgbG9hZERhdGEoZGF0YSkge1xuICAgICAgICAvLyBmb3IgbW9zdCBjbGFzc2VzLCBsb2FkRGF0YSBkb2Vzbid0IGRvIGFueXRoaW5nLiBCdXQgZm9yIFBhcnNvbnMsIGFuZCBwZXJoYXBzIG90aGVycyBpbiB0aGUgZnV0dXJlLFxuICAgICAgICAvLyBpbml0aWFsaXphdGlvbiBjYW4gaGFwcGVuIGV2ZW4gd2hlbiB0aGVyZSdzIG5vIGhpc3RvcnkgdG8gYmUgbG9hZGVkXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHJlcG9wdWxhdGVGcm9tU3RvcmFnZSBpcyBjYWxsZWQgYWZ0ZXIgYSBzdWNjZXNzZnVsIEFQSSBjYWxsIGlzIG1hZGUgdG8gYGBnZXRBc3Nlc3NSZXN1bHRzYGAgaW5cbiAgICAgKiB0aGUgY2hlY2tTZXJ2ZXIgbWV0aG9kIGluIHRoaXMgY2xhc3NcbiAgICAgKlxuICAgICAqIGBgcmVzdG9yZUFuc3dlcnMsYGAgYGBzZXRMb2NhbFN0b3JhZ2VgYCBhbmQgYGBjaGVja0xvY2FsU3RvcmFnZWBgIGFyZSBkZWZpbmVkIGluIHRoZSBjaGlsZCBjbGFzc2VzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBkYXRhIC0gYSBKU09OIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIGRhdGEgbmVlZGVkIHRvIHJlc3RvcmUgYSBwcmV2aW91cyBhbnN3ZXIgZm9yIGEgY29tcG9uZW50XG4gICAgICogQHBhcmFtIHsqfSBzdGF0dXMgLSB0aGUgaHR0cCBzdGF0dXNcbiAgICAgKiBAcGFyYW0geyp9IHdoYXRldmVyIC0gaWdub3JlZFxuICAgICAqL1xuICAgIHJlcG9wdWxhdGVGcm9tU3RvcmFnZShkYXRhKSB7XG4gICAgICAgIC8vIGRlY2lkZSB3aGV0aGVyIHRvIHVzZSB0aGUgc2VydmVyJ3MgYW5zd2VyIChpZiB0aGVyZSBpcyBvbmUpIG9yIHRvIGxvYWQgZnJvbSBzdG9yYWdlXG4gICAgICAgIGlmIChkYXRhICE9PSBudWxsICYmIGRhdGEgIT09IFwibm8gZGF0YVwiICYmIHRoaXMuc2hvdWxkVXNlU2VydmVyKGRhdGEpKSB7XG4gICAgICAgICAgICB0aGlzLnJlc3RvcmVBbnN3ZXJzKGRhdGEpO1xuICAgICAgICAgICAgdGhpcy5zZXRMb2NhbFN0b3JhZ2UoZGF0YSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNoZWNrTG9jYWxTdG9yYWdlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2hvdWxkVXNlU2VydmVyKGRhdGEpIHtcbiAgICAgICAgLy8gcmV0dXJucyB0cnVlIGlmIHNlcnZlciBkYXRhIGlzIG1vcmUgcmVjZW50IHRoYW4gbG9jYWwgc3RvcmFnZSBvciBpZiBzZXJ2ZXIgc3RvcmFnZSBpcyBjb3JyZWN0XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIGRhdGEuY29ycmVjdCA9PT0gXCJUXCIgfHxcbiAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5sZW5ndGggPT09IDAgfHxcbiAgICAgICAgICAgIHRoaXMuZ3JhZGVyYWN0aXZlID09PSB0cnVlIHx8XG4gICAgICAgICAgICB0aGlzLmlzVGltZWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZXggPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLmxvY2FsU3RvcmFnZUtleSgpKTtcbiAgICAgICAgaWYgKGV4ID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgc3RvcmVkRGF0YTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHN0b3JlZERhdGEgPSBKU09OLnBhcnNlKGV4KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAvLyBlcnJvciB3aGlsZSBwYXJzaW5nOyBsaWtlbHkgZHVlIHRvIGJhZCB2YWx1ZSBzdG9yZWQgaW4gc3RvcmFnZVxuICAgICAgICAgICAgY29uc29sZS5sb2coZXJyLm1lc3NhZ2UpO1xuICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5sb2NhbFN0b3JhZ2VLZXkoKSk7XG4gICAgICAgICAgICAvLyBkZWZpbml0ZWx5IGRvbid0IHdhbnQgdG8gdXNlIGxvY2FsIHN0b3JhZ2UgaGVyZVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRhdGEuYW5zd2VyID09IHN0b3JlZERhdGEuYW5zd2VyKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgbGV0IHN0b3JhZ2VEYXRlID0gbmV3IERhdGUoc3RvcmVkRGF0YS50aW1lc3RhbXApO1xuICAgICAgICBsZXQgc2VydmVyRGF0ZSA9IG5ldyBEYXRlKGRhdGEudGltZXN0YW1wKTtcbiAgICAgICAgcmV0dXJuIHNlcnZlckRhdGUgPj0gc3RvcmFnZURhdGU7XG4gICAgfVxuICAgIC8vIFJldHVybiB0aGUga2V5IHdoaWNoIHRvIGJlIHVzZWQgd2hlbiBhY2Nlc3NpbmcgbG9jYWwgc3RvcmFnZS5cbiAgICBsb2NhbFN0b3JhZ2VLZXkoKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBlQm9va0NvbmZpZy5lbWFpbCArXG4gICAgICAgICAgICBcIjpcIiArXG4gICAgICAgICAgICBlQm9va0NvbmZpZy5jb3Vyc2UgK1xuICAgICAgICAgICAgXCI6XCIgK1xuICAgICAgICAgICAgdGhpcy5kaXZpZCArXG4gICAgICAgICAgICBcIi1naXZlblwiXG4gICAgICAgICk7XG4gICAgfVxuICAgIGFkZENhcHRpb24oZWxUeXBlKSB7XG4gICAgICAgIC8vc29tZUVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUobmV3RWxlbWVudCwgc29tZUVsZW1lbnQubmV4dFNpYmxpbmcpO1xuICAgICAgICBpZiAoIXRoaXMuaXNUaW1lZCkge1xuICAgICAgICAgICAgdmFyIGNhcERpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJwXCIpO1xuICAgICAgICAgICAgaWYgKHRoaXMucXVlc3Rpb25fbGFiZWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhcHRpb24gPSBgQWN0aXZpdHk6ICR7dGhpcy5xdWVzdGlvbl9sYWJlbH0gJHt0aGlzLmNhcHRpb259ICA8c3BhbiBjbGFzcz1cInJ1bmVzdG9uZV9jYXB0aW9uX2RpdmlkXCI+KCR7dGhpcy5kaXZpZH0pPC9zcGFuPmA7XG4gICAgICAgICAgICAgICAgJChjYXBEaXYpLmh0bWwodGhpcy5jYXB0aW9uKTtcbiAgICAgICAgICAgICAgICAkKGNhcERpdikuYWRkQ2xhc3MoYCR7ZWxUeXBlfV9jYXB0aW9uYCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICQoY2FwRGl2KS5odG1sKHRoaXMuY2FwdGlvbiArIFwiIChcIiArIHRoaXMuZGl2aWQgKyBcIilcIik7XG4gICAgICAgICAgICAgICAgJChjYXBEaXYpLmFkZENsYXNzKGAke2VsVHlwZX1fY2FwdGlvbmApO1xuICAgICAgICAgICAgICAgICQoY2FwRGl2KS5hZGRDbGFzcyhgJHtlbFR5cGV9X2NhcHRpb25fdGV4dGApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jYXBEaXYgPSBjYXBEaXY7XG4gICAgICAgICAgICAvL3RoaXMub3V0ZXJEaXYucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoY2FwRGl2LCB0aGlzLm91dGVyRGl2Lm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgI
4060HRoaXMuY29udGFpbmVyRGl2LmFwcGVuZENoaWxkKGNhcERpdik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBoYXNVc2VyQWN0aXZpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzQW5zd2VyZWQ7XG4gICAgfVxuXG4gICAgY2hlY2tDdXJyZW50QW5zd2VyKCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIFwiRWFjaCBjb21wb25lbnQgc2hvdWxkIHByb3ZpZGUgYW4gaW1wbGVtZW50YXRpb24gb2YgY2hlY2tDdXJyZW50QW5zd2VyXCJcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBhc3luYyBsb2dDdXJyZW50QW5zd2VyKCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIFwiRWFjaCBjb21wb25lbnQgc2hvdWxkIHByb3ZpZGUgYW4gaW1wbGVtZW50YXRpb24gb2YgbG9nQ3VycmVudEFuc3dlclwiXG4gICAgICAgICk7XG4gICAgfVxuICAgIHJlbmRlckZlZWRiYWNrKCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIFwiRWFjaCBjb21wb25lbnQgc2hvdWxkIHByb3ZpZGUgYW4gaW1wbGVtZW50YXRpb24gb2YgcmVuZGVyRmVlZGJhY2tcIlxuICAgICAgICApO1xuICAgIH1cbiAgICBkaXNhYmxlSW50ZXJhY3Rpb24oKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgXCJFYWNoIGNvbXBvbmVudCBzaG91bGQgcHJvdmlkZSBhbiBpbXBsZW1lbnRhdGlvbiBvZiBkaXNhYmxlSW50ZXJhY3Rpb25cIlxuICAgICAgICApO1xuICAgIH1cblxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfTogJHt0aGlzLmRpdmlkfWA7XG4gICAgfVxuXG4gICAgcXVldWVNYXRoSmF4KGNvbXBvbmVudCkge1xuICAgICAgICBpZiAodHlwZW9mKE1hdGhKYXgpID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIkVycm9yIC0tIE1hdGhKYXggaXMgbm90IGxvYWRlZFwiKVxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNlZSAtIGh0dHBzOi8vZG9jcy5tYXRoamF4Lm9yZy9lbi9sYXRlc3QvYWR2YW5jZWQvdHlwZXNldC5odG1sXG4gICAgICAgICAgICAvLyBQZXIgdGhlIGFib3ZlIHdlIHNob3VsZCBrZWVwIHRyYWNrIG9mIHRoZSBwcm9taXNlcyBhbmQgb25seSBjYWxsIHRoaXNcbiAgICAgICAgICAgIC8vIGEgc2Vjb25kIHRpbWUgaWYgYWxsIHByZXZpb3VzIHByb21pc2VzIGhhdmUgcmVzb2x2ZWQuXG4gICAgICAgICAgICAvLyBDcmVhdGUgYSBxdWV1ZSBvZiBjb21wb25lbnRzXG4gICAgICAgICAgICAvLyBzaG91bGQgd2FpdCB1bnRpbCBkZWZhdWx0UGFnZVJlYWR5IGlzIGRlZmluZWRcbiAgICAgICAgICAgIC8vIElmIGRlZmF1bHRQYWdlUmVhZHkgaXMgbm90IGRlZmluZWQgdGhlbiBqdXN0IGVucXVldWUgdGhlIGNvbXBvbmVudHMuXG4gICAgICAgICAgICAvLyBPbmNlIGRlZmF1bHRQYWdlUmVhZHkgaXMgZGVmaW5lZFxuICAgICAgICAgICAgLy8gdGhlIHdpbmRvdy5ydW5lc3RvbmVNYXRoUmVhZHkgcHJvbWlzZSB3aWxsIGJlIGZ1bGZpbGxlZCB3aGVuIHRoZVxuICAgICAgICAgICAgLy8gaW5pdGlhbCB0eXBlc2V0dGluZyBpcyBjb21wbGV0ZS5cbiAgICAgICAgICAgIGlmIChNYXRoSmF4LnR5cGVzZXRQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZih3aW5kb3cucnVuZXN0b25lTWF0aFJlYWR5KSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gd2luZG93LnJ1bmVzdG9uZU1hdGhSZWFkeS50aGVuKFxuICAgICAgICAgICAgICAgICAgICAgICAgKCkgPT4gdGhpcy5tanJlc29sdmVyKHRoaXMuYVF1ZXVlLmVucXVldWUoY29tcG9uZW50KSlcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1qcmVzb2x2ZXIodGhpcy5hUXVldWUuZW5xdWV1ZShjb21wb25lbnQpKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFdhaXRpbmcgb24gTWF0aEpheCEhICR7TWF0aEpheC50eXBlc2V0UHJvbWlzZX1gKTtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMucXVldWVNYXRoSmF4KGNvbXBvbmVudCksIDIwMCk7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFJldHVybmluZyBtanJlYWR5IHByb21pc2U6ICR7dGhpcy5talJlYWR5fWApXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubWpSZWFkeTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRlY29yYXRlU3RhdHVzKCkge1xuICAgICAgICBsZXQgcnNEaXYgPSAkKHRoaXMuY29udGFpbmVyRGl2KS5jbG9zZXN0KFwiZGl2LnJ1bmVzdG9uZVwiKVswXTtcbiAgICAgICAgaWYgKHRoaXMuY29ycmVjdCkge1xuICAgICAgICAgICAgcnNEaXYuY2xhc3NMaXN0LmFkZChcImlzQ29ycmVjdFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvcnJlY3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByc0Rpdi5jbGFzc0xpc3QuYWRkKFwibm90QW5zd2VyZWRcIik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJzRGl2LmNsYXNzTGlzdC5hZGQoXCJpc0luQ29ycmVjdFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxufVxuXG5cbi8vIEluc3BpcmF0aW9uIGFuZCBsb3RzIG9mIGNvZGUgZm9yIHRoaXMgc29sdXRpb24gY29tZSBmcm9tXG4vLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81MzU0MDM0OC9qcy1hc3luYy1hd2FpdC10YXNrcy1xdWV1ZVxuLy8gVGhlIGlkZWEgaGVyZSBpcyB0aGF0IHVudGlsIE1hdGhKYXggaXMgcmVhZHkgd2UgY2FuIGp1c3QgZW5xdWV1ZSB0aGluZ3Ncbi8vIG9uY2UgbWF0aGpheCBiZWNvbWVzIHJlYWR5IHRoZW4gd2UgY2FuIGRyYWluIHRoZSBxdWV1ZSBhbmQgY29udGludWUgYXMgdXN1YWwuXG5cbmNsYXNzIFF1ZXVlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHsgdGhpcy5faXRlbXMgPSBbXTsgfVxuICAgIGVucXVldWUoaXRlbSkgeyB0aGlzLl9pdGVtcy5wdXNoKGl0ZW0pOyB9XG4gICAgZGVxdWV1ZSgpIHsgcmV0dXJuIHRoaXMuX2l0ZW
40601zLnNoaWZ0KCk7IH1cbiAgICBnZXQgc2l6ZSgpIHsgcmV0dXJuIHRoaXMuX2l0ZW1zLmxlbmd0aDsgfVxufVxuXG5jbGFzcyBBdXRvUXVldWUgZXh0ZW5kcyBRdWV1ZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuX3BlbmRpbmdQcm9taXNlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgZW5xdWV1ZShjb21wb25lbnQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHN1cGVyLmVucXVldWUoeyBjb21wb25lbnQsIHJlc29sdmUsIHJlamVjdCB9KTtcbiAgICAgICAgICAgIHRoaXMuZGVxdWV1ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBkZXF1ZXVlKCkge1xuICAgICAgICBpZiAodGhpcy5fcGVuZGluZ1Byb21pc2UpIHJldHVybiBmYWxzZTtcblxuICAgICAgICBsZXQgaXRlbSA9IHN1cGVyLmRlcXVldWUoKTtcblxuICAgICAgICBpZiAoIWl0ZW0pIHJldHVybiBmYWxzZTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5fcGVuZGluZ1Byb21pc2UgPSB0cnVlO1xuXG4gICAgICAgICAgICBsZXQgcGF5bG9hZCA9IGF3YWl0IE1hdGhKYXguc3RhcnR1cC5kZWZhdWx0UGFnZVJlYWR5KCkudGhlbihcbiAgICAgICAgICAgICAgICBhc3luYyBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYE1hdGhKYXggUmVhZHkgLS0gZGVxdWVpbmcgYSB0eXBlc2V0dGluZyBydW4gZm9yICR7aXRlbS5jb21wb25lbnQuaWR9YClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IE1hdGhKYXgudHlwZXNldFByb21pc2UoW2l0ZW0uY29tcG9uZW50XSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5fcGVuZGluZ1Byb21pc2UgPSBmYWxzZTsgaXRlbS5yZXNvbHZlKHBheWxvYWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wZW5kaW5nUHJvbWlzZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGl0ZW0ucmVqZWN0KGUpO1xuICAgICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICB0aGlzLmRlcXVldWUoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIHdpbmRvdy5SdW5lc3RvbmVCYXNlID0gUnVuZXN0b25lQmFzZTtcbiIsImV4cG9ydCBmdW5jdGlvbiBnZXRTd2l0Y2goKSB7XG4gICAgY29uc3QgdG9nZ2xlU3dpdGNoID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnRoZW1lLXN3aXRjaCBpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0nKTtcbiAgICBjb25zdCBjdXJyZW50VGhlbWUgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgndGhlbWUnKSA/IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCd0aGVtZScpIDogbnVsbDtcblxuICAgIGlmIChjdXJyZW50VGhlbWUpIHtcbiAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS10aGVtZScsIGN1cnJlbnRUaGVtZSk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnRUaGVtZSA9PT0gJ2RhcmsnKSB7XG4gICAgICAgICAgICB0b2dnbGVTd2l0Y2guY2hlY2tlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzd2l0Y2hUaGVtZSgpIHtcblxuXHR2YXIgY2hlY2tCb3ggPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcImNoZWNrYm94XCIpO1xuICAgIGlmIChjaGVja0JveC5jaGVja2VkID09IHRydWUpIHtcbiAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS10aGVtZScsICdkYXJrJyk
40607XG4gICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCd0aGVtZScsICdkYXJrJyk7IC8vYWRkIHRoaXNcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2RhdGEtdGhlbWUnLCAnbGlnaHQnKTtcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ3RoZW1lJywgJ2xpZ2h0Jyk7IC8vYWRkIHRoaXNcbiAgICB9XG59XG4iLCIvKmdsb2JhbCB2YXJpYWJsZSBkZWNsYXJhdGlvbnMqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IFwiLi4vY3NzL3VzZXItaGlnaGxpZ2h0cy5jc3NcIjtcblxuZnVuY3Rpb24gZ2V0Q29tcGxldGlvbnMoKSB7XG4gICAgLy8gR2V0IHRoZSBjb21wbGV0aW9uIHN0YXR1c1xuICAgIGlmIChcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYubWF0Y2goXG4gICAgICAgICAgICAvKGluZGV4Lmh0bWx8dG9jdHJlZS5odG1sfGdlbmluZGV4Lmh0bWx8bmF2aGVscC5odG1sfHRvYy5odG1sfGFzc2lnbm1lbnRzLmh0bWx8RXhlcmNpc2VzLmh0bWwpL1xuICAgICAgICApXG4gICAgKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY3VycmVudFBhdGhuYW1lID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lO1xuICAgIGlmIChjdXJyZW50UGF0aG5hbWUuaW5kZXhPZihcIj9cIikgIT09IC0xKSB7XG4gICAgICAgIGN1cnJlbnRQYXRobmFtZSA9IGN1cnJlbnRQYXRobmFtZS5zdWJzdHJpbmcoXG4gICAgICAgICAgICAwLFxuICAgICAgICAgICAgY3VycmVudFBhdGhuYW1lLmxhc3RJbmRleE9mKFwiP1wiKVxuICAgICAgICApO1xuICAgIH1cbiAgICB2YXIgZGF0YSA9IHtcbiAgICAgICAgbGFzdFBhZ2VVcmw6IGN1cnJlbnRQYXRobmFtZSxcbiAgICAgICAgaXNQdHhCb29rOiBpc1ByZVRlWHQoKVxuICAgICB9O1xuICAgIGpRdWVyeVxuICAgICAgICAuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGAke2VCb29rQ29uZmlnLm5ld19zZXJ2ZXJfcHJlZml4fS9sb2dnZXIvZ2V0Q29tcGxldGlvblN0YXR1c2AsXG4gICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgICAgYXN5bmM6IGZhbHNlLFxuICAgICAgICB9KVxuICAgICAgICAuZG9uZShmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgaWYgKGRhdGEgIT0gXCJOb25lXCIpIHtcbiAgICAgICAgICAgICAgICB2Y
4060XIgY29tcGxldGlvbkRhdGEgPSBkYXRhLmRldGFpbDtcbiAgICAgICAgICAgICAgICB2YXIgY29tcGxldGlvbkNsYXNzLCBjb21wbGV0aW9uTXNnO1xuICAgICAgICAgICAgICAgIGlmIChjb21wbGV0aW9uRGF0YVswXS5jb21wbGV0aW9uU3RhdHVzID09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkNsYXNzID0gXCJidXR0b25Db25maXJtQ29tcGxldGlvblwiO1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uTXNnID1cbiAgICAgICAgICAgICAgICAgICAgICAgIFwiPGkgY2xhc3M9J2dseXBoaWNvbiBnbHlwaGljb24tb2snPjwvaT4gQ29tcGxldGVkLiBXZWxsIERvbmUhXCI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkNsYXNzID0gXCJidXR0b25Bc2tDb21wbGV0aW9uXCI7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRpb25Nc2cgPSBcIk1hcmsgYXMgQ29tcGxldGVkXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICQoXCIjc2Nwcm9ncmVzc2NvbnRhaW5lclwiKS5hcHBlbmQoXG4gICAgICAgICAgICAgICAgICAgICc8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjpjZW50ZXJcIj48YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1sZyAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRpb25DbGFzcyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnXCIgaWQ9XCJjb21wbGV0aW9uQnV0dG9uXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uTXNnICtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiPC9idXR0b24+PC9kaXY+XCJcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbn1cblxuZnVuY3Rpb24gc2hvd0xhc3RQb3NpdGlvbkJhbm5lcigpIHtcbiAgICB2YXIgbGFzdFBvc2l0aW9uVmFsID0gJC5nZXRVcmxWYXIoXCJsYXN0UG9zaXRpb25cIik7XG4gICAgaWYgKHR5cGVvZiBsYXN0UG9zaXRpb25WYWwgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgJChcImJvZHlcIikuYXBwZW5kKFxuICAgICAgICAgICAgJzxpbWcgc3JjPVwiLi4vX3N0YXRpYy9sYXN0LXBvaW50LnBuZ1wiIHN0eWxlPVwicG9zaXRpb246YWJzb2x1dGU7IHBhZGRpbmctdG9wOjU1cHg7IGxlZnQ6IDEwcHg7IHRvcDogJyArXG4gICAgICAgICAgICAgICAgcGFyc2VJbnQobGFzdFBvc2l0aW9uVmFsKSArXG4gICAgICAgICAgICAgICAgJ3B4O1wiLz4nXG4gICAgICAgICk7XG4gICAgICAgICQoXCJodG1sLCBib2R5XCIpLmFuaW1hdGUoeyBzY3JvbGxUb3A6IHBhcnNlSW50KGxhc3RQb3NpdGlvblZhbCkgfSwgMTAwMCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBhZGROYXZpZ2F0aW9uQW5kQ29tcGxldGlvbkJ1dHRvbnMoKSB7XG4gICAgaWYgKFxuICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZi5tYXRjaChcbiAgICAgICAgICAgIC8oaW5kZXguaHRtbHxnZW5pbmRleC5odG1sfG5hdmhlbHAuaHRtbHx0b2MuaHRtbHxhc3NpZ25tZW50cy5odG1sfEV4ZXJjaXNlcy5odG1sfHRvY3RyZWUuaHRtbCkvXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgbmF2TGlua0JnUmlnaHRIaWRkZW5Qb3NpdGlvbiA9IC0kKFwiI25hdkxpbmtCZ1JpZ2h0XCIpLm91dGVyV2lkdGgoKSAtIDU7XG4gICAgdmFyIG5hdkxpbmtCZ1JpZ2h0SGFsZk9wZW47XG4gICAgdmFyIG5hdkxpbmtCZ1JpZ2h0RnVsbE9wZW4gPSAwO1xuXG4gICAgaWYgKCQoXCIjY29tcGxldGlvbkJ1dHRvblwiKS5oYXNDbGFzcyhcImJ1dHRvbkFza0NvbXBsZXRpb25cIikpIHtcbiAgICAgICAgbmF2TGlua0JnUmlnaHRIYWxmT3BlbiA9IG5hdkxpbmtCZ1JpZ2h0SGlkZGVuUG9zaXRpb24gKyA3MDtcbiAgICB9IGVsc2UgaWYgKCQoXCIjY29tcGxldGlvbkJ1dHRvblwiKS5oYXNDbGFzcyhcImJ1dHRvbkNvbmZpcm1Db21wbGV0aW9uXCIpKSB7XG4gICAgICAgIG5hdkxpbmtCZ1JpZ2h0SGFsZk9wZW4gPSAwO1xuICAgIH1cbiAgICB2YXIgcmVsYXRpb25zTmV4dEljb25Jbml0aWFsUG9zaXRpb24gPSAkKFwiI3JlbGF0aW9ucy1uZXh0XCIpLmNzcyhcInJpZ2h0XCIpO1xuICAgIHZhciByZWxhdGlvbnNOZXh0SWNvbk5ld1Bvc2l0aW9uID0gLShuYXZMaW5rQmdSaWdodEhpZGRlblBvc2l0aW9uICsgMzUpO1xuXG4gICAgJChcIiNuYXZMaW5rQmdSaWdodFwiKS5jc3MoXCJyaWdodFwiLCBuYXZMaW5rQmdSaWdodEhpZGRlblBvc2l0aW9uKS5zaG93KCk7XG4gICAgdmFyIG5hdkJnU2hvd24gPSBmYWxzZTtcbiAgICAkKHdpbmRvdykuc2Nyb2xsKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgJCh3aW5kb3cpLnNjcm9sbFRvcCgpICsgJCh3aW5kb3cpLmhlaWdodCgpID09XG4gICAgICAgICAgICAkKGRvY3VtZW50KS5oZWlnaHQoKVxuICAgICAgICApIHtcbiAgICAgICAgICAgICQoXCIjbmF2TGlua0JnUmlnaHRcIikuYW5pbWF0ZShcbiAgICAgICAgICAgICAgICB7IHJpZ2h0OiBuYXZMaW5rQmdSaWdodEhhbGZPcGVuIH0sXG4gICAgICAgICAgICAgICAgMjAwXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgJChcIiNuYXZMaW5rQmdMZWZ0XCIpLmFuaW1hdGUoeyBsZWZ0OiBcIjBweFwiIH0sIDIwMCk7XG4gICAgICAgICAgICBpZiAoJChcIiNjb21wbGV0aW9uQnV0dG9uXCIpLmhhc0NsYXNzKFwiYnV0dG9uQ29uZmlybUNvbXBsZXRpb25cIikpIHtcbiAgICAgICAgICAgICAgICAkKFwiI3JlbGF0aW9ucy1uZXh0XCIpLmFuaW1hdGUoXG4gICAgICAgICAgICAgICAgICAgIHsgcmlnaHQ6IHJlbGF0aW9uc05leHRJY29uTmV3UG9zaXRpb24gfSxcbiAgICAgICAgICAgICAgICAgICAgMjAwXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5hdkJnU2hvd24gPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKG5hdkJnU2hvd24pIHtcbiAgICAgICAgICAgICQoXCIjbmF2TGlua0JnUmlnaHRcIikuYW5pbWF0ZShcbiAgICAgICAgICAgICAgICB7IHJpZ2h0OiBuYXZMaW5rQmdSaWdodEhpZGRlblBvc2l0aW9uIH0sXG4gICAgICAgICAgICAgICAgMjAwXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgJChcIiNuYXZMaW5rQmdMZWZ0XCIpLmFuaW1hdGUoeyBsZWZ0OiBcIi02NXB4XCIgfSwgMjAwKTtcbiAgICAgICAgICAgICQoXCIjcmVsYXRpb25zLW5leHRcIikuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgcmlnaHQ6IHJlbGF0aW9uc05leHRJY29uSW5pdGlhbFBvc2l0aW9uLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBuYXZCZ1Nob3duID0gZmFsc2U7XG4gICAgICAgI
4060H1cbiAgICB9KTtcblxuICAgIHZhciBjb21wbGV0aW9uRmxhZyA9IDA7XG4gICAgaWYgKCQoXCIjY29tcGxldGlvbkJ1dHRvblwiKS5oYXNDbGFzcyhcImJ1dHRvbkFza0NvbXBsZXRpb25cIikpIHtcbiAgICAgICAgY29tcGxldGlvbkZsYWcgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbXBsZXRpb25GbGFnID0gMTtcbiAgICB9XG4gICAgLy8gTWFrZSBzdXJlIHdlIG1hcmsgdGhpcyBwYWdlIGFzIHZpc2l0ZWQgcmVnYXJkbGVzcyBvZiBob3cgZmxha2V5XG4gICAgLy8gdGhlIG9udW5sb2FkIGhhbmRsZXJzIGJlY29tZS5cbiAgICBwcm9jZXNzUGFnZVN0YXRlKGNvbXBsZXRpb25GbGFnKTtcbiAgICAkKFwiI2NvbXBsZXRpb25CdXR0b25cIikub24oXCJjbGlja1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICgkKHRoaXMpLmhhc0NsYXNzKFwiYnV0dG9uQXNrQ29tcGxldGlvblwiKSkge1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhcImJ1dHRvbkFza0NvbXBsZXRpb25cIilcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoXCJidXR0b25Db25maXJtQ29tcGxldGlvblwiKVxuICAgICAgICAgICAgICAgIC5odG1sKFxuICAgICAgICAgICAgICAgICAgICBcIjxpIGNsYXNzPSdnbHlwaGljb24gZ2x5cGhpY29uLW9rJz48L2k+IENvbXBsZXRlZC4gV2VsbCBEb25lIVwiXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICQoXCIjbmF2TGlua0JnUmlnaHRcIikuYW5pbWF0ZSh7IHJpZ2h0OiBuYXZMaW5rQmdSaWdodEZ1bGxPcGVuIH0pO1xuICAgICAgICAgICAgJChcIiNyZWxhdGlvbnMtbmV4dFwiKS5hbmltYXRlKHtcbiAgICAgICAgICAgICAgICByaWdodDogcmVsYXRpb25zTmV4dEljb25OZXdQb3NpdGlvbixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbmF2TGlua0JnUmlnaHRIYWxmT3BlbiA9IDA7XG4gICAgICAgICAgICBjb21wbGV0aW9uRmxhZyA9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAoJCh0aGlzKS5oYXNDbGFzcyhcImJ1dHRvbkNvbmZpcm1Db21wbGV0aW9uXCIpKSB7XG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKFwiYnV0dG9uQ29uZmlybUNvbXBsZXRpb25cIilcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoXCJidXR0b25Bc2tDb21wbGV0aW9uXCIpXG4gICAgICAgICAgICAgICAgLmh0bWwoXCJNYXJrIGFzIENvbXBsZXRlZFwiKTtcbiAgICAgICAgICAgIG5hdkxpbmtCZ1JpZ2h0SGFsZk9wZW4gPSBuYXZMaW5rQmdSaWdodEhpZGRlblBvc2l0aW9uICsgNzA7XG4gICAgICAgICAgICAkKFwiI25hdkxpbmtCZ1JpZ2h0XCIpLmFuaW1hdGUoeyByaWdodDogbmF2TGlua0JnUmlnaHRIYWxmT3BlbiB9KTtcbiAgICAgICAgICAgICQoXCIjcmVsYXRpb25zLW5leHRcIikuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgcmlnaHQ6IHJlbGF0aW9uc05leHRJY29uSW5pdGlhbFBvc2l0aW9uLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb21wbGV0aW9uRmxhZyA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgcHJvY2Vzc1BhZ2VTdGF0ZShjb21wbGV0aW9uRmxhZyk7XG4gICAgfSk7XG5cbiAgICAkKHdpbmRvdykub24oXCJiZWZvcmV1bmxvYWRcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgaWYgKGNvbXBsZXRpb25GbGFnID09IDApIHtcbiAgICAgICAgICAgIHByb2Nlc3NQYWdlU3RhdGUoY29tcGxldGlvbkZsYWcpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cbi8vIF8gZGVjb3JhdGVUYWJsZU9mQ29udGVudHNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIGRlY29yYXRlVGFibGVPZkNvbnRlbnRzKCkge1xuICAgIGlmIChcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYudG9Mb3dlckNhc2UoKS5pbmRleE9mKFwidG9jLmh0bWxcIikgIT0gLTEgfHxcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYudG9Mb3dlckNhc2UoKS5pbmRleE9mKFwiaW5kZXguaHRtbFwiKSAhPSAtMVxuICAgICkge1xuICAgICAgICBqUXVlcnkuZ2V0KFxuICAgICAgICAgICAgYCR7ZUJvb2tDb25maWcubmV3X3NlcnZlcl9wcmVmaXh9L2xvZ2dlci9nZXRBbGxDb21wbGV0aW9uU3RhdHVzYCxcbiAgICAgICAgICAgIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN1YkNoYXB0ZXJMaXN0O1xuICAgICAgICAgICAgICAgIGlmIChkYXRhICE9IFwiTm9uZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHN1YkNoYXB0ZXJMaXN0ID0gZGF0YS5kZXRhaWw7XG5cbiAgICAgICAgICAgICAgICAgICAgdmFyIGFsbFN1YkNoYXB0ZXJVUkxzID0gJChcIiNtYWluLWNvbnRlbnQgZGl2IGxpIGFcIik7XG4gICAgICAgICAgICAgICAgICAgICQuZWFjaChzdWJDaGFwdGVyTGlzdCwgZnVuY3Rpb24gKGluZGV4LCBpdGVtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBzID0gMDsgcyA8IGFsbFN1YkNoYXB0ZXJVUkxzLmxlbmd0aDsgcysrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGxTdWJDaGFwdGVyVVJMc1tzXS5ocmVmLmluZGV4T2YoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmNoYXB0ZXJOYW1lICsgXCIvXCIgKyBpdGVtLnN1YkNoYXB0ZXJOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgIT0gLTFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKGFsbFN1YkNoYXB0ZXJVUkxzW3NdLnBhcmVudEVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKFwiY29tcGxldGVkXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwiaW5mb1RleHRDb21wbGV0ZWRcIj4tIENvbXBsZXRlZCB0aGlzIHRvcGljIG9uICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbS5lbmREYXRlICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiPC9zcGFuPlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jaGlsZHJlbigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZpcnN0KClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaG92ZXIoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQo
4060dGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubmV4dChcIi5pbmZvVGV4dENvbXBsZXRlZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zaG93KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubmV4dChcIi5pbmZvVGV4dENvbXBsZXRlZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5oaWRlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGl0ZW0uY29tcGxldGlvblN0YXR1cyA9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKGFsbFN1YkNoYXB0ZXJVUkxzW3NdLnBhcmVudEVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKFwiYWN0aXZlXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFwcGVuZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwiaW5mb1RleHRBY3RpdmVcIj5MYXN0IHJlYWQgdGhpcyB0b3BpYyBvbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0uZW5kRGF0ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIjwvc3Bhbj5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2hpbGRyZW4oKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5maXJzdCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmhvdmVyKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm5leHQoXCIuaW5mb1RleHRBY3RpdmVcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc2hvdygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm5leHQoXCIuaW5mb1RleHRBY3RpdmVcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuaGlkZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICB2Y
4060XIgZGF0YSA9IHsgY291cnNlOiBlQm9va0NvbmZpZy5jb3Vyc2UgfTtcbiAgICAgICAgalF1ZXJ5LmdldChcbiAgICAgICAgICAgIGAke2VCb29rQ29uZmlnLm5ld19zZXJ2ZXJfcHJlZml4fS9sb2dnZXIvZ2V0bGFzdHBhZ2VgLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgdmFyIGxhc3RQYWdlRGF0YTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YSAhPSBcIk5vbmVcIikge1xuICAgICAgICAgICAgICAgICAgICBsYXN0UGFnZURhdGEgPSBkYXRhLmRldGFpbDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RQYWdlRGF0YS5sYXN0UGFnZUNoYXB0ZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgJChcIiNjb250aW51ZS1yZWFkaW5nXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNob3coKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5odG1sKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGRpdiBpZD1cImp1bXAtdG8tY2hhcHRlclwiIGNsYXNzPVwiYWxlcnQgYWxlcnQtaW5mb1wiID48c3Ryb25nPllvdSB3ZXJlIExhc3QgUmVhZGluZzo8L3N0cm9uZz4gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0UGFnZURhdGEubGFzdFBhZ2VDaGFwdGVyICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsYXN0UGFnZURhdGEubGFzdFBhZ2VTdWJjaGFwdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBcIiAmZ3Q7IFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RQYWdlRGF0YS5sYXN0UGFnZVN1YmNoYXB0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFwiXCIpICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgPGEgaHJlZj1cIicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFBhZ2VEYXRhLmxhc3RQYWdlVXJsICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiP2xhc3RQb3NpdGlvbj1cIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0UGFnZURhdGEubGFzdFBhZ2VTY3JvbGxMb2NhdGlvbiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXCI+Q29udGludWUgUmVhZGluZzwvYT48L2Rpdj4nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGVuYWJsZUNvbXBsZXRpb25zKCkge1xuICAgIGdldENvbXBsZXRpb25zKCk7XG4gICAgc2hvd0xhc3RQb3NpdGlvbkJhbm5lcigpO1xuICAgIGFkZE5hdmlnYXRpb25BbmRDb21wbGV0aW9uQnV0dG9ucygpO1xuICAgIGRlY29yYXRlVGFibGVPZkNvbnRlbnRzKCk7XG59XG5cbi8vIGNhbGwgZW5hYmxlIHVzZXIgaGlnaGxpZ2h0cyBhZnRlciBsb2dpblxuJChkb2N1bWVudCkub24oXCJydW5lc3RvbmU6bG9naW5cIiwgZW5hYmxlQ29tcGxldGlvbnMpO1xuXG5mdW5jdGlvbiBpc1ByZVRlWHQoKSB7XG4gICAgbGV0IHB0eE1hcmtlciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJib2R5LnByZXRleHRcIik7XG4gICAgaWYgKHB0eE1hcmtlcikge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuLy8gXyBwcm9jZXNzUGFnZVN0YXRlXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBwcm9jZXNzUGFnZVN0YXRlKGNvbXBsZXRpb25GbGFnKSB7XG4gICAgLypMb2cgbGFzdCBwYWdlIHZpc2l0ZWQqL1xuICAgIHZhciBjdXJyZW50UGF0aG5hbWUgPSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWU7XG4gICAgaWYgKGN1cnJlbnRQYXRobmFtZS5pbmRleE9mKFwiP1wiKSAhPT0gLTEpIHtcbiAgICAgICAgY3VycmVudFBhdGhuYW1lID0gY3VycmVudFBhdGhuYW1lLnN1YnN0cmluZyhcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICBjdXJyZW50UGF0aG5hbWUubGFzdEluZGV4T2YoXCI/XCIpXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8vIElzIHRoaXMgYSBwdHggYm9vaz9cbiAgICBsZXQgaXNQdHhCb29rID0gaXNQcmVUZVh0KClcbiAgICB2YXIgZGF0YSA9IHtcbiAgICAgICAgbGFzdFBhZ2VVcmw6IGN1cnJlbnRQYXRobmFtZSxcbiAgICAgICAgbGFzdFBhZ2VTY3JvbGxMb2NhdGlvbjogJCh3aW5kb3cpLnNjcm9sbFRvcCgpLFxuICAgICAgICBjb21wbGV0aW9uRmxhZzogY29tcGxldGlvbkZsYWcsXG4gICAgICAgIGNvdXJzZTogZUJvb2tDb25maWcuY291cnNlLFxuICAgICAgICBpc1B0eEJvb2s6IGlzUHR4Qm9vayxcbiAgICB9O1xuICAgICQoZG9jdW1lbnQpLmFqYXhFcnJvcihmdW5jdGlvbiAoZSwganFoeHIsIHNldHRpbmdzLCBleGNlcHRpb24pIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJSZXF1ZXN0IEZhaWxlZCBmb3IgXCIgKyBzZXR0aW5ncy51cmwpO1xuICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICB9KTtcbiAgICBqUXVlcnkuYWpheCh7XG4gICAgICAgIHVybDogYCR7ZUJvb2tDb25maWcubmV3X3NlcnZlcl9wcmVmaXh9L2xvZ2dlci91cGRhdGVsYXN0cGFnZWAsXG4gICAgICAgIGNvbnRlbnRUeXBlOiBcImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLThcIixcbiAgICAgICAgZGF0YVR5cGU6IFwianNvblwiLFxuICAgICAgICBkYXRhOiBKU09OLnN0cmluZ2lmeShkYXRhKSxcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgYXN5bmM6IHRydWUsXG4gICAgfSk7XG59XG5cbiQuZXh0ZW5kKHtcbiAgICBnZXRVcmxWYXJzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2YXJzID0gW10sXG4gICAgICAgICAgICBoYXNoO1xuICAgICAgICB2Y
4060XIgaGFzaGVzID0gd2luZG93LmxvY2F0aW9uLnNlYXJjaFxuICAgICAgICAgICAgLnNsaWNlKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guaW5kZXhPZihcIj9cIikgKyAxKVxuICAgICAgICAgICAgLnNwbGl0KFwiJlwiKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGhhc2ggPSBoYXNoZXNbaV0uc3BsaXQoXCI9XCIpO1xuICAgICAgICAgICAgdmFycy5wdXNoKGhhc2hbMF0pO1xuICAgICAgICAgICAgdmFyc1toYXNoWzBdXSA9IGhhc2hbMV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhcnM7XG4gICAgfSxcbiAgICBnZXRVcmxWYXI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiAkLmdldFVybFZhcnMoKVtuYW1lXTtcbiAgICB9LFxufSk7XG4iLCIoZnVuY3Rpb24gKCQpIHtcbiAgLyoqXG4gICAqIFBhdGNoIFRPQyBsaXN0LlxuICAgKlxuICAgKiBXaWxsIG11dGF0ZSB0aGUgdW5kZXJseWluZyBzcGFuIHRvIGhhdmUgYSBjb3JyZWN0IHVsIGZvciBuYXYuXG4gICAqXG4gICAqIEBwYXJhbSAkc3BhbjogU3BhbiBjb250YWluaW5nIG5lc3RlZCBVTCdzIHRvIG11dGF0ZS5cbiAgICogQHBhcmFtIG1pbkxldmVsOiBTdGFydGluZyBsZXZlbCBmb3IgbmVzdGVkIGxpc3RzLiAoMTogZ2xvYmFsLCAyOiBsb2NhbCkuXG4gICAqL1xuICB2YXIgcGF0Y2hUb2MgPSBmdW5jdGlvbiAoJHVsLCBtaW5MZXZlbCkge1xuICAgIHZhciBmaW5kQSxcbiAgICAgIHBhdGNoVGFibGVzLFxuICAgICAgJGxvY2FsTGk7XG5cbiAgICAvLyBGaW5kIGFsbCBhIFwiaW50ZXJuYWxcIiB0YWdzLCB0cmF2ZXJzaW5nIHJlY3Vyc2l2ZWx5LlxuICAgIGZpbmRBID0gZnVuY3Rpb24gKCRlbGVtLCBsZXZlbCkge1xuICAgICAgbGV2ZWwgPSBsZXZlbCB8fCAwO1xuICAgICAgdmFyICRpdGVtcyA9ICRlbGVtLmZpbmQoXCI+IGxpID4gYS5pbnRlcm5hbCwgPiB1bCwgPiBsaSA+IHVsXCIpO1xuXG4gICAgICAvLyBJdGVyYXRlIGV2ZXJ5dGhpbmcgaW4gb3JkZXIuXG4gICAgICAkaXRlbXMuZWFjaChmdW5jdGlvbiAoaW5kZXgsIGl0ZW0pIHtcbiAgICAgICAgdmFyICRpdGVtID0gJChpdGVtKSxcbiAgICAgICAgICB0YWcgPSBpdGVtLnRhZ05hbWUudG9Mb3dlckNhc2UoKSxcbiAgICAgICAgICAkY2hpbGRyZW5MaSA9ICRpdGVtLmNoaWxkcmVuKCdsaScpLFxuICAgICAgICAgICRwYXJlbnRMaSA9ICQoJGl0ZW0ucGFyZW50KCdsaScpLCAkaXRlbS5wYXJlbnQoKS5wYXJlbnQoJ2xpJykpO1xuXG4gICAgICAgIC8vIEFkZCBkcm9wZG93bnMgaWYgbW9yZSBjaGlsZHJlbiBhbmQgYWJvdmUgbWluaW11bSBsZXZlbC5cbiAgICAgICAgaWYgKHRhZyA9PT0gJ3VsJyAmJiBsZXZlbCA+PSBtaW5MZXZlbCAmJiAkY2hpbGRyZW5MaS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgJHBhcmVudExpXG4gICAgICAgICAgICAuYWRkQ2xhc3MoJ2Ryb3Bkb3duLXN1Ym1lbnUnKVxuICAgICAgICAgICAgLmNoaWxkcmVuKCdhJykuZmlyc3QoKS5hdHRyKCd0YWJpbmRleCcsIC0xKTtcblxuICAgICAgICAgICRpdGVtLmFkZENsYXNzKCdkcm9wZG93bi1tZW51Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBmaW5kQSgkaXRlbSwgbGV2ZWwgKyAxKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBmaW5kQSgkdWwpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBQYXRjaCBhbGwgdGFibGVzIHRvIHJlbW92ZSBgYGRvY3V0aWxzYGAgY2xhc3MgYW5kIGFkZCBCb290c3RyYXAgYmFzZVxuICAgKiBgYHRhYmxlYGAgY2xhc3MuXG4gICAqL1xuICBwYXRjaFRhYmxlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAkKFwidGFibGUuZG9jdXRpbHNcIilcbiAgICAgIC5yZW1vdmVDbGFzcyhcImRvY3V0aWxzXCIpXG4gICAgICAuYWRkQ2xhc3MoXCJ0YWJsZVwiKVxuICAgICAgLmF0dHIoXCJib3JkZXJcIiwgMCk7XG4gIH07XG5cbiQoZnVuY3Rpb24gKCkge1xuXG4gICAgLypcbiAgICAgKiBTY3JvbGwgdGhlIHdpbmRvdyB0byBhdm9pZCB0aGUgdG9wbmF2IGJhclxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS90d2l0dGVyL2Jvb3RzdHJhcC9pc3N1ZXMvMTc2OFxuICAgICAqL1xuICAgIGlmICgkKFwiI25hdmJhci5uYXZiYXItZml4ZWQtdG9wXCIpLmxlbmd0aCA+IDApIHtcbiAgICAgIHZhciBuYXZIZWlnaHQgPSAkKFwiI25hdmJhclwiKS5oZWlnaHQoKSxcbiAgICAgICAgc2hpZnRXaW5kb3cgPSBmdW5jdGlvbigpIHsgc2Nyb2xsQnkoMCwgLW5hdkhlaWdodCAtIDEwKTsgfTtcblxuICAgICAgaWYgKGxvY2F0aW9uLmhhc2gpIHtcbiAgICAgICAgc2hpZnRXaW5kb3coKTtcbiAgICAgIH1cblxuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJoYXNoY2hhbmdlXCIsIHNoaWZ0V2luZG93KTtcbiAgICB9XG5cbiAgICAvLyBBZGQgc3R5bGluZywgc3RydWN0dXJlIHRvIFRPQydzLlxuICAgICQoXCIuZHJvcGRvd24tbWVudVwiKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICQodGhpcykuZmluZChcInVsXCIpLmVhY2goZnVuY3Rpb24gKGluZGV4LCBpdGVtKXtcbiAgICAgICAgdmFyICRpdGVtID0gJChpdGVtKTtcbiAgICAgICAgJGl0ZW0uYWRkQ2xhc3MoJ3Vuc3R5bGVkJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIEdsb2JhbCBUT0MuXG4gICAgaWYgKCQoXCJ1bC5nbG9iYWx0b2MgbGlcIikubGVuZ3RoKSB7XG4gICAgICBwYXRjaFRvYygkKFwidWwuZ2xvYmFsdG9jXCIpLCAxKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmVtb3ZlIEdsb2JhbCBUT0MuXG4gICAgICAkKFwiLmdsb2JhbHRvYy1jb250YWluZXJcIikucmVtb3ZlKCk7XG4gICAgfVxuXG4gICAgLy8gTG9jYWwgVE9DLlxuICAgIHBhdGNoVG9jKCQoXCJ1bC5sb2NhbHRvY1wiKSwgMik7XG5cbiAgICAvLyBNdXRhdGUgc3ViLWxpc3RzIChmb3IgYnMtMi4zLjApLlxuICAgICQoXCIuZHJvcGRvd24tbWVudSB1bFwiKS5ub3QoXCIuZHJvcGRvd24tbWVudVwiKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdWwgPSAkKHRoaXMpLFxuICAgICAgICAkcGFyZW50ID0gJHVsLnBhcmVudCgpLFxuICAgICAgICB0YWcgPSAkcGFyZW50WzBdLnRhZ05hbWUudG9Mb3dlckNhc2UoKSxcbiAgICAgICAgJGtpZHMgPSAkdWwuY2hpbGRyZW4oKS5kZXRhY2goKTtcblxuICAgICAgLy8gUmVwbGFjZSBsaXN0IHdpdGggaXRlbXMgaWYgc3VibWVudSBoZWFkZXIuXG4gICAgICBpZiAodGFnID09PSBcInVsXCIpIHtcbiAgICAgICAgJHVsLnJlcGxhY2VXaXRoKCRraWRzKTtcbiAgICAgIH0gZWxzZSBpZiAodGFnID09PSBcImxpXCIpIHtcbiAgICAgICAgLy8gSW5zZXJ0IGludG8gcHJldmlvdXMgbGlzdC5cbiAgICAgICAgJHBhcmVudC5hZnRlcigka2lkcyk7XG4gICAgICAgICR1bC5yZW1vdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIEFkZCBkaXZpZGVyIGluIHBhZ2UgVE9DLlxuICAgICRsb2NhbExpID0gJChcInVsLmxvY2FsdG9jIGxpXCIpO1xuICAgIGlmICgkbG9jYWxMaS5sZW5ndGggPiAyKSB7XG4gICAgICAkbG9jYWxMaS5maXJzdCgpLmFmdGVyKCc8bGkgY2xhc3M9XCJkaXZpZGVyXCI+PC9saT4nKTtcbiAgICB9XG5cbiAgICAvLyBFbmFibGUgZHJvcGRvd24uXG4gICAgJCgnLmRyb3Bkb3duLXRvZ2dsZScpLmRyb3Bkb3duKCk7XG5cbiAgICAvLyBQYXRjaCB0YWJsZXMuXG4gICAgcGF0Y2hUYWJsZXMoKTtcblxuICAgIC8vIEFkZCBOb3RlLCBXYXJuaW5nIHN0eWxlcy5cbiAgICAkKCdkaXYubm90ZScpLmFkZENsYXNzKCdhbGVydCcpLmFkZENsYXNzKCdhbGVydC1pbmZvJyk7XG4gICAgJCgnZGl2Lndhcm5pbmcnKS5hZGRDbGFzcygnYWxlcnQnKS5hZGRDbGFzcygnYWxlcnQtd2FybmluZycpO1xuXG4gICAgLy8gSW5saW5lIGNvZGUgc3R5bGVzIHRvIEJvb3RzdHJhcCBzdHlsZS5cbiAgICAkKCd0dC5kb2N1dGlscy5saXRlcmFsJykubm90KFwiLnhyZWZcIikuZWFjaChmdW5jdGlvbiAoaSwgZSkge1xuICAgICAgLy8gaWdub3JlIHJlZmVyZW5jZXNcbiAgICAgIGlmICghJChlKS5wYXJlbnQoKS5oYXNDbGFzcyhcInJlZmVyZW5jZVwiKSkge1xuICAgICAgICAkKGUpLnJlcGxhY2VXaXRoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gJChcIjxjb2RlIC8+XCIpLnRleHQoJCh0aGlzKS50ZXh0KCkpO1xuICAgICAgICB9KTtcbiAgICAgIH19KTtcbiAgfSk7XG59KHdpbmRvdy5qUXVlcnkpKTtcbiIsIi8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4vLyB8ZG9jbmFtZXwgLSBBIGZyYW1ld29yayBhbGxvd2luZyBhIFJ1bmVzdG9uZSBjb21wb25lbnQgdG8gbG9hZCBvbmx5IHRoZSBKUyBpdCBuZWVkc1xuLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbi8vIFRoZSBKYXZhU2NyaXB0IHJlcXVpcmVkIGJ5IGFsbCBSdW5lc3RvbmUgY29tcG9uZW50cyBpcyBxdWl0ZSBsYXJnZSBhbmQgcmVzdWx0cyBpbiBzbG93IHBhZ2UgbG9hZHMuIFRoaXMgYXBwcm9hY2ggZW5hYmxlcyBhIFJ1bmVzdG9uZSBjb21wb25lbnQgdG8gbG9hZCBvbmx5IHRoZSBKYXZhU2NyaXB0IGl0IG5lZWRzLCByYXRoZXIgdGhhbiBsb2FkaW5nIEphdmFTY3JpcHQgZm9yIGFsbCB0aGUgY29tcG9uZW50cyByZWdhcmRsZXNzIG9mIHdoaWNoIGFyZSBhY3R1YWxseSB1c2VkLlxuLy9cbi8vIFRvIGFjY29tcGxpc2ggdGhpcywgd2VicGFjaydzIHNwbGl0LWNodW5rcyBhYmlsaXR5IGFuYWx5emVzIGFsbCBKUywgc3RhcnRpbmcgZnJvbSB0aGlzIGZpbGUuIFRoZSBkeW5hbWljIGltcG9ydHMgYmVsb3cgYXJlIHRyYW5zZm9ybWVkIGJ5IHdlYnBhY2sgaW50byB0aGUgZHluYW1pYyBmZXRjaGVzIG9mIGp1c3QgdGhlIE
4060pTIHJlcXVpcmVkIGJ5IGVhY2ggZmlsZSBhbmQgYWxsIGl0cyBkZXBlbmRlbmNpZXMuIChJZiB1c2luZyBzdGF0aWMgaW1wb3J0cywgd2VicGFjayB3aWxsIGFzc3VtZSB0aGF0IGFsbCBmaWxlcyBhcmUgYWxyZWFkeSBzdGF0aWNhbGx5IGxvYWRlZCB2aWEgc2NyaXB0IHRhZ3MsIGRlZmVhdGluZyB0aGUgcHVycG9zZSBvZiB0aGlzIGZyYW1ld29yay4pXG4vL1xuLy8gSG93ZXZlciwgdGhpcyBhcHByb2FjaCBsZWFkcyB0byBjb21wbGV4aXR5OlxuLy9cbi8vIC0gICAgVGhlIGBgZGF0YS1jb21wb25lbnRgYCBhdHRyaWJ1dGUgb2YgZWFjaCBjb21wb25lbnQgbXVzdCBiZSBrZXB0IGluIHN5bmMgd2l0aCB0aGUga2V5cyBvZiB0aGUgYGBtb2R1bGVfbWFwYGAgYmVsb3cuXG4vLyAtICAgIFRoZSB2YWx1ZXMgaW4gdGhlIGBgbW9kdWxlX21hcGBgIG11c3QgYmUga2VwdCBpbiBzeW5jIHdpdGggdGhlIEphdmFTY3JpcHQgZmlsZXMgd2hpY2ggaW1wbGVtZW50IGVhY2ggb2YgdGhlIGNvbXBvbmVudHMuXG5cblwidXNlIHN0cmljdFwiO1xuXG4vLyBTdGF0aWMgaW1wb3J0c1xuLy8gPT09PT09PT09PT09PT1cbi8vIFRoZXNlIGltcG9ydHMgYXJlICh3ZSBhc3N1bWUpIG5lZWRlZCBieSBhbGwgcGFnZXMuIEhvd2V2ZXIsIGl0IHdvdWxkIGJlIG11Y2ggYmV0dGVyIHRvIGxvYWQgdGhlc2UgaW4gdGhlIG1vZHVsZXMgdGhhdCBhY3R1YWxseSB1c2UgdGhlbS5cbi8vXG4vLyBUaGVzZSBhcmUgc3RhdGljIGltcG9ydHM7IGNvZGUgaW4gYGR5bmFtaWNhbGx5IGxvYWRlZCBjb21wb25lbnRzYF8gZGVhbHMgd2l0aCBkeW5hbWljIGltcG9ydHMuXG4vL1xuLy8galF1ZXJ5LXJlbGF0ZWQgaW1wb3J0cy5cbmltcG9ydCBcImpxdWVyeS11aS9qcXVlcnktdWkuanNcIjtcbmltcG9ydCBcImpxdWVyeS11aS90aGVtZXMvYmFzZS9qcXVlcnkudWkuYWxsLmNzc1wiO1xuaW1wb3J0IFwiLi9ydW5lc3RvbmUvY29tbW9uL2pzL2pxdWVyeS5pZGxlLXRpbWVyLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4uanNcIjtcbmltcG9ydCBcIi4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5lbWl0dGVyLmJpZGkuanNcIjtcbmltcG9ydCBcIi4vcnVuZXN0b25lL2NvbW1vbi9qcy9qcXVlcnlfaTE4bi9qcXVlcnkuaTE4bi5lbWl0dGVyLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4uZmFsbGJhY2tzLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4ubWVzc2FnZXN0b3JlLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4ucGFyc2VyLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvanF1ZXJ5X2kxOG4vanF1ZXJ5LmkxOG4ubGFuZ3VhZ2UuanNcIjtcblxuLy8gQm9vdHN0cmFwXG5pbXBvcnQgXCJib290c3RyYXAvZGlzdC9qcy9ib290c3RyYXAuanNcIjtcbmltcG9ydCBcImJvb3RzdHJhcC9kaXN0L2Nzcy9ib290c3RyYXAuY3NzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vcHJvamVjdF90ZW1wbGF0ZS9fdGVtcGxhdGVzL3BsdWdpbl9sYXlvdXRzL3NwaGlueF9ib290c3RyYXAvc3RhdGljL2Jvb3RzdHJhcC1zcGhpbnguanNcIjtcbmltcG9ydCBcIi4vcnVuZXN0b25lL2NvbW1vbi9jc3MvcnVuZXN0b25lLWN1c3RvbS1zcGhpbngtYm9vdHN0cmFwLmNzc1wiO1xuXG4vLyBNaXNjXG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvYm9va2Z1bmNzLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvdXNlci1oaWdobGlnaHRzLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvcHJldGV4dC5qc1wiO1xuXG4vLyBUaGVzZSBiZWxvbmcgaW4gZHluYW1pYyBpbXBvcnRzIGZvciB0aGUgb2J2aW91cyBjb21wb25lbnQ7IGhvd2V2ZXIsIHRoZXNlIGNvbXBvbmVudHMgZG9uJ3QgaW5jbHVkZSBhIGBgZGF0YS1jb21wb25lbnRgYCBhdHRyaWJ1dGUuXG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9tYXRyaXhlcS9jc3MvbWF0cml4ZXEuY3NzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS93ZWJnbGRlbW8vY3NzL3dlYmdsaW50ZXJhY3RpdmUuY3NzXCI7XG5cbi8vIFRoZXNlIGFyZSBvbmx5IG5lZWRlZCBmb3IgdGhlIFJ1bmVzdG9uZSBib29rLCBidXQgbm90IGluIGEgbGlicmFyeSBtb2RlIChzdWNoIGFzIHByZXRleHQpLiBJIHdvdWxkIHByZWZlciB0byBkeW5hbWljYWxseSBsb2FkIHRoZW0uIEhvd2V2ZXIsIHRoZXNlIHNjcmlwdHMgYXJlIHNvIHNtYWxsIEkgaGF2ZW4ndCBib3RoZXJlZCB0byBkbyBzby5cbmltcG9ydCB7IGdldFN3aXRjaCwgc3dpdGNoVGhlbWUgfSBmcm9tIFwiLi9ydW5lc3RvbmUvY29tbW9uL2pzL3RoZW1lLmpzXCI7XG5pbXBvcnQgXCIuL3J1bmVzdG9uZS9jb21tb24vanMvcHJlc2VudGVyX21vZGUuanNcIjtcbmltcG9ydCBcIi4vcnVuZXN0b25lL2NvbW1vbi9jc3MvcHJlc2VudGVyX21vZGUuY3NzXCI7XG5cbi8vIER5bmFtaWNhbGx5IGxvYWRlZCBjb21wb25lbnRzXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gVGhpcyBwcm92aWRlcyBhIGxpc3Qgb2YgbW9kdWxlcyB0aGF0IGNvbXBvbmVudHMgY2FuIGR5bmFtaWNhbGx5IGltcG9ydC4gV2VicGFjayB3aWxsIGNyZWF0ZSBhIGxpc3Qgb2YgaW1wb3J0cyBmb3IgZWFjaCBiYXNlZCBvbiBpdHMgYW5hbHlzaXMuXG5jb25zdCBtb2R1bGVfbWFwID0ge1xuICAgIC8vIFdyYXAgZWFjaCBpbXBvcnQgaW4gYSBmdW5jdGlvbiwgc28gdGhhdCBpdCB3b24ndCBvY2N1ciB1bnRpbCB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkLiBXaGlsZSBzb21ldGhpbmcgY2xlYW5lciB3b3VsZCBiZSBuaWNlLCB3ZWJwYWNrIGNhbid0IGFuYWx5emUgdGhpbmdzIGxpa2UgYGBpbXBvcnQoZXhwcmVzc2lvbilgYC5cbiAgICAvL1xuICAgIC8vIFRoZSBrZXlzIG11c3QgbWF0Y2ggdGhlIHZhbHVlIG9mIGVhY2ggY29tcG9uZW50J3MgYGBkYXRhLWNvbXBvbmVudGBgIGF0dHJpYnV0ZSAtLSB0aGUgYGBydW5lc3RvbmVfaW1wb3J0YGAgYW5kIGBgcnVuZXN0b25lX2F1dG9faW1wb3J0YGAgZnVuY3Rpb25zIGFzc3VtZSB0aGlzLlxuICAgIGFjdGl2ZWNvZGU6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL2FjdGl2ZWNvZGUvanMvYWNmYWN0b3J5LmpzXCIpLFxuICAgIGJsZTogKCkgPT4gaW1wb3J0KFwiLi9ydW5lc3RvbmUvY2VsbGJvdGljcy9qcy9ibGUuanNcIiksXG4gICAgLy8gQWx3YXlzIGltcG9ydCB0aGUgdGltZWQgdmVyc2lvbiBvZiBhIGNvbXBvbmVudCBpZiBhdmFpbGFibGUsIHNpbmNlIHRoZSB0aW1lZCBjb21wb25lbnRzIGFsc28gZGVmaW5lIHRoZSBjb21wb25lbnQncyBmYWN0b3J5IGFuZCBpbmNsdWRlIHRoZSBjb21wb25lbnQgYXMgd2VsbC4gTm90ZSB0aGF0IGBgYWNmYWN0b3J5YGAgaW1wb3J0cyB0aGUgdGltZWQgY29tcG9uZW50cyBvZiBBY3RpdmVDb2RlLCBzbyBpdCBmb2xsb3dzIHRoaXMgcGF0dGVybi5cbiAgICBjbGlja2FibGVhcmVhOiAoKSA9PlxuICAgICAgICBpbXBvcnQoXCIuL3J1bmVzdG9uZS9jbGlja2FibGVBcmVhL2pzL3RpbWVkY2xpY2thYmxlLmpzXCIpLFxuICAgIGNvZGVsZW5zOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9jb2RlbGVucy9qcy9jb2RlbGVucy5qc1wiKSxcbiAgICBkYXRhZmlsZTogKCkgPT4gaW1wb3J0KFwiLi9ydW5lc3RvbmUvZGF0YWZpbGUvanMvZGF0YWZpbGUuanNcIiksXG4gICAgZHJhZ25kcm9wOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9kcmFnbmRyb3AvanMvdGltZWRkbmQuanNcIiksXG4gICAgZmlsbGludGhlYmxhbms6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL2ZpdGIvanMvdGltZWRmaXRiLmpzXCIpLFxuICAgIGdyb3Vwc3ViOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9ncm91cHN1Yi9qcy9ncm91cHN1Yi5qc1wiKSxcbiAgICBraGFuZXg6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL2toYW5leC9qcy9raGFuZXguanNcIiksXG4gICAgbHBfYnVpbGQ6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL2xwL2pzL2xwLmpzXCIpLFxuICAgIG11bHRpcGxlY2hvaWNlOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9tY2hvaWNlL2pzL3RpbWVkbWMuanNcIiksXG4gICAgaHBhcnNvbnM6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL2hwYXJzb25zL2pzL2hwYXJzb25zLmpzXCIpLFxuICAgIHBhcnNvbnM6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL3BhcnNvbnMvanMvdGltZWRwYXJzb25zLmpzXCIpLFxuICAgIHBvbGw6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL3BvbGwvanMvcG9sbC5qc1wiKSxcbiAgICBxdWl6bHk6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL3F1aXpseS9qcy9xdWl6bHkuanNcIiksXG4gICAgcmV2ZWFsOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9yZXZlYWwvanMvcmV2ZWFsLmpzXCIpLFxuICAgIHNlbGVjdHF1ZXN0aW9uOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9zZWxlY3RxdWVzdGlvbi9qcy9zZWxlY3RvbmUuanNcIiksXG4gICAgc2hvcnRhbnN3ZXI6ICgpID0+XG4gICAgICAgIGltcG9ydChcIi4vcnVuZXN0b25lL3Nob3J0YW5zd2VyL2pzL3RpbWVkX3Nob3J0YW5zd2VyLmpzXCIpLFxuICAgIHNob3dldmFsOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9zaG93ZXZhbC9qcy9zaG93RXZhbC5qc1wiKSxcbiAgICBzaW1wbGVf
4060c2Vuc29yOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS9jZWxsYm90aWNzL2pzL3NpbXBsZV9zZW5zb3IuanNcIiksXG4gICAgc3ByZWFkc2hlZXQ6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL3NwcmVhZHNoZWV0L2pzL3NwcmVhZHNoZWV0LmpzXCIpLFxuICAgIHRhYmJlZFN0dWZmOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS90YWJiZWRTdHVmZi9qcy90YWJiZWRzdHVmZi5qc1wiKSxcbiAgICB0aW1lZEFzc2Vzc21lbnQ6ICgpID0+IGltcG9ydChcIi4vcnVuZXN0b25lL3RpbWVkL2pzL3RpbWVkLmpzXCIpLFxuICAgIHdhdmVkcm9tOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS93YXZlZHJvbS9qcy93YXZlZHJvbS5qc1wiKSxcbiAgICAvLyBUT0RPOiBzaW5jZSB0aGlzIGlzbid0IGluIGEgYGBkYXRhLWNvbXBvbmVudGBgLCBuZWVkIHRvIHRyaWdnZXIgYW4gaW1wb3J0IG9mIHRoaXMgY29kZSBtYW51YWxseS5cbiAgICB3ZWJ3b3JrOiAoKSA9PiBpbXBvcnQoXCIuL3J1bmVzdG9uZS93ZWJ3b3JrL2pzL3dlYndvcmsuanNcIiksXG4gICAgeW91dHViZTogKCkgPT4gaW1wb3J0KFwiLi9ydW5lc3RvbmUvdmlkZW8vanMvcnVuZXN0b25ldmlkZW8uanNcIiksXG59O1xuXG4vLyAuLiBfZHluYW1pYyBpbXBvcnQgbWFjaGluZXJ5OlxuLy9cbi8vIER5bmFtaWMgaW1wb3J0IG1hY2hpbmVyeVxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBGdWxmaWxsIGEgcHJvbWlzZSB3aGVuIHRoZSBSdW5lc3RvbmUgcHJlLWxvZ2luIGNvbXBsZXRlIGV2ZW50IG9jY3Vycy5cbmxldCBwcmVfbG9naW5fY29tcGxldGVfcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PlxuICAgICQoZG9jdW1lbnQpLm9uKFwicnVuZXN0b25lOnByZS1sb2dpbi1jb21wbGV0ZVwiLCByZXNvbHZlKVxuKTtcbmxldCBsb2FkZWRDb21wb25lbnRzO1xuLy8gUHJvdmlkZSBhIHNpbXBsZSBmdW5jdGlvbiB0byBpbXBvcnQgdGhlIEpTIGZvciBhbGwgY29tcG9uZW50cyBvbiB0aGUgcGFnZS5cbmV4cG9ydCBmdW5jdGlvbiBydW5lc3RvbmVfYXV0b19pbXBvcnQoKSB7XG4gICAgLy8gQ3JlYXRlIGEgc2V0IG9mIGBgZGF0YS1jb21wb25lbnRgYCB2YWx1ZXMsIHRvIGF2b2lkIGR1cGxpY2F0aW9uLlxuICAgIGNvbnN0IHMgPSBuZXcgU2V0KFxuICAgICAgICAvLyBBbGwgUnVuZXN0b25lIGNvbXBvbmVudHMgaGF2ZSBhIGBgZGF0YS1jb21wb25lbnRgYCBhdHRyaWJ1dGUuXG4gICAgICAgICQoXCJbZGF0YS1jb21wb25lbnRdXCIpXG4gICAgICAgICAgICAubWFwKFxuICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgdGhlIHZhbHVlIG9mIHRoZSBkYXRhLWNvbXBvbmVudCBhdHRyaWJ1dGUuXG4gICAgICAgICAgICAgICAgKGluZGV4LCBlbGVtZW50KSA9PiAkKGVsZW1lbnQpLmF0dHIoXCJkYXRhLWNvbXBvbmVudFwiKVxuICAgICAgICAgICAgICAgIC8vIFN3aXRjaCBmcm9tIGEgalF1ZXJ5IG9iamVjdCBiYWNrIHRvIGFuIGFycmF5LCBwYXNzaW5nIHRoYXQgdG8gdGhlIFNldCBjb25zdHJ1Y3Rvci5cbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5nZXQoKVxuICAgICk7XG4gICAgLy8gd2Vid29yayBxdWVzdGlvbnMgYXJlIG5vdCB3cmFwcGVkIGluIGRpdiB3aXRoIGEgZGF0YS1jb21wb25lbnQgc28gd2UgaGF2ZSB0byBjaGVjayBhIGRpZmZlcmVudCB3YXlcbiAgICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIi53ZWJ3b3JrLWJ1dHRvblwiKSkge1xuICAgICAgICBzLmFkZChcIndlYndvcmtcIik7XG4gICAgfVxuXG4gICAgLy8gTG9hZCBKUyBmb3IgZWFjaCBvZiB0aGUgY29tcG9uZW50cyBmb3VuZC5cbiAgICBjb25zdCBhID0gWy4uLnNdLm1hcCgodmFsdWUpID0+XG4gICAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gSlMgZm9yIHRoaXMgY29tcG9uZW50LCByZXR1cm4gYW4gZW1wdHkgUHJvbWlzZS5cbiAgICAgICAgKG1vZHVsZV9tYXBbdmFsdWVdIHx8ICgoKSA9PiBQcm9taXNlLnJlc29sdmUoKSkpKClcbiAgICApO1xuXG4gICAgLy8gU2VuZCB0aGUgUnVuZXN0b25lIGxvZ2luIGNvbXBsZXRlIGV2ZW50IHdoZW4gYWxsIEpTIGlzIGxvYWRlZCBhbmQgdGhlIHByZS1sb2dpbiBpcyBhbHNvIGNvbXBsZXRlLlxuICAgIFByb21pc2UuYWxsKFtwcmVfbG9naW5fY29tcGxldGVfcHJvbWlzZSwgLi4uYV0pLnRoZW4oKCkgPT5cbiAgICAgICAgJChkb2N1bWVudCkudHJpZ2dlcihcInJ1bmVzdG9uZTpsb2dpbi1jb21wbGV0ZVwiKVxuICAgICk7XG59XG5cbi8vIExvYWQgY29tcG9uZW50IEpTIHdoZW4gdGhlIGRvY3VtZW50IGlzIHJlYWR5LlxuJChkb2N1bWVudCkucmVhZHkocnVuZXN0b25lX2F1dG9faW1wb3J0KTtcblxuLy8gUHJvdmlkZSBhIGZ1bmN0aW9uIHRvIGltcG9ydCBvbmUgc3BlY2lmaWMgUnVuZXN0b25lIGNvbXBvbmVudC5cbi8vIHRoZSBpbXBvcnQgZnVuY3Rpb24gaW5zaWRlIG1vZHVsZV9tYXAgaXMgYXN5bmMgLS0gcnVuZXN0b25lX2ltcG9ydFxuLy8gc2hvdWxkIGJlIGF3YWl0ZWQgd2hlbiBuZWNlc3NhcnkgdG8gZW5zdXJlIHRoZSBpbXBvcnQgY29tcGxldGVzXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuZXN0b25lX2ltcG9ydChjb21wb25lbnRfbmFtZSkge1xuICAgIHJldHVybiBtb2R1bGVfbWFwW2NvbXBvbmVudF9uYW1lXSgpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBwb3B1cFNjcmF0Y2hBQygpIHtcbiAgICAvLyBsb2FkIHRoZSBhY3RpdmVjb2RlIGJ1bmRsZVxuICAgIGF3YWl0IHJ1bmVzdG9uZV9pbXBvcnQoXCJhY3RpdmVjb2RlXCIpO1xuICAgIC8vIHNjcmF0Y2hEaXYgd2lsbCBiZSBkZWZpbmVkIGlmIHdlIGhhdmUgYWxyZWFkeSBjcmVhdGVkIGEgc2NyYXRjaFxuICAgIC8vIGFjdGl2ZWNvZGUuICBJZiBpdHMgbm90IGRlZmluZWQgdGhlbiB3ZSBuZWVkIHRvIGdldCBpdCByZWFkeSB0byB0b2dnbGVcbiAgICBpZiAoIWVCb29rQ29uZmlnLnNjcmF0Y2hEaXYpIHtcbiAgICAgICAgd2luZG93LkFDRmFjdG9yeS5jcmVhdGVTY3JhdGNoQWN0aXZlY29kZSgpO1xuICAgICAgICBsZXQgZGl2aWQgPSBlQm9va0NvbmZpZy5zY3JhdGNoRGl2O1xuICAgICAgICB3aW5kb3cuZWRMaXN0W2RpdmlkXSA9IEFDRmFjdG9yeS5jcmVhdGVBY3RpdmVDb2RlKFxuICAgICAgICAgICAgJChgIyR7ZGl2aWR9YClbMF0sXG4gICAgICAgICAgICBlQm9va0NvbmZpZy5hY0RlZmF1bHRMYW5ndWFnZVxuICAgICAgICApO1xuICAgICAgICBpZiAoZUJvb2tDb25maWcuaXNMb2dnZWRJbikge1xuICAgICAgICAgICAgd2luZG93LmVkTGlzdFtkaXZpZF0uZW5hYmxlU2F2ZUxvYWQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB3aW5kb3cuQUNGYWN0b3J5LnRvZ2dsZVNjcmF0Y2hBY3RpdmVjb2RlKCk7XG59XG5cbi8vIFNldCB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgdGhpcyBzY3JpcHQgYXMgdGhlIGBwYXRoIDxodHRwczovL3dlYnBhY2suanMub3JnL2d1aWRlcy9wdWJsaWMtcGF0aC8jb24tdGhlLWZseT5gXyBmb3IgYWxsIHdlYnBhY2tlZCBzY3JpcHRzLlxuY29uc3Qgc2NyaXB0X3NyYyA9IGRvY3VtZW50LmN1cnJlbnRTY3JpcHQuc3JjO1xuX193ZWJwYWNrX3B1YmxpY19wYXRoX18gPSBzY3JpcHRfc3JjLnN1YnN0cmluZyhcbiAgICAwLFxuICAgIHNjcmlwdF9zcmMubGFzdEluZGV4T2YoXCIvXCIpICsgMVxuKTtcblxuLy8gTWFudWFsIGV4cG9ydHNcbi8vID09PT09PT09PT09PT09XG4vLyBXZWJwYWNrJ3MgYGBvdXRwdXQubGlicmFyeWBgIHNldHRpbmcgZG9lc24ndCBzZWVtIHRvIHdvcmsgd2l0aCB0aGUgc3BsaXQgY2h1bmtzIHBsdWdpbjsgZG8gYWxsIGV4cG9ydHMgbWFudWFsbHkgdGhyb3VnaCB0aGUgYGB3aW5kb3dgYCBvYmplY3QgaW5zdGVhZC5cbmNvbnN0IHJjID0ge307XG5yYy5ydW5lc3RvbmVfaW1wb3J0ID0gcnVuZXN0b25lX2ltcG9ydDtcbnJjLnJ1bmVzdG9uZV9hdXRvX2ltcG9ydCA9IHJ1bmVzdG9uZV9hdXRvX2ltcG9ydDtcbnJjLmdldFN3aXRjaCA9IGdldFN3aXRjaDtcbnJjLnN3aXRjaFRoZW1lID0gc3dpdGNoVGhlbWU7XG5yYy5wb3B1cFNjcmF0Y2hBQyA9IHBvcHVwU2NyYXRjaEFDO1xud2luZG93LnJ1bmVzdG9uZUNvbXBvbmVudHMgPSByYztcbiIsIm1vZHVsZS5leHBvcnRzID0galF1ZXJ5OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==

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.