rubyfox-server 2.17.3.1 → 2.19.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rubyfox/server/data/config/admin/descriptors/config_room.txt +10 -1
- data/lib/rubyfox/server/data/config/admin/descriptors/config_server.txt +90 -20
- data/lib/rubyfox/server/data/config/admin/descriptors/config_zone.txt +9 -0
- data/lib/rubyfox/server/data/config/admin/descriptors/runtime_room.txt +11 -0
- data/lib/rubyfox/server/data/config/admin/descriptors/runtime_user.txt +3 -3
- data/lib/rubyfox/server/data/config/core.xml +4 -4
- data/lib/rubyfox/server/data/config/default.words.txt +11 -0
- data/lib/rubyfox/server/data/config/log4j.properties +1 -2
- data/lib/rubyfox/server/data/config/server.xml +1 -1
- data/lib/rubyfox/server/data/data/GeoLite2-Country.mmdb +0 -0
- data/lib/rubyfox/server/data/data/bannedusers/users.bin +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/bootstrap.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/catalina-tasks.xml +39 -39
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/catalina.sh +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/ciphers.sh +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/commons-daemon-native.tar.gz +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/commons-daemon.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/configtest.sh +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/daemon.sh +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/digest.sh +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/makebase.sh +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/setclasspath.sh +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/shutdown.sh +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/startup.sh +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/tomcat-juli.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/tomcat-native.tar.gz +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/tool-wrapper.sh +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/bin/version.sh +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/conf/Catalina/localhost/rewrite.config +1 -1
- data/lib/rubyfox/server/data/lib/apache-tomcat/conf/catalina.policy +263 -264
- data/lib/rubyfox/server/data/lib/apache-tomcat/conf/catalina.properties +209 -207
- data/lib/rubyfox/server/data/lib/apache-tomcat/conf/context.xml +31 -31
- data/lib/rubyfox/server/data/lib/apache-tomcat/conf/jaspic-providers.xml +23 -23
- data/lib/rubyfox/server/data/lib/apache-tomcat/conf/jaspic-providers.xsd +52 -52
- data/lib/rubyfox/server/data/lib/apache-tomcat/conf/keystore.jks +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/conf/server.xml +177 -161
- data/lib/rubyfox/server/data/lib/apache-tomcat/conf/tomcat-users.xml +18 -7
- data/lib/rubyfox/server/data/lib/apache-tomcat/conf/tomcat-users.xsd +59 -59
- data/lib/rubyfox/server/data/lib/apache-tomcat/conf/web.xml +4740 -4737
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/annotations-api.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-ant.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-ha.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-ssi.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-storeconfig.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-tribes.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/el-api.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jasper-el.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jasper.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jaspic-api.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jsp-api.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/servlet-api.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/sfs2x-ws-helper.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-api.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-coyote.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-dbcp.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-cs.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-de.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-es.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-fr.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-ja.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-ko.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-pt-BR.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-ru.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-zh-CN.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-jdbc.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-jni.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-util-scan.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-util.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-websocket.jar +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/lib/websocket-api.jar +0 -0
- data/lib/rubyfox/server/data/lib/javax.activation-1.2.0.jar +0 -0
- data/lib/rubyfox/server/data/lib/javax.mail.jar +0 -0
- data/lib/rubyfox/server/data/lib/js/JSApi.js +2 -1
- data/lib/rubyfox/server/data/lib/js/LibApi.js +181 -48
- data/lib/rubyfox/server/data/lib/sfs2x-admin.jar +0 -0
- data/lib/rubyfox/server/data/lib/sfs2x-cluster.jar +0 -0
- data/lib/rubyfox/server/data/lib/sfs2x-core.jar +0 -0
- data/lib/rubyfox/server/data/lib/sfs2x.jar +0 -0
- data/lib/rubyfox/server/data/sfs2x-service +26 -30
- data/lib/rubyfox/server/data/www/BlueBox.war +0 -0
- data/lib/rubyfox/server/data/www/HelloServlet/WEB-INF/web.xml +1 -3
- data/lib/rubyfox/server/data/www/ROOT/_css_/default.css +14 -6
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/style.css +44 -2
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/application.bundle.js +98 -61
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/endors~mod-0~mod-1~mod-11~mod-12~mod-17~mod-6~mod-7~mod-8~mod-9.bundle.js +17357 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-0.bundle.js +4 -4
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-1.bundle.js +3 -3
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-10.bundle.js +101 -66
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-11.bundle.js +544 -8
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-12.bundle.js +915 -1480
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-12~module-15~module-16~module-4.bundle.js +2665 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-13.bundle.js +606 -3093
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-13~module-16~module-17~module-4.bundle.js +2665 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-14.bundle.js +764 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-15.bundle.js +71 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-16.bundle.js +1787 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-17.bundle.js +3383 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-4.bundle.js +121 -1009
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-5.bundle.js +1214 -1744
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-6.bundle.js +398 -666
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-7.bundle.js +717 -192
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-8.bundle.js +2117 -665
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-9.bundle.js +613 -690
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/vendors~mod-0~mod-1~mod-10~mod-11~mod-16~mod-5~mod-6~mod-7~mod-8.bundle.js +17357 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/vendors~mod-0~mod-1~mod-11~mod-12~mod-17~mod-5~mod-6~mod-7~mod-8~mod-9.bundle.js +17357 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/{vendors~module-0~module-1~module-13~module-4~module-5~module-7~module-8.bundle.js → vendors~mod-0~mod-1~mod-11~mod-12~mod-17~mod-5~mod-7~mod-8~mod-9.bundle.js} +2 -2
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/vendors~module-12.bundle.js +807 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/vendors~module-13.bundle.js +807 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/modules/cluster-configurator.html +32 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/modules/cluster-monitor.html +185 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/modules/cluster-updater.html +47 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/modules/extension-deployer.html +84 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/modules/zone-monitor.html +15 -8
- data/lib/rubyfox/server/data/www/ROOT/index.html +13 -23
- data/lib/rubyfox/server/data/www/host-manager/META-INF/context.xml +2 -2
- data/lib/rubyfox/server/data/www/host-manager/WEB-INF/jsp/404.jsp +2 -2
- data/lib/rubyfox/server/data/www/host-manager/{manager.xml → WEB-INF/manager.xml} +5 -1
- data/lib/rubyfox/server/data/www/host-manager/WEB-INF/web.xml +17 -0
- data/lib/rubyfox/server/data/www/host-manager/css/manager.css +141 -0
- data/lib/rubyfox/server/data/www/host-manager/images/tomcat.svg +967 -0
- data/lib/rubyfox/server/data/www/manager/META-INF/context.xml +2 -0
- data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/connectorCerts.jsp +1 -1
- data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/connectorCiphers.jsp +1 -1
- data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/connectorTrustedCerts.jsp +1 -1
- data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/sessionDetail.jsp +3 -3
- data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/sessionsList.jsp +1 -1
- data/lib/rubyfox/server/data/www/manager/WEB-INF/web.xml +17 -0
- data/lib/rubyfox/server/data/www/manager/css/manager.css +141 -0
- data/lib/rubyfox/server/data/www/manager/images/tomcat.svg +967 -0
- data/lib/rubyfox/server/data/www/manager/xform.xsl +74 -59
- data/lib/rubyfox/server/version.rb +1 -1
- metadata +30 -31
- data/lib/rubyfox/server/data/config/admin/icons/Analytics.png +0 -0
- data/lib/rubyfox/server/data/config/admin/icons/BanManager.png +0 -0
- data/lib/rubyfox/server/data/config/admin/icons/BlueBoxMonitor.png +0 -0
- data/lib/rubyfox/server/data/config/admin/icons/Console.png +0 -0
- data/lib/rubyfox/server/data/config/admin/icons/Dashboard.png +0 -0
- data/lib/rubyfox/server/data/config/admin/icons/ExtensionManager.png +0 -0
- data/lib/rubyfox/server/data/config/admin/icons/LicenseManager.png +0 -0
- data/lib/rubyfox/server/data/config/admin/icons/LogViewer.png +0 -0
- data/lib/rubyfox/server/data/config/admin/icons/ServerConfigurator.png +0 -0
- data/lib/rubyfox/server/data/config/admin/icons/ServletManager.png +0 -0
- data/lib/rubyfox/server/data/config/admin/icons/ZoneConfigurator.png +0 -0
- data/lib/rubyfox/server/data/config/admin/icons/ZoneMonitor.png +0 -0
- data/lib/rubyfox/server/data/lib/BlueBox.war +0 -0
- data/lib/rubyfox/server/data/lib/apache-tomcat/LICENSE +0 -1061
- data/lib/rubyfox/server/data/lib/apache-tomcat/NOTICE +0 -68
- data/lib/rubyfox/server/data/lib/apache-tomcat/README.md +0 -81
- data/lib/rubyfox/server/data/lib/apache-tomcat/RELEASE-NOTES +0 -174
- data/lib/rubyfox/server/data/lib/imap.jar +0 -0
- data/lib/rubyfox/server/data/lib/mailapi.jar +0 -0
- data/lib/rubyfox/server/data/lib/pop3.jar +0 -0
- data/lib/rubyfox/server/data/lib/smtp.jar +0 -0
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-12~module-13~module-9.bundle.js +0 -2634
- data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/vendors~module-9.bundle.js +0 -807
- data/lib/rubyfox/server/data/www/host-manager/images/tomcat.gif +0 -0
- data/lib/rubyfox/server/data/www/manager/images/tomcat.gif +0 -0
- /data/lib/rubyfox/server/data/data/buddylists/{BasicExamples/.keep → .keep} +0 -0
@@ -287,149 +287,11 @@ webpackContext.id = "./node_modules/moment/locale sync recursive ^\\.\\/.*$";
|
|
287
287
|
|
288
288
|
/***/ }),
|
289
289
|
|
290
|
-
/***/ "./src/components/charts/base-chart.js":
|
291
|
-
/*!*********************************************!*\
|
292
|
-
!*** ./src/components/charts/base-chart.js ***!
|
293
|
-
\*********************************************/
|
294
|
-
/*! exports provided: BaseChart */
|
295
|
-
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
296
|
-
|
297
|
-
"use strict";
|
298
|
-
__webpack_require__.r(__webpack_exports__);
|
299
|
-
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseChart", function() { return BaseChart; });
|
300
|
-
class BaseChart extends HTMLElement
|
301
|
-
{
|
302
|
-
constructor(maxValues)
|
303
|
-
{
|
304
|
-
super();
|
305
|
-
|
306
|
-
this._maxValues = maxValues;
|
307
|
-
|
308
|
-
// Initialize
|
309
|
-
this._initialize();
|
310
|
-
}
|
311
|
-
|
312
|
-
// Can be overridden
|
313
|
-
_initialize()
|
314
|
-
{
|
315
|
-
// Create chart html
|
316
|
-
let chartHtml = $('<div>');
|
317
|
-
$(this).append(chartHtml);
|
318
|
-
|
319
|
-
this._chartWidget = this._initChartWidget(chartHtml);
|
320
|
-
|
321
|
-
// Reset data source
|
322
|
-
this.reset();
|
323
|
-
}
|
324
|
-
|
325
|
-
// MUST BE OVERRIDDEN
|
326
|
-
_initChartWidget()
|
327
|
-
{
|
328
|
-
throw new Error('Chart widget must be initialized!')
|
329
|
-
}
|
330
|
-
|
331
|
-
set paused(value)
|
332
|
-
{
|
333
|
-
this.isPaused = value;
|
334
|
-
this._onPauseChange();
|
335
|
-
}
|
336
|
-
|
337
|
-
get paused()
|
338
|
-
{
|
339
|
-
return this.isPaused;
|
340
|
-
}
|
341
|
-
|
342
|
-
reset()
|
343
|
-
{
|
344
|
-
this._chartWidget.setDataSource([]);
|
345
|
-
}
|
346
|
-
|
347
|
-
redraw()
|
348
|
-
{
|
349
|
-
this._chartWidget.redraw();
|
350
|
-
}
|
351
|
-
|
352
|
-
getLastEntry()
|
353
|
-
{
|
354
|
-
let ds;
|
355
|
-
|
356
|
-
if (this.isPaused)
|
357
|
-
ds = this._tempDS;
|
358
|
-
else
|
359
|
-
ds = this._dataSource;
|
360
|
-
|
361
|
-
if (ds != null && ds.total() > 0)
|
362
|
-
return ds.at(ds.total() - 1);
|
363
|
-
else
|
364
|
-
return null;
|
365
|
-
}
|
366
|
-
|
367
|
-
_addEntry(newEntry)
|
368
|
-
{
|
369
|
-
if (this.isPaused)
|
370
|
-
{
|
371
|
-
if (this._tempDS == null)
|
372
|
-
this._tempDS = new kendo.data.DataSource();
|
373
|
-
|
374
|
-
// Store new value in a temporary array
|
375
|
-
this._tempDS.add(newEntry);
|
376
|
-
}
|
377
|
-
else
|
378
|
-
{
|
379
|
-
let ds = this._dataSource;
|
380
|
-
|
381
|
-
if (this._tempDS != null)
|
382
|
-
{
|
383
|
-
// Concatenate temporary entries to actual data source
|
384
|
-
let newArr = $.merge(ds.data(), this._tempDS.data());
|
385
|
-
|
386
|
-
// Remove values exceeding MAX_VALUES
|
387
|
-
if (newArr.length > this._maxValues)
|
388
|
-
newArr.splice(0, newArr.length - this._maxValues)
|
389
|
-
|
390
|
-
// Create new datasource
|
391
|
-
let newDS = new kendo.data.DataSource({data: newArr})
|
392
|
-
|
393
|
-
// Assign new data source to chart
|
394
|
-
this._chartWidget.setDataSource(newDS);
|
395
|
-
|
396
|
-
// Remove temporary array
|
397
|
-
this._tempDS = null;
|
398
|
-
}
|
399
|
-
|
400
|
-
// Add new entry
|
401
|
-
ds.add(newEntry);
|
402
|
-
|
403
|
-
// Remove first item if needed
|
404
|
-
if (ds.total() > this._maxValues)
|
405
|
-
ds.remove(ds.at(0));
|
406
|
-
}
|
407
|
-
}
|
408
|
-
|
409
|
-
get _dataSource()
|
410
|
-
{
|
411
|
-
return this._chartWidget.dataSource;
|
412
|
-
}
|
413
|
-
|
414
|
-
_onPauseChange()
|
415
|
-
{
|
416
|
-
// Nothing to do, should be overridden
|
417
|
-
}
|
418
|
-
}
|
419
|
-
|
420
|
-
// DEFINE COMPONENT
|
421
|
-
if (!window.customElements.get('base-chart'))
|
422
|
-
window.customElements.define('base-chart', BaseChart);
|
423
|
-
|
424
|
-
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery")))
|
425
|
-
|
426
|
-
/***/ }),
|
427
|
-
|
428
290
|
/***/ "./src/components/charts/chart-utils.js":
|
429
291
|
/*!**********************************************!*\
|
430
292
|
!*** ./src/components/charts/chart-utils.js ***!
|
431
293
|
\**********************************************/
|
432
|
-
/*! exports provided: getFormattedDateTime, getBasicSharedTemplate, getMemorySharedTemplate, getMemoryValueAxisLabelTemplate, getNetworkSharedTemplate, getNetworkValueAxisLabelTemplate, getUserCountSharedTemplate, getTimeRangeTooltipTemplate, getWRBytesLabelTemplate */
|
294
|
+
/*! exports provided: getFormattedDateTime, getBasicSharedTemplate, getMemorySharedTemplate, getMemoryValueAxisLabelTemplate, getNetworkSharedTemplate, getNetworkValueAxisLabelTemplate, getNetworkValueAxisLabelTemplateB, getUserCountSharedTemplate, getTimeRangeTooltipTemplate, getWRBytesLabelTemplate, getBasicTemplate, getMemoryTemplate, getNetworkTemplate */
|
433
295
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
434
296
|
|
435
297
|
"use strict";
|
@@ -440,9 +302,13 @@ __webpack_require__.r(__webpack_exports__);
|
|
440
302
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getMemoryValueAxisLabelTemplate", function() { return getMemoryValueAxisLabelTemplate; });
|
441
303
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getNetworkSharedTemplate", function() { return getNetworkSharedTemplate; });
|
442
304
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getNetworkValueAxisLabelTemplate", function() { return getNetworkValueAxisLabelTemplate; });
|
305
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getNetworkValueAxisLabelTemplateB", function() { return getNetworkValueAxisLabelTemplateB; });
|
443
306
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getUserCountSharedTemplate", function() { return getUserCountSharedTemplate; });
|
444
307
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getTimeRangeTooltipTemplate", function() { return getTimeRangeTooltipTemplate; });
|
445
308
|
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getWRBytesLabelTemplate", function() { return getWRBytesLabelTemplate; });
|
309
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getBasicTemplate", function() { return getBasicTemplate; });
|
310
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getMemoryTemplate", function() { return getMemoryTemplate; });
|
311
|
+
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getNetworkTemplate", function() { return getNetworkTemplate; });
|
446
312
|
/* harmony import */ var _utils_utilities__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils/utilities */ "./src/utils/utilities.js");
|
447
313
|
|
448
314
|
|
@@ -511,6 +377,15 @@ function getNetworkValueAxisLabelTemplate() {
|
|
511
377
|
};
|
512
378
|
}
|
513
379
|
|
380
|
+
function getNetworkValueAxisLabelTemplateB() {
|
381
|
+
return function(dataItem) {
|
382
|
+
dataItem.bytesToSize = _utils_utilities__WEBPACK_IMPORTED_MODULE_0__["bytesToSize"]; // Pass bytesToSize utility function to template
|
383
|
+
return kendo.template(`
|
384
|
+
#: bytesToSize(value, 1, '', '/s') #
|
385
|
+
`)(dataItem);
|
386
|
+
};
|
387
|
+
}
|
388
|
+
|
514
389
|
function getUserCountSharedTemplate(categoryFormat = 'dd MMM HH:mm:ss') {
|
515
390
|
return function(dataItem) {
|
516
391
|
return kendo.template(`
|
@@ -555,82 +430,178 @@ function getWRBytesLabelTemplate() {
|
|
555
430
|
};
|
556
431
|
}
|
557
432
|
|
433
|
+
function getBasicTemplate(valueFormat = '{0}') {
|
434
|
+
return kendo.template(`
|
435
|
+
<div>
|
436
|
+
<span class="text-nowrap">#: kendo.toString(new Date(value.x), "dd/MM/yy HH:mm") #</span>
|
437
|
+
<br>
|
438
|
+
<strong class="text-nowrap">#: series.name #: #: kendo.format('${valueFormat}', value.y) # </strong>
|
439
|
+
</div>
|
440
|
+
`);
|
441
|
+
}
|
442
|
+
|
443
|
+
function getMemoryTemplate() {
|
444
|
+
return function(dataItem) {
|
445
|
+
dataItem.bytesToSize = _utils_utilities__WEBPACK_IMPORTED_MODULE_0__["bytesToSize"]; // Pass bytesToSize utility function to template
|
446
|
+
return kendo.template(`
|
447
|
+
<div>
|
448
|
+
<span class="text-nowrap">#: kendo.toString(new Date(value.x), "dd/MM/yy HH:mm") #</span>
|
449
|
+
<br>
|
450
|
+
<strong class="text-nowrap">#: series.name #: #: bytesToSize(value.y) # </strong>
|
451
|
+
</div>
|
452
|
+
`)(dataItem);
|
453
|
+
};
|
454
|
+
}
|
455
|
+
|
456
|
+
function getNetworkTemplate() {
|
457
|
+
return function(dataItem) {
|
458
|
+
dataItem.bytesToSize = _utils_utilities__WEBPACK_IMPORTED_MODULE_0__["bytesToSize"]; // Pass bytesToSize utility function to template
|
459
|
+
return kendo.template(`
|
460
|
+
<div>
|
461
|
+
<span class="text-nowrap">#: kendo.toString(new Date(value.x), "dd/MM/yy HH:mm") #</span>
|
462
|
+
<br>
|
463
|
+
<strong class="text-nowrap">#: series.name #: #: bytesToSize(value.y, 1, '', '/s') # </strong>
|
464
|
+
</div>
|
465
|
+
`)(dataItem);
|
466
|
+
};
|
467
|
+
}
|
468
|
+
|
558
469
|
|
559
470
|
/***/ }),
|
560
471
|
|
561
|
-
/***/ "./src/components/
|
562
|
-
|
563
|
-
!*** ./src/components/
|
564
|
-
|
565
|
-
/*! exports provided:
|
472
|
+
/***/ "./src/components/module-specific/cluster-monitor/node-mini-charts.js":
|
473
|
+
/*!****************************************************************************!*\
|
474
|
+
!*** ./src/components/module-specific/cluster-monitor/node-mini-charts.js ***!
|
475
|
+
\****************************************************************************/
|
476
|
+
/*! exports provided: NodeMiniCharts */
|
566
477
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
567
478
|
|
568
479
|
"use strict";
|
569
480
|
__webpack_require__.r(__webpack_exports__);
|
570
|
-
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "
|
571
|
-
/* harmony import */ var
|
572
|
-
/* harmony import */ var
|
481
|
+
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMiniCharts", function() { return NodeMiniCharts; });
|
482
|
+
/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! moment */ "./node_modules/moment/moment.js");
|
483
|
+
/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_0__);
|
484
|
+
/* harmony import */ var _charts_chart_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../charts/chart-utils */ "./src/components/charts/chart-utils.js");
|
573
485
|
|
574
486
|
|
575
487
|
|
576
|
-
|
577
|
-
class CpuUsageChart extends _base_chart__WEBPACK_IMPORTED_MODULE_0__["BaseChart"]
|
488
|
+
class NodeMiniCharts extends HTMLElement
|
578
489
|
{
|
579
|
-
constructor()
|
490
|
+
constructor(nodeId, nodeAlias, nodeName)
|
580
491
|
{
|
581
|
-
super(
|
582
|
-
}
|
492
|
+
super();
|
583
493
|
|
584
|
-
|
585
|
-
|
586
|
-
|
494
|
+
const shadowRoot = this.attachShadow({mode: 'open'});
|
495
|
+
shadowRoot.innerHTML = `
|
496
|
+
<link rel="stylesheet" type="text/css" href="assets/css/custom-bootstrap.min.css" />
|
497
|
+
<link rel="stylesheet" type="text/css" href="assets/css/kendo.custom-bootstrap-v4.css" />
|
498
|
+
|
499
|
+
<style>
|
500
|
+
.box {
|
501
|
+
background-color: #FFF;
|
502
|
+
border-radius: .5rem;
|
503
|
+
}
|
504
|
+
|
505
|
+
.chart-container {
|
506
|
+
cursor: pointer;
|
507
|
+
}
|
508
|
+
</style>
|
509
|
+
|
510
|
+
<div class="container-fluid">
|
511
|
+
<div class="row py-3 box">
|
512
|
+
<div class="col-sm-6 col-md-4 col-lg-2 d-flex flex-column justify-content-center">
|
513
|
+
<small class="text-muted">Node</small>
|
514
|
+
<strong id="alias"></strong>
|
515
|
+
<small id="name"></small>
|
516
|
+
</div>
|
517
|
+
<div class="col-sm-6 col-md-4 col-lg-2 text-center chart-container" data-type="ccu">
|
518
|
+
<div class="chart"></div>
|
519
|
+
</div>
|
520
|
+
<div class="col-sm-6 col-md-4 col-lg-2 text-center chart-container" data-type="cpu">
|
521
|
+
<div class="chart"></div>
|
522
|
+
</div>
|
523
|
+
<div class="col-sm-6 col-md-4 col-lg-2 text-center chart-container" data-type="mem">
|
524
|
+
<div class="chart"></div>
|
525
|
+
</div>
|
526
|
+
<div class="col-sm-6 col-md-4 col-lg-2 text-center chart-container" data-type="net">
|
527
|
+
<div class="chart"></div>
|
528
|
+
</div>
|
529
|
+
<div class="col-sm-6 col-md-4 col-lg-2 text-center chart-container" data-type="thd">
|
530
|
+
<div class="chart"></div>
|
531
|
+
</div>
|
532
|
+
</div>
|
533
|
+
</div>
|
534
|
+
`;
|
535
|
+
|
536
|
+
this.nId = nodeId;
|
537
|
+
this.nAlias = nodeAlias;
|
538
|
+
this.nName = nodeName;
|
539
|
+
|
540
|
+
// Set tag's id attribute
|
541
|
+
this.id = 'node_' + nodeId;
|
542
|
+
|
543
|
+
if (nodeAlias)
|
544
|
+
{
|
545
|
+
$('#alias', shadowRoot).text(nodeAlias);
|
546
|
+
$('#name', shadowRoot).text(nodeName);
|
547
|
+
}
|
548
|
+
else
|
549
|
+
{
|
550
|
+
$('#alias', shadowRoot).text(nodeName);
|
551
|
+
$('#name', shadowRoot).hide();
|
552
|
+
}
|
553
|
+
|
554
|
+
this._getChartDiv('ccu').kendoChart({
|
587
555
|
transitions: false,
|
588
556
|
chartArea: {
|
589
|
-
height: 120
|
557
|
+
height: 120,
|
558
|
+
background: 'transparent',
|
559
|
+
margin: 0,
|
560
|
+
padding:0
|
590
561
|
},
|
591
562
|
legend: {
|
592
563
|
visible: false
|
593
564
|
},
|
565
|
+
title: {
|
566
|
+
text: 'Concurrent Users',
|
567
|
+
font: '12px sans-serif',
|
568
|
+
color: '#212529'
|
569
|
+
},
|
594
570
|
seriesDefaults: {
|
595
|
-
type: '
|
571
|
+
type: 'scatterLine',
|
596
572
|
labels: {
|
597
573
|
visible: false,
|
598
|
-
format: '{0}
|
574
|
+
format: '{0}',
|
599
575
|
background: 'transparent'
|
600
|
-
}
|
576
|
+
},
|
577
|
+
missingValues: 'gap',
|
578
|
+
markers: {
|
579
|
+
visible: false,
|
580
|
+
type: 'circle',
|
581
|
+
size: 2,
|
582
|
+
},
|
583
|
+
width: 2
|
601
584
|
},
|
602
585
|
series: [
|
603
586
|
{
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
color:
|
608
|
-
|
609
|
-
width: 2
|
610
|
-
}
|
611
|
-
},
|
612
|
-
{
|
613
|
-
name: 'Process',
|
614
|
-
field: 'processLoad',
|
615
|
-
categoryField: 'time',
|
616
|
-
color: this.processColor,
|
617
|
-
line: {
|
618
|
-
width: 2
|
619
|
-
}
|
620
|
-
}
|
587
|
+
xField: 'ts',
|
588
|
+
yField: 'val',
|
589
|
+
name: 'CCU',
|
590
|
+
color: '#3399FF'
|
591
|
+
}
|
621
592
|
],
|
622
|
-
|
593
|
+
yAxis: {
|
623
594
|
labels: {
|
624
|
-
format: '{0}
|
595
|
+
format: '{0}',
|
596
|
+
step: 2
|
625
597
|
},
|
626
598
|
line: {
|
627
599
|
visible: false
|
628
600
|
},
|
629
|
-
min: 0
|
630
|
-
max: 100
|
601
|
+
min: 0
|
631
602
|
},
|
632
|
-
|
633
|
-
|
603
|
+
xAxis: {
|
604
|
+
majorGridLines: {
|
634
605
|
visible: false
|
635
606
|
},
|
636
607
|
majorTicks: {
|
@@ -641,118 +612,63 @@ class CpuUsageChart extends _base_chart__WEBPACK_IMPORTED_MODULE_0__["BaseChart"
|
|
641
612
|
}
|
642
613
|
},
|
643
614
|
tooltip: {
|
644
|
-
|
645
|
-
|
646
|
-
sharedTemplate: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getBasicSharedTemplate"])('{0}%'),
|
615
|
+
visible: true,
|
616
|
+
template: Object(_charts_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getBasicTemplate"])('{0}'),
|
647
617
|
background: '#e4e4e4'
|
648
618
|
}
|
649
619
|
}).data('kendoChart');
|
650
|
-
}
|
651
|
-
|
652
|
-
get systemColor()
|
653
|
-
{
|
654
|
-
return '#3399FF';
|
655
|
-
}
|
656
|
-
|
657
|
-
get processColor()
|
658
|
-
{
|
659
|
-
return '#0033CC';
|
660
|
-
}
|
661
|
-
|
662
|
-
addEntry(processLoad, systemLoad)
|
663
|
-
{
|
664
|
-
let newEntry = {
|
665
|
-
time: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getFormattedDateTime"])(new Date()),
|
666
|
-
processLoad: processLoad,
|
667
|
-
systemLoad: systemLoad
|
668
|
-
};
|
669
|
-
|
670
|
-
// Add entry to chart
|
671
|
-
super._addEntry(newEntry);
|
672
|
-
}
|
673
|
-
}
|
674
|
-
|
675
|
-
// DEFINE COMPONENT
|
676
|
-
if (!window.customElements.get('cpu-usage-chart'))
|
677
|
-
window.customElements.define('cpu-usage-chart', CpuUsageChart);
|
678
|
-
|
679
|
-
|
680
|
-
/***/ }),
|
681
|
-
|
682
|
-
/***/ "./src/components/charts/memory-chart.js":
|
683
|
-
/*!***********************************************!*\
|
684
|
-
!*** ./src/components/charts/memory-chart.js ***!
|
685
|
-
\***********************************************/
|
686
|
-
/*! exports provided: MemoryChart */
|
687
|
-
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
688
|
-
|
689
|
-
"use strict";
|
690
|
-
__webpack_require__.r(__webpack_exports__);
|
691
|
-
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MemoryChart", function() { return MemoryChart; });
|
692
|
-
/* harmony import */ var _base_chart__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-chart */ "./src/components/charts/base-chart.js");
|
693
|
-
/* harmony import */ var _chart_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./chart-utils */ "./src/components/charts/chart-utils.js");
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
class MemoryChart extends _base_chart__WEBPACK_IMPORTED_MODULE_0__["BaseChart"]
|
699
|
-
{
|
700
|
-
constructor()
|
701
|
-
{
|
702
|
-
super(300);
|
703
620
|
|
704
|
-
|
705
|
-
this._elapsedTxt = $('<div>', {class: 'text-center', text: '---'});
|
706
|
-
$(this).append(this._elapsedTxt);
|
707
|
-
}
|
708
|
-
|
709
|
-
_initChartWidget(chartHtml)
|
710
|
-
{
|
711
|
-
return chartHtml.kendoChart({
|
621
|
+
this._getChartDiv('cpu').kendoChart({
|
712
622
|
transitions: false,
|
713
623
|
chartArea: {
|
714
|
-
height:
|
624
|
+
height: 120,
|
625
|
+
background: 'transparent',
|
626
|
+
margin: 0,
|
627
|
+
padding:0
|
715
628
|
},
|
716
629
|
legend: {
|
717
630
|
visible: false
|
718
631
|
},
|
632
|
+
title: {
|
633
|
+
text: 'CPU',
|
634
|
+
font: '12px sans-serif',
|
635
|
+
color: '#212529'
|
636
|
+
},
|
719
637
|
seriesDefaults: {
|
720
|
-
type: '
|
638
|
+
type: 'scatterLine',
|
721
639
|
labels: {
|
722
640
|
visible: false,
|
723
|
-
format: '{0}',
|
641
|
+
format: '{0}%',
|
724
642
|
background: 'transparent'
|
725
643
|
},
|
644
|
+
missingValues: 'gap',
|
645
|
+
markers: {
|
646
|
+
visible: false,
|
647
|
+
type: 'circle',
|
648
|
+
size: 3,
|
649
|
+
},
|
650
|
+
width: 2
|
726
651
|
},
|
727
|
-
series: [
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
{
|
737
|
-
name: 'Used',
|
738
|
-
field: 'usedMem',
|
739
|
-
categoryField: 'time',
|
740
|
-
color: this.usedColor,
|
741
|
-
line: {
|
742
|
-
width: 2
|
743
|
-
}
|
744
|
-
}],
|
745
|
-
valueAxis: {
|
652
|
+
series: [
|
653
|
+
{
|
654
|
+
xField: 'ts',
|
655
|
+
yField: 'val',
|
656
|
+
name: 'CPU',
|
657
|
+
color: '#3399FF'
|
658
|
+
}
|
659
|
+
],
|
660
|
+
yAxis: {
|
746
661
|
labels: {
|
747
|
-
format: '{0}'
|
748
|
-
template: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getMemoryValueAxisLabelTemplate"])()
|
662
|
+
format: '{0}%'
|
749
663
|
},
|
750
664
|
line: {
|
751
665
|
visible: false
|
752
666
|
},
|
753
|
-
min: 0
|
667
|
+
min: 0,
|
668
|
+
max: 100,
|
669
|
+
majorUnit: 25
|
754
670
|
},
|
755
|
-
|
671
|
+
xAxis: {
|
756
672
|
majorGridLines: {
|
757
673
|
visible: false
|
758
674
|
},
|
@@ -763,390 +679,131 @@ class MemoryChart extends _base_chart__WEBPACK_IMPORTED_MODULE_0__["BaseChart"]
|
|
763
679
|
visible: false
|
764
680
|
}
|
765
681
|
},
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
background: '#e4e4e4'
|
682
|
+
tooltip: {
|
683
|
+
visible: true,
|
684
|
+
template: Object(_charts_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getBasicTemplate"])('{0}%'),
|
685
|
+
background: '#e4e4e4',
|
771
686
|
}
|
772
687
|
}).data('kendoChart');
|
773
|
-
}
|
774
|
-
|
775
|
-
get allocatedColor()
|
776
|
-
{
|
777
|
-
return '#3399FF';
|
778
|
-
}
|
779
|
-
|
780
|
-
get usedColor()
|
781
|
-
{
|
782
|
-
return '#0033CC';
|
783
|
-
}
|
784
|
-
|
785
|
-
addEntry(allocMem, usedMem)
|
786
|
-
{
|
787
|
-
let now = new Date();
|
788
|
-
|
789
|
-
let newEntry = {
|
790
|
-
time: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getFormattedDateTime"])(now),
|
791
|
-
timestamp: now.getTime(),
|
792
|
-
allocMem: allocMem,
|
793
|
-
usedMem: usedMem
|
794
|
-
};
|
795
|
-
|
796
|
-
// Add entry to chart
|
797
|
-
super._addEntry(newEntry);
|
798
|
-
|
799
|
-
// Update x axis
|
800
|
-
if (!this.isPaused)
|
801
|
-
this._updateElapsedText();
|
802
|
-
}
|
803
|
-
|
804
|
-
_updateElapsedText()
|
805
|
-
{
|
806
|
-
let ds = this._dataSource;
|
807
|
-
|
808
|
-
if (ds.total() > 1)
|
809
|
-
{
|
810
|
-
// Get axis limits
|
811
|
-
const chartMinimum = ds.at(0).timestamp;
|
812
|
-
const chartMaximum = ds.at(ds.total() - 1).timestamp;
|
813
|
-
|
814
|
-
// Set elapsed text
|
815
|
-
let seconds = Math.round( (chartMaximum - chartMinimum) / 1000 );
|
816
|
-
let title;
|
817
|
-
|
818
|
-
if (seconds < 60)
|
819
|
-
title = 'Last ' + (seconds != 1 ? seconds + ' seconds' : 'second');
|
820
|
-
else
|
821
|
-
{
|
822
|
-
const minutes = Math.floor(seconds / 60);
|
823
|
-
title = 'Last ' + (minutes != 1 ? minutes + ' minutes' : 'minute');
|
824
|
-
}
|
825
|
-
|
826
|
-
this._elapsedTxt.text(title);
|
827
|
-
}
|
828
|
-
}
|
829
|
-
}
|
830
|
-
|
831
|
-
// DEFINE COMPONENT
|
832
|
-
if (!window.customElements.get('memory-chart'))
|
833
|
-
window.customElements.define('memory-chart', MemoryChart);
|
834
|
-
|
835
|
-
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery")))
|
836
|
-
|
837
|
-
/***/ }),
|
838
|
-
|
839
|
-
/***/ "./src/components/charts/network-24h-chart.js":
|
840
|
-
/*!****************************************************!*\
|
841
|
-
!*** ./src/components/charts/network-24h-chart.js ***!
|
842
|
-
\****************************************************/
|
843
|
-
/*! exports provided: Network24hChart */
|
844
|
-
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
845
|
-
|
846
|
-
"use strict";
|
847
|
-
__webpack_require__.r(__webpack_exports__);
|
848
|
-
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Network24hChart", function() { return Network24hChart; });
|
849
|
-
/* harmony import */ var _chart_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./chart-utils */ "./src/components/charts/chart-utils.js");
|
850
|
-
/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! moment */ "./node_modules/moment/moment.js");
|
851
|
-
/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_1__);
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
class Network24hChart extends HTMLElement
|
856
|
-
{
|
857
|
-
constructor()
|
858
|
-
{
|
859
|
-
super();
|
860
|
-
|
861
|
-
this._lastTotalOut = 0;
|
862
|
-
this._lastTotalIn = 0;
|
863
|
-
this._lastDate = new Date();
|
864
|
-
this._samplingRateSeconds = 0;
|
865
|
-
|
866
|
-
// Create chart html
|
867
|
-
let chartHtml = $('<div>');
|
868
|
-
$(this).append(chartHtml);
|
869
|
-
|
870
|
-
// Initialize chart
|
871
|
-
this._chartWidget = this._initChartWidget(chartHtml);
|
872
|
-
}
|
873
688
|
|
874
|
-
|
875
|
-
{
|
876
|
-
return chartHtml.kendoChart({
|
689
|
+
this._getChartDiv('mem').kendoChart({
|
877
690
|
transitions: false,
|
878
691
|
chartArea: {
|
879
|
-
height:
|
880
|
-
background: 'transparent'
|
692
|
+
height: 120,
|
693
|
+
background: 'transparent',
|
694
|
+
margin: 0,
|
695
|
+
padding:0
|
881
696
|
},
|
882
697
|
legend: {
|
883
698
|
visible: false
|
884
699
|
},
|
700
|
+
title: {
|
701
|
+
text: 'Memory',
|
702
|
+
font: '12px sans-serif',
|
703
|
+
color: '#212529'
|
704
|
+
},
|
885
705
|
seriesDefaults: {
|
886
|
-
type: '
|
706
|
+
type: 'scatterLine',
|
887
707
|
labels: {
|
888
708
|
visible: false,
|
889
709
|
format: '{0}',
|
890
710
|
background: 'transparent'
|
891
711
|
},
|
712
|
+
missingValues: 'gap',
|
713
|
+
markers: {
|
714
|
+
visible: false,
|
715
|
+
type: 'circle',
|
716
|
+
size: 3,
|
717
|
+
},
|
718
|
+
width: 2
|
892
719
|
},
|
893
|
-
series: [
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
{
|
903
|
-
name: 'Incoming',
|
904
|
-
field: 'incoming',
|
905
|
-
categoryField: 'time',
|
906
|
-
color: '#009900',
|
907
|
-
line: {
|
908
|
-
width: 2
|
909
|
-
}
|
910
|
-
}],
|
911
|
-
valueAxis: {
|
720
|
+
series: [
|
721
|
+
{
|
722
|
+
xField: 'ts',
|
723
|
+
yField: 'val',
|
724
|
+
name: 'Memory',
|
725
|
+
color: '#3399FF'
|
726
|
+
}
|
727
|
+
],
|
728
|
+
yAxis: {
|
912
729
|
labels: {
|
913
730
|
format: '{0}',
|
914
|
-
template: Object(
|
731
|
+
template: Object(_charts_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getMemoryValueAxisLabelTemplate"])(),
|
732
|
+
step: 2
|
915
733
|
},
|
916
734
|
line: {
|
917
735
|
visible: false
|
918
736
|
},
|
919
|
-
min: 0
|
737
|
+
min: 0,
|
920
738
|
},
|
921
|
-
|
739
|
+
xAxis: {
|
922
740
|
majorGridLines: {
|
923
|
-
visible:
|
924
|
-
step: 60
|
741
|
+
visible: false
|
925
742
|
},
|
926
743
|
majorTicks: {
|
927
|
-
visible:
|
928
|
-
step: 60
|
744
|
+
visible: false
|
929
745
|
},
|
930
746
|
labels: {
|
931
|
-
visible:
|
932
|
-
|
933
|
-
},
|
934
|
-
baseUnit: 'minutes',
|
935
|
-
type: 'date',
|
747
|
+
visible: false
|
748
|
+
}
|
936
749
|
},
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
background: '#e4e4e4'
|
750
|
+
tooltip: {
|
751
|
+
visible: true,
|
752
|
+
template: Object(_charts_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getMemoryTemplate"])(),
|
753
|
+
background: '#e4e4e4',
|
942
754
|
}
|
943
755
|
}).data('kendoChart');
|
944
|
-
}
|
945
|
-
|
946
|
-
redraw()
|
947
|
-
{
|
948
|
-
this._chartWidget.redraw();
|
949
|
-
}
|
950
|
-
|
951
|
-
set range(values)
|
952
|
-
{
|
953
|
-
this._range = values;
|
954
|
-
|
955
|
-
this._updateXAxisLimits();
|
956
|
-
}
|
957
|
-
|
958
|
-
get range()
|
959
|
-
{
|
960
|
-
return this._range;
|
961
|
-
}
|
962
|
-
|
963
|
-
addHistoryEntries(outgoingData, incomingData, samplingRateSeconds, shiftSeconds)
|
964
|
-
{
|
965
|
-
this._samplingRateSeconds = samplingRateSeconds;
|
966
|
-
|
967
|
-
let now = new Date();
|
968
|
-
|
969
|
-
// NOTE: outgoingData and incominData are supposed to have the same size!!!
|
970
|
-
|
971
|
-
if (outgoingData.length > 0)
|
972
|
-
{
|
973
|
-
let start = moment__WEBPACK_IMPORTED_MODULE_1__(now);
|
974
|
-
start.subtract((samplingRateSeconds * outgoingData.length) + shiftSeconds, 's')
|
975
756
|
|
976
|
-
|
977
|
-
this._lastTotalIn = incomingData[0];
|
978
|
-
this._lastDate = start.toDate();
|
979
|
-
|
980
|
-
if (outgoingData.length > 1)
|
981
|
-
{
|
982
|
-
let dataSource = new kendo.data.DataSource();
|
983
|
-
|
984
|
-
for (let i = 1; i < outgoingData.length; i++)
|
985
|
-
{
|
986
|
-
const totalOut = outgoingData[i];
|
987
|
-
const totalIn = incomingData[i];
|
988
|
-
|
989
|
-
let date = start.clone();
|
990
|
-
date.add(i * samplingRateSeconds, 's');
|
991
|
-
|
992
|
-
this.addEntry(totalOut, totalIn, dataSource, date.toDate(), false);
|
993
|
-
}
|
994
|
-
|
995
|
-
// Assign datasource to chart
|
996
|
-
this._chartWidget.setDataSource(dataSource);
|
997
|
-
|
998
|
-
// Update axis
|
999
|
-
this._updateXAxisLimits();
|
1000
|
-
}
|
1001
|
-
}
|
1002
|
-
else
|
1003
|
-
{
|
1004
|
-
this._lastTotalOut = 0;
|
1005
|
-
this._lastTotalIn = 0;
|
1006
|
-
this._lastDate = now;
|
1007
|
-
}
|
1008
|
-
}
|
1009
|
-
|
1010
|
-
addEntry(totalOut, totalIn, dataSource = null, date = null, updateAxis = true)
|
1011
|
-
{
|
1012
|
-
if (date == null)
|
1013
|
-
date = new Date();
|
1014
|
-
|
1015
|
-
const elapsedSecs = Math.round((date.getTime() - this._lastDate.getTime()) / 1000);
|
1016
|
-
|
1017
|
-
// The 24h chart is updated at the same sampling rate used by the server to save the traffic history
|
1018
|
-
if (elapsedSecs >= this._samplingRateSeconds)
|
1019
|
-
{
|
1020
|
-
let newEntry = {
|
1021
|
-
time: date,
|
1022
|
-
outgoing: Math.round((totalOut - this._lastTotalOut) / elapsedSecs),
|
1023
|
-
incoming: Math.round((totalIn - this._lastTotalIn) / elapsedSecs)
|
1024
|
-
};
|
1025
|
-
|
1026
|
-
// Add entry to data source
|
1027
|
-
if (dataSource == null)
|
1028
|
-
dataSource = this._dataSource;
|
1029
|
-
|
1030
|
-
dataSource.add(newEntry);
|
1031
|
-
|
1032
|
-
this._lastTotalOut = totalOut;
|
1033
|
-
this._lastTotalIn = totalIn;
|
1034
|
-
this._lastDate = date;
|
1035
|
-
|
1036
|
-
if (updateAxis)
|
1037
|
-
this._updateXAxisLimits();
|
1038
|
-
}
|
1039
|
-
}
|
1040
|
-
|
1041
|
-
_updateXAxisLimits()
|
1042
|
-
{
|
1043
|
-
let ds = this._dataSource;
|
1044
|
-
|
1045
|
-
if (ds.total() > 0)
|
1046
|
-
{
|
1047
|
-
const chartMinimum = moment__WEBPACK_IMPORTED_MODULE_1__(this._lastDate).add(this._range[0], 'h');
|
1048
|
-
const chartMaximum = moment__WEBPACK_IMPORTED_MODULE_1__(this._lastDate).add(this._range[1], 'h');
|
1049
|
-
|
1050
|
-
this._chartWidget.options.categoryAxis.min = chartMinimum.toDate();
|
1051
|
-
this._chartWidget.options.categoryAxis.max = chartMaximum.toDate();
|
1052
|
-
|
1053
|
-
this._chartWidget.redraw();
|
1054
|
-
}
|
1055
|
-
}
|
1056
|
-
|
1057
|
-
get _dataSource()
|
1058
|
-
{
|
1059
|
-
return this._chartWidget.dataSource;
|
1060
|
-
}
|
1061
|
-
}
|
1062
|
-
|
1063
|
-
// DEFINE COMPONENT
|
1064
|
-
if (!window.customElements.get('network-24h-chart'))
|
1065
|
-
window.customElements.define('network-24h-chart', Network24hChart);
|
1066
|
-
|
1067
|
-
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery")))
|
1068
|
-
|
1069
|
-
/***/ }),
|
1070
|
-
|
1071
|
-
/***/ "./src/components/charts/network-realtime-chart.js":
|
1072
|
-
/*!*********************************************************!*\
|
1073
|
-
!*** ./src/components/charts/network-realtime-chart.js ***!
|
1074
|
-
\*********************************************************/
|
1075
|
-
/*! exports provided: NetworkRealtimeChart */
|
1076
|
-
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1077
|
-
|
1078
|
-
"use strict";
|
1079
|
-
__webpack_require__.r(__webpack_exports__);
|
1080
|
-
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NetworkRealtimeChart", function() { return NetworkRealtimeChart; });
|
1081
|
-
/* harmony import */ var _base_chart__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-chart */ "./src/components/charts/base-chart.js");
|
1082
|
-
/* harmony import */ var _chart_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./chart-utils */ "./src/components/charts/chart-utils.js");
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
class NetworkRealtimeChart extends _base_chart__WEBPACK_IMPORTED_MODULE_0__["BaseChart"]
|
1088
|
-
{
|
1089
|
-
constructor()
|
1090
|
-
{
|
1091
|
-
super(300);
|
1092
|
-
|
1093
|
-
this._lastTotalKbOut = 0;
|
1094
|
-
this._lastTotalKbIn = 0;
|
1095
|
-
this._lastTime = 0;
|
1096
|
-
|
1097
|
-
// Append text to display elapsed time
|
1098
|
-
this._elapsedTxt = $('<div>', {class: 'text-center', text: '---'});
|
1099
|
-
$(this).append(this._elapsedTxt);
|
1100
|
-
}
|
1101
|
-
|
1102
|
-
_initChartWidget(chartHtml)
|
1103
|
-
{
|
1104
|
-
return chartHtml.kendoChart({
|
757
|
+
this._getChartDiv('thd').kendoChart({
|
1105
758
|
transitions: false,
|
1106
759
|
chartArea: {
|
1107
|
-
height:
|
1108
|
-
background: 'transparent'
|
760
|
+
height: 120,
|
761
|
+
background: 'transparent',
|
762
|
+
margin: 0,
|
763
|
+
padding:0
|
1109
764
|
},
|
1110
765
|
legend: {
|
1111
766
|
visible: false
|
1112
767
|
},
|
768
|
+
title: {
|
769
|
+
text: 'Threads',
|
770
|
+
font: '12px sans-serif',
|
771
|
+
color: '#212529'
|
772
|
+
},
|
1113
773
|
seriesDefaults: {
|
1114
|
-
type: '
|
774
|
+
type: 'scatterLine',
|
1115
775
|
labels: {
|
1116
776
|
visible: false,
|
1117
777
|
format: '{0}',
|
1118
778
|
background: 'transparent'
|
1119
779
|
},
|
780
|
+
missingValues: 'gap',
|
781
|
+
markers: {
|
782
|
+
visible: false,
|
783
|
+
type: 'circle',
|
784
|
+
size: 3,
|
785
|
+
},
|
786
|
+
width: 2
|
1120
787
|
},
|
1121
|
-
series: [
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
{
|
1131
|
-
name: 'Incoming',
|
1132
|
-
field: 'incoming',
|
1133
|
-
categoryField: 'time',
|
1134
|
-
color: this.incomingColor,
|
1135
|
-
line: {
|
1136
|
-
width: 2
|
1137
|
-
}
|
1138
|
-
}],
|
1139
|
-
valueAxis: {
|
788
|
+
series: [
|
789
|
+
{
|
790
|
+
xField: 'ts',
|
791
|
+
yField: 'val',
|
792
|
+
name: 'Threads',
|
793
|
+
color: '#3399FF'
|
794
|
+
}
|
795
|
+
],
|
796
|
+
yAxis: {
|
1140
797
|
labels: {
|
1141
798
|
format: '{0}',
|
1142
|
-
|
799
|
+
step: 2
|
1143
800
|
},
|
1144
801
|
line: {
|
1145
802
|
visible: false
|
1146
803
|
},
|
1147
|
-
min: 0
|
804
|
+
min: 0
|
1148
805
|
},
|
1149
|
-
|
806
|
+
xAxis: {
|
1150
807
|
majorGridLines: {
|
1151
808
|
visible: false
|
1152
809
|
},
|
@@ -1157,209 +814,71 @@ class NetworkRealtimeChart extends _base_chart__WEBPACK_IMPORTED_MODULE_0__["Bas
|
|
1157
814
|
visible: false
|
1158
815
|
}
|
1159
816
|
},
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
sharedTemplate: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getNetworkSharedTemplate"])(),
|
817
|
+
tooltip: {
|
818
|
+
visible: true,
|
819
|
+
template: Object(_charts_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getBasicTemplate"])('{0}'),
|
1164
820
|
background: '#e4e4e4'
|
1165
821
|
}
|
1166
822
|
}).data('kendoChart');
|
1167
|
-
}
|
1168
|
-
|
1169
|
-
get outgoingColor()
|
1170
|
-
{
|
1171
|
-
return '#CC0000';
|
1172
|
-
}
|
1173
|
-
|
1174
|
-
get incomingColor()
|
1175
|
-
{
|
1176
|
-
return '#009900';
|
1177
|
-
}
|
1178
|
-
|
1179
|
-
addEntry(totalOutKb, totalInKb)
|
1180
|
-
{
|
1181
|
-
let now = new Date()
|
1182
|
-
let time = now.getTime();
|
1183
|
-
|
1184
|
-
// The first value sent by the server is not plotted: it would be a worng value because
|
1185
|
-
// we have to calculate it as the difference between two total values, but we don't have the previous one
|
1186
|
-
if (this._lastTime > 0)
|
1187
|
-
{
|
1188
|
-
let elapsedSecs = (time - this._lastTime) / 1000;
|
1189
|
-
|
1190
|
-
const valueOut = Math.round((totalOutKb - this._lastTotalKbOut) / elapsedSecs);
|
1191
|
-
const valueIn = Math.round((totalInKb - this._lastTotalKbIn) / elapsedSecs);
|
1192
|
-
|
1193
|
-
let newEntry = {
|
1194
|
-
time: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getFormattedDateTime"])(now),
|
1195
|
-
timestamp: time,
|
1196
|
-
outgoing: valueOut,
|
1197
|
-
incoming: valueIn
|
1198
|
-
};
|
1199
|
-
|
1200
|
-
// Add entry to chart
|
1201
|
-
super._addEntry(newEntry);
|
1202
|
-
|
1203
|
-
// Update x axis
|
1204
|
-
if (!this.isPaused)
|
1205
|
-
this._updateElapsedText();
|
1206
|
-
}
|
1207
|
-
|
1208
|
-
this._lastTotalKbOut = totalOutKb;
|
1209
|
-
this._lastTotalKbIn = totalInKb;
|
1210
|
-
this._lastTime = time;
|
1211
|
-
}
|
1212
|
-
|
1213
|
-
_updateElapsedText()
|
1214
|
-
{
|
1215
|
-
let ds = this._dataSource;
|
1216
|
-
|
1217
|
-
if (ds.total() > 1)
|
1218
|
-
{
|
1219
|
-
// Get axis limits
|
1220
|
-
const chartMinimum = ds.at(0).timestamp;
|
1221
|
-
const chartMaximum = ds.at(ds.total() - 1).timestamp;
|
1222
|
-
|
1223
|
-
// Set elapsed text
|
1224
|
-
let title;
|
1225
|
-
let seconds = Math.round( (chartMaximum - chartMinimum) / 1000 );
|
1226
|
-
|
1227
|
-
if (seconds < 60)
|
1228
|
-
title = 'Last ' + (seconds != 1 ? seconds + ' seconds' : 'second');
|
1229
|
-
else
|
1230
|
-
{
|
1231
|
-
const minutes = Math.floor(seconds / 60);
|
1232
|
-
title = 'Last ' + (minutes != 1 ? minutes + ' minutes' : 'minute');
|
1233
|
-
}
|
1234
|
-
|
1235
|
-
this._elapsedTxt.text(title);
|
1236
|
-
}
|
1237
|
-
}
|
1238
|
-
}
|
1239
|
-
|
1240
|
-
// DEFINE COMPONENT
|
1241
|
-
if (!window.customElements.get('network-realtime-chart'))
|
1242
|
-
window.customElements.define('network-realtime-chart', NetworkRealtimeChart);
|
1243
|
-
|
1244
|
-
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery")))
|
1245
|
-
|
1246
|
-
/***/ }),
|
1247
|
-
|
1248
|
-
/***/ "./src/components/charts/system-queue-chart.js":
|
1249
|
-
/*!*****************************************************!*\
|
1250
|
-
!*** ./src/components/charts/system-queue-chart.js ***!
|
1251
|
-
\*****************************************************/
|
1252
|
-
/*! exports provided: SystemQueueChart */
|
1253
|
-
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1254
|
-
|
1255
|
-
"use strict";
|
1256
|
-
__webpack_require__.r(__webpack_exports__);
|
1257
|
-
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SystemQueueChart", function() { return SystemQueueChart; });
|
1258
|
-
/* harmony import */ var _base_chart__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-chart */ "./src/components/charts/base-chart.js");
|
1259
|
-
/* harmony import */ var _chart_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./chart-utils */ "./src/components/charts/chart-utils.js");
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
class SystemQueueChart extends _base_chart__WEBPACK_IMPORTED_MODULE_0__["BaseChart"]
|
1265
|
-
{
|
1266
|
-
constructor()
|
1267
|
-
{
|
1268
|
-
super(240);
|
1269
|
-
|
1270
|
-
this._averageLoad = 0;
|
1271
|
-
}
|
1272
|
-
|
1273
|
-
_initialize()
|
1274
|
-
{
|
1275
|
-
const chartHeight = 240;
|
1276
|
-
|
1277
|
-
// Append container for chart & gauge
|
1278
|
-
let container = $('<div>', {class: 'd-flex flex-row'});
|
1279
|
-
$(this).append(container);
|
1280
|
-
|
1281
|
-
// CHART
|
1282
|
-
|
1283
|
-
let chartContainer = $('<div>', {class: 'flex-grow-1'});
|
1284
|
-
container.append(chartContainer);
|
1285
|
-
|
1286
|
-
// Create chart html
|
1287
|
-
let chartHtml = $('<div>');
|
1288
|
-
chartContainer.append(chartHtml);
|
1289
|
-
|
1290
|
-
// Initialize chart
|
1291
|
-
this._chartWidget = this._initChartWidget(chartHtml, chartHeight);
|
1292
|
-
|
1293
|
-
// Append text to display elapsed time
|
1294
|
-
this._elapsedTxt = $('<div>', {class: 'text-center', text: '---'});
|
1295
|
-
chartContainer.append(this._elapsedTxt);
|
1296
|
-
|
1297
|
-
// GAUGE
|
1298
|
-
|
1299
|
-
let gaugeContainer = $('<div>');
|
1300
|
-
container.append(gaugeContainer);
|
1301
|
-
|
1302
|
-
// Create gauge html
|
1303
|
-
let gaugeHtml = $('<div>');
|
1304
|
-
gaugeContainer.append(gaugeHtml);
|
1305
823
|
|
1306
|
-
|
1307
|
-
this._gaugeWidget = this._initGaugeWidget(gaugeHtml, chartHeight);
|
1308
|
-
|
1309
|
-
// Append text to display load
|
1310
|
-
this._loadTxt = $('<div>', {class: 'text-center font-weight-bold', text: '---'});
|
1311
|
-
gaugeContainer.append(this._loadTxt);
|
1312
|
-
|
1313
|
-
//------------------------------
|
1314
|
-
|
1315
|
-
// Reset data source
|
1316
|
-
this.reset();
|
1317
|
-
}
|
1318
|
-
|
1319
|
-
_initChartWidget(chartHtml, height)
|
1320
|
-
{
|
1321
|
-
return chartHtml.kendoChart({
|
824
|
+
this._getChartDiv('net').kendoChart({
|
1322
825
|
transitions: false,
|
1323
826
|
chartArea: {
|
1324
|
-
height:
|
1325
|
-
background: 'transparent'
|
827
|
+
height: 120,
|
828
|
+
background: 'transparent',
|
829
|
+
margin: 0,
|
830
|
+
padding:0
|
1326
831
|
},
|
1327
832
|
legend: {
|
1328
833
|
visible: false
|
1329
834
|
},
|
835
|
+
title: {
|
836
|
+
text: 'Network',
|
837
|
+
font: '12px sans-serif',
|
838
|
+
color: '#212529'
|
839
|
+
},
|
1330
840
|
seriesDefaults: {
|
1331
|
-
type: '
|
841
|
+
type: 'scatterLine',
|
1332
842
|
labels: {
|
1333
843
|
visible: false,
|
1334
844
|
format: '{0}',
|
1335
845
|
background: 'transparent'
|
1336
|
-
}
|
846
|
+
},
|
847
|
+
missingValues: 'gap',
|
848
|
+
markers: {
|
849
|
+
visible: false,
|
850
|
+
type: 'circle',
|
851
|
+
size: 3,
|
852
|
+
},
|
853
|
+
width: 2
|
1337
854
|
},
|
1338
855
|
series: [
|
1339
856
|
{
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
color: '#
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
857
|
+
xField: 'ts',
|
858
|
+
yField: 'val',
|
859
|
+
name: 'Network Out',
|
860
|
+
color: '#CC0000',
|
861
|
+
},
|
862
|
+
{
|
863
|
+
xField: 'ts',
|
864
|
+
yField: 'val1',
|
865
|
+
name: 'Network In',
|
866
|
+
color: '#009900',
|
867
|
+
}
|
1348
868
|
],
|
1349
|
-
|
1350
|
-
title: {
|
1351
|
-
text: 'Messages'
|
1352
|
-
},
|
869
|
+
yAxis: {
|
1353
870
|
labels: {
|
1354
|
-
format: '{0}'
|
871
|
+
format: '{0}',
|
872
|
+
template: Object(_charts_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getNetworkValueAxisLabelTemplateB"])(),
|
873
|
+
step: 2
|
1355
874
|
},
|
1356
875
|
line: {
|
1357
876
|
visible: false
|
1358
877
|
},
|
1359
878
|
min: 0
|
1360
879
|
},
|
1361
|
-
|
1362
|
-
|
880
|
+
xAxis: {
|
881
|
+
majorGridLines: {
|
1363
882
|
visible: false
|
1364
883
|
},
|
1365
884
|
majorTicks: {
|
@@ -1370,571 +889,186 @@ class SystemQueueChart extends _base_chart__WEBPACK_IMPORTED_MODULE_0__["BaseCha
|
|
1370
889
|
}
|
1371
890
|
},
|
1372
891
|
tooltip: {
|
1373
|
-
|
1374
|
-
|
1375
|
-
sharedTemplate: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getBasicSharedTemplate"])(),
|
892
|
+
visible: true,
|
893
|
+
template: Object(_charts_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getNetworkTemplate"])(),
|
1376
894
|
background: '#e4e4e4'
|
1377
895
|
}
|
1378
896
|
}).data('kendoChart');
|
1379
|
-
}
|
1380
|
-
|
1381
|
-
_initGaugeWidget(gaugeHtml, height)
|
1382
|
-
{
|
1383
|
-
return gaugeHtml.kendoLinearGauge({
|
1384
|
-
pointer: {
|
1385
|
-
value: 0,
|
1386
|
-
shape: 'arrow',
|
1387
|
-
size: 10,
|
1388
|
-
color: '#212529'
|
1389
|
-
},
|
1390
|
-
gaugeArea: {
|
1391
|
-
height: height
|
1392
|
-
},
|
1393
|
-
scale: {
|
1394
|
-
majorUnit: 10,
|
1395
|
-
minorUnit: 1,
|
1396
|
-
min: 0,
|
1397
|
-
max: 100,
|
1398
|
-
ranges: [
|
1399
|
-
{
|
1400
|
-
from: 0,
|
1401
|
-
to: 50,
|
1402
|
-
color: '#00cc00',
|
1403
|
-
opacity: .5
|
1404
|
-
}, {
|
1405
|
-
from: 50,
|
1406
|
-
to: 75,
|
1407
|
-
color: '#ffe106',
|
1408
|
-
opacity: .5
|
1409
|
-
}, {
|
1410
|
-
from: 75,
|
1411
|
-
to: 100,
|
1412
|
-
color: '#ed1601',
|
1413
|
-
opacity: .5
|
1414
|
-
}
|
1415
|
-
],
|
1416
|
-
majorTicks: {
|
1417
|
-
visible: true,
|
1418
|
-
size: 10
|
1419
|
-
},
|
1420
|
-
minorTicks: {
|
1421
|
-
visible: false
|
1422
|
-
},
|
1423
|
-
labels: {
|
1424
|
-
visible: false
|
1425
|
-
},
|
1426
|
-
line: {
|
1427
|
-
visible: false
|
1428
|
-
},
|
1429
|
-
rangeSize: 10
|
1430
|
-
}
|
1431
|
-
}).data('kendoLinearGauge');
|
1432
|
-
}
|
1433
|
-
|
1434
|
-
addEntry(load, queueMsgLimit)
|
1435
|
-
{
|
1436
|
-
// CHART
|
1437
|
-
|
1438
|
-
let now = new Date();
|
1439
|
-
|
1440
|
-
let newEntry = {
|
1441
|
-
time: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getFormattedDateTime"])(now),
|
1442
|
-
timestamp: now.getTime(),
|
1443
|
-
load: load
|
1444
|
-
};
|
1445
|
-
|
1446
|
-
// Add entry to chart
|
1447
|
-
super._addEntry(newEntry);
|
1448
|
-
|
1449
|
-
// Update x axis
|
1450
|
-
if (!this.isPaused)
|
1451
|
-
this._updateElapsedText();
|
1452
897
|
|
1453
|
-
//
|
898
|
+
// Add chart container click listeners
|
899
|
+
$('.chart-container', this.shadowRoot).on('click', $.proxy(this._onChartContainerClick, this));
|
1454
900
|
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
if (numValues > 0)
|
1459
|
-
{
|
1460
|
-
let total = 0;
|
1461
|
-
for (let i = 0; i < numValues; i++)
|
1462
|
-
total += this._dataSource.at(i).load;
|
1463
|
-
|
1464
|
-
this._averageLoad = Math.round(total / numValues);
|
1465
|
-
}
|
1466
|
-
else
|
1467
|
-
this._averageLoad = 0;
|
1468
|
-
|
1469
|
-
const avgLoadPerc = Math.round(this._averageLoad / queueMsgLimit * 1000) / 10;
|
1470
|
-
|
1471
|
-
// Set gauge value
|
1472
|
-
this._gaugeWidget.value(avgLoadPerc);
|
1473
|
-
|
1474
|
-
// Set load text
|
1475
|
-
this._loadTxt.text(avgLoadPerc + '%')
|
1476
|
-
}
|
1477
|
-
|
1478
|
-
_updateElapsedText()
|
1479
|
-
{
|
1480
|
-
let ds = this._dataSource;
|
1481
|
-
|
1482
|
-
if (ds.total() > 1)
|
1483
|
-
{
|
1484
|
-
// Get axis limits
|
1485
|
-
const chartMinimum = ds.at(0).timestamp;
|
1486
|
-
const chartMaximum = ds.at(ds.total() - 1).timestamp;
|
1487
|
-
|
1488
|
-
// Set elapsed text
|
1489
|
-
let seconds = Math.round( (chartMaximum - chartMinimum) / 1000 );
|
1490
|
-
let title;
|
1491
|
-
|
1492
|
-
if (seconds < 60)
|
1493
|
-
title = 'Last ' + (seconds != 1 ? seconds + ' seconds' : 'second');
|
1494
|
-
else
|
1495
|
-
{
|
1496
|
-
const minutes = Math.floor(seconds / 60);
|
1497
|
-
title = 'Last ' + (minutes != 1 ? minutes + ' minutes' : 'minute');
|
1498
|
-
}
|
1499
|
-
|
1500
|
-
this._elapsedTxt.text(title);
|
1501
|
-
}
|
901
|
+
$(window).on('resize', $.proxy(this._onWindowResize, this));
|
902
|
+
this._onWindowResize();
|
1502
903
|
}
|
1503
904
|
|
1504
|
-
|
905
|
+
_onWindowResize()
|
1505
906
|
{
|
1506
|
-
|
907
|
+
this._getChartWidget('ccu').redraw();
|
908
|
+
this._getChartWidget('cpu').redraw();
|
909
|
+
this._getChartWidget('mem').redraw();
|
910
|
+
this._getChartWidget('thd').redraw();
|
911
|
+
this._getChartWidget('net').redraw();
|
1507
912
|
}
|
1508
|
-
}
|
1509
|
-
|
1510
|
-
// DEFINE COMPONENT
|
1511
|
-
if (!window.customElements.get('system-queue-chart'))
|
1512
|
-
window.customElements.define('system-queue-chart', SystemQueueChart);
|
1513
|
-
|
1514
|
-
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery")))
|
1515
|
-
|
1516
|
-
/***/ }),
|
1517
913
|
|
1518
|
-
|
1519
|
-
/*!********************************************************!*\
|
1520
|
-
!*** ./src/components/charts/system-workload-chart.js ***!
|
1521
|
-
\********************************************************/
|
1522
|
-
/*! exports provided: SystemWorkloadChart */
|
1523
|
-
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1524
|
-
|
1525
|
-
"use strict";
|
1526
|
-
__webpack_require__.r(__webpack_exports__);
|
1527
|
-
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SystemWorkloadChart", function() { return SystemWorkloadChart; });
|
1528
|
-
/* harmony import */ var _base_chart__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-chart */ "./src/components/charts/base-chart.js");
|
1529
|
-
/* harmony import */ var _chart_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./chart-utils */ "./src/components/charts/chart-utils.js");
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
class SystemWorkloadChart extends _base_chart__WEBPACK_IMPORTED_MODULE_0__["BaseChart"]
|
1535
|
-
{
|
1536
|
-
constructor()
|
914
|
+
destroy()
|
1537
915
|
{
|
1538
|
-
|
916
|
+
$(window).off('resize');
|
1539
917
|
}
|
1540
918
|
|
1541
|
-
|
919
|
+
addChartEntries(type, data, data1, intervalMillis)
|
1542
920
|
{
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
let
|
1547
|
-
$(this).append(container);
|
1548
|
-
|
1549
|
-
// CHART
|
1550
|
-
|
1551
|
-
let chartContainer = $('<div>', {class: 'flex-grow-1'});
|
1552
|
-
container.append(chartContainer);
|
1553
|
-
|
1554
|
-
// Create chart html
|
1555
|
-
let chartHtml = $('<div>');
|
1556
|
-
chartContainer.append(chartHtml);
|
1557
|
-
|
1558
|
-
// Initialize chart
|
1559
|
-
this._chartWidget = this._initChartWidget(chartHtml, chartHeight);
|
1560
|
-
|
1561
|
-
// Append text to display elapsed time
|
1562
|
-
this._elapsedTxt = $('<div>', {class: 'text-center', text: '---'});
|
1563
|
-
chartContainer.append(this._elapsedTxt);
|
1564
|
-
|
1565
|
-
// GAUGE
|
1566
|
-
|
1567
|
-
let gaugeContainer = $('<div>');
|
1568
|
-
container.append(gaugeContainer);
|
1569
|
-
|
1570
|
-
// Create gauge html
|
1571
|
-
let gaugeHtml = $('<div>');
|
1572
|
-
gaugeContainer.append(gaugeHtml);
|
1573
|
-
|
1574
|
-
// Initialize gauge
|
1575
|
-
this._gaugeWidget = this._initGaugeWidget(gaugeHtml, chartHeight);
|
921
|
+
let lastTimestamp = data.getLong('last');
|
922
|
+
let values = data.getLongArray('data');
|
923
|
+
let values1 = (data1 != null ? data1.getLongArray('data') : null);
|
924
|
+
let chartWidget = this._getChartWidget(type);
|
1576
925
|
|
1577
|
-
|
1578
|
-
this._loadTxt = $('<div>', {class: 'text-center font-weight-bold', text: '---'});
|
1579
|
-
gaugeContainer.append(this._loadTxt);
|
1580
|
-
|
1581
|
-
//------------------------------
|
1582
|
-
|
1583
|
-
// Reset data source
|
1584
|
-
this.reset();
|
926
|
+
this._addChartEntries(chartWidget, values, values1, intervalMillis, lastTimestamp);
|
1585
927
|
}
|
1586
928
|
|
1587
|
-
|
929
|
+
_addChartEntries(chartWidget, values, values1, intervalMillis, lastTimestamp)
|
1588
930
|
{
|
1589
|
-
|
1590
|
-
|
1591
|
-
chartArea: {
|
1592
|
-
height: height,
|
1593
|
-
background: 'transparent'
|
1594
|
-
},
|
1595
|
-
legend: {
|
1596
|
-
visible: false
|
1597
|
-
},
|
1598
|
-
seriesDefaults: {
|
1599
|
-
type: 'area',
|
1600
|
-
labels: {
|
1601
|
-
visible: false,
|
1602
|
-
format: '{0}%',
|
1603
|
-
background: 'transparent'
|
1604
|
-
}
|
1605
|
-
},
|
1606
|
-
series: [
|
1607
|
-
{
|
1608
|
-
name: 'Workload',
|
1609
|
-
field: 'load',
|
1610
|
-
categoryField: 'time',
|
1611
|
-
color: '#3399ff',
|
1612
|
-
line: {
|
1613
|
-
width: 2
|
1614
|
-
}
|
1615
|
-
}
|
1616
|
-
],
|
1617
|
-
valueAxis: {
|
1618
|
-
labels: {
|
1619
|
-
format: '{0}%'
|
1620
|
-
},
|
1621
|
-
line: {
|
1622
|
-
visible: false
|
1623
|
-
},
|
1624
|
-
min: 0,
|
1625
|
-
max: 100
|
1626
|
-
},
|
1627
|
-
categoryAxis: {
|
1628
|
-
majorGridLines: {
|
1629
|
-
visible: false
|
1630
|
-
},
|
1631
|
-
majorTicks: {
|
1632
|
-
visible: false
|
1633
|
-
},
|
1634
|
-
labels: {
|
1635
|
-
visible: false
|
1636
|
-
}
|
1637
|
-
},
|
1638
|
-
tooltip: {
|
1639
|
-
shared: true,
|
1640
|
-
visible: true,
|
1641
|
-
sharedTemplate: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getBasicSharedTemplate"])('{0}%'),
|
1642
|
-
background: '#e4e4e4'
|
1643
|
-
}
|
1644
|
-
}).data('kendoChart');
|
1645
|
-
}
|
931
|
+
// Divide interval by the number of data points to calculate their timestamps
|
932
|
+
let sliceMillis = Math.round(intervalMillis / values.length);
|
1646
933
|
|
1647
|
-
|
1648
|
-
|
1649
|
-
return gaugeHtml.kendoLinearGauge({
|
1650
|
-
pointer: {
|
1651
|
-
value: 0,
|
1652
|
-
shape: 'arrow',
|
1653
|
-
size: 10,
|
1654
|
-
color: '#212529'
|
1655
|
-
},
|
1656
|
-
gaugeArea: {
|
1657
|
-
height: height
|
1658
|
-
},
|
1659
|
-
scale: {
|
1660
|
-
majorUnit: 10,
|
1661
|
-
minorUnit: 1,
|
1662
|
-
max: 100,
|
1663
|
-
min: 0,
|
1664
|
-
ranges: [
|
1665
|
-
{
|
1666
|
-
from: 0,
|
1667
|
-
to: 50,
|
1668
|
-
color: '#00cc00',
|
1669
|
-
opacity: .5
|
1670
|
-
}, {
|
1671
|
-
from: 50,
|
1672
|
-
to: 75,
|
1673
|
-
color: '#ffe106',
|
1674
|
-
opacity: .5
|
1675
|
-
}, {
|
1676
|
-
from: 75,
|
1677
|
-
to: 100,
|
1678
|
-
color: '#ed1601',
|
1679
|
-
opacity: .5
|
1680
|
-
}
|
1681
|
-
],
|
1682
|
-
majorTicks: {
|
1683
|
-
visible: true,
|
1684
|
-
size: 10
|
1685
|
-
},
|
1686
|
-
minorTicks: {
|
1687
|
-
visible: false
|
1688
|
-
},
|
1689
|
-
labels: {
|
1690
|
-
visible: false
|
1691
|
-
},
|
1692
|
-
line: {
|
1693
|
-
visible: false
|
1694
|
-
},
|
1695
|
-
rangeSize: 10
|
1696
|
-
}
|
1697
|
-
}).data('kendoLinearGauge');
|
1698
|
-
}
|
1699
|
-
|
1700
|
-
addEntry(load)
|
1701
|
-
{
|
1702
|
-
// CHART
|
1703
|
-
|
1704
|
-
let now = new Date();
|
1705
|
-
|
1706
|
-
let newEntry = {
|
1707
|
-
time: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getFormattedDateTime"])(now),
|
1708
|
-
timestamp: now.getTime(),
|
1709
|
-
load: load
|
1710
|
-
};
|
1711
|
-
|
1712
|
-
// Add entry to chart
|
1713
|
-
super._addEntry(newEntry);
|
934
|
+
let ds = new kendo.data.DataSource();
|
935
|
+
let firstTimestamp = lastTimestamp - intervalMillis;
|
1714
936
|
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
// GAUGE
|
937
|
+
for (let i = 0; i < values.length; i++)
|
938
|
+
{
|
939
|
+
let timestamp = firstTimestamp + (sliceMillis * i);
|
1720
940
|
|
1721
|
-
|
1722
|
-
|
1723
|
-
let averageLoad = 0;
|
941
|
+
let value = values[i] < 0 ? null : values[i];
|
942
|
+
let value1 = values1 ? (values1[i] < 0 ? null : values1[i]) : null;
|
1724
943
|
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
|
1729
|
-
|
944
|
+
let entry = {
|
945
|
+
ts: timestamp,
|
946
|
+
val: value,
|
947
|
+
val1: value1,
|
948
|
+
};
|
1730
949
|
|
1731
|
-
|
950
|
+
ds.add(entry);
|
1732
951
|
}
|
1733
952
|
|
1734
|
-
// Set
|
1735
|
-
|
953
|
+
// Set chart's x-axis limits
|
954
|
+
chartWidget.options.xAxis.min = firstTimestamp;
|
955
|
+
chartWidget.options.xAxis.max = lastTimestamp;
|
1736
956
|
|
1737
|
-
|
1738
|
-
this._loadTxt.text(averageLoad + '%')
|
957
|
+
chartWidget.setDataSource(ds);
|
1739
958
|
}
|
1740
959
|
|
1741
|
-
|
960
|
+
_getChartDiv(type)
|
1742
961
|
{
|
1743
|
-
|
1744
|
-
|
1745
|
-
if (ds.total() > 1)
|
1746
|
-
{
|
1747
|
-
// Get axis limits
|
1748
|
-
const chartMinimum = ds.at(0).timestamp;
|
1749
|
-
const chartMaximum = ds.at(ds.total() - 1).timestamp;
|
1750
|
-
|
1751
|
-
// Set elapsed text
|
1752
|
-
let seconds = Math.round( (chartMaximum - chartMinimum) / 1000 );
|
1753
|
-
let title;
|
1754
|
-
|
1755
|
-
if (seconds < 60)
|
1756
|
-
title = 'Last ' + (seconds != 1 ? seconds + ' seconds' : 'second');
|
1757
|
-
else
|
1758
|
-
{
|
1759
|
-
const minutes = Math.floor(seconds / 60);
|
1760
|
-
title = 'Last ' + (minutes != 1 ? minutes + ' minutes' : 'minute');
|
1761
|
-
}
|
1762
|
-
|
1763
|
-
this._elapsedTxt.text(title);
|
1764
|
-
}
|
962
|
+
return $('.chart-container[data-type="' + type + '"] .chart', this.shadowRoot);
|
1765
963
|
}
|
1766
964
|
|
1767
|
-
|
965
|
+
_getChartWidget(type)
|
1768
966
|
{
|
1769
|
-
return this.
|
967
|
+
return this._getChartDiv(type).data('kendoChart');
|
1770
968
|
}
|
1771
|
-
}
|
1772
|
-
|
1773
|
-
// DEFINE COMPONENT
|
1774
|
-
if (!window.customElements.get('system-workload-chart'))
|
1775
|
-
window.customElements.define('system-workload-chart', SystemWorkloadChart);
|
1776
969
|
|
1777
|
-
|
1778
|
-
|
1779
|
-
/***/ }),
|
1780
|
-
|
1781
|
-
/***/ "./src/components/charts/thread-count-chart.js":
|
1782
|
-
/*!*****************************************************!*\
|
1783
|
-
!*** ./src/components/charts/thread-count-chart.js ***!
|
1784
|
-
\*****************************************************/
|
1785
|
-
/*! exports provided: ThreadCountChart */
|
1786
|
-
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1787
|
-
|
1788
|
-
"use strict";
|
1789
|
-
__webpack_require__.r(__webpack_exports__);
|
1790
|
-
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ThreadCountChart", function() { return ThreadCountChart; });
|
1791
|
-
/* harmony import */ var _base_chart__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-chart */ "./src/components/charts/base-chart.js");
|
1792
|
-
/* harmony import */ var _chart_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./chart-utils */ "./src/components/charts/chart-utils.js");
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
class ThreadCountChart extends _base_chart__WEBPACK_IMPORTED_MODULE_0__["BaseChart"]
|
1798
|
-
{
|
1799
|
-
constructor()
|
970
|
+
_onChartContainerClick(e)
|
1800
971
|
{
|
1801
|
-
|
1802
|
-
}
|
972
|
+
let chartType = $(e.currentTarget).data('type');
|
1803
973
|
|
1804
|
-
|
1805
|
-
|
1806
|
-
|
1807
|
-
|
1808
|
-
|
1809
|
-
|
1810
|
-
background: 'transparent'
|
974
|
+
// Dispatch custom event
|
975
|
+
let evt = new CustomEvent('chartClick', {
|
976
|
+
detail: {
|
977
|
+
type: chartType,
|
978
|
+
node: this.nId,
|
979
|
+
options: this._getChartWidget(chartType).options
|
1811
980
|
},
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
type: 'area',
|
1817
|
-
labels: {
|
1818
|
-
visible: false,
|
1819
|
-
format: '{0}',
|
1820
|
-
background: 'transparent'
|
1821
|
-
},
|
1822
|
-
},
|
1823
|
-
series: [
|
1824
|
-
{
|
1825
|
-
name: 'Threads',
|
1826
|
-
field: 'threads',
|
1827
|
-
categoryField: 'time',
|
1828
|
-
color: this.threadsColor,
|
1829
|
-
line: {
|
1830
|
-
width: 2
|
1831
|
-
}
|
1832
|
-
}
|
1833
|
-
],
|
1834
|
-
valueAxis: {
|
1835
|
-
min: 0,
|
1836
|
-
labels: {
|
1837
|
-
format: '{0}'
|
1838
|
-
},
|
1839
|
-
line: {
|
1840
|
-
visible: false
|
1841
|
-
},
|
1842
|
-
},
|
1843
|
-
categoryAxis: {
|
1844
|
-
majorGridLines: {
|
1845
|
-
visible: false
|
1846
|
-
},
|
1847
|
-
majorTicks: {
|
1848
|
-
visible: false
|
1849
|
-
},
|
1850
|
-
labels: {
|
1851
|
-
visible: false
|
1852
|
-
}
|
1853
|
-
},
|
1854
|
-
tooltip: {
|
1855
|
-
shared: true,
|
1856
|
-
visible: true,
|
1857
|
-
sharedTemplate: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getBasicSharedTemplate"])(),
|
1858
|
-
background: '#e4e4e4'
|
1859
|
-
}
|
1860
|
-
}).data('kendoChart');
|
1861
|
-
}
|
1862
|
-
|
1863
|
-
get threadsColor()
|
1864
|
-
{
|
1865
|
-
return '#3399FF';
|
1866
|
-
}
|
1867
|
-
|
1868
|
-
addEntry(threads)
|
1869
|
-
{
|
1870
|
-
let newEntry = {
|
1871
|
-
time: Object(_chart_utils__WEBPACK_IMPORTED_MODULE_1__["getFormattedDateTime"])(new Date()),
|
1872
|
-
threads: threads
|
1873
|
-
};
|
981
|
+
bubbles: true,
|
982
|
+
cancelable: false,
|
983
|
+
composed: true // Allows event to bubble outside of Custom Element
|
984
|
+
});
|
1874
985
|
|
1875
|
-
|
1876
|
-
super._addEntry(newEntry);
|
986
|
+
this.dispatchEvent(evt);
|
1877
987
|
}
|
1878
988
|
}
|
1879
989
|
|
1880
990
|
// DEFINE COMPONENT
|
1881
|
-
if (!window.customElements.get('
|
1882
|
-
window.customElements.define('
|
991
|
+
if (!window.customElements.get('node-mini-charts'))
|
992
|
+
window.customElements.define('node-mini-charts', NodeMiniCharts);
|
1883
993
|
|
994
|
+
/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery")))
|
1884
995
|
|
1885
996
|
/***/ }),
|
1886
997
|
|
1887
|
-
/***/ "./src/modules/
|
1888
|
-
|
1889
|
-
!*** ./src/modules/
|
1890
|
-
|
998
|
+
/***/ "./src/modules/cluster-monitor.js":
|
999
|
+
/*!****************************************!*\
|
1000
|
+
!*** ./src/modules/cluster-monitor.js ***!
|
1001
|
+
\****************************************/
|
1891
1002
|
/*! exports provided: default */
|
1892
1003
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
1893
1004
|
|
1894
1005
|
"use strict";
|
1895
1006
|
__webpack_require__.r(__webpack_exports__);
|
1896
|
-
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return
|
1007
|
+
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ClusterMonitor; });
|
1897
1008
|
/* harmony import */ var _base_module__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-module */ "./src/modules/base-module.js");
|
1898
|
-
/* harmony import */ var
|
1899
|
-
/* harmony import */ var
|
1900
|
-
/* harmony import */ var
|
1901
|
-
/* harmony import */ var
|
1902
|
-
/* harmony import */ var _components_charts_memory_chart__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../components/charts/memory-chart */ "./src/components/charts/memory-chart.js");
|
1903
|
-
/* harmony import */ var _components_charts_network_realtime_chart__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../components/charts/network-realtime-chart */ "./src/components/charts/network-realtime-chart.js");
|
1904
|
-
/* harmony import */ var _components_charts_network_24h_chart__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../components/charts/network-24h-chart */ "./src/components/charts/network-24h-chart.js");
|
1905
|
-
/* harmony import */ var _components_charts_system_workload_chart__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../components/charts/system-workload-chart */ "./src/components/charts/system-workload-chart.js");
|
1906
|
-
/* harmony import */ var _components_charts_system_queue_chart__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../components/charts/system-queue-chart */ "./src/components/charts/system-queue-chart.js");
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1009
|
+
/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! moment */ "./node_modules/moment/moment.js");
|
1010
|
+
/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_1__);
|
1011
|
+
/* harmony import */ var _utils_utilities__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/utilities */ "./src/utils/utilities.js");
|
1012
|
+
/* harmony import */ var _components_module_specific_cluster_monitor_node_mini_charts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/module-specific/cluster-monitor/node-mini-charts */ "./src/components/module-specific/cluster-monitor/node-mini-charts.js");
|
1913
1013
|
|
1914
1014
|
|
1915
1015
|
|
1916
1016
|
|
1917
1017
|
|
1918
|
-
class
|
1018
|
+
class ClusterMonitor extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModule"]
|
1919
1019
|
{
|
1920
1020
|
constructor()
|
1921
1021
|
{
|
1922
|
-
super('
|
1022
|
+
super('clusterMon');
|
1023
|
+
|
1024
|
+
this.MAX_LOG_SIZE = 100;
|
1923
1025
|
|
1924
1026
|
// Outgoing requests
|
1925
|
-
this.
|
1926
|
-
this.
|
1927
|
-
this.
|
1027
|
+
this.REQ_GET_NODES = 'getNodes';
|
1028
|
+
this.REQ_DEACTIVATE_NODES = 'deact';
|
1029
|
+
this.REQ_GET_NODES_DATA = 'getDataN';
|
1030
|
+
this.REQ_GET_CHART_DATA = 'getDataC';
|
1031
|
+
this.REQ_SCALE_UP = 'scaleUp';
|
1032
|
+
this.REQ_GET_LOG_MESSAGES = 'getLog';
|
1033
|
+
|
1034
|
+
// Incoming responses
|
1035
|
+
this.RESP_NODES = 'nodes';
|
1036
|
+
this.RESP_NODES_DATA = 'dataN';
|
1037
|
+
this.RESP_CHART_DATA = 'dataC';
|
1038
|
+
this.RESP_LOG_MESSAGES = 'log';
|
1039
|
+
|
1040
|
+
this.intervals = [
|
1041
|
+
{
|
1042
|
+
label: 'Last hour',
|
1043
|
+
minutes: 60,
|
1044
|
+
points1: 30,
|
1045
|
+
points2: 30,
|
1046
|
+
},
|
1047
|
+
{
|
1048
|
+
label: 'Last 3 hours',
|
1049
|
+
minutes: 180,
|
1050
|
+
points1: 30,
|
1051
|
+
points2: 90,
|
1052
|
+
},
|
1053
|
+
{
|
1054
|
+
label: 'Last 12 hours',
|
1055
|
+
minutes: 720,
|
1056
|
+
points1: 30,
|
1057
|
+
points2: 180,
|
1058
|
+
},
|
1059
|
+
{
|
1060
|
+
label: 'Last 24 hours',
|
1061
|
+
minutes: 1440,
|
1062
|
+
points1: 30,
|
1063
|
+
points2: 360,
|
1064
|
+
},
|
1065
|
+
]
|
1928
1066
|
|
1929
|
-
|
1930
|
-
this.
|
1931
|
-
this.
|
1932
|
-
this.
|
1933
|
-
|
1934
|
-
this._tcpOutThreads = 0;
|
1935
|
-
this._tcpOutLoad = 0;
|
1936
|
-
this._udpOutThreads = 0;
|
1937
|
-
this._udpOutLoad = 0;
|
1067
|
+
this._selectedNodes = [];
|
1068
|
+
this._selectedActiveNodes = [];
|
1069
|
+
this._chartedNodes = [];
|
1070
|
+
this._chartInfo = null;
|
1071
|
+
this._lastLogsReqTimestamp = 0;
|
1938
1072
|
}
|
1939
1073
|
|
1940
1074
|
//------------------------------------
|
@@ -1949,7 +1083,7 @@ class Dashboard extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModule"]
|
|
1949
1083
|
super.initialize(idData, shellController);
|
1950
1084
|
|
1951
1085
|
// Initialize scrolling tabs
|
1952
|
-
$('#
|
1086
|
+
$('#clm-tabNavigator > #tabs').scrollingTabs({
|
1953
1087
|
bootstrapVersion: 4,
|
1954
1088
|
scrollToTabEdge: true,
|
1955
1089
|
enableSwiping: true,
|
@@ -1958,135 +1092,266 @@ class Dashboard extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModule"]
|
|
1958
1092
|
cssClassRightArrow: 'fa fa-chevron-right'
|
1959
1093
|
});
|
1960
1094
|
|
1961
|
-
// Initialize
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1095
|
+
// Initialize buttons
|
1096
|
+
$('#clm-deactivateBt').on('click', $.proxy(this._onDeactivateBtClick, this));
|
1097
|
+
$('#clm-scaleUpBt').on('click', $.proxy(this._onScaleUpBtClick, this));
|
1098
|
+
$('#clm-scaleUpModalBt').on('click', $.proxy(this._onScaleUpConfirmBtClick, this));
|
1099
|
+
$('#clm-refreshBt').on('click', $.proxy(this._requestNodesList, this));
|
1966
1100
|
|
1967
|
-
// Initialize
|
1968
|
-
this.
|
1969
|
-
dataSource: this._getThreadsGridDataSource(),
|
1101
|
+
// Initialize grid
|
1102
|
+
this._grid = $('#clm-nodesList').kendoGrid({
|
1970
1103
|
scrollable: true,
|
1971
1104
|
sortable: true,
|
1972
|
-
|
1973
|
-
resizable: true,
|
1105
|
+
//resizable: true,
|
1974
1106
|
selectable: false,
|
1975
|
-
|
1107
|
+
columns: [
|
1976
1108
|
{
|
1977
|
-
|
1978
|
-
|
1979
|
-
width: 60
|
1109
|
+
selectable: true,
|
1110
|
+
width: 41
|
1980
1111
|
},
|
1981
1112
|
{
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1113
|
+
field: 'name',
|
1114
|
+
width: 250,
|
1115
|
+
title: 'Node',
|
1116
|
+
template: function(dataItem) {
|
1117
|
+
if (dataItem['alias'])
|
1118
|
+
return '<div class="name-cell"><span>' + dataItem['alias'] + '</span> <a href="http://' + dataItem['name'] + ':8080/admin" class="name-admin-link" target="_blank"><i class="fas fa-toolbox"></i></a><br><small class="text-muted">' + dataItem['name'] + '<small></div>';
|
1119
|
+
else
|
1120
|
+
return '<div class="name-cell"><span>' + dataItem['name'] + '</span> <a href="http://' + dataItem['name'] + ':8080/admin" class="name-admin-link" target="_blank"><i class="fas fa-toolbox"></i></a></div>';
|
1121
|
+
}
|
1122
|
+
},
|
1123
|
+
{
|
1124
|
+
field: 'ccu',
|
1125
|
+
width: 80,
|
1126
|
+
title: 'CCU',
|
1127
|
+
},
|
1128
|
+
{
|
1129
|
+
field: 'cpu',
|
1130
|
+
width: 80,
|
1131
|
+
title: 'CPU',
|
1132
|
+
template: function(dataItem) {
|
1133
|
+
return Object(_utils_utilities__WEBPACK_IMPORTED_MODULE_2__["roundToDecimals"])(dataItem['cpu'], 2) + '%';
|
1134
|
+
}
|
1135
|
+
},
|
1986
1136
|
{
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
|
1991
|
-
|
1137
|
+
title: 'Memory',
|
1138
|
+
columns: [
|
1139
|
+
{
|
1140
|
+
field: 'usedMem',
|
1141
|
+
width: 100,
|
1142
|
+
title: 'Used',
|
1143
|
+
template: function(dataItem) {
|
1144
|
+
return Object(_utils_utilities__WEBPACK_IMPORTED_MODULE_2__["bytesToSize"])(dataItem['usedMem']);
|
1145
|
+
}
|
1146
|
+
},
|
1147
|
+
{
|
1148
|
+
field: 'allocMem',
|
1149
|
+
width: 100,
|
1150
|
+
title: 'Allocated',
|
1151
|
+
template: function(dataItem) {
|
1152
|
+
return Object(_utils_utilities__WEBPACK_IMPORTED_MODULE_2__["bytesToSize"])(dataItem['allocMem']);
|
1153
|
+
}
|
1154
|
+
}
|
1155
|
+
]
|
1156
|
+
},
|
1157
|
+
{
|
1158
|
+
title: 'Network',
|
1159
|
+
columns: [
|
1160
|
+
{
|
1161
|
+
field: 'netIn',
|
1162
|
+
width: 100,
|
1163
|
+
title: 'In',
|
1164
|
+
template: function(dataItem) {
|
1165
|
+
return (dataItem['netIn'] > -1 ? Object(_utils_utilities__WEBPACK_IMPORTED_MODULE_2__["bytesToSize"])(dataItem['netIn'], 2, 'KB', '/s') : '–');
|
1166
|
+
}
|
1167
|
+
},
|
1168
|
+
{
|
1169
|
+
field: 'netOut',
|
1170
|
+
width: 100,
|
1171
|
+
title: 'Out',
|
1172
|
+
template: function(dataItem) {
|
1173
|
+
return (dataItem['netOut'] > -1 ? Object(_utils_utilities__WEBPACK_IMPORTED_MODULE_2__["bytesToSize"])(dataItem['netOut'], 2, 'KB', '/s') : '–');
|
1174
|
+
}
|
1175
|
+
}
|
1176
|
+
]
|
1177
|
+
},
|
1178
|
+
{
|
1179
|
+
field: 'threads',
|
1180
|
+
width: 100,
|
1181
|
+
title: 'Threads',
|
1182
|
+
},
|
1183
|
+
{
|
1184
|
+
field: 'rooms',
|
1185
|
+
width: 100,
|
1186
|
+
title: 'Rooms',
|
1187
|
+
},
|
1188
|
+
{
|
1189
|
+
field: 'joinTime',
|
1190
|
+
width: 100,
|
1191
|
+
title: 'Joined',
|
1192
|
+
sortable: false,
|
1193
|
+
template: $.proxy(this._getTimeSinceJoinTemplate, this)
|
1194
|
+
},
|
1195
|
+
{
|
1196
|
+
field: 'health',
|
1197
|
+
width: 75,
|
1198
|
+
title: 'Health',
|
1199
|
+
sortable: false,
|
1200
|
+
template: $.proxy(this._getHealthTemplate, this)
|
1201
|
+
},
|
1202
|
+
{
|
1203
|
+
field: 'recyclable',
|
1204
|
+
width: 45,
|
1205
|
+
title: 'R.',
|
1206
|
+
sortable: false,
|
1207
|
+
template: $.proxy(this._getRecyclableTemplate, this)
|
1208
|
+
},
|
1209
|
+
{
|
1210
|
+
field: 'terminable',
|
1211
|
+
width: 45,
|
1212
|
+
title: 'T.',
|
1213
|
+
sortable: false,
|
1214
|
+
template: $.proxy(this._getTerminableTemplate, this)
|
1215
|
+
},
|
1992
1216
|
],
|
1993
1217
|
noRecords: {
|
1994
|
-
template: 'No
|
1218
|
+
template: 'No game nodes.'
|
1995
1219
|
},
|
1996
|
-
|
1997
|
-
|
1220
|
+
dataSource: {
|
1221
|
+
schema: {
|
1222
|
+
model: {
|
1223
|
+
id: 'id',
|
1224
|
+
// fields: {
|
1225
|
+
// id: { type: 'string' },
|
1226
|
+
// active: { type: 'boolean' }
|
1227
|
+
// }
|
1228
|
+
}
|
1229
|
+
},
|
1230
|
+
group: {
|
1231
|
+
field: 'active',
|
1232
|
+
dir: 'desc',
|
1233
|
+
}
|
1234
|
+
},
|
1235
|
+
change: $.proxy(this._onNodesGridChange, this),
|
1236
|
+
dataBound: $.proxy(this._onNodesGridDataBound, this),
|
1237
|
+
}).data('kendoGrid');
|
1998
1238
|
|
1999
|
-
// Add
|
2000
|
-
$('#
|
1239
|
+
// Add listener to mini charts container
|
1240
|
+
$('#clm-nodeMiniChartsContainer').on('chartClick', $.proxy(this._onMiniChartClick, this));
|
2001
1241
|
|
2002
|
-
// Configure
|
2003
|
-
$('#
|
1242
|
+
// Configure detail chart modal
|
1243
|
+
$('#clm-chartModal').modal({
|
2004
1244
|
backdrop: 'static',
|
2005
1245
|
keyboard: false,
|
2006
1246
|
show: false,
|
2007
1247
|
});
|
2008
1248
|
|
2009
|
-
// Add listener for
|
2010
|
-
$('#
|
1249
|
+
// Add event listener for modal hidden event
|
1250
|
+
$('#clm-chartModal').on('hidden.bs.modal', $.proxy(this._onChartModalHidden, this));
|
1251
|
+
|
1252
|
+
// Initialize data interval dropdowns
|
1253
|
+
let items = [];
|
1254
|
+
for (let i = 0; i < this.intervals.length; i++)
|
1255
|
+
items.push({label:this.intervals[i].label, value:i});
|
1256
|
+
|
1257
|
+
this._mainRangeDD = $('#clm-mainRangeDD').kendoDropDownList({
|
1258
|
+
dataTextField: 'label',
|
1259
|
+
dataValueField: 'value',
|
1260
|
+
dataSource: items,
|
1261
|
+
index: 0,
|
1262
|
+
//valueTemplate: '<span class="text-muted pr-1">Last </span><span>#:data.text#</span>',
|
1263
|
+
change: $.proxy(this._onMainRangeChange, this)
|
1264
|
+
}).data('kendoDropDownList');
|
2011
1265
|
|
2012
|
-
|
2013
|
-
$('#dsh-copyThreadDumpBt').on('click', $.proxy(this._onCopyThreadDumpClick, this));
|
1266
|
+
$('#clm-mainRangeContainer').hide();
|
2014
1267
|
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2021
|
-
change: $.proxy(this.
|
2022
|
-
|
2023
|
-
|
1268
|
+
this._chartRangeDD = $('#clm-chartRangeDD').kendoDropDownList({
|
1269
|
+
dataTextField: 'label',
|
1270
|
+
dataValueField: 'value',
|
1271
|
+
dataSource: items,
|
1272
|
+
index: 0,
|
1273
|
+
//valueTemplate: '<span class="text-muted pr-1">Last </span><span>#:data.text#</span>',
|
1274
|
+
change: $.proxy(this._onChartRangeChange, this)
|
1275
|
+
}).data('kendoDropDownList');
|
1276
|
+
|
1277
|
+
// Initialize lobby state info
|
1278
|
+
$('#clm-lobbyState').hide();
|
1279
|
+
|
1280
|
+
// Configure scale-up modal
|
1281
|
+
$('#clm-scaleUpModal').modal({
|
1282
|
+
backdrop: 'static',
|
1283
|
+
keyboard: false,
|
1284
|
+
show: false,
|
1285
|
+
});
|
1286
|
+
|
1287
|
+
// Init nodes' number numeric stepper in scale-up modal
|
1288
|
+
this._numNodesIn = $('#clm-numNodesNS').kendoNumericTextBox({
|
1289
|
+
min: 1,
|
1290
|
+
max: 5,
|
1291
|
+
step: 1,
|
1292
|
+
format: '#'
|
1293
|
+
}).data('kendoNumericTextBox');
|
1294
|
+
|
1295
|
+
// Initialize kendo validation on scale-up form
|
1296
|
+
this._scaleUpValidator = $('#clm-scaleUpForm').kendoValidator({}).data('kendoValidator');
|
1297
|
+
|
1298
|
+
// Add listener for scale-up panel hide
|
1299
|
+
$('#clm-scaleUpModal').on('hidden.bs.modal', $.proxy(this._onScaleUpModalHidden, this));
|
1300
|
+
|
1301
|
+
// Initialize orchestration log grid
|
1302
|
+
this._logGrid = $('#clm-logGrid').kendoGrid({
|
1303
|
+
dataSource: [],
|
1304
|
+
resizable: true,
|
1305
|
+
selectable: false,
|
1306
|
+
noRecords: {
|
1307
|
+
template: 'No entries.'
|
2024
1308
|
},
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2047
|
-
|
2048
|
-
// Set colors in chart legends
|
2049
|
-
$('#dsh-systemLoadColor').css('color', this._cpuUsageChart.systemColor);
|
2050
|
-
$('#dsh-processLoadColor').css('color', this._cpuUsageChart.processColor);
|
2051
|
-
$('#dsh-allocMemColor').css('color', this._memoryChart.allocatedColor);
|
2052
|
-
$('#dsh-usedMemColor').css('color', this._memoryChart.usedColor);
|
2053
|
-
$('#dsh-incomingNetColor').css('color', this._networkRTChart.incomingColor);
|
2054
|
-
$('#dsh-outgoingNetColor').css('color', this._networkRTChart.outgoingColor);
|
2055
|
-
|
2056
|
-
// Reset time range on 24h network chart
|
2057
|
-
this._onTimeRangeChange();
|
2058
|
-
|
2059
|
-
// Add listener to redraw all charts on main tab change
|
2060
|
-
// (to work around an issue with the chart resizing to default width when pane is hidden)
|
2061
|
-
$('a[data-toggle="tab"]').on('shown.bs.tab', $.proxy(this._onWindowResize, this));
|
2062
|
-
|
2063
|
-
// Add listener to redraw network charts on network tab change
|
2064
|
-
// (to work around an issue with the chart resizing to default width when pane is hidden)
|
2065
|
-
$('#dsh-networkPills a[data-toggle="pill"]').on('shown.bs.tab', $.proxy(this._redrawNetworkCharts, this));
|
2066
|
-
|
2067
|
-
// Add listener to redraw outgoing messages queue charts on tab change
|
2068
|
-
// (to work around an issue with the chart resizing to default width when pane is hidden)
|
2069
|
-
$('#dsh-msgQueuePills a[data-toggle="pill"]').on('shown.bs.tab', $.proxy(this._redrawOutMsgCharts, this));
|
2070
|
-
|
2071
|
-
// Add listener to redraw all charts in case of window resize
|
2072
|
-
$(window).on('resize', $.proxy(this._onWindowResize, this));
|
2073
|
-
this._onWindowResize(); // Also do it immediately
|
1309
|
+
columns: [
|
1310
|
+
{
|
1311
|
+
field: 'timestamp',
|
1312
|
+
title: 'Timestamp',
|
1313
|
+
width: 180
|
1314
|
+
},
|
1315
|
+
{
|
1316
|
+
field: 'level',
|
1317
|
+
title: 'Level',
|
1318
|
+
width: 100
|
1319
|
+
},
|
1320
|
+
{
|
1321
|
+
field: 'message',
|
1322
|
+
title: 'Message',
|
1323
|
+
width: 400
|
1324
|
+
},
|
1325
|
+
],
|
1326
|
+
dataBound: function() {
|
1327
|
+
this.content.scrollTop(this.tbody.height()); // Scroll to bottom
|
1328
|
+
}
|
1329
|
+
}).data('kendoGrid');
|
1330
|
+
|
1331
|
+
$('#clm_maxLogMsgs').text(this.MAX_LOG_SIZE);
|
2074
1332
|
|
2075
|
-
//
|
2076
|
-
$(
|
1333
|
+
// Initialize help tooltips
|
1334
|
+
$(this).kendoTooltip({
|
2077
1335
|
filter: 'i[title].help',
|
2078
1336
|
position: 'right',
|
2079
|
-
width: '250px',
|
2080
1337
|
content: function(e) {
|
2081
1338
|
return `<div class="help-tooltip">${e.target.data('title')}</div>`;
|
2082
1339
|
}
|
2083
1340
|
});
|
2084
1341
|
|
2085
|
-
|
2086
|
-
$('#dsh-useHttpsCheck').on('change', $.proxy(this._onUseHttpsForWsManagerChange, this));
|
1342
|
+
//-------------------------------------------------------
|
2087
1343
|
|
2088
|
-
//
|
2089
|
-
this.
|
1344
|
+
// Request nodes list to server
|
1345
|
+
this._requestNodesList();
|
1346
|
+
|
1347
|
+
// Schedule continuous data request for the selected nodes
|
1348
|
+
this._requestDataTimer = setInterval($.proxy(this._onRequestDataInterval, this), 60000); // 1 minute
|
1349
|
+
|
1350
|
+
// Request orchestration logs to server
|
1351
|
+
this._requestOrchestrationLogs();
|
1352
|
+
|
1353
|
+
// Schedule continuous orchestration logs request
|
1354
|
+
this._requestLogsTimer = setInterval($.proxy(this._requestOrchestrationLogs, this), 3000); // 3 seconds
|
2090
1355
|
}
|
2091
1356
|
|
2092
1357
|
destroy()
|
@@ -2095,224 +1360,207 @@ class Dashboard extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModule"]
|
|
2095
1360
|
super.destroy();
|
2096
1361
|
|
2097
1362
|
// Destroy scrolling tabs
|
2098
|
-
$('#
|
2099
|
-
|
2100
|
-
// Remove other listeners
|
2101
|
-
$('#dsh-resetBt').off('click');
|
2102
|
-
$('#dsh-pauseBt').off('click');
|
2103
|
-
$('#dsh-playBt').off('click');
|
2104
|
-
$('#dsh-dumpThreadsBt').off('click');
|
2105
|
-
$('a[data-toggle="tab"]').off('shown.bs.tab');
|
2106
|
-
$('a[data-toggle="pill"]').off('shown.bs.tab');
|
2107
|
-
$(window).off('resize');
|
2108
|
-
$('#dsh-useHttpsCheck').off('change');
|
1363
|
+
$('#clm-tabNavigator #tabs').scrollingTabs('destroy');
|
2109
1364
|
|
2110
|
-
//
|
2111
|
-
$('#
|
1365
|
+
// Hide modals
|
1366
|
+
$('#clm-chartModal').modal('hide');
|
1367
|
+
$('#clm-scaleUpModal').modal('hide');
|
2112
1368
|
|
2113
|
-
//
|
2114
|
-
|
1369
|
+
// Remove click listeners
|
1370
|
+
$('#clm-refreshBt').off('click');
|
1371
|
+
$('#clm-scaleUpBt').off('click');
|
1372
|
+
$('#clm-scaleUpModalBt').off('click');
|
1373
|
+
$('#clm-nodeMiniChartsContainer').off('chartClick');
|
1374
|
+
|
1375
|
+
// Remove scale-up panel listener
|
1376
|
+
$('#clm-scaleUpModal').off('hidden.bs.modal');
|
1377
|
+
|
1378
|
+
// Clear nodes, data and logs request scheduling
|
1379
|
+
clearTimeout(this._requestNodesTimer);
|
1380
|
+
clearInterval(this._requestDataTimer);
|
1381
|
+
clearInterval(this._requestLogsTimer);
|
2115
1382
|
}
|
2116
1383
|
|
2117
1384
|
onExtensionCommand(command, data)
|
2118
1385
|
{
|
2119
|
-
|
2120
|
-
if (command == this.RESP_INIT)
|
2121
|
-
{
|
2122
|
-
// Server sends flags indicating if web server's internal manager is accessible and how
|
2123
|
-
this._wsManagerConfig = {
|
2124
|
-
hasAccess: data.getBool('hasWsManager'),
|
2125
|
-
httpEnabled: data.getBool('httpEnabled'),
|
2126
|
-
httpsEnabled: data.getBool('httpsEnabled'),
|
2127
|
-
httpPort: data.getInt('httpPort'),
|
2128
|
-
httpsPort: data.getInt('httpsPort'),
|
2129
|
-
}
|
2130
|
-
|
2131
|
-
// Enable access to web server manager console
|
2132
|
-
this._enableWebServerManagerAccess();
|
2133
|
-
|
2134
|
-
// Request data to server
|
2135
|
-
this._requestData(true);
|
2136
|
-
}
|
2137
|
-
|
2138
|
-
// Data received
|
2139
|
-
else if (command == this.RESP_DATA)
|
1386
|
+
if (command == this.RESP_NODES)
|
2140
1387
|
{
|
2141
|
-
|
1388
|
+
let nodesObj = data.getSFSArray('nodes');
|
2142
1389
|
|
2143
|
-
|
2144
|
-
|
2145
|
-
$('#dsh-processLoadLabel').text(data.getDouble('pCpu'));
|
1390
|
+
let nodes = [];
|
1391
|
+
let nodesIds = [];
|
2146
1392
|
|
2147
|
-
|
2148
|
-
|
2149
|
-
|
1393
|
+
for (let i = 0; i < nodesObj.size(); i++)
|
1394
|
+
{
|
1395
|
+
let node = nodesObj.getSFSArray(i);
|
1396
|
+
|
1397
|
+
nodesIds.push(node.getUtfString(0));
|
1398
|
+
|
1399
|
+
nodes.push({
|
1400
|
+
'id': node.getUtfString(0),
|
1401
|
+
'alias': node.getUtfString(1), // Set in node configuration, but can't be edited - could be removed
|
1402
|
+
'name': node.getUtfString(2), // IP address or domain name
|
1403
|
+
'rooms': node.getInt(3),
|
1404
|
+
'ccu': node.getInt(4),
|
1405
|
+
'threads': node.getInt(5),
|
1406
|
+
'cpu': node.getDouble(6),
|
1407
|
+
'usedMem': node.getLong(7),
|
1408
|
+
'allocMem': node.getLong(8),
|
1409
|
+
'netIn': node.getLong(9),
|
1410
|
+
'netOut': node.getLong(10),
|
1411
|
+
'joinTime': node.getLong(11),
|
1412
|
+
'health': node.getBool(12),
|
1413
|
+
'active': node.getBool(13), // Used for grouping
|
1414
|
+
'recyclable': node.getBool(14),
|
1415
|
+
'terminable': node.getBool(15),
|
1416
|
+
});
|
1417
|
+
}
|
2150
1418
|
|
2151
|
-
//
|
1419
|
+
// Get nodes grid datasource
|
1420
|
+
let ds = this._grid.dataSource;
|
2152
1421
|
|
2153
|
-
|
2154
|
-
this._threadCountChart.addEntry(threadCount);
|
2155
|
-
$('#dsh-threadsCountLabel').text(threadCount);
|
1422
|
+
// --- REMOVE NODES ---
|
2156
1423
|
|
2157
|
-
|
2158
|
-
|
1424
|
+
let self = this;
|
1425
|
+
$.map(ds.data(), function (dataItem, index) {
|
1426
|
+
if (dataItem && !nodesIds.includes(dataItem['id']))
|
1427
|
+
{
|
1428
|
+
// Remove node from datastore
|
1429
|
+
ds.remove(dataItem);
|
2159
1430
|
|
2160
|
-
|
2161
|
-
|
2162
|
-
|
2163
|
-
|
1431
|
+
// Remove node from list of selected nodes (if selected)
|
1432
|
+
self._selectedNodes = self._selectedNodes.filter(x => x !== dataItem['id']);
|
1433
|
+
self._selectedActiveNodes = self._selectedActiveNodes.filter(x => x !== dataItem['id']);
|
1434
|
+
}
|
1435
|
+
});
|
2164
1436
|
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
1437
|
+
// Update nodes charts view and nodes deactivate button, in case a selected node was removed
|
1438
|
+
this._updateChartedNodes();
|
1439
|
+
this._updateDeactivateButton();
|
2168
1440
|
|
2169
|
-
//
|
1441
|
+
// --- ADD/UPDATE NODES ---
|
2170
1442
|
|
2171
|
-
|
2172
|
-
let threads = [];
|
1443
|
+
let activeNodesCnt = 0;
|
2173
1444
|
|
2174
|
-
for (let
|
1445
|
+
for (let node of nodes)
|
2175
1446
|
{
|
2176
|
-
|
2177
|
-
|
2178
|
-
threads.push({
|
2179
|
-
id: threadData.getLong('id'),
|
2180
|
-
name: threadData.getUtfString('name'),
|
2181
|
-
cpuTime: Math.round(threadData.getLong('cpu') / totalThreadCpuTime * 1000) / 10
|
2182
|
-
});
|
2183
|
-
}
|
1447
|
+
var dataItem = ds.get(node.id);
|
2184
1448
|
|
2185
|
-
|
2186
|
-
|
2187
|
-
|
2188
|
-
|
2189
|
-
|
2190
|
-
|
1449
|
+
// Update node
|
1450
|
+
if (dataItem)
|
1451
|
+
{
|
1452
|
+
dataItem.set('rooms', node.rooms);
|
1453
|
+
dataItem.set('ccu', node.ccu);
|
1454
|
+
dataItem.set('threads', node.threads);
|
1455
|
+
dataItem.set('cpu', node.cpu);
|
1456
|
+
dataItem.set('usedMem', node.usedMem);
|
1457
|
+
dataItem.set('allocMem', node.allocMem);
|
1458
|
+
dataItem.set('netIn', node.netIn);
|
1459
|
+
dataItem.set('netOut', node.netOut);
|
1460
|
+
dataItem.set('joinTime', node.joinTime);
|
1461
|
+
dataItem.set('health', node.health);
|
1462
|
+
dataItem.set('active', node.active);
|
1463
|
+
dataItem.set('recyclable', node.recyclable);
|
1464
|
+
dataItem.set('terminable', node.terminable);
|
1465
|
+
|
1466
|
+
dataItem.dirty = false; // Hides "dirty" indicator in grid
|
1467
|
+
}
|
2191
1468
|
|
2192
|
-
|
2193
|
-
|
2194
|
-
|
2195
|
-
const incomingData = data.getLongArray('ntInHistory');
|
2196
|
-
const samplingRateMins = data.getInt('ntRate');
|
2197
|
-
const shiftSeconds = data.getInt('ntShift');
|
1469
|
+
// Add node
|
1470
|
+
else
|
1471
|
+
ds.add(node);
|
2198
1472
|
|
2199
|
-
|
1473
|
+
// Count active nodes
|
1474
|
+
if (node.active)
|
1475
|
+
activeNodesCnt++;
|
2200
1476
|
}
|
2201
1477
|
|
2202
|
-
//
|
2203
|
-
this.
|
2204
|
-
this._networkRTChart.addEntry(data.getLong('ntOut'), data.getLong('ntIn'));
|
1478
|
+
// Refresh grid
|
1479
|
+
this._grid.refresh();
|
2205
1480
|
|
2206
|
-
//
|
1481
|
+
// Display global values
|
1482
|
+
$('#clm-totalActiveNodes').text(activeNodesCnt);
|
1483
|
+
$('#clm-totalInactiveNodes').text(nodes.length - activeNodesCnt);
|
1484
|
+
$('#clm-totalCcuLobby').text(data.getInt('ccuLobby'));
|
1485
|
+
$('#clm-totalCcuNodes').text(data.getInt('ccuNodes'));
|
1486
|
+
$('#clm-totalRooms').text(data.getInt('rooms'));
|
2207
1487
|
|
2208
|
-
//
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2212
|
-
|
1488
|
+
// Show lobby state
|
1489
|
+
this._showLobbyState(data.getBool('active'));
|
1490
|
+
}
|
1491
|
+
|
1492
|
+
else if (command == this.RESP_NODES_DATA)
|
1493
|
+
{
|
1494
|
+
let stats = data.getSFSArray('stats');
|
1495
|
+
let i = this._mainRangeDD.value();
|
1496
|
+
let intervalMillis = this.intervals[i].minutes * 60 * 1000;
|
2213
1497
|
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
2217
|
-
$('#dsh-detUsersSocket').text('Socket: ' + data.getInt('uSocket'));
|
2218
|
-
$('#dsh-detUsersHttp').text('Http: ' + data.getInt('uHttp'));
|
2219
|
-
$('#dsh-detUsersNpc').text('Npc: ' + data.getInt('uNpc'));
|
1498
|
+
for (let i = 0; i < stats.size(); i++)
|
1499
|
+
{
|
1500
|
+
let nodeStats = stats.getSFSObject(i);
|
2220
1501
|
|
2221
|
-
|
2222
|
-
|
2223
|
-
$('#dsh-detRoomsRegular').text('Regular: ' + (data.getInt('rTotal') - data.getInt('rGame')));
|
2224
|
-
$('#dsh-detRoomsGame').text('Game: ' + data.getInt('rGame'));
|
1502
|
+
// Get node id
|
1503
|
+
let id = nodeStats.getUtfString('id');
|
2225
1504
|
|
2226
|
-
|
2227
|
-
|
2228
|
-
$('#dsh-detDataTransferIn').text('In: ' + Object(_utils_utilities__WEBPACK_IMPORTED_MODULE_1__["kBytesToSize"])(data.getLong('ntIn')));
|
1505
|
+
// Get charts item for node
|
1506
|
+
let item = this.querySelector('#clm-nodeMiniChartsContainer #node_' + id);
|
2229
1507
|
|
2230
|
-
|
2231
|
-
|
1508
|
+
if (item)
|
1509
|
+
{
|
1510
|
+
item.addChartEntries('ccu', nodeStats.getSFSObject('ccu'), null, intervalMillis);
|
1511
|
+
item.addChartEntries('cpu', nodeStats.getSFSObject('cpu'), null, intervalMillis);
|
1512
|
+
item.addChartEntries('mem', nodeStats.getSFSObject('mem'), null, intervalMillis);
|
1513
|
+
item.addChartEntries('thd', nodeStats.getSFSObject('thd'), null, intervalMillis);
|
1514
|
+
item.addChartEntries('net', nodeStats.getSFSObject('netOut'), nodeStats.getSFSObject('netIn'), intervalMillis);
|
1515
|
+
}
|
1516
|
+
}
|
1517
|
+
}
|
2232
1518
|
|
2233
|
-
|
2234
|
-
|
1519
|
+
else if (command == this.RESP_CHART_DATA)
|
1520
|
+
{
|
1521
|
+
let chartData = data.getSFSObject('chart');
|
1522
|
+
let i = this._chartRangeDD.value();
|
1523
|
+
let intervalMillis = this.intervals[i].minutes * 60 * 1000;
|
2235
1524
|
|
2236
|
-
|
2237
|
-
|
1525
|
+
// Get node id and chart type
|
1526
|
+
let id = chartData.getUtfString('id');
|
1527
|
+
let type = chartData.getUtfString('type');
|
2238
1528
|
|
2239
|
-
|
2240
|
-
if (this._uptimeSecs > 0)
|
1529
|
+
if (this._chartInfo && this._chartInfo.id == id && this._chartInfo.type == type)
|
2241
1530
|
{
|
2242
|
-
|
2243
|
-
|
1531
|
+
switch (type)
|
1532
|
+
{
|
1533
|
+
case 'net':
|
1534
|
+
this._addDetailChartEntries(chartData.getSFSObject('netOut'), chartData.getSFSObject('netIn'), intervalMillis);
|
1535
|
+
break;
|
2244
1536
|
|
2245
|
-
|
2246
|
-
|
1537
|
+
default:
|
1538
|
+
this._addDetailChartEntries(chartData.getSFSObject(type), null, intervalMillis);
|
1539
|
+
}
|
2247
1540
|
}
|
2248
|
-
|
2249
|
-
// Dropped packets
|
2250
|
-
const totalPacketsOut = data.getLong('pktOut');
|
2251
|
-
|
2252
|
-
const totalDroppedTcpPacketsOut = data.getLong('pktOutDrop');
|
2253
|
-
$('#dsh-detDroppedTcpPacketsOut').text(`Out TCP: ${totalDroppedTcpPacketsOut} (${Math.round(totalDroppedTcpPacketsOut / totalPacketsOut * 100)}%)`);
|
2254
|
-
|
2255
|
-
const totalDroppedUdpPacketsOut = data.getLong('pktOutUdpDrop');
|
2256
|
-
$('#dsh-detDroppedUdpPacketsOut').text(`Out UDP: ${totalDroppedUdpPacketsOut} (${Math.round(totalDroppedUdpPacketsOut / totalPacketsOut * 100)}%)`);
|
2257
|
-
|
2258
|
-
const totalPacketsIn = data.getLong('pktIn');
|
2259
|
-
const totalDroppedPacketsIn = data.getLong('pktInDrop');
|
2260
|
-
$('#dsh-detDroppedPacketsIn').text(`In: ${totalDroppedPacketsIn} (${Math.round(totalDroppedPacketsIn / totalPacketsIn * 100)}%)`);
|
2261
|
-
|
2262
|
-
// SYSTEM STATUS
|
2263
|
-
|
2264
|
-
// Outgoing TCP messages queue
|
2265
|
-
const outMsgQueue = data.getInt('outMsgQueue');
|
2266
|
-
const outMsgQueueMax = data.getInt('outMsgQueueMax');
|
2267
|
-
this._outTcpMsgQueueChart.addEntry(outMsgQueue, outMsgQueueMax);
|
2268
|
-
this._tcpOutThreads = data.getInt('outMsgTh');
|
2269
|
-
this._tcpOutLoad = this._outTcpMsgQueueChart.load;
|
2270
|
-
|
2271
|
-
// Outgoing UDP messages queue
|
2272
|
-
const outUdpMsgQueue = data.getInt('outUdpMsgQueue');
|
2273
|
-
const outUdpMsgQueueMax = data.getInt('outUdpMsgQueueMax');
|
2274
|
-
this._outUdpMsgQueueChart.addEntry(outUdpMsgQueue, outUdpMsgQueueMax);
|
2275
|
-
this._udpOutThreads = data.getInt('outUdpMsgTh');
|
2276
|
-
this._udpOutLoad = this._outUdpMsgQueueChart.load;
|
2277
|
-
|
2278
|
-
this._updateOutMessagesQueueStatus();
|
2279
|
-
|
2280
|
-
// System Controller requests queue
|
2281
|
-
const sysCtrlQueue = data.getInt('sysCtrlQueue');
|
2282
|
-
const sysCtrlQueueMax = data.getInt('sysCtrlQueueMax');
|
2283
|
-
this._sysQueueChart.addEntry(sysCtrlQueue, sysCtrlQueueMax);
|
2284
|
-
$('#dsh-systemQueueThreads').text(this._getQueueThreadsLabel(data.getInt('sysCtrlTh')));
|
2285
|
-
$('#dsh-systemQueueLoad').text(this._getQueueLoadLabel(this._sysQueueChart.load));
|
2286
|
-
|
2287
|
-
// Extension Controller requests queue
|
2288
|
-
const extCtrlQueue = data.getInt('extCtrlQueue');
|
2289
|
-
const extCtrlQueueMax = data.getInt('extCtrlQueueMax');
|
2290
|
-
this._extQueueChart.addEntry(extCtrlQueue, extCtrlQueueMax);
|
2291
|
-
$('#dsh-extensionQueueThreads').text(this._getQueueThreadsLabel(data.getInt('extCtrlTh')));
|
2292
|
-
$('#dsh-extensionQueueLoad').text(this._getQueueLoadLabel(this._sysQueueChart.load));
|
2293
|
-
|
2294
|
-
// Evaluate overall system workload
|
2295
|
-
let sysWorkload = Math.round((outMsgQueue / outMsgQueueMax +
|
2296
|
-
outUdpMsgQueue / outUdpMsgQueueMax +
|
2297
|
-
sysCtrlQueue / sysCtrlQueueMax +
|
2298
|
-
extCtrlQueue / extCtrlQueueMax) * 100 / 4);
|
2299
|
-
if (sysWorkload > 100)
|
2300
|
-
sysWorkload = 100;
|
2301
|
-
|
2302
|
-
this._sysWorkloadChart.addEntry(sysWorkload);
|
2303
1541
|
}
|
2304
1542
|
|
2305
|
-
|
2306
|
-
else if (command == this.RESP_THREAD_DUMP)
|
1543
|
+
else if (command == this.RESP_LOG_MESSAGES)
|
2307
1544
|
{
|
2308
|
-
|
2309
|
-
|
1545
|
+
let logEntries = data.getSFSArray('entries');
|
1546
|
+
|
1547
|
+
for (let e = 0; e < logEntries.size(); e++)
|
1548
|
+
{
|
1549
|
+
let logEntry = logEntries.getSFSObject(e);
|
1550
|
+
|
1551
|
+
let ele = {
|
1552
|
+
timestamp: kendo.toString(new Date(logEntry.getLong('time')), 'dd/MM/yyyy HH:mm:ss'),
|
1553
|
+
level: logEntry.getUtfString('level'),
|
1554
|
+
message: logEntry.getUtfString('msg'),
|
1555
|
+
};
|
2310
1556
|
|
2311
|
-
|
2312
|
-
|
1557
|
+
let ds = this._logGrid.dataSource;
|
1558
|
+
ds.add(ele);
|
2313
1559
|
|
2314
|
-
|
2315
|
-
|
1560
|
+
// Check items limit
|
1561
|
+
while (ds.total() > this.MAX_LOG_SIZE)
|
1562
|
+
ds.remove(ds.at(0));
|
1563
|
+
}
|
2316
1564
|
}
|
2317
1565
|
}
|
2318
1566
|
|
@@ -2321,294 +1569,516 @@ class Dashboard extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModule"]
|
|
2321
1569
|
this._uptimeSecs = values[3];
|
2322
1570
|
this._uptimeSecs += (values[2] * 60);
|
2323
1571
|
this._uptimeSecs += (values[1] * 60 * 60);
|
2324
|
-
this._uptimeSecs += (values[0] * 24 * 60 * 60);
|
2325
1572
|
|
2326
|
-
$('#
|
2327
|
-
$('#
|
2328
|
-
$('#
|
2329
|
-
$('#dsh-uptimeSeconds').text( (values[3] <= 9 ? '0' : '') + values[3] );
|
1573
|
+
$('#clm-uptimeDays').text( (values[0] <= 9 ? '00' : (values[0] <= 99 ? '0' : '')) + values[0] );
|
1574
|
+
$('#clm-uptimeHours').text( (values[1] <= 9 ? '0' : '') + values[1] );
|
1575
|
+
$('#clm-uptimeMinutes').text( (values[2] <= 9 ? '0' : '') + values[2] );
|
2330
1576
|
}
|
2331
1577
|
|
2332
1578
|
//---------------------------------
|
2333
1579
|
// UI EVENT LISTENERS
|
2334
1580
|
//---------------------------------
|
2335
1581
|
|
2336
|
-
|
1582
|
+
_onNodesGridChange(e, args)
|
2337
1583
|
{
|
2338
|
-
|
2339
|
-
|
2340
|
-
}
|
1584
|
+
let grid = e.sender;
|
1585
|
+
let items = grid.items();
|
2341
1586
|
|
2342
|
-
|
2343
|
-
|
2344
|
-
|
1587
|
+
this._selectedNodes = [];
|
1588
|
+
this._selectedActiveNodes = [];
|
1589
|
+
|
1590
|
+
for (let i of grid.select())
|
1591
|
+
{
|
1592
|
+
let dataItem = grid.dataItem(i);
|
1593
|
+
this._selectedNodes.push(dataItem['id']);
|
1594
|
+
|
1595
|
+
if (dataItem['active'])
|
1596
|
+
this._selectedActiveNodes.push(dataItem['id']);
|
1597
|
+
}
|
1598
|
+
|
1599
|
+
// Compare the list of selected nodes with the list of visible
|
1600
|
+
// chart rows, to show/hide the selected/deselected ones
|
1601
|
+
this._updateChartedNodes();
|
2345
1602
|
|
2346
|
-
//
|
2347
|
-
|
2348
|
-
$('#dsh-playBt').removeClass('hidden');
|
1603
|
+
// Enable/disable button to deactivate selected active nodes
|
1604
|
+
this._updateDeactivateButton();
|
2349
1605
|
}
|
2350
1606
|
|
2351
|
-
|
1607
|
+
_onNodesGridDataBound(e)
|
2352
1608
|
{
|
2353
|
-
|
1609
|
+
let grid = e.sender;
|
1610
|
+
let items = grid.items();
|
1611
|
+
let itemsToSelect = [];
|
1612
|
+
let self = this;
|
1613
|
+
|
1614
|
+
items.each(function (idx, row) {
|
1615
|
+
let dataItem = grid.dataItem(row);
|
1616
|
+
if (self._selectedNodes.includes(dataItem['id'])) {
|
1617
|
+
itemsToSelect.push(row);
|
1618
|
+
}
|
1619
|
+
});
|
1620
|
+
|
1621
|
+
e.sender.select(itemsToSelect);
|
1622
|
+
|
1623
|
+
//==================================================
|
1624
|
+
|
1625
|
+
// Hide group column and collapse icon
|
1626
|
+
$('#clm-nodesList .k-group-col, #clm-nodesList .k-group-cell').remove();
|
1627
|
+
let spanCells = $('#clm-nodesList .k-grouping-row').children('td');
|
1628
|
+
spanCells.attr('colspan', spanCells.attr('colspan') - 1);
|
1629
|
+
$('#clm-nodesList .k-icon.k-i-collapse').hide();
|
2354
1630
|
|
2355
|
-
//
|
2356
|
-
$('#
|
2357
|
-
|
1631
|
+
// Modify group label
|
1632
|
+
$('#clm-nodesList .k-grouping-row td p.k-reset').each(function( index ) {
|
1633
|
+
if ($(this).text() == 'active: true')
|
1634
|
+
$(this).text('Active nodes');
|
1635
|
+
else
|
1636
|
+
$(this).text('Inactive nodes');
|
1637
|
+
});
|
2358
1638
|
}
|
2359
1639
|
|
2360
|
-
|
1640
|
+
_onMainRangeChange(e)
|
2361
1641
|
{
|
2362
|
-
//
|
2363
|
-
this.
|
2364
|
-
|
2365
|
-
// Reset realtime charts
|
2366
|
-
this._cpuUsageChart.reset();
|
2367
|
-
this._threadCountChart.reset();
|
2368
|
-
this._memoryChart.reset();
|
2369
|
-
this._networkRTChart.reset();
|
2370
|
-
this._sysWorkloadChart.reset();
|
2371
|
-
this._outTcpMsgQueueChart.reset();
|
2372
|
-
this._outUdpMsgQueueChart.reset();
|
2373
|
-
this._sysQueueChart.reset();
|
2374
|
-
this._extQueueChart.reset();
|
1642
|
+
// Request nodes data to server
|
1643
|
+
this._requestNodesData();
|
2375
1644
|
}
|
2376
1645
|
|
2377
|
-
|
1646
|
+
_onChartRangeChange(e)
|
2378
1647
|
{
|
2379
|
-
//
|
2380
|
-
this.
|
2381
|
-
this._network24hChart.redraw();
|
2382
|
-
|
2383
|
-
// Redraw time range slider
|
2384
|
-
this._timeSlider.resize();
|
1648
|
+
// Request detail chart data to server
|
1649
|
+
this._requestDetailChartData();
|
2385
1650
|
}
|
2386
1651
|
|
2387
|
-
|
1652
|
+
_onRequestDataInterval()
|
2388
1653
|
{
|
2389
|
-
//
|
2390
|
-
this.
|
2391
|
-
this._outUdpMsgQueueChart.redraw();
|
1654
|
+
// Request selected nodes data
|
1655
|
+
this._requestNodesData();
|
2392
1656
|
|
2393
|
-
|
1657
|
+
// Request detail chart data
|
1658
|
+
this._requestDetailChartData();
|
2394
1659
|
}
|
2395
1660
|
|
2396
|
-
|
1661
|
+
_requestNodesList()
|
2397
1662
|
{
|
2398
|
-
//
|
2399
|
-
this.
|
2400
|
-
|
2401
|
-
|
2402
|
-
this.
|
2403
|
-
|
2404
|
-
|
2405
|
-
|
2406
|
-
|
2407
|
-
|
2408
|
-
|
1663
|
+
// Clear previous request scheduling
|
1664
|
+
clearTimeout(this._requestNodesTimer);
|
1665
|
+
|
1666
|
+
// Check if connection is still available
|
1667
|
+
if (this.smartFox.isConnected)
|
1668
|
+
{
|
1669
|
+
// Send request to extension
|
1670
|
+
this.sendExtensionRequest(this.REQ_GET_NODES);
|
1671
|
+
|
1672
|
+
// Schedule next request
|
1673
|
+
this._requestNodesTimer = setTimeout($.proxy(this._requestNodesList, this), 5000); // Every 5 seconds
|
1674
|
+
}
|
2409
1675
|
}
|
2410
1676
|
|
2411
|
-
|
1677
|
+
_onMiniChartClick(e)
|
2412
1678
|
{
|
2413
|
-
let
|
1679
|
+
let nodeId = e.detail.node;
|
1680
|
+
let nodeDataItem = this._grid.dataSource.get(nodeId);
|
1681
|
+
let chartType = e.detail.type;
|
1682
|
+
let chartOptions = e.detail.options;
|
2414
1683
|
|
2415
|
-
|
2416
|
-
{
|
2417
|
-
|
2418
|
-
|
1684
|
+
// Save ref to charted node
|
1685
|
+
this._chartInfo = {
|
1686
|
+
id: nodeId,
|
1687
|
+
type: chartType
|
1688
|
+
};
|
2419
1689
|
|
2420
|
-
|
1690
|
+
// Extract chart title from options
|
1691
|
+
$('#clm-chartModalTitle').text(chartOptions.title.text);
|
2421
1692
|
|
2422
|
-
|
2423
|
-
|
2424
|
-
|
1693
|
+
if (nodeDataItem.alias)
|
1694
|
+
{
|
1695
|
+
$('#clm-chartNodeAlias').text(nodeDataItem.alias);
|
1696
|
+
$('#clm-chartNodeName').text(nodeDataItem.name);
|
1697
|
+
}
|
1698
|
+
else
|
1699
|
+
{
|
1700
|
+
$('#clm-chartNodeAlias').text(nodeDataItem.name);
|
1701
|
+
$('#clm-chartNodeName').hide();
|
2425
1702
|
}
|
2426
1703
|
|
2427
|
-
|
2428
|
-
|
1704
|
+
// Set secondary range dropdown to main range value
|
1705
|
+
let index = this._mainRangeDD.select();
|
1706
|
+
this._chartRangeDD.select(index);
|
2429
1707
|
|
2430
|
-
|
2431
|
-
|
2432
|
-
const wsMan = this._wsManagerConfig;
|
1708
|
+
// Create chart tag
|
1709
|
+
$('#clm-nodeDetailChartContainer').append($('<div>', {'class': 'chart'}))
|
2433
1710
|
|
2434
|
-
|
2435
|
-
|
2436
|
-
|
2437
|
-
|
1711
|
+
// Initialize chart
|
1712
|
+
this._getChartTag().kendoChart({
|
1713
|
+
transitions: false,
|
1714
|
+
chartArea: {
|
1715
|
+
background: 'transparent',
|
1716
|
+
margin: 0,
|
1717
|
+
padding:0
|
1718
|
+
},
|
1719
|
+
legend: {
|
1720
|
+
visible: false
|
1721
|
+
},
|
2438
1722
|
|
2439
|
-
|
2440
|
-
|
1723
|
+
seriesDefaults: {
|
1724
|
+
type: 'scatterLine',
|
1725
|
+
labels: {
|
1726
|
+
visible: false,
|
1727
|
+
format: '{0}',
|
1728
|
+
background: 'transparent'
|
1729
|
+
},
|
1730
|
+
missingValues: 'gap',
|
1731
|
+
markers: {
|
1732
|
+
visible: true,
|
1733
|
+
type: 'circle',
|
1734
|
+
size: 3,
|
1735
|
+
},
|
1736
|
+
},
|
1737
|
+
series: chartOptions.series,
|
1738
|
+
yAxis: chartOptions.yAxis,
|
1739
|
+
xAxis: {
|
1740
|
+
majorGridLines: {
|
1741
|
+
visible: false
|
1742
|
+
},
|
1743
|
+
majorTicks: {
|
1744
|
+
visible: true
|
1745
|
+
},
|
1746
|
+
labels: {
|
1747
|
+
visible: true,
|
1748
|
+
rotation: 0,
|
1749
|
+
template: '#: kendo.toString(new Date(value), "HH:mm") #'
|
1750
|
+
},
|
1751
|
+
},
|
1752
|
+
tooltip: chartOptions.tooltip
|
1753
|
+
}).data('kendoChart');
|
2441
1754
|
|
2442
|
-
|
2443
|
-
|
2444
|
-
// Disable button
|
2445
|
-
$('#dsh-dumpThreadsBt').attr('disabled', true);
|
1755
|
+
// Clear chart
|
1756
|
+
this._getChartWidget().setDataSource(null);
|
2446
1757
|
|
2447
|
-
//
|
2448
|
-
|
1758
|
+
// Display chart modal
|
1759
|
+
$('#clm-chartModal').modal('show');
|
1760
|
+
|
1761
|
+
// Request detail chart data to server
|
1762
|
+
this._requestDetailChartData();
|
2449
1763
|
}
|
2450
1764
|
|
2451
|
-
|
1765
|
+
_onChartModalHidden(e)
|
2452
1766
|
{
|
2453
|
-
|
2454
|
-
|
2455
|
-
|
2456
|
-
|
2457
|
-
|
2458
|
-
|
2459
|
-
|
2460
|
-
|
1767
|
+
// Destroy chart
|
1768
|
+
this._chartInfo = null;
|
1769
|
+
|
1770
|
+
$('#clm-chartModalTitle').text('');
|
1771
|
+
$('#clm-chartNodeAlias').text('');
|
1772
|
+
$('#clm-chartNodeName').text('');
|
1773
|
+
|
1774
|
+
this._getChartWidget().destroy();
|
1775
|
+
this._getChartTag().remove();
|
2461
1776
|
}
|
2462
1777
|
|
2463
|
-
|
1778
|
+
_requestOrchestrationLogs()
|
2464
1779
|
{
|
2465
|
-
//
|
2466
|
-
|
1780
|
+
// Build request parameters
|
1781
|
+
let params = new SFS2X.SFSObject();
|
1782
|
+
params.putLong('ts', this._lastLogsReqTimestamp);
|
1783
|
+
|
1784
|
+
// Send request to extension
|
1785
|
+
this.sendExtensionRequest(this.REQ_GET_LOG_MESSAGES, params);
|
1786
|
+
|
1787
|
+
// Update last request time
|
1788
|
+
this._lastLogsReqTimestamp = Date.now();
|
2467
1789
|
}
|
2468
1790
|
|
2469
1791
|
//------------------------------------
|
2470
1792
|
// PRIVATE METHODS
|
2471
1793
|
//------------------------------------
|
2472
1794
|
|
2473
|
-
|
1795
|
+
_updateChartedNodes()
|
2474
1796
|
{
|
2475
|
-
|
1797
|
+
// Get selected nodes not yet shown in the chart area
|
1798
|
+
let toShow = this._selectedNodes.filter(x => !this._chartedNodes.includes(x));
|
2476
1799
|
|
2477
|
-
|
1800
|
+
// Get nodes shown in the chart area not in the selected list anymore
|
1801
|
+
let toHide = this._chartedNodes.filter(x => !this._selectedNodes.includes(x));
|
1802
|
+
|
1803
|
+
// Show nodes charts
|
1804
|
+
if (toShow.length > 0)
|
2478
1805
|
{
|
2479
|
-
//
|
2480
|
-
|
1806
|
+
//console.log("SHOWING CHARTS OF NODES: " + toShow)
|
1807
|
+
this._chartedNodes = [...this._chartedNodes, ...toShow]; // Merge arrays
|
1808
|
+
|
1809
|
+
// Display node charts
|
1810
|
+
for (let id of toShow)
|
1811
|
+
this._displayNodeChartsItem(id);
|
1812
|
+
}
|
2481
1813
|
|
2482
|
-
|
2483
|
-
|
1814
|
+
// Hide nodes charts
|
1815
|
+
if (toHide.length > 0)
|
1816
|
+
{
|
1817
|
+
//console.log("HIDING CHARTS OF NODES: " + toHide)
|
1818
|
+
this._chartedNodes = this._chartedNodes.filter(x => !toHide.includes(x));
|
2484
1819
|
|
2485
|
-
//
|
2486
|
-
|
2487
|
-
|
1820
|
+
// Remove node charts
|
1821
|
+
for (let id of toHide)
|
1822
|
+
{
|
1823
|
+
this._removeNodeChartsItem(id);
|
2488
1824
|
|
2489
|
-
|
2490
|
-
|
1825
|
+
// Remove detail chart if visible
|
1826
|
+
if (this._chartInfo && id == this._chartInfo.id)
|
1827
|
+
$('#clm-chartModal').modal('hide');
|
1828
|
+
}
|
2491
1829
|
}
|
2492
|
-
else
|
2493
|
-
{
|
2494
|
-
// Show alert
|
2495
|
-
$('#dsh-wsManagerAlert').show();
|
2496
1830
|
|
2497
|
-
|
2498
|
-
|
1831
|
+
// Show/hide interval dropdown
|
1832
|
+
if (toShow.length > 0 || toHide.length > 0)
|
1833
|
+
{
|
1834
|
+
if (this._chartedNodes.length > 0)
|
1835
|
+
$('#clm-mainRangeContainer').show();
|
2499
1836
|
else
|
2500
|
-
$('#
|
1837
|
+
$('#clm-mainRangeContainer').hide();
|
1838
|
+
}
|
2501
1839
|
|
2502
|
-
|
2503
|
-
|
1840
|
+
// Request charts data for newly selected nodes
|
1841
|
+
// NOTE: we have to use a timeout as a workaround to give charts time to be rendered before drawing them, or they will exceed their container's width
|
1842
|
+
if (toShow.length > 0)
|
1843
|
+
setTimeout($.proxy(this._requestNodesData, this), 20, toShow);
|
1844
|
+
}
|
1845
|
+
|
1846
|
+
_getTimeSinceJoinTemplate(dataItem)
|
1847
|
+
{
|
1848
|
+
let now = moment__WEBPACK_IMPORTED_MODULE_1__();
|
1849
|
+
let joinTime = moment__WEBPACK_IMPORTED_MODULE_1__(dataItem['joinTime']);
|
1850
|
+
|
1851
|
+
let diffDays = now.diff(joinTime, 'days');
|
1852
|
+
let diffHours = now.diff(joinTime, 'hours') - (diffDays * 24);
|
1853
|
+
let diffMinutes = now.diff(joinTime, 'minutes') - (((diffDays * 24) + diffHours) * 60);
|
1854
|
+
|
1855
|
+
return `<span>${diffDays}d ${diffHours}h ${diffMinutes}m<span>`;
|
1856
|
+
}
|
1857
|
+
|
1858
|
+
_getHealthTemplate(dataItem)
|
1859
|
+
{
|
1860
|
+
let style = 'text-success';
|
1861
|
+
|
1862
|
+
if (!dataItem['health'])
|
1863
|
+
style = 'text-danger';
|
1864
|
+
|
1865
|
+
return `<span class="${style}"><i class="fas fa-circle"></i></span>`;
|
1866
|
+
}
|
1867
|
+
|
1868
|
+
_getRecyclableTemplate(dataItem)
|
1869
|
+
{
|
1870
|
+
let style = dataItem['recyclable'] ? 'text-success' : 'text-light';
|
1871
|
+
return `<span class="${style}"><i class="fas fa-circle"></i></span>`;
|
1872
|
+
}
|
1873
|
+
|
1874
|
+
_getTerminableTemplate(dataItem)
|
1875
|
+
{
|
1876
|
+
let style = dataItem['terminable'] ? 'text-success' : 'text-light';
|
1877
|
+
return `<span class="${style}"><i class="fas fa-circle"></i></span>`;
|
1878
|
+
}
|
2504
1879
|
|
2505
|
-
|
2506
|
-
|
2507
|
-
|
1880
|
+
_showLobbyState(isActive)
|
1881
|
+
{
|
1882
|
+
if (isActive)
|
1883
|
+
{
|
1884
|
+
$('#clm-lobbyState .active').show();
|
1885
|
+
$('#clm-lobbyState .inactive').hide();
|
1886
|
+
}
|
1887
|
+
else
|
1888
|
+
{
|
1889
|
+
$('#clm-lobbyState .active').hide();
|
1890
|
+
$('#clm-lobbyState .inactive').show();
|
2508
1891
|
}
|
1892
|
+
|
1893
|
+
$('#clm-lobbyState').show();
|
1894
|
+
|
1895
|
+
// Enable/disable scale-up button
|
1896
|
+
$('#clm-scaleUpBt').prop('disabled', !isActive);
|
2509
1897
|
}
|
2510
1898
|
|
2511
|
-
|
2512
|
-
* Build the polling request to be sent to the server.
|
2513
|
-
*/
|
2514
|
-
_requestData(getHistory = false)
|
1899
|
+
_requestNodesData(nodes = null)
|
2515
1900
|
{
|
2516
|
-
|
2517
|
-
|
1901
|
+
if (nodes == null)
|
1902
|
+
nodes = this._chartedNodes;
|
2518
1903
|
|
2519
|
-
//
|
2520
|
-
|
1904
|
+
//console.log("REQUESTING DATA FOR NODES " + nodes + " (last " + this.intervals[this._mainRangeDD.value()].minutes + " minutes)")
|
1905
|
+
|
1906
|
+
if (nodes.length > 0 && this.smartFox.isConnected)
|
2521
1907
|
{
|
1908
|
+
let i = this._mainRangeDD.value();
|
1909
|
+
let intervalMillis = this.intervals[i].minutes * 60 * 1000;
|
1910
|
+
let dataPoints = this.intervals[i].points1;
|
1911
|
+
|
1912
|
+
// List nodes
|
1913
|
+
let list = new SFS2X.SFSArray();
|
1914
|
+
|
1915
|
+
for (let nodeId of nodes)
|
1916
|
+
{
|
1917
|
+
let obj = new SFS2X.SFSObject();
|
1918
|
+
obj.putUtfString('id', nodeId);
|
1919
|
+
obj.putLong('int', intervalMillis);
|
1920
|
+
obj.putInt('pts', dataPoints);
|
1921
|
+
|
1922
|
+
list.addSFSObject(obj);
|
1923
|
+
}
|
1924
|
+
|
2522
1925
|
// Build request parameters
|
2523
1926
|
let params = new SFS2X.SFSObject();
|
1927
|
+
params.putSFSArray('nodes', list);
|
2524
1928
|
|
2525
|
-
|
2526
|
-
|
1929
|
+
// Send request to Extension
|
1930
|
+
this.sendExtensionRequest(this.REQ_GET_NODES_DATA, params);
|
1931
|
+
}
|
1932
|
+
}
|
2527
1933
|
|
2528
|
-
|
2529
|
-
|
1934
|
+
_requestDetailChartData()
|
1935
|
+
{
|
1936
|
+
if (this._chartInfo)
|
1937
|
+
{
|
1938
|
+
let i = this._chartRangeDD.value();
|
2530
1939
|
|
2531
|
-
|
2532
|
-
|
1940
|
+
let params = new SFS2X.SFSObject();
|
1941
|
+
params.putUtfString('id', this._chartInfo.id);
|
1942
|
+
params.putUtfString('type', this._chartInfo.type);
|
1943
|
+
params.putLong('int', this.intervals[i].minutes * 60 * 1000);
|
1944
|
+
params.putInt('pts', this.intervals[i].points2);
|
1945
|
+
|
1946
|
+
// Send request to Extension
|
1947
|
+
this.sendExtensionRequest(this.REQ_GET_CHART_DATA, params);
|
2533
1948
|
}
|
2534
1949
|
}
|
2535
1950
|
|
2536
|
-
|
1951
|
+
_removeNodeChartsItem(nodeId)
|
2537
1952
|
{
|
2538
|
-
|
2539
|
-
|
2540
|
-
|
2541
|
-
|
1953
|
+
let element = this.querySelector('#clm-nodeMiniChartsContainer #node_' + nodeId);
|
1954
|
+
|
1955
|
+
// Destroy element
|
1956
|
+
element.destroy();
|
1957
|
+
|
1958
|
+
// Remove element from container
|
1959
|
+
this.querySelector('#clm-nodeMiniChartsContainer').removeChild(element);
|
1960
|
+
}
|
1961
|
+
|
1962
|
+
_displayNodeChartsItem(nodeId)
|
1963
|
+
{
|
1964
|
+
let nodeDataItem = this._grid.dataSource.get(nodeId);
|
1965
|
+
|
1966
|
+
// Create element
|
1967
|
+
let element = new _components_module_specific_cluster_monitor_node_mini_charts__WEBPACK_IMPORTED_MODULE_3__["NodeMiniCharts"](nodeDataItem['id'], nodeDataItem['alias'], nodeDataItem['name']);
|
1968
|
+
|
1969
|
+
// Append element to container
|
1970
|
+
this.querySelector('#clm-nodeMiniChartsContainer').appendChild(element);
|
1971
|
+
}
|
1972
|
+
|
1973
|
+
_getChartTag()
|
1974
|
+
{
|
1975
|
+
return $('#clm-chartModal .chart');
|
2542
1976
|
}
|
2543
1977
|
|
2544
|
-
|
1978
|
+
_getChartWidget()
|
2545
1979
|
{
|
2546
|
-
|
2547
|
-
this._cpuUsageChart.paused = paused;
|
2548
|
-
this._threadCountChart.paused = paused;
|
2549
|
-
this._memoryChart.paused = paused;
|
2550
|
-
this._networkRTChart.paused = paused;
|
2551
|
-
this._sysWorkloadChart.paused = paused;
|
2552
|
-
this._outTcpMsgQueueChart.paused = paused;
|
2553
|
-
this._sysQueueChart.paused = paused;
|
2554
|
-
this._extQueueChart.paused = paused;
|
1980
|
+
return this._getChartTag().data('kendoChart');
|
2555
1981
|
}
|
2556
1982
|
|
2557
|
-
|
1983
|
+
_addDetailChartEntries(data, data1, intervalMillis)
|
2558
1984
|
{
|
2559
|
-
|
2560
|
-
|
1985
|
+
let lastTimestamp = data.getLong('last');
|
1986
|
+
let values = data.getLongArray('data');
|
1987
|
+
let values1 = (data1 != null ? data1.getLongArray('data') : null);
|
1988
|
+
let chartWidget = this._getChartWidget();
|
1989
|
+
|
1990
|
+
// Divide interval by the number of data points to calculate their timestamps
|
1991
|
+
let sliceMillis = Math.round(intervalMillis / values.length);
|
2561
1992
|
|
2562
|
-
|
1993
|
+
let ds = new kendo.data.DataSource();
|
1994
|
+
let firstTimestamp = lastTimestamp - intervalMillis;
|
1995
|
+
|
1996
|
+
for (let i = 0; i < values.length; i++)
|
2563
1997
|
{
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
1998
|
+
let timestamp = firstTimestamp + (sliceMillis * i);
|
1999
|
+
|
2000
|
+
let value = values[i] < 0 ? null : values[i];
|
2001
|
+
let value1 = values1 ? (values1[i] < 0 ? null : values1[i]) : null;
|
2002
|
+
|
2003
|
+
let entry = {
|
2004
|
+
ts: timestamp,
|
2005
|
+
val: value,
|
2006
|
+
val1: value1,
|
2567
2007
|
};
|
2008
|
+
|
2009
|
+
ds.add(entry);
|
2568
2010
|
}
|
2569
2011
|
|
2570
|
-
|
2571
|
-
|
2572
|
-
|
2573
|
-
|
2574
|
-
|
2575
|
-
},
|
2576
|
-
sort: sort,
|
2577
|
-
data: items
|
2578
|
-
});
|
2012
|
+
// Set chart's x-axis limits
|
2013
|
+
chartWidget.options.xAxis.min = firstTimestamp;
|
2014
|
+
chartWidget.options.xAxis.max = lastTimestamp;
|
2015
|
+
|
2016
|
+
chartWidget.setDataSource(ds);
|
2579
2017
|
}
|
2580
2018
|
|
2581
|
-
|
2019
|
+
_updateDeactivateButton()
|
2582
2020
|
{
|
2583
|
-
|
2021
|
+
let cnt = this._selectedActiveNodes.length;
|
2022
|
+
let txt = (cnt > 0 ? cnt : '') + ' node' + (cnt != 1 ? 's' : '');
|
2023
|
+
|
2024
|
+
$('#clm-deactivateBt').prop('disabled', cnt == 0);
|
2025
|
+
$('#clm-deactivateNodesNum').text(txt);
|
2584
2026
|
}
|
2585
2027
|
|
2586
|
-
|
2028
|
+
_onDeactivateBtClick()
|
2587
2029
|
{
|
2588
|
-
|
2030
|
+
this.shellCtrl.showConfirmWarning(`Are you sure you want to deactivate the selected active node${this._selectedActiveNodes.length > 1 ? 's' : ''}? This operation is irreversible.`, $.proxy(this._onDeactivateNodesConfirm, this));
|
2589
2031
|
}
|
2590
2032
|
|
2591
|
-
|
2033
|
+
_onDeactivateNodesConfirm()
|
2592
2034
|
{
|
2593
|
-
|
2594
|
-
let loadStr = this._getQueueLoadLabel('--');
|
2595
|
-
|
2596
|
-
if ($('#dsh-tcpPill').hasClass('active'))
|
2035
|
+
if (this._selectedActiveNodes.length > 0 && this.smartFox.isConnected)
|
2597
2036
|
{
|
2598
|
-
|
2599
|
-
|
2037
|
+
let params = new SFS2X.SFSObject();
|
2038
|
+
params.putUtfStringArray('nodes', this._selectedActiveNodes);
|
2039
|
+
|
2040
|
+
this.sendExtensionRequest(this.REQ_DEACTIVATE_NODES, params);
|
2600
2041
|
}
|
2042
|
+
}
|
2043
|
+
|
2044
|
+
_onScaleUpBtClick()
|
2045
|
+
{
|
2046
|
+
// Display scale-up modal
|
2047
|
+
$('#clm-scaleUpModal').modal('show');
|
2048
|
+
}
|
2601
2049
|
|
2602
|
-
|
2050
|
+
_onScaleUpConfirmBtClick()
|
2051
|
+
{
|
2052
|
+
if (this._scaleUpValidator.validate())
|
2603
2053
|
{
|
2604
|
-
|
2605
|
-
|
2054
|
+
// Retrieve scale-up details
|
2055
|
+
let params = new SFS2X.SFSObject();
|
2056
|
+
params.putInt('num', this._numNodesIn.value());
|
2057
|
+
|
2058
|
+
// Send scale-up request to server
|
2059
|
+
this.sendExtensionRequest(this.REQ_SCALE_UP, params);
|
2060
|
+
|
2061
|
+
// Hide modal
|
2062
|
+
$('#clm-scaleUpModal').modal('hide');
|
2606
2063
|
}
|
2064
|
+
}
|
2065
|
+
|
2066
|
+
_onScaleUpModalHidden(e)
|
2067
|
+
{
|
2068
|
+
// Reset validator
|
2069
|
+
this._scaleUpValidator.hideMessages();
|
2070
|
+
|
2071
|
+
// The method above doesn't remove the k-invalid classes and aria-invalid="true" attributes from inputs
|
2072
|
+
// Let's do it manually
|
2073
|
+
$('#clm-scaleUpForm .k-invalid').removeClass('k-invalid');
|
2074
|
+
$('#clm-scaleUpForm [aria-invalid="true"]').removeAttr('aria-invalid');
|
2607
2075
|
|
2608
|
-
|
2609
|
-
|
2076
|
+
// Reset scale-up form
|
2077
|
+
this._numNodesIn.value(1);
|
2610
2078
|
}
|
2611
2079
|
|
2080
|
+
|
2081
|
+
|
2612
2082
|
//---------------------------------
|
2613
2083
|
// PRIVATE GETTERS
|
2614
2084
|
//---------------------------------
|
@@ -2621,4 +2091,4 @@ class Dashboard extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModule"]
|
|
2621
2091
|
/***/ })
|
2622
2092
|
|
2623
2093
|
}]);
|
2624
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzL2pzL2NvcmUvbW9kdWxlcy9tb2R1bGUtNS5idW5kbGUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9hcHBsaWNhdGlvbi8uL3NyYy9jb21wb25lbnRzL2NoYXJ0cy9iYXNlLWNoYXJ0LmpzIiwid2VicGFjazovL2FwcGxpY2F0aW9uLy4vc3JjL2NvbXBvbmVudHMvY2hhcnRzL2NoYXJ0LXV0aWxzLmpzIiwid2VicGFjazovL2FwcGxpY2F0aW9uLy4vc3JjL2NvbXBvbmVudHMvY2hhcnRzL2NwdS11c2FnZS1jaGFydC5qcyIsIndlYnBhY2s6Ly9hcHBsaWNhdGlvbi8uL3NyYy9jb21wb25lbnRzL2NoYXJ0cy9tZW1vcnktY2hhcnQuanMiLCJ3ZWJwYWNrOi8vYXBwbGljYXRpb24vLi9zcmMvY29tcG9uZW50cy9jaGFydHMvbmV0d29yay0yNGgtY2hhcnQuanMiLCJ3ZWJwYWNrOi8vYXBwbGljYXRpb24vLi9zcmMvY29tcG9uZW50cy9jaGFydHMvbmV0d29yay1yZWFsdGltZS1jaGFydC5qcyIsIndlYnBhY2s6Ly9hcHBsaWNhdGlvbi8uL3NyYy9jb21wb25lbnRzL2NoYXJ0cy9zeXN0ZW0tcXVldWUtY2hhcnQuanMiLCJ3ZWJwYWNrOi8vYXBwbGljYXRpb24vLi9zcmMvY29tcG9uZW50cy9jaGFydHMvc3lzdGVtLXdvcmtsb2FkLWNoYXJ0LmpzIiwid2VicGFjazovL2FwcGxpY2F0aW9uLy4vc3JjL2NvbXBvbmVudHMvY2hhcnRzL3RocmVhZC1jb3VudC1jaGFydC5qcyIsIndlYnBhY2s6Ly9hcHBsaWNhdGlvbi8uL3NyYy9tb2R1bGVzL2Rhc2hib2FyZC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgQmFzZUNoYXJ0IGV4dGVuZHMgSFRNTEVsZW1lbnRcbntcblx0Y29uc3RydWN0b3IobWF4VmFsdWVzKVxuXHR7XG5cdCAgICBzdXBlcigpO1xuXG5cdFx0dGhpcy5fbWF4VmFsdWVzID0gbWF4VmFsdWVzO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZVxuXHRcdHRoaXMuX2luaXRpYWxpemUoKTtcblx0fVxuXG5cdC8vIENhbiBiZSBvdmVycmlkZGVuXG5cdF9pbml0aWFsaXplKClcblx0e1xuXHRcdC8vIENyZWF0ZSBjaGFydCBodG1sXG5cdFx0bGV0IGNoYXJ0SHRtbCA9ICQoJzxkaXY+Jyk7XG5cdFx0JCh0aGlzKS5hcHBlbmQoY2hhcnRIdG1sKTtcblxuXHRcdHRoaXMuX2NoYXJ0V2lkZ2V0ID0gdGhpcy5faW5pdENoYXJ0V2lkZ2V0KGNoYXJ0SHRtbCk7XG5cblx0XHQvLyBSZXNldCBkYXRhIHNvdXJjZVxuXHRcdHRoaXMucmVzZXQoKTtcblx0fVxuXG5cdC8vIE1VU1QgQkUgT1ZFUlJJRERFTlxuXHRfaW5pdENoYXJ0V2lkZ2V0KClcblx0e1xuXHRcdHRocm93IG5ldyBFcnJvcignQ2hhcnQgd2lkZ2V0IG11c3QgYmUgaW5pdGlhbGl6ZWQhJylcblx0fVxuXG5cdHNldCBwYXVzZWQodmFsdWUpXG5cdHtcblx0XHR0aGlzLmlzUGF1c2VkID0gdmFsdWU7XG5cdFx0dGhpcy5fb25QYXVzZUNoYW5nZSgpO1xuXHR9XG5cblx0Z2V0IHBhdXNlZCgpXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5pc1BhdXNlZDtcblx0fVxuXG5cdHJlc2V0KClcblx0e1xuXHRcdHRoaXMuX2NoYXJ0V2lkZ2V0LnNldERhdGFTb3VyY2UoW10pO1xuXHR9XG5cblx0cmVkcmF3KClcblx0e1xuXHRcdHRoaXMuX2NoYXJ0V2lkZ2V0LnJlZHJhdygpO1xuXHR9XG5cblx0Z2V0TGFzdEVudHJ5KClcblx0e1xuXHRcdGxldCBkcztcblxuXHRcdGlmICh0aGlzLmlzUGF1c2VkKVxuXHRcdFx0ZHMgPSB0aGlzLl90ZW1wRFM7XG5cdFx0ZWxzZVxuXHRcdFx0ZHMgPSB0aGlzLl9kYXRhU291cmNlO1xuXG5cdFx0aWYgKGRzICE9IG51bGwgJiYgZHMudG90YWwoKSA+IDApXG5cdFx0XHRyZXR1cm4gZHMuYXQoZHMudG90YWwoKSAtIDEpO1xuXHRcdGVsc2Vcblx0XHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0X2FkZEVudHJ5KG5ld0VudHJ5KVxuXHR7XG5cdFx0aWYgKHRoaXMuaXNQYXVzZWQpXG5cdFx0e1xuXHRcdFx0aWYgKHRoaXMuX3RlbXBEUyA9PSBudWxsKVxuXHRcdFx0XHR0aGlzLl90ZW1wRFMgPSBuZXcga2VuZG8uZGF0YS5EYXRhU291cmNlKCk7XG5cblx0XHRcdC8vIFN0b3JlIG5ldyB2YWx1ZSBpbiBhIHRlbXBvcmFyeSBhcnJheVxuXHRcdFx0dGhpcy5fdGVtcERTLmFkZChuZXdFbnRyeSk7XG5cdFx0fVxuXHRcdGVsc2Vcblx0XHR7XG5cdFx0XHRsZXQgZHMgPSB0aGlzLl9kYXRhU291cmNlO1xuXG5cdFx0XHRpZiAodGhpcy5fdGVtcERTICE9IG51bGwpXG5cdFx0XHR7XG5cdFx0XHRcdC8vIENvbmNhdGVuYXRlIHRlbXBvcmFyeSBlbnRyaWVzIHRvIGFjdHVhbCBkYXRhIHNvdXJjZVxuXHRcdFx0XHRsZXQgbmV3QXJyID0gJC5tZXJnZShkcy5kYXRhKCksIHRoaXMuX3RlbXBEUy5kYXRhKCkpO1xuXG5cdFx0XHRcdC8vIFJlbW92ZSB2YWx1ZXMgZXhjZWVkaW5nIE1BWF9WQUxVRVNcblx0XHRcdFx0aWYgKG5ld0Fyci5sZW5ndGggPiB0aGlzLl9tYXhWYWx1ZXMpXG5cdFx0XHRcdFx0bmV3QXJyLnNwbGljZSgwLCBuZXdBcnIubGVuZ3RoIC0gdGhpcy5fbWF4VmFsdWVzKVxuXG5cdFx0XHRcdC8vIENyZWF0ZSBuZXcgZGF0YXNvdXJjZVxuXHRcdFx0XHRsZXQgbmV3RFMgPSBuZXcga2VuZG8uZGF0YS5EYXRhU291cmNlKHtkYXRhOiBuZXdBcnJ9KVxuXG5cdFx0XHRcdC8vIEFzc2lnbiBuZXcgZGF0YSBzb3VyY2UgdG8gY2hhcnRcblx0XHRcdFx0dGhpcy5fY2hhcnRXaWRnZXQuc2V0RGF0YVNvdXJjZShuZXdEUyk7XG5cblx0XHRcdFx0Ly8gUmVtb3ZlIHRlbXBvcmFyeSBhcnJheVxuXHRcdFx0XHR0aGlzLl90ZW1wRFMgPSBudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgbmV3IGVudHJ5XG5cdFx0XHRkcy5hZGQobmV3RW50cnkpO1xuXG5cdFx0XHQvLyBSZW1vdmUgZmlyc3QgaXRlbSBpZiBuZWVkZWRcblx0XHRcdGlmIChkcy50b3RhbCgpID4gdGhpcy5fbWF4VmFsdWVzKVxuXHRcdFx0XHRkcy5yZW1vdmUoZHMuYXQoMCkpO1xuXHRcdH1cblx0fVxuXG5cdGdldCBfZGF0YVNvdXJjZSgpXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fY2hhcnRXaWRnZXQuZGF0YVNvdXJjZTtcblx0fVxuXG5cdF9vblBhdXNlQ2hhbmdlKClcblx0e1xuXHRcdC8vIE5vdGhpbmcgdG8gZG8sIHNob3VsZCBiZSBvdmVycmlkZGVuXG5cdH1cbn1cblxuLy8gREVGSU5FIENPTVBPTkVOVFxuaWYgKCF3aW5kb3cuY3VzdG9tRWxlbWVudHMuZ2V0KCdiYXNlLWNoYXJ0JykpXG5cdHdpbmRvdy5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ2Jhc2UtY2hhcnQnLCBCYXNlQ2hhcnQpO1xuIiwiaW1wb3J0IHtieXRlc1RvU2l6ZSwga0J5dGVzVG9TaXplfSBmcm9tICcuLi8uLi91dGlscy91dGlsaXRpZXMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkRGF0ZVRpbWUoZGF0ZSwgZm9ybWF0ID0gJ2RkIE1NTSBISDptbTpzcycpXG57XG5cdHJldHVybiBrZW5kby50b1N0cmluZyhkYXRlLCBmb3JtYXQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QmFzaWNTaGFyZWRUZW1wbGF0ZSh2YWx1ZUZvcm1hdCA9ICd7MH0nKSB7XG5cdHJldHVybiBrZW5kby50ZW1wbGF0ZShgXG5cdFx0PGRpdiBjbGFzcz1cImNoYXJ0LXRvb2x0aXAtY2F0ZWdvcnlcIj48c3Ryb25nPiM6IGNhdGVnb3J5ICM8L3N0cm9uZz48L2Rpdj5cblx0XHQjIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7ICNcblx0XHQ8ZGl2PlxuXHRcdFx0PGkgY2xhc3M9XCJmYXMgZmEtc3F1YXJlXCIgc3R5bGU9XCJjb2xvcjogIzogcG9pbnRzW2ldLmNvbG9yICMgXCI+PC9pPlxuXHRcdFx0IzogcG9pbnRzW2ldLnNlcmllcy5uYW1lIyA6ICM6IGtlbmRvLmZvcm1hdCgnJHt2YWx1ZUZvcm1hdH0nLCBwb2ludHNbaV0udmFsdWUpICNcblx0XHQ8L2Rpdj5cblx0XHQjIH0gI1xuXHRgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1lbW9yeVNoYXJlZFRlbXBsYXRlKCkge1xuXHRyZXR1cm4gZnVuY3Rpb24oZGF0YUl0ZW0pIHtcblx0XHRkYXRhSXRlbS5ieXRlc1RvU2l6ZSA9IGJ5dGVzVG9TaXplOyAvLyBQYXNzIGJ5dGVzVG9TaXplIHV0aWxpdHkgZnVuY3Rpb24gdG8gdGVtcGxhdGVcblx0XHRyZXR1cm4ga2VuZG8udGVtcGxhdGUoYFxuXHRcdFx0PGRpdiBjbGFzcz1cImNoYXJ0LXRvb2x0aXAtY2F0ZWdvcnlcIj48c3Ryb25nPiM6IGNhdGVnb3J5ICM8L3N0cm9uZz48L2Rpdj5cblx0XHRcdCMgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHsgI1xuXHRcdFx0PGRpdj5cblx0XHRcdFx0PGkgY2xhc3M9XCJmYXMgZmEtc3F1YXJlXCIgc3R5bGU9XCJjb2xvcjogIzogcG9pbnRzW2ldLmNvbG9yICMgXCI+PC9pPlxuXHRcdFx0XHQjOiBwb2ludHNbaV0uc2VyaWVzLm5hbWUjIDogIzogYnl0ZXNUb1NpemUocG9pbnRzW2ldLnZhbHVlKSAjXG5cdFx0XHQ8L2Rpdj5cblx0XHRcdCMgfSAjXG5cdFx0YCkoZGF0YUl0ZW0pO1xuXHR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWVtb3J5VmFsdWVBeGlzTGFiZWxUZW1wbGF0ZSgpIHtcblx0cmV0dXJuIGZ1bmN0aW9uKGRhdGFJdGVtKSB7XG5cdFx0ZGF0YUl0ZW0uYnl0ZXNUb1NpemUgPSBieXRlc1RvU2l6ZTsgLy8gUGFzcyBieXRlc1RvU2l6ZSB1dGlsaXR5IGZ1bmN0aW9uIHRvIHRlbXBsYXRlXG5cdFx0cmV0dXJuIGtlbmRvLnRlbXBsYXRlKGBcblx0XHRcdCM6IGJ5dGVzVG9TaXplKHZhbHVlKSAjXG5cdFx0YCkoZGF0YUl0ZW0pO1xuXHR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmV0d29ya1NoYXJlZFRlbXBsYXRlKGNhdGVnb3J5Rm9ybWF0ID0gJ2RkIE1NTSBISDptbTpzcycpIHtcblx0cmV0dXJuIGZ1bmN0aW9uKGRhdGFJdGVtKSB7XG5cdFx0ZGF0YUl0ZW0ua0J5dGVzVG9TaXplID0ga0J5dGVzVG9TaXplOyAvLyBQYXNzIGtCeXRlc1RvU2l6ZSB1dGlsaXR5IGZ1bmN0aW9uIHRvIHRlbXBsYXRlXG5cdFx0cmV0dXJuIGtlbmRvLnRlbXBsYXRlKGBcblx0XHRcdDxkaXYgY2xhc3M9XCJjaGFydC10b29sdGlwLWNhdGVnb3J5XCI+PHN0cm9uZz4jOiBrZW5kby50b1N0cmluZyhjYXRlZ29yeSwgJyR7Y2F0ZWdvcnlGb3JtYXR9JykgIzwvc3Ryb25nPjwvZGl2PlxuXHRcdFx0IyBmb3IgKHZhciBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkrKykgeyAjXG5cdFx0XHQ8ZGl2PlxuXHRcdFx0XHQ8aSBjbGFzcz1cImZhcyBmYS1zcXVhcmVcIiBzdHlsZT1cImNvbG9yOiAjOiBwb2ludHNbaV0uY29sb3IgIyBcIj48L2k+XG5cdFx0XHRcdCM6IHBvaW50c1tpXS5zZXJpZXMubmFtZSMgOiAjOiBrQnl0ZXNUb1NpemUocG9pbnRzW2ldLnZhbHVlLCAxLCAnJywgJy9zJykgI1xuXHRcdFx0PC9kaXY+XG5cdFx0XHQjIH0gI1xuXHRcdGApKGRhdGFJdGVtKTtcblx0fTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE5ldHdvcmtWYWx1ZUF4aXNMYWJlbFRlbXBsYXRlKCkge1xuXHRyZXR1cm4gZnVuY3Rpb24oZGF0YUl0ZW0pIHtcblx0XHRkYXRhSXRlbS5rQnl0ZXNUb1NpemUgPSBrQnl0ZXNUb1NpemU7IC8vIFBhc3Mga0J5dGVzVG9TaXplIHV0aWxpdHkgZnVuY3Rpb24gdG8gdGVtcGxhdGVcblx0XHRyZXR1cm4ga2VuZG8udGVtcGxhdGUoYFxuXHRcdFx0Izoga0J5dGVzVG9TaXplKHZhbHVlLCAxLCAnJywgJy9zJykgI1xuXHRcdGApKGRhdGFJdGVtKTtcblx0fTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVzZXJDb3VudFNoYXJlZFRlbXBsYXRlKGNhdGVnb3J5Rm9ybWF0ID0gJ2RkIE1NTSBISDptbTpzcycpIHtcblx0cmV0dXJuIGZ1bmN0aW9uKGRhdGFJdGVtKSB7XG5cdFx0cmV0dXJuIGtlbmRvLnRlbXBsYXRlKGBcblx0XHRcdDxkaXYgY2xhc3M9XCJjaGFydC10b29sdGlwLWNhdGVnb3J5XCI+PHN0cm9uZz4jOiBrZW5kby50b1N0cmluZyhjYXRlZ29yeSwgJyR7Y2F0ZWdvcnlGb3JtYXR9JykgIzwvc3Ryb25nPjwvZGl2PlxuXHRcdFx0IyBmb3IgKHZhciBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkrKykgeyAjXG5cdFx0XHQ8ZGl2PlxuXHRcdFx0XHQ8aSBjbGFzcz1cImZhcyBmYS1zcXVhcmVcIiBzdHlsZT1cImNvbG9yOiAjOiBwb2ludHNbaV0uY29sb3IgIyBcIj48L2k+XG5cdFx0XHRcdCM6IHBvaW50c1tpXS5zZXJpZXMubmFtZSMgOiAjOiBwb2ludHNbaV0udmFsdWUgI1xuXHRcdFx0PC9kaXY+XG5cdFx0XHQjIH0gI1xuXHRcdGApKGRhdGFJdGVtKTtcblx0fTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRpbWVSYW5nZVRvb2x0aXBUZW1wbGF0ZSgpIHtcblx0cmV0dXJuIGZ1bmN0aW9uKGRhdGFJdGVtKSB7XG5cdFx0ZGF0YUl0ZW0uZ2V0VG9vbHRpcFN0cmluZyA9IGZ1bmN0aW9uKHYxLCB2Mikge1xuXHRcdFx0aWYgKHYxID09IHYyKVxuXHRcdFx0e1xuXHRcdFx0XHRpZiAodjIgPT0gLTI0KVxuXHRcdFx0XHRcdHYyID0gLTIzO1xuXG5cdFx0XHRcdHYxID0gdjIgLSAxO1xuXHRcdFx0fVxuXG5cdFx0XHRsZXQgc3RhcnQgPSBNYXRoLmFicyh2MSk7XG5cdFx0XHRsZXQgZW5kID0gTWF0aC5hYnModjIpO1xuXG5cdFx0XHRyZXR1cm4gYEZyb20gJHtzdGFydH0gaG91ciR7c3RhcnQgIT0gMSA/ICdzJyA6ICcnfSBhZ28gdG8gJHtlbmQgPiAwID8gKCd0byAnICsgZW5kICsgJyBob3VyJyArIChlbmQgIT0gMSA/ICdzJyA6ICcnKSArICcgYWdvJykgOiAnbm93J31gO1xuXHRcdH07IC8vIFBhc3MgdXRpbGl0eSBmdW5jdGlvbiB0byB0ZW1wbGF0ZVxuXHRcdHJldHVybiBrZW5kby50ZW1wbGF0ZShgXG5cdFx0XHQjOiBnZXRUb29sdGlwU3RyaW5nKHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQpICNcblx0XHRgKShkYXRhSXRlbSk7XG5cdH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRXUkJ5dGVzTGFiZWxUZW1wbGF0ZSgpIHtcblx0cmV0dXJuIGZ1bmN0aW9uKGRhdGFJdGVtKSB7XG5cdFx0cmV0dXJuIGtlbmRvLnRlbXBsYXRlKGBcblx0XHRcdCM6IHZhbHVlICMgIzogZGF0YUl0ZW0udW5pdCAjXG5cdFx0YCkoZGF0YUl0ZW0pO1xuXHR9O1xufVxuIiwiaW1wb3J0IHtCYXNlQ2hhcnR9IGZyb20gJy4vYmFzZS1jaGFydCc7XG5cbmltcG9ydCB7Z2V0QmFzaWNTaGFyZWRUZW1wbGF0ZSwgZ2V0Rm9ybWF0dGVkRGF0ZVRpbWV9IGZyb20gJy4vY2hhcnQtdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgQ3B1VXNhZ2VDaGFydCBleHRlbmRzIEJhc2VDaGFydFxue1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0ICAgIHN1cGVyKDEyMCk7XG5cdH1cblxuXHRfaW5pdENoYXJ0V2lkZ2V0KGNoYXJ0SHRtbClcblx0e1xuXHRcdHJldHVybiBjaGFydEh0bWwua2VuZG9DaGFydCh7XG5cdFx0XHR0cmFuc2l0aW9uczogZmFsc2UsXG5cdFx0XHRjaGFydEFyZWE6IHtcblx0XHRcdFx0aGVpZ2h0OiAxMjBcblx0XHRcdH0sXG5cdCAgICAgICAgbGVnZW5kOiB7XG5cdCAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXJpZXNEZWZhdWx0czoge1xuXHQgICAgICAgICAgICB0eXBlOiAnYXJlYScsXG5cdCAgICAgICAgICAgIGxhYmVsczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXQ6ICd7MH0lJyxcblx0ICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICd0cmFuc3BhcmVudCdcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2VyaWVzOiBbXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRuYW1lOiAnU3lzdGVtJyxcblx0XHQgICAgICAgICAgICBmaWVsZDogJ3N5c3RlbUxvYWQnLFxuXHRcdCAgICAgICAgICAgIGNhdGVnb3J5RmllbGQ6ICd0aW1lJyxcblx0XHRcdFx0XHRjb2xvcjogdGhpcy5zeXN0ZW1Db2xvcixcblx0XHRcdFx0XHRsaW5lOiB7XG5cdFx0XHRcdFx0XHR3aWR0aDogMlxuXHRcdFx0XHRcdH1cblx0XHQgICAgICAgIH0sXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRuYW1lOiAnUHJvY2VzcycsXG5cdFx0XHRcdFx0ZmllbGQ6ICdwcm9jZXNzTG9hZCcsXG5cdFx0XHRcdFx0Y2F0ZWdvcnlGaWVsZDogJ3RpbWUnLFxuXHRcdFx0XHRcdGNvbG9yOiB0aGlzLnByb2Nlc3NDb2xvcixcblx0XHRcdFx0XHRsaW5lOiB7XG5cdFx0XHRcdFx0XHR3aWR0aDogMlxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XSxcblx0ICAgICAgICB2YWx1ZUF4aXM6IHtcblx0ICAgICAgICAgICAgbGFiZWxzOiB7XG5cdCAgICAgICAgICAgICAgICBmb3JtYXQ6ICd7MH0lJ1xuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICBsaW5lOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtaW46IDAsXG5cdCAgICBcdFx0bWF4OiAxMDBcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGNhdGVnb3J5QXhpczoge1xuXHQgICAgICAgICAgICBtYWpvckdyaWRMaW5lczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICAgICAgfSxcblx0XHRcdFx0bWFqb3JUaWNrczoge1xuXHRcdFx0XHRcdHZpc2libGU6IGZhbHNlXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGxhYmVsczoge1xuXHRcdFx0XHRcdHZpc2libGU6IGZhbHNlXG5cdFx0XHRcdH1cblx0ICAgICAgICB9LFxuXHRcdFx0dG9vbHRpcDoge1xuXHRcdFx0XHRzaGFyZWQ6IHRydWUsXG5cdCAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG5cdFx0XHRcdHNoYXJlZFRlbXBsYXRlOiBnZXRCYXNpY1NoYXJlZFRlbXBsYXRlKCd7MH0lJyksXG5cdFx0XHRcdGJhY2tncm91bmQ6ICcjZTRlNGU0J1xuXHQgICAgICAgIH1cblx0ICAgIH0pLmRhdGEoJ2tlbmRvQ2hhcnQnKTtcblx0fVxuXG5cdGdldCBzeXN0ZW1Db2xvcigpXG5cdHtcblx0XHRyZXR1cm4gJyMzMzk5RkYnO1xuXHR9XG5cblx0Z2V0IHByb2Nlc3NDb2xvcigpXG5cdHtcblx0XHRyZXR1cm4gJyMwMDMzQ0MnO1xuXHR9XG5cblx0YWRkRW50cnkocHJvY2Vzc0xvYWQsIHN5c3RlbUxvYWQpXG5cdHtcblx0XHRsZXQgbmV3RW50cnkgPSB7XG5cdFx0XHR0aW1lOiBnZXRGb3JtYXR0ZWREYXRlVGltZShuZXcgRGF0ZSgpKSxcblx0XHRcdHByb2Nlc3NMb2FkOiBwcm9jZXNzTG9hZCxcblx0XHRcdHN5c3RlbUxvYWQ6IHN5c3RlbUxvYWRcblx0XHR9O1xuXG5cdFx0Ly8gQWRkIGVudHJ5IHRvIGNoYXJ0XG5cdFx0c3VwZXIuX2FkZEVudHJ5KG5ld0VudHJ5KTtcblx0fVxufVxuXG4vLyBERUZJTkUgQ09NUE9ORU5UXG5pZiAoIXdpbmRvdy5jdXN0b21FbGVtZW50cy5nZXQoJ2NwdS11c2FnZS1jaGFydCcpKVxuXHR3aW5kb3cuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCdjcHUtdXNhZ2UtY2hhcnQnLCBDcHVVc2FnZUNoYXJ0KTtcbiIsImltcG9ydCB7QmFzZUNoYXJ0fSBmcm9tICcuL2Jhc2UtY2hhcnQnO1xuXG5pbXBvcnQge2dldE1lbW9yeVNoYXJlZFRlbXBsYXRlLCBnZXRNZW1vcnlWYWx1ZUF4aXNMYWJlbFRlbXBsYXRlLCBnZXRGb3JtYXR0ZWREYXRlVGltZX0gZnJvbSAnLi9jaGFydC11dGlscyc7XG5cbmV4cG9ydCBjbGFzcyBNZW1vcnlDaGFydCBleHRlbmRzIEJhc2VDaGFydFxue1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0ICAgIHN1cGVyKDMwMCk7XG5cblx0XHQvLyBBcHBlbmQgdGV4dCB0byBkaXNwbGF5IGVsYXBzZWQgdGltZVxuXHRcdHRoaXMuX2VsYXBzZWRUeHQgPSAkKCc8ZGl2PicsIHtjbGFzczogJ3RleHQtY2VudGVyJywgdGV4dDogJy0tLSd9KTtcblx0XHQkKHRoaXMpLmFwcGVuZCh0aGlzLl9lbGFwc2VkVHh0KTtcblx0fVxuXG5cdF9pbml0Q2hhcnRXaWRnZXQoY2hhcnRIdG1sKVxuXHR7XG5cdFx0cmV0dXJuIGNoYXJ0SHRtbC5rZW5kb0NoYXJ0KHtcblx0XHRcdHRyYW5zaXRpb25zOiBmYWxzZSxcblx0XHRcdGNoYXJ0QXJlYToge1xuXHRcdFx0XHRoZWlnaHQ6IDI0MFxuXHRcdFx0fSxcblx0ICAgICAgICBsZWdlbmQ6IHtcblx0ICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNlcmllc0RlZmF1bHRzOiB7XG5cdCAgICAgICAgICAgIHR5cGU6ICdhcmVhJyxcblx0ICAgICAgICAgICAgbGFiZWxzOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcblx0ICAgICAgICAgICAgICAgIGZvcm1hdDogJ3swfScsXG5cdCAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAndHJhbnNwYXJlbnQnXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXJpZXM6IFt7XG5cdFx0XHRcdG5hbWU6ICdBbGxvY2F0ZWQnLFxuXHQgICAgICAgICAgICBmaWVsZDogJ2FsbG9jTWVtJyxcblx0ICAgICAgICAgICAgY2F0ZWdvcnlGaWVsZDogJ3RpbWUnLFxuXHRcdFx0XHRjb2xvcjogdGhpcy5hbGxvY2F0ZWRDb2xvcixcblx0XHRcdFx0bGluZToge1xuXHRcdFx0XHRcdHdpZHRoOiAyXG5cdFx0XHRcdH1cblx0ICAgICAgICB9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiAnVXNlZCcsXG5cdFx0XHRcdGZpZWxkOiAndXNlZE1lbScsXG5cdFx0XHRcdGNhdGVnb3J5RmllbGQ6ICd0aW1lJyxcblx0XHRcdFx0Y29sb3I6IHRoaXMudXNlZENvbG9yLFxuXHRcdFx0XHRsaW5lOiB7XG5cdFx0XHRcdFx0d2lkdGg6IDJcblx0XHRcdFx0fVxuXHRcdFx0fV0sXG5cdCAgICAgICAgdmFsdWVBeGlzOiB7XG5cdCAgICAgICAgICAgIGxhYmVsczoge1xuXHQgICAgICAgICAgICAgICAgZm9ybWF0OiAnezB9JyxcbiAgICAgIFx0XHRcdFx0dGVtcGxhdGU6IGdldE1lbW9yeVZhbHVlQXhpc0xhYmVsVGVtcGxhdGUoKVxuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICBsaW5lOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtaW46IDBcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGNhdGVnb3J5QXhpczoge1xuXHRcdFx0XHRtYWpvckdyaWRMaW5lczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICAgICAgfSxcblx0XHRcdFx0bWFqb3JUaWNrczoge1xuXHRcdFx0XHRcdHZpc2libGU6IGZhbHNlXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGxhYmVsczoge1xuXHRcdFx0XHRcdHZpc2libGU6IGZhbHNlXG5cdFx0XHRcdH1cblx0ICAgICAgICB9LFxuXHQgICAgICAgIHRvb2x0aXA6IHtcblx0XHRcdFx0c2hhcmVkOiB0cnVlLFxuXHQgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuXHRcdFx0XHRzaGFyZWRUZW1wbGF0ZTogZ2V0TWVtb3J5U2hhcmVkVGVtcGxhdGUoKSxcblx0XHRcdFx0YmFja2dyb3VuZDogJyNlNGU0ZTQnXG5cdCAgICAgICAgfVxuXHQgICAgfSkuZGF0YSgna2VuZG9DaGFydCcpO1xuXHR9XG5cblx0Z2V0IGFsbG9jYXRlZENvbG9yKClcblx0e1xuXHRcdHJldHVybiAnIzMzOTlGRic7XG5cdH1cblxuXHRnZXQgdXNlZENvbG9yKClcblx0e1xuXHRcdHJldHVybiAnIzAwMzNDQyc7XG5cdH1cblxuXHRhZGRFbnRyeShhbGxvY01lbSwgdXNlZE1lbSlcblx0e1xuXHRcdGxldCBub3cgPSBuZXcgRGF0ZSgpO1xuXG5cdFx0bGV0IG5ld0VudHJ5ID0ge1xuXHRcdFx0dGltZTogZ2V0Rm9ybWF0dGVkRGF0ZVRpbWUobm93KSxcblx0XHRcdHRpbWVzdGFtcDogbm93LmdldFRpbWUoKSxcblx0XHRcdGFsbG9jTWVtOiBhbGxvY01lbSxcblx0XHRcdHVzZWRNZW06IHVzZWRNZW1cblx0XHR9O1xuXG5cdFx0Ly8gQWRkIGVudHJ5IHRvIGNoYXJ0XG5cdFx0c3VwZXIuX2FkZEVudHJ5KG5ld0VudHJ5KTtcblxuXHRcdC8vIFVwZGF0ZSB4IGF4aXNcblx0XHRpZiAoIXRoaXMuaXNQYXVzZWQpXG5cdFx0XHR0aGlzLl91cGRhdGVFbGFwc2VkVGV4dCgpO1xuXHR9XG5cblx0X3VwZGF0ZUVsYXBzZWRUZXh0KClcblx0e1xuXHRcdGxldCBkcyA9IHRoaXMuX2RhdGFTb3VyY2U7XG5cblx0XHRpZiAoZHMudG90YWwoKSA+IDEpXG5cdFx0e1xuXHRcdFx0Ly8gR2V0IGF4aXMgbGltaXRzXG5cdFx0XHRjb25zdCBjaGFydE1pbmltdW0gPSBkcy5hdCgwKS50aW1lc3RhbXA7XG5cdFx0XHRjb25zdCBjaGFydE1heGltdW0gPSBkcy5hdChkcy50b3RhbCgpIC0gMSkudGltZXN0YW1wO1xuXG5cdFx0XHQvLyBTZXQgZWxhcHNlZCB0ZXh0XG5cdFx0XHRsZXQgc2Vjb25kcyA9IE1hdGgucm91bmQoIChjaGFydE1heGltdW0gLSBjaGFydE1pbmltdW0pIC8gMTAwMCApO1xuXHRcdFx0bGV0IHRpdGxlO1xuXG5cdFx0XHRpZiAoc2Vjb25kcyA8IDYwKVxuXHRcdFx0XHR0aXRsZSA9ICdMYXN0ICcgKyAoc2Vjb25kcyAhPSAxID8gc2Vjb25kcyArICcgc2Vjb25kcycgOiAnc2Vjb25kJyk7XG5cdFx0XHRlbHNlXG5cdFx0XHR7XG5cdFx0XHRcdGNvbnN0IG1pbnV0ZXMgPSBNYXRoLmZsb29yKHNlY29uZHMgLyA2MCk7XG5cdFx0XHRcdHRpdGxlID0gJ0xhc3QgJyArIChtaW51dGVzICE9IDEgPyBtaW51dGVzICsgJyBtaW51dGVzJyA6ICdtaW51dGUnKTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5fZWxhcHNlZFR4dC50ZXh0KHRpdGxlKTtcblx0XHR9XG5cdH1cbn1cblxuLy8gREVGSU5FIENPTVBPTkVOVFxuaWYgKCF3aW5kb3cuY3VzdG9tRWxlbWVudHMuZ2V0KCdtZW1vcnktY2hhcnQnKSlcblx0d2luZG93LmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnbWVtb3J5LWNoYXJ0JywgTWVtb3J5Q2hhcnQpO1xuIiwiaW1wb3J0IHtnZXROZXR3b3JrU2hhcmVkVGVtcGxhdGUsIGdldE5ldHdvcmtWYWx1ZUF4aXNMYWJlbFRlbXBsYXRlfSBmcm9tICcuL2NoYXJ0LXV0aWxzJztcbmltcG9ydCAqIGFzIG1vbWVudCBmcm9tICdtb21lbnQnO1xuXG5leHBvcnQgY2xhc3MgTmV0d29yazI0aENoYXJ0IGV4dGVuZHMgSFRNTEVsZW1lbnRcbntcblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdCAgICBzdXBlcigpO1xuXG5cdFx0dGhpcy5fbGFzdFRvdGFsT3V0ID0gMDtcblx0XHR0aGlzLl9sYXN0VG90YWxJbiA9IDA7XG5cdFx0dGhpcy5fbGFzdERhdGUgPSBuZXcgRGF0ZSgpO1xuXHRcdHRoaXMuX3NhbXBsaW5nUmF0ZVNlY29uZHMgPSAwO1xuXG5cdFx0Ly8gQ3JlYXRlIGNoYXJ0IGh0bWxcblx0XHRsZXQgY2hhcnRIdG1sID0gJCgnPGRpdj4nKTtcblx0XHQkKHRoaXMpLmFwcGVuZChjaGFydEh0bWwpO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSBjaGFydFxuXHRcdHRoaXMuX2NoYXJ0V2lkZ2V0ID0gdGhpcy5faW5pdENoYXJ0V2lkZ2V0KGNoYXJ0SHRtbCk7XG5cdH1cblxuXHRfaW5pdENoYXJ0V2lkZ2V0KGNoYXJ0SHRtbClcblx0e1xuXHRcdHJldHVybiBjaGFydEh0bWwua2VuZG9DaGFydCh7XG5cdFx0XHR0cmFuc2l0aW9uczogZmFsc2UsXG5cdFx0XHRjaGFydEFyZWE6IHtcblx0XHRcdFx0aGVpZ2h0OiAyNzAsXG5cdFx0XHRcdGJhY2tncm91bmQ6ICd0cmFuc3BhcmVudCdcblx0XHRcdH0sXG5cdCAgICAgICAgbGVnZW5kOiB7XG5cdCAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXJpZXNEZWZhdWx0czoge1xuXHQgICAgICAgICAgICB0eXBlOiAnYXJlYScsXG5cdCAgICAgICAgICAgIGxhYmVsczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXQ6ICd7MH0nLFxuXHQgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJ3RyYW5zcGFyZW50J1xuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2VyaWVzOiBbe1xuXHRcdFx0XHRuYW1lOiAnT3V0Z29pbmcnLFxuXHQgICAgICAgICAgICBmaWVsZDogJ291dGdvaW5nJyxcblx0ICAgICAgICAgICAgY2F0ZWdvcnlGaWVsZDogJ3RpbWUnLFxuXHRcdFx0XHRjb2xvcjogJyNDQzAwMDAnLFxuXHRcdFx0XHRsaW5lOiB7XG5cdFx0XHRcdFx0d2lkdGg6IDJcblx0XHRcdFx0fVxuXHQgICAgICAgIH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6ICdJbmNvbWluZycsXG5cdFx0XHRcdGZpZWxkOiAnaW5jb21pbmcnLFxuXHRcdFx0XHRjYXRlZ29yeUZpZWxkOiAndGltZScsXG5cdFx0XHRcdGNvbG9yOiAnIzAwOTkwMCcsXG5cdFx0XHRcdGxpbmU6IHtcblx0XHRcdFx0XHR3aWR0aDogMlxuXHRcdFx0XHR9XG5cdFx0XHR9XSxcblx0ICAgICAgICB2YWx1ZUF4aXM6IHtcblx0ICAgICAgICAgICAgbGFiZWxzOiB7XG5cdCAgICAgICAgICAgICAgICBmb3JtYXQ6ICd7MH0nLFxuICAgICAgXHRcdFx0XHR0ZW1wbGF0ZTogZ2V0TmV0d29ya1ZhbHVlQXhpc0xhYmVsVGVtcGxhdGUoKVxuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICBsaW5lOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtaW46IDBcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGNhdGVnb3J5QXhpczoge1xuXHRcdFx0XHRtYWpvckdyaWRMaW5lczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcblx0XHRcdFx0XHRzdGVwOiA2MFxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtYWpvclRpY2tzOiB7XG5cdFx0XHRcdFx0dmlzaWJsZTogdHJ1ZSxcblx0XHRcdFx0XHRzdGVwOiA2MFxuXHRcdFx0XHR9LFxuXHRcdFx0XHRsYWJlbHM6IHtcblx0XHRcdFx0XHR2aXNpYmxlOiB0cnVlLFxuXHRcdFx0XHRcdHN0ZXA6IDYwXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGJhc2VVbml0OiAnbWludXRlcycsXG5cdFx0XHRcdHR5cGU6ICdkYXRlJyxcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHRvb2x0aXA6IHtcblx0XHRcdFx0c2hhcmVkOiB0cnVlLFxuXHQgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuXHRcdFx0XHRzaGFyZWRUZW1wbGF0ZTogZ2V0TmV0d29ya1NoYXJlZFRlbXBsYXRlKCdkZCBNTU0gSEg6bW0nKSxcblx0XHRcdFx0YmFja2dyb3VuZDogJyNlNGU0ZTQnXG5cdCAgICAgICAgfVxuXHQgICAgfSkuZGF0YSgna2VuZG9DaGFydCcpO1xuXHR9XG5cblx0cmVkcmF3KClcblx0e1xuXHRcdHRoaXMuX2NoYXJ0V2lkZ2V0LnJlZHJhdygpO1xuXHR9XG5cblx0c2V0IHJhbmdlKHZhbHVlcylcblx0e1xuXHRcdHRoaXMuX3JhbmdlID0gdmFsdWVzO1xuXG5cdFx0dGhpcy5fdXBkYXRlWEF4aXNMaW1pdHMoKTtcblx0fVxuXG5cdGdldCByYW5nZSgpXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fcmFuZ2U7XG5cdH1cblxuXHRhZGRIaXN0b3J5RW50cmllcyhvdXRnb2luZ0RhdGEsIGluY29taW5nRGF0YSwgc2FtcGxpbmdSYXRlU2Vjb25kcywgc2hpZnRTZWNvbmRzKVxuXHR7XG5cdFx0dGhpcy5fc2FtcGxpbmdSYXRlU2Vjb25kcyA9IHNhbXBsaW5nUmF0ZVNlY29uZHM7XG5cblx0XHRsZXQgbm93ID0gbmV3IERhdGUoKTtcblxuXHRcdC8vIE5PVEU6IG91dGdvaW5nRGF0YSBhbmQgaW5jb21pbkRhdGEgYXJlIHN1cHBvc2VkIHRvIGhhdmUgdGhlIHNhbWUgc2l6ZSEhIVxuXG5cdFx0aWYgKG91dGdvaW5nRGF0YS5sZW5ndGggPiAwKVxuXHRcdHtcblx0XHRcdGxldCBzdGFydCA9IG1vbWVudChub3cpO1xuXHRcdFx0c3RhcnQuc3VidHJhY3QoKHNhbXBsaW5nUmF0ZVNlY29uZHMgKiBvdXRnb2luZ0RhdGEubGVuZ3RoKSArIHNoaWZ0U2Vjb25kcywgJ3MnKVxuXG5cdFx0XHR0aGlzLl9sYXN0VG90YWxPdXQgPSBvdXRnb2luZ0RhdGFbMF07XG5cdFx0XHR0aGlzLl9sYXN0VG90YWxJbiA9IGluY29taW5nRGF0YVswXTtcblx0XHRcdHRoaXMuX2xhc3REYXRlID0gc3RhcnQudG9EYXRlKCk7XG5cblx0XHRcdGlmIChvdXRnb2luZ0RhdGEubGVuZ3RoID4gMSlcblx0XHRcdHtcblx0XHRcdFx0bGV0IGRhdGFTb3VyY2UgPSBuZXcga2VuZG8uZGF0YS5EYXRhU291cmNlKCk7XG5cblx0XHRcdFx0Zm9yIChsZXQgaSA9IDE7IGkgPCBvdXRnb2luZ0RhdGEubGVuZ3RoOyBpKyspXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRjb25zdCB0b3RhbE91dCA9IG91dGdvaW5nRGF0YVtpXTtcblx0XHRcdFx0XHRjb25zdCB0b3RhbEluID0gaW5jb21pbmdEYXRhW2ldO1xuXG5cdFx0XHRcdFx0bGV0IGRhdGUgPSBzdGFydC5jbG9uZSgpO1xuXHRcdFx0XHRcdGRhdGUuYWRkKGkgKiBzYW1wbGluZ1JhdGVTZWNvbmRzLCAncycpO1xuXG5cdFx0XHRcdFx0dGhpcy5hZGRFbnRyeSh0b3RhbE91dCwgdG90YWxJbiwgZGF0YVNvdXJjZSwgZGF0ZS50b0RhdGUoKSwgZmFsc2UpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQXNzaWduIGRhdGFzb3VyY2UgdG8gY2hhcnRcblx0XHRcdFx0dGhpcy5fY2hhcnRXaWRnZXQuc2V0RGF0YVNvdXJjZShkYXRhU291cmNlKTtcblxuXHRcdFx0XHQvLyBVcGRhdGUgYXhpc1xuXHRcdFx0XHR0aGlzLl91cGRhdGVYQXhpc0xpbWl0cygpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRlbHNlXG5cdFx0e1xuXHRcdFx0dGhpcy5fbGFzdFRvdGFsT3V0ID0gMDtcblx0XHRcdHRoaXMuX2xhc3RUb3RhbEluID0gMDtcblx0XHRcdHRoaXMuX2xhc3REYXRlID0gbm93O1xuXHRcdH1cblx0fVxuXG5cdGFkZEVudHJ5KHRvdGFsT3V0LCB0b3RhbEluLCBkYXRhU291cmNlID0gbnVsbCwgZGF0ZSA9IG51bGwsIHVwZGF0ZUF4aXMgPSB0cnVlKVxuXHR7XG5cdFx0aWYgKGRhdGUgPT0gbnVsbClcblx0XHRcdGRhdGUgPSBuZXcgRGF0ZSgpO1xuXG5cdFx0Y29uc3QgZWxhcHNlZFNlY3MgPSBNYXRoLnJvdW5kKChkYXRlLmdldFRpbWUoKSAtIHRoaXMuX2xhc3REYXRlLmdldFRpbWUoKSkgLyAxMDAwKTtcblxuXHRcdC8vIFRoZSAyNGggY2hhcnQgaXMgdXBkYXRlZCBhdCB0aGUgc2FtZSBzYW1wbGluZyByYXRlIHVzZWQgYnkgdGhlIHNlcnZlciB0byBzYXZlIHRoZSB0cmFmZmljIGhpc3Rvcnlcblx0XHRpZiAoZWxhcHNlZFNlY3MgPj0gdGhpcy5fc2FtcGxpbmdSYXRlU2Vjb25kcylcblx0XHR7XG5cdFx0XHRsZXQgbmV3RW50cnkgPSB7XG5cdFx0XHRcdHRpbWU6IGRhdGUsXG5cdFx0XHRcdG91dGdvaW5nOiBNYXRoLnJvdW5kKCh0b3RhbE91dCAtIHRoaXMuX2xhc3RUb3RhbE91dCkgLyBlbGFwc2VkU2VjcyksXG5cdFx0XHRcdGluY29taW5nOiBNYXRoLnJvdW5kKCh0b3RhbEluIC0gdGhpcy5fbGFzdFRvdGFsSW4pIC8gZWxhcHNlZFNlY3MpXG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBBZGQgZW50cnkgdG8gZGF0YSBzb3VyY2Vcblx0XHRcdGlmIChkYXRhU291cmNlID09IG51bGwpXG5cdFx0XHRcdGRhdGFTb3VyY2UgPSB0aGlzLl9kYXRhU291cmNlO1xuXG5cdFx0XHRkYXRhU291cmNlLmFkZChuZXdFbnRyeSk7XG5cblx0XHRcdHRoaXMuX2xhc3RUb3RhbE91dCA9IHRvdGFsT3V0O1xuXHRcdFx0dGhpcy5fbGFzdFRvdGFsSW4gPSB0b3RhbEluO1xuXHRcdFx0dGhpcy5fbGFzdERhdGUgPSBkYXRlO1xuXG5cdFx0XHRpZiAodXBkYXRlQXhpcylcblx0XHRcdFx0dGhpcy5fdXBkYXRlWEF4aXNMaW1pdHMoKTtcblx0XHR9XG5cdH1cblxuXHRfdXBkYXRlWEF4aXNMaW1pdHMoKVxuXHR7XG5cdFx0bGV0IGRzID0gdGhpcy5fZGF0YVNvdXJjZTtcblxuXHRcdGlmIChkcy50b3RhbCgpID4gMClcblx0XHR7XG5cdFx0XHRjb25zdCBjaGFydE1pbmltdW0gPSBtb21lbnQodGhpcy5fbGFzdERhdGUpLmFkZCh0aGlzLl9yYW5nZVswXSwgJ2gnKTtcblx0XHRcdGNvbnN0IGNoYXJ0TWF4aW11bSA9IG1vbWVudCh0aGlzLl9sYXN0RGF0ZSkuYWRkKHRoaXMuX3JhbmdlWzFdLCAnaCcpO1xuXG5cdFx0XHR0aGlzLl9jaGFydFdpZGdldC5vcHRpb25zLmNhdGVnb3J5QXhpcy5taW4gPSBjaGFydE1pbmltdW0udG9EYXRlKCk7XG5cdFx0XHR0aGlzLl9jaGFydFdpZGdldC5vcHRpb25zLmNhdGVnb3J5QXhpcy5tYXggPSBjaGFydE1heGltdW0udG9EYXRlKCk7XG5cblx0XHRcdHRoaXMuX2NoYXJ0V2lkZ2V0LnJlZHJhdygpO1xuXHRcdH1cblx0fVxuXG5cdGdldCBfZGF0YVNvdXJjZSgpXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fY2hhcnRXaWRnZXQuZGF0YVNvdXJjZTtcblx0fVxufVxuXG4vLyBERUZJTkUgQ09NUE9ORU5UXG5pZiAoIXdpbmRvdy5jdXN0b21FbGVtZW50cy5nZXQoJ25ldHdvcmstMjRoLWNoYXJ0JykpXG5cdHdpbmRvdy5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ25ldHdvcmstMjRoLWNoYXJ0JywgTmV0d29yazI0aENoYXJ0KTtcbiIsImltcG9ydCB7QmFzZUNoYXJ0fSBmcm9tICcuL2Jhc2UtY2hhcnQnO1xuXG5pbXBvcnQge2dldE5ldHdvcmtTaGFyZWRUZW1wbGF0ZSwgZ2V0TmV0d29ya1ZhbHVlQXhpc0xhYmVsVGVtcGxhdGUsIGdldEZvcm1hdHRlZERhdGVUaW1lfSBmcm9tICcuL2NoYXJ0LXV0aWxzJztcblxuZXhwb3J0IGNsYXNzIE5ldHdvcmtSZWFsdGltZUNoYXJ0IGV4dGVuZHMgQmFzZUNoYXJ0XG57XG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHQgICAgc3VwZXIoMzAwKTtcblxuXHRcdHRoaXMuX2xhc3RUb3RhbEtiT3V0ID0gMDtcblx0XHR0aGlzLl9sYXN0VG90YWxLYkluID0gMDtcblx0XHR0aGlzLl9sYXN0VGltZSA9IDA7XG5cblx0XHQvLyBBcHBlbmQgdGV4dCB0byBkaXNwbGF5IGVsYXBzZWQgdGltZVxuXHRcdHRoaXMuX2VsYXBzZWRUeHQgPSAkKCc8ZGl2PicsIHtjbGFzczogJ3RleHQtY2VudGVyJywgdGV4dDogJy0tLSd9KTtcblx0XHQkKHRoaXMpLmFwcGVuZCh0aGlzLl9lbGFwc2VkVHh0KTtcblx0fVxuXG5cdF9pbml0Q2hhcnRXaWRnZXQoY2hhcnRIdG1sKVxuXHR7XG5cdFx0cmV0dXJuIGNoYXJ0SHRtbC5rZW5kb0NoYXJ0KHtcblx0XHRcdHRyYW5zaXRpb25zOiBmYWxzZSxcblx0XHRcdGNoYXJ0QXJlYToge1xuXHRcdFx0XHRoZWlnaHQ6IDI3MCxcblx0XHRcdFx0YmFja2dyb3VuZDogJ3RyYW5zcGFyZW50J1xuXHRcdFx0fSxcblx0ICAgICAgICBsZWdlbmQ6IHtcblx0ICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNlcmllc0RlZmF1bHRzOiB7XG5cdCAgICAgICAgICAgIHR5cGU6ICdhcmVhJyxcblx0ICAgICAgICAgICAgbGFiZWxzOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcblx0ICAgICAgICAgICAgICAgIGZvcm1hdDogJ3swfScsXG5cdCAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAndHJhbnNwYXJlbnQnXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXJpZXM6IFt7XG5cdFx0XHRcdG5hbWU6ICdPdXRnb2luZycsXG5cdCAgICAgICAgICAgIGZpZWxkOiAnb3V0Z29pbmcnLFxuXHQgICAgICAgICAgICBjYXRlZ29yeUZpZWxkOiAndGltZScsXG5cdFx0XHRcdGNvbG9yOiB0aGlzLm91dGdvaW5nQ29sb3IsXG5cdFx0XHRcdGxpbmU6IHtcblx0XHRcdFx0XHR3aWR0aDogMlxuXHRcdFx0XHR9XG5cdCAgICAgICAgfSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogJ0luY29taW5nJyxcblx0XHRcdFx0ZmllbGQ6ICdpbmNvbWluZycsXG5cdFx0XHRcdGNhdGVnb3J5RmllbGQ6ICd0aW1lJyxcblx0XHRcdFx0Y29sb3I6IHRoaXMuaW5jb21pbmdDb2xvcixcblx0XHRcdFx0bGluZToge1xuXHRcdFx0XHRcdHdpZHRoOiAyXG5cdFx0XHRcdH1cblx0XHRcdH1dLFxuXHQgICAgICAgIHZhbHVlQXhpczoge1xuXHQgICAgICAgICAgICBsYWJlbHM6IHtcblx0ICAgICAgICAgICAgICAgIGZvcm1hdDogJ3swfScsXG4gICAgICBcdFx0XHRcdHRlbXBsYXRlOiBnZXROZXR3b3JrVmFsdWVBeGlzTGFiZWxUZW1wbGF0ZSgpXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgIGxpbmU6IHtcblx0ICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgICAgIH0sXG5cdFx0XHRcdG1pbjogMCxcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGNhdGVnb3J5QXhpczoge1xuXHRcdFx0XHRtYWpvckdyaWRMaW5lczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICAgICAgfSxcblx0XHRcdFx0bWFqb3JUaWNrczoge1xuXHRcdFx0XHRcdHZpc2libGU6IGZhbHNlXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGxhYmVsczoge1xuXHRcdFx0XHRcdHZpc2libGU6IGZhbHNlXG5cdFx0XHRcdH1cblx0ICAgICAgICB9LFxuXHQgICAgICAgIHRvb2x0aXA6IHtcblx0XHRcdFx0c2hhcmVkOiB0cnVlLFxuXHQgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuXHRcdFx0XHRzaGFyZWRUZW1wbGF0ZTogZ2V0TmV0d29ya1NoYXJlZFRlbXBsYXRlKCksXG5cdFx0XHRcdGJhY2tncm91bmQ6ICcjZTRlNGU0J1xuXHQgICAgICAgIH1cblx0ICAgIH0pLmRhdGEoJ2tlbmRvQ2hhcnQnKTtcblx0fVxuXG5cdGdldCBvdXRnb2luZ0NvbG9yKClcblx0e1xuXHRcdHJldHVybiAnI0NDMDAwMCc7XG5cdH1cblxuXHRnZXQgaW5jb21pbmdDb2xvcigpXG5cdHtcblx0XHRyZXR1cm4gJyMwMDk5MDAnO1xuXHR9XG5cblx0YWRkRW50cnkodG90YWxPdXRLYiwgdG90YWxJbktiKVxuXHR7XG5cdFx0bGV0IG5vdyA9IG5ldyBEYXRlKClcblx0XHRsZXQgdGltZSA9IG5vdy5nZXRUaW1lKCk7XG5cblx0XHQvLyBUaGUgZmlyc3QgdmFsdWUgc2VudCBieSB0aGUgc2VydmVyIGlzIG5vdCBwbG90dGVkOiBpdCB3b3VsZCBiZSBhIHdvcm5nIHZhbHVlIGJlY2F1c2Vcblx0XHQvLyB3ZSBoYXZlIHRvIGNhbGN1bGF0ZSBpdCBhcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHR3byB0b3RhbCB2YWx1ZXMsIGJ1dCB3ZSBkb24ndCBoYXZlIHRoZSBwcmV2aW91cyBvbmVcblx0XHRpZiAodGhpcy5fbGFzdFRpbWUgPiAwKVxuXHRcdHtcblx0XHRcdGxldCBlbGFwc2VkU2VjcyA9ICh0aW1lIC0gdGhpcy5fbGFzdFRpbWUpIC8gMTAwMDtcblxuXHRcdFx0Y29uc3QgdmFsdWVPdXQgPSBNYXRoLnJvdW5kKCh0b3RhbE91dEtiIC0gdGhpcy5fbGFzdFRvdGFsS2JPdXQpIC8gZWxhcHNlZFNlY3MpO1xuXHRcdFx0Y29uc3QgdmFsdWVJbiA9IE1hdGgucm91bmQoKHRvdGFsSW5LYiAtIHRoaXMuX2xhc3RUb3RhbEtiSW4pIC8gZWxhcHNlZFNlY3MpO1xuXG5cdFx0XHRsZXQgbmV3RW50cnkgPSB7XG5cdFx0XHRcdHRpbWU6IGdldEZvcm1hdHRlZERhdGVUaW1lKG5vdyksXG5cdFx0XHRcdHRpbWVzdGFtcDogdGltZSxcblx0XHRcdFx0b3V0Z29pbmc6IHZhbHVlT3V0LFxuXHRcdFx0XHRpbmNvbWluZzogdmFsdWVJblxuXHRcdFx0fTtcblxuXHRcdFx0Ly8gQWRkIGVudHJ5IHRvIGNoYXJ0XG5cdFx0XHRzdXBlci5fYWRkRW50cnkobmV3RW50cnkpO1xuXG5cdFx0XHQvLyBVcGRhdGUgeCBheGlzXG5cdFx0XHRpZiAoIXRoaXMuaXNQYXVzZWQpXG5cdFx0XHRcdHRoaXMuX3VwZGF0ZUVsYXBzZWRUZXh0KCk7XG5cdFx0fVxuXG5cdFx0dGhpcy5fbGFzdFRvdGFsS2JPdXQgPSB0b3RhbE91dEtiO1xuXHRcdHRoaXMuX2xhc3RUb3RhbEtiSW4gPSB0b3RhbEluS2I7XG5cdFx0dGhpcy5fbGFzdFRpbWUgPSB0aW1lO1xuXHR9XG5cblx0X3VwZGF0ZUVsYXBzZWRUZXh0KClcblx0e1xuXHRcdGxldCBkcyA9IHRoaXMuX2RhdGFTb3VyY2U7XG5cblx0XHRpZiAoZHMudG90YWwoKSA+IDEpXG5cdFx0e1xuXHRcdFx0Ly8gR2V0IGF4aXMgbGltaXRzXG5cdFx0XHRjb25zdCBjaGFydE1pbmltdW0gPSBkcy5hdCgwKS50aW1lc3RhbXA7XG5cdFx0XHRjb25zdCBjaGFydE1heGltdW0gPSBkcy5hdChkcy50b3RhbCgpIC0gMSkudGltZXN0YW1wO1xuXG5cdFx0XHQvLyBTZXQgZWxhcHNlZCB0ZXh0XG5cdFx0XHRsZXQgdGl0bGU7XG5cdFx0XHRsZXQgc2Vjb25kcyA9IE1hdGgucm91bmQoIChjaGFydE1heGltdW0gLSBjaGFydE1pbmltdW0pIC8gMTAwMCApO1xuXG5cdFx0XHRpZiAoc2Vjb25kcyA8IDYwKVxuXHRcdFx0XHR0aXRsZSA9ICdMYXN0ICcgKyAoc2Vjb25kcyAhPSAxID8gc2Vjb25kcyArICcgc2Vjb25kcycgOiAnc2Vjb25kJyk7XG5cdFx0XHRlbHNlXG5cdFx0XHR7XG5cdFx0XHRcdGNvbnN0IG1pbnV0ZXMgPSBNYXRoLmZsb29yKHNlY29uZHMgLyA2MCk7XG5cdFx0XHRcdHRpdGxlID0gJ0xhc3QgJyArIChtaW51dGVzICE9IDEgPyBtaW51dGVzICsgJyBtaW51dGVzJyA6ICdtaW51dGUnKTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5fZWxhcHNlZFR4dC50ZXh0KHRpdGxlKTtcblx0XHR9XG5cdH1cbn1cblxuLy8gREVGSU5FIENPTVBPTkVOVFxuaWYgKCF3aW5kb3cuY3VzdG9tRWxlbWVudHMuZ2V0KCduZXR3b3JrLXJlYWx0aW1lLWNoYXJ0JykpXG5cdHdpbmRvdy5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ25ldHdvcmstcmVhbHRpbWUtY2hhcnQnLCBOZXR3b3JrUmVhbHRpbWVDaGFydCk7XG4iLCJpbXBvcnQge0Jhc2VDaGFydH0gZnJvbSAnLi9iYXNlLWNoYXJ0JztcblxuaW1wb3J0IHtnZXRCYXNpY1NoYXJlZFRlbXBsYXRlLCBnZXRGb3JtYXR0ZWREYXRlVGltZX0gZnJvbSAnLi9jaGFydC11dGlscyc7XG5cbmV4cG9ydCBjbGFzcyBTeXN0ZW1RdWV1ZUNoYXJ0IGV4dGVuZHMgQmFzZUNoYXJ0XG57XG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHQgICAgc3VwZXIoMjQwKTtcblxuXHRcdHRoaXMuX2F2ZXJhZ2VMb2FkID0gMDtcblx0fVxuXG5cdF9pbml0aWFsaXplKClcblx0e1xuXHRcdGNvbnN0IGNoYXJ0SGVpZ2h0ID0gMjQwO1xuXG5cdFx0Ly8gQXBwZW5kIGNvbnRhaW5lciBmb3IgY2hhcnQgJiBnYXVnZVxuXHRcdGxldCBjb250YWluZXIgPSAkKCc8ZGl2PicsIHtjbGFzczogJ2QtZmxleCBmbGV4LXJvdyd9KTtcblx0XHQkKHRoaXMpLmFwcGVuZChjb250YWluZXIpO1xuXG5cdFx0Ly8gQ0hBUlRcblxuXHRcdGxldCBjaGFydENvbnRhaW5lciA9ICQoJzxkaXY+Jywge2NsYXNzOiAnZmxleC1ncm93LTEnfSk7XG5cdFx0Y29udGFpbmVyLmFwcGVuZChjaGFydENvbnRhaW5lcik7XG5cblx0XHQvLyBDcmVhdGUgY2hhcnQgaHRtbFxuXHRcdGxldCBjaGFydEh0bWwgPSAkKCc8ZGl2PicpO1xuXHRcdGNoYXJ0Q29udGFpbmVyLmFwcGVuZChjaGFydEh0bWwpO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSBjaGFydFxuXHRcdHRoaXMuX2NoYXJ0V2lkZ2V0ID0gdGhpcy5faW5pdENoYXJ0V2lkZ2V0KGNoYXJ0SHRtbCwgY2hhcnRIZWlnaHQpO1xuXG5cdFx0Ly8gQXBwZW5kIHRleHQgdG8gZGlzcGxheSBlbGFwc2VkIHRpbWVcblx0XHR0aGlzLl9lbGFwc2VkVHh0ID0gJCgnPGRpdj4nLCB7Y2xhc3M6ICd0ZXh0LWNlbnRlcicsIHRleHQ6ICctLS0nfSk7XG5cdFx0Y2hhcnRDb250YWluZXIuYXBwZW5kKHRoaXMuX2VsYXBzZWRUeHQpO1xuXG5cdFx0Ly8gR0FVR0VcblxuXHRcdGxldCBnYXVnZUNvbnRhaW5lciA9ICQoJzxkaXY+Jyk7XG5cdFx0Y29udGFpbmVyLmFwcGVuZChnYXVnZUNvbnRhaW5lcik7XG5cblx0XHQvLyBDcmVhdGUgZ2F1Z2UgaHRtbFxuXHRcdGxldCBnYXVnZUh0bWwgPSAkKCc8ZGl2PicpO1xuXHRcdGdhdWdlQ29udGFpbmVyLmFwcGVuZChnYXVnZUh0bWwpO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSBnYXVnZVxuXHRcdHRoaXMuX2dhdWdlV2lkZ2V0ID0gdGhpcy5faW5pdEdhdWdlV2lkZ2V0KGdhdWdlSHRtbCwgY2hhcnRIZWlnaHQpO1xuXG5cdFx0Ly8gQXBwZW5kIHRleHQgdG8gZGlzcGxheSBsb2FkXG5cdFx0dGhpcy5fbG9hZFR4dCA9ICQoJzxkaXY+Jywge2NsYXNzOiAndGV4dC1jZW50ZXIgZm9udC13ZWlnaHQtYm9sZCcsIHRleHQ6ICctLS0nfSk7XG5cdFx0Z2F1Z2VDb250YWluZXIuYXBwZW5kKHRoaXMuX2xvYWRUeHQpO1xuXG5cdFx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRcdC8vIFJlc2V0IGRhdGEgc291cmNlXG5cdFx0dGhpcy5yZXNldCgpO1xuXHR9XG5cblx0X2luaXRDaGFydFdpZGdldChjaGFydEh0bWwsIGhlaWdodClcblx0e1xuXHRcdHJldHVybiBjaGFydEh0bWwua2VuZG9DaGFydCh7XG5cdFx0XHR0cmFuc2l0aW9uczogZmFsc2UsXG5cdFx0XHRjaGFydEFyZWE6IHtcblx0XHRcdFx0aGVpZ2h0OiBoZWlnaHQsXG5cdFx0XHRcdGJhY2tncm91bmQ6ICd0cmFuc3BhcmVudCdcblx0XHRcdH0sXG5cdCAgICAgICAgbGVnZW5kOiB7XG5cdCAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXJpZXNEZWZhdWx0czoge1xuXHQgICAgICAgICAgICB0eXBlOiAnYXJlYScsXG5cdCAgICAgICAgICAgIGxhYmVsczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXQ6ICd7MH0nLFxuXHQgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJ3RyYW5zcGFyZW50J1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXJpZXM6IFtcblx0XHRcdFx0e1xuXHRcdFx0XHRcdG5hbWU6ICdNZXNzYWdlcycsXG5cdFx0ICAgICAgICAgICAgZmllbGQ6ICdsb2FkJyxcblx0XHQgICAgICAgICAgICBjYXRlZ29yeUZpZWxkOiAndGltZScsXG5cdFx0XHRcdFx0Y29sb3I6ICcjMzM5OWZmJyxcblx0XHRcdFx0XHRsaW5lOiB7XG5cdFx0XHRcdFx0XHR3aWR0aDogMlxuXHRcdFx0XHRcdH1cblx0XHQgICAgICAgIH1cblx0XHRcdF0sXG5cdCAgICAgICAgdmFsdWVBeGlzOiB7XG5cdFx0XHRcdHRpdGxlOiB7XG5cdFx0XHRcdFx0dGV4dDogJ01lc3NhZ2VzJ1xuXHRcdFx0XHR9LFxuXHQgICAgICAgICAgICBsYWJlbHM6IHtcblx0ICAgICAgICAgICAgICAgIGZvcm1hdDogJ3swfSdcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgbGluZToge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICAgICAgfSxcblx0XHRcdFx0bWluOiAwXG5cdCAgICAgICAgfSxcblx0ICAgICAgICBjYXRlZ29yeUF4aXM6IHtcblx0ICAgICAgICAgICAgbWFqb3JHcmlkTGluZXM6IHtcblx0ICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgICAgIH0sXG5cdFx0XHRcdG1ham9yVGlja3M6IHtcblx0XHRcdFx0XHR2aXNpYmxlOiBmYWxzZVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRsYWJlbHM6IHtcblx0XHRcdFx0XHR2aXNpYmxlOiBmYWxzZVxuXHRcdFx0XHR9XG5cdCAgICAgICAgfSxcblx0XHRcdHRvb2x0aXA6IHtcblx0XHRcdFx0c2hhcmVkOiB0cnVlLFxuXHQgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuXHRcdFx0XHRzaGFyZWRUZW1wbGF0ZTogZ2V0QmFzaWNTaGFyZWRUZW1wbGF0ZSgpLFxuXHRcdFx0XHRiYWNrZ3JvdW5kOiAnI2U0ZTRlNCdcblx0ICAgICAgICB9XG5cdCAgICB9KS5kYXRhKCdrZW5kb0NoYXJ0Jyk7XG5cdH1cblxuXHRfaW5pdEdhdWdlV2lkZ2V0KGdhdWdlSHRtbCwgaGVpZ2h0KVxuXHR7XG5cdFx0cmV0dXJuIGdhdWdlSHRtbC5rZW5kb0xpbmVhckdhdWdlKHtcblx0XHRcdHBvaW50ZXI6IHtcblx0ICAgICAgICAgICAgdmFsdWU6IDAsXG5cdCAgICAgICAgICAgIHNoYXBlOiAnYXJyb3cnLFxuXHQgICAgICAgICAgXHRzaXplOiAxMCxcblx0XHRcdFx0Y29sb3I6ICcjMjEyNTI5J1xuXHQgICAgICAgIH0sXG5cdFx0XHRnYXVnZUFyZWE6IHtcblx0XHRcdFx0aGVpZ2h0OiBoZWlnaHRcblx0XHRcdH0sXG5cdCAgICAgICAgc2NhbGU6IHtcblx0ICAgICAgICAgICAgbWFqb3JVbml0OiAxMCxcblx0ICAgICAgICAgICAgbWlub3JVbml0OiAxLFxuXHRcdFx0XHRtaW46IDAsXG5cdFx0XHRcdG1heDogMTAwLFxuXHQgICAgICAgICAgICByYW5nZXM6IFtcblx0ICAgICAgICAgICAgICAgIHtcblx0XHRcdFx0XHRcdGZyb206IDAsXG5cdCAgICAgICAgICAgICAgICAgICAgdG86IDUwLFxuXHQgICAgICAgICAgICAgICAgICAgIGNvbG9yOiAnIzAwY2MwMCcsXG5cdCAgICAgICAgICAgICAgICAgIFx0b3BhY2l0eTogLjVcblx0ICAgICAgICAgICAgICAgIH0sIHtcblx0ICAgICAgICAgICAgICAgICAgICBmcm9tOiA1MCxcblx0ICAgICAgICAgICAgICAgICAgICB0bzogNzUsXG5cdCAgICAgICAgICAgICAgICAgICAgY29sb3I6ICcjZmZlMTA2Jyxcblx0ICAgICAgICAgICAgICAgICAgXHRvcGFjaXR5OiAuNVxuXHQgICAgICAgICAgICAgICAgfSwge1xuXHQgICAgICAgICAgICAgICAgICAgIGZyb206IDc1LFxuXHQgICAgICAgICAgICAgICAgICAgIHRvOiAxMDAsXG5cdCAgICAgICAgICAgICAgICAgICAgY29sb3I6ICcjZWQxNjAxJyxcblx0ICAgICAgICAgICAgICAgICAgXHRvcGFjaXR5OiAuNVxuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBdLFxuXHQgICAgICAgICAgXHRtYWpvclRpY2tzOiB7XG5cdCAgICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcblx0ICAgICAgICAgICAgICBzaXplOiAxMFxuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgXHRtaW5vclRpY2tzOiB7XG5cdCAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgIFx0bGFiZWxzOiB7XG5cdCAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgIFx0bGluZToge1xuXHQgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICBcdHJhbmdlU2l6ZTogMTBcblx0ICAgICAgICB9XG5cdCAgICB9KS5kYXRhKCdrZW5kb0xpbmVhckdhdWdlJyk7XG5cdH1cblxuXHRhZGRFbnRyeShsb2FkLCBxdWV1ZU1zZ0xpbWl0KVxuXHR7XG5cdFx0Ly8gQ0hBUlRcblxuXHRcdGxldCBub3cgPSBuZXcgRGF0ZSgpO1xuXG5cdFx0bGV0IG5ld0VudHJ5ID0ge1xuXHRcdFx0dGltZTogZ2V0Rm9ybWF0dGVkRGF0ZVRpbWUobm93KSxcblx0XHRcdHRpbWVzdGFtcDogbm93LmdldFRpbWUoKSxcblx0XHRcdGxvYWQ6IGxvYWRcblx0XHR9O1xuXG5cdFx0Ly8gQWRkIGVudHJ5IHRvIGNoYXJ0XG5cdFx0c3VwZXIuX2FkZEVudHJ5KG5ld0VudHJ5KTtcblxuXHRcdC8vIFVwZGF0ZSB4IGF4aXNcblx0XHRpZiAoIXRoaXMuaXNQYXVzZWQpXG5cdFx0XHR0aGlzLl91cGRhdGVFbGFwc2VkVGV4dCgpO1xuXG5cdFx0Ly8gR0FVR0VcblxuXHRcdC8vIEV2YWx1YXRlIGF2ZXJhZ2Vcblx0XHRsZXQgbnVtVmFsdWVzID0gdGhpcy5fZGF0YVNvdXJjZS50b3RhbCgpO1xuXG5cdFx0aWYgKG51bVZhbHVlcyA+IDApXG5cdFx0e1xuXHRcdFx0bGV0IHRvdGFsID0gMDtcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgbnVtVmFsdWVzOyBpKyspXG5cdFx0XHRcdHRvdGFsICs9IHRoaXMuX2RhdGFTb3VyY2UuYXQoaSkubG9hZDtcblxuXHRcdFx0dGhpcy5fYXZlcmFnZUxvYWQgPSBNYXRoLnJvdW5kKHRvdGFsIC8gbnVtVmFsdWVzKTtcblx0XHR9XG5cdFx0ZWxzZVxuXHRcdFx0dGhpcy5fYXZlcmFnZUxvYWQgPSAwO1xuXG5cdFx0Y29uc3QgYXZnTG9hZFBlcmMgPSBNYXRoLnJvdW5kKHRoaXMuX2F2ZXJhZ2VMb2FkIC8gcXVldWVNc2dMaW1pdCAqIDEwMDApIC8gMTA7XG5cblx0XHQvLyBTZXQgZ2F1Z2UgdmFsdWVcblx0XHR0aGlzLl9nYXVnZVdpZGdldC52YWx1ZShhdmdMb2FkUGVyYyk7XG5cblx0XHQvLyBTZXQgbG9hZCB0ZXh0XG5cdFx0dGhpcy5fbG9hZFR4dC50ZXh0KGF2Z0xvYWRQZXJjICsgJyUnKVxuXHR9XG5cblx0X3VwZGF0ZUVsYXBzZWRUZXh0KClcblx0e1xuXHRcdGxldCBkcyA9IHRoaXMuX2RhdGFTb3VyY2U7XG5cblx0XHRpZiAoZHMudG90YWwoKSA+IDEpXG5cdFx0e1xuXHRcdFx0Ly8gR2V0IGF4aXMgbGltaXRzXG5cdFx0XHRjb25zdCBjaGFydE1pbmltdW0gPSBkcy5hdCgwKS50aW1lc3RhbXA7XG5cdFx0XHRjb25zdCBjaGFydE1heGltdW0gPSBkcy5hdChkcy50b3RhbCgpIC0gMSkudGltZXN0YW1wO1xuXG5cdFx0XHQvLyBTZXQgZWxhcHNlZCB0ZXh0XG5cdFx0XHRsZXQgc2Vjb25kcyA9IE1hdGgucm91bmQoIChjaGFydE1heGltdW0gLSBjaGFydE1pbmltdW0pIC8gMTAwMCApO1xuXHRcdFx0bGV0IHRpdGxlO1xuXG5cdFx0XHRpZiAoc2Vjb25kcyA8IDYwKVxuXHRcdFx0XHR0aXRsZSA9ICdMYXN0ICcgKyAoc2Vjb25kcyAhPSAxID8gc2Vjb25kcyArICcgc2Vjb25kcycgOiAnc2Vjb25kJyk7XG5cdFx0XHRlbHNlXG5cdFx0XHR7XG5cdFx0XHRcdGNvbnN0IG1pbnV0ZXMgPSBNYXRoLmZsb29yKHNlY29uZHMgLyA2MCk7XG5cdFx0XHRcdHRpdGxlID0gJ0xhc3QgJyArIChtaW51dGVzICE9IDEgPyBtaW51dGVzICsgJyBtaW51dGVzJyA6ICdtaW51dGUnKTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5fZWxhcHNlZFR4dC50ZXh0KHRpdGxlKTtcblx0XHR9XG5cdH1cblxuXHRnZXQgbG9hZCgpXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fYXZlcmFnZUxvYWQ7XG5cdH1cbn1cblxuLy8gREVGSU5FIENPTVBPTkVOVFxuaWYgKCF3aW5kb3cuY3VzdG9tRWxlbWVudHMuZ2V0KCdzeXN0ZW0tcXVldWUtY2hhcnQnKSlcblx0d2luZG93LmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnc3lzdGVtLXF1ZXVlLWNoYXJ0JywgU3lzdGVtUXVldWVDaGFydCk7XG4iLCJpbXBvcnQge0Jhc2VDaGFydH0gZnJvbSAnLi9iYXNlLWNoYXJ0JztcblxuaW1wb3J0IHtnZXRCYXNpY1NoYXJlZFRlbXBsYXRlLCBnZXRGb3JtYXR0ZWREYXRlVGltZX0gZnJvbSAnLi9jaGFydC11dGlscyc7XG5cbmV4cG9ydCBjbGFzcyBTeXN0ZW1Xb3JrbG9hZENoYXJ0IGV4dGVuZHMgQmFzZUNoYXJ0XG57XG5cdGNvbnN0cnVjdG9yKClcblx0e1xuXHQgICAgc3VwZXIoMjQwKTtcblx0fVxuXG5cdF9pbml0aWFsaXplKClcblx0e1xuXHRcdGNvbnN0IGNoYXJ0SGVpZ2h0ID0gMjQwO1xuXG5cdFx0Ly8gQXBwZW5kIGNvbnRhaW5lciBmb3IgY2hhcnQgJiBnYXVnZVxuXHRcdGxldCBjb250YWluZXIgPSAkKCc8ZGl2PicsIHtjbGFzczogJ2QtZmxleCBmbGV4LXJvdyd9KTtcblx0XHQkKHRoaXMpLmFwcGVuZChjb250YWluZXIpO1xuXG5cdFx0Ly8gQ0hBUlRcblxuXHRcdGxldCBjaGFydENvbnRhaW5lciA9ICQoJzxkaXY+Jywge2NsYXNzOiAnZmxleC1ncm93LTEnfSk7XG5cdFx0Y29udGFpbmVyLmFwcGVuZChjaGFydENvbnRhaW5lcik7XG5cblx0XHQvLyBDcmVhdGUgY2hhcnQgaHRtbFxuXHRcdGxldCBjaGFydEh0bWwgPSAkKCc8ZGl2PicpO1xuXHRcdGNoYXJ0Q29udGFpbmVyLmFwcGVuZChjaGFydEh0bWwpO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSBjaGFydFxuXHRcdHRoaXMuX2NoYXJ0V2lkZ2V0ID0gdGhpcy5faW5pdENoYXJ0V2lkZ2V0KGNoYXJ0SHRtbCwgY2hhcnRIZWlnaHQpO1xuXG5cdFx0Ly8gQXBwZW5kIHRleHQgdG8gZGlzcGxheSBlbGFwc2VkIHRpbWVcblx0XHR0aGlzLl9lbGFwc2VkVHh0ID0gJCgnPGRpdj4nLCB7Y2xhc3M6ICd0ZXh0LWNlbnRlcicsIHRleHQ6ICctLS0nfSk7XG5cdFx0Y2hhcnRDb250YWluZXIuYXBwZW5kKHRoaXMuX2VsYXBzZWRUeHQpO1xuXG5cdFx0Ly8gR0FVR0VcblxuXHRcdGxldCBnYXVnZUNvbnRhaW5lciA9ICQoJzxkaXY+Jyk7XG5cdFx0Y29udGFpbmVyLmFwcGVuZChnYXVnZUNvbnRhaW5lcik7XG5cblx0XHQvLyBDcmVhdGUgZ2F1Z2UgaHRtbFxuXHRcdGxldCBnYXVnZUh0bWwgPSAkKCc8ZGl2PicpO1xuXHRcdGdhdWdlQ29udGFpbmVyLmFwcGVuZChnYXVnZUh0bWwpO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSBnYXVnZVxuXHRcdHRoaXMuX2dhdWdlV2lkZ2V0ID0gdGhpcy5faW5pdEdhdWdlV2lkZ2V0KGdhdWdlSHRtbCwgY2hhcnRIZWlnaHQpO1xuXG5cdFx0Ly8gQXBwZW5kIHRleHQgdG8gZGlzcGxheSBsb2FkXG5cdFx0dGhpcy5fbG9hZFR4dCA9ICQoJzxkaXY+Jywge2NsYXNzOiAndGV4dC1jZW50ZXIgZm9udC13ZWlnaHQtYm9sZCcsIHRleHQ6ICctLS0nfSk7XG5cdFx0Z2F1Z2VDb250YWluZXIuYXBwZW5kKHRoaXMuX2xvYWRUeHQpO1xuXG5cdFx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRcdC8vIFJlc2V0IGRhdGEgc291cmNlXG5cdFx0dGhpcy5yZXNldCgpO1xuXHR9XG5cblx0X2luaXRDaGFydFdpZGdldChjaGFydEh0bWwsIGhlaWdodClcblx0e1xuXHRcdHJldHVybiBjaGFydEh0bWwua2VuZG9DaGFydCh7XG5cdFx0XHR0cmFuc2l0aW9uczogZmFsc2UsXG5cdFx0XHRjaGFydEFyZWE6IHtcblx0XHRcdFx0aGVpZ2h0OiBoZWlnaHQsXG5cdFx0XHRcdGJhY2tncm91bmQ6ICd0cmFuc3BhcmVudCdcblx0XHRcdH0sXG5cdCAgICAgICAgbGVnZW5kOiB7XG5cdCAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXJpZXNEZWZhdWx0czoge1xuXHQgICAgICAgICAgICB0eXBlOiAnYXJlYScsXG5cdCAgICAgICAgICAgIGxhYmVsczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXQ6ICd7MH0lJyxcblx0ICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICd0cmFuc3BhcmVudCdcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2VyaWVzOiBbXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRuYW1lOiAnV29ya2xvYWQnLFxuXHRcdCAgICAgICAgICAgIGZpZWxkOiAnbG9hZCcsXG5cdFx0ICAgICAgICAgICAgY2F0ZWdvcnlGaWVsZDogJ3RpbWUnLFxuXHRcdFx0XHRcdGNvbG9yOiAnIzMzOTlmZicsXG5cdFx0XHRcdFx0bGluZToge1xuXHRcdFx0XHRcdFx0d2lkdGg6IDJcblx0XHRcdFx0XHR9XG5cdFx0ICAgICAgICB9XG5cdFx0XHRdLFxuXHQgICAgICAgIHZhbHVlQXhpczoge1xuXHQgICAgICAgICAgICBsYWJlbHM6IHtcblx0ICAgICAgICAgICAgICAgIGZvcm1hdDogJ3swfSUnXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgIGxpbmU6IHtcblx0ICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgICAgIH0sXG5cdFx0XHRcdG1pbjogMCxcblx0ICAgIFx0XHRtYXg6IDEwMFxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgY2F0ZWdvcnlBeGlzOiB7XG5cdCAgICAgICAgICAgIG1ham9yR3JpZExpbmVzOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtYWpvclRpY2tzOiB7XG5cdFx0XHRcdFx0dmlzaWJsZTogZmFsc2Vcblx0XHRcdFx0fSxcblx0XHRcdFx0bGFiZWxzOiB7XG5cdFx0XHRcdFx0dmlzaWJsZTogZmFsc2Vcblx0XHRcdFx0fVxuXHQgICAgICAgIH0sXG5cdFx0XHR0b29sdGlwOiB7XG5cdFx0XHRcdHNoYXJlZDogdHJ1ZSxcblx0ICAgICAgICAgICAgdmlzaWJsZTogdHJ1ZSxcblx0XHRcdFx0c2hhcmVkVGVtcGxhdGU6IGdldEJhc2ljU2hhcmVkVGVtcGxhdGUoJ3swfSUnKSxcblx0XHRcdFx0YmFja2dyb3VuZDogJyNlNGU0ZTQnXG5cdCAgICAgICAgfVxuXHQgICAgfSkuZGF0YSgna2VuZG9DaGFydCcpO1xuXHR9XG5cblx0X2luaXRHYXVnZVdpZGdldChnYXVnZUh0bWwsIGhlaWdodClcblx0e1xuXHRcdHJldHVybiBnYXVnZUh0bWwua2VuZG9MaW5lYXJHYXVnZSh7XG5cdFx0XHRwb2ludGVyOiB7XG5cdCAgICAgICAgICAgIHZhbHVlOiAwLFxuXHQgICAgICAgICAgICBzaGFwZTogJ2Fycm93Jyxcblx0ICAgICAgICAgIFx0c2l6ZTogMTAsXG5cdFx0XHRcdGNvbG9yOiAnIzIxMjUyOSdcblx0ICAgICAgICB9LFxuXHRcdFx0Z2F1Z2VBcmVhOiB7XG5cdFx0XHRcdGhlaWdodDogaGVpZ2h0XG5cdFx0XHR9LFxuXHQgICAgICAgIHNjYWxlOiB7XG5cdCAgICAgICAgICAgIG1ham9yVW5pdDogMTAsXG5cdCAgICAgICAgICAgIG1pbm9yVW5pdDogMSxcblx0ICAgICAgICAgICAgbWF4OiAxMDAsXG5cdFx0XHRcdG1pbjogMCxcblx0ICAgICAgICAgICAgcmFuZ2VzOiBbXG5cdCAgICAgICAgICAgICAgICB7XG5cdCAgICAgICAgICAgICAgICAgICAgZnJvbTogMCxcblx0ICAgICAgICAgICAgICAgICAgICB0bzogNTAsXG5cdCAgICAgICAgICAgICAgICAgICAgY29sb3I6ICcjMDBjYzAwJyxcblx0ICAgICAgICAgICAgICAgICAgXHRvcGFjaXR5OiAuNVxuXHQgICAgICAgICAgICAgICAgfSwge1xuXHQgICAgICAgICAgICAgICAgICAgIGZyb206IDUwLFxuXHQgICAgICAgICAgICAgICAgICAgIHRvOiA3NSxcblx0ICAgICAgICAgICAgICAgICAgICBjb2xvcjogJyNmZmUxMDYnLFxuXHQgICAgICAgICAgICAgICAgICBcdG9wYWNpdHk6IC41XG5cdCAgICAgICAgICAgICAgICB9LCB7XG5cdCAgICAgICAgICAgICAgICAgICAgZnJvbTogNzUsXG5cdCAgICAgICAgICAgICAgICAgICAgdG86IDEwMCxcblx0ICAgICAgICAgICAgICAgICAgICBjb2xvcjogJyNlZDE2MDEnLFxuXHQgICAgICAgICAgICAgICAgICBcdG9wYWNpdHk6IC41XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIF0sXG5cdCAgICAgICAgICBcdG1ham9yVGlja3M6IHtcblx0ICAgICAgICAgICAgICB2aXNpYmxlOiB0cnVlLFxuXHQgICAgICAgICAgICAgIHNpemU6IDEwXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICBcdG1pbm9yVGlja3M6IHtcblx0ICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgXHRsYWJlbHM6IHtcblx0ICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgXHRsaW5lOiB7XG5cdCAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgIFx0cmFuZ2VTaXplOiAxMFxuXHQgICAgICAgIH1cblx0ICAgIH0pLmRhdGEoJ2tlbmRvTGluZWFyR2F1Z2UnKTtcblx0fVxuXG5cdGFkZEVudHJ5KGxvYWQpXG5cdHtcblx0XHQvLyBDSEFSVFxuXG5cdFx0bGV0IG5vdyA9IG5ldyBEYXRlKCk7XG5cblx0XHRsZXQgbmV3RW50cnkgPSB7XG5cdFx0XHR0aW1lOiBnZXRGb3JtYXR0ZWREYXRlVGltZShub3cpLFxuXHRcdFx0dGltZXN0YW1wOiBub3cuZ2V0VGltZSgpLFxuXHRcdFx0bG9hZDogbG9hZFxuXHRcdH07XG5cblx0XHQvLyBBZGQgZW50cnkgdG8gY2hhcnRcblx0XHRzdXBlci5fYWRkRW50cnkobmV3RW50cnkpO1xuXG5cdFx0Ly8gVXBkYXRlIHggYXhpc1xuXHRcdGlmICghdGhpcy5pc1BhdXNlZClcblx0XHRcdHRoaXMuX3VwZGF0ZUVsYXBzZWRUZXh0KCk7XG5cblx0XHQvLyBHQVVHRVxuXG5cdFx0Ly8gRXZhbHVhdGUgYXZlcmFnZVxuXHRcdGxldCBudW1WYWx1ZXMgPSB0aGlzLl9kYXRhU291cmNlLnRvdGFsKCk7XG5cdFx0bGV0IGF2ZXJhZ2VMb2FkID0gMDtcblxuXHRcdGlmIChudW1WYWx1ZXMgPiAwKVxuXHRcdHtcblx0XHRcdGxldCB0b3RhbCA9IDA7XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IG51bVZhbHVlczsgaSsrKVxuXHRcdFx0XHR0b3RhbCArPSB0aGlzLl9kYXRhU291cmNlLmF0KGkpLmxvYWQ7XG5cblx0XHRcdGF2ZXJhZ2VMb2FkID0gTWF0aC5yb3VuZCh0b3RhbCAvIG51bVZhbHVlcyk7XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IGdhdWdlIHZhbHVlXG5cdFx0dGhpcy5fZ2F1Z2VXaWRnZXQudmFsdWUoYXZlcmFnZUxvYWQpO1xuXG5cdFx0Ly8gU2V0IGxvYWQgdGV4dFxuXHRcdHRoaXMuX2xvYWRUeHQudGV4dChhdmVyYWdlTG9hZCArICclJylcblx0fVxuXG5cdF91cGRhdGVFbGFwc2VkVGV4dCgpXG5cdHtcblx0XHRsZXQgZHMgPSB0aGlzLl9kYXRhU291cmNlO1xuXG5cdFx0aWYgKGRzLnRvdGFsKCkgPiAxKVxuXHRcdHtcblx0XHRcdC8vIEdldCBheGlzIGxpbWl0c1xuXHRcdFx0Y29uc3QgY2hhcnRNaW5pbXVtID0gZHMuYXQoMCkudGltZXN0YW1wO1xuXHRcdFx0Y29uc3QgY2hhcnRNYXhpbXVtID0gZHMuYXQoZHMudG90YWwoKSAtIDEpLnRpbWVzdGFtcDtcblxuXHRcdFx0Ly8gU2V0IGVsYXBzZWQgdGV4dFxuXHRcdFx0bGV0IHNlY29uZHMgPSBNYXRoLnJvdW5kKCAoY2hhcnRNYXhpbXVtIC0gY2hhcnRNaW5pbXVtKSAvIDEwMDAgKTtcblx0XHRcdGxldCB0aXRsZTtcblxuXHRcdFx0aWYgKHNlY29uZHMgPCA2MClcblx0XHRcdFx0dGl0bGUgPSAnTGFzdCAnICsgKHNlY29uZHMgIT0gMSA/IHNlY29uZHMgKyAnIHNlY29uZHMnIDogJ3NlY29uZCcpO1xuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0XHRjb25zdCBtaW51dGVzID0gTWF0aC5mbG9vcihzZWNvbmRzIC8gNjApO1xuXHRcdFx0XHR0aXRsZSA9ICdMYXN0ICcgKyAobWludXRlcyAhPSAxID8gbWludXRlcyArICcgbWludXRlcycgOiAnbWludXRlJyk7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuX2VsYXBzZWRUeHQudGV4dCh0aXRsZSk7XG5cdFx0fVxuXHR9XG5cblx0Z2V0IGxvYWQoKVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2F2ZXJhZ2VMb2FkO1xuXHR9XG59XG5cbi8vIERFRklORSBDT01QT05FTlRcbmlmICghd2luZG93LmN1c3RvbUVsZW1lbnRzLmdldCgnc3lzdGVtLXdvcmtsb2FkLWNoYXJ0JykpXG5cdHdpbmRvdy5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ3N5c3RlbS13b3JrbG9hZC1jaGFydCcsIFN5c3RlbVdvcmtsb2FkQ2hhcnQpO1xuIiwiaW1wb3J0IHtCYXNlQ2hhcnR9IGZyb20gJy4vYmFzZS1jaGFydCc7XG5cbmltcG9ydCB7Z2V0QmFzaWNTaGFyZWRUZW1wbGF0ZSwgZ2V0Rm9ybWF0dGVkRGF0ZVRpbWV9IGZyb20gJy4vY2hhcnQtdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgVGhyZWFkQ291bnRDaGFydCBleHRlbmRzIEJhc2VDaGFydFxue1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0ICAgIHN1cGVyKDEyMCk7XG5cdH1cblxuXHRfaW5pdENoYXJ0V2lkZ2V0KGNoYXJ0SHRtbClcblx0e1xuXHRcdHJldHVybiBjaGFydEh0bWwua2VuZG9DaGFydCh7XG5cdFx0XHR0cmFuc2l0aW9uczogZmFsc2UsXG5cdFx0XHRjaGFydEFyZWE6IHtcblx0XHRcdFx0aGVpZ2h0OiAxMjAsXG5cdFx0XHRcdGJhY2tncm91bmQ6ICd0cmFuc3BhcmVudCdcblx0XHRcdH0sXG5cdCAgICAgICAgbGVnZW5kOiB7XG5cdCAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgfSxcblx0ICAgICAgICBzZXJpZXNEZWZhdWx0czoge1xuXHQgICAgICAgICAgICB0eXBlOiAnYXJlYScsXG5cdCAgICAgICAgICAgIGxhYmVsczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXQ6ICd7MH0nLFxuXHQgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJ3RyYW5zcGFyZW50J1xuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2VyaWVzOiBbXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRuYW1lOiAnVGhyZWFkcycsXG5cdFx0ICAgICAgICAgICAgZmllbGQ6ICd0aHJlYWRzJyxcblx0XHQgICAgICAgICAgICBjYXRlZ29yeUZpZWxkOiAndGltZScsXG5cdFx0XHRcdFx0Y29sb3I6IHRoaXMudGhyZWFkc0NvbG9yLFxuXHRcdFx0XHRcdGxpbmU6IHtcblx0XHRcdFx0XHRcdHdpZHRoOiAyXG5cdFx0XHRcdFx0fVxuXHRcdCAgICAgICAgfVxuXHRcdFx0XSxcblx0ICAgICAgICB2YWx1ZUF4aXM6IHtcblx0XHRcdFx0bWluOiAwLFxuXHQgICAgICAgICAgICBsYWJlbHM6IHtcblx0ICAgICAgICAgICAgICAgIGZvcm1hdDogJ3swfSdcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgbGluZToge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICB9LFxuXHQgICAgICAgIGNhdGVnb3J5QXhpczoge1xuXHQgICAgICAgICAgICBtYWpvckdyaWRMaW5lczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICAgICAgfSxcblx0XHRcdFx0bWFqb3JUaWNrczoge1xuXHRcdFx0XHRcdHZpc2libGU6IGZhbHNlXG5cdFx0XHRcdH0sXG5cdFx0XHRcdGxhYmVsczoge1xuXHRcdFx0XHRcdHZpc2libGU6IGZhbHNlXG5cdFx0XHRcdH1cblx0ICAgICAgICB9LFxuXHRcdFx0dG9vbHRpcDoge1xuXHRcdFx0XHRzaGFyZWQ6IHRydWUsXG5cdCAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG5cdFx0XHRcdHNoYXJlZFRlbXBsYXRlOiBnZXRCYXNpY1NoYXJlZFRlbXBsYXRlKCksXG5cdFx0XHRcdGJhY2tncm91bmQ6ICcjZTRlNGU0J1xuXHQgICAgICAgIH1cblx0ICAgIH0pLmRhdGEoJ2tlbmRvQ2hhcnQnKTtcblx0fVxuXG5cdGdldCB0aHJlYWRzQ29sb3IoKVxuXHR7XG5cdFx0cmV0dXJuICcjMzM5OUZGJztcblx0fVxuXG5cdGFkZEVudHJ5KHRocmVhZHMpXG5cdHtcblx0XHRsZXQgbmV3RW50cnkgPSB7XG5cdFx0XHR0aW1lOiBnZXRGb3JtYXR0ZWREYXRlVGltZShuZXcgRGF0ZSgpKSxcblx0XHRcdHRocmVhZHM6IHRocmVhZHNcblx0XHR9O1xuXG5cdFx0Ly8gQWRkIGVudHJ5IHRvIGNoYXJ0XG5cdFx0c3VwZXIuX2FkZEVudHJ5KG5ld0VudHJ5KTtcblx0fVxufVxuXG4vLyBERUZJTkUgQ09NUE9ORU5UXG5pZiAoIXdpbmRvdy5jdXN0b21FbGVtZW50cy5nZXQoJ3RocmVhZC1jb3VudC1jaGFydCcpKVxuXHR3aW5kb3cuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCd0aHJlYWQtY291bnQtY2hhcnQnLCBUaHJlYWRDb3VudENoYXJ0KTtcbiIsImltcG9ydCB7QmFzZU1vZHVsZX0gZnJvbSAnLi9iYXNlLW1vZHVsZSc7XG5pbXBvcnQge2J5dGVzVG9TaXplLCBrQnl0ZXNUb1NpemV9IGZyb20gJy4uL3V0aWxzL3V0aWxpdGllcyc7XG5pbXBvcnQge2dldFRpbWVSYW5nZVRvb2x0aXBUZW1wbGF0ZX0gZnJvbSAnLi4vY29tcG9uZW50cy9jaGFydHMvY2hhcnQtdXRpbHMnO1xuaW1wb3J0IHtDcHVVc2FnZUNoYXJ0fSBmcm9tICcuLi9jb21wb25lbnRzL2NoYXJ0cy9jcHUtdXNhZ2UtY2hhcnQnO1xuaW1wb3J0IHtUaHJlYWRDb3VudENoYXJ0fSBmcm9tICcuLi9jb21wb25lbnRzL2NoYXJ0cy90aHJlYWQtY291bnQtY2hhcnQnO1xuaW1wb3J0IHtNZW1vcnlDaGFydH0gZnJvbSAnLi4vY29tcG9uZW50cy9jaGFydHMvbWVtb3J5LWNoYXJ0JztcbmltcG9ydCB7TmV0d29ya1JlYWx0aW1lQ2hhcnR9IGZyb20gJy4uL2NvbXBvbmVudHMvY2hhcnRzL25ldHdvcmstcmVhbHRpbWUtY2hhcnQnO1xuaW1wb3J0IHtOZXR3b3JrMjRoQ2hhcnR9IGZyb20gJy4uL2NvbXBvbmVudHMvY2hhcnRzL25ldHdvcmstMjRoLWNoYXJ0JztcbmltcG9ydCB7U3lzdGVtV29ya2xvYWRDaGFydH0gZnJvbSAnLi4vY29tcG9uZW50cy9jaGFydHMvc3lzdGVtLXdvcmtsb2FkLWNoYXJ0JztcbmltcG9ydCB7U3lzdGVtUXVldWVDaGFydH0gZnJvbSAnLi4vY29tcG9uZW50cy9jaGFydHMvc3lzdGVtLXF1ZXVlLWNoYXJ0JztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRGFzaGJvYXJkIGV4dGVuZHMgQmFzZU1vZHVsZVxue1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0ICAgIHN1cGVyKCdkYXNoYm9hcmQnKTtcblxuXHRcdC8vIE91dGdvaW5nIHJlcXVlc3RzXG5cdFx0dGhpcy5SRVFfSU5JVCA9ICdpbml0Jztcblx0XHR0aGlzLlJFUV9HRVRfREFUQSA9ICdnZXREYXRhJztcblx0XHR0aGlzLlJFUV9EVU1QX1RIUkVBRFMgPSAnZ2V0VGhEdW1wJztcblxuXHRcdC8vIEluY29taW5nIHJlc3BvbnNlc1xuXHRcdHRoaXMuUkVTUF9JTklUID0gJ2luaXQnO1xuXHRcdHRoaXMuUkVTUF9EQVRBID0gJ2RhdGEnO1xuXHRcdHRoaXMuUkVTUF9USFJFQURfRFVNUCA9ICd0aER1bXAnO1xuXG5cdFx0dGhpcy5fdGNwT3V0VGhyZWFkcyA9IDA7XG5cdFx0dGhpcy5fdGNwT3V0TG9hZCA9IDA7XG5cdFx0dGhpcy5fdWRwT3V0VGhyZWFkcyA9IDA7XG5cdFx0dGhpcy5fdWRwT3V0TG9hZCA9IDA7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBDT01NT04gTU9EVUxFIElOVEVSRkFDRSBNRVRIT0RTXG5cdC8vIFRoaXMgbWVtYmVycyBhcmUgdXNlZCBieSB0aGUgbWFpbiBjb250cm9sbGVyXG5cdC8vIHRvIGNvbW11bmljYXRlIHdpdGggdGhlIG1vZHVsZSdzIGNvbnRyb2xsZXIuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0aW5pdGlhbGl6ZShpZERhdGEsIHNoZWxsQ29udHJvbGxlcilcblx0e1xuXHRcdC8vIENhbGwgc3VwZXIgbWV0aG9kXG5cdFx0c3VwZXIuaW5pdGlhbGl6ZShpZERhdGEsIHNoZWxsQ29udHJvbGxlcik7XG5cblx0XHQvLyBJbml0aWFsaXplIHNjcm9sbGluZyB0YWJzXG5cdFx0JCgnI2RzaC10YWJOYXZpZ2F0b3IgPiAjdGFicycpLnNjcm9sbGluZ1RhYnMoe1xuXHRcdFx0Ym9vdHN0cmFwVmVyc2lvbjogNCxcblx0XHRcdHNjcm9sbFRvVGFiRWRnZTogdHJ1ZSxcblx0XHRcdGVuYWJsZVN3aXBpbmc6IHRydWUsXG5cdFx0XHRkaXNhYmxlU2Nyb2xsQXJyb3dzT25GdWxseVNjcm9sbGVkOiB0cnVlLFxuXHRcdFx0Y3NzQ2xhc3NMZWZ0QXJyb3c6ICdmYSBmYS1jaGV2cm9uLWxlZnQnLFxuXHRcdFx0Y3NzQ2xhc3NSaWdodEFycm93OiAnZmEgZmEtY2hldnJvbi1yaWdodCdcblx0XHR9KTtcblxuXHRcdC8vIEluaXRpYWxpemUgaW50ZXJ2YWwgZHJvcGRvd25cblx0XHR0aGlzLl9pbnRlcnZhbERyb3BEb3duID0gJCgnI2RzaC1pbnRlcnZhbEREJykua2VuZG9Ecm9wRG93bkxpc3Qoe1xuXHRcdFx0dmFsdWVUZW1wbGF0ZTogJzxzcGFuIGNsYXNzPVwidGV4dC1tdXRlZCBwci0xXCI+SW50ZXJ2YWw6PC9zcGFuPjxzcGFuPiM6ZGF0YS50ZXh0Izwvc3Bhbj4nLFxuXHRcdFx0Y2hhbmdlOiAkLnByb3h5KHRoaXMuX29uVXBkYXRlSW50ZXJ2YWxDaGFuZ2UsIHRoaXMpXG5cdFx0fSkuZGF0YSgna2VuZG9Ecm9wRG93bkxpc3QnKTtcblxuXHRcdC8vIEluaXRpYWxpemUgdGhyZWFkcyBncmlkXG5cdFx0dGhpcy5fdGhyZWFkc0dyaWQgPSAkKCcjZHNoLXRocmVhZHNHcmlkJykua2VuZG9HcmlkKHtcblx0XHRcdGRhdGFTb3VyY2U6IHRoaXMuX2dldFRocmVhZHNHcmlkRGF0YVNvdXJjZSgpLFxuXHRcdFx0c2Nyb2xsYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIHNvcnRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZmlsdGVyYWJsZTogZmFsc2UsXG5cdFx0XHRyZXNpemFibGU6IHRydWUsXG5cdFx0XHRzZWxlY3RhYmxlOiBmYWxzZSxcblx0XHRcdGNvbHVtbnM6IFtcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGZpZWxkOiAnaWQnLFxuXHRcdFx0XHRcdHRpdGxlOiAnSWQnLFxuXHRcdFx0XHRcdHdpZHRoOiA2MFxuXHRcdFx0XHR9LFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0ZmllbGQ6ICduYW1lJyxcblx0XHRcdFx0XHR0aXRsZTogJ05hbWUnLFxuXHRcdFx0XHRcdHdpZHRoOiAnNjUlJ1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0ZmllbGQ6ICdjcHVUaW1lJyxcblx0XHRcdFx0XHR0aXRsZTogJ0NQVSBUaW1lJyxcblx0XHRcdFx0XHRmb3JtYXQ6ICd7MH0lJyxcblx0XHRcdFx0XHR3aWR0aDogJzM1JSdcblx0XHRcdFx0fSxcblx0XHRcdF0sXG5cdFx0XHRub1JlY29yZHM6IHtcblx0XHRcdFx0dGVtcGxhdGU6ICdObyB0aHJlYWRzLidcblx0XHRcdH0sXG5cdFx0XHRoZWlnaHQ6ICdjYWxjKDI0MHB4IC0gLjc1cmVtICsgMXJlbSknXG5cdFx0fSkuZGF0YSgna2VuZG9HcmlkJyk7XG5cblx0XHQvLyBBZGQgY2xpY2sgbGlzdGVuZXIgdG8gdGhyZWFkcyBkdW1wIGJ1dHRvblxuXHRcdCQoJyNkc2gtZHVtcFRocmVhZHNCdCcpLm9uKCdjbGljaycsICQucHJveHkodGhpcy5fb25EdW1wVGhyZWFkc0NsaWNrLCB0aGlzKSk7XG5cblx0XHQvLyBDb25maWd1cmUgdGhyZWFkIGR1bXAgcGFuZWxcblx0XHQkKCcjZHNoLXRocmVhZER1bXBNb2RhbCcpLm1vZGFsKHtcblx0XHRcdGJhY2tkcm9wOiAnc3RhdGljJyxcblx0XHRcdGtleWJvYXJkOiBmYWxzZSxcblx0XHRcdHNob3c6IGZhbHNlLFxuXHRcdH0pO1xuXG5cdFx0Ly8gQWRkIGxpc3RlbmVyIGZvciB0aHJlYWRzIGR1bXAgcGFuZWwgaGlkZVxuXHRcdCQoJyNkc2gtdGhyZWFkRHVtcE1vZGFsJykub24oJ2hpZGRlbi5icy5tb2RhbCcsICQucHJveHkodGhpcy5fb25UaHJlYWREdW1wTW9kYWxIaWRkZW4sIHRoaXMpKTtcblxuXHRcdC8vIEFkZCBjbGljayBsaXN0ZW5lciB0byB0aHJlYWRzIGR1bXAgY29weSBidXR0b25cblx0XHQkKCcjZHNoLWNvcHlUaHJlYWREdW1wQnQnKS5vbignY2xpY2snLCAkLnByb3h5KHRoaXMuX29uQ29weVRocmVhZER1bXBDbGljaywgdGhpcykpO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSB0aW1lIHJhbmdlIHNsaWRlclxuXHRcdHRoaXMuX3RpbWVTbGlkZXIgPSAkKCcjZHNoLXRpbWVTbGlkZXInKS5rZW5kb1JhbmdlU2xpZGVyKHtcblx0XHRcdG1pbjogLTI0LFxuICAgICAgICAgICAgbWF4OiAwLFxuICAgICAgICAgICAgc21hbGxTdGVwOiAxLFxuICAgICAgICAgICAgbGFyZ2VTdGVwOiAwLFxuXHRcdFx0Y2hhbmdlOiAkLnByb3h5KHRoaXMuX29uVGltZVJhbmdlQ2hhbmdlLCB0aGlzKSxcblx0XHRcdHRvb2x0aXA6IHtcblx0XHRcdFx0dGVtcGxhdGU6IGdldFRpbWVSYW5nZVRvb2x0aXBUZW1wbGF0ZSgpXG5cdFx0XHR9LFxuXHRcdFx0bGVmdERyYWdIYW5kbGVUaXRsZTogJ0RyYWcnLFxuXHRcdFx0cmlnaHREcmFnSGFuZGxlVGl0bGU6ICdEcmFnJyxcblx0XHR9KS5kYXRhKCdrZW5kb1JhbmdlU2xpZGVyJyk7XG5cblx0XHQvLyBBZGQgY2xpY2sgbGlzdGVuZXIgdG8gcmVzZXQgY2hhcnRzIGJ1dHRvblxuXHRcdCQoJyNkc2gtcmVzZXRCdCcpLm9uKCdjbGljaycsICQucHJveHkodGhpcy5fb25SZXNldENoYXJ0c0NsaWNrLCB0aGlzKSk7XG5cblx0XHQvLyBBZGQgY2xpY2sgbGlzdGVuZXIgdG8gcGxheSAmIHBhdXNlIGNoYXJ0IHVwZGF0ZSBidXR0b25zXG5cdFx0JCgnI2RzaC1wYXVzZUJ0Jykub24oJ2NsaWNrJywgJC5wcm94eSh0aGlzLl9vblBhdXNlVXBkYXRlQ2xpY2ssIHRoaXMpKTtcblx0XHQkKCcjZHNoLXBsYXlCdCcpLm9uKCdjbGljaycsICQucHJveHkodGhpcy5fb25QbGF5VXBkYXRlQ2xpY2ssIHRoaXMpKTtcblxuXHRcdC8vIFNldCByZWZlcmVuY2UgdG8gY2hhcnRzXG5cdFx0dGhpcy5fY3B1VXNhZ2VDaGFydCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkc2gtY3B1VXNhZ2VDaGFydCcpO1xuXHRcdHRoaXMuX3RocmVhZENvdW50Q2hhcnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHNoLXRocmVhZENvdW50Q2hhcnQnKTtcblx0XHR0aGlzLl9tZW1vcnlDaGFydCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkc2gtbWVtb3J5Q2hhcnQnKTtcblx0XHR0aGlzLl9uZXR3b3JrUlRDaGFydCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkc2gtbmV0d29ya1JUQ2hhcnQnKTtcblx0XHR0aGlzLl9uZXR3b3JrMjRoQ2hhcnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHNoLW5ldHdvcmsyNGhDaGFydCcpO1xuXHRcdHRoaXMuX3N5c1dvcmtsb2FkQ2hhcnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHNoLXN5c3RlbVdvcmtsb2FkQ2hhcnQnKTtcblx0XHR0aGlzLl9vdXRUY3BNc2dRdWV1ZUNoYXJ0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2RzaC1vdXRnb2luZ1RjcE1lc3NhZ2VzUXVldWVDaGFydCcpO1xuXHRcdHRoaXMuX291dFVkcE1zZ1F1ZXVlQ2hhcnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHNoLW91dGdvaW5nVWRwTWVzc2FnZXNRdWV1ZUNoYXJ0Jyk7XG5cdFx0dGhpcy5fc3lzUXVldWVDaGFydCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkc2gtc3lzdGVtUXVldWVDaGFydCcpO1xuXHRcdHRoaXMuX2V4dFF1ZXVlQ2hhcnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZHNoLWV4dGVuc2lvblF1ZXVlQ2hhcnQnKTtcblxuXHRcdC8vIFNldCBjb2xvcnMgaW4gY2hhcnQgbGVnZW5kc1xuXHRcdCQoJyNkc2gtc3lzdGVtTG9hZENvbG9yJykuY3NzKCdjb2xvcicsIHRoaXMuX2NwdVVzYWdlQ2hhcnQuc3lzdGVtQ29sb3IpO1xuXHRcdCQoJyNkc2gtcHJvY2Vzc0xvYWRDb2xvcicpLmNzcygnY29sb3InLCB0aGlzLl9jcHVVc2FnZUNoYXJ0LnByb2Nlc3NDb2xvcik7XG5cdFx0JCgnI2RzaC1hbGxvY01lbUNvbG9yJykuY3NzKCdjb2xvcicsIHRoaXMuX21lbW9yeUNoYXJ0LmFsbG9jYXRlZENvbG9yKTtcblx0XHQkKCcjZHNoLXVzZWRNZW1Db2xvcicpLmNzcygnY29sb3InLCB0aGlzLl9tZW1vcnlDaGFydC51c2VkQ29sb3IpO1xuXHRcdCQoJyNkc2gtaW5jb21pbmdOZXRDb2xvcicpLmNzcygnY29sb3InLCB0aGlzLl9uZXR3b3JrUlRDaGFydC5pbmNvbWluZ0NvbG9yKTtcblx0XHQkKCcjZHNoLW91dGdvaW5nTmV0Q29sb3InKS5jc3MoJ2NvbG9yJywgdGhpcy5fbmV0d29ya1JUQ2hhcnQub3V0Z29pbmdDb2xvcik7XG5cblx0XHQvLyBSZXNldCB0aW1lIHJhbmdlIG9uIDI0aCBuZXR3b3JrIGNoYXJ0XG5cdFx0dGhpcy5fb25UaW1lUmFuZ2VDaGFuZ2UoKTtcblxuXHRcdC8vIEFkZCBsaXN0ZW5lciB0byByZWRyYXcgYWxsIGNoYXJ0cyBvbiBtYWluIHRhYiBjaGFuZ2Vcblx0XHQvLyAodG8gd29yayBhcm91bmQgYW4gaXNzdWUgd2l0aCB0aGUgY2hhcnQgcmVzaXppbmcgdG8gZGVmYXVsdCB3aWR0aCB3aGVuIHBhbmUgaXMgaGlkZGVuKVxuXHRcdCQoJ2FbZGF0YS10b2dnbGU9XCJ0YWJcIl0nKS5vbignc2hvd24uYnMudGFiJywgJC5wcm94eSh0aGlzLl9vbldpbmRvd1Jlc2l6ZSwgdGhpcykpO1xuXG5cdFx0Ly8gQWRkIGxpc3RlbmVyIHRvIHJlZHJhdyBuZXR3b3JrIGNoYXJ0cyBvbiBuZXR3b3JrIHRhYiBjaGFuZ2Vcblx0XHQvLyAodG8gd29yayBhcm91bmQgYW4gaXNzdWUgd2l0aCB0aGUgY2hhcnQgcmVzaXppbmcgdG8gZGVmYXVsdCB3aWR0aCB3aGVuIHBhbmUgaXMgaGlkZGVuKVxuXHRcdCQoJyNkc2gtbmV0d29ya1BpbGxzIGFbZGF0YS10b2dnbGU9XCJwaWxsXCJdJykub24oJ3Nob3duLmJzLnRhYicsICQucHJveHkodGhpcy5fcmVkcmF3TmV0d29ya0NoYXJ0cywgdGhpcykpO1xuXG5cdFx0Ly8gQWRkIGxpc3RlbmVyIHRvIHJlZHJhdyBvdXRnb2luZyBtZXNzYWdlcyBxdWV1ZSBjaGFydHMgb24gdGFiIGNoYW5nZVxuXHRcdC8vICh0byB3b3JrIGFyb3VuZCBhbiBpc3N1ZSB3aXRoIHRoZSBjaGFydCByZXNpemluZyB0byBkZWZhdWx0IHdpZHRoIHdoZW4gcGFuZSBpcyBoaWRkZW4pXG5cdFx0JCgnI2RzaC1tc2dRdWV1ZVBpbGxzIGFbZGF0YS10b2dnbGU9XCJwaWxsXCJdJykub24oJ3Nob3duLmJzLnRhYicsICQucHJveHkodGhpcy5fcmVkcmF3T3V0TXNnQ2hhcnRzLCB0aGlzKSk7XG5cblx0XHQvLyBBZGQgbGlzdGVuZXIgdG8gcmVkcmF3IGFsbCBjaGFydHMgaW4gY2FzZSBvZiB3aW5kb3cgcmVzaXplXG5cdFx0JCh3aW5kb3cpLm9uKCdyZXNpemUnLCAkLnByb3h5KHRoaXMuX29uV2luZG93UmVzaXplLCB0aGlzKSk7XG5cdFx0dGhpcy5fb25XaW5kb3dSZXNpemUoKTsgLy8gQWxzbyBkbyBpdCBpbW1lZGlhdGVseVxuXG5cdFx0Ly8gQWRkIGxpc3RlbmVyIHRvIHNob3cgaGVscCB0b29sdGlwcyBpbiBxdWV1ZXMgc3RhdHVzIHRhYlxuXHRcdCQoJyNkc2gtcXVldWVzJykua2VuZG9Ub29sdGlwKHtcblx0XHRcdGZpbHRlcjogJ2lbdGl0bGVdLmhlbHAnLFxuXHRcdFx0cG9zaXRpb246ICdyaWdodCcsXG5cdFx0XHR3aWR0aDogJzI1MHB4Jyxcblx0XHRcdGNvbnRlbnQ6IGZ1bmN0aW9uKGUpIHtcblx0XHRcdFx0cmV0dXJuIGA8ZGl2IGNsYXNzPVwiaGVscC10b29sdGlwXCI+JHtlLnRhcmdldC5kYXRhKCd0aXRsZScpfTwvZGl2PmA7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHQvLyBBZGQgbGlzdGVuZXIgdG8gcmVnZW5lcmF0ZSBsaW5rIHRvIG9wZW4gd2ViIHNlcnZlciBleHRlcm5hbCBtYW5hZ2VyIGNvbnNvbGVcblx0XHQkKCcjZHNoLXVzZUh0dHBzQ2hlY2snKS5vbignY2hhbmdlJywgJC5wcm94eSh0aGlzLl9vblVzZUh0dHBzRm9yV3NNYW5hZ2VyQ2hhbmdlLCB0aGlzKSk7XG5cblx0XHQvLyBTZW5kIGluaXRpYWxpemF0aW9uIHJlcXVlc3Rcblx0XHR0aGlzLnNlbmRFeHRlbnNpb25SZXF1ZXN0KHRoaXMuUkVRX0lOSVQpO1xuXHR9XG5cblx0ZGVzdHJveSgpXG5cdHtcblx0XHQvLyBDYWxsIHN1cGVyIG1ldGhvZFxuXHRcdHN1cGVyLmRlc3Ryb3koKTtcblxuXHRcdC8vIERlc3Ryb3kgc2Nyb2xsaW5nIHRhYnNcblx0XHQkKCcjZHNoLXRhYk5hdmlnYXRvciAjdGFicycpLnNjcm9sbGluZ1RhYnMoJ2Rlc3Ryb3knKTtcblxuXHRcdC8vIFJlbW92ZSBvdGhlciBsaXN0ZW5lcnNcblx0XHQkKCcjZHNoLXJlc2V0QnQnKS5vZmYoJ2NsaWNrJyk7XG5cdFx0JCgnI2RzaC1wYXVzZUJ0Jykub2ZmKCdjbGljaycpO1xuXHRcdCQoJyNkc2gtcGxheUJ0Jykub2ZmKCdjbGljaycpO1xuXHRcdCQoJyNkc2gtZHVtcFRocmVhZHNCdCcpLm9mZignY2xpY2snKTtcblx0XHQkKCdhW2RhdGEtdG9nZ2xlPVwidGFiXCJdJykub2ZmKCdzaG93bi5icy50YWInKTtcblx0XHQkKCdhW2RhdGEtdG9nZ2xlPVwicGlsbFwiXScpLm9mZignc2hvd24uYnMudGFiJyk7XG5cdFx0JCh3aW5kb3cpLm9mZigncmVzaXplJyk7XG5cdFx0JCgnI2RzaC11c2VIdHRwc0NoZWNrJykub2ZmKCdjaGFuZ2UnKTtcblxuXHRcdC8vIFJlbW92ZSB0aHJlYWQgZHVtcCBwYW5lbCBsaXN0ZW5lclxuXHRcdCQoJyNkc2gtdGhyZWFkRHVtcE1vZGFsJykub2ZmKCdoaWRkZW4uYnMubW9kYWwnKTtcblxuXHRcdC8vIENsZWFyIHJlcXVlc3Qgc2NoZWR1bGluZ1xuXHRcdGNsZWFyVGltZW91dCh0aGlzLl9yZXF1ZXN0VGltZXIpO1xuXHR9XG5cblx0b25FeHRlbnNpb25Db21tYW5kKGNvbW1hbmQsIGRhdGEpXG5cdHtcblx0XHQvLyBJbml0aWFsaXphdGlvbiBkYXRhIHJlY2VpdmVkXG5cdFx0aWYgKGNvbW1hbmQgPT0gdGhpcy5SRVNQX0lOSVQpXG5cdFx0e1xuXHRcdFx0Ly8gU2VydmVyIHNlbmRzIGZsYWdzIGluZGljYXRpbmcgaWYgd2ViIHNlcnZlcidzIGludGVybmFsIG1hbmFnZXIgaXMgYWNjZXNzaWJsZSBhbmQgaG93XG5cdFx0XHR0aGlzLl93c01hbmFnZXJDb25maWcgPSB7XG5cdFx0XHRcdGhhc0FjY2VzczogZGF0YS5nZXRCb29sKCdoYXNXc01hbmFnZXInKSxcblx0XHRcdFx0aHR0cEVuYWJsZWQ6IGRhdGEuZ2V0Qm9vbCgnaHR0cEVuYWJsZWQnKSxcblx0XHRcdFx0aHR0cHNFbmFibGVkOiBkYXRhLmdldEJvb2woJ2h0dHBzRW5hYmxlZCcpLFxuXHRcdFx0XHRodHRwUG9ydDogZGF0YS5nZXRJbnQoJ2h0dHBQb3J0JyksXG5cdFx0XHRcdGh0dHBzUG9ydDogZGF0YS5nZXRJbnQoJ2h0dHBzUG9ydCcpLFxuXHRcdFx0fVxuXG5cdFx0XHQvLyBFbmFibGUgYWNjZXNzIHRvIHdlYiBzZXJ2ZXIgbWFuYWdlciBjb25zb2xlXG5cdFx0XHR0aGlzLl9lbmFibGVXZWJTZXJ2ZXJNYW5hZ2VyQWNjZXNzKCk7XG5cblx0XHRcdC8vIFJlcXVlc3QgZGF0YSB0byBzZXJ2ZXJcblx0XHRcdHRoaXMuX3JlcXVlc3REYXRhKHRydWUpO1xuXHRcdH1cblxuXHRcdC8vIERhdGEgcmVjZWl2ZWRcblx0XHRlbHNlIGlmIChjb21tYW5kID09IHRoaXMuUkVTUF9EQVRBKVxuXHRcdHtcblx0XHRcdC8vIENQVSBMT0FEIENIQVJUXG5cblx0XHRcdHRoaXMuX2NwdVVzYWdlQ2hhcnQuYWRkRW50cnkoZGF0YS5nZXREb3VibGUoJ3BDcHUnKSwgZGF0YS5nZXREb3VibGUoJ3NDcHUnKSk7XG5cdFx0XHQkKCcjZHNoLXN5c3RlbUxvYWRMYWJlbCcpLnRleHQoZGF0YS5nZXREb3VibGUoJ3NDcHUnKSk7XG5cdFx0XHQkKCcjZHNoLXByb2Nlc3NMb2FkTGFiZWwnKS50ZXh0KGRhdGEuZ2V0RG91YmxlKCdwQ3B1JykpO1xuXG5cdFx0XHQvLyBBcyBzeXN0ZW0gY3B1IGxvYWQgaXMgbm90IGFsd2F5cyBhdmFpbGFibGUgKGZvciBleGFtcGxlIG9uIE1hY09TIFgpLCBsZXQncyBoaWRlIGl0IGluIGNhc2UgaXQgaXNuJ3Rcblx0XHRcdGlmIChkYXRhLmdldERvdWJsZSgnc0NwdScpIDwgMClcblx0XHRcdFx0JCgnI2RzaC1zeXN0ZW1Mb2FkTGVnZW5kJykuaGlkZSgpO1xuXG5cdFx0XHQvLyBUSFJFQURTIENPVU5UIENIQVJUXG5cblx0XHRcdGNvbnN0IHRocmVhZENvdW50ID0gZGF0YS5nZXRTRlNBcnJheSgndGhMaXN0Jykuc2l6ZSgpO1xuXHRcdFx0dGhpcy5fdGhyZWFkQ291bnRDaGFydC5hZGRFbnRyeSh0aHJlYWRDb3VudCk7XG5cdFx0XHQkKCcjZHNoLXRocmVhZHNDb3VudExhYmVsJykudGV4dCh0aHJlYWRDb3VudCk7XG5cblx0XHRcdC8vIE1FTU9SWSBVU0FHRSBDSEFSVFxuXHRcdFx0Ly8gTk9URTogbWVtb3J5IGRhdGEgaXMgc2VudCBhcyBCeXRlcyBieSB0aGUgc2VydmVyXG5cblx0XHRcdGNvbnN0IGZyZWVNZW0gPSBkYXRhLmdldExvbmcoJ2ZyZWVNZW0nKTtcblx0XHRcdGNvbnN0IG1heE1lbSA9IGRhdGEuZ2V0TG9uZygnbWF4TWVtJyk7XG5cdFx0XHRjb25zdCB0b3RhbE1lbSA9IGRhdGEuZ2V0TG9uZygndG90YWxNZW0nKTtcblx0XHRcdGNvbnN0IHVzZWRNZW0gPSB0b3RhbE1lbSAtIGZyZWVNZW07XG5cblx0XHRcdHRoaXMuX21lbW9yeUNoYXJ0LmFkZEVudHJ5KHRvdGFsTWVtLCB1c2VkTWVtKTtcblx0XHRcdCQoJyNkc2gtbWF4TWVtb3J5TGFiZWwnKS50ZXh0KHRoaXMuX2dldE1lbU9iamVjdChtYXhNZW0pLmxhYmVsKTtcblx0XHRcdCQoJyNkc2gtZnJlZU1lbW9yeUxhYmVsJykudGV4dCh0aGlzLl9nZXRNZW1PYmplY3QoZnJlZU1lbSkubGFiZWwpO1xuXG5cdFx0XHQvLyBUSFJFQURTIExJU1RcblxuXHRcdFx0Y29uc3QgdG90YWxUaHJlYWRDcHVUaW1lID0gZGF0YS5nZXRMb25nKCd0aENwdScpO1xuXHRcdFx0bGV0IHRocmVhZHMgPSBbXTtcblxuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmdldFNGU0FycmF5KCd0aExpc3QnKS5zaXplKCk7IGkrKylcblx0XHRcdHtcblx0XHRcdFx0bGV0IHRocmVhZERhdGEgPSBkYXRhLmdldFNGU0FycmF5KCd0aExpc3QnKS5nZXRTRlNPYmplY3QoaSk7XG5cblx0XHRcdFx0dGhyZWFkcy5wdXNoKHtcblx0XHRcdFx0XHRpZDogdGhyZWFkRGF0YS5nZXRMb25nKCdpZCcpLFxuXHRcdFx0XHRcdG5hbWU6IHRocmVhZERhdGEuZ2V0VXRmU3RyaW5nKCduYW1lJyksXG5cdFx0XHRcdFx0Y3B1VGltZTogTWF0aC5yb3VuZCh0aHJlYWREYXRhLmdldExvbmcoJ2NwdScpIC8gdG90YWxUaHJlYWRDcHVUaW1lICogMTAwMCkgLyAxMFxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3Vic3RpdHV0ZSBncmlkJ3MgZGF0YSBzb3VyY2UsIHJldGFpbmluZyBjdXJyZW50IHNvcnRpbmdcblx0XHRcdGxldCBjdXJyU29ydCA9IHRoaXMuX3RocmVhZHNHcmlkLmRhdGFTb3VyY2Uuc29ydCgpO1xuXHRcdFx0dGhpcy5fdGhyZWFkc0dyaWQuc2V0RGF0YVNvdXJjZSh0aGlzLl9nZXRUaHJlYWRzR3JpZERhdGFTb3VyY2UodGhyZWFkcywgY3VyclNvcnQpKTtcblxuXHRcdFx0Ly8gTkVUV09SSyBUUkFGRklDXG5cdFx0XHQvLyBOT1RFOiBuZXR3b3JrIHRyYWZmaWMgZGF0YSBpcyBzZW50IGFzIEtCeXRlcyBieSB0aGUgc2VydmVyXG5cblx0XHRcdGlmIChkYXRhLmNvbnRhaW5zS2V5KCdudE91dEhpc3RvcnknKSlcblx0XHRcdHtcblx0XHRcdFx0Y29uc3Qgb3V0Z29pbmdEYXRhID0gZGF0YS5nZXRMb25nQXJyYXkoJ250T3V0SGlzdG9yeScpO1xuXHRcdFx0XHRjb25zdCBpbmNvbWluZ0RhdGEgPSBkYXRhLmdldExvbmdBcnJheSgnbnRJbkhpc3RvcnknKTtcblx0XHRcdFx0Y29uc3Qgc2FtcGxpbmdSYXRlTWlucyA9IGRhdGEuZ2V0SW50KCdudFJhdGUnKTtcblx0XHRcdFx0Y29uc3Qgc2hpZnRTZWNvbmRzID0gZGF0YS5nZXRJbnQoJ250U2hpZnQnKTtcblxuXHRcdFx0XHR0aGlzLl9uZXR3b3JrMjRoQ2hhcnQuYWRkSGlzdG9yeUVudHJpZXMob3V0Z29pbmdEYXRhLCBpbmNvbWluZ0RhdGEsIHNhbXBsaW5nUmF0ZU1pbnMgKiA2MCwgc2hpZnRTZWNvbmRzKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIGN1cnJlbnQgdmFsdWVzXG5cdFx0XHR0aGlzLl9uZXR3b3JrMjRoQ2hhcnQuYWRkRW50cnkoZGF0YS5nZXRMb25nKCdudE91dCcpLCBkYXRhLmdldExvbmcoJ250SW4nKSk7XG5cdFx0XHR0aGlzLl9uZXR3b3JrUlRDaGFydC5hZGRFbnRyeShkYXRhLmdldExvbmcoJ250T3V0JyksIGRhdGEuZ2V0TG9uZygnbnRJbicpKTtcblxuXHRcdFx0Ly8gVFJBRkZJQyBERVRBSUxTXG5cblx0XHRcdC8vIFNlc3Npb25zXG5cdFx0XHQkKCcjZHNoLWRldFNlc3Npb25zQ3VycmVudCcpLnRleHQoJ0N1cnJlbnQ6ICcgKyAoZGF0YS5nZXRJbnQoJ3NTb2NrZXQnKSArIGRhdGEuZ2V0SW50KCdzSHR0cCcpKSk7XG5cdFx0XHQkKCcjZHNoLWRldFNlc3Npb25zTWF4JykudGV4dCgnTWF4OiAnICsgZGF0YS5nZXRJbnQoJ2Njc01heCcpKTtcblx0XHRcdCQoJyNkc2gtZGV0U2Vzc2lvbnNTb2NrZXQnKS50ZXh0KCdTb2NrZXQ6ICcgKyBkYXRhLmdldEludCgnc1NvY2tldCcpKTtcblx0XHRcdCQoJyNkc2gtZGV0U2Vzc2lvbnNIdHRwJykudGV4dCgnSHR0cDogJyArIGRhdGEuZ2V0SW50KCdzSHR0cCcpKTtcblxuXHRcdFx0Ly8gVXNlcnNcblx0XHRcdCQoJyNkc2gtZGV0VXNlcnNDdXJyZW50JykudGV4dCgnQ3VycmVudDogJyArIChkYXRhLmdldEludCgndVNvY2tldCcpICsgZGF0YS5nZXRJbnQoJ3VIdHRwJykgKyBkYXRhLmdldEludCgndU5wYycpKSk7XG5cdFx0XHQkKCcjZHNoLWRldFVzZXJzTWF4JykudGV4dCgnTWF4OiAnICsgZGF0YS5nZXRJbnQoJ2NjdU1heCcpKTtcblx0XHRcdCQoJyNkc2gtZGV0VXNlcnNTb2NrZXQnKS50ZXh0KCdTb2NrZXQ6ICcgKyBkYXRhLmdldEludCgndVNvY2tldCcpKTtcblx0XHRcdCQoJyNkc2gtZGV0VXNlcnNIdHRwJykudGV4dCgnSHR0cDogJyArIGRhdGEuZ2V0SW50KCd1SHR0cCcpKTtcblx0XHRcdCQoJyNkc2gtZGV0VXNlcnNOcGMnKS50ZXh0KCdOcGM6ICcgKyBkYXRhLmdldEludCgndU5wYycpKTtcblxuXHRcdFx0Ly8gUm9vbXNcblx0XHRcdCQoJyNkc2gtZGV0Um9vbXMnKS50ZXh0KGRhdGEuZ2V0SW50KCdyVG90YWwnKSk7XG5cdFx0XHQkKCcjZHNoLWRldFJvb21zUmVndWxhcicpLnRleHQoJ1JlZ3VsYXI6ICcgKyAoZGF0YS5nZXRJbnQoJ3JUb3RhbCcpIC0gZGF0YS5nZXRJbnQoJ3JHYW1lJykpKTtcblx0XHRcdCQoJyNkc2gtZGV0Um9vbXNHYW1lJykudGV4dCgnR2FtZTogJyArIGRhdGEuZ2V0SW50KCdyR2FtZScpKTtcblxuXHRcdFx0Ly8gVG90YWwgZGF0YSB0cmFuc2ZlclxuXHRcdFx0JCgnI2RzaC1kZXREYXRhVHJhbnNmZXJPdXQnKS50ZXh0KCdPdXQ6ICcgKyBrQnl0ZXNUb1NpemUoZGF0YS5nZXRMb25nKCdudE91dCcpKSk7XG5cdFx0XHQkKCcjZHNoLWRldERhdGFUcmFuc2ZlckluJykudGV4dCgnSW46ICcgKyBrQnl0ZXNUb1NpemUoZGF0YS5nZXRMb25nKCdudEluJykpKTtcblxuXHRcdFx0Ly8gQ3VycmVudCBkYXRhIHRyYW5zZmVyIHJhdGVcblx0XHRcdGxldCBvYmogPSB0aGlzLl9uZXR3b3JrUlRDaGFydC5nZXRMYXN0RW50cnkoKTtcblxuXHRcdFx0aWYgKG9iaiA9PSBudWxsKVxuXHRcdFx0XHRvYmogPSB7b3V0Z29pbmc6IDAsIGluY29taW5nOiAwfTtcblxuXHRcdFx0JCgnI2RzaC1kZXRUcmFuc2ZlclJhdGVPdXQnKS50ZXh0KCdPdXQ6ICcgKyBrQnl0ZXNUb1NpemUob2JqLm91dGdvaW5nLCAyLCAnS0InLCAnL3MnKSk7XG5cdFx0XHQkKCcjZHNoLWRldFRyYW5zZmVyUmF0ZUluJykudGV4dCgnSW46ICcgKyBrQnl0ZXNUb1NpemUob2JqLmluY29taW5nLCAyLCAnS0InLCAnL3MnKSk7XG5cblx0XHRcdC8vIEF2ZXJhZ2UgZGF0YSB0cmFuc2ZlciByYXRlIG92ZXIgd2hvbGUgdXB0aW1lXG5cdFx0XHRpZiAodGhpcy5fdXB0aW1lU2VjcyA+IDApXG5cdFx0XHR7XG5cdFx0XHRcdGNvbnN0IGF2Z091dCA9IE1hdGgucm91bmQoZGF0YS5nZXRMb25nKCdudE91dCcpIC8gdGhpcy5fdXB0aW1lU2VjcyAqIDEwMCkgLyAxMDA7XG5cdFx0XHRcdGNvbnN0IGF2Z0luID0gTWF0aC5yb3VuZChkYXRhLmdldExvbmcoJ250SW4nKSAvIHRoaXMuX3VwdGltZVNlY3MgKiAxMDApIC8gMTAwO1xuXG5cdFx0XHRcdCQoJyNkc2gtZGV0QXZnVHJhbnNmZXJSYXRlT3V0JykudGV4dCgnT3V0OiAnICsga0J5dGVzVG9TaXplKGF2Z091dCwgMiwgJ0tCJywgJy9zJykpO1xuXHRcdFx0XHQkKCcjZHNoLWRldEF2Z1RyYW5zZmVyUmF0ZUluJykudGV4dCgnSW46ICcgKyBrQnl0ZXNUb1NpemUoYXZnSW4sIDIsICdLQicsICcvcycpKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRHJvcHBlZCBwYWNrZXRzXG5cdFx0XHRjb25zdCB0b3RhbFBhY2tldHNPdXQgPSBkYXRhLmdldExvbmcoJ3BrdE91dCcpO1xuXG5cdFx0XHRjb25zdCB0b3RhbERyb3BwZWRUY3BQYWNrZXRzT3V0ID0gZGF0YS5nZXRMb25nKCdwa3RPdXREcm9wJyk7XG5cdFx0XHQkKCcjZHNoLWRldERyb3BwZWRUY3BQYWNrZXRzT3V0JykudGV4dChgT3V0IFRDUDogJHt0b3RhbERyb3BwZWRUY3BQYWNrZXRzT3V0fSAoJHtNYXRoLnJvdW5kKHRvdGFsRHJvcHBlZFRjcFBhY2tldHNPdXQgLyB0b3RhbFBhY2tldHNPdXQgKiAxMDApfSUpYCk7XG5cblx0XHRcdGNvbnN0IHRvdGFsRHJvcHBlZFVkcFBhY2tldHNPdXQgPSBkYXRhLmdldExvbmcoJ3BrdE91dFVkcERyb3AnKTtcblx0XHRcdCQoJyNkc2gtZGV0RHJvcHBlZFVkcFBhY2tldHNPdXQnKS50ZXh0KGBPdXQgVURQOiAke3RvdGFsRHJvcHBlZFVkcFBhY2tldHNPdXR9ICgke01hdGgucm91bmQodG90YWxEcm9wcGVkVWRwUGFja2V0c091dCAvIHRvdGFsUGFja2V0c091dCAqIDEwMCl9JSlgKTtcblxuXHRcdFx0Y29uc3QgdG90YWxQYWNrZXRzSW4gPSBkYXRhLmdldExvbmcoJ3BrdEluJyk7XG5cdFx0XHRjb25zdCB0b3RhbERyb3BwZWRQYWNrZXRzSW4gPSBkYXRhLmdldExvbmcoJ3BrdEluRHJvcCcpO1xuXHRcdFx0JCgnI2RzaC1kZXREcm9wcGVkUGFja2V0c0luJykudGV4dChgSW46ICR7dG90YWxEcm9wcGVkUGFja2V0c0lufSAoJHtNYXRoLnJvdW5kKHRvdGFsRHJvcHBlZFBhY2tldHNJbiAvIHRvdGFsUGFja2V0c0luICogMTAwKX0lKWApO1xuXG5cdFx0XHQvLyBTWVNURU0gU1RBVFVTXG5cblx0XHRcdC8vIE91dGdvaW5nIFRDUCBtZXNzYWdlcyBxdWV1ZVxuXHRcdFx0Y29uc3Qgb3V0TXNnUXVldWUgPSBkYXRhLmdldEludCgnb3V0TXNnUXVldWUnKTtcblx0XHRcdGNvbnN0IG91dE1zZ1F1ZXVlTWF4ID0gZGF0YS5nZXRJbnQoJ291dE1zZ1F1ZXVlTWF4Jyk7XG5cdFx0XHR0aGlzLl9vdXRUY3BNc2dRdWV1ZUNoYXJ0LmFkZEVudHJ5KG91dE1zZ1F1ZXVlLCBvdXRNc2dRdWV1ZU1heCk7XG5cdFx0XHR0aGlzLl90Y3BPdXRUaHJlYWRzID0gZGF0YS5nZXRJbnQoJ291dE1zZ1RoJyk7XG5cdFx0XHR0aGlzLl90Y3BPdXRMb2FkID0gdGhpcy5fb3V0VGNwTXNnUXVldWVDaGFydC5sb2FkO1xuXG5cdFx0XHQvLyBPdXRnb2luZyBVRFAgbWVzc2FnZXMgcXVldWVcblx0XHRcdGNvbnN0IG91dFVkcE1zZ1F1ZXVlID0gZGF0YS5nZXRJbnQoJ291dFVkcE1zZ1F1ZXVlJyk7XG5cdFx0XHRjb25zdCBvdXRVZHBNc2dRdWV1ZU1heCA9IGRhdGEuZ2V0SW50KCdvdXRVZHBNc2dRdWV1ZU1heCcpO1xuXHRcdFx0dGhpcy5fb3V0VWRwTXNnUXVldWVDaGFydC5hZGRFbnRyeShvdXRVZHBNc2dRdWV1ZSwgb3V0VWRwTXNnUXVldWVNYXgpO1xuXHRcdFx0dGhpcy5fdWRwT3V0VGhyZWFkcyA9IGRhdGEuZ2V0SW50KCdvdXRVZHBNc2dUaCcpO1xuXHRcdFx0dGhpcy5fdWRwT3V0TG9hZCA9IHRoaXMuX291dFVkcE1zZ1F1ZXVlQ2hhcnQubG9hZDtcblxuXHRcdFx0dGhpcy5fdXBkYXRlT3V0TWVzc2FnZXNRdWV1ZVN0YXR1cygpO1xuXG5cdFx0XHQvLyBTeXN0ZW0gQ29udHJvbGxlciByZXF1ZXN0cyBxdWV1ZVxuXHRcdFx0Y29uc3Qgc3lzQ3RybFF1ZXVlID0gZGF0YS5nZXRJbnQoJ3N5c0N0cmxRdWV1ZScpO1xuXHRcdFx0Y29uc3Qgc3lzQ3RybFF1ZXVlTWF4ID0gZGF0YS5nZXRJbnQoJ3N5c0N0cmxRdWV1ZU1heCcpO1xuXHRcdFx0dGhpcy5fc3lzUXVldWVDaGFydC5hZGRFbnRyeShzeXNDdHJsUXVldWUsIHN5c0N0cmxRdWV1ZU1heCk7XG5cdFx0XHQkKCcjZHNoLXN5c3RlbVF1ZXVlVGhyZWFkcycpLnRleHQodGhpcy5fZ2V0UXVldWVUaHJlYWRzTGFiZWwoZGF0YS5nZXRJbnQoJ3N5c0N0cmxUaCcpKSk7XG5cdFx0XHQkKCcjZHNoLXN5c3RlbVF1ZXVlTG9hZCcpLnRleHQodGhpcy5fZ2V0UXVldWVMb2FkTGFiZWwodGhpcy5fc3lzUXVldWVDaGFydC5sb2FkKSk7XG5cblx0XHRcdC8vIEV4dGVuc2lvbiBDb250cm9sbGVyIHJlcXVlc3RzIHF1ZXVlXG5cdFx0XHRjb25zdCBleHRDdHJsUXVldWUgPSBkYXRhLmdldEludCgnZXh0Q3RybFF1ZXVlJyk7XG5cdFx0XHRjb25zdCBleHRDdHJsUXVldWVNYXggPSBkYXRhLmdldEludCgnZXh0Q3RybFF1ZXVlTWF4Jyk7XG5cdFx0XHR0aGlzLl9leHRRdWV1ZUNoYXJ0LmFkZEVudHJ5KGV4dEN0cmxRdWV1ZSwgZXh0Q3RybFF1ZXVlTWF4KTtcblx0XHRcdCQoJyNkc2gtZXh0ZW5zaW9uUXVldWVUaHJlYWRzJykudGV4dCh0aGlzLl9nZXRRdWV1ZVRocmVhZHNMYWJlbChkYXRhLmdldEludCgnZXh0Q3RybFRoJykpKTtcblx0XHRcdCQoJyNkc2gtZXh0ZW5zaW9uUXVldWVMb2FkJykudGV4dCh0aGlzLl9nZXRRdWV1ZUxvYWRMYWJlbCh0aGlzLl9zeXNRdWV1ZUNoYXJ0LmxvYWQpKTtcblxuXHRcdFx0Ly8gRXZhbHVhdGUgb3ZlcmFsbCBzeXN0ZW0gd29ya2xvYWRcblx0XHRcdGxldCBzeXNXb3JrbG9hZCA9IE1hdGgucm91bmQoKG91dE1zZ1F1ZXVlIC8gb3V0TXNnUXVldWVNYXggK1xuXHRcdFx0XHRcdFx0XHRcdFx0XHQgIG91dFVkcE1zZ1F1ZXVlIC8gb3V0VWRwTXNnUXVldWVNYXggK1xuXHRcdFx0XHQgXHRcdFx0XHRcdFx0ICBzeXNDdHJsUXVldWUgLyBzeXNDdHJsUXVldWVNYXggK1xuXHRcdFx0XHQgXHRcdFx0XHRcdCAgXHQgIGV4dEN0cmxRdWV1ZSAvIGV4dEN0cmxRdWV1ZU1heCkgKiAxMDAgLyA0KTtcblx0XHRcdGlmIChzeXNXb3JrbG9hZCA+IDEwMClcblx0XHRcdFx0c3lzV29ya2xvYWQgPSAxMDA7XG5cblx0XHRcdHRoaXMuX3N5c1dvcmtsb2FkQ2hhcnQuYWRkRW50cnkoc3lzV29ya2xvYWQpO1xuXHRcdH1cblxuXHRcdC8vIFRocmVhZCBkdW1wIHJlY2VpdmVkXG5cdFx0ZWxzZSBpZiAoY29tbWFuZCA9PSB0aGlzLlJFU1BfVEhSRUFEX0RVTVApXG5cdFx0e1xuXHRcdFx0Ly8gRW5hYmxlIGJ1dHRvblxuXHRcdFx0JCgnI2RzaC1kdW1wVGhyZWFkc0J0JykuYXR0cignZGlzYWJsZWQnLCBmYWxzZSk7XG5cblx0XHRcdC8vIFNldCByZXN1bHRcblx0XHRcdCQoJyNkc2gtdGhyZWFkRHVtcFJlc3VsdCcpLnRleHQoZGF0YS5nZXRUZXh0KCdkdW1wJykpO1xuXG5cdFx0XHQvLyBEaXNwbGF5IG1vZGFsXG5cdFx0XHQkKCcjZHNoLXRocmVhZER1bXBNb2RhbCcpLm1vZGFsKCdzaG93Jyk7XG5cdFx0fVxuXHR9XG5cblx0b25VcHRpbWVVcGRhdGVkKHZhbHVlcylcblx0e1xuXHRcdHRoaXMuX3VwdGltZVNlY3MgPSB2YWx1ZXNbM107XG5cdFx0dGhpcy5fdXB0aW1lU2VjcyArPSAodmFsdWVzWzJdICogNjApO1xuXHRcdHRoaXMuX3VwdGltZVNlY3MgKz0gKHZhbHVlc1sxXSAqIDYwICogNjApO1xuXHRcdHRoaXMuX3VwdGltZVNlY3MgKz0gKHZhbHVlc1swXSAqIDI0ICogNjAgKiA2MCk7XG5cblx0XHQkKCcjZHNoLXVwdGltZURheXMnKS50ZXh0KCAodmFsdWVzWzBdIDw9IDkgPyAnMDAnIDogKHZhbHVlc1swXSA8PSA5OSA/ICcwJyA6ICcnKSkgKyB2YWx1ZXNbMF0gKTtcblx0XHQkKCcjZHNoLXVwdGltZUhvdXJzJykudGV4dCggKHZhbHVlc1sxXSA8PSA5ID8gJzAnIDogJycpICsgdmFsdWVzWzFdICk7XG5cdFx0JCgnI2RzaC11cHRpbWVNaW51dGVzJykudGV4dCggKHZhbHVlc1syXSA8PSA5ID8gJzAnIDogJycpICsgdmFsdWVzWzJdICk7XG5cdFx0JCgnI2RzaC11cHRpbWVTZWNvbmRzJykudGV4dCggKHZhbHVlc1szXSA8PSA5ID8gJzAnIDogJycpICsgdmFsdWVzWzNdICk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBVSSBFVkVOVCBMSVNURU5FUlNcblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRfb25VcGRhdGVJbnRlcnZhbENoYW5nZSgpXG5cdHtcblx0XHQvLyBSZXF1ZXN0IGRhdGEgdG8gc2VydmVyXG5cdFx0dGhpcy5fcmVxdWVzdERhdGEoKTtcblx0fVxuXG5cdF9vblBhdXNlVXBkYXRlQ2xpY2soKVxuXHR7XG5cdFx0dGhpcy5fc2V0Q2hhcnRVcGRhdGVQYXVzZWQodHJ1ZSk7XG5cblx0XHQvLyBIaWRlIHBhdXNlIGJ1dHRvbiBhbmQgc2hvdyBwbGF5IGJ1dHRvblxuXHRcdCQoJyNkc2gtcGF1c2VCdCcpLmFkZENsYXNzKCdoaWRkZW4nKTtcblx0XHQkKCcjZHNoLXBsYXlCdCcpLnJlbW92ZUNsYXNzKCdoaWRkZW4nKTtcblx0fVxuXG5cdF9vblBsYXlVcGRhdGVDbGljaygpXG5cdHtcblx0XHR0aGlzLl9zZXRDaGFydFVwZGF0ZVBhdXNlZChmYWxzZSk7XG5cblx0XHQvLyBIaWRlIHBsYXkgYnV0dG9uIGFuZCBzaG93IHBhdXNlIGJ1dHRvblxuXHRcdCQoJyNkc2gtcGF1c2VCdCcpLnJlbW92ZUNsYXNzKCdoaWRkZW4nKTtcblx0XHQkKCcjZHNoLXBsYXlCdCcpLmFkZENsYXNzKCdoaWRkZW4nKTtcblx0fVxuXG5cdF9vblJlc2V0Q2hhcnRzQ2xpY2soKVxuXHR7XG5cdFx0Ly8gUmVhY3RpdmF0ZSByZWFsdGltZSBjaGFydHMgdXBkYXRlXG5cdFx0dGhpcy5fb25QbGF5VXBkYXRlQ2xpY2soKTtcblxuXHRcdC8vIFJlc2V0IHJlYWx0aW1lIGNoYXJ0c1xuXHRcdHRoaXMuX2NwdVVzYWdlQ2hhcnQucmVzZXQoKTtcblx0XHR0aGlzLl90aHJlYWRDb3VudENoYXJ0LnJlc2V0KCk7XG5cdFx0dGhpcy5fbWVtb3J5Q2hhcnQucmVzZXQoKTtcblx0XHR0aGlzLl9uZXR3b3JrUlRDaGFydC5yZXNldCgpO1xuXHRcdHRoaXMuX3N5c1dvcmtsb2FkQ2hhcnQucmVzZXQoKTtcblx0XHR0aGlzLl9vdXRUY3BNc2dRdWV1ZUNoYXJ0LnJlc2V0KCk7XG5cdFx0dGhpcy5fb3V0VWRwTXNnUXVldWVDaGFydC5yZXNldCgpO1xuXHRcdHRoaXMuX3N5c1F1ZXVlQ2hhcnQucmVzZXQoKTtcblx0XHR0aGlzLl9leHRRdWV1ZUNoYXJ0LnJlc2V0KCk7XG5cdH1cblxuXHRfcmVkcmF3TmV0d29ya0NoYXJ0cygpXG5cdHtcblx0XHQvLyBSZWRyYXcgY2hhcnRzXG5cdFx0dGhpcy5fbmV0d29ya1JUQ2hhcnQucmVkcmF3KCk7XG5cdFx0dGhpcy5fbmV0d29yazI0aENoYXJ0LnJlZHJhdygpO1xuXG5cdFx0Ly8gUmVkcmF3IHRpbWUgcmFuZ2Ugc2xpZGVyXG5cdFx0dGhpcy5fdGltZVNsaWRlci5yZXNpemUoKTtcblx0fVxuXG5cdF9yZWRyYXdPdXRNc2dDaGFydHMoKVxuXHR7XG5cdFx0Ly8gUmVkcmF3IGNoYXJ0c1xuXHRcdHRoaXMuX291dFRjcE1zZ1F1ZXVlQ2hhcnQucmVkcmF3KCk7XG5cdFx0dGhpcy5fb3V0VWRwTXNnUXVldWVDaGFydC5yZWRyYXcoKTtcblxuXHRcdHRoaXMuX3VwZGF0ZU91dE1lc3NhZ2VzUXVldWVTdGF0dXMoKTtcblx0fVxuXG5cdF9vbldpbmRvd1Jlc2l6ZSgpXG5cdHtcblx0XHQvLyBSZWRyYXcgYWxsIGdsb2JhbCBjaGFydHNcblx0XHR0aGlzLl9jcHVVc2FnZUNoYXJ0LnJlZHJhdygpO1xuXHRcdHRoaXMuX3RocmVhZENvdW50Q2hhcnQucmVkcmF3KCk7XG5cdFx0dGhpcy5fbWVtb3J5Q2hhcnQucmVkcmF3KCk7XG5cdFx0dGhpcy5fcmVkcmF3TmV0d29ya0NoYXJ0cygpO1xuXG5cdFx0Ly8gUmVkcmF3IGFsbCBxdWV1ZSBjaGFydHNcblx0XHR0aGlzLl9zeXNXb3JrbG9hZENoYXJ0LnJlZHJhdygpO1xuXHRcdHRoaXMuX3N5c1F1ZXVlQ2hhcnQucmVkcmF3KCk7XG5cdFx0dGhpcy5fZXh0UXVldWVDaGFydC5yZWRyYXcoKTtcblx0XHR0aGlzLl9yZWRyYXdPdXRNc2dDaGFydHMoKTtcblx0fVxuXG5cdF9vblRpbWVSYW5nZUNoYW5nZSgpXG5cdHtcblx0XHRsZXQgdmFsdWVzID0gdGhpcy5fdGltZVNsaWRlci52YWx1ZSgpO1xuXG5cdFx0aWYgKHZhbHVlc1swXSA9PSB2YWx1ZXNbMV0pXG5cdFx0e1xuXHRcdFx0aWYgKHZhbHVlc1sxXSA9PSAtMjQpXG5cdFx0XHRcdHZhbHVlc1sxXSA9IC0yMztcblxuXHRcdFx0dmFsdWVzWzBdID0gdmFsdWVzWzFdIC0gMTtcblxuXHRcdFx0Ly8gUmVzZXQgdGhlIHRpbWUgcmFuZ2Ugc2xpZGVyIHZhbHVlICh3ZSBuZWVkIHRvIHVzZSBzZXRUaW1lb3V0XG5cdFx0XHQvLyBiYWNhdXNlIGRvaW5nIGl0IGluIHRoZSBjaGFuZ2UgZXZlbnQgbGlzdGVuZXIgZG9lc24ndCByZWRyYXcgdGhlIHNsaWRlcilcblx0XHRcdHNldFRpbWVvdXQoJC5wcm94eSggZnVuY3Rpb24odmFsdWVzKSB7IHRoaXMuX3RpbWVTbGlkZXIudmFsdWUodmFsdWVzKTsgfSwgdGhpcyksIDEwLCB2YWx1ZXMpO1xuXHRcdH1cblxuXHRcdHRoaXMuX25ldHdvcmsyNGhDaGFydC5yYW5nZSA9IHZhbHVlcztcblx0fVxuXG5cdF9vblVzZUh0dHBzRm9yV3NNYW5hZ2VyQ2hhbmdlKClcblx0e1xuXHRcdGNvbnN0IHdzTWFuID0gdGhpcy5fd3NNYW5hZ2VyQ29uZmlnO1xuXG5cdFx0bGV0IHVybCA9ICgkKCcjZHNoLXVzZUh0dHBzQ2hlY2snKS5wcm9wKCdjaGVja2VkJykgPyAnaHR0cHMnIDogJ2h0dHAnKSArICc6Ly8nO1xuXHRcdHVybCArPSB0aGlzLnNtYXJ0Rm94LmNvbmZpZy5ob3N0O1xuXHRcdHVybCArPSAnOicgKyAoJCgnI2RzaC11c2VIdHRwc0NoZWNrJykucHJvcCgnY2hlY2tlZCcpID8gd3NNYW4uaHR0cHNQb3J0IDogd3NNYW4uaHR0cFBvcnQpO1xuXHRcdHVybCArPSAnL21hbmFnZXIvc3RhdHVzJztcblxuXHRcdCQoJyNkc2gtdG9Xc01hbmFnZXJCdCcpLmF0dHIoJ2hyZWYnLCB1cmwpO1xuXHR9XG5cblx0X29uRHVtcFRocmVhZHNDbGljaygpXG5cdHtcblx0XHQvLyBEaXNhYmxlIGJ1dHRvblxuXHRcdCQoJyNkc2gtZHVtcFRocmVhZHNCdCcpLmF0dHIoJ2Rpc2FibGVkJywgdHJ1ZSk7XG5cblx0XHQvLyBTZW5kIHJlcXVlc3QgdG8gZXh0ZW5zaW9uXG5cdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9EVU1QX1RIUkVBRFMpO1xuXHR9XG5cblx0X29uQ29weVRocmVhZER1bXBDbGljaygpXG5cdHtcblx0XHQkKCcjZHNoLXRocmVhZER1bXBSZXN1bHQnKS5hdHRyKCdjb250ZW50ZWRpdGFibGUnLCB0cnVlKTtcblx0XHQkKCcjZHNoLXRocmVhZER1bXBSZXN1bHQnKS5hdHRyKCdzcGVsbGNoZWNrJywgZmFsc2UpO1xuXHRcdCQoJyNkc2gtdGhyZWFkRHVtcFJlc3VsdCcpLmZvY3VzKCk7XG5cdFx0ZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ3NlbGVjdEFsbCcpO1xuXHRcdGRvY3VtZW50LmV4ZWNDb21tYW5kKCdjb3B5Jyk7XG5cdFx0d2luZG93LmdldFNlbGVjdGlvbigpLnJlbW92ZUFsbFJhbmdlcygpO1xuXHRcdCQoJyNkc2gtdGhyZWFkRHVtcFJlc3VsdCcpLmJsdXIoKTtcblx0XHQkKCcjZHNoLXRocmVhZER1bXBSZXN1bHQnKS5hdHRyKCdjb250ZW50ZWRpdGFibGUnLCBmYWxzZSk7XG5cdH1cblxuXHRfb25UaHJlYWREdW1wTW9kYWxIaWRkZW4oKVxuXHR7XG5cdFx0Ly8gQ2xlYXIgbW9kYWwgY29udGVudFxuXHRcdCQoJyNkc2gtdGhyZWFkRHVtcFJlc3VsdCcpLnRleHQoJycpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8gUFJJVkFURSBNRVRIT0RTXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0X2VuYWJsZVdlYlNlcnZlck1hbmFnZXJBY2Nlc3MoKVxuXHR7XG5cdFx0Y29uc3Qgd3NNYW4gPSB0aGlzLl93c01hbmFnZXJDb25maWc7XG5cblx0XHRpZiAod3NNYW4uaGFzQWNjZXNzICYmICh3c01hbi5odHRwRW5hYmxlZCB8fCB3c01hbi5odHRwc0VuYWJsZWQpKVxuXHRcdHtcblx0XHRcdC8vIEhpZGUgYWxlcnRcblx0XHRcdCQoJyNkc2gtd3NNYW5hZ2VyQWxlcnQnKS5oaWRlKCk7XG5cblx0XHRcdC8vIEVuYWJsZSBidXR0b25cblx0XHRcdCQoJyNkc2gtdG9Xc01hbmFnZXJCdCcpLmF0dHIoJ2Rpc2FibGVkJywgZmFsc2UpO1xuXG5cdFx0XHQvLyBTZXQgY2hlY2tib3hcblx0XHRcdCQoJyNkc2gtdXNlSHR0cHNDaGVjaycpLnByb3AoJ2NoZWNrZWQnLCB3c01hbi5odHRwc0VuYWJsZWQpO1xuXHRcdFx0JCgnI2RzaC11c2VIdHRwc0NoZWNrJykuYXR0cignZGlzYWJsZWQnLCAhd3NNYW4uaHR0cEVuYWJsZWQgfHwgIXdzTWFuLmh0dHBzRW5hYmxlZCk7XG5cblx0XHRcdC8vIEdlbmVyYXRlIGxpbmtcblx0XHRcdHRoaXMuX29uVXNlSHR0cHNGb3JXc01hbmFnZXJDaGFuZ2UoKTtcblx0XHR9XG5cdFx0ZWxzZVxuXHRcdHtcblx0XHRcdC8vIFNob3cgYWxlcnRcblx0XHRcdCQoJyNkc2gtd3NNYW5hZ2VyQWxlcnQnKS5zaG93KCk7XG5cblx0XHRcdGlmICghd3NNYW4uaGFzQWNjZXNzKVxuXHRcdFx0XHQkKCcjZHNoLXdzTWFuYWdlckFsZXJ0JykuaHRtbCgnQWNjZXNzIHRvIFRvbWNhdCBNYW5hZ2VyIGNvbnNvbGUgcmVxdWlyZXMgYXQgbGVhc3Qgb25lIHVzZXIgdG8gYmUgZGVmaW5lZCBpbiA8ZW0+V2ViIFNlcnZlcjwvZW0+IHRhYiBvZiA8c3Ryb25nPlNlcnZlciBDb25maWd1cmF0b3I8L3N0cm9uZz4gbW9kdWxlLicpO1xuXHRcdFx0ZWxzZVxuXHRcdFx0XHQkKCcjZHNoLXdzTWFuYWdlckFsZXJ0JykuaHRtbCgnQWNjZXNzIHRvIFRvbWNhdCBNYW5hZ2VyIGNvbnNvbGUgcmVxdWlyZXMgZWl0aGVyIEhUVFAgb3IgSFRUUFMgdG8gYmUgZW5hYmxlZCBpbiA8ZW0+V2ViIFNlcnZlcjwvZW0+IHRhYiBvZiA8c3Ryb25nPlNlcnZlciBDb25maWd1cmF0b3I8L3N0cm9uZz4gbW9kdWxlLicpO1xuXG5cdFx0XHQvLyBEaXNhYmxlIGJ1dHRvblxuXHRcdFx0JCgnI2RzaC10b1dzTWFuYWdlckJ0JykuYXR0cignZGlzYWJsZWQnLCB0cnVlKTtcblxuXHRcdFx0Ly8gRGlzYWJsZSBjaGVja2JveFxuXHRcdFx0JCgnI2RzaC11c2VIdHRwc0NoZWNrJykuYXR0cignY2hlY2tlZCcsIHdzTWFuLmh0dHBzRW5hYmxlZCk7XG5cdFx0XHQkKCcjZHNoLXVzZUh0dHBzQ2hlY2snKS5hdHRyKCdkaXNhYmxlZCcsIHRydWUpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBCdWlsZCB0aGUgcG9sbGluZyByZXF1ZXN0IHRvIGJlIHNlbnQgdG8gdGhlIHNlcnZlci5cblx0ICovXG5cdF9yZXF1ZXN0RGF0YShnZXRIaXN0b3J5ID0gZmFsc2UpXG5cdHtcblx0XHQvLyBDbGVhciBwcmV2aW91cyByZXF1ZXN0IHNjaGVkdWxpbmdcblx0XHRjbGVhclRpbWVvdXQodGhpcy5fcmVxdWVzdFRpbWVyKTtcblxuXHRcdC8vIENoZWNrIGlmIGNvbm5lY3Rpb24gaXMgc3RpbGwgYXZhaWxhYmxlXG5cdFx0aWYgKHRoaXMuc21hcnRGb3guaXNDb25uZWN0ZWQpXG5cdFx0e1xuXHRcdFx0Ly8gQnVpbGQgcmVxdWVzdCBwYXJhbWV0ZXJzXG5cdFx0XHRsZXQgcGFyYW1zID0gbmV3IFNGUzJYLlNGU09iamVjdCgpO1xuXG5cdFx0XHRpZiAoZ2V0SGlzdG9yeSlcblx0XHRcdFx0cGFyYW1zLnB1dEJvb2woJ2hpc3RvcnknLCB0cnVlKTtcblxuXHRcdFx0Ly8gU2VuZCByZXF1ZXN0IHRvIGV4dGVuc2lvblxuXHRcdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9HRVRfREFUQSwgcGFyYW1zKTtcblxuXHRcdFx0Ly8gU2NoZWR1bGUgbmV4dCByZXF1ZXN0XG5cdFx0XHR0aGlzLl9yZXF1ZXN0VGltZXIgPSBzZXRUaW1lb3V0KCQucHJveHkodGhpcy5fcmVxdWVzdERhdGEsIHRoaXMpLCBOdW1iZXIodGhpcy5faW50ZXJ2YWxEcm9wRG93bi52YWx1ZSgpKSAqIDEwMDApO1xuXHRcdH1cblx0fVxuXG5cdF9nZXRNZW1PYmplY3QoYnl0ZXMpXG5cdHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0ZGF0YTogYnl0ZXMsXG5cdFx0XHRsYWJlbDogYnl0ZXNUb1NpemUoYnl0ZXMpXG5cdFx0fTtcblx0fVxuXG5cdF9zZXRDaGFydFVwZGF0ZVBhdXNlZChwYXVzZWQpXG5cdHtcblx0XHQvLyBQYXVzZS9yZWFjdGl2YXRlIHJlYWx0aW1lIGNoYXJ0c1xuXHRcdHRoaXMuX2NwdVVzYWdlQ2hhcnQucGF1c2VkID0gcGF1c2VkO1xuXHRcdHRoaXMuX3RocmVhZENvdW50Q2hhcnQucGF1c2VkID0gcGF1c2VkO1xuXHRcdHRoaXMuX21lbW9yeUNoYXJ0LnBhdXNlZCA9IHBhdXNlZDtcblx0XHR0aGlzLl9uZXR3b3JrUlRDaGFydC5wYXVzZWQgPSBwYXVzZWQ7XG5cdFx0dGhpcy5fc3lzV29ya2xvYWRDaGFydC5wYXVzZWQgPSBwYXVzZWQ7XG5cdFx0dGhpcy5fb3V0VGNwTXNnUXVldWVDaGFydC5wYXVzZWQgPSBwYXVzZWQ7XG5cdFx0dGhpcy5fc3lzUXVldWVDaGFydC5wYXVzZWQgPSBwYXVzZWQ7XG5cdFx0dGhpcy5fZXh0UXVldWVDaGFydC5wYXVzZWQgPSBwYXVzZWQ7XG5cdH1cblxuXHRfZ2V0VGhyZWFkc0dyaWREYXRhU291cmNlKGl0ZW1zLCBzb3J0KVxuXHR7XG5cdFx0aWYgKCFpdGVtcylcblx0XHRcdGl0ZW1zID0gJyc7XG5cblx0XHRpZiAoIXNvcnQpXG5cdFx0e1xuXHRcdFx0c29ydCA9IHtcblx0XHRcdFx0ZmllbGQ6ICdjcHVUaW1lJyxcblx0XHRcdFx0ZGlyOiAnZGVzYydcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG5ldyBrZW5kby5kYXRhLkRhdGFTb3VyY2Uoe1xuXHRcdFx0c2NoZW1hOiB7XG5cdFx0XHRcdG1vZGVsOiB7XG5cdFx0XHRcdFx0aWQ6ICdpZCdcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHNvcnQ6IHNvcnQsXG5cdFx0XHRkYXRhOiBpdGVtc1xuXHRcdH0pO1xuXHR9XG5cblx0X2dldFF1ZXVlVGhyZWFkc0xhYmVsKHRocmVhZHNOdW0pXG5cdHtcblx0XHRyZXR1cm4gYFRocmVhZHM6ICR7dGhyZWFkc051bX1gO1xuXHR9XG5cblx0X2dldFF1ZXVlTG9hZExhYmVsKGxvYWQpXG5cdHtcblx0XHRyZXR1cm4gYEF2Zy4gbWVzc2FnZXM6ICR7bG9hZH1gO1xuXHR9XG5cblx0X3VwZGF0ZU91dE1lc3NhZ2VzUXVldWVTdGF0dXMoKVxuXHR7XG5cdFx0bGV0IHRocmVhZHNTdHIgPSB0aGlzLl9nZXRRdWV1ZVRocmVhZHNMYWJlbCgnLS0nKTtcblx0XHRsZXQgbG9hZFN0ciA9IHRoaXMuX2dldFF1ZXVlTG9hZExhYmVsKCctLScpO1xuXG5cdFx0aWYgKCQoJyNkc2gtdGNwUGlsbCcpLmhhc0NsYXNzKCdhY3RpdmUnKSlcblx0XHR7XG5cdFx0XHR0aHJlYWRzU3RyID0gdGhpcy5fZ2V0UXVldWVUaHJlYWRzTGFiZWwodGhpcy5fdGNwT3V0VGhyZWFkcyk7XG5cdFx0XHRsb2FkU3RyID0gdGhpcy5fZ2V0UXVldWVMb2FkTGFiZWwodGhpcy5fdGNwT3V0TG9hZCk7XG5cdFx0fVxuXG5cdFx0aWYgKCQoJyNkc2gtdWRwUGlsbCcpLmhhc0NsYXNzKCdhY3RpdmUnKSlcblx0XHR7XG5cdFx0XHR0aHJlYWRzU3RyID0gdGhpcy5fZ2V0UXVldWVUaHJlYWRzTGFiZWwodGhpcy5fdWRwT3V0VGhyZWFkcyk7XG5cdFx0XHRsb2FkU3RyID0gdGhpcy5fZ2V0UXVldWVMb2FkTGFiZWwodGhpcy5fdWRwT3V0TG9hZCk7XG5cdFx0fVxuXG5cdFx0JCgnI2RzaC1vdXRnb2luZ01lc3NhZ2VzUXVldWVUaHJlYWRzJykudGV4dCh0aHJlYWRzU3RyKTtcblx0XHQkKCcjZHNoLW91dGdvaW5nTWVzc2FnZXNRdWV1ZUxvYWQnKS50ZXh0KGxvYWRTdHIpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8gUFJJVkFURSBHRVRURVJTXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7OztBQzFIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQzdHQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ3hHQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FDM0lBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7QUNyTkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7QUMvSkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7QUM1UEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FDclBBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDekZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0EiLCJzb3VyY2VSb290IjoiIn0=
|
2094
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzL2pzL2NvcmUvbW9kdWxlcy9tb2R1bGUtNS5idW5kbGUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9hcHBsaWNhdGlvbi8uL3NyYy9jb21wb25lbnRzL2NoYXJ0cy9jaGFydC11dGlscy5qcyIsIndlYnBhY2s6Ly9hcHBsaWNhdGlvbi8uL3NyYy9jb21wb25lbnRzL21vZHVsZS1zcGVjaWZpYy9jbHVzdGVyLW1vbml0b3Ivbm9kZS1taW5pLWNoYXJ0cy5qcyIsIndlYnBhY2s6Ly9hcHBsaWNhdGlvbi8uL3NyYy9tb2R1bGVzL2NsdXN0ZXItbW9uaXRvci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2J5dGVzVG9TaXplLCBrQnl0ZXNUb1NpemV9IGZyb20gJy4uLy4uL3V0aWxzL3V0aWxpdGllcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JtYXR0ZWREYXRlVGltZShkYXRlLCBmb3JtYXQgPSAnZGQgTU1NIEhIOm1tOnNzJylcbntcblx0cmV0dXJuIGtlbmRvLnRvU3RyaW5nKGRhdGUsIGZvcm1hdCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCYXNpY1NoYXJlZFRlbXBsYXRlKHZhbHVlRm9ybWF0ID0gJ3swfScpIHtcblx0cmV0dXJuIGtlbmRvLnRlbXBsYXRlKGBcblx0XHQ8ZGl2IGNsYXNzPVwiY2hhcnQtdG9vbHRpcC1jYXRlZ29yeVwiPjxzdHJvbmc+IzogY2F0ZWdvcnkgIzwvc3Ryb25nPjwvZGl2PlxuXHRcdCMgZm9yICh2YXIgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHsgI1xuXHRcdDxkaXY+XG5cdFx0XHQ8aSBjbGFzcz1cImZhcyBmYS1zcXVhcmVcIiBzdHlsZT1cImNvbG9yOiAjOiBwb2ludHNbaV0uY29sb3IgIyBcIj48L2k+XG5cdFx0XHQjOiBwb2ludHNbaV0uc2VyaWVzLm5hbWUjIDogIzoga2VuZG8uZm9ybWF0KCcke3ZhbHVlRm9ybWF0fScsIHBvaW50c1tpXS52YWx1ZSkgI1xuXHRcdDwvZGl2PlxuXHRcdCMgfSAjXG5cdGApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWVtb3J5U2hhcmVkVGVtcGxhdGUoKSB7XG5cdHJldHVybiBmdW5jdGlvbihkYXRhSXRlbSkge1xuXHRcdGRhdGFJdGVtLmJ5dGVzVG9TaXplID0gYnl0ZXNUb1NpemU7IC8vIFBhc3MgYnl0ZXNUb1NpemUgdXRpbGl0eSBmdW5jdGlvbiB0byB0ZW1wbGF0ZVxuXHRcdHJldHVybiBrZW5kby50ZW1wbGF0ZShgXG5cdFx0XHQ8ZGl2IGNsYXNzPVwiY2hhcnQtdG9vbHRpcC1jYXRlZ29yeVwiPjxzdHJvbmc+IzogY2F0ZWdvcnkgIzwvc3Ryb25nPjwvZGl2PlxuXHRcdFx0IyBmb3IgKHZhciBpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkrKykgeyAjXG5cdFx0XHQ8ZGl2PlxuXHRcdFx0XHQ8aSBjbGFzcz1cImZhcyBmYS1zcXVhcmVcIiBzdHlsZT1cImNvbG9yOiAjOiBwb2ludHNbaV0uY29sb3IgIyBcIj48L2k+XG5cdFx0XHRcdCM6IHBvaW50c1tpXS5zZXJpZXMubmFtZSMgOiAjOiBieXRlc1RvU2l6ZShwb2ludHNbaV0udmFsdWUpICNcblx0XHRcdDwvZGl2PlxuXHRcdFx0IyB9ICNcblx0XHRgKShkYXRhSXRlbSk7XG5cdH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNZW1vcnlWYWx1ZUF4aXNMYWJlbFRlbXBsYXRlKCkge1xuXHRyZXR1cm4gZnVuY3Rpb24oZGF0YUl0ZW0pIHtcblx0XHRkYXRhSXRlbS5ieXRlc1RvU2l6ZSA9IGJ5dGVzVG9TaXplOyAvLyBQYXNzIGJ5dGVzVG9TaXplIHV0aWxpdHkgZnVuY3Rpb24gdG8gdGVtcGxhdGVcblx0XHRyZXR1cm4ga2VuZG8udGVtcGxhdGUoYFxuXHRcdFx0IzogYnl0ZXNUb1NpemUodmFsdWUpICNcblx0XHRgKShkYXRhSXRlbSk7XG5cdH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXROZXR3b3JrU2hhcmVkVGVtcGxhdGUoY2F0ZWdvcnlGb3JtYXQgPSAnZGQgTU1NIEhIOm1tOnNzJykge1xuXHRyZXR1cm4gZnVuY3Rpb24oZGF0YUl0ZW0pIHtcblx0XHRkYXRhSXRlbS5rQnl0ZXNUb1NpemUgPSBrQnl0ZXNUb1NpemU7IC8vIFBhc3Mga0J5dGVzVG9TaXplIHV0aWxpdHkgZnVuY3Rpb24gdG8gdGVtcGxhdGVcblx0XHRyZXR1cm4ga2VuZG8udGVtcGxhdGUoYFxuXHRcdFx0PGRpdiBjbGFzcz1cImNoYXJ0LXRvb2x0aXAtY2F0ZWdvcnlcIj48c3Ryb25nPiM6IGtlbmRvLnRvU3RyaW5nKGNhdGVnb3J5LCAnJHtjYXRlZ29yeUZvcm1hdH0nKSAjPC9zdHJvbmc+PC9kaXY+XG5cdFx0XHQjIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7ICNcblx0XHRcdDxkaXY+XG5cdFx0XHRcdDxpIGNsYXNzPVwiZmFzIGZhLXNxdWFyZVwiIHN0eWxlPVwiY29sb3I6ICM6IHBvaW50c1tpXS5jb2xvciAjIFwiPjwvaT5cblx0XHRcdFx0IzogcG9pbnRzW2ldLnNlcmllcy5uYW1lIyA6ICM6IGtCeXRlc1RvU2l6ZShwb2ludHNbaV0udmFsdWUsIDEsICcnLCAnL3MnKSAjXG5cdFx0XHQ8L2Rpdj5cblx0XHRcdCMgfSAjXG5cdFx0YCkoZGF0YUl0ZW0pO1xuXHR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmV0d29ya1ZhbHVlQXhpc0xhYmVsVGVtcGxhdGUoKSB7XG5cdHJldHVybiBmdW5jdGlvbihkYXRhSXRlbSkge1xuXHRcdGRhdGFJdGVtLmtCeXRlc1RvU2l6ZSA9IGtCeXRlc1RvU2l6ZTsgLy8gUGFzcyBrQnl0ZXNUb1NpemUgdXRpbGl0eSBmdW5jdGlvbiB0byB0ZW1wbGF0ZVxuXHRcdHJldHVybiBrZW5kby50ZW1wbGF0ZShgXG5cdFx0XHQjOiBrQnl0ZXNUb1NpemUodmFsdWUsIDEsICcnLCAnL3MnKSAjXG5cdFx0YCkoZGF0YUl0ZW0pO1xuXHR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmV0d29ya1ZhbHVlQXhpc0xhYmVsVGVtcGxhdGVCKCkge1xuXHRyZXR1cm4gZnVuY3Rpb24oZGF0YUl0ZW0pIHtcblx0XHRkYXRhSXRlbS5ieXRlc1RvU2l6ZSA9IGJ5dGVzVG9TaXplOyAvLyBQYXNzIGJ5dGVzVG9TaXplIHV0aWxpdHkgZnVuY3Rpb24gdG8gdGVtcGxhdGVcblx0XHRyZXR1cm4ga2VuZG8udGVtcGxhdGUoYFxuXHRcdFx0IzogYnl0ZXNUb1NpemUodmFsdWUsIDEsICcnLCAnL3MnKSAjXG5cdFx0YCkoZGF0YUl0ZW0pO1xuXHR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VXNlckNvdW50U2hhcmVkVGVtcGxhdGUoY2F0ZWdvcnlGb3JtYXQgPSAnZGQgTU1NIEhIOm1tOnNzJykge1xuXHRyZXR1cm4gZnVuY3Rpb24oZGF0YUl0ZW0pIHtcblx0XHRyZXR1cm4ga2VuZG8udGVtcGxhdGUoYFxuXHRcdFx0PGRpdiBjbGFzcz1cImNoYXJ0LXRvb2x0aXAtY2F0ZWdvcnlcIj48c3Ryb25nPiM6IGtlbmRvLnRvU3RyaW5nKGNhdGVnb3J5LCAnJHtjYXRlZ29yeUZvcm1hdH0nKSAjPC9zdHJvbmc+PC9kaXY+XG5cdFx0XHQjIGZvciAodmFyIGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7ICNcblx0XHRcdDxkaXY+XG5cdFx0XHRcdDxpIGNsYXNzPVwiZmFzIGZhLXNxdWFyZVwiIHN0eWxlPVwiY29sb3I6ICM6IHBvaW50c1tpXS5jb2xvciAjIFwiPjwvaT5cblx0XHRcdFx0IzogcG9pbnRzW2ldLnNlcmllcy5uYW1lIyA6ICM6IHBvaW50c1tpXS52YWx1ZSAjXG5cdFx0XHQ8L2Rpdj5cblx0XHRcdCMgfSAjXG5cdFx0YCkoZGF0YUl0ZW0pO1xuXHR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGltZVJhbmdlVG9vbHRpcFRlbXBsYXRlKCkge1xuXHRyZXR1cm4gZnVuY3Rpb24oZGF0YUl0ZW0pIHtcblx0XHRkYXRhSXRlbS5nZXRUb29sdGlwU3RyaW5nID0gZnVuY3Rpb24odjEsIHYyKSB7XG5cdFx0XHRpZiAodjEgPT0gdjIpXG5cdFx0XHR7XG5cdFx0XHRcdGlmICh2MiA9PSAtMjQpXG5cdFx0XHRcdFx0djIgPSAtMjM7XG5cblx0XHRcdFx0djEgPSB2MiAtIDE7XG5cdFx0XHR9XG5cblx0XHRcdGxldCBzdGFydCA9IE1hdGguYWJzKHYxKTtcblx0XHRcdGxldCBlbmQgPSBNYXRoLmFicyh2Mik7XG5cblx0XHRcdHJldHVybiBgRnJvbSAke3N0YXJ0fSBob3VyJHtzdGFydCAhPSAxID8gJ3MnIDogJyd9IGFnbyB0byAke2VuZCA+IDAgPyAoJ3RvICcgKyBlbmQgKyAnIGhvdXInICsgKGVuZCAhPSAxID8gJ3MnIDogJycpICsgJyBhZ28nKSA6ICdub3cnfWA7XG5cdFx0fTsgLy8gUGFzcyB1dGlsaXR5IGZ1bmN0aW9uIHRvIHRlbXBsYXRlXG5cdFx0cmV0dXJuIGtlbmRvLnRlbXBsYXRlKGBcblx0XHRcdCM6IGdldFRvb2x0aXBTdHJpbmcoc2VsZWN0aW9uU3RhcnQsIHNlbGVjdGlvbkVuZCkgI1xuXHRcdGApKGRhdGFJdGVtKTtcblx0fTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFdSQnl0ZXNMYWJlbFRlbXBsYXRlKCkge1xuXHRyZXR1cm4gZnVuY3Rpb24oZGF0YUl0ZW0pIHtcblx0XHRyZXR1cm4ga2VuZG8udGVtcGxhdGUoYFxuXHRcdFx0IzogdmFsdWUgIyAjOiBkYXRhSXRlbS51bml0ICNcblx0XHRgKShkYXRhSXRlbSk7XG5cdH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCYXNpY1RlbXBsYXRlKHZhbHVlRm9ybWF0ID0gJ3swfScpIHtcblx0cmV0dXJuIGtlbmRvLnRlbXBsYXRlKGBcblx0XHQ8ZGl2PlxuXHRcdFx0PHNwYW4gY2xhc3M9XCJ0ZXh0LW5vd3JhcFwiPiM6IGtlbmRvLnRvU3RyaW5nKG5ldyBEYXRlKHZhbHVlLngpLCBcImRkL01NL3l5IEhIOm1tXCIpICM8L3NwYW4+XG5cdFx0XHQ8YnI+XG5cdFx0XHQ8c3Ryb25nIGNsYXNzPVwidGV4dC1ub3dyYXBcIj4jOiBzZXJpZXMubmFtZSAjOiAjOiBrZW5kby5mb3JtYXQoJyR7dmFsdWVGb3JtYXR9JywgdmFsdWUueSkgIyA8L3N0cm9uZz5cblx0XHQ8L2Rpdj5cblx0YCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNZW1vcnlUZW1wbGF0ZSgpIHtcblx0cmV0dXJuIGZ1bmN0aW9uKGRhdGFJdGVtKSB7XG5cdFx0ZGF0YUl0ZW0uYnl0ZXNUb1NpemUgPSBieXRlc1RvU2l6ZTsgLy8gUGFzcyBieXRlc1RvU2l6ZSB1dGlsaXR5IGZ1bmN0aW9uIHRvIHRlbXBsYXRlXG5cdFx0cmV0dXJuIGtlbmRvLnRlbXBsYXRlKGBcblx0XHRcdDxkaXY+XG5cdFx0XHRcdDxzcGFuIGNsYXNzPVwidGV4dC1ub3dyYXBcIj4jOiBrZW5kby50b1N0cmluZyhuZXcgRGF0ZSh2YWx1ZS54KSwgXCJkZC9NTS95eSBISDptbVwiKSAjPC9zcGFuPlxuXHRcdFx0XHQ8YnI+XG5cdFx0XHRcdDxzdHJvbmcgY2xhc3M9XCJ0ZXh0LW5vd3JhcFwiPiM6IHNlcmllcy5uYW1lICM6ICM6IGJ5dGVzVG9TaXplKHZhbHVlLnkpICMgPC9zdHJvbmc+XG5cdFx0XHQ8L2Rpdj5cblx0XHRgKShkYXRhSXRlbSk7XG5cdH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXROZXR3b3JrVGVtcGxhdGUoKSB7XG5cdHJldHVybiBmdW5jdGlvbihkYXRhSXRlbSkge1xuXHRcdGRhdGFJdGVtLmJ5dGVzVG9TaXplID0gYnl0ZXNUb1NpemU7IC8vIFBhc3MgYnl0ZXNUb1NpemUgdXRpbGl0eSBmdW5jdGlvbiB0byB0ZW1wbGF0ZVxuXHRcdHJldHVybiBrZW5kby50ZW1wbGF0ZShgXG5cdFx0XHQ8ZGl2PlxuXHRcdFx0XHQ8c3BhbiBjbGFzcz1cInRleHQtbm93cmFwXCI+Izoga2VuZG8udG9TdHJpbmcobmV3IERhdGUodmFsdWUueCksIFwiZGQvTU0veXkgSEg6bW1cIikgIzwvc3Bhbj5cblx0XHRcdFx0PGJyPlxuXHRcdFx0XHQ8c3Ryb25nIGNsYXNzPVwidGV4dC1ub3dyYXBcIj4jOiBzZXJpZXMubmFtZSAjOiAjOiBieXRlc1RvU2l6ZSh2YWx1ZS55LCAxLCAnJywgJy9zJykgIyA8L3N0cm9uZz5cblx0XHRcdDwvZGl2PlxuXHRcdGApKGRhdGFJdGVtKTtcblx0fTtcbn1cbiIsImltcG9ydCAqIGFzIG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHtnZXRCYXNpY1RlbXBsYXRlLCBnZXRNZW1vcnlWYWx1ZUF4aXNMYWJlbFRlbXBsYXRlLCBnZXRNZW1vcnlUZW1wbGF0ZSwgZ2V0TmV0d29ya1RlbXBsYXRlLCBnZXROZXR3b3JrVmFsdWVBeGlzTGFiZWxUZW1wbGF0ZUJ9IGZyb20gJy4uLy4uL2NoYXJ0cy9jaGFydC11dGlscyc7XG5cbmV4cG9ydCBjbGFzcyBOb2RlTWluaUNoYXJ0cyBleHRlbmRzIEhUTUxFbGVtZW50XG57XG5cdGNvbnN0cnVjdG9yKG5vZGVJZCwgbm9kZUFsaWFzLCBub2RlTmFtZSlcblx0e1xuXHQgICAgc3VwZXIoKTtcblxuXHRcdGNvbnN0IHNoYWRvd1Jvb3QgPSB0aGlzLmF0dGFjaFNoYWRvdyh7bW9kZTogJ29wZW4nfSk7XG5cdFx0c2hhZG93Um9vdC5pbm5lckhUTUwgPSBgXG5cdFx0XHQ8bGluayByZWw9XCJzdHlsZXNoZWV0XCIgdHlwZT1cInRleHQvY3NzXCIgaHJlZj1cImFzc2V0cy9jc3MvY3VzdG9tLWJvb3RzdHJhcC5taW4uY3NzXCIgLz5cblx0XHRcdDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiB0eXBlPVwidGV4dC9jc3NcIiBocmVmPVwiYXNzZXRzL2Nzcy9rZW5kby5jdXN0b20tYm9vdHN0cmFwLXY0LmNzc1wiIC8+XG5cblx0XHRcdDxzdHlsZT5cblx0XHRcdFx0LmJveCB7XG5cdFx0XHRcdFx0YmFja2dyb3VuZC1jb2xvcjogI0ZGRjtcblx0XHRcdFx0XHRib3JkZXItcmFkaXVzOiAuNXJlbTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC5jaGFydC1jb250YWluZXIge1xuXHRcdFx0XHRcdGN1cnNvcjogcG9pbnRlcjtcblx0XHRcdFx0fVxuXHRcdFx0PC9zdHlsZT5cblxuXHRcdFx0PGRpdiBjbGFzcz1cImNvbnRhaW5lci1mbHVpZFwiPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwicm93IHB5LTMgYm94XCI+XG5cdFx0XHRcdFx0PGRpdiBjbGFzcz1cImNvbC1zbS02IGNvbC1tZC00IGNvbC1sZy0yIGQtZmxleCBmbGV4LWNvbHVtbiBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+XG5cdFx0XHRcdFx0XHQ8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+Tm9kZTwvc21hbGw+XG5cdFx0XHRcdFx0XHQ8c3Ryb25nIGlkPVwiYWxpYXNcIj48L3N0cm9uZz5cblx0XHRcdFx0XHRcdDxzbWFsbCBpZD1cIm5hbWVcIj48L3NtYWxsPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjb2wtc20tNiBjb2wtbWQtNCBjb2wtbGctMiB0ZXh0LWNlbnRlciBjaGFydC1jb250YWluZXJcIiBkYXRhLXR5cGU9XCJjY3VcIj5cblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjaGFydFwiPjwvZGl2PlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjb2wtc20tNiBjb2wtbWQtNCBjb2wtbGctMiB0ZXh0LWNlbnRlciBjaGFydC1jb250YWluZXJcIiBkYXRhLXR5cGU9XCJjcHVcIj5cblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjaGFydFwiPjwvZGl2PlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjb2wtc20tNiBjb2wtbWQtNCBjb2wtbGctMiB0ZXh0LWNlbnRlciBjaGFydC1jb250YWluZXJcIiBkYXRhLXR5cGU9XCJtZW1cIj5cblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjaGFydFwiPjwvZGl2PlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjb2wtc20tNiBjb2wtbWQtNCBjb2wtbGctMiB0ZXh0LWNlbnRlciBjaGFydC1jb250YWluZXJcIiBkYXRhLXR5cGU9XCJuZXRcIj5cblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjaGFydFwiPjwvZGl2PlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjb2wtc20tNiBjb2wtbWQtNCBjb2wtbGctMiB0ZXh0LWNlbnRlciBjaGFydC1jb250YWluZXJcIiBkYXRhLXR5cGU9XCJ0aGRcIj5cblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjaGFydFwiPjwvZGl2PlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdGA7XG5cblx0XHR0aGlzLm5JZCA9IG5vZGVJZDtcblx0XHR0aGlzLm5BbGlhcyA9IG5vZGVBbGlhcztcblx0XHR0aGlzLm5OYW1lID0gbm9kZU5hbWU7XG5cblx0XHQvLyBTZXQgdGFnJ3MgaWQgYXR0cmlidXRlXG5cdFx0dGhpcy5pZCA9ICdub2RlXycgKyBub2RlSWQ7XG5cblx0XHRpZiAobm9kZUFsaWFzKVxuXHRcdHtcblx0XHRcdCQoJyNhbGlhcycsIHNoYWRvd1Jvb3QpLnRleHQobm9kZUFsaWFzKTtcblx0XHRcdCQoJyNuYW1lJywgc2hhZG93Um9vdCkudGV4dChub2RlTmFtZSk7XG5cdFx0fVxuXHRcdGVsc2Vcblx0XHR7XG5cdFx0XHQkKCcjYWxpYXMnLCBzaGFkb3dSb290KS50ZXh0KG5vZGVOYW1lKTtcblx0XHRcdCQoJyNuYW1lJywgc2hhZG93Um9vdCkuaGlkZSgpO1xuXHRcdH1cblxuXHRcdHRoaXMuX2dldENoYXJ0RGl2KCdjY3UnKS5rZW5kb0NoYXJ0KHtcblx0XHRcdHRyYW5zaXRpb25zOiBmYWxzZSxcblx0XHRcdGNoYXJ0QXJlYToge1xuXHRcdFx0XHRoZWlnaHQ6IDEyMCxcblx0XHRcdFx0YmFja2dyb3VuZDogJ3RyYW5zcGFyZW50Jyxcblx0XHRcdFx0bWFyZ2luOiAwLFxuXHRcdFx0ICAgIHBhZGRpbmc6MFxuXHRcdFx0fSxcblx0ICAgICAgICBsZWdlbmQ6IHtcblx0ICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICB9LFxuXHRcdFx0dGl0bGU6IHtcblx0XHRcdFx0dGV4dDogJ0NvbmN1cnJlbnQgVXNlcnMnLFxuXHRcdFx0XHRmb250OiAnMTJweCBzYW5zLXNlcmlmJyxcblx0XHRcdFx0Y29sb3I6ICcjMjEyNTI5J1xuXHRcdFx0fSxcblx0ICAgICAgICBzZXJpZXNEZWZhdWx0czoge1xuXHQgICAgICAgICAgICB0eXBlOiAnc2NhdHRlckxpbmUnLFxuXHQgICAgICAgICAgICBsYWJlbHM6IHtcblx0ICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlLFxuXHQgICAgICAgICAgICAgICAgZm9ybWF0OiAnezB9Jyxcblx0ICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6ICd0cmFuc3BhcmVudCdcblx0ICAgICAgICAgICAgfSxcblx0XHRcdFx0bWlzc2luZ1ZhbHVlczogJ2dhcCcsXG5cdFx0XHRcdG1hcmtlcnM6IHtcblx0XHRcdCAgICAgIHZpc2libGU6IGZhbHNlLFxuXHRcdFx0XHQgIHR5cGU6ICdjaXJjbGUnLFxuXHRcdFx0XHQgIHNpemU6IDIsXG5cdFx0XHQgICAgfSxcblx0XHRcdFx0d2lkdGg6IDJcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNlcmllczogW1xuXHRcdFx0XHR7XG5cdCAgICAgICAgICAgICAgICB4RmllbGQ6ICd0cycsXG5cdCAgICAgICAgICAgICAgICB5RmllbGQ6ICd2YWwnLFxuXHRcdFx0XHRcdG5hbWU6ICdDQ1UnLFxuXHRcdFx0XHRcdGNvbG9yOiAnIzMzOTlGRidcblx0ICAgICAgICAgICAgfVxuXHRcdFx0XSxcblx0ICAgICAgICB5QXhpczoge1xuXHQgICAgICAgICAgICBsYWJlbHM6IHtcblx0ICAgICAgICAgICAgICAgIGZvcm1hdDogJ3swfScsXG5cdFx0XHRcdFx0c3RlcDogMlxuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICBsaW5lOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtaW46IDBcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHhBeGlzOiB7XG5cdFx0XHRcdG1ham9yR3JpZExpbmVzOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtYWpvclRpY2tzOiB7XG5cdFx0XHRcdFx0dmlzaWJsZTogZmFsc2Vcblx0XHRcdFx0fSxcblx0XHRcdFx0bGFiZWxzOiB7XG5cdFx0XHRcdFx0dmlzaWJsZTogZmFsc2Vcblx0XHRcdFx0fVxuXHQgICAgICAgIH0sXG5cdFx0XHR0b29sdGlwOiB7XG5cdFx0XHRcdHZpc2libGU6IHRydWUsXG5cdFx0XHRcdHRlbXBsYXRlOiBnZXRCYXNpY1RlbXBsYXRlKCd7MH0nKSxcblx0XHRcdFx0YmFja2dyb3VuZDogJyNlNGU0ZTQnXG5cdCAgICAgICAgfVxuXHQgICAgfSkuZGF0YSgna2VuZG9DaGFydCcpO1xuXG5cdFx0dGhpcy5fZ2V0Q2hhcnREaXYoJ2NwdScpLmtlbmRvQ2hhcnQoe1xuXHRcdFx0dHJhbnNpdGlvbnM6IGZhbHNlLFxuXHRcdFx0Y2hhcnRBcmVhOiB7XG5cdFx0XHRcdGhlaWdodDogMTIwLFxuXHRcdFx0XHRiYWNrZ3JvdW5kOiAndHJhbnNwYXJlbnQnLFxuXHRcdFx0XHRtYXJnaW46IDAsXG5cdFx0XHQgICAgcGFkZGluZzowXG5cdFx0XHR9LFxuXHQgICAgICAgIGxlZ2VuZDoge1xuXHQgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgIH0sXG5cdFx0XHR0aXRsZToge1xuXHRcdFx0XHR0ZXh0OiAnQ1BVJyxcblx0XHRcdFx0Zm9udDogJzEycHggc2Fucy1zZXJpZicsXG5cdFx0XHRcdGNvbG9yOiAnIzIxMjUyOSdcblx0XHRcdH0sXG5cdCAgICAgICAgc2VyaWVzRGVmYXVsdHM6IHtcblx0ICAgICAgICAgICAgdHlwZTogJ3NjYXR0ZXJMaW5lJyxcblx0ICAgICAgICAgICAgbGFiZWxzOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcblx0ICAgICAgICAgICAgICAgIGZvcm1hdDogJ3swfSUnLFxuXHQgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJ3RyYW5zcGFyZW50J1xuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtaXNzaW5nVmFsdWVzOiAnZ2FwJyxcblx0XHRcdFx0bWFya2Vyczoge1xuXHRcdFx0ICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdFx0XHRcdCAgdHlwZTogJ2NpcmNsZScsXG5cdFx0XHRcdCAgc2l6ZTogMyxcblx0XHRcdCAgICB9LFxuXHRcdFx0XHR3aWR0aDogMlxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2VyaWVzOiBbXG5cdFx0XHRcdHtcblx0ICAgICAgICAgICAgICAgIHhGaWVsZDogJ3RzJyxcblx0ICAgICAgICAgICAgICAgIHlGaWVsZDogJ3ZhbCcsXG5cdFx0XHRcdFx0bmFtZTogJ0NQVScsXG5cdFx0XHRcdFx0Y29sb3I6ICcjMzM5OUZGJ1xuXHQgICAgICAgICAgICB9XG5cdFx0XHRdLFxuXHQgICAgICAgIHlBeGlzOiB7XG5cdCAgICAgICAgICAgIGxhYmVsczoge1xuXHQgICAgICAgICAgICAgICAgZm9ybWF0OiAnezB9JSdcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgbGluZToge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICAgICAgfSxcblx0XHRcdFx0bWluOiAwLFxuXHQgICAgXHRcdG1heDogMTAwLFxuICAgICAgXHRcdFx0bWFqb3JVbml0OiAyNVxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgeEF4aXM6IHtcblx0XHRcdFx0bWFqb3JHcmlkTGluZXM6IHtcblx0ICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgICAgIH0sXG5cdFx0XHRcdG1ham9yVGlja3M6IHtcblx0XHRcdFx0XHR2aXNpYmxlOiBmYWxzZVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRsYWJlbHM6IHtcblx0XHRcdFx0XHR2aXNpYmxlOiBmYWxzZVxuXHRcdFx0XHR9XG5cdCAgICAgICAgfSxcblx0XHRcdHRvb2x0aXA6IHtcblx0XHRcdFx0dmlzaWJsZTogdHJ1ZSxcblx0XHRcdFx0dGVtcGxhdGU6IGdldEJhc2ljVGVtcGxhdGUoJ3swfSUnKSxcblx0XHRcdFx0YmFja2dyb3VuZDogJyNlNGU0ZTQnLFxuXHQgICAgICAgIH1cblx0ICAgIH0pLmRhdGEoJ2tlbmRvQ2hhcnQnKTtcblxuXHRcdHRoaXMuX2dldENoYXJ0RGl2KCdtZW0nKS5rZW5kb0NoYXJ0KHtcblx0XHRcdHRyYW5zaXRpb25zOiBmYWxzZSxcblx0XHRcdGNoYXJ0QXJlYToge1xuXHRcdFx0XHRoZWlnaHQ6IDEyMCxcblx0XHRcdFx0YmFja2dyb3VuZDogJ3RyYW5zcGFyZW50Jyxcblx0XHRcdFx0bWFyZ2luOiAwLFxuXHRcdFx0ICAgIHBhZGRpbmc6MFxuXHRcdFx0fSxcblx0ICAgICAgICBsZWdlbmQ6IHtcblx0ICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICB9LFxuXHRcdFx0dGl0bGU6IHtcblx0XHRcdFx0dGV4dDogJ01lbW9yeScsXG5cdFx0XHRcdGZvbnQ6ICcxMnB4IHNhbnMtc2VyaWYnLFxuXHRcdFx0XHRjb2xvcjogJyMyMTI1MjknXG5cdFx0XHR9LFxuXHQgICAgICAgIHNlcmllc0RlZmF1bHRzOiB7XG5cdCAgICAgICAgICAgIHR5cGU6ICdzY2F0dGVyTGluZScsXG5cdCAgICAgICAgICAgIGxhYmVsczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXQ6ICd7MH0nLFxuXHQgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJ3RyYW5zcGFyZW50J1xuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtaXNzaW5nVmFsdWVzOiAnZ2FwJyxcblx0XHRcdFx0bWFya2Vyczoge1xuXHRcdFx0ICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdFx0XHRcdCAgdHlwZTogJ2NpcmNsZScsXG5cdFx0XHRcdCAgc2l6ZTogMyxcblx0XHRcdCAgICB9LFxuXHRcdFx0XHR3aWR0aDogMlxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2VyaWVzOiBbXG5cdFx0XHRcdHtcblx0ICAgICAgICAgICAgICAgIHhGaWVsZDogJ3RzJyxcblx0ICAgICAgICAgICAgICAgIHlGaWVsZDogJ3ZhbCcsXG5cdFx0XHRcdFx0bmFtZTogJ01lbW9yeScsXG5cdFx0XHRcdFx0Y29sb3I6ICcjMzM5OUZGJ1xuXHQgICAgICAgICAgICB9XG5cdFx0XHRdLFxuXHQgICAgICAgIHlBeGlzOiB7XG5cdCAgICAgICAgICAgIGxhYmVsczoge1xuXHQgICAgICAgICAgICAgICAgZm9ybWF0OiAnezB9JyxcbiAgICAgIFx0XHRcdFx0dGVtcGxhdGU6IGdldE1lbW9yeVZhbHVlQXhpc0xhYmVsVGVtcGxhdGUoKSxcblx0XHRcdFx0XHRzdGVwOiAyXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgIGxpbmU6IHtcblx0ICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgICAgIH0sXG5cdFx0XHRcdG1pbjogMCxcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHhBeGlzOiB7XG5cdFx0XHRcdG1ham9yR3JpZExpbmVzOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtYWpvclRpY2tzOiB7XG5cdFx0XHRcdFx0dmlzaWJsZTogZmFsc2Vcblx0XHRcdFx0fSxcblx0XHRcdFx0bGFiZWxzOiB7XG5cdFx0XHRcdFx0dmlzaWJsZTogZmFsc2Vcblx0XHRcdFx0fVxuXHQgICAgICAgIH0sXG5cdFx0XHR0b29sdGlwOiB7XG5cdFx0XHRcdHZpc2libGU6IHRydWUsXG5cdFx0XHRcdHRlbXBsYXRlOiBnZXRNZW1vcnlUZW1wbGF0ZSgpLFxuXHRcdFx0XHRiYWNrZ3JvdW5kOiAnI2U0ZTRlNCcsXG5cdCAgICAgICAgfVxuXHQgICAgfSkuZGF0YSgna2VuZG9DaGFydCcpO1xuXG5cdFx0dGhpcy5fZ2V0Q2hhcnREaXYoJ3RoZCcpLmtlbmRvQ2hhcnQoe1xuXHRcdFx0dHJhbnNpdGlvbnM6IGZhbHNlLFxuXHRcdFx0Y2hhcnRBcmVhOiB7XG5cdFx0XHRcdGhlaWdodDogMTIwLFxuXHRcdFx0XHRiYWNrZ3JvdW5kOiAndHJhbnNwYXJlbnQnLFxuXHRcdFx0XHRtYXJnaW46IDAsXG5cdFx0XHQgICAgcGFkZGluZzowXG5cdFx0XHR9LFxuXHQgICAgICAgIGxlZ2VuZDoge1xuXHQgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgIH0sXG5cdFx0XHR0aXRsZToge1xuXHRcdFx0XHR0ZXh0OiAnVGhyZWFkcycsXG5cdFx0XHRcdGZvbnQ6ICcxMnB4IHNhbnMtc2VyaWYnLFxuXHRcdFx0XHRjb2xvcjogJyMyMTI1MjknXG5cdFx0XHR9LFxuXHQgICAgICAgIHNlcmllc0RlZmF1bHRzOiB7XG5cdCAgICAgICAgICAgIHR5cGU6ICdzY2F0dGVyTGluZScsXG5cdCAgICAgICAgICAgIGxhYmVsczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXQ6ICd7MH0nLFxuXHQgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJ3RyYW5zcGFyZW50J1xuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtaXNzaW5nVmFsdWVzOiAnZ2FwJyxcblx0XHRcdFx0bWFya2Vyczoge1xuXHRcdFx0ICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdFx0XHRcdCAgdHlwZTogJ2NpcmNsZScsXG5cdFx0XHRcdCAgc2l6ZTogMyxcblx0XHRcdCAgICB9LFxuXHRcdFx0XHR3aWR0aDogMlxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2VyaWVzOiBbXG5cdFx0XHRcdHtcblx0ICAgICAgICAgICAgICAgIHhGaWVsZDogJ3RzJyxcblx0ICAgICAgICAgICAgICAgIHlGaWVsZDogJ3ZhbCcsXG5cdFx0XHRcdFx0bmFtZTogJ1RocmVhZHMnLFxuXHRcdFx0XHRcdGNvbG9yOiAnIzMzOTlGRidcblx0ICAgICAgICAgICAgfVxuXHRcdFx0XSxcblx0ICAgICAgICB5QXhpczoge1xuXHQgICAgICAgICAgICBsYWJlbHM6IHtcblx0ICAgICAgICAgICAgICAgIGZvcm1hdDogJ3swfScsXG5cdFx0XHRcdFx0c3RlcDogMlxuXHQgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICBsaW5lOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtaW46IDBcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHhBeGlzOiB7XG5cdFx0XHRcdG1ham9yR3JpZExpbmVzOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtYWpvclRpY2tzOiB7XG5cdFx0XHRcdFx0dmlzaWJsZTogZmFsc2Vcblx0XHRcdFx0fSxcblx0XHRcdFx0bGFiZWxzOiB7XG5cdFx0XHRcdFx0dmlzaWJsZTogZmFsc2Vcblx0XHRcdFx0fVxuXHQgICAgICAgIH0sXG5cdFx0XHR0b29sdGlwOiB7XG5cdFx0XHRcdHZpc2libGU6IHRydWUsXG5cdFx0XHRcdHRlbXBsYXRlOiBnZXRCYXNpY1RlbXBsYXRlKCd7MH0nKSxcblx0XHRcdFx0YmFja2dyb3VuZDogJyNlNGU0ZTQnXG5cdCAgICAgICAgfVxuXHQgICAgfSkuZGF0YSgna2VuZG9DaGFydCcpO1xuXG5cdFx0dGhpcy5fZ2V0Q2hhcnREaXYoJ25ldCcpLmtlbmRvQ2hhcnQoe1xuXHRcdFx0dHJhbnNpdGlvbnM6IGZhbHNlLFxuXHRcdFx0Y2hhcnRBcmVhOiB7XG5cdFx0XHRcdGhlaWdodDogMTIwLFxuXHRcdFx0XHRiYWNrZ3JvdW5kOiAndHJhbnNwYXJlbnQnLFxuXHRcdFx0XHRtYXJnaW46IDAsXG5cdFx0XHQgICAgcGFkZGluZzowXG5cdFx0XHR9LFxuXHQgICAgICAgIGxlZ2VuZDoge1xuXHQgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgIH0sXG5cdFx0XHR0aXRsZToge1xuXHRcdFx0XHR0ZXh0OiAnTmV0d29yaycsXG5cdFx0XHRcdGZvbnQ6ICcxMnB4IHNhbnMtc2VyaWYnLFxuXHRcdFx0XHRjb2xvcjogJyMyMTI1MjknXG5cdFx0XHR9LFxuXHQgICAgICAgIHNlcmllc0RlZmF1bHRzOiB7XG5cdCAgICAgICAgICAgIHR5cGU6ICdzY2F0dGVyTGluZScsXG5cdCAgICAgICAgICAgIGxhYmVsczoge1xuXHQgICAgICAgICAgICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdCAgICAgICAgICAgICAgICBmb3JtYXQ6ICd7MH0nLFxuXHQgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogJ3RyYW5zcGFyZW50J1xuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtaXNzaW5nVmFsdWVzOiAnZ2FwJyxcblx0XHRcdFx0bWFya2Vyczoge1xuXHRcdFx0ICAgICAgdmlzaWJsZTogZmFsc2UsXG5cdFx0XHRcdCAgdHlwZTogJ2NpcmNsZScsXG5cdFx0XHRcdCAgc2l6ZTogMyxcblx0XHRcdCAgICB9LFxuXHRcdFx0XHR3aWR0aDogMlxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgc2VyaWVzOiBbXG5cdFx0XHRcdHtcblx0ICAgICAgICAgICAgICAgIHhGaWVsZDogJ3RzJyxcblx0ICAgICAgICAgICAgICAgIHlGaWVsZDogJ3ZhbCcsXG5cdFx0XHRcdFx0bmFtZTogJ05ldHdvcmsgT3V0Jyxcblx0XHRcdFx0XHRjb2xvcjogJyNDQzAwMDAnLFxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHR7XG5cdCAgICAgICAgICAgICAgICB4RmllbGQ6ICd0cycsXG5cdCAgICAgICAgICAgICAgICB5RmllbGQ6ICd2YWwxJyxcblx0XHRcdFx0XHRuYW1lOiAnTmV0d29yayBJbicsXG5cdFx0XHRcdFx0Y29sb3I6ICcjMDA5OTAwJyxcblx0ICAgICAgICAgICAgfVxuXHRcdFx0XSxcblx0ICAgICAgICB5QXhpczoge1xuXHQgICAgICAgICAgICBsYWJlbHM6IHtcblx0ICAgICAgICAgICAgICAgIGZvcm1hdDogJ3swfScsXG4gICAgICBcdFx0XHRcdHRlbXBsYXRlOiBnZXROZXR3b3JrVmFsdWVBeGlzTGFiZWxUZW1wbGF0ZUIoKSxcblx0XHRcdFx0XHRzdGVwOiAyXG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgIGxpbmU6IHtcblx0ICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgICAgIH0sXG5cdFx0XHRcdG1pbjogMFxuXHQgICAgICAgIH0sXG5cdCAgICAgICAgeEF4aXM6IHtcblx0XHRcdFx0bWFqb3JHcmlkTGluZXM6IHtcblx0ICAgICAgICAgICAgICAgIHZpc2libGU6IGZhbHNlXG5cdCAgICAgICAgICAgIH0sXG5cdFx0XHRcdG1ham9yVGlja3M6IHtcblx0XHRcdFx0XHR2aXNpYmxlOiBmYWxzZVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRsYWJlbHM6IHtcblx0XHRcdFx0XHR2aXNpYmxlOiBmYWxzZVxuXHRcdFx0XHR9XG5cdCAgICAgICAgfSxcblx0XHRcdHRvb2x0aXA6IHtcblx0XHRcdFx0dmlzaWJsZTogdHJ1ZSxcblx0XHRcdFx0dGVtcGxhdGU6IGdldE5ldHdvcmtUZW1wbGF0ZSgpLFxuXHRcdFx0XHRiYWNrZ3JvdW5kOiAnI2U0ZTRlNCdcblx0ICAgICAgICB9XG5cdCAgICB9KS5kYXRhKCdrZW5kb0NoYXJ0Jyk7XG5cblx0XHQvLyBBZGQgY2hhcnQgY29udGFpbmVyIGNsaWNrIGxpc3RlbmVyc1xuXHRcdCQoJy5jaGFydC1jb250YWluZXInLCB0aGlzLnNoYWRvd1Jvb3QpLm9uKCdjbGljaycsICQucHJveHkodGhpcy5fb25DaGFydENvbnRhaW5lckNsaWNrLCB0aGlzKSk7XG5cblx0XHQkKHdpbmRvdykub24oJ3Jlc2l6ZScsICQucHJveHkodGhpcy5fb25XaW5kb3dSZXNpemUsIHRoaXMpKTtcblx0XHR0aGlzLl9vbldpbmRvd1Jlc2l6ZSgpO1xuXHR9XG5cblx0X29uV2luZG93UmVzaXplKClcblx0e1xuXHRcdHRoaXMuX2dldENoYXJ0V2lkZ2V0KCdjY3UnKS5yZWRyYXcoKTtcblx0XHR0aGlzLl9nZXRDaGFydFdpZGdldCgnY3B1JykucmVkcmF3KCk7XG5cdFx0dGhpcy5fZ2V0Q2hhcnRXaWRnZXQoJ21lbScpLnJlZHJhdygpO1xuXHRcdHRoaXMuX2dldENoYXJ0V2lkZ2V0KCd0aGQnKS5yZWRyYXcoKTtcblx0XHR0aGlzLl9nZXRDaGFydFdpZGdldCgnbmV0JykucmVkcmF3KCk7XG5cdH1cblxuXHRkZXN0cm95KClcblx0e1xuXHRcdCQod2luZG93KS5vZmYoJ3Jlc2l6ZScpO1xuXHR9XG5cblx0YWRkQ2hhcnRFbnRyaWVzKHR5cGUsIGRhdGEsIGRhdGExLCBpbnRlcnZhbE1pbGxpcylcblx0e1xuXHRcdGxldCBsYXN0VGltZXN0YW1wID0gZGF0YS5nZXRMb25nKCdsYXN0Jyk7XG5cdFx0bGV0IHZhbHVlcyA9IGRhdGEuZ2V0TG9uZ0FycmF5KCdkYXRhJyk7XG5cdFx0bGV0IHZhbHVlczEgPSAoZGF0YTEgIT0gbnVsbCA/IGRhdGExLmdldExvbmdBcnJheSgnZGF0YScpIDogbnVsbCk7XG5cdFx0bGV0IGNoYXJ0V2lkZ2V0ID0gdGhpcy5fZ2V0Q2hhcnRXaWRnZXQodHlwZSk7XG5cblx0XHR0aGlzLl9hZGRDaGFydEVudHJpZXMoY2hhcnRXaWRnZXQsIHZhbHVlcywgdmFsdWVzMSwgaW50ZXJ2YWxNaWxsaXMsIGxhc3RUaW1lc3RhbXApO1xuXHR9XG5cblx0X2FkZENoYXJ0RW50cmllcyhjaGFydFdpZGdldCwgdmFsdWVzLCB2YWx1ZXMxLCBpbnRlcnZhbE1pbGxpcywgbGFzdFRpbWVzdGFtcClcblx0e1xuXHRcdC8vIERpdmlkZSBpbnRlcnZhbCBieSB0aGUgbnVtYmVyIG9mIGRhdGEgcG9pbnRzIHRvIGNhbGN1bGF0ZSB0aGVpciB0aW1lc3RhbXBzXG5cdFx0bGV0IHNsaWNlTWlsbGlzID0gTWF0aC5yb3VuZChpbnRlcnZhbE1pbGxpcyAvIHZhbHVlcy5sZW5ndGgpO1xuXG5cdFx0bGV0IGRzID0gbmV3IGtlbmRvLmRhdGEuRGF0YVNvdXJjZSgpO1xuXHRcdGxldCBmaXJzdFRpbWVzdGFtcCA9IGxhc3RUaW1lc3RhbXAgLSBpbnRlcnZhbE1pbGxpcztcblxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKVxuXHRcdHtcblx0XHRcdGxldCB0aW1lc3RhbXAgPSBmaXJzdFRpbWVzdGFtcCArIChzbGljZU1pbGxpcyAqIGkpO1xuXG5cdFx0XHRsZXQgdmFsdWUgPSB2YWx1ZXNbaV0gPCAwID8gbnVsbCA6IHZhbHVlc1tpXTtcblx0XHRcdGxldCB2YWx1ZTEgPSB2YWx1ZXMxID8gKHZhbHVlczFbaV0gPCAwID8gbnVsbCA6IHZhbHVlczFbaV0pIDogbnVsbDtcblxuXHRcdFx0bGV0IGVudHJ5ID0ge1xuXHRcdFx0XHR0czogdGltZXN0YW1wLFxuXHRcdFx0XHR2YWw6IHZhbHVlLFxuXHRcdFx0XHR2YWwxOiB2YWx1ZTEsXG5cdFx0XHR9O1xuXG5cdFx0XHRkcy5hZGQoZW50cnkpO1xuXHRcdH1cblxuXHRcdC8vIFNldCBjaGFydCdzIHgtYXhpcyBsaW1pdHNcblx0XHRjaGFydFdpZGdldC5vcHRpb25zLnhBeGlzLm1pbiA9IGZpcnN0VGltZXN0YW1wO1xuXHRcdGNoYXJ0V2lkZ2V0Lm9wdGlvbnMueEF4aXMubWF4ID0gbGFzdFRpbWVzdGFtcDtcblxuXHRcdGNoYXJ0V2lkZ2V0LnNldERhdGFTb3VyY2UoZHMpO1xuXHR9XG5cblx0X2dldENoYXJ0RGl2KHR5cGUpXG5cdHtcblx0XHRyZXR1cm4gJCgnLmNoYXJ0LWNvbnRhaW5lcltkYXRhLXR5cGU9XCInICsgdHlwZSArICdcIl0gLmNoYXJ0JywgdGhpcy5zaGFkb3dSb290KTtcblx0fVxuXG5cdF9nZXRDaGFydFdpZGdldCh0eXBlKVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2dldENoYXJ0RGl2KHR5cGUpLmRhdGEoJ2tlbmRvQ2hhcnQnKTtcblx0fVxuXG5cdF9vbkNoYXJ0Q29udGFpbmVyQ2xpY2soZSlcblx0e1xuXHRcdGxldCBjaGFydFR5cGUgPSAkKGUuY3VycmVudFRhcmdldCkuZGF0YSgndHlwZScpO1xuXG5cdFx0Ly8gRGlzcGF0Y2ggY3VzdG9tIGV2ZW50XG5cdFx0bGV0IGV2dCA9IG5ldyBDdXN0b21FdmVudCgnY2hhcnRDbGljaycsIHtcblx0ICAgIFx0ZGV0YWlsOiB7XG5cdFx0XHRcdHR5cGU6IGNoYXJ0VHlwZSxcblx0XHRcdFx0bm9kZTogdGhpcy5uSWQsXG5cdFx0XHRcdG9wdGlvbnM6IHRoaXMuX2dldENoYXJ0V2lkZ2V0KGNoYXJ0VHlwZSkub3B0aW9uc1xuXHRcdFx0fSxcblx0XHRcdGJ1YmJsZXM6IHRydWUsXG5cdFx0XHRjYW5jZWxhYmxlOiBmYWxzZSxcblx0XHRcdGNvbXBvc2VkOiB0cnVlIC8vIEFsbG93cyBldmVudCB0byBidWJibGUgb3V0c2lkZSBvZiBDdXN0b20gRWxlbWVudFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5kaXNwYXRjaEV2ZW50KGV2dCk7XG5cdH1cbn1cblxuLy8gREVGSU5FIENPTVBPTkVOVFxuaWYgKCF3aW5kb3cuY3VzdG9tRWxlbWVudHMuZ2V0KCdub2RlLW1pbmktY2hhcnRzJykpXG5cdHdpbmRvdy5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ25vZGUtbWluaS1jaGFydHMnLCBOb2RlTWluaUNoYXJ0cyk7XG4iLCJpbXBvcnQge0Jhc2VNb2R1bGV9IGZyb20gJy4vYmFzZS1tb2R1bGUnO1xuaW1wb3J0ICogYXMgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQge2J5dGVzVG9TaXplLCByb3VuZFRvRGVjaW1hbHN9IGZyb20gJy4uL3V0aWxzL3V0aWxpdGllcyc7XG5pbXBvcnQge05vZGVNaW5pQ2hhcnRzfSBmcm9tICcuLi9jb21wb25lbnRzL21vZHVsZS1zcGVjaWZpYy9jbHVzdGVyLW1vbml0b3Ivbm9kZS1taW5pLWNoYXJ0cyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENsdXN0ZXJNb25pdG9yIGV4dGVuZHMgQmFzZU1vZHVsZVxue1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0ICAgIHN1cGVyKCdjbHVzdGVyTW9uJyk7XG5cblx0XHR0aGlzLk1BWF9MT0dfU0laRSA9IDEwMDtcblxuXHRcdC8vIE91dGdvaW5nIHJlcXVlc3RzXG5cdFx0dGhpcy5SRVFfR0VUX05PREVTID0gJ2dldE5vZGVzJztcblx0XHR0aGlzLlJFUV9ERUFDVElWQVRFX05PREVTID0gJ2RlYWN0Jztcblx0XHR0aGlzLlJFUV9HRVRfTk9ERVNfREFUQSA9ICdnZXREYXRhTic7XG5cdFx0dGhpcy5SRVFfR0VUX0NIQVJUX0RBVEEgPSAnZ2V0RGF0YUMnO1xuXHRcdHRoaXMuUkVRX1NDQUxFX1VQID0gJ3NjYWxlVXAnO1xuXHRcdHRoaXMuUkVRX0dFVF9MT0dfTUVTU0FHRVMgPSAnZ2V0TG9nJztcblxuXHRcdC8vIEluY29taW5nIHJlc3BvbnNlc1xuXHRcdHRoaXMuUkVTUF9OT0RFUyA9ICdub2Rlcyc7XG5cdFx0dGhpcy5SRVNQX05PREVTX0RBVEEgPSAnZGF0YU4nO1xuXHRcdHRoaXMuUkVTUF9DSEFSVF9EQVRBID0gJ2RhdGFDJztcblx0XHR0aGlzLlJFU1BfTE9HX01FU1NBR0VTID0gJ2xvZyc7XG5cblx0XHR0aGlzLmludGVydmFscyA9IFtcblx0XHRcdHtcblx0XHRcdFx0bGFiZWw6ICdMYXN0IGhvdXInLFxuXHRcdFx0XHRtaW51dGVzOiA2MCxcblx0XHRcdFx0cG9pbnRzMTogMzAsXG5cdFx0XHRcdHBvaW50czI6IDMwLFxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bGFiZWw6ICdMYXN0IDMgaG91cnMnLFxuXHRcdFx0XHRtaW51dGVzOiAxODAsXG5cdFx0XHRcdHBvaW50czE6IDMwLFxuXHRcdFx0XHRwb2ludHMyOiA5MCxcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdGxhYmVsOiAnTGFzdCAxMiBob3VycycsXG5cdFx0XHRcdG1pbnV0ZXM6IDcyMCxcblx0XHRcdFx0cG9pbnRzMTogMzAsXG5cdFx0XHRcdHBvaW50czI6IDE4MCxcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdGxhYmVsOiAnTGFzdCAyNCBob3VycycsXG5cdFx0XHRcdG1pbnV0ZXM6IDE0NDAsXG5cdFx0XHRcdHBvaW50czE6IDMwLFxuXHRcdFx0XHRwb2ludHMyOiAzNjAsXG5cdFx0XHR9LFxuXHRcdF1cblxuXHRcdHRoaXMuX3NlbGVjdGVkTm9kZXMgPSBbXTtcblx0XHR0aGlzLl9zZWxlY3RlZEFjdGl2ZU5vZGVzID0gW107XG5cdFx0dGhpcy5fY2hhcnRlZE5vZGVzID0gW107XG5cdFx0dGhpcy5fY2hhcnRJbmZvID0gbnVsbDtcblx0XHR0aGlzLl9sYXN0TG9nc1JlcVRpbWVzdGFtcCA9IDA7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBDT01NT04gTU9EVUxFIElOVEVSRkFDRSBNRVRIT0RTXG5cdC8vIFRoaXMgbWVtYmVycyBhcmUgdXNlZCBieSB0aGUgbWFpbiBjb250cm9sbGVyXG5cdC8vIHRvIGNvbW11bmljYXRlIHdpdGggdGhlIG1vZHVsZSdzIGNvbnRyb2xsZXIuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0aW5pdGlhbGl6ZShpZERhdGEsIHNoZWxsQ29udHJvbGxlcilcblx0e1xuXHRcdC8vIENhbGwgc3VwZXIgbWV0aG9kXG5cdFx0c3VwZXIuaW5pdGlhbGl6ZShpZERhdGEsIHNoZWxsQ29udHJvbGxlcik7XG5cblx0XHQvLyBJbml0aWFsaXplIHNjcm9sbGluZyB0YWJzXG5cdFx0JCgnI2NsbS10YWJOYXZpZ2F0b3IgPiAjdGFicycpLnNjcm9sbGluZ1RhYnMoe1xuXHRcdFx0Ym9vdHN0cmFwVmVyc2lvbjogNCxcblx0XHRcdHNjcm9sbFRvVGFiRWRnZTogdHJ1ZSxcblx0XHRcdGVuYWJsZVN3aXBpbmc6IHRydWUsXG5cdFx0XHRkaXNhYmxlU2Nyb2xsQXJyb3dzT25GdWxseVNjcm9sbGVkOiB0cnVlLFxuXHRcdFx0Y3NzQ2xhc3NMZWZ0QXJyb3c6ICdmYSBmYS1jaGV2cm9uLWxlZnQnLFxuXHRcdFx0Y3NzQ2xhc3NSaWdodEFycm93OiAnZmEgZmEtY2hldnJvbi1yaWdodCdcblx0XHR9KTtcblxuXHRcdC8vIEluaXRpYWxpemUgYnV0dG9uc1xuXHRcdCQoJyNjbG0tZGVhY3RpdmF0ZUJ0Jykub24oJ2NsaWNrJywgJC5wcm94eSh0aGlzLl9vbkRlYWN0aXZhdGVCdENsaWNrLCB0aGlzKSk7XG5cdFx0JCgnI2NsbS1zY2FsZVVwQnQnKS5vbignY2xpY2snLCAkLnByb3h5KHRoaXMuX29uU2NhbGVVcEJ0Q2xpY2ssIHRoaXMpKTtcblx0XHQkKCcjY2xtLXNjYWxlVXBNb2RhbEJ0Jykub24oJ2NsaWNrJywgJC5wcm94eSh0aGlzLl9vblNjYWxlVXBDb25maXJtQnRDbGljaywgdGhpcykpO1xuXHRcdCQoJyNjbG0tcmVmcmVzaEJ0Jykub24oJ2NsaWNrJywgJC5wcm94eSh0aGlzLl9yZXF1ZXN0Tm9kZXNMaXN0LCB0aGlzKSk7XG5cblx0XHQvLyBJbml0aWFsaXplIGdyaWRcblx0XHR0aGlzLl9ncmlkID0gJCgnI2NsbS1ub2Rlc0xpc3QnKS5rZW5kb0dyaWQoe1xuXHRcdFx0c2Nyb2xsYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIHNvcnRhYmxlOiB0cnVlLFxuXHRcdFx0Ly9yZXNpemFibGU6IHRydWUsXG5cdFx0XHRzZWxlY3RhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbHVtbnM6IFtcblx0XHRcdFx0e1xuXHRcdFx0XHRcdHNlbGVjdGFibGU6IHRydWUsXG5cdFx0XHRcdFx0d2lkdGg6IDQxXG5cdFx0XHRcdH0sXG5cdFx0XHRcdHtcblx0ICAgICAgICAgICAgICAgIGZpZWxkOiAnbmFtZScsXG5cdCAgICAgICAgICAgICAgICB3aWR0aDogMjUwLFxuXHRcdFx0XHRcdHRpdGxlOiAnTm9kZScsXG5cdFx0XHRcdFx0dGVtcGxhdGU6IGZ1bmN0aW9uKGRhdGFJdGVtKSB7XG5cdFx0XHRcdFx0XHRpZiAoZGF0YUl0ZW1bJ2FsaWFzJ10pXG5cdFx0XHRcdFx0XHRcdHJldHVybiAnPGRpdiBjbGFzcz1cIm5hbWUtY2VsbFwiPjxzcGFuPicgKyBkYXRhSXRlbVsnYWxpYXMnXSArICc8L3NwYW4+IDxhIGhyZWY9XCJodHRwOi8vJyArIGRhdGFJdGVtWyduYW1lJ10gKyAnOjgwODAvYWRtaW5cIiBjbGFzcz1cIm5hbWUtYWRtaW4tbGlua1wiIHRhcmdldD1cIl9ibGFua1wiPjxpIGNsYXNzPVwiZmFzIGZhLXRvb2xib3hcIj48L2k+PC9hPjxicj48c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+JyArIGRhdGFJdGVtWyduYW1lJ10gKyAnPHNtYWxsPjwvZGl2Pic7XG5cdFx0XHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0XHRcdHJldHVybiAnPGRpdiBjbGFzcz1cIm5hbWUtY2VsbFwiPjxzcGFuPicgKyBkYXRhSXRlbVsnbmFtZSddICsgJzwvc3Bhbj4gPGEgaHJlZj1cImh0dHA6Ly8nICsgZGF0YUl0ZW1bJ25hbWUnXSArICc6ODA4MC9hZG1pblwiIGNsYXNzPVwibmFtZS1hZG1pbi1saW5rXCIgdGFyZ2V0PVwiX2JsYW5rXCI+PGkgY2xhc3M9XCJmYXMgZmEtdG9vbGJveFwiPjwvaT48L2E+PC9kaXY+Jztcblx0XHRcdFx0XHR9XG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgIHtcblx0ICAgICAgICAgICAgICAgIGZpZWxkOiAnY2N1Jyxcblx0ICAgICAgICAgICAgICAgIHdpZHRoOiA4MCxcblx0ICAgICAgICAgICAgICAgIHRpdGxlOiAnQ0NVJyxcblx0ICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAge1xuXHQgICAgICAgICAgICAgICAgZmllbGQ6ICdjcHUnLFxuXHQgICAgICAgICAgICAgICAgd2lkdGg6IDgwLFxuXHQgICAgICAgICAgICAgICAgdGl0bGU6ICdDUFUnLFxuXHRcdFx0XHRcdHRlbXBsYXRlOiBmdW5jdGlvbihkYXRhSXRlbSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHJvdW5kVG9EZWNpbWFscyhkYXRhSXRlbVsnY3B1J10sIDIpICsgJyUnO1xuXHRcdFx0XHRcdH1cblx0ICAgICAgICAgICAgfSxcblx0XHRcdFx0e1xuICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ01lbW9yeScsXG4gICAgICAgICAgICAgICAgICAgIGNvbHVtbnM6IFtcblx0XHRcdFx0XHRcdHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQ6ICd1c2VkTWVtJyxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IDEwMCxcblx0XHRcdFx0XHRcdFx0dGl0bGU6ICdVc2VkJyxcblx0XHRcdFx0XHRcdFx0dGVtcGxhdGU6IGZ1bmN0aW9uKGRhdGFJdGVtKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGJ5dGVzVG9TaXplKGRhdGFJdGVtWyd1c2VkTWVtJ10pO1xuXHRcdFx0XHRcdFx0XHR9XG5cdCAgICAgICAgICAgICAgICAgICAgfSxcblx0XHRcdFx0XHRcdHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQ6ICdhbGxvY01lbScsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiAxMDAsXG5cdFx0XHRcdFx0XHRcdHRpdGxlOiAnQWxsb2NhdGVkJyxcblx0XHRcdFx0XHRcdFx0dGVtcGxhdGU6IGZ1bmN0aW9uKGRhdGFJdGVtKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGJ5dGVzVG9TaXplKGRhdGFJdGVtWydhbGxvY01lbSddKTtcblx0XHRcdFx0XHRcdFx0fVxuICAgICAgICAgICAgICAgICAgICBcdH1cblx0XHRcdFx0XHRdXG4gICAgICAgICAgICAgICAgfSxcblx0XHRcdFx0e1xuICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ05ldHdvcmsnLFxuICAgICAgICAgICAgICAgICAgICBjb2x1bW5zOiBbXG5cdFx0XHRcdFx0XHR7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkOiAnbmV0SW4nLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogMTAwLFxuXHRcdFx0XHRcdFx0XHR0aXRsZTogJ0luJyxcblx0XHRcdFx0XHRcdFx0dGVtcGxhdGU6IGZ1bmN0aW9uKGRhdGFJdGVtKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIChkYXRhSXRlbVsnbmV0SW4nXSA+IC0xID8gYnl0ZXNUb1NpemUoZGF0YUl0ZW1bJ25ldEluJ10sIDIsICdLQicsICcvcycpIDogJyZuZGFzaDsnKTtcblx0XHRcdFx0XHRcdFx0fVxuXHQgICAgICAgICAgICAgICAgICAgIH0sXG5cdFx0XHRcdFx0XHR7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkOiAnbmV0T3V0Jyxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IDEwMCxcblx0XHRcdFx0XHRcdFx0dGl0bGU6ICdPdXQnLFxuXHRcdFx0XHRcdFx0XHR0ZW1wbGF0ZTogZnVuY3Rpb24oZGF0YUl0ZW0pIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gKGRhdGFJdGVtWyduZXRPdXQnXSA+IC0xID8gYnl0ZXNUb1NpemUoZGF0YUl0ZW1bJ25ldE91dCddLCAyLCAnS0InLCAnL3MnKSA6ICcmbmRhc2g7Jyk7XG5cdFx0XHRcdFx0XHRcdH1cbiAgICAgICAgICAgICAgICAgICAgXHR9XG5cdFx0XHRcdFx0XVxuICAgICAgICAgICAgICAgIH0sXG5cdFx0XHRcdHtcblx0ICAgICAgICAgICAgICAgIGZpZWxkOiAndGhyZWFkcycsXG5cdCAgICAgICAgICAgICAgICB3aWR0aDogMTAwLFxuXHRcdFx0XHRcdHRpdGxlOiAnVGhyZWFkcycsXG5cdCAgICAgICAgICAgIH0sXG5cdFx0XHRcdHtcblx0ICAgICAgICAgICAgICAgIGZpZWxkOiAncm9vbXMnLFxuXHQgICAgICAgICAgICAgICAgd2lkdGg6IDEwMCxcblx0XHRcdFx0XHR0aXRsZTogJ1Jvb21zJyxcblx0ICAgICAgICAgICAgfSxcblx0XHRcdFx0e1xuXHQgICAgICAgICAgICAgICAgZmllbGQ6ICdqb2luVGltZScsXG5cdCAgICAgICAgICAgICAgICB3aWR0aDogMTAwLFxuXHRcdFx0XHRcdHRpdGxlOiAnSm9pbmVkJyxcblx0XHRcdFx0XHRzb3J0YWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dGVtcGxhdGU6ICQucHJveHkodGhpcy5fZ2V0VGltZVNpbmNlSm9pblRlbXBsYXRlLCB0aGlzKVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHR7XG5cdCAgICAgICAgICAgICAgICBmaWVsZDogJ2hlYWx0aCcsXG5cdCAgICAgICAgICAgICAgICB3aWR0aDogNzUsXG5cdFx0XHRcdFx0dGl0bGU6ICdIZWFsdGgnLFxuXHRcdFx0XHRcdHNvcnRhYmxlOiBmYWxzZSxcblx0XHRcdFx0XHR0ZW1wbGF0ZTogJC5wcm94eSh0aGlzLl9nZXRIZWFsdGhUZW1wbGF0ZSwgdGhpcylcblx0ICAgICAgICAgICAgfSxcblx0XHRcdFx0e1xuXHQgICAgICAgICAgICAgICAgZmllbGQ6ICdyZWN5Y2xhYmxlJyxcblx0ICAgICAgICAgICAgICAgIHdpZHRoOiA0NSxcblx0XHRcdFx0XHR0aXRsZTogJ1IuJyxcblx0XHRcdFx0XHRzb3J0YWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0dGVtcGxhdGU6ICQucHJveHkodGhpcy5fZ2V0UmVjeWNsYWJsZVRlbXBsYXRlLCB0aGlzKVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHR7XG5cdCAgICAgICAgICAgICAgICBmaWVsZDogJ3Rlcm1pbmFibGUnLFxuXHQgICAgICAgICAgICAgICAgd2lkdGg6IDQ1LFxuXHRcdFx0XHRcdHRpdGxlOiAnVC4nLFxuXHRcdFx0XHRcdHNvcnRhYmxlOiBmYWxzZSxcblx0XHRcdFx0XHR0ZW1wbGF0ZTogJC5wcm94eSh0aGlzLl9nZXRUZXJtaW5hYmxlVGVtcGxhdGUsIHRoaXMpXG5cdCAgICAgICAgICAgIH0sXG5cdFx0XHRdLFxuXHRcdFx0bm9SZWNvcmRzOiB7XG5cdFx0XHRcdHRlbXBsYXRlOiAnTm8gZ2FtZSBub2Rlcy4nXG5cdFx0XHR9LFxuXHRcdFx0ZGF0YVNvdXJjZToge1xuXHRcdFx0XHRzY2hlbWE6IHtcblx0XHRcdFx0XHRtb2RlbDoge1xuXHRcdFx0XHRcdFx0aWQ6ICdpZCcsXG5cdFx0XHRcdFx0XHQvLyBmaWVsZHM6IHtcblx0XHRcdFx0XHRcdC8vIFx0aWQ6IHsgdHlwZTogJ3N0cmluZycgfSxcblx0XHRcdFx0XHRcdC8vIFx0YWN0aXZlOiB7IHR5cGU6ICdib29sZWFuJyB9XG5cdFx0XHRcdFx0XHQvLyB9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRncm91cDoge1xuXHRcdFx0XHRcdGZpZWxkOiAnYWN0aXZlJyxcblx0XHRcdFx0XHRkaXI6ICdkZXNjJyxcblx0XHRcdFx0fVxuICAgICAgICAgICAgfSxcblx0XHRcdGNoYW5nZTogJC5wcm94eSh0aGlzLl9vbk5vZGVzR3JpZENoYW5nZSwgdGhpcyksXG5cdFx0XHRkYXRhQm91bmQ6ICQucHJveHkodGhpcy5fb25Ob2Rlc0dyaWREYXRhQm91bmQsIHRoaXMpLFxuICAgICAgICB9KS5kYXRhKCdrZW5kb0dyaWQnKTtcblxuXHRcdC8vIEFkZCBsaXN0ZW5lciB0byBtaW5pIGNoYXJ0cyBjb250YWluZXJcblx0XHQkKCcjY2xtLW5vZGVNaW5pQ2hhcnRzQ29udGFpbmVyJykub24oJ2NoYXJ0Q2xpY2snLCAkLnByb3h5KHRoaXMuX29uTWluaUNoYXJ0Q2xpY2ssIHRoaXMpKTtcblxuXHRcdC8vIENvbmZpZ3VyZSBkZXRhaWwgY2hhcnQgbW9kYWxcblx0XHQkKCcjY2xtLWNoYXJ0TW9kYWwnKS5tb2RhbCh7XG5cdFx0XHRiYWNrZHJvcDogJ3N0YXRpYycsXG5cdFx0XHRrZXlib2FyZDogZmFsc2UsXG5cdFx0XHRzaG93OiBmYWxzZSxcblx0XHR9KTtcblxuXHRcdC8vIEFkZCBldmVudCBsaXN0ZW5lciBmb3IgbW9kYWwgaGlkZGVuIGV2ZW50XG5cdFx0JCgnI2NsbS1jaGFydE1vZGFsJykub24oJ2hpZGRlbi5icy5tb2RhbCcsICQucHJveHkodGhpcy5fb25DaGFydE1vZGFsSGlkZGVuLCB0aGlzKSk7XG5cblx0XHQvLyBJbml0aWFsaXplIGRhdGEgaW50ZXJ2YWwgZHJvcGRvd25zXG5cdFx0bGV0IGl0ZW1zID0gW107XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmludGVydmFscy5sZW5ndGg7IGkrKylcblx0XHRcdGl0ZW1zLnB1c2goe2xhYmVsOnRoaXMuaW50ZXJ2YWxzW2ldLmxhYmVsLCB2YWx1ZTppfSk7XG5cblx0XHR0aGlzLl9tYWluUmFuZ2VERCA9ICQoJyNjbG0tbWFpblJhbmdlREQnKS5rZW5kb0Ryb3BEb3duTGlzdCh7XG5cdFx0XHRkYXRhVGV4dEZpZWxkOiAnbGFiZWwnLFxuXHRcdFx0ZGF0YVZhbHVlRmllbGQ6ICd2YWx1ZScsXG5cdFx0XHRkYXRhU291cmNlOiBpdGVtcyxcblx0XHRcdGluZGV4OiAwLFxuXHRcdFx0Ly92YWx1ZVRlbXBsYXRlOiAnPHNwYW4gY2xhc3M9XCJ0ZXh0LW11dGVkIHByLTFcIj5MYXN0IDwvc3Bhbj48c3Bhbj4jOmRhdGEudGV4dCM8L3NwYW4+Jyxcblx0XHRcdGNoYW5nZTogJC5wcm94eSh0aGlzLl9vbk1haW5SYW5nZUNoYW5nZSwgdGhpcylcblx0XHR9KS5kYXRhKCdrZW5kb0Ryb3BEb3duTGlzdCcpO1xuXG5cdFx0JCgnI2NsbS1tYWluUmFuZ2VDb250YWluZXInKS5oaWRlKCk7XG5cblx0XHR0aGlzLl9jaGFydFJhbmdlREQgPSAkKCcjY2xtLWNoYXJ0UmFuZ2VERCcpLmtlbmRvRHJvcERvd25MaXN0KHtcblx0XHRcdGRhdGFUZXh0RmllbGQ6ICdsYWJlbCcsXG5cdFx0XHRkYXRhVmFsdWVGaWVsZDogJ3ZhbHVlJyxcblx0XHRcdGRhdGFTb3VyY2U6IGl0ZW1zLFxuXHRcdFx0aW5kZXg6IDAsXG5cdFx0XHQvL3ZhbHVlVGVtcGxhdGU6ICc8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWQgcHItMVwiPkxhc3QgPC9zcGFuPjxzcGFuPiM6ZGF0YS50ZXh0Izwvc3Bhbj4nLFxuXHRcdFx0Y2hhbmdlOiAkLnByb3h5KHRoaXMuX29uQ2hhcnRSYW5nZUNoYW5nZSwgdGhpcylcblx0XHR9KS5kYXRhKCdrZW5kb0Ryb3BEb3duTGlzdCcpO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSBsb2JieSBzdGF0ZSBpbmZvXG5cdFx0JCgnI2NsbS1sb2JieVN0YXRlJykuaGlkZSgpO1xuXG5cdFx0Ly8gQ29uZmlndXJlIHNjYWxlLXVwIG1vZGFsXG5cdFx0JCgnI2NsbS1zY2FsZVVwTW9kYWwnKS5tb2RhbCh7XG5cdFx0XHRiYWNrZHJvcDogJ3N0YXRpYycsXG5cdFx0XHRrZXlib2FyZDogZmFsc2UsXG5cdFx0XHRzaG93OiBmYWxzZSxcblx0XHR9KTtcblxuXHRcdC8vIEluaXQgbm9kZXMnIG51bWJlciBudW1lcmljIHN0ZXBwZXIgaW4gc2NhbGUtdXAgbW9kYWxcblx0XHR0aGlzLl9udW1Ob2Rlc0luID0gJCgnI2NsbS1udW1Ob2Rlc05TJykua2VuZG9OdW1lcmljVGV4dEJveCh7XG5cdFx0ICAgIG1pbjogMSxcblx0XHRcdG1heDogNSxcblx0XHQgICAgc3RlcDogMSxcblx0XHQgICAgZm9ybWF0OiAnIydcblx0XHR9KS5kYXRhKCdrZW5kb051bWVyaWNUZXh0Qm94Jyk7XG5cblx0XHQvLyBJbml0aWFsaXplIGtlbmRvIHZhbGlkYXRpb24gb24gc2NhbGUtdXAgZm9ybVxuXHRcdHRoaXMuX3NjYWxlVXBWYWxpZGF0b3IgPSAkKCcjY2xtLXNjYWxlVXBGb3JtJykua2VuZG9WYWxpZGF0b3Ioe30pLmRhdGEoJ2tlbmRvVmFsaWRhdG9yJyk7XG5cblx0XHQvLyBBZGQgbGlzdGVuZXIgZm9yIHNjYWxlLXVwIHBhbmVsIGhpZGVcblx0XHQkKCcjY2xtLXNjYWxlVXBNb2RhbCcpLm9uKCdoaWRkZW4uYnMubW9kYWwnLCAkLnByb3h5KHRoaXMuX29uU2NhbGVVcE1vZGFsSGlkZGVuLCB0aGlzKSk7XG5cblx0XHQvLyBJbml0aWFsaXplIG9yY2hlc3RyYXRpb24gbG9nIGdyaWRcblx0XHR0aGlzLl9sb2dHcmlkID0gJCgnI2NsbS1sb2dHcmlkJykua2VuZG9HcmlkKHtcblx0XHRcdGRhdGFTb3VyY2U6IFtdLFxuXHRcdFx0cmVzaXphYmxlOiB0cnVlLFxuXHRcdFx0c2VsZWN0YWJsZTogZmFsc2UsXG5cdFx0XHRub1JlY29yZHM6IHtcblx0XHRcdFx0dGVtcGxhdGU6ICdObyBlbnRyaWVzLidcblx0XHRcdH0sXG5cdFx0XHRjb2x1bW5zOiBbXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRmaWVsZDogJ3RpbWVzdGFtcCcsXG5cdFx0XHRcdFx0dGl0bGU6ICdUaW1lc3RhbXAnLFxuXHRcdFx0XHRcdHdpZHRoOiAxODBcblx0XHRcdFx0fSxcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGZpZWxkOiAnbGV2ZWwnLFxuXHRcdFx0XHRcdHRpdGxlOiAnTGV2ZWwnLFxuXHRcdFx0XHRcdHdpZHRoOiAxMDBcblx0XHRcdFx0fSxcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGZpZWxkOiAnbWVzc2FnZScsXG5cdFx0XHRcdFx0dGl0bGU6ICdNZXNzYWdlJyxcblx0XHRcdFx0XHR3aWR0aDogNDAwXG5cdFx0XHRcdH0sXG5cdFx0XHRdLFxuXHRcdFx0ZGF0YUJvdW5kOiBmdW5jdGlvbigpIHtcblx0XHRcdCAgICB0aGlzLmNvbnRlbnQuc2Nyb2xsVG9wKHRoaXMudGJvZHkuaGVpZ2h0KCkpOyAvLyBTY3JvbGwgdG8gYm90dG9tXG5cdFx0XHR9XG5cdFx0fSkuZGF0YSgna2VuZG9HcmlkJyk7XG5cblx0XHQkKCcjY2xtX21heExvZ01zZ3MnKS50ZXh0KHRoaXMuTUFYX0xPR19TSVpFKTtcblxuXHRcdC8vIEluaXRpYWxpemUgaGVscCB0b29sdGlwc1xuXHRcdCQodGhpcykua2VuZG9Ub29sdGlwKHtcblx0XHRcdGZpbHRlcjogJ2lbdGl0bGVdLmhlbHAnLFxuXHRcdFx0cG9zaXRpb246ICdyaWdodCcsXG5cdFx0XHRjb250ZW50OiBmdW5jdGlvbihlKSB7XG5cdFx0XHRcdHJldHVybiBgPGRpdiBjbGFzcz1cImhlbHAtdG9vbHRpcFwiPiR7ZS50YXJnZXQuZGF0YSgndGl0bGUnKX08L2Rpdj5gO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0XHQvLyBSZXF1ZXN0IG5vZGVzIGxpc3QgdG8gc2VydmVyXG5cdFx0dGhpcy5fcmVxdWVzdE5vZGVzTGlzdCgpO1xuXG5cdFx0Ly8gU2NoZWR1bGUgY29udGludW91cyBkYXRhIHJlcXVlc3QgZm9yIHRoZSBzZWxlY3RlZCBub2Rlc1xuXHRcdHRoaXMuX3JlcXVlc3REYXRhVGltZXIgPSBzZXRJbnRlcnZhbCgkLnByb3h5KHRoaXMuX29uUmVxdWVzdERhdGFJbnRlcnZhbCwgdGhpcyksIDYwMDAwKTsgLy8gMSBtaW51dGVcblxuXHRcdC8vIFJlcXVlc3Qgb3JjaGVzdHJhdGlvbiBsb2dzIHRvIHNlcnZlclxuXHRcdHRoaXMuX3JlcXVlc3RPcmNoZXN0cmF0aW9uTG9ncygpO1xuXG5cdFx0Ly8gU2NoZWR1bGUgY29udGludW91cyBvcmNoZXN0cmF0aW9uIGxvZ3MgcmVxdWVzdFxuXHRcdHRoaXMuX3JlcXVlc3RMb2dzVGltZXIgPSBzZXRJbnRlcnZhbCgkLnByb3h5KHRoaXMuX3JlcXVlc3RPcmNoZXN0cmF0aW9uTG9ncywgdGhpcyksIDMwMDApOyAvLyAzIHNlY29uZHNcblx0fVxuXG5cdGRlc3Ryb3koKVxuXHR7XG5cdFx0Ly8gQ2FsbCBzdXBlciBtZXRob2Rcblx0XHRzdXBlci5kZXN0cm95KCk7XG5cblx0XHQvLyBEZXN0cm95IHNjcm9sbGluZyB0YWJzXG5cdFx0JCgnI2NsbS10YWJOYXZpZ2F0b3IgI3RhYnMnKS5zY3JvbGxpbmdUYWJzKCdkZXN0cm95Jyk7XG5cblx0XHQvLyBIaWRlIG1vZGFsc1xuXHRcdCQoJyNjbG0tY2hhcnRNb2RhbCcpLm1vZGFsKCdoaWRlJyk7XG5cdFx0JCgnI2NsbS1zY2FsZVVwTW9kYWwnKS5tb2RhbCgnaGlkZScpO1xuXG5cdFx0Ly8gUmVtb3ZlIGNsaWNrIGxpc3RlbmVyc1xuXHRcdCQoJyNjbG0tcmVmcmVzaEJ0Jykub2ZmKCdjbGljaycpO1xuXHRcdCQoJyNjbG0tc2NhbGVVcEJ0Jykub2ZmKCdjbGljaycpO1xuXHRcdCQoJyNjbG0tc2NhbGVVcE1vZGFsQnQnKS5vZmYoJ2NsaWNrJyk7XG5cdFx0JCgnI2NsbS1ub2RlTWluaUNoYXJ0c0NvbnRhaW5lcicpLm9mZignY2hhcnRDbGljaycpO1xuXG5cdFx0Ly8gUmVtb3ZlIHNjYWxlLXVwIHBhbmVsIGxpc3RlbmVyXG5cdFx0JCgnI2NsbS1zY2FsZVVwTW9kYWwnKS5vZmYoJ2hpZGRlbi5icy5tb2RhbCcpO1xuXG5cdFx0Ly8gQ2xlYXIgbm9kZXMsIGRhdGEgYW5kIGxvZ3MgcmVxdWVzdCBzY2hlZHVsaW5nXG5cdFx0Y2xlYXJUaW1lb3V0KHRoaXMuX3JlcXVlc3ROb2Rlc1RpbWVyKTtcblx0XHRjbGVhckludGVydmFsKHRoaXMuX3JlcXVlc3REYXRhVGltZXIpO1xuXHRcdGNsZWFySW50ZXJ2YWwodGhpcy5fcmVxdWVzdExvZ3NUaW1lcik7XG5cdH1cblxuXHRvbkV4dGVuc2lvbkNvbW1hbmQoY29tbWFuZCwgZGF0YSlcblx0e1xuXHRcdGlmIChjb21tYW5kID09IHRoaXMuUkVTUF9OT0RFUylcblx0XHR7XG5cdFx0XHRsZXQgbm9kZXNPYmogPSBkYXRhLmdldFNGU0FycmF5KCdub2RlcycpO1xuXG5cdFx0XHRsZXQgbm9kZXMgPSBbXTtcblx0XHRcdGxldCBub2Rlc0lkcyA9IFtdO1xuXG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVzT2JqLnNpemUoKTsgaSsrKVxuXHRcdFx0e1xuXHRcdFx0XHRsZXQgbm9kZSA9IG5vZGVzT2JqLmdldFNGU0FycmF5KGkpO1xuXG5cdFx0XHRcdG5vZGVzSWRzLnB1c2gobm9kZS5nZXRVdGZTdHJpbmcoMCkpO1xuXG5cdFx0XHRcdG5vZGVzLnB1c2goe1xuXHRcdFx0XHRcdCdpZCc6IG5vZGUuZ2V0VXRmU3RyaW5nKDApLFxuXHRcdFx0XHRcdCdhbGlhcyc6IG5vZGUuZ2V0VXRmU3RyaW5nKDEpLCAvLyBTZXQgaW4gbm9kZSBjb25maWd1cmF0aW9uLCBidXQgY2FuJ3QgYmUgZWRpdGVkIC0gY291bGQgYmUgcmVtb3ZlZFxuXHRcdFx0XHRcdCduYW1lJzogbm9kZS5nZXRVdGZTdHJpbmcoMiksIC8vIElQIGFkZHJlc3Mgb3IgZG9tYWluIG5hbWVcblx0XHRcdFx0XHQncm9vbXMnOiBub2RlLmdldEludCgzKSxcblx0XHRcdFx0XHQnY2N1Jzogbm9kZS5nZXRJbnQoNCksXG5cdFx0XHRcdFx0J3RocmVhZHMnOiBub2RlLmdldEludCg1KSxcblx0XHRcdFx0XHQnY3B1Jzogbm9kZS5nZXREb3VibGUoNiksXG5cdFx0XHRcdFx0J3VzZWRNZW0nOiBub2RlLmdldExvbmcoNyksXG5cdFx0XHRcdFx0J2FsbG9jTWVtJzogbm9kZS5nZXRMb25nKDgpLFxuXHRcdFx0XHRcdCduZXRJbic6IG5vZGUuZ2V0TG9uZyg5KSxcblx0XHRcdFx0XHQnbmV0T3V0Jzogbm9kZS5nZXRMb25nKDEwKSxcblx0XHRcdFx0XHQnam9pblRpbWUnOiBub2RlLmdldExvbmcoMTEpLFxuXHRcdFx0XHRcdCdoZWFsdGgnOiBub2RlLmdldEJvb2woMTIpLFxuXHRcdFx0XHRcdCdhY3RpdmUnOiBub2RlLmdldEJvb2woMTMpLCAvLyBVc2VkIGZvciBncm91cGluZ1xuXHRcdFx0XHRcdCdyZWN5Y2xhYmxlJzogbm9kZS5nZXRCb29sKDE0KSxcblx0XHRcdFx0XHQndGVybWluYWJsZSc6IG5vZGUuZ2V0Qm9vbCgxNSksXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBHZXQgbm9kZXMgZ3JpZCBkYXRhc291cmNlXG5cdFx0XHRsZXQgZHMgPSB0aGlzLl9ncmlkLmRhdGFTb3VyY2U7XG5cblx0XHRcdC8vIC0tLSBSRU1PVkUgTk9ERVMgLS0tXG5cblx0XHRcdGxldCBzZWxmID0gdGhpcztcblx0XHRcdCQubWFwKGRzLmRhdGEoKSwgZnVuY3Rpb24gKGRhdGFJdGVtLCBpbmRleCkge1xuXHRcdFx0XHRpZiAoZGF0YUl0ZW0gJiYgIW5vZGVzSWRzLmluY2x1ZGVzKGRhdGFJdGVtWydpZCddKSlcblx0XHRcdFx0e1xuXHRcdFx0XHRcdC8vIFJlbW92ZSBub2RlIGZyb20gZGF0YXN0b3JlXG5cdFx0XHRcdFx0ZHMucmVtb3ZlKGRhdGFJdGVtKTtcblxuXHRcdFx0XHRcdC8vIFJlbW92ZSBub2RlIGZyb20gbGlzdCBvZiBzZWxlY3RlZCBub2RlcyAoaWYgc2VsZWN0ZWQpXG5cdFx0XHRcdFx0c2VsZi5fc2VsZWN0ZWROb2RlcyA9IHNlbGYuX3NlbGVjdGVkTm9kZXMuZmlsdGVyKHggPT4geCAhPT0gZGF0YUl0ZW1bJ2lkJ10pO1xuXHRcdFx0XHRcdHNlbGYuX3NlbGVjdGVkQWN0aXZlTm9kZXMgPSBzZWxmLl9zZWxlY3RlZEFjdGl2ZU5vZGVzLmZpbHRlcih4ID0+IHggIT09IGRhdGFJdGVtWydpZCddKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdC8vIFVwZGF0ZSBub2RlcyBjaGFydHMgdmlldyBhbmQgbm9kZXMgZGVhY3RpdmF0ZSBidXR0b24sIGluIGNhc2UgYSBzZWxlY3RlZCBub2RlIHdhcyByZW1vdmVkXG5cdFx0XHR0aGlzLl91cGRhdGVDaGFydGVkTm9kZXMoKTtcblx0XHRcdHRoaXMuX3VwZGF0ZURlYWN0aXZhdGVCdXR0b24oKTtcblxuXHRcdFx0Ly8gLS0tIEFERC9VUERBVEUgTk9ERVMgLS0tXG5cblx0XHRcdGxldCBhY3RpdmVOb2Rlc0NudCA9IDA7XG5cblx0XHRcdGZvciAobGV0IG5vZGUgb2Ygbm9kZXMpXG5cdFx0XHR7XG5cdFx0XHRcdHZhciBkYXRhSXRlbSA9IGRzLmdldChub2RlLmlkKTtcblxuXHRcdFx0XHQvLyBVcGRhdGUgbm9kZVxuXHRcdFx0XHRpZiAoZGF0YUl0ZW0pXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRkYXRhSXRlbS5zZXQoJ3Jvb21zJywgbm9kZS5yb29tcyk7XG5cdFx0XHRcdFx0ZGF0YUl0ZW0uc2V0KCdjY3UnLCBub2RlLmNjdSk7XG5cdFx0XHRcdFx0ZGF0YUl0ZW0uc2V0KCd0aHJlYWRzJywgbm9kZS50aHJlYWRzKTtcblx0XHRcdFx0XHRkYXRhSXRlbS5zZXQoJ2NwdScsIG5vZGUuY3B1KTtcblx0XHRcdFx0XHRkYXRhSXRlbS5zZXQoJ3VzZWRNZW0nLCBub2RlLnVzZWRNZW0pO1xuXHRcdFx0XHRcdGRhdGFJdGVtLnNldCgnYWxsb2NNZW0nLCBub2RlLmFsbG9jTWVtKTtcblx0XHRcdFx0XHRkYXRhSXRlbS5zZXQoJ25ldEluJywgbm9kZS5uZXRJbik7XG5cdFx0XHRcdFx0ZGF0YUl0ZW0uc2V0KCduZXRPdXQnLCBub2RlLm5ldE91dCk7XG5cdFx0XHRcdFx0ZGF0YUl0ZW0uc2V0KCdqb2luVGltZScsIG5vZGUuam9pblRpbWUpO1xuXHRcdFx0XHRcdGRhdGFJdGVtLnNldCgnaGVhbHRoJywgbm9kZS5oZWFsdGgpO1xuXHRcdFx0XHRcdGRhdGFJdGVtLnNldCgnYWN0aXZlJywgbm9kZS5hY3RpdmUpO1xuXHRcdFx0XHRcdGRhdGFJdGVtLnNldCgncmVjeWNsYWJsZScsIG5vZGUucmVjeWNsYWJsZSk7XG5cdFx0XHRcdFx0ZGF0YUl0ZW0uc2V0KCd0ZXJtaW5hYmxlJywgbm9kZS50ZXJtaW5hYmxlKTtcblxuXHRcdFx0XHRcdGRhdGFJdGVtLmRpcnR5ID0gZmFsc2U7IC8vIEhpZGVzIFwiZGlydHlcIiBpbmRpY2F0b3IgaW4gZ3JpZFxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQWRkIG5vZGVcblx0XHRcdFx0ZWxzZVxuXHRcdFx0XHQgXHRkcy5hZGQobm9kZSk7XG5cblx0XHRcdFx0Ly8gQ291bnQgYWN0aXZlIG5vZGVzXG5cdFx0XHRcdGlmIChub2RlLmFjdGl2ZSlcblx0XHRcdFx0XHRhY3RpdmVOb2Rlc0NudCsrO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZWZyZXNoIGdyaWRcblx0XHRcdHRoaXMuX2dyaWQucmVmcmVzaCgpO1xuXG5cdFx0XHQvLyBEaXNwbGF5IGdsb2JhbCB2YWx1ZXNcblx0XHRcdCQoJyNjbG0tdG90YWxBY3RpdmVOb2RlcycpLnRleHQoYWN0aXZlTm9kZXNDbnQpO1xuXHRcdFx0JCgnI2NsbS10b3RhbEluYWN0aXZlTm9kZXMnKS50ZXh0KG5vZGVzLmxlbmd0aCAtIGFjdGl2ZU5vZGVzQ250KTtcblx0XHRcdCQoJyNjbG0tdG90YWxDY3VMb2JieScpLnRleHQoZGF0YS5nZXRJbnQoJ2NjdUxvYmJ5JykpO1xuXHRcdFx0JCgnI2NsbS10b3RhbENjdU5vZGVzJykudGV4dChkYXRhLmdldEludCgnY2N1Tm9kZXMnKSk7XG5cdFx0XHQkKCcjY2xtLXRvdGFsUm9vbXMnKS50ZXh0KGRhdGEuZ2V0SW50KCdyb29tcycpKTtcblxuXHRcdFx0Ly8gU2hvdyBsb2JieSBzdGF0ZVxuXHRcdFx0dGhpcy5fc2hvd0xvYmJ5U3RhdGUoZGF0YS5nZXRCb29sKCdhY3RpdmUnKSk7XG5cdFx0fVxuXG5cdFx0ZWxzZSBpZiAoY29tbWFuZCA9PSB0aGlzLlJFU1BfTk9ERVNfREFUQSlcblx0XHR7XG5cdFx0XHRsZXQgc3RhdHMgPSBkYXRhLmdldFNGU0FycmF5KCdzdGF0cycpO1xuXHRcdFx0bGV0IGkgPSB0aGlzLl9tYWluUmFuZ2VERC52YWx1ZSgpO1xuXHRcdFx0bGV0IGludGVydmFsTWlsbGlzID0gdGhpcy5pbnRlcnZhbHNbaV0ubWludXRlcyAqIDYwICogMTAwMDtcblxuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBzdGF0cy5zaXplKCk7IGkrKylcblx0XHRcdHtcblx0XHRcdFx0bGV0IG5vZGVTdGF0cyA9IHN0YXRzLmdldFNGU09iamVjdChpKTtcblxuXHRcdFx0XHQvLyBHZXQgbm9kZSBpZFxuXHRcdFx0XHRsZXQgaWQgPSBub2RlU3RhdHMuZ2V0VXRmU3RyaW5nKCdpZCcpO1xuXG5cdFx0XHRcdC8vIEdldCBjaGFydHMgaXRlbSBmb3Igbm9kZVxuXHRcdFx0XHRsZXQgaXRlbSA9IHRoaXMucXVlcnlTZWxlY3RvcignI2NsbS1ub2RlTWluaUNoYXJ0c0NvbnRhaW5lciAjbm9kZV8nICsgaWQpO1xuXG5cdFx0XHRcdGlmIChpdGVtKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0aXRlbS5hZGRDaGFydEVudHJpZXMoJ2NjdScsIG5vZGVTdGF0cy5nZXRTRlNPYmplY3QoJ2NjdScpLCBudWxsLCBpbnRlcnZhbE1pbGxpcyk7XG5cdFx0XHRcdFx0aXRlbS5hZGRDaGFydEVudHJpZXMoJ2NwdScsIG5vZGVTdGF0cy5nZXRTRlNPYmplY3QoJ2NwdScpLCBudWxsLCBpbnRlcnZhbE1pbGxpcyk7XG5cdFx0XHRcdFx0aXRlbS5hZGRDaGFydEVudHJpZXMoJ21lbScsIG5vZGVTdGF0cy5nZXRTRlNPYmplY3QoJ21lbScpLCBudWxsLCBpbnRlcnZhbE1pbGxpcyk7XG5cdFx0XHRcdFx0aXRlbS5hZGRDaGFydEVudHJpZXMoJ3RoZCcsIG5vZGVTdGF0cy5nZXRTRlNPYmplY3QoJ3RoZCcpLCBudWxsLCBpbnRlcnZhbE1pbGxpcyk7XG5cdFx0XHRcdFx0aXRlbS5hZGRDaGFydEVudHJpZXMoJ25ldCcsIG5vZGVTdGF0cy5nZXRTRlNPYmplY3QoJ25ldE91dCcpLCBub2RlU3RhdHMuZ2V0U0ZTT2JqZWN0KCduZXRJbicpLCBpbnRlcnZhbE1pbGxpcyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRlbHNlIGlmIChjb21tYW5kID09IHRoaXMuUkVTUF9DSEFSVF9EQVRBKVxuXHRcdHtcblx0XHRcdGxldCBjaGFydERhdGEgPSBkYXRhLmdldFNGU09iamVjdCgnY2hhcnQnKTtcblx0XHRcdGxldCBpID0gdGhpcy5fY2hhcnRSYW5nZURELnZhbHVlKCk7XG5cdFx0XHRsZXQgaW50ZXJ2YWxNaWxsaXMgPSB0aGlzLmludGVydmFsc1tpXS5taW51dGVzICogNjAgKiAxMDAwO1xuXG5cdFx0XHQvLyBHZXQgbm9kZSBpZCBhbmQgY2hhcnQgdHlwZVxuXHRcdFx0bGV0IGlkID0gY2hhcnREYXRhLmdldFV0ZlN0cmluZygnaWQnKTtcblx0XHRcdGxldCB0eXBlID0gY2hhcnREYXRhLmdldFV0ZlN0cmluZygndHlwZScpO1xuXG5cdFx0XHRpZiAodGhpcy5fY2hhcnRJbmZvICYmIHRoaXMuX2NoYXJ0SW5mby5pZCA9PSBpZCAmJiB0aGlzLl9jaGFydEluZm8udHlwZSA9PSB0eXBlKVxuXHRcdFx0e1xuXHRcdFx0XHRzd2l0Y2ggKHR5cGUpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRjYXNlICduZXQnOlxuXHRcdFx0XHRcdFx0dGhpcy5fYWRkRGV0YWlsQ2hhcnRFbnRyaWVzKGNoYXJ0RGF0YS5nZXRTRlNPYmplY3QoJ25ldE91dCcpLCBjaGFydERhdGEuZ2V0U0ZTT2JqZWN0KCduZXRJbicpLCBpbnRlcnZhbE1pbGxpcyk7XG5cdFx0XHRcdFx0XHRicmVhaztcblxuXHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHR0aGlzLl9hZGREZXRhaWxDaGFydEVudHJpZXMoY2hhcnREYXRhLmdldFNGU09iamVjdCh0eXBlKSwgbnVsbCwgaW50ZXJ2YWxNaWxsaXMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0ZWxzZSBpZiAoY29tbWFuZCA9PSB0aGlzLlJFU1BfTE9HX01FU1NBR0VTKVxuXHRcdHtcblx0XHRcdGxldCBsb2dFbnRyaWVzID0gZGF0YS5nZXRTRlNBcnJheSgnZW50cmllcycpO1xuXHRcdFx0XG5cdFx0XHRmb3IgKGxldCBlID0gMDsgZSA8IGxvZ0VudHJpZXMuc2l6ZSgpOyBlKyspXG5cdFx0XHR7XG5cdFx0XHRcdGxldCBsb2dFbnRyeSA9IGxvZ0VudHJpZXMuZ2V0U0ZTT2JqZWN0KGUpO1xuXG5cdFx0XHRcdGxldCBlbGUgPSB7XG5cdFx0XHRcdFx0dGltZXN0YW1wOiBrZW5kby50b1N0cmluZyhuZXcgRGF0ZShsb2dFbnRyeS5nZXRMb25nKCd0aW1lJykpLCAnZGQvTU0veXl5eSBISDptbTpzcycpLFxuXHRcdFx0XHRcdGxldmVsOiBsb2dFbnRyeS5nZXRVdGZTdHJpbmcoJ2xldmVsJyksXG5cdFx0XHRcdFx0bWVzc2FnZTogbG9nRW50cnkuZ2V0VXRmU3RyaW5nKCdtc2cnKSxcblx0XHRcdFx0fTtcblxuXHRcdFx0XHRsZXQgZHMgPSB0aGlzLl9sb2dHcmlkLmRhdGFTb3VyY2U7XG5cdFx0XHRcdGRzLmFkZChlbGUpO1xuXG5cdFx0XHRcdC8vIENoZWNrIGl0ZW1zIGxpbWl0XG5cdFx0XHRcdHdoaWxlIChkcy50b3RhbCgpID4gdGhpcy5NQVhfTE9HX1NJWkUpXG5cdFx0XHRcdFx0ZHMucmVtb3ZlKGRzLmF0KDApKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRvblVwdGltZVVwZGF0ZWQodmFsdWVzKVxuXHR7XG5cdFx0dGhpcy5fdXB0aW1lU2VjcyA9IHZhbHVlc1szXTtcblx0XHR0aGlzLl91cHRpbWVTZWNzICs9ICh2YWx1ZXNbMl0gKiA2MCk7XG5cdFx0dGhpcy5fdXB0aW1lU2VjcyArPSAodmFsdWVzWzFdICogNjAgKiA2MCk7XG5cblx0XHQkKCcjY2xtLXVwdGltZURheXMnKS50ZXh0KCAodmFsdWVzWzBdIDw9IDkgPyAnMDAnIDogKHZhbHVlc1swXSA8PSA5OSA/ICcwJyA6ICcnKSkgKyB2YWx1ZXNbMF0gKTtcblx0XHQkKCcjY2xtLXVwdGltZUhvdXJzJykudGV4dCggKHZhbHVlc1sxXSA8PSA5ID8gJzAnIDogJycpICsgdmFsdWVzWzFdICk7XG5cdFx0JCgnI2NsbS11cHRpbWVNaW51dGVzJykudGV4dCggKHZhbHVlc1syXSA8PSA5ID8gJzAnIDogJycpICsgdmFsdWVzWzJdICk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBVSSBFVkVOVCBMSVNURU5FUlNcblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRfb25Ob2Rlc0dyaWRDaGFuZ2UoZSwgYXJncylcblx0e1xuXHRcdGxldCBncmlkID0gZS5zZW5kZXI7XG5cdFx0bGV0IGl0ZW1zID0gZ3JpZC5pdGVtcygpO1xuXG5cdFx0dGhpcy5fc2VsZWN0ZWROb2RlcyA9IFtdO1xuXHRcdHRoaXMuX3NlbGVjdGVkQWN0aXZlTm9kZXMgPSBbXTtcblxuXHRcdGZvciAobGV0IGkgb2YgZ3JpZC5zZWxlY3QoKSlcblx0XHR7XG5cdFx0XHRsZXQgZGF0YUl0ZW0gPSBncmlkLmRhdGFJdGVtKGkpO1xuXHRcdFx0dGhpcy5fc2VsZWN0ZWROb2Rlcy5wdXNoKGRhdGFJdGVtWydpZCddKTtcblxuXHRcdFx0aWYgKGRhdGFJdGVtWydhY3RpdmUnXSlcblx0XHRcdFx0dGhpcy5fc2VsZWN0ZWRBY3RpdmVOb2Rlcy5wdXNoKGRhdGFJdGVtWydpZCddKTtcblx0XHR9XG5cblx0XHQvLyBDb21wYXJlIHRoZSBsaXN0IG9mIHNlbGVjdGVkIG5vZGVzIHdpdGggdGhlIGxpc3Qgb2YgdmlzaWJsZVxuXHRcdC8vIGNoYXJ0IHJvd3MsIHRvIHNob3cvaGlkZSB0aGUgc2VsZWN0ZWQvZGVzZWxlY3RlZCBvbmVzXG5cdFx0dGhpcy5fdXBkYXRlQ2hhcnRlZE5vZGVzKCk7XG5cblx0XHQvLyBFbmFibGUvZGlzYWJsZSBidXR0b24gdG8gZGVhY3RpdmF0ZSBzZWxlY3RlZCBhY3RpdmUgbm9kZXNcblx0XHR0aGlzLl91cGRhdGVEZWFjdGl2YXRlQnV0dG9uKCk7XG5cdH1cblxuXHRfb25Ob2Rlc0dyaWREYXRhQm91bmQoZSlcblx0e1xuXHRcdGxldCBncmlkID0gZS5zZW5kZXI7XG5cdFx0bGV0IGl0ZW1zID0gZ3JpZC5pdGVtcygpO1xuXHRcdGxldCBpdGVtc1RvU2VsZWN0ID0gW107XG5cdFx0bGV0IHNlbGYgPSB0aGlzO1xuXG5cdFx0aXRlbXMuZWFjaChmdW5jdGlvbiAoaWR4LCByb3cpIHtcblx0XHRcdGxldCBkYXRhSXRlbSA9IGdyaWQuZGF0YUl0ZW0ocm93KTtcblx0XHRcdGlmIChzZWxmLl9zZWxlY3RlZE5vZGVzLmluY2x1ZGVzKGRhdGFJdGVtWydpZCddKSkge1xuXHRcdFx0IFx0aXRlbXNUb1NlbGVjdC5wdXNoKHJvdyk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRlLnNlbmRlci5zZWxlY3QoaXRlbXNUb1NlbGVjdCk7XG5cblx0XHQvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cblx0XHQvLyBIaWRlIGdyb3VwIGNvbHVtbiBhbmQgY29sbGFwc2UgaWNvblxuXHRcdCQoJyNjbG0tbm9kZXNMaXN0IC5rLWdyb3VwLWNvbCwgI2NsbS1ub2Rlc0xpc3QgLmstZ3JvdXAtY2VsbCcpLnJlbW92ZSgpO1xuXHRcdGxldCBzcGFuQ2VsbHMgPSAkKCcjY2xtLW5vZGVzTGlzdCAuay1ncm91cGluZy1yb3cnKS5jaGlsZHJlbigndGQnKTtcblx0XHRzcGFuQ2VsbHMuYXR0cignY29sc3BhbicsIHNwYW5DZWxscy5hdHRyKCdjb2xzcGFuJykgLSAxKTtcblx0XHQkKCcjY2xtLW5vZGVzTGlzdCAuay1pY29uLmstaS1jb2xsYXBzZScpLmhpZGUoKTtcblxuXHRcdC8vIE1vZGlmeSBncm91cCBsYWJlbFxuXHRcdCQoJyNjbG0tbm9kZXNMaXN0IC5rLWdyb3VwaW5nLXJvdyB0ZCBwLmstcmVzZXQnKS5lYWNoKGZ1bmN0aW9uKCBpbmRleCApIHtcblx0XHRcdGlmICgkKHRoaXMpLnRleHQoKSA9PSAnYWN0aXZlOiB0cnVlJylcblx0XHRcdFx0JCh0aGlzKS50ZXh0KCdBY3RpdmUgbm9kZXMnKTtcblx0XHRcdGVsc2Vcblx0XHRcdFx0JCh0aGlzKS50ZXh0KCdJbmFjdGl2ZSBub2RlcycpO1xuXHRcdH0pO1xuXHR9XG5cblx0X29uTWFpblJhbmdlQ2hhbmdlKGUpXG5cdHtcblx0XHQvLyBSZXF1ZXN0IG5vZGVzIGRhdGEgdG8gc2VydmVyXG5cdFx0dGhpcy5fcmVxdWVzdE5vZGVzRGF0YSgpO1xuXHR9XG5cblx0X29uQ2hhcnRSYW5nZUNoYW5nZShlKVxuXHR7XG5cdFx0Ly8gUmVxdWVzdCBkZXRhaWwgY2hhcnQgZGF0YSB0byBzZXJ2ZXJcblx0XHR0aGlzLl9yZXF1ZXN0RGV0YWlsQ2hhcnREYXRhKCk7XG5cdH1cblxuXHRfb25SZXF1ZXN0RGF0YUludGVydmFsKClcblx0e1xuXHRcdC8vIFJlcXVlc3Qgc2VsZWN0ZWQgbm9kZXMgZGF0YVxuXHRcdHRoaXMuX3JlcXVlc3ROb2Rlc0RhdGEoKTtcblxuXHRcdC8vIFJlcXVlc3QgZGV0YWlsIGNoYXJ0IGRhdGFcblx0XHR0aGlzLl9yZXF1ZXN0RGV0YWlsQ2hhcnREYXRhKCk7XG5cdH1cblxuXHRfcmVxdWVzdE5vZGVzTGlzdCgpXG5cdHtcblx0XHQvLyBDbGVhciBwcmV2aW91cyByZXF1ZXN0IHNjaGVkdWxpbmdcblx0XHRjbGVhclRpbWVvdXQodGhpcy5fcmVxdWVzdE5vZGVzVGltZXIpO1xuXG5cdFx0Ly8gQ2hlY2sgaWYgY29ubmVjdGlvbiBpcyBzdGlsbCBhdmFpbGFibGVcblx0XHRpZiAodGhpcy5zbWFydEZveC5pc0Nvbm5lY3RlZClcblx0XHR7XG5cdFx0XHQvLyBTZW5kIHJlcXVlc3QgdG8gZXh0ZW5zaW9uXG5cdFx0XHR0aGlzLnNlbmRFeHRlbnNpb25SZXF1ZXN0KHRoaXMuUkVRX0dFVF9OT0RFUyk7XG5cblx0XHRcdC8vIFNjaGVkdWxlIG5leHQgcmVxdWVzdFxuXHRcdFx0dGhpcy5fcmVxdWVzdE5vZGVzVGltZXIgPSBzZXRUaW1lb3V0KCQucHJveHkodGhpcy5fcmVxdWVzdE5vZGVzTGlzdCwgdGhpcyksIDUwMDApOyAvLyBFdmVyeSA1IHNlY29uZHNcblx0XHR9XG5cdH1cblxuXHRfb25NaW5pQ2hhcnRDbGljayhlKVxuXHR7XG5cdFx0bGV0IG5vZGVJZCA9IGUuZGV0YWlsLm5vZGU7XG5cdFx0bGV0IG5vZGVEYXRhSXRlbSA9IHRoaXMuX2dyaWQuZGF0YVNvdXJjZS5nZXQobm9kZUlkKTtcblx0XHRsZXQgY2hhcnRUeXBlID0gZS5kZXRhaWwudHlwZTtcblx0XHRsZXQgY2hhcnRPcHRpb25zID0gZS5kZXRhaWwub3B0aW9ucztcblxuXHRcdC8vIFNhdmUgcmVmIHRvIGNoYXJ0ZWQgbm9kZVxuXHRcdHRoaXMuX2NoYXJ0SW5mbyA9IHtcblx0XHRcdGlkOiBub2RlSWQsXG5cdFx0XHR0eXBlOiBjaGFydFR5cGVcblx0XHR9O1xuXG5cdFx0Ly8gRXh0cmFjdCBjaGFydCB0aXRsZSBmcm9tIG9wdGlvbnNcblx0XHQkKCcjY2xtLWNoYXJ0TW9kYWxUaXRsZScpLnRleHQoY2hhcnRPcHRpb25zLnRpdGxlLnRleHQpO1xuXG5cdFx0aWYgKG5vZGVEYXRhSXRlbS5hbGlhcylcblx0XHR7XG5cdFx0XHQkKCcjY2xtLWNoYXJ0Tm9kZUFsaWFzJykudGV4dChub2RlRGF0YUl0ZW0uYWxpYXMpO1xuXHRcdFx0JCgnI2NsbS1jaGFydE5vZGVOYW1lJykudGV4dChub2RlRGF0YUl0ZW0ubmFtZSk7XG5cdFx0fVxuXHRcdGVsc2Vcblx0XHR7XG5cdFx0XHQkKCcjY2xtLWNoYXJ0Tm9kZUFsaWFzJykudGV4dChub2RlRGF0YUl0ZW0ubmFtZSk7XG5cdFx0XHQkKCcjY2xtLWNoYXJ0Tm9kZU5hbWUnKS5oaWRlKCk7XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHNlY29uZGFyeSByYW5nZSBkcm9wZG93biB0byBtYWluIHJhbmdlIHZhbHVlXG5cdFx0bGV0IGluZGV4ID0gdGhpcy5fbWFpblJhbmdlREQuc2VsZWN0KCk7XG5cdFx0dGhpcy5fY2hhcnRSYW5nZURELnNlbGVjdChpbmRleCk7XG5cblx0XHQvLyBDcmVhdGUgY2hhcnQgdGFnXG5cdFx0JCgnI2NsbS1ub2RlRGV0YWlsQ2hhcnRDb250YWluZXInKS5hcHBlbmQoJCgnPGRpdj4nLCB7J2NsYXNzJzogJ2NoYXJ0J30pKVxuXG5cdFx0Ly8gSW5pdGlhbGl6ZSBjaGFydFxuXHRcdHRoaXMuX2dldENoYXJ0VGFnKCkua2VuZG9DaGFydCh7XG5cdFx0XHR0cmFuc2l0aW9uczogZmFsc2UsXG5cdFx0XHRjaGFydEFyZWE6IHtcblx0XHRcdFx0YmFja2dyb3VuZDogJ3RyYW5zcGFyZW50Jyxcblx0XHRcdFx0bWFyZ2luOiAwLFxuXHRcdFx0ICAgIHBhZGRpbmc6MFxuXHRcdFx0fSxcblx0ICAgICAgICBsZWdlbmQ6IHtcblx0ICAgICAgICAgICAgdmlzaWJsZTogZmFsc2Vcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgc2VyaWVzRGVmYXVsdHM6IHtcblx0ICAgICAgICAgICAgdHlwZTogJ3NjYXR0ZXJMaW5lJyxcblx0ICAgICAgICAgICAgbGFiZWxzOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZSxcblx0ICAgICAgICAgICAgICAgIGZvcm1hdDogJ3swfScsXG5cdCAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiAndHJhbnNwYXJlbnQnXG5cdCAgICAgICAgICAgIH0sXG5cdFx0XHRcdG1pc3NpbmdWYWx1ZXM6ICdnYXAnLFxuXHRcdFx0XHRtYXJrZXJzOiB7XG5cdFx0XHQgICAgICB2aXNpYmxlOiB0cnVlLFxuXHRcdFx0XHQgIHR5cGU6ICdjaXJjbGUnLFxuXHRcdFx0XHQgIHNpemU6IDMsXG5cdFx0XHQgICAgfSxcblx0ICAgICAgICB9LFxuXHQgICAgICAgIHNlcmllczogY2hhcnRPcHRpb25zLnNlcmllcyxcblx0ICAgICAgICB5QXhpczogY2hhcnRPcHRpb25zLnlBeGlzLFxuXHQgICAgICAgIHhBeGlzOiB7XG5cdFx0XHRcdG1ham9yR3JpZExpbmVzOiB7XG5cdCAgICAgICAgICAgICAgICB2aXNpYmxlOiBmYWxzZVxuXHQgICAgICAgICAgICB9LFxuXHRcdFx0XHRtYWpvclRpY2tzOiB7XG5cdFx0XHRcdFx0dmlzaWJsZTogdHJ1ZVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRsYWJlbHM6IHtcblx0XHRcdFx0XHR2aXNpYmxlOiB0cnVlLFxuXHRcdFx0XHRcdHJvdGF0aW9uOiAwLFxuXHRcdFx0XHRcdHRlbXBsYXRlOiAnIzoga2VuZG8udG9TdHJpbmcobmV3IERhdGUodmFsdWUpLCBcIkhIOm1tXCIpICMnXG5cdFx0XHRcdH0sXG5cdCAgICAgICAgfSxcblx0XHRcdHRvb2x0aXA6IGNoYXJ0T3B0aW9ucy50b29sdGlwXG5cdCAgICB9KS5kYXRhKCdrZW5kb0NoYXJ0Jyk7XG5cblx0XHQvLyBDbGVhciBjaGFydFxuXHRcdHRoaXMuX2dldENoYXJ0V2lkZ2V0KCkuc2V0RGF0YVNvdXJjZShudWxsKTtcblxuXHRcdC8vIERpc3BsYXkgY2hhcnQgbW9kYWxcblx0XHQkKCcjY2xtLWNoYXJ0TW9kYWwnKS5tb2RhbCgnc2hvdycpO1xuXG5cdFx0Ly8gUmVxdWVzdCBkZXRhaWwgY2hhcnQgZGF0YSB0byBzZXJ2ZXJcblx0XHR0aGlzLl9yZXF1ZXN0RGV0YWlsQ2hhcnREYXRhKCk7XG5cdH1cblxuXHRfb25DaGFydE1vZGFsSGlkZGVuKGUpXG5cdHtcblx0XHQvLyBEZXN0cm95IGNoYXJ0XG5cdFx0dGhpcy5fY2hhcnRJbmZvID0gbnVsbDtcblxuXHRcdCQoJyNjbG0tY2hhcnRNb2RhbFRpdGxlJykudGV4dCgnJyk7XG5cdFx0JCgnI2NsbS1jaGFydE5vZGVBbGlhcycpLnRleHQoJycpO1xuXHRcdCQoJyNjbG0tY2hhcnROb2RlTmFtZScpLnRleHQoJycpO1xuXG5cdFx0dGhpcy5fZ2V0Q2hhcnRXaWRnZXQoKS5kZXN0cm95KCk7XG5cdFx0dGhpcy5fZ2V0Q2hhcnRUYWcoKS5yZW1vdmUoKTtcblx0fVxuXG5cdF9yZXF1ZXN0T3JjaGVzdHJhdGlvbkxvZ3MoKVxuXHR7XG5cdFx0Ly8gQnVpbGQgcmVxdWVzdCBwYXJhbWV0ZXJzXG5cdFx0bGV0IHBhcmFtcyA9IG5ldyBTRlMyWC5TRlNPYmplY3QoKTtcblx0XHRwYXJhbXMucHV0TG9uZygndHMnLCB0aGlzLl9sYXN0TG9nc1JlcVRpbWVzdGFtcCk7XG5cblx0XHQvLyBTZW5kIHJlcXVlc3QgdG8gZXh0ZW5zaW9uXG5cdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9HRVRfTE9HX01FU1NBR0VTLCBwYXJhbXMpO1xuXG5cdFx0Ly8gVXBkYXRlIGxhc3QgcmVxdWVzdCB0aW1lXG5cdFx0dGhpcy5fbGFzdExvZ3NSZXFUaW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8gUFJJVkFURSBNRVRIT0RTXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0X3VwZGF0ZUNoYXJ0ZWROb2RlcygpXG5cdHtcblx0XHQvLyBHZXQgc2VsZWN0ZWQgbm9kZXMgbm90IHlldCBzaG93biBpbiB0aGUgY2hhcnQgYXJlYVxuXHRcdGxldCB0b1Nob3cgPSB0aGlzLl9zZWxlY3RlZE5vZGVzLmZpbHRlcih4ID0+ICF0aGlzLl9jaGFydGVkTm9kZXMuaW5jbHVkZXMoeCkpO1xuXG5cdFx0Ly8gR2V0IG5vZGVzIHNob3duIGluIHRoZSBjaGFydCBhcmVhIG5vdCBpbiB0aGUgc2VsZWN0ZWQgbGlzdCBhbnltb3JlXG5cdFx0bGV0IHRvSGlkZSA9IHRoaXMuX2NoYXJ0ZWROb2Rlcy5maWx0ZXIoeCA9PiAhdGhpcy5fc2VsZWN0ZWROb2Rlcy5pbmNsdWRlcyh4KSk7XG5cblx0XHQvLyBTaG93IG5vZGVzIGNoYXJ0c1xuXHRcdGlmICh0b1Nob3cubGVuZ3RoID4gMClcblx0XHR7XG5cdFx0XHQvL2NvbnNvbGUubG9nKFwiU0hPV0lORyBDSEFSVFMgT0YgTk9ERVM6IFwiICsgdG9TaG93KVxuXHRcdFx0dGhpcy5fY2hhcnRlZE5vZGVzID0gWy4uLnRoaXMuX2NoYXJ0ZWROb2RlcywgLi4udG9TaG93XTsgLy8gTWVyZ2UgYXJyYXlzXG5cblx0XHRcdC8vIERpc3BsYXkgbm9kZSBjaGFydHNcblx0XHRcdGZvciAobGV0IGlkIG9mIHRvU2hvdylcblx0XHRcdFx0dGhpcy5fZGlzcGxheU5vZGVDaGFydHNJdGVtKGlkKTtcblx0XHR9XG5cblx0XHQvLyBIaWRlIG5vZGVzIGNoYXJ0c1xuXHRcdGlmICh0b0hpZGUubGVuZ3RoID4gMClcblx0XHR7XG5cdFx0XHQvL2NvbnNvbGUubG9nKFwiSElESU5HIENIQVJUUyBPRiBOT0RFUzogXCIgKyB0b0hpZGUpXG5cdFx0XHR0aGlzLl9jaGFydGVkTm9kZXMgPSB0aGlzLl9jaGFydGVkTm9kZXMuZmlsdGVyKHggPT4gIXRvSGlkZS5pbmNsdWRlcyh4KSk7XG5cblx0XHRcdC8vIFJlbW92ZSBub2RlIGNoYXJ0c1xuXHRcdFx0Zm9yIChsZXQgaWQgb2YgdG9IaWRlKVxuXHRcdFx0e1xuXHRcdFx0XHR0aGlzLl9yZW1vdmVOb2RlQ2hhcnRzSXRlbShpZCk7XG5cblx0XHRcdFx0Ly8gUmVtb3ZlIGRldGFpbCBjaGFydCBpZiB2aXNpYmxlXG5cdFx0XHRcdGlmICh0aGlzLl9jaGFydEluZm8gJiYgaWQgPT0gdGhpcy5fY2hhcnRJbmZvLmlkKVxuXHRcdFx0XHRcdCQoJyNjbG0tY2hhcnRNb2RhbCcpLm1vZGFsKCdoaWRlJyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU2hvdy9oaWRlIGludGVydmFsIGRyb3Bkb3duXG5cdFx0aWYgKHRvU2hvdy5sZW5ndGggPiAwIHx8IHRvSGlkZS5sZW5ndGggPiAwKVxuXHRcdHtcblx0XHRcdGlmICh0aGlzLl9jaGFydGVkTm9kZXMubGVuZ3RoID4gMClcblx0XHRcdFx0JCgnI2NsbS1tYWluUmFuZ2VDb250YWluZXInKS5zaG93KCk7XG5cdFx0XHRlbHNlXG5cdFx0XHRcdCQoJyNjbG0tbWFpblJhbmdlQ29udGFpbmVyJykuaGlkZSgpO1xuXHRcdH1cblxuXHRcdC8vIFJlcXVlc3QgY2hhcnRzIGRhdGEgZm9yIG5ld2x5IHNlbGVjdGVkIG5vZGVzXG5cdFx0Ly8gTk9URTogd2UgaGF2ZSB0byB1c2UgYSB0aW1lb3V0IGFzIGEgd29ya2Fyb3VuZCB0byBnaXZlIGNoYXJ0cyB0aW1lIHRvIGJlIHJlbmRlcmVkIGJlZm9yZSBkcmF3aW5nIHRoZW0sIG9yIHRoZXkgd2lsbCBleGNlZWQgdGhlaXIgY29udGFpbmVyJ3Mgd2lkdGhcblx0XHRpZiAodG9TaG93Lmxlbmd0aCA+IDApXG5cdFx0XHRzZXRUaW1lb3V0KCQucHJveHkodGhpcy5fcmVxdWVzdE5vZGVzRGF0YSwgdGhpcyksIDIwLCB0b1Nob3cpO1xuXHR9XG5cblx0X2dldFRpbWVTaW5jZUpvaW5UZW1wbGF0ZShkYXRhSXRlbSlcblx0e1xuXHRcdGxldCBub3cgPSBtb21lbnQoKTtcblx0XHRsZXQgam9pblRpbWUgPSBtb21lbnQoZGF0YUl0ZW1bJ2pvaW5UaW1lJ10pO1xuXG5cdFx0bGV0IGRpZmZEYXlzID0gbm93LmRpZmYoam9pblRpbWUsICdkYXlzJyk7XG5cdFx0bGV0IGRpZmZIb3VycyA9IG5vdy5kaWZmKGpvaW5UaW1lLCAnaG91cnMnKSAtIChkaWZmRGF5cyAqIDI0KTtcblx0XHRsZXQgZGlmZk1pbnV0ZXMgPSBub3cuZGlmZihqb2luVGltZSwgJ21pbnV0ZXMnKSAtICgoKGRpZmZEYXlzICogMjQpICsgZGlmZkhvdXJzKSAqIDYwKTtcblxuXHRcdHJldHVybiBgPHNwYW4+JHtkaWZmRGF5c31kICR7ZGlmZkhvdXJzfWggJHtkaWZmTWludXRlc31tPHNwYW4+YDtcblx0fVxuXG5cdF9nZXRIZWFsdGhUZW1wbGF0ZShkYXRhSXRlbSlcblx0e1xuXHRcdGxldCBzdHlsZSA9ICd0ZXh0LXN1Y2Nlc3MnO1xuXG5cdFx0aWYgKCFkYXRhSXRlbVsnaGVhbHRoJ10pXG5cdFx0XHRzdHlsZSA9ICd0ZXh0LWRhbmdlcic7XG5cblx0XHRyZXR1cm4gYDxzcGFuIGNsYXNzPVwiJHtzdHlsZX1cIj48aSBjbGFzcz1cImZhcyBmYS1jaXJjbGVcIj48L2k+PC9zcGFuPmA7XG5cdH1cblxuXHRfZ2V0UmVjeWNsYWJsZVRlbXBsYXRlKGRhdGFJdGVtKVxuXHR7XG5cdFx0bGV0IHN0eWxlID0gZGF0YUl0ZW1bJ3JlY3ljbGFibGUnXSA/ICd0ZXh0LXN1Y2Nlc3MnIDogJ3RleHQtbGlnaHQnO1xuXHRcdHJldHVybiBgPHNwYW4gY2xhc3M9XCIke3N0eWxlfVwiPjxpIGNsYXNzPVwiZmFzIGZhLWNpcmNsZVwiPjwvaT48L3NwYW4+YDtcblx0fVxuXG5cdF9nZXRUZXJtaW5hYmxlVGVtcGxhdGUoZGF0YUl0ZW0pXG5cdHtcblx0XHRsZXQgc3R5bGUgPSBkYXRhSXRlbVsndGVybWluYWJsZSddID8gJ3RleHQtc3VjY2VzcycgOiAndGV4dC1saWdodCc7XG5cdFx0cmV0dXJuIGA8c3BhbiBjbGFzcz1cIiR7c3R5bGV9XCI+PGkgY2xhc3M9XCJmYXMgZmEtY2lyY2xlXCI+PC9pPjwvc3Bhbj5gO1xuXHR9XG5cblx0X3Nob3dMb2JieVN0YXRlKGlzQWN0aXZlKVxuXHR7XG5cdFx0aWYgKGlzQWN0aXZlKVxuXHRcdHtcblx0XHRcdCQoJyNjbG0tbG9iYnlTdGF0ZSAuYWN0aXZlJykuc2hvdygpO1xuXHRcdFx0JCgnI2NsbS1sb2JieVN0YXRlIC5pbmFjdGl2ZScpLmhpZGUoKTtcblx0XHR9XG5cdFx0ZWxzZVxuXHRcdHtcblx0XHRcdCQoJyNjbG0tbG9iYnlTdGF0ZSAuYWN0aXZlJykuaGlkZSgpO1xuXHRcdFx0JCgnI2NsbS1sb2JieVN0YXRlIC5pbmFjdGl2ZScpLnNob3coKTtcblx0XHR9XG5cblx0XHQkKCcjY2xtLWxvYmJ5U3RhdGUnKS5zaG93KCk7XG5cblx0XHQvLyBFbmFibGUvZGlzYWJsZSBzY2FsZS11cCBidXR0b25cblx0XHQkKCcjY2xtLXNjYWxlVXBCdCcpLnByb3AoJ2Rpc2FibGVkJywgIWlzQWN0aXZlKTtcblx0fVxuXG5cdF9yZXF1ZXN0Tm9kZXNEYXRhKG5vZGVzID0gbnVsbClcblx0e1xuXHRcdGlmIChub2RlcyA9PSBudWxsKVxuXHRcdFx0bm9kZXMgPSB0aGlzLl9jaGFydGVkTm9kZXM7XG5cblx0XHQvL2NvbnNvbGUubG9nKFwiUkVRVUVTVElORyBEQVRBIEZPUiBOT0RFUyBcIiArIG5vZGVzICsgXCIgKGxhc3QgXCIgKyB0aGlzLmludGVydmFsc1t0aGlzLl9tYWluUmFuZ2VERC52YWx1ZSgpXS5taW51dGVzICsgXCIgbWludXRlcylcIilcblxuXHRcdGlmIChub2Rlcy5sZW5ndGggPiAwICYmIHRoaXMuc21hcnRGb3guaXNDb25uZWN0ZWQpXG5cdFx0e1xuXHRcdFx0bGV0IGkgPSB0aGlzLl9tYWluUmFuZ2VERC52YWx1ZSgpO1xuXHRcdFx0bGV0IGludGVydmFsTWlsbGlzID0gdGhpcy5pbnRlcnZhbHNbaV0ubWludXRlcyAqIDYwICogMTAwMDtcblx0XHRcdGxldCBkYXRhUG9pbnRzID0gdGhpcy5pbnRlcnZhbHNbaV0ucG9pbnRzMTtcblxuXHRcdFx0Ly8gTGlzdCBub2Rlc1xuXHRcdFx0bGV0IGxpc3QgPSBuZXcgU0ZTMlguU0ZTQXJyYXkoKTtcblxuXHRcdFx0Zm9yIChsZXQgbm9kZUlkIG9mIG5vZGVzKVxuXHRcdFx0e1xuXHRcdFx0XHRsZXQgb2JqID0gbmV3IFNGUzJYLlNGU09iamVjdCgpO1xuXHRcdFx0XHRvYmoucHV0VXRmU3RyaW5nKCdpZCcsIG5vZGVJZCk7XG5cdFx0XHRcdG9iai5wdXRMb25nKCdpbnQnLCBpbnRlcnZhbE1pbGxpcyk7XG5cdFx0XHRcdG9iai5wdXRJbnQoJ3B0cycsIGRhdGFQb2ludHMpO1xuXG5cdFx0XHRcdGxpc3QuYWRkU0ZTT2JqZWN0KG9iaik7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEJ1aWxkIHJlcXVlc3QgcGFyYW1ldGVyc1xuXHRcdFx0bGV0IHBhcmFtcyA9IG5ldyBTRlMyWC5TRlNPYmplY3QoKTtcblx0XHRcdHBhcmFtcy5wdXRTRlNBcnJheSgnbm9kZXMnLCBsaXN0KTtcblxuXHRcdFx0Ly8gU2VuZCByZXF1ZXN0IHRvIEV4dGVuc2lvblxuXHRcdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9HRVRfTk9ERVNfREFUQSwgcGFyYW1zKTtcblx0XHR9XG5cdH1cblxuXHRfcmVxdWVzdERldGFpbENoYXJ0RGF0YSgpXG5cdHtcblx0XHRpZiAodGhpcy5fY2hhcnRJbmZvKVxuXHRcdHtcblx0XHRcdGxldCBpID0gdGhpcy5fY2hhcnRSYW5nZURELnZhbHVlKCk7XG5cblx0XHRcdGxldCBwYXJhbXMgPSBuZXcgU0ZTMlguU0ZTT2JqZWN0KCk7XG5cdFx0XHRwYXJhbXMucHV0VXRmU3RyaW5nKCdpZCcsIHRoaXMuX2NoYXJ0SW5mby5pZCk7XG5cdFx0XHRwYXJhbXMucHV0VXRmU3RyaW5nKCd0eXBlJywgdGhpcy5fY2hhcnRJbmZvLnR5cGUpO1xuXHRcdFx0cGFyYW1zLnB1dExvbmcoJ2ludCcsIHRoaXMuaW50ZXJ2YWxzW2ldLm1pbnV0ZXMgKiA2MCAqIDEwMDApO1xuXHRcdFx0cGFyYW1zLnB1dEludCgncHRzJywgdGhpcy5pbnRlcnZhbHNbaV0ucG9pbnRzMik7XG5cblx0XHRcdC8vIFNlbmQgcmVxdWVzdCB0byBFeHRlbnNpb25cblx0XHRcdHRoaXMuc2VuZEV4dGVuc2lvblJlcXVlc3QodGhpcy5SRVFfR0VUX0NIQVJUX0RBVEEsIHBhcmFtcyk7XG5cdFx0fVxuXHR9XG5cblx0X3JlbW92ZU5vZGVDaGFydHNJdGVtKG5vZGVJZClcblx0e1xuXHRcdGxldCBlbGVtZW50ID0gdGhpcy5xdWVyeVNlbGVjdG9yKCcjY2xtLW5vZGVNaW5pQ2hhcnRzQ29udGFpbmVyICNub2RlXycgKyBub2RlSWQpO1xuXG5cdFx0Ly8gRGVzdHJveSBlbGVtZW50XG5cdFx0ZWxlbWVudC5kZXN0cm95KCk7XG5cblx0XHQvLyBSZW1vdmUgZWxlbWVudCBmcm9tIGNvbnRhaW5lclxuXHRcdHRoaXMucXVlcnlTZWxlY3RvcignI2NsbS1ub2RlTWluaUNoYXJ0c0NvbnRhaW5lcicpLnJlbW92ZUNoaWxkKGVsZW1lbnQpO1xuXHR9XG5cblx0X2Rpc3BsYXlOb2RlQ2hhcnRzSXRlbShub2RlSWQpXG5cdHtcblx0XHRsZXQgbm9kZURhdGFJdGVtID0gdGhpcy5fZ3JpZC5kYXRhU291cmNlLmdldChub2RlSWQpO1xuXG5cdFx0Ly8gQ3JlYXRlIGVsZW1lbnRcblx0XHRsZXQgZWxlbWVudCA9IG5ldyBOb2RlTWluaUNoYXJ0cyhub2RlRGF0YUl0ZW1bJ2lkJ10sIG5vZGVEYXRhSXRlbVsnYWxpYXMnXSwgbm9kZURhdGFJdGVtWyduYW1lJ10pO1xuXG5cdFx0Ly8gQXBwZW5kIGVsZW1lbnQgdG8gY29udGFpbmVyXG5cdFx0dGhpcy5xdWVyeVNlbGVjdG9yKCcjY2xtLW5vZGVNaW5pQ2hhcnRzQ29udGFpbmVyJykuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cdH1cblxuXHRfZ2V0Q2hhcnRUYWcoKVxuXHR7XG5cdFx0cmV0dXJuICQoJyNjbG0tY2hhcnRNb2RhbCAuY2hhcnQnKTtcblx0fVxuXG5cdF9nZXRDaGFydFdpZGdldCgpXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5fZ2V0Q2hhcnRUYWcoKS5kYXRhKCdrZW5kb0NoYXJ0Jyk7XG5cdH1cblxuXHRfYWRkRGV0YWlsQ2hhcnRFbnRyaWVzKGRhdGEsIGRhdGExLCBpbnRlcnZhbE1pbGxpcylcblx0e1xuXHRcdGxldCBsYXN0VGltZXN0YW1wID0gZGF0YS5nZXRMb25nKCdsYXN0Jyk7XG5cdFx0bGV0IHZhbHVlcyA9IGRhdGEuZ2V0TG9uZ0FycmF5KCdkYXRhJyk7XG5cdFx0bGV0IHZhbHVlczEgPSAoZGF0YTEgIT0gbnVsbCA/IGRhdGExLmdldExvbmdBcnJheSgnZGF0YScpIDogbnVsbCk7XG5cdFx0bGV0IGNoYXJ0V2lkZ2V0ID0gdGhpcy5fZ2V0Q2hhcnRXaWRnZXQoKTtcblxuXHRcdC8vIERpdmlkZSBpbnRlcnZhbCBieSB0aGUgbnVtYmVyIG9mIGRhdGEgcG9pbnRzIHRvIGNhbGN1bGF0ZSB0aGVpciB0aW1lc3RhbXBzXG5cdFx0bGV0IHNsaWNlTWlsbGlzID0gTWF0aC5yb3VuZChpbnRlcnZhbE1pbGxpcyAvIHZhbHVlcy5sZW5ndGgpO1xuXG5cdFx0bGV0IGRzID0gbmV3IGtlbmRvLmRhdGEuRGF0YVNvdXJjZSgpO1xuXHRcdGxldCBmaXJzdFRpbWVzdGFtcCA9IGxhc3RUaW1lc3RhbXAgLSBpbnRlcnZhbE1pbGxpcztcblxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKVxuXHRcdHtcblx0XHRcdGxldCB0aW1lc3RhbXAgPSBmaXJzdFRpbWVzdGFtcCArIChzbGljZU1pbGxpcyAqIGkpO1xuXG5cdFx0XHRsZXQgdmFsdWUgPSB2YWx1ZXNbaV0gPCAwID8gbnVsbCA6IHZhbHVlc1tpXTtcblx0XHRcdGxldCB2YWx1ZTEgPSB2YWx1ZXMxID8gKHZhbHVlczFbaV0gPCAwID8gbnVsbCA6IHZhbHVlczFbaV0pIDogbnVsbDtcblxuXHRcdFx0bGV0IGVudHJ5ID0ge1xuXHRcdFx0XHR0czogdGltZXN0YW1wLFxuXHRcdFx0XHR2YWw6IHZhbHVlLFxuXHRcdFx0XHR2YWwxOiB2YWx1ZTEsXG5cdFx0XHR9O1xuXG5cdFx0XHRkcy5hZGQoZW50cnkpO1xuXHRcdH1cblxuXHRcdC8vIFNldCBjaGFydCdzIHgtYXhpcyBsaW1pdHNcblx0XHRjaGFydFdpZGdldC5vcHRpb25zLnhBeGlzLm1pbiA9IGZpcnN0VGltZXN0YW1wO1xuXHRcdGNoYXJ0V2lkZ2V0Lm9wdGlvbnMueEF4aXMubWF4ID0gbGFzdFRpbWVzdGFtcDtcblxuXHRcdGNoYXJ0V2lkZ2V0LnNldERhdGFTb3VyY2UoZHMpO1xuXHR9XG5cblx0X3VwZGF0ZURlYWN0aXZhdGVCdXR0b24oKVxuXHR7XG5cdFx0bGV0IGNudCA9IHRoaXMuX3NlbGVjdGVkQWN0aXZlTm9kZXMubGVuZ3RoO1xuXHRcdGxldCB0eHQgPSAoY250ID4gMCA/IGNudCA6ICcnKSArICcgbm9kZScgKyAoY250ICE9IDEgPyAncycgOiAnJyk7XG5cblx0XHQkKCcjY2xtLWRlYWN0aXZhdGVCdCcpLnByb3AoJ2Rpc2FibGVkJywgY250ID09IDApO1xuXHRcdCQoJyNjbG0tZGVhY3RpdmF0ZU5vZGVzTnVtJykudGV4dCh0eHQpO1xuXHR9XG5cblx0X29uRGVhY3RpdmF0ZUJ0Q2xpY2soKVxuXHR7XG5cdFx0dGhpcy5zaGVsbEN0cmwuc2hvd0NvbmZpcm1XYXJuaW5nKGBBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVhY3RpdmF0ZSB0aGUgc2VsZWN0ZWQgYWN0aXZlIG5vZGUke3RoaXMuX3NlbGVjdGVkQWN0aXZlTm9kZXMubGVuZ3RoID4gMSA/ICdzJyA6ICcnfT8gVGhpcyBvcGVyYXRpb24gaXMgaXJyZXZlcnNpYmxlLmAsICQucHJveHkodGhpcy5fb25EZWFjdGl2YXRlTm9kZXNDb25maXJtLCB0aGlzKSk7XG5cdH1cblxuXHRfb25EZWFjdGl2YXRlTm9kZXNDb25maXJtKClcblx0e1xuXHRcdGlmICh0aGlzLl9zZWxlY3RlZEFjdGl2ZU5vZGVzLmxlbmd0aCA+IDAgICYmIHRoaXMuc21hcnRGb3guaXNDb25uZWN0ZWQpXG5cdFx0e1xuXHRcdFx0bGV0IHBhcmFtcyA9IG5ldyBTRlMyWC5TRlNPYmplY3QoKTtcblx0XHRcdHBhcmFtcy5wdXRVdGZTdHJpbmdBcnJheSgnbm9kZXMnLCB0aGlzLl9zZWxlY3RlZEFjdGl2ZU5vZGVzKTtcblxuXHRcdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9ERUFDVElWQVRFX05PREVTLCBwYXJhbXMpO1xuXHRcdH1cblx0fVxuXG5cdF9vblNjYWxlVXBCdENsaWNrKClcblx0e1xuXHRcdC8vIERpc3BsYXkgc2NhbGUtdXAgbW9kYWxcblx0XHQkKCcjY2xtLXNjYWxlVXBNb2RhbCcpLm1vZGFsKCdzaG93Jyk7XG5cdH1cblxuXHRfb25TY2FsZVVwQ29uZmlybUJ0Q2xpY2soKVxuXHR7XG5cdFx0aWYgKHRoaXMuX3NjYWxlVXBWYWxpZGF0b3IudmFsaWRhdGUoKSlcblx0XHR7XG5cdFx0XHQvLyBSZXRyaWV2ZSBzY2FsZS11cCBkZXRhaWxzXG5cdFx0XHRsZXQgcGFyYW1zID0gbmV3IFNGUzJYLlNGU09iamVjdCgpO1xuXHRcdFx0cGFyYW1zLnB1dEludCgnbnVtJywgdGhpcy5fbnVtTm9kZXNJbi52YWx1ZSgpKTtcblxuXHRcdFx0Ly8gU2VuZCBzY2FsZS11cCByZXF1ZXN0IHRvIHNlcnZlclxuXHRcdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9TQ0FMRV9VUCwgcGFyYW1zKTtcblxuXHRcdFx0Ly8gSGlkZSBtb2RhbFxuXHRcdFx0JCgnI2NsbS1zY2FsZVVwTW9kYWwnKS5tb2RhbCgnaGlkZScpO1xuXHRcdH1cblx0fVxuXG5cdF9vblNjYWxlVXBNb2RhbEhpZGRlbihlKVxuXHR7XG5cdFx0Ly8gUmVzZXQgdmFsaWRhdG9yXG5cdFx0dGhpcy5fc2NhbGVVcFZhbGlkYXRvci5oaWRlTWVzc2FnZXMoKTtcblxuXHRcdC8vIFRoZSBtZXRob2QgYWJvdmUgZG9lc24ndCByZW1vdmUgdGhlIGstaW52YWxpZCBjbGFzc2VzIGFuZCBhcmlhLWludmFsaWQ9XCJ0cnVlXCIgYXR0cmlidXRlcyBmcm9tIGlucHV0c1xuXHRcdC8vIExldCdzIGRvIGl0IG1hbnVhbGx5XG5cdFx0JCgnI2NsbS1zY2FsZVVwRm9ybSAuay1pbnZhbGlkJykucmVtb3ZlQ2xhc3MoJ2staW52YWxpZCcpO1xuXHRcdCQoJyNjbG0tc2NhbGVVcEZvcm0gW2FyaWEtaW52YWxpZD1cInRydWVcIl0nKS5yZW1vdmVBdHRyKCdhcmlhLWludmFsaWQnKTtcblxuXHRcdC8vIFJlc2V0IHNjYWxlLXVwIGZvcm1cblx0XHR0aGlzLl9udW1Ob2Rlc0luLnZhbHVlKDEpO1xuXHR9XG5cblxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vIFBSSVZBVEUgR0VUVEVSU1xuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQzFKQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FDM2ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7OztBIiwic291cmNlUm9vdCI6IiJ9
|