rubyfox-server 2.17.3.2 → 2.19.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rubyfox/server/data/config/admin/descriptors/config_room.txt +10 -1
  3. data/lib/rubyfox/server/data/config/admin/descriptors/config_server.txt +90 -20
  4. data/lib/rubyfox/server/data/config/admin/descriptors/config_zone.txt +9 -0
  5. data/lib/rubyfox/server/data/config/admin/descriptors/runtime_room.txt +11 -0
  6. data/lib/rubyfox/server/data/config/admin/descriptors/runtime_user.txt +3 -3
  7. data/lib/rubyfox/server/data/config/core.xml +4 -4
  8. data/lib/rubyfox/server/data/config/default.words.txt +11 -0
  9. data/lib/rubyfox/server/data/config/log4j.properties +1 -2
  10. data/lib/rubyfox/server/data/config/server.xml +1 -1
  11. data/lib/rubyfox/server/data/data/GeoLite2-Country.mmdb +0 -0
  12. data/lib/rubyfox/server/data/data/bannedusers/users.bin +0 -0
  13. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/bootstrap.jar +0 -0
  14. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/catalina-tasks.xml +39 -39
  15. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/catalina.sh +0 -0
  16. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/ciphers.sh +0 -0
  17. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/commons-daemon-native.tar.gz +0 -0
  18. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/commons-daemon.jar +0 -0
  19. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/configtest.sh +0 -0
  20. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/daemon.sh +0 -0
  21. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/digest.sh +0 -0
  22. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/makebase.sh +0 -0
  23. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/setclasspath.sh +0 -0
  24. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/shutdown.sh +0 -0
  25. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/startup.sh +0 -0
  26. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/tomcat-juli.jar +0 -0
  27. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/tomcat-native.tar.gz +0 -0
  28. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/tool-wrapper.sh +0 -0
  29. data/lib/rubyfox/server/data/lib/apache-tomcat/bin/version.sh +0 -0
  30. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/Catalina/localhost/rewrite.config +1 -1
  31. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/catalina.policy +263 -263
  32. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/catalina.properties +209 -207
  33. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/context.xml +31 -31
  34. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/jaspic-providers.xml +23 -23
  35. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/jaspic-providers.xsd +52 -52
  36. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/keystore.jks +0 -0
  37. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/server.xml +177 -161
  38. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/tomcat-users.xml +18 -7
  39. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/tomcat-users.xsd +59 -59
  40. data/lib/rubyfox/server/data/lib/apache-tomcat/conf/web.xml +4740 -4737
  41. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/annotations-api.jar +0 -0
  42. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-ant.jar +0 -0
  43. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-ha.jar +0 -0
  44. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-ssi.jar +0 -0
  45. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-storeconfig.jar +0 -0
  46. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina-tribes.jar +0 -0
  47. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/catalina.jar +0 -0
  48. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/el-api.jar +0 -0
  49. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jasper-el.jar +0 -0
  50. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jasper.jar +0 -0
  51. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jaspic-api.jar +0 -0
  52. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/jsp-api.jar +0 -0
  53. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/servlet-api.jar +0 -0
  54. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/sfs2x-ws-helper.jar +0 -0
  55. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-api.jar +0 -0
  56. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-coyote.jar +0 -0
  57. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-dbcp.jar +0 -0
  58. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-cs.jar +0 -0
  59. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-de.jar +0 -0
  60. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-es.jar +0 -0
  61. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-fr.jar +0 -0
  62. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-ja.jar +0 -0
  63. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-ko.jar +0 -0
  64. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-pt-BR.jar +0 -0
  65. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-ru.jar +0 -0
  66. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-i18n-zh-CN.jar +0 -0
  67. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-jdbc.jar +0 -0
  68. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-jni.jar +0 -0
  69. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-util-scan.jar +0 -0
  70. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-util.jar +0 -0
  71. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/tomcat-websocket.jar +0 -0
  72. data/lib/rubyfox/server/data/lib/apache-tomcat/lib/websocket-api.jar +0 -0
  73. data/lib/rubyfox/server/data/lib/javax.activation-1.2.0.jar +0 -0
  74. data/lib/rubyfox/server/data/lib/javax.mail.jar +0 -0
  75. data/lib/rubyfox/server/data/lib/js/JSApi.js +2 -1
  76. data/lib/rubyfox/server/data/lib/js/LibApi.js +181 -48
  77. data/lib/rubyfox/server/data/lib/sfs2x-admin.jar +0 -0
  78. data/lib/rubyfox/server/data/lib/sfs2x-cluster.jar +0 -0
  79. data/lib/rubyfox/server/data/lib/sfs2x-core.jar +0 -0
  80. data/lib/rubyfox/server/data/lib/sfs2x.jar +0 -0
  81. data/lib/rubyfox/server/data/sfs2x-service +26 -30
  82. data/lib/rubyfox/server/data/www/BlueBox.war +0 -0
  83. data/lib/rubyfox/server/data/www/HelloServlet/WEB-INF/web.xml +1 -3
  84. data/lib/rubyfox/server/data/www/ROOT/_css_/default.css +14 -6
  85. data/lib/rubyfox/server/data/www/ROOT/admin/assets/css/style.css +44 -2
  86. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/application.bundle.js +98 -61
  87. 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
  88. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-0.bundle.js +4 -4
  89. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-1.bundle.js +3 -3
  90. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-10.bundle.js +101 -66
  91. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-11.bundle.js +544 -8
  92. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-12.bundle.js +915 -1480
  93. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-12~module-15~module-16~module-4.bundle.js +2665 -0
  94. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-13.bundle.js +606 -3093
  95. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-13~module-16~module-17~module-4.bundle.js +2665 -0
  96. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-14.bundle.js +764 -0
  97. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-15.bundle.js +71 -0
  98. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-16.bundle.js +1787 -0
  99. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-17.bundle.js +3383 -0
  100. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-4.bundle.js +121 -1009
  101. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-5.bundle.js +1214 -1744
  102. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-6.bundle.js +398 -666
  103. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-7.bundle.js +717 -192
  104. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-8.bundle.js +2117 -665
  105. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-9.bundle.js +613 -690
  106. 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
  107. 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
  108. 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
  109. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/vendors~module-12.bundle.js +807 -0
  110. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/vendors~module-13.bundle.js +807 -0
  111. data/lib/rubyfox/server/data/www/ROOT/admin/modules/cluster-configurator.html +32 -0
  112. data/lib/rubyfox/server/data/www/ROOT/admin/modules/cluster-monitor.html +185 -0
  113. data/lib/rubyfox/server/data/www/ROOT/admin/modules/cluster-updater.html +47 -0
  114. data/lib/rubyfox/server/data/www/ROOT/admin/modules/extension-deployer.html +84 -0
  115. data/lib/rubyfox/server/data/www/ROOT/admin/modules/zone-monitor.html +15 -8
  116. data/lib/rubyfox/server/data/www/ROOT/index.html +13 -23
  117. data/lib/rubyfox/server/data/www/host-manager/META-INF/context.xml +2 -2
  118. data/lib/rubyfox/server/data/www/host-manager/WEB-INF/jsp/404.jsp +2 -2
  119. data/lib/rubyfox/server/data/www/host-manager/{manager.xml → WEB-INF/manager.xml} +5 -1
  120. data/lib/rubyfox/server/data/www/host-manager/WEB-INF/web.xml +17 -0
  121. data/lib/rubyfox/server/data/www/host-manager/css/manager.css +141 -0
  122. data/lib/rubyfox/server/data/www/host-manager/images/tomcat.svg +967 -0
  123. data/lib/rubyfox/server/data/www/manager/META-INF/context.xml +2 -0
  124. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/connectorCerts.jsp +1 -1
  125. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/connectorCiphers.jsp +1 -1
  126. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/connectorTrustedCerts.jsp +1 -1
  127. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/sessionDetail.jsp +3 -3
  128. data/lib/rubyfox/server/data/www/manager/WEB-INF/jsp/sessionsList.jsp +1 -1
  129. data/lib/rubyfox/server/data/www/manager/WEB-INF/web.xml +17 -0
  130. data/lib/rubyfox/server/data/www/manager/css/manager.css +141 -0
  131. data/lib/rubyfox/server/data/www/manager/images/tomcat.svg +967 -0
  132. data/lib/rubyfox/server/data/www/manager/xform.xsl +74 -59
  133. data/lib/rubyfox/server/version.rb +1 -1
  134. metadata +30 -31
  135. data/lib/rubyfox/server/data/config/admin/icons/Analytics.png +0 -0
  136. data/lib/rubyfox/server/data/config/admin/icons/BanManager.png +0 -0
  137. data/lib/rubyfox/server/data/config/admin/icons/BlueBoxMonitor.png +0 -0
  138. data/lib/rubyfox/server/data/config/admin/icons/Console.png +0 -0
  139. data/lib/rubyfox/server/data/config/admin/icons/Dashboard.png +0 -0
  140. data/lib/rubyfox/server/data/config/admin/icons/ExtensionManager.png +0 -0
  141. data/lib/rubyfox/server/data/config/admin/icons/LicenseManager.png +0 -0
  142. data/lib/rubyfox/server/data/config/admin/icons/LogViewer.png +0 -0
  143. data/lib/rubyfox/server/data/config/admin/icons/ServerConfigurator.png +0 -0
  144. data/lib/rubyfox/server/data/config/admin/icons/ServletManager.png +0 -0
  145. data/lib/rubyfox/server/data/config/admin/icons/ZoneConfigurator.png +0 -0
  146. data/lib/rubyfox/server/data/config/admin/icons/ZoneMonitor.png +0 -0
  147. data/lib/rubyfox/server/data/lib/BlueBox.war +0 -0
  148. data/lib/rubyfox/server/data/lib/apache-tomcat/LICENSE +0 -1061
  149. data/lib/rubyfox/server/data/lib/apache-tomcat/NOTICE +0 -68
  150. data/lib/rubyfox/server/data/lib/apache-tomcat/README.md +0 -81
  151. data/lib/rubyfox/server/data/lib/apache-tomcat/RELEASE-NOTES +0 -174
  152. data/lib/rubyfox/server/data/lib/imap.jar +0 -0
  153. data/lib/rubyfox/server/data/lib/mailapi.jar +0 -0
  154. data/lib/rubyfox/server/data/lib/pop3.jar +0 -0
  155. data/lib/rubyfox/server/data/lib/smtp.jar +0 -0
  156. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/module-12~module-13~module-9.bundle.js +0 -2634
  157. data/lib/rubyfox/server/data/www/ROOT/admin/assets/js/core/modules/vendors~module-9.bundle.js +0 -807
  158. data/lib/rubyfox/server/data/www/host-manager/images/tomcat.gif +0 -0
  159. data/lib/rubyfox/server/data/www/manager/images/tomcat.gif +0 -0
  160. /data/lib/rubyfox/server/data/data/buddylists/{BasicExamples/.keep → .keep} +0 -0
@@ -1,6 +1,23 @@
1
1
  /*! (c) gotoAndPlay | All rights reserved */
2
2
  (window["webpackJsonpapplication"] = window["webpackJsonpapplication"] || []).push([["module-7"],{
3
3
 
4
+ /***/ "./node_modules/file-saver/dist/FileSaver.min.js":
5
+ /*!*******************************************************!*\
6
+ !*** ./node_modules/file-saver/dist/FileSaver.min.js ***!
7
+ \*******************************************************/
8
+ /*! no static exports found */
9
+ /***/ (function(module, exports, __webpack_require__) {
10
+
11
+ /* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(a,b){if(true)!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (b),
12
+ __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
13
+ (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
14
+ __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));else {}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(b,c,d){var e=new XMLHttpRequest;e.open("GET",b),e.responseType="blob",e.onload=function(){a(e.response,c,d)},e.onerror=function(){console.error("could not download file")},e.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(a,b,d,e){if(e=e||open("","_blank"),e&&(e.document.title=e.document.body.innerText="downloading..."),"string"==typeof a)return c(a,b,d);var g="application/octet-stream"===a.type,h=/constructor/i.test(f.HTMLElement)||f.safari,i=/CriOS\/[\d]+/.test(navigator.userAgent);if((i||g&&h)&&"object"==typeof FileReader){var j=new FileReader;j.onloadend=function(){var a=j.result;a=i?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),e?e.location.href=a:location=a,e=null},j.readAsDataURL(a)}else{var k=f.URL||f.webkitURL,l=k.createObjectURL(a);e?e.location=l:location.href=l,e=null,setTimeout(function(){k.revokeObjectURL(l)},4E4)}});f.saveAs=a.saveAs=a, true&&(module.exports=a)});
15
+
16
+ //# sourceMappingURL=FileSaver.min.js.map
17
+ /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js")))
18
+
19
+ /***/ }),
20
+
4
21
  /***/ "./node_modules/moment/locale sync recursive ^\\.\\/.*$":
5
22
  /*!**************************************************!*\
6
23
  !*** ./node_modules/moment/locale sync ^\.\/.*$ ***!
@@ -287,45 +304,227 @@ webpackContext.id = "./node_modules/moment/locale sync recursive ^\\.\\/.*$";
287
304
 
288
305
  /***/ }),
289
306
 
290
- /***/ "./src/modules/license-manager.js":
291
- /*!****************************************!*\
292
- !*** ./src/modules/license-manager.js ***!
293
- \****************************************/
307
+ /***/ "./node_modules/webpack/buildin/global.js":
308
+ /*!***********************************!*\
309
+ !*** (webpack)/buildin/global.js ***!
310
+ \***********************************/
311
+ /*! no static exports found */
312
+ /***/ (function(module, exports) {
313
+
314
+ var g;
315
+
316
+ // This works in non-strict mode
317
+ g = (function() {
318
+ return this;
319
+ })();
320
+
321
+ try {
322
+ // This works if eval is allowed (see CSP)
323
+ g = g || new Function("return this")();
324
+ } catch (e) {
325
+ // This works if the window reference is available
326
+ if (typeof window === "object") g = window;
327
+ }
328
+
329
+ // g can still be undefined, but nothing to do about it...
330
+ // We return undefined, instead of nothing here, so it's
331
+ // easier to handle this case. if(!global) { ...}
332
+
333
+ module.exports = g;
334
+
335
+
336
+ /***/ }),
337
+
338
+ /***/ "./src/data/command-history.js":
339
+ /*!*************************************!*\
340
+ !*** ./src/data/command-history.js ***!
341
+ \*************************************/
342
+ /*! exports provided: CommandHistory */
343
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
344
+
345
+ "use strict";
346
+ __webpack_require__.r(__webpack_exports__);
347
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CommandHistory", function() { return CommandHistory; });
348
+ class CommandHistory
349
+ {
350
+ constructor(size = 50)
351
+ {
352
+ this._size = size;
353
+
354
+ // TODO
355
+ // As the history is saved in cookies, and they are now limited to 4 KB size,
356
+ // this class should be updated to remove entries based on the total size,
357
+ // and not on the total number of items anymore
358
+
359
+ this.clear();
360
+ this._loadState();
361
+ }
362
+
363
+ addCommand(cmd)
364
+ {
365
+ if (this._history.length >= this._size)
366
+ this._history.splice(0, 1);
367
+
368
+ this._history.push(cmd);
369
+ this._pos = this._history.length;
370
+ this._tempCmd = '';
371
+
372
+ this._saveState();
373
+ }
374
+
375
+ addTempCommand(cmd)
376
+ {
377
+ this._tempCmd = cmd;
378
+ this._pos = this._history.length;
379
+ }
380
+
381
+ rewind()
382
+ {
383
+ if (this._pos > 0)
384
+ this._pos--;
385
+
386
+ return this._history[this._pos];
387
+ }
388
+
389
+ forward()
390
+ {
391
+ if (this._pos < this._history.length)
392
+ this._pos++;
393
+
394
+ if (this._pos <= this._history.length - 1)
395
+ return this._history[this._pos];
396
+ else
397
+ return this._tempCmd;
398
+ }
399
+
400
+ getList()
401
+ {
402
+ return this._history;
403
+ }
404
+
405
+ getSize()
406
+ {
407
+ return this._history.length
408
+ }
409
+
410
+ clear()
411
+ {
412
+ this._history = [];
413
+ this._pos = 0;
414
+ this._tempCmd = '';
415
+ }
416
+
417
+ _saveState()
418
+ {
419
+ Cookies.set('console-history', {
420
+ history: this._history
421
+ }, {expires: 36000});
422
+ }
423
+
424
+ _loadState()
425
+ {
426
+ let data = Cookies.getJSON('console-history')
427
+
428
+ if (data)
429
+ {
430
+ this._history = data.history;
431
+ this._pos = this._history.length;
432
+ }
433
+ }
434
+ }
435
+
436
+
437
+ /***/ }),
438
+
439
+ /***/ "./src/modules/console.js":
440
+ /*!********************************!*\
441
+ !*** ./src/modules/console.js ***!
442
+ \********************************/
294
443
  /*! exports provided: default */
295
444
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
296
445
 
297
446
  "use strict";
298
447
  __webpack_require__.r(__webpack_exports__);
299
- /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return LicenseManager; });
448
+ /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Console; });
300
449
  /* harmony import */ var _base_module__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-module */ "./src/modules/base-module.js");
301
- /* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! moment */ "./node_modules/moment/moment.js");
302
- /* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_1__);
450
+ /* harmony import */ var _data_command_history__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../data/command-history */ "./src/data/command-history.js");
451
+ /* harmony import */ var file_saver__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! file-saver */ "./node_modules/file-saver/dist/FileSaver.min.js");
452
+ /* harmony import */ var file_saver__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(file_saver__WEBPACK_IMPORTED_MODULE_2__);
453
+ /* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! moment */ "./node_modules/moment/moment.js");
454
+ /* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_3__);
455
+ /* harmony import */ var _utils_utilities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/utilities */ "./src/utils/utilities.js");
456
+
457
+
303
458
 
304
459
 
305
460
 
306
- class LicenseManager extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModule"]
461
+
462
+ class Console extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModule"]
307
463
  {
308
464
  constructor()
309
465
  {
310
- super('licenseMan');
466
+ super('console');
311
467
 
312
468
  // Outgoing requests
313
- this.REQ_GET_DATA = 'getData';
314
- this.REQ_SAVE_DATA = 'saveData';
315
- this.REQ_TEST_CONNECTION = 'testConn';
316
- this.REQ_REFRESH_LICENSE = 'refreshLic';
469
+ this.REQ_CMD = 'cmd';
470
+ this.REQ_HINT = 'hint';
471
+ this.REQ_SCRIPT = 'script';
317
472
 
318
473
  // Incoming responses
319
- this.RESP_DATA = 'data';
320
- this.RESP_DATA_SAVED = 'dataSaved';
321
- this.RESP_TEST_RESULT = 'testRes';
474
+ this.RES_CMD = 'cmd';
475
+ this.RES_HINT = 'hint';
476
+ this.RES_SCRIPT = 'script';
477
+ this.RES_ERROR_LOCKED = 'locked';
478
+
479
+ this.VERSION = '3.0.0';
480
+ this.TOKENS = ['=', 'from ', 'import '];
481
+
482
+ this.TRANSCRIPT_TEMPLATE = `
483
+ <html>
484
+ <head>
485
+ <title>SFS2X ADMIN CONSOLE Session Transcript</title>
486
+ <style type='text/css' media='screen'>
487
+ body, pre {
488
+ background-color: #333;
489
+ font-size: .8rem;
490
+ font-family: Monaco,'Courier New', monospace;
491
+ }
322
492
 
323
- this.COMMUNICATION_CHECK_OK = 1;
324
- this.COMMUNICATION_CHECK_KO_LICENSE_INVALID = 2;
493
+ h3 {
494
+ color: #f8f9fa;
495
+ }
496
+
497
+ pre {
498
+ white-space: pre-wrap;
499
+ -moz-tab-size: 5;
500
+ tab-size: 5;
501
+ }
502
+
503
+ .text-console {
504
+ color: #28F32D;
505
+ }
506
+
507
+ .text-error {
508
+ color: #dc3545;
509
+ }
325
510
 
326
- this._code = '';
327
- this._emails = '';
328
- this._alert = false;
511
+ .text-highlight {
512
+ color: #ffc107;
513
+ }
514
+
515
+ .text-command {
516
+ color: #f8f9fa;
517
+ }
518
+ </style>
519
+ </head>
520
+ <body>
521
+ <h3><!--HEADER--></h3>
522
+ <pre><!--TRANSCRIPT--></pre>
523
+ </body>
524
+ </html>
525
+ `;
526
+
527
+ this._cmdHistory = new _data_command_history__WEBPACK_IMPORTED_MODULE_1__["CommandHistory"]();
329
528
  }
330
529
 
331
530
  //------------------------------------
@@ -339,28 +538,58 @@ class LicenseManager extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModu
339
538
  // Call super method
340
539
  super.initialize(idData, shellController);
341
540
 
342
- // Initialize kendo switch
343
- kendo.init($('#lcm-alertCb'));
541
+ $('#cns-input').on('keyup', $.proxy(this.onInputKeyUp, this));
542
+ $('#cns-input').on('keydown', $.proxy(this.onInputKeyDown, this));
344
543
 
345
- // Initialize help tooltips
346
- $(this).kendoTooltip({
347
- filter: 'i[title].help',
348
- position: 'right',
349
- content: function(e) {
350
- return `<div class="help-tooltip">${e.target.data('title')}</div>`;
351
- }
352
- });
544
+ // Show welcome message
545
+ this._showWelcomeMessage();
546
+
547
+ // Focus on prompt input
548
+ $('#cns-input').focus();
549
+
550
+ // Add global click listener to close hint panel
551
+ $(this).on('click', $.proxy(this._onGenericClick, this));
552
+
553
+ // Add global window resize listener to close hint panel
554
+ $(window).on('resize', $.proxy(this._onGenericClick, this));
353
555
 
354
- // Add button event listeners
355
- $('#lcm-refreshBt').on('click', $.proxy(this._onRefreshClick, this));
356
- $('#lcm-submitBt').on('click', $.proxy(this._onSubmitClick, this));
357
- $('#lcm-testBt').on('click', $.proxy(this._onTestClick, this));
556
+ // Add buttons click listeners
557
+ $('#cns-clearButton').on('click', $.proxy(this._onClearConsoleClick, this));
558
+ $('#cns-runButton').on('click', $.proxy(this._onRunScriptClick, this));
559
+ $('#cns-exportButton').on('click', $.proxy(this._onExportSessionClick, this));
358
560
 
359
- // Disable interface
360
- this._enableInterface(false);
561
+ // Initialize "upload script" modal
562
+ this._uploadScriptModal = $('#cns-uploadModal');
563
+ this._uploadScriptModal.modal({
564
+ backdrop: 'static',
565
+ keyboard: false,
566
+ show: false
567
+ });
361
568
 
362
- // Request license data to server instance
363
- this.sendExtensionRequest(this.REQ_GET_DATA);
569
+ // Initialize kendo uploader
570
+ this._uploader = $('#cns-uploader').kendoUpload({
571
+ allowedExtensions: ['.py'],
572
+ multiple: false,
573
+ template: function(dataItem) {
574
+ dataItem.bytesToSize = _utils_utilities__WEBPACK_IMPORTED_MODULE_4__["bytesToSize"]; // Pass bytesToSize utility function to template
575
+ return kendo.template(`
576
+ <span class='k-progress w-100'></span>
577
+ <span class="">
578
+ <span class="k-file-name" title="#=name#">#=name#</span>
579
+ <span class="k-file-size">Size: #=bytesToSize(size, 1, 'Bytes')#</span>
580
+ </span>
581
+ `)(dataItem);
582
+ },
583
+ localization: {
584
+ select: 'Select file...'
585
+ }
586
+ }).data('kendoUpload');
587
+
588
+ // Add listener to modal hide event
589
+ this._uploadScriptModal.on('hidden.bs.modal', $.proxy(this._onUploadScriptrModalHidden, this));
590
+
591
+ // Add listener to modal button
592
+ $('#cns-uploadScriptButton').on('click', $.proxy(this._onUploadScriptrButtonCLick, this));
364
593
  }
365
594
 
366
595
  destroy()
@@ -368,235 +597,531 @@ class LicenseManager extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModu
368
597
  // Call super method
369
598
  super.destroy();
370
599
 
371
- // Remove button event listeners
372
- $('#lcm-refreshBt').off('click');
373
- $('#lcm-submitBt').off('click');
374
- $('#lcm-testBt').off('click');
600
+ $('#cns-clearButton').off('click');
601
+ $('#cns-runButton').off('click');
602
+ $('#cns-exportButton').off('click');
603
+ $('#cns-uploadScriptButton').off('click');
604
+
605
+ $(this).off('click');
606
+ $(window).off('resize');
607
+
608
+ this._uploadScriptModal.off('hidden.bs.modal');
609
+ this._uploadScriptModal.modal('dispose');
375
610
  }
376
611
 
377
612
  onExtensionCommand(command, data)
378
613
  {
379
- // License configuration data received
380
- if (command == this.RESP_DATA)
614
+ if (command == this.RES_CMD || command == this.RES_SCRIPT)
615
+ {
616
+ const result = data.getUtfString('r');
617
+ const error = data.getUtfString('e');
618
+
619
+ if (result != null)
620
+ this._writeConsole(result);
621
+ else if (error != null)
622
+ this._writeConsole(`<span class="text-error">ERROR</span> ${this._parseHtml(error)}`);
623
+ }
624
+
625
+ else if (command == this.RES_HINT)
626
+ {
627
+ this._lastHints = data.getUtfStringArray('h');
628
+
629
+ this._showHintPanel();
630
+ }
631
+
632
+ else if (command == this.RES_ERROR_LOCKED)
633
+ {
634
+ this._writeConsole(`<span class="text-error">ERROR</span> <span class="text-highlight">Console module is locked from server side. Please follow the instructions you were given to unlock it.</span>`);
635
+ }
636
+ }
637
+
638
+ //---------------------------------
639
+ // UI EVENT LISTENERS
640
+ //---------------------------------
641
+
642
+ onInputKeyDown(e)
643
+ {
644
+ // Save previous input value
645
+ this._prevInput = $('#cns-input').val();
646
+
647
+ const keyName = e.key;
648
+
649
+ if (keyName == 'ArrowUp' || keyName == 'ArrowDown' || keyName == 'Tab')
381
650
  {
382
- // Configuration
383
- if (data.containsKey('code'))
384
- this._code = data.getUtfString('code');
651
+ e.preventDefault();
652
+ }
653
+ }
385
654
 
386
- if (data.containsKey('emails'))
387
- this._emails = data.getUtfString('emails');
655
+ onInputKeyUp(e)
656
+ {
657
+ const keyName = e.key;
658
+ const input = $('#cns-input').val();
388
659
 
389
- if (data.containsKey('alert'))
390
- this._alert = data.getBool('alert');
660
+ // Copy input to dummy
661
+ $('#cns-input-dummy').html(input);
391
662
 
392
- // Display currently running license details
393
- if (data.containsKey('details'))
663
+ //--- DOT (CODE HINTING) -----------------------------------------------
664
+ if (keyName == '.')
665
+ {
666
+ // Close hint panel if open
667
+ if (this._isHintPanelOpen)
668
+ this._closeHintPanel();
669
+
670
+ // Request code hints
671
+ this._requestHints(input);
672
+ }
673
+
674
+ //--- ENTER ------------------------------------------------------------
675
+ else if (keyName == 'Enter' && input.length > 0)
676
+ {
677
+ // Get selected hint
678
+ if (this._isHintPanelOpen)
394
679
  {
395
- let licDetails = data.getUtfStringArray('details');
680
+ if (this._hintPanel.find('.hint-item.selected').length > 0)
681
+ this._setInputOnHintSelected();
682
+ }
683
+ else
684
+ {
685
+ // Send command to server
686
+ let sfso = new SFS2X.SFSObject();
687
+ sfso.putUtfString('c', input);
688
+ this.sendExtensionRequest(this.REQ_CMD, sfso);
396
689
 
397
- $('#lcm-currType').text(licDetails[0]);
398
- $('#lcm-currMaxUsers').text(licDetails[1]);
399
- $('#lcm-currOptions').text(licDetails[2].split(',').join(' | '));
400
- $('#lcm-currExpire').text(licDetails[3]);
401
- $('#lcm-currPrivate').text(licDetails[4]);
690
+ // Write command to console
691
+ this._writeConsole(input, true);
402
692
 
403
- if (licDetails[2] != '')
404
- $('#lcm-currOptions').parent().show();
405
- else
406
- $('#lcm-currOptions').parent().hide();
693
+ // Clear hints
694
+ this._lastHints = null;
407
695
 
408
- if (licDetails[3] != '')
409
- $('#lcm-currExpire').parent().show();
410
- else
411
- $('#lcm-currExpire').parent().hide();
696
+ // Clear input
697
+ this._clearInput();
412
698
 
413
- if (licDetails[4] != '')
414
- $('#lcm-currPrivate').parent().show();
415
- else
416
- $('#lcm-currPrivate').parent().hide();
699
+ // Add command to history
700
+ this._cmdHistory.addCommand(input);
417
701
  }
702
+ }
703
+
704
+ //--- ENTER ------------------------------------------------------------
705
+ else if (keyName == 'Tab')
706
+ {
707
+ // Get selected hint
708
+ if (this._isHintPanelOpen)
709
+ {
710
+ if (this._hintPanel.find('.hint-item.selected').length > 0)
711
+ this._setInputOnHintSelected();
712
+ }
713
+ }
714
+
715
+ //--- CTRL+BACKSPACE (CLEAR CONSOLE) -----------------------------------
716
+ else if (e.ctrlKey && keyName == 'Backspace')
717
+ {
718
+ this._onClearConsoleClick();
719
+ }
720
+
721
+ //--- BACKSPACE ------------------------------------------------------
722
+ else if (keyName == 'Backspace')
723
+ {
724
+ // Check the deleted char
725
+ if (this._prevInput.substring(this._prevInput.length - 1) == '.')
726
+ {
727
+ // Reset hinting
728
+ this._resetHinting(input);
729
+ }
730
+
731
+ // Update hint panel if open
732
+ if (this._isHintPanelOpen)
733
+ this._updateHintPanel();
734
+ }
418
735
 
419
- // Display warning is sent by the server
420
- // This can happen if a license refresh request was sent and this couldn't be completed or caused the license to revert to CE
421
- if (data.containsKey('warning'))
422
- this.shellCtrl.showSimpleAlert(data.getUtfString('warning'));
736
+ //--- ESC (CLEAR) ------------------------------------------------------
737
+ else if (keyName == 'Escape')
738
+ {
739
+ // Close hint panel if open
740
+ if (this._isHintPanelOpen)
741
+ this._closeHintPanel();
423
742
 
424
- this._enableInterface(true);
743
+ else
744
+ {
745
+ // Clear hints
746
+ this._lastHints = null;
747
+
748
+ // Clear input
749
+ this._clearInput();
750
+ }
425
751
  }
426
752
 
427
- // License configuration update confirmation
428
- else if (command == this.RESP_DATA_SAVED)
753
+ //--- ARROW UP ---------------------------------------------------------
754
+ else if (keyName == 'ArrowUp')
429
755
  {
430
- this._code = data.getUtfString('code');
431
- this._emails = data.getUtfString('emails');
432
- this._alert = data.getBool('alert');
756
+ // If hint panel is open, set selection
757
+ if (this._isHintPanelOpen)
758
+ {
759
+ this._currHintFocus--;
433
760
 
434
- // Enable interface
435
- this._enableInterface(true);
761
+ this._setHintItemSelected();
762
+ }
436
763
 
437
- // Log message
438
- const updater = data.getUtfString('user');
764
+ // Browse history
765
+ else
766
+ {
767
+ this._setInputOnHistorySelected(this._cmdHistory.rewind());
768
+ }
769
+ }
439
770
 
440
- if (updater == this.smartFox.mySelf.name)
771
+ //--- ARROW DOWN -------------------------------------------------------
772
+ else if (keyName == 'ArrowDown')
773
+ {
774
+ // If hint panel is open, set selection
775
+ if (this._isHintPanelOpen)
441
776
  {
442
- // Display notification
443
- this.shellCtrl.showNotification(`Configuration updated`, `License details saved successfully`);
777
+ this._currHintFocus++;
444
778
 
445
- // Show screen
446
- this._switchView('lcm-panelSaved');
779
+ this._setHintItemSelected();
447
780
  }
781
+
782
+ // Browse history
448
783
  else
449
784
  {
450
- // Display notification
451
- this.shellCtrl.showNotification(`Configuration updated`, `Administrator ${updater} has modified the license details`);
785
+ this._setInputOnHistorySelected(this._cmdHistory.forward());
452
786
  }
453
787
  }
454
788
 
455
- // Response to License Server connection test received
456
- else if (command == this.RESP_TEST_RESULT)
789
+ //--- ARROW LEFT & RIGHT -----------------------------------------------
790
+ else if (keyName == 'ArrowLeft' || keyName == 'ArrowRight')
457
791
  {
458
- this._enableInterface(true);
792
+ // Close hint panel if open
793
+ if (this._isHintPanelOpen)
794
+ this._closeHintPanel();
795
+ }
796
+
797
+ //--- ANY OTHER KEY ----------------------------------------------------
798
+ else
799
+ {
800
+ // Update temp in command history
801
+ this._cmdHistory.addTempCommand(input);
459
802
 
460
- if (data.isNull('lsData'))
803
+ if (input.length == $('#cns-input')[0].selectionEnd)
461
804
  {
462
- // Show screen
463
- this._switchView('lcm-panelTestKO');
805
+ // Update hint panel if open
806
+ if (this._isHintPanelOpen)
807
+ this._updateHintPanel();
808
+
809
+ // Show hint panel
810
+ else
811
+ this._showHintPanel();
464
812
  }
465
813
  else
466
814
  {
467
- let lsData = data.getSFSObject('lsData');
468
-
469
- if (lsData.getInt('id') == this.COMMUNICATION_CHECK_KO_LICENSE_INVALID)
470
- {
471
- // Show screen
472
- this._switchView('lcm-panelTestOK-invalid');
473
- }
474
- else if (lsData.getInt('id') == this.COMMUNICATION_CHECK_OK)
475
- {
476
- // Show screen
477
- this._switchView('lcm-panelTestOK-valid');
478
-
479
- // Populate license details
480
- $('#lcm-maxUsers').text(lsData.getInt('users') > 0 ? lsData.getInt('users').toString() : 'Unlimited');
481
- $('#lcm-privateIp').text(lsData.getBool('private') ? 'Yes' : 'No');
482
- $('#lcm-expire').text(lsData.getLong('expire') > 0 ? moment__WEBPACK_IMPORTED_MODULE_1__(lsData.getLong('expire')).format('DD MMM YYYY HH:mm') + ' GMT' + moment__WEBPACK_IMPORTED_MODULE_1__(lsData.getLong('expire')).format('Z') : 'Never');
483
- $('#lcm-options').text('None');
484
-
485
- if (lsData.containsKey('options') && lsData.getUtfString('options') != '')
486
- {
487
- let options = lsData.getUtfString('options').split(',');
488
- $('#lcm-options').text(options.join(' | '));
489
- }
490
-
491
- const now = Date.now();
492
- let isExpired = (lsData.getLong('expire') > 0) && (now > lsData.getLong('expire'));
493
-
494
- if (isExpired)
495
- $('#lcm-expireAlert').show();
496
- else
497
- $('#lcm-expireAlert').hide();
498
-
499
- // Check the license initialization status
500
- if (lsData.getBool('initStatus') && !isExpired)
501
- $('#lcm-initNote').show();
502
- else
503
- $('#lcm-initNote').hide();
504
- }
815
+ // Reset hinting
816
+ this._resetHinting(input);
505
817
  }
506
818
  }
819
+ }
507
820
 
508
- // else if ()
821
+ _onClearConsoleClick()
822
+ {
823
+ $('#cns-console').empty();
509
824
  }
510
825
 
511
- //---------------------------------
512
- // UI EVENT LISTENERS
513
- //---------------------------------
826
+ _onHintItemClick(e)
827
+ {
828
+ e.preventDefault();
829
+
830
+ // Set clicked item as selected
831
+ e.currentTarget.classList.add('selected');
832
+
833
+ // Set input value
834
+ this._setInputOnHintSelected();
835
+
836
+ // Focus on prompt input
837
+ $('#cns-input').focus();
838
+ }
839
+
840
+ _onGenericClick()
841
+ {
842
+ // Close hint panel if open
843
+ if (this._isHintPanelOpen)
844
+ this._closeHintPanel();
845
+ }
514
846
 
515
- _onSubmitClick()
847
+ _onExportSessionClick()
516
848
  {
517
- // Validate email addresses
518
- // Invalid addresses are stripped off
519
- let validEmails = [];
849
+ let date = moment__WEBPACK_IMPORTED_MODULE_3__();
850
+
851
+ let transcript = this.TRANSCRIPT_TEMPLATE.replace('<!--HEADER-->', `Saved on ${date.format('dddd, MMMM Do YYYY, HH:mm:ss')}`);
852
+ transcript = transcript.replace('<!--TRANSCRIPT-->', $('#cns-console').html());
853
+
854
+ let blob = new Blob([transcript], {type: 'text/html;charset=utf-8'});
855
+
856
+ file_saver__WEBPACK_IMPORTED_MODULE_2__["saveAs"](blob, `ConsoleSession_${date.format('YYYYMMDD_HHmmss')}.html`);
857
+ }
858
+
859
+ _onRunScriptClick()
860
+ {
861
+ // Open modal
862
+ this._uploadScriptModal.modal('show');
863
+ }
520
864
 
521
- if ($('#lcm-emailIn').val() != '')
865
+ _onUploadScriptrModalHidden()
866
+ {
867
+ // Clear uploader
868
+ this._uploader.clearAllFiles();
869
+ }
870
+
871
+ _onUploadScriptrButtonCLick()
872
+ {
873
+ if (this._uploader.getFiles().length > 0)
522
874
  {
523
- let enteredEmails = $('#lcm-emailIn').val().split(',');
524
- const regExpPattern = /^[0-9a-zA-Z][-._a-zA-Z0-9]*@([0-9a-zA-Z][-._0-9a-zA-Z]*\.)+[a-zA-Z]{2,4}$/;
875
+ let file = this._uploader.getFiles()[0].rawFile;
525
876
 
526
- for (let i = 0; i < enteredEmails.length; i++)
527
- {
528
- const email = enteredEmails[i].trim();
529
- if (regExpPattern.test(email))
530
- validEmails.push(email);
531
- }
877
+ file.arrayBuffer().then(buffer => {
878
+ this._writeConsole(`EXEC: ${file.name}`, true);
879
+
880
+ let sfso = new SFS2X.SFSObject();
881
+ sfso.putByteArray('script', new Uint8Array(buffer));
882
+
883
+ this.sendExtensionRequest(this.REQ_SCRIPT, sfso);
884
+ });
885
+
886
+ // Close modal
887
+ this._uploadScriptModal.modal('hide');
532
888
  }
889
+ }
533
890
 
534
- let submitEmails = validEmails.join(',');
535
- $('#lcm-emailIn').val(submitEmails);
891
+ //------------------------------------
892
+ // PRIVATE METHODS
893
+ //------------------------------------
536
894
 
537
- if ($('#lcm-codeIn').val() != this._code || $('#lcm-emailIn').val() != this._emails || $('#lcm-alertCb').data('kendoSwitch').check() != this._alert)
895
+ _showWelcomeMessage()
896
+ {
897
+ this._writeConsole(`--------------------------------------\nADMIN_CONSOLE, version ${this.VERSION}\n--------------------------------------\nType help() for assistance.\n`, false, false);
898
+ }
899
+
900
+ _clearInput()
901
+ {
902
+ $('#cns-input').val('');
903
+ $('#cns-input-dummy').html('');
904
+ }
905
+
906
+ _setInputOnHintSelected()
907
+ {
908
+ if (this._hintPanel)
538
909
  {
539
- this._code = $('#lcm-codeIn').val();
540
- this._emails = submitEmails;
541
- this._alert = $('#lcm-alertCb').data('kendoSwitch').check();
910
+ const input = $('#cns-input').val();
911
+ const selectedVal = this._hintPanel.find('.hint-item.selected input').val();
912
+ const newInput = input.substring(0, input.lastIndexOf('.')) + '.' + selectedVal;
913
+
914
+ $('#cns-input').val(newInput);
915
+ $('#cns-input-dummy').html(newInput);
916
+
917
+ this._closeHintPanel();
918
+ }
919
+ }
920
+
921
+ _setInputOnHistorySelected(command)
922
+ {
923
+ $('#cns-input').val(command);
924
+ $('#cns-input-dummy').html(command);
925
+ }
926
+
927
+ _writeConsole(txt, isInput = false, linebreak = true)
928
+ {
929
+ let msg;
930
+
931
+ if (isInput)
932
+ msg = `<span class="text-command">&gt; ${txt}</span>`;
933
+ else
934
+ msg = `<span class="text-console">${txt}</span>`;
542
935
 
543
- // Disable interface
544
- this._enableInterface(false);
936
+ if (linebreak)
937
+ msg = `\n${msg}`;
545
938
 
546
- // Submid data
547
- let params = new SFS2X.SFSObject();
548
- params.putUtfString('code', this._code);
549
- params.putUtfString('emails', this._emails);
550
- params.putBool('alert', this._alert);
939
+ // Append text to console
940
+ $('#cns-console').append(msg);
941
+
942
+ // scroll console to bottom
943
+ $('#cns-console').scrollTop(function() { return this.scrollHeight; });
944
+ }
945
+
946
+ _parseHtml(ss)
947
+ {
948
+ ss = ss.replace('<', '&lt;');
949
+ ss = ss.replace('>', '&gt;');
551
950
 
552
- this.sendExtensionRequest(this.REQ_SAVE_DATA, params);
951
+ return ss;
952
+ }
953
+
954
+ _showHintPanel()
955
+ {
956
+ if (this._lastHints != null && this._lastHints.length > 0)
957
+ {
958
+ this._currHintFocus = -1;
959
+
960
+ // Create panel
961
+ this._hintPanel = $('<div>', {'class': 'hint-panel'});
962
+ $(this).append(this._hintPanel);
963
+
964
+ // Show hints
965
+ this._updateHintPanel();
553
966
  }
554
967
  }
555
968
 
556
- _onTestClick()
969
+ _closeHintPanel()
970
+ {
971
+ this._hintPanel.remove();
972
+ this._hintPanel = null;
973
+ }
974
+
975
+ _updateHintPanel()
557
976
  {
558
- // Disable interface
559
- this._enableInterface(false);
977
+ if (this._lastHints != null && this._lastHints.length > 0)
978
+ {
979
+ // Clear hints panel
980
+ this._hintPanel.empty();
981
+
982
+ const dotIndex = $('#cns-input').val().lastIndexOf('.');
983
+ let lastWord = '';
984
+
985
+ if (dotIndex > -1)
986
+ lastWord = $('#cns-input').val().substr(dotIndex + 1, $('#cns-input').val().length);
987
+
988
+ let isEmpty = true;
989
+
990
+ for (let word of this._lastHints)
991
+ {
992
+ // Check if the item starts with the same letters as the input's last word
993
+ if (lastWord == '' || word.substr(0, lastWord.length).toUpperCase() == lastWord.toUpperCase())
994
+ {
995
+ // Create div
996
+ let item = $('<div>', {'class': 'hint-item'});
997
+
998
+ // Show value, and make the matching letters bold
999
+ item.append(`<strong>${word.substr(0, lastWord.length)}</strong>${word.substr(lastWord.length)}`);
1000
+
1001
+ // Insert an input field that will hold the current item's value
1002
+ item.append(`<input type="hidden" value="${word}">`);
1003
+
1004
+ // Add click listener
1005
+ item.on('click', $.proxy(this._onHintItemClick, this));
1006
+
1007
+ this._hintPanel.append(item);
1008
+
1009
+ isEmpty = false;
1010
+ }
1011
+ }
1012
+
1013
+ // If panel is empty, remove it
1014
+ if (isEmpty)
1015
+ this._closeHintPanel();
1016
+
1017
+ // Else set panel position
1018
+ else
1019
+ {
1020
+ const extContPos = $('#cns-input-container-2').position();
1021
+ const intContPos = $('#cns-input-container-1').position();
1022
+
1023
+ let left = extContPos.left + intContPos.left + $('#cns-input-dummy').outerWidth();
1024
+ let top = extContPos.top + intContPos.top - this._hintPanel.outerHeight();
1025
+
1026
+ if (left > window.innerWidth - this._hintPanel.outerWidth())
1027
+ left = window.innerWidth - this._hintPanel.outerWidth();
1028
+
1029
+ this._hintPanel.css({top: top, left: left, position: 'absolute'});
560
1030
 
561
- // Send request
562
- this.sendExtensionRequest(this.REQ_TEST_CONNECTION);
1031
+ // Select first item
1032
+ this._currHintFocus = 0;
1033
+ this._setHintItemSelected();
1034
+ }
1035
+ }
563
1036
  }
564
1037
 
565
- _onRefreshClick()
1038
+ _requestHints(input)
566
1039
  {
567
- // Disable interface
568
- this._enableInterface(false);
1040
+ // Clear previous hints
1041
+ this._lastHints = null;
1042
+
1043
+ // Parse input
1044
+ let hintParent = this._extractHintParent(input);
1045
+
1046
+ // Request code hint
1047
+ let params = new SFS2X.SFSObject();
1048
+ params.putUtfString('c', hintParent);
569
1049
 
570
- // Send request
571
- this.sendExtensionRequest(this.REQ_REFRESH_LICENSE);
1050
+ this.sendExtensionRequest(this.REQ_HINT, params);
572
1051
  }
573
1052
 
574
- //------------------------------------
575
- // PRIVATE METHODS
576
- //------------------------------------
1053
+ _extractHintParent(inVal)
1054
+ {
1055
+ let outVal = null;
1056
+
1057
+ for (let tok of this.TOKENS)
1058
+ {
1059
+ const p = inVal.indexOf(tok);
1060
+
1061
+ if (p > -1)
1062
+ {
1063
+ outVal = inVal.substring(p + tok.length, inVal.length).trim();
1064
+ break;
1065
+ }
1066
+ }
1067
+
1068
+ if (outVal == null)
1069
+ outVal = inVal;
577
1070
 
578
- _enableInterface(enabled)
1071
+ // Remove dot at the end if needed
1072
+ if (outVal.endsWith('.'))
1073
+ outVal = outVal.substr(0, outVal.length - 1);
1074
+
1075
+ return outVal;
1076
+ }
1077
+
1078
+ _setHintItemSelected()
579
1079
  {
580
- $('#lcm-codeIn').val(this._code);
581
- $('#lcm-emailIn').val(this._emails);
582
- $('#lcm-alertCb').data('kendoSwitch').check(this._alert);
1080
+ let items = this._hintPanel.find('.hint-item');
1081
+ items.removeClass('selected');
1082
+
1083
+ if (this._currHintFocus >= items.length)
1084
+ this._currHintFocus = 0;
583
1085
 
584
- $('#lcm-submitBt').attr('disabled', !enabled);
585
- $('#lcm-testBt').attr('disabled', !(enabled && this._code != ''));
1086
+ if (this._currHintFocus < 0)
1087
+ this._currHintFocus = items.length - 1;
586
1088
 
587
- $('#lcm-refreshBt').attr('disabled', !enabled);
1089
+ let item = items.eq(this._currHintFocus);
1090
+ item.addClass('selected');
1091
+
1092
+ // Scroll to item
1093
+ this._hintPanel.scrollTop(this._hintPanel.scrollTop() + item.position().top);
588
1094
  }
589
1095
 
590
- _switchView(viewId)
1096
+ _resetHinting(input)
591
1097
  {
592
- document.getElementById('lcm-resultVS').selectedElement = document.getElementById(viewId);
1098
+ // Close hint panel
1099
+ if (this._isHintPanelOpen)
1100
+ this._closeHintPanel();
1101
+
1102
+ // Clear hints
1103
+ this._lastHints = null;
1104
+
1105
+ // Get previous word
1106
+ const dotIndex = input.lastIndexOf('.');
1107
+
1108
+ if (dotIndex > -1)
1109
+ {
1110
+ let value = input.substring(0, dotIndex);
1111
+
1112
+ // Request code hints
1113
+ this._requestHints(value);
1114
+ }
593
1115
  }
594
1116
 
595
1117
  //---------------------------------
596
1118
  // PRIVATE GETTERS
597
1119
  //---------------------------------
598
1120
 
599
-
1121
+ get _isHintPanelOpen()
1122
+ {
1123
+ return this._hintPanel != null;
1124
+ }
600
1125
  }
601
1126
 
602
1127
  /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery")))
@@ -604,4 +1129,4 @@ class LicenseManager extends _base_module__WEBPACK_IMPORTED_MODULE_0__["BaseModu
604
1129
  /***/ })
605
1130
 
606
1131
  }]);
607
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzL2pzL2NvcmUvbW9kdWxlcy9tb2R1bGUtNy5idW5kbGUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9hcHBsaWNhdGlvbi8uL3NyYy9tb2R1bGVzL2xpY2Vuc2UtbWFuYWdlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0Jhc2VNb2R1bGV9IGZyb20gJy4vYmFzZS1tb2R1bGUnO1xuaW1wb3J0ICogYXMgbW9tZW50IGZyb20gJ21vbWVudCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpY2Vuc2VNYW5hZ2VyIGV4dGVuZHMgQmFzZU1vZHVsZVxue1xuXHRjb25zdHJ1Y3RvcigpXG5cdHtcblx0ICAgIHN1cGVyKCdsaWNlbnNlTWFuJyk7XG5cblx0XHQvLyBPdXRnb2luZyByZXF1ZXN0c1xuXHRcdHRoaXMuUkVRX0dFVF9EQVRBID0gJ2dldERhdGEnO1xuXHRcdHRoaXMuUkVRX1NBVkVfREFUQSA9ICdzYXZlRGF0YSc7XG5cdFx0dGhpcy5SRVFfVEVTVF9DT05ORUNUSU9OID0gJ3Rlc3RDb25uJztcblx0XHR0aGlzLlJFUV9SRUZSRVNIX0xJQ0VOU0UgPSAncmVmcmVzaExpYyc7XG5cblx0XHQvLyBJbmNvbWluZyByZXNwb25zZXNcblx0XHR0aGlzLlJFU1BfREFUQSA9ICdkYXRhJztcblx0XHR0aGlzLlJFU1BfREFUQV9TQVZFRCA9ICdkYXRhU2F2ZWQnO1xuXHRcdHRoaXMuUkVTUF9URVNUX1JFU1VMVCA9ICd0ZXN0UmVzJztcblxuXHRcdHRoaXMuQ09NTVVOSUNBVElPTl9DSEVDS19PSyA9IDE7XG5cdFx0dGhpcy5DT01NVU5JQ0FUSU9OX0NIRUNLX0tPX0xJQ0VOU0VfSU5WQUxJRCA9IDI7XG5cblx0XHR0aGlzLl9jb2RlID0gJyc7XG5cdFx0dGhpcy5fZW1haWxzID0gJyc7XG5cdFx0dGhpcy5fYWxlcnQgPSBmYWxzZTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vIENPTU1PTiBNT0RVTEUgSU5URVJGQUNFIE1FVEhPRFNcblx0Ly8gVGhpcyBtZW1iZXJzIGFyZSB1c2VkIGJ5IHRoZSBtYWluIGNvbnRyb2xsZXJcblx0Ly8gdG8gY29tbXVuaWNhdGUgd2l0aCB0aGUgbW9kdWxlJ3MgY29udHJvbGxlci5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRpbml0aWFsaXplKGlkRGF0YSwgc2hlbGxDb250cm9sbGVyKVxuXHR7XG5cdFx0Ly8gQ2FsbCBzdXBlciBtZXRob2Rcblx0XHRzdXBlci5pbml0aWFsaXplKGlkRGF0YSwgc2hlbGxDb250cm9sbGVyKTtcblxuXHRcdC8vIEluaXRpYWxpemUga2VuZG8gc3dpdGNoXG5cdFx0a2VuZG8uaW5pdCgkKCcjbGNtLWFsZXJ0Q2InKSk7XG5cblx0XHQvLyBJbml0aWFsaXplIGhlbHAgdG9vbHRpcHNcblx0XHQkKHRoaXMpLmtlbmRvVG9vbHRpcCh7XG5cdFx0XHRmaWx0ZXI6ICdpW3RpdGxlXS5oZWxwJyxcblx0XHRcdHBvc2l0aW9uOiAncmlnaHQnLFxuXHRcdFx0Y29udGVudDogZnVuY3Rpb24oZSkge1xuXHRcdFx0XHRyZXR1cm4gYDxkaXYgY2xhc3M9XCJoZWxwLXRvb2x0aXBcIj4ke2UudGFyZ2V0LmRhdGEoJ3RpdGxlJyl9PC9kaXY+YDtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIEFkZCBidXR0b24gZXZlbnQgbGlzdGVuZXJzXG5cdFx0JCgnI2xjbS1yZWZyZXNoQnQnKS5vbignY2xpY2snLCAkLnByb3h5KHRoaXMuX29uUmVmcmVzaENsaWNrLCB0aGlzKSk7XG5cdFx0JCgnI2xjbS1zdWJtaXRCdCcpLm9uKCdjbGljaycsICQucHJveHkodGhpcy5fb25TdWJtaXRDbGljaywgdGhpcykpO1xuXHRcdCQoJyNsY20tdGVzdEJ0Jykub24oJ2NsaWNrJywgJC5wcm94eSh0aGlzLl9vblRlc3RDbGljaywgdGhpcykpO1xuXG5cdFx0Ly8gRGlzYWJsZSBpbnRlcmZhY2Vcblx0XHR0aGlzLl9lbmFibGVJbnRlcmZhY2UoZmFsc2UpO1xuXG5cdFx0Ly8gUmVxdWVzdCBsaWNlbnNlIGRhdGEgdG8gc2VydmVyIGluc3RhbmNlXG5cdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9HRVRfREFUQSk7XG5cdH1cblxuXHRkZXN0cm95KClcblx0e1xuXHRcdC8vIENhbGwgc3VwZXIgbWV0aG9kXG5cdFx0c3VwZXIuZGVzdHJveSgpO1xuXG5cdFx0Ly8gUmVtb3ZlIGJ1dHRvbiBldmVudCBsaXN0ZW5lcnNcblx0XHQkKCcjbGNtLXJlZnJlc2hCdCcpLm9mZignY2xpY2snKTtcblx0XHQkKCcjbGNtLXN1Ym1pdEJ0Jykub2ZmKCdjbGljaycpO1xuXHRcdCQoJyNsY20tdGVzdEJ0Jykub2ZmKCdjbGljaycpO1xuXHR9XG5cblx0b25FeHRlbnNpb25Db21tYW5kKGNvbW1hbmQsIGRhdGEpXG5cdHtcblx0XHQvLyBMaWNlbnNlIGNvbmZpZ3VyYXRpb24gZGF0YSByZWNlaXZlZFxuXHRcdGlmIChjb21tYW5kID09IHRoaXMuUkVTUF9EQVRBKVxuXHRcdHtcblx0XHRcdC8vIENvbmZpZ3VyYXRpb25cblx0XHRcdGlmIChkYXRhLmNvbnRhaW5zS2V5KCdjb2RlJykpXG5cdFx0XHRcdHRoaXMuX2NvZGUgPSBkYXRhLmdldFV0ZlN0cmluZygnY29kZScpO1xuXG5cdFx0XHRpZiAoZGF0YS5jb250YWluc0tleSgnZW1haWxzJykpXG5cdFx0XHRcdHRoaXMuX2VtYWlscyA9IGRhdGEuZ2V0VXRmU3RyaW5nKCdlbWFpbHMnKTtcblxuXHRcdFx0aWYgKGRhdGEuY29udGFpbnNLZXkoJ2FsZXJ0JykpXG5cdFx0XHRcdHRoaXMuX2FsZXJ0ID0gZGF0YS5nZXRCb29sKCdhbGVydCcpO1xuXG5cdFx0XHQvLyBEaXNwbGF5IGN1cnJlbnRseSBydW5uaW5nIGxpY2Vuc2UgZGV0YWlsc1xuXHRcdFx0aWYgKGRhdGEuY29udGFpbnNLZXkoJ2RldGFpbHMnKSlcblx0XHRcdHtcblx0XHRcdFx0bGV0IGxpY0RldGFpbHMgPSBkYXRhLmdldFV0ZlN0cmluZ0FycmF5KCdkZXRhaWxzJyk7XG5cblx0XHRcdFx0JCgnI2xjbS1jdXJyVHlwZScpLnRleHQobGljRGV0YWlsc1swXSk7XG5cdFx0XHRcdCQoJyNsY20tY3Vyck1heFVzZXJzJykudGV4dChsaWNEZXRhaWxzWzFdKTtcblx0XHRcdFx0JCgnI2xjbS1jdXJyT3B0aW9ucycpLnRleHQobGljRGV0YWlsc1syXS5zcGxpdCgnLCcpLmpvaW4oJyB8ICcpKTtcblx0XHRcdFx0JCgnI2xjbS1jdXJyRXhwaXJlJykudGV4dChsaWNEZXRhaWxzWzNdKTtcblx0XHRcdFx0JCgnI2xjbS1jdXJyUHJpdmF0ZScpLnRleHQobGljRGV0YWlsc1s0XSk7XG5cblx0XHRcdFx0aWYgKGxpY0RldGFpbHNbMl0gIT0gJycpXG5cdFx0XHRcdFx0JCgnI2xjbS1jdXJyT3B0aW9ucycpLnBhcmVudCgpLnNob3coKTtcblx0XHRcdFx0ZWxzZVxuXHRcdFx0XHRcdCQoJyNsY20tY3Vyck9wdGlvbnMnKS5wYXJlbnQoKS5oaWRlKCk7XG5cblx0XHRcdFx0aWYgKGxpY0RldGFpbHNbM10gIT0gJycpXG5cdFx0XHRcdFx0JCgnI2xjbS1jdXJyRXhwaXJlJykucGFyZW50KCkuc2hvdygpO1xuXHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0JCgnI2xjbS1jdXJyRXhwaXJlJykucGFyZW50KCkuaGlkZSgpO1xuXG5cdFx0XHRcdGlmIChsaWNEZXRhaWxzWzRdICE9ICcnKVxuXHRcdFx0XHRcdCQoJyNsY20tY3VyclByaXZhdGUnKS5wYXJlbnQoKS5zaG93KCk7XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHQkKCcjbGNtLWN1cnJQcml2YXRlJykucGFyZW50KCkuaGlkZSgpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBEaXNwbGF5IHdhcm5pbmcgaXMgc2VudCBieSB0aGUgc2VydmVyXG5cdFx0XHQvLyBUaGlzIGNhbiBoYXBwZW4gaWYgYSBsaWNlbnNlIHJlZnJlc2ggcmVxdWVzdCB3YXMgc2VudCBhbmQgdGhpcyBjb3VsZG4ndCBiZSBjb21wbGV0ZWQgb3IgY2F1c2VkIHRoZSBsaWNlbnNlIHRvIHJldmVydCB0byBDRVxuXHRcdFx0aWYgKGRhdGEuY29udGFpbnNLZXkoJ3dhcm5pbmcnKSlcblx0XHRcdFx0dGhpcy5zaGVsbEN0cmwuc2hvd1NpbXBsZUFsZXJ0KGRhdGEuZ2V0VXRmU3RyaW5nKCd3YXJuaW5nJykpO1xuXG5cdFx0XHR0aGlzLl9lbmFibGVJbnRlcmZhY2UodHJ1ZSk7XG5cdFx0fVxuXG5cdFx0Ly8gTGljZW5zZSBjb25maWd1cmF0aW9uIHVwZGF0ZSBjb25maXJtYXRpb25cblx0XHRlbHNlIGlmIChjb21tYW5kID09IHRoaXMuUkVTUF9EQVRBX1NBVkVEKVxuXHRcdHtcblx0XHRcdHRoaXMuX2NvZGUgPSBkYXRhLmdldFV0ZlN0cmluZygnY29kZScpO1xuXHRcdFx0dGhpcy5fZW1haWxzID0gZGF0YS5nZXRVdGZTdHJpbmcoJ2VtYWlscycpO1xuXHRcdFx0dGhpcy5fYWxlcnQgPSBkYXRhLmdldEJvb2woJ2FsZXJ0Jyk7XG5cblx0XHRcdC8vIEVuYWJsZSBpbnRlcmZhY2Vcblx0XHRcdHRoaXMuX2VuYWJsZUludGVyZmFjZSh0cnVlKTtcblxuXHRcdFx0Ly8gTG9nIG1lc3NhZ2Vcblx0XHRcdGNvbnN0IHVwZGF0ZXIgPSBkYXRhLmdldFV0ZlN0cmluZygndXNlcicpO1xuXG5cdFx0XHRpZiAodXBkYXRlciA9PSB0aGlzLnNtYXJ0Rm94Lm15U2VsZi5uYW1lKVxuXHRcdFx0e1xuXHRcdFx0XHQvLyBEaXNwbGF5IG5vdGlmaWNhdGlvblxuXHRcdFx0XHR0aGlzLnNoZWxsQ3RybC5zaG93Tm90aWZpY2F0aW9uKGBDb25maWd1cmF0aW9uIHVwZGF0ZWRgLCBgTGljZW5zZSBkZXRhaWxzIHNhdmVkIHN1Y2Nlc3NmdWxseWApO1xuXG5cdFx0XHRcdC8vIFNob3cgc2NyZWVuXG5cdFx0XHRcdHRoaXMuX3N3aXRjaFZpZXcoJ2xjbS1wYW5lbFNhdmVkJyk7XG5cdFx0XHR9XG5cdFx0XHRlbHNlXG5cdFx0XHR7XG5cdFx0XHRcdC8vIERpc3BsYXkgbm90aWZpY2F0aW9uXG5cdFx0XHRcdHRoaXMuc2hlbGxDdHJsLnNob3dOb3RpZmljYXRpb24oYENvbmZpZ3VyYXRpb24gdXBkYXRlZGAsIGBBZG1pbmlzdHJhdG9yICR7dXBkYXRlcn0gaGFzIG1vZGlmaWVkIHRoZSBsaWNlbnNlIGRldGFpbHNgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBSZXNwb25zZSB0byBMaWNlbnNlIFNlcnZlciBjb25uZWN0aW9uIHRlc3QgcmVjZWl2ZWRcblx0XHRlbHNlIGlmIChjb21tYW5kID09IHRoaXMuUkVTUF9URVNUX1JFU1VMVClcblx0XHR7XG5cdFx0XHR0aGlzLl9lbmFibGVJbnRlcmZhY2UodHJ1ZSk7XG5cblx0XHRcdGlmIChkYXRhLmlzTnVsbCgnbHNEYXRhJykpXG5cdFx0XHR7XG5cdFx0XHRcdC8vIFNob3cgc2NyZWVuXG5cdFx0XHRcdHRoaXMuX3N3aXRjaFZpZXcoJ2xjbS1wYW5lbFRlc3RLTycpO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0XHRsZXQgbHNEYXRhID0gZGF0YS5nZXRTRlNPYmplY3QoJ2xzRGF0YScpO1xuXG5cdFx0XHRcdGlmIChsc0RhdGEuZ2V0SW50KCdpZCcpID09IHRoaXMuQ09NTVVOSUNBVElPTl9DSEVDS19LT19MSUNFTlNFX0lOVkFMSUQpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHQvLyBTaG93IHNjcmVlblxuXHRcdFx0XHRcdHRoaXMuX3N3aXRjaFZpZXcoJ2xjbS1wYW5lbFRlc3RPSy1pbnZhbGlkJyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZSBpZiAobHNEYXRhLmdldEludCgnaWQnKSA9PSB0aGlzLkNPTU1VTklDQVRJT05fQ0hFQ0tfT0spXG5cdFx0XHRcdHtcblx0XHRcdFx0XHQvLyBTaG93IHNjcmVlblxuXHRcdFx0XHRcdHRoaXMuX3N3aXRjaFZpZXcoJ2xjbS1wYW5lbFRlc3RPSy12YWxpZCcpO1xuXG5cdFx0XHRcdFx0Ly8gUG9wdWxhdGUgbGljZW5zZSBkZXRhaWxzXG5cdFx0XHRcdFx0JCgnI2xjbS1tYXhVc2VycycpLnRleHQobHNEYXRhLmdldEludCgndXNlcnMnKSA+IDAgPyBsc0RhdGEuZ2V0SW50KCd1c2VycycpLnRvU3RyaW5nKCkgOiAnVW5saW1pdGVkJyk7XG5cdFx0XHRcdFx0JCgnI2xjbS1wcml2YXRlSXAnKS50ZXh0KGxzRGF0YS5nZXRCb29sKCdwcml2YXRlJykgPyAnWWVzJyA6ICdObycpO1xuXHRcdFx0XHRcdCQoJyNsY20tZXhwaXJlJykudGV4dChsc0RhdGEuZ2V0TG9uZygnZXhwaXJlJykgPiAwID8gbW9tZW50KGxzRGF0YS5nZXRMb25nKCdleHBpcmUnKSkuZm9ybWF0KCdERCBNTU0gWVlZWSBISDptbScpICsgJyBHTVQnICsgbW9tZW50KGxzRGF0YS5nZXRMb25nKCdleHBpcmUnKSkuZm9ybWF0KCdaJykgOiAnTmV2ZXInKTtcblx0XHRcdFx0XHQkKCcjbGNtLW9wdGlvbnMnKS50ZXh0KCdOb25lJyk7XG5cblx0XHRcdFx0XHRpZiAobHNEYXRhLmNvbnRhaW5zS2V5KCdvcHRpb25zJykgJiYgbHNEYXRhLmdldFV0ZlN0cmluZygnb3B0aW9ucycpICE9ICcnKVxuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdGxldCBvcHRpb25zID0gbHNEYXRhLmdldFV0ZlN0cmluZygnb3B0aW9ucycpLnNwbGl0KCcsJyk7XG5cdFx0XHRcdFx0XHQkKCcjbGNtLW9wdGlvbnMnKS50ZXh0KG9wdGlvbnMuam9pbignIHwgJykpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cdFx0XHRcdFx0bGV0IGlzRXhwaXJlZCA9IChsc0RhdGEuZ2V0TG9uZygnZXhwaXJlJykgPiAwKSAmJiAobm93ID4gbHNEYXRhLmdldExvbmcoJ2V4cGlyZScpKTtcblxuXHRcdFx0XHRcdGlmIChpc0V4cGlyZWQpXG5cdFx0XHRcdFx0XHQkKCcjbGNtLWV4cGlyZUFsZXJ0Jykuc2hvdygpO1xuXHRcdFx0XHRcdGVsc2Vcblx0XHRcdFx0XHRcdCQoJyNsY20tZXhwaXJlQWxlcnQnKS5oaWRlKCk7XG5cblx0XHRcdFx0XHQvLyBDaGVjayB0aGUgbGljZW5zZSBpbml0aWFsaXphdGlvbiBzdGF0dXNcblx0XHRcdFx0XHRpZiAobHNEYXRhLmdldEJvb2woJ2luaXRTdGF0dXMnKSAmJiAhaXNFeHBpcmVkKVxuXHRcdFx0XHRcdFx0JCgnI2xjbS1pbml0Tm90ZScpLnNob3coKTtcblx0XHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0XHQkKCcjbGNtLWluaXROb3RlJykuaGlkZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gZWxzZSBpZiAoKVxuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8gVUkgRVZFTlQgTElTVEVORVJTXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0X29uU3VibWl0Q2xpY2soKVxuXHR7XG5cdFx0Ly8gVmFsaWRhdGUgZW1haWwgYWRkcmVzc2VzXG5cdFx0Ly8gSW52YWxpZCBhZGRyZXNzZXMgYXJlIHN0cmlwcGVkIG9mZlxuXHRcdGxldCB2YWxpZEVtYWlscyA9IFtdO1xuXG5cdFx0aWYgKCQoJyNsY20tZW1haWxJbicpLnZhbCgpICE9ICcnKVxuXHRcdHtcblx0XHRcdGxldCBlbnRlcmVkRW1haWxzID0gJCgnI2xjbS1lbWFpbEluJykudmFsKCkuc3BsaXQoJywnKTtcblx0XHRcdGNvbnN0IHJlZ0V4cFBhdHRlcm4gPSAvXlswLTlhLXpBLVpdWy0uX2EtekEtWjAtOV0qQChbMC05YS16QS1aXVstLl8wLTlhLXpBLVpdKlxcLikrW2EtekEtWl17Miw0fSQvO1xuXG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGVudGVyZWRFbWFpbHMubGVuZ3RoOyBpKyspXG5cdFx0XHR7XG5cdFx0XHRcdGNvbnN0IGVtYWlsID0gZW50ZXJlZEVtYWlsc1tpXS50cmltKCk7XG5cdFx0XHRcdGlmIChyZWdFeHBQYXR0ZXJuLnRlc3QoZW1haWwpKVxuXHRcdFx0XHRcdHZhbGlkRW1haWxzLnB1c2goZW1haWwpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGxldCBzdWJtaXRFbWFpbHMgPSB2YWxpZEVtYWlscy5qb2luKCcsJyk7XG5cdFx0JCgnI2xjbS1lbWFpbEluJykudmFsKHN1Ym1pdEVtYWlscyk7XG5cblx0XHRpZiAoJCgnI2xjbS1jb2RlSW4nKS52YWwoKSAhPSB0aGlzLl9jb2RlIHx8ICQoJyNsY20tZW1haWxJbicpLnZhbCgpICE9IHRoaXMuX2VtYWlscyB8fCAkKCcjbGNtLWFsZXJ0Q2InKS5kYXRhKCdrZW5kb1N3aXRjaCcpLmNoZWNrKCkgIT0gdGhpcy5fYWxlcnQpXG5cdFx0e1xuXHRcdFx0dGhpcy5fY29kZSA9ICQoJyNsY20tY29kZUluJykudmFsKCk7XG5cdFx0XHR0aGlzLl9lbWFpbHMgPSBzdWJtaXRFbWFpbHM7XG5cdFx0XHR0aGlzLl9hbGVydCA9ICQoJyNsY20tYWxlcnRDYicpLmRhdGEoJ2tlbmRvU3dpdGNoJykuY2hlY2soKTtcblxuXHRcdFx0Ly8gRGlzYWJsZSBpbnRlcmZhY2Vcblx0XHRcdHRoaXMuX2VuYWJsZUludGVyZmFjZShmYWxzZSk7XG5cblx0XHRcdC8vIFN1Ym1pZCBkYXRhXG5cdFx0XHRsZXQgcGFyYW1zID0gbmV3IFNGUzJYLlNGU09iamVjdCgpO1xuXHRcdFx0cGFyYW1zLnB1dFV0ZlN0cmluZygnY29kZScsIHRoaXMuX2NvZGUpO1xuXHRcdFx0cGFyYW1zLnB1dFV0ZlN0cmluZygnZW1haWxzJywgdGhpcy5fZW1haWxzKTtcblx0XHRcdHBhcmFtcy5wdXRCb29sKCdhbGVydCcsIHRoaXMuX2FsZXJ0KTtcblxuXHRcdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9TQVZFX0RBVEEsIHBhcmFtcyk7XG5cdFx0fVxuXHR9XG5cblx0X29uVGVzdENsaWNrKClcblx0e1xuXHRcdC8vIERpc2FibGUgaW50ZXJmYWNlXG5cdFx0dGhpcy5fZW5hYmxlSW50ZXJmYWNlKGZhbHNlKTtcblxuXHRcdC8vIFNlbmQgcmVxdWVzdFxuXHRcdHRoaXMuc2VuZEV4dGVuc2lvblJlcXVlc3QodGhpcy5SRVFfVEVTVF9DT05ORUNUSU9OKTtcblx0fVxuXG5cdF9vblJlZnJlc2hDbGljaygpXG5cdHtcblx0XHQvLyBEaXNhYmxlIGludGVyZmFjZVxuXHRcdHRoaXMuX2VuYWJsZUludGVyZmFjZShmYWxzZSk7XG5cblx0XHQvLyBTZW5kIHJlcXVlc3Rcblx0XHR0aGlzLnNlbmRFeHRlbnNpb25SZXF1ZXN0KHRoaXMuUkVRX1JFRlJFU0hfTElDRU5TRSk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBQUklWQVRFIE1FVEhPRFNcblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRfZW5hYmxlSW50ZXJmYWNlKGVuYWJsZWQpXG5cdHtcblx0XHQkKCcjbGNtLWNvZGVJbicpLnZhbCh0aGlzLl9jb2RlKTtcblx0XHQkKCcjbGNtLWVtYWlsSW4nKS52YWwodGhpcy5fZW1haWxzKTtcblx0XHQkKCcjbGNtLWFsZXJ0Q2InKS5kYXRhKCdrZW5kb1N3aXRjaCcpLmNoZWNrKHRoaXMuX2FsZXJ0KTtcblxuXHRcdCQoJyNsY20tc3VibWl0QnQnKS5hdHRyKCdkaXNhYmxlZCcsICFlbmFibGVkKTtcblx0XHQkKCcjbGNtLXRlc3RCdCcpLmF0dHIoJ2Rpc2FibGVkJywgIShlbmFibGVkICYmIHRoaXMuX2NvZGUgIT0gJycpKTtcblxuXHRcdCQoJyNsY20tcmVmcmVzaEJ0JykuYXR0cignZGlzYWJsZWQnLCAhZW5hYmxlZCk7XG5cdH1cblxuXHRfc3dpdGNoVmlldyh2aWV3SWQpXG5cdHtcblx0XHRkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnbGNtLXJlc3VsdFZTJykuc2VsZWN0ZWRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodmlld0lkKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vIFBSSVZBVEUgR0VUVEVSU1xuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7QSIsInNvdXJjZVJvb3QiOiIifQ==
1132
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzL2pzL2NvcmUvbW9kdWxlcy9tb2R1bGUtNy5idW5kbGUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9hcHBsaWNhdGlvbi8uL25vZGVfbW9kdWxlcy9maWxlLXNhdmVyL2Rpc3QvRmlsZVNhdmVyLm1pbi5qcyIsIndlYnBhY2s6Ly9hcHBsaWNhdGlvbi8od2VicGFjaykvYnVpbGRpbi9nbG9iYWwuanMiLCJ3ZWJwYWNrOi8vYXBwbGljYXRpb24vLi9zcmMvZGF0YS9jb21tYW5kLWhpc3RvcnkuanMiLCJ3ZWJwYWNrOi8vYXBwbGljYXRpb24vLi9zcmMvbW9kdWxlcy9jb25zb2xlLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbihhLGIpe2lmKFwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZClkZWZpbmUoW10sYik7ZWxzZSBpZihcInVuZGVmaW5lZFwiIT10eXBlb2YgZXhwb3J0cyliKCk7ZWxzZXtiKCksYS5GaWxlU2F2ZXI9e2V4cG9ydHM6e319LmV4cG9ydHN9fSkodGhpcyxmdW5jdGlvbigpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIGIoYSxiKXtyZXR1cm5cInVuZGVmaW5lZFwiPT10eXBlb2YgYj9iPXthdXRvQm9tOiExfTpcIm9iamVjdFwiIT10eXBlb2YgYiYmKGNvbnNvbGUud2FybihcIkRlcHJlY2F0ZWQ6IEV4cGVjdGVkIHRoaXJkIGFyZ3VtZW50IHRvIGJlIGEgb2JqZWN0XCIpLGI9e2F1dG9Cb206IWJ9KSxiLmF1dG9Cb20mJi9eXFxzKig/OnRleHRcXC9cXFMqfGFwcGxpY2F0aW9uXFwveG1sfFxcUypcXC9cXFMqXFwreG1sKVxccyo7LipjaGFyc2V0XFxzKj1cXHMqdXRmLTgvaS50ZXN0KGEudHlwZSk/bmV3IEJsb2IoW1wiXFx1RkVGRlwiLGFdLHt0eXBlOmEudHlwZX0pOmF9ZnVuY3Rpb24gYyhiLGMsZCl7dmFyIGU9bmV3IFhNTEh0dHBSZXF1ZXN0O2Uub3BlbihcIkdFVFwiLGIpLGUucmVzcG9uc2VUeXBlPVwiYmxvYlwiLGUub25sb2FkPWZ1bmN0aW9uKCl7YShlLnJlc3BvbnNlLGMsZCl9LGUub25lcnJvcj1mdW5jdGlvbigpe2NvbnNvbGUuZXJyb3IoXCJjb3VsZCBub3QgZG93bmxvYWQgZmlsZVwiKX0sZS5zZW5kKCl9ZnVuY3Rpb24gZChhKXt2YXIgYj1uZXcgWE1MSHR0cFJlcXVlc3Q7Yi5vcGVuKFwiSEVBRFwiLGEsITEpO3RyeXtiLnNlbmQoKX1jYXRjaChhKXt9cmV0dXJuIDIwMDw9Yi5zdGF0dXMmJjI5OT49Yi5zdGF0dXN9ZnVuY3Rpb24gZShhKXt0cnl7YS5kaXNwYXRjaEV2ZW50KG5ldyBNb3VzZUV2ZW50KFwiY2xpY2tcIikpfWNhdGNoKGMpe3ZhciBiPWRvY3VtZW50LmNyZWF0ZUV2ZW50KFwiTW91c2VFdmVudHNcIik7Yi5pbml0TW91c2VFdmVudChcImNsaWNrXCIsITAsITAsd2luZG93LDAsMCwwLDgwLDIwLCExLCExLCExLCExLDAsbnVsbCksYS5kaXNwYXRjaEV2ZW50KGIpfX12YXIgZj1cIm9iamVjdFwiPT10eXBlb2Ygd2luZG93JiZ3aW5kb3cud2luZG93PT09d2luZG93P3dpbmRvdzpcIm9iamVjdFwiPT10eXBlb2Ygc2VsZiYmc2VsZi5zZWxmPT09c2VsZj9zZWxmOlwib2JqZWN0XCI9PXR5cGVvZiBnbG9iYWwmJmdsb2JhbC5nbG9iYWw9PT1nbG9iYWw/Z2xvYmFsOnZvaWQgMCxhPWYuc2F2ZUFzfHwoXCJvYmplY3RcIiE9dHlwZW9mIHdpbmRvd3x8d2luZG93IT09Zj9mdW5jdGlvbigpe306XCJkb3dubG9hZFwiaW4gSFRNTEFuY2hvckVsZW1lbnQucHJvdG90eXBlP2Z1bmN0aW9uKGIsZyxoKXt2YXIgaT1mLlVSTHx8Zi53ZWJraXRVUkwsaj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtnPWd8fGIubmFtZXx8XCJkb3dubG9hZFwiLGouZG93bmxvYWQ9ZyxqLnJlbD1cIm5vb3BlbmVyXCIsXCJzdHJpbmdcIj09dHlwZW9mIGI/KGouaHJlZj1iLGoub3JpZ2luPT09bG9jYXRpb24ub3JpZ2luP2Uoaik6ZChqLmhyZWYpP2MoYixnLGgpOmUoaixqLnRhcmdldD1cIl9ibGFua1wiKSk6KGouaHJlZj1pLmNyZWF0ZU9iamVjdFVSTChiKSxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7aS5yZXZva2VPYmplY3RVUkwoai5ocmVmKX0sNEU0KSxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ZShqKX0sMCkpfTpcIm1zU2F2ZU9yT3BlbkJsb2JcImluIG5hdmlnYXRvcj9mdW5jdGlvbihmLGcsaCl7aWYoZz1nfHxmLm5hbWV8fFwiZG93bmxvYWRcIixcInN0cmluZ1wiIT10eXBlb2YgZiluYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYihiKGYsaCksZyk7ZWxzZSBpZihkKGYpKWMoZixnLGgpO2Vsc2V7dmFyIGk9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImFcIik7aS5ocmVmPWYsaS50YXJnZXQ9XCJfYmxhbmtcIixzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ZShpKX0pfX06ZnVuY3Rpb24oYSxiLGQsZSl7aWYoZT1lfHxvcGVuKFwiXCIsXCJfYmxhbmtcIiksZSYmKGUuZG9jdW1lbnQudGl0bGU9ZS5kb2N1bWVudC5ib2R5LmlubmVyVGV4dD1cImRvd25sb2FkaW5nLi4uXCIpLFwic3RyaW5nXCI9PXR5cGVvZiBhKXJldHVybiBjKGEsYixkKTt2YXIgZz1cImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiPT09YS50eXBlLGg9L2NvbnN0cnVjdG9yL2kudGVzdChmLkhUTUxFbGVtZW50KXx8Zi5zYWZhcmksaT0vQ3JpT1NcXC9bXFxkXSsvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7aWYoKGl8fGcmJmgpJiZcIm9iamVjdFwiPT10eXBlb2YgRmlsZVJlYWRlcil7dmFyIGo9bmV3IEZpbGVSZWFkZXI7ai5vbmxvYWRlbmQ9ZnVuY3Rpb24oKXt2YXIgYT1qLnJlc3VsdDthPWk/YTphLnJlcGxhY2UoL15kYXRhOlteO10qOy8sXCJkYXRhOmF0dGFjaG1lbnQvZmlsZTtcIiksZT9lLmxvY2F0aW9uLmhyZWY9YTpsb2NhdGlvbj1hLGU9bnVsbH0sai5yZWFkQXNEYXRhVVJMKGEpfWVsc2V7dmFyIGs9Zi5VUkx8fGYud2Via2l0VVJMLGw9ay5jcmVhdGVPYmplY3RVUkwoYSk7ZT9lLmxvY2F0aW9uPWw6bG9jYXRpb24uaHJlZj1sLGU9bnVsbCxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ay5yZXZva2VPYmplY3RVUkwobCl9LDRFNCl9fSk7Zi5zYXZlQXM9YS5zYXZlQXM9YSxcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlJiYobW9kdWxlLmV4cG9ydHM9YSl9KTtcblxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmlsZVNhdmVyLm1pbi5qcy5tYXAiLCJ2YXIgZztcblxuLy8gVGhpcyB3b3JrcyBpbiBub24tc3RyaWN0IG1vZGVcbmcgPSAoZnVuY3Rpb24oKSB7XG5cdHJldHVybiB0aGlzO1xufSkoKTtcblxudHJ5IHtcblx0Ly8gVGhpcyB3b3JrcyBpZiBldmFsIGlzIGFsbG93ZWQgKHNlZSBDU1ApXG5cdGcgPSBnIHx8IG5ldyBGdW5jdGlvbihcInJldHVybiB0aGlzXCIpKCk7XG59IGNhdGNoIChlKSB7XG5cdC8vIFRoaXMgd29ya3MgaWYgdGhlIHdpbmRvdyByZWZlcmVuY2UgaXMgYXZhaWxhYmxlXG5cdGlmICh0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiKSBnID0gd2luZG93O1xufVxuXG4vLyBnIGNhbiBzdGlsbCBiZSB1bmRlZmluZWQsIGJ1dCBub3RoaW5nIHRvIGRvIGFib3V0IGl0Li4uXG4vLyBXZSByZXR1cm4gdW5kZWZpbmVkLCBpbnN0ZWFkIG9mIG5vdGhpbmcgaGVyZSwgc28gaXQnc1xuLy8gZWFzaWVyIHRvIGhhbmRsZSB0aGlzIGNhc2UuIGlmKCFnbG9iYWwpIHsgLi4ufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGc7XG4iLCJleHBvcnQgY2xhc3MgQ29tbWFuZEhpc3Rvcnlcbntcblx0Y29uc3RydWN0b3Ioc2l6ZSA9IDUwKVxuXHR7XG5cdFx0dGhpcy5fc2l6ZSA9IHNpemU7XG5cblx0XHQvLyBUT0RPXG5cdFx0Ly8gQXMgdGhlIGhpc3RvcnkgaXMgc2F2ZWQgaW4gY29va2llcywgYW5kIHRoZXkgYXJlIG5vdyBsaW1pdGVkIHRvIDQgS0Igc2l6ZSxcblx0XHQvLyB0aGlzIGNsYXNzIHNob3VsZCBiZSB1cGRhdGVkIHRvIHJlbW92ZSBlbnRyaWVzIGJhc2VkIG9uIHRoZSB0b3RhbCBzaXplLFxuXHRcdC8vIGFuZCBub3Qgb24gdGhlIHRvdGFsIG51bWJlciBvZiBpdGVtcyBhbnltb3JlXG5cblx0XHR0aGlzLmNsZWFyKCk7XG5cdFx0dGhpcy5fbG9hZFN0YXRlKCk7XG5cdH1cblxuXHRhZGRDb21tYW5kKGNtZClcblx0e1xuXHRcdGlmICh0aGlzLl9oaXN0b3J5Lmxlbmd0aCA+PSB0aGlzLl9zaXplKVxuXHRcdFx0dGhpcy5faGlzdG9yeS5zcGxpY2UoMCwgMSk7XG5cblx0XHR0aGlzLl9oaXN0b3J5LnB1c2goY21kKTtcblx0XHR0aGlzLl9wb3MgPSB0aGlzLl9oaXN0b3J5Lmxlbmd0aDtcblx0XHR0aGlzLl90ZW1wQ21kID0gJyc7XG5cblx0XHR0aGlzLl9zYXZlU3RhdGUoKTtcblx0fVxuXG5cdGFkZFRlbXBDb21tYW5kKGNtZClcblx0e1xuXHRcdHRoaXMuX3RlbXBDbWQgPSBjbWQ7XG5cdFx0dGhpcy5fcG9zID0gdGhpcy5faGlzdG9yeS5sZW5ndGg7XG5cdH1cblxuXHRyZXdpbmQoKVxuXHR7XG5cdFx0aWYgKHRoaXMuX3BvcyA+IDApXG5cdFx0XHR0aGlzLl9wb3MtLTtcblxuXHRcdHJldHVybiB0aGlzLl9oaXN0b3J5W3RoaXMuX3Bvc107XG5cdH1cblxuXHRmb3J3YXJkKClcblx0e1xuXHRcdGlmICh0aGlzLl9wb3MgPCB0aGlzLl9oaXN0b3J5Lmxlbmd0aClcblx0XHRcdHRoaXMuX3BvcysrO1xuXG5cdFx0aWYgKHRoaXMuX3BvcyA8PSB0aGlzLl9oaXN0b3J5Lmxlbmd0aCAtIDEpXG5cdFx0XHRyZXR1cm4gdGhpcy5faGlzdG9yeVt0aGlzLl9wb3NdO1xuXHRcdGVsc2Vcblx0XHRcdHJldHVybiB0aGlzLl90ZW1wQ21kO1xuXHR9XG5cblx0Z2V0TGlzdCgpXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5faGlzdG9yeTtcblx0fVxuXG5cdGdldFNpemUoKVxuXHR7XG5cdFx0cmV0dXJuIHRoaXMuX2hpc3RvcnkubGVuZ3RoXG5cdH1cblxuXHRjbGVhcigpXG5cdHtcblx0XHR0aGlzLl9oaXN0b3J5ID0gW107XG5cdFx0dGhpcy5fcG9zID0gMDtcblx0XHR0aGlzLl90ZW1wQ21kID0gJyc7XG5cdH1cblxuXHRfc2F2ZVN0YXRlKClcblx0e1xuXHRcdENvb2tpZXMuc2V0KCdjb25zb2xlLWhpc3RvcnknLCB7XG5cdFx0XHRoaXN0b3J5OiB0aGlzLl9oaXN0b3J5XG5cdFx0fSwge2V4cGlyZXM6IDM2MDAwfSk7XG5cdH1cblxuXHRfbG9hZFN0YXRlKClcblx0e1xuXHRcdGxldCBkYXRhID0gQ29va2llcy5nZXRKU09OKCdjb25zb2xlLWhpc3RvcnknKVxuXG5cdFx0aWYgKGRhdGEpXG5cdFx0e1xuXHRcdFx0dGhpcy5faGlzdG9yeSA9IGRhdGEuaGlzdG9yeTtcblx0XHRcdHRoaXMuX3BvcyA9IHRoaXMuX2hpc3RvcnkubGVuZ3RoO1xuXHRcdH1cblx0fVxufVxuIiwiaW1wb3J0IHtCYXNlTW9kdWxlfSBmcm9tICcuL2Jhc2UtbW9kdWxlJztcbmltcG9ydCB7Q29tbWFuZEhpc3Rvcnl9IGZyb20gJy4uL2RhdGEvY29tbWFuZC1oaXN0b3J5JztcbmltcG9ydCAqIGFzIEZpbGVTYXZlciBmcm9tICdmaWxlLXNhdmVyJztcbmltcG9ydCAqIGFzIG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHtieXRlc1RvU2l6ZX0gZnJvbSAnLi4vdXRpbHMvdXRpbGl0aWVzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29uc29sZSBleHRlbmRzIEJhc2VNb2R1bGVcbntcblx0Y29uc3RydWN0b3IoKVxuXHR7XG5cdCAgICBzdXBlcignY29uc29sZScpO1xuXG5cdFx0Ly8gT3V0Z29pbmcgcmVxdWVzdHNcblx0XHR0aGlzLlJFUV9DTUQgPSAnY21kJztcblx0XHR0aGlzLlJFUV9ISU5UID0gJ2hpbnQnO1xuXHRcdHRoaXMuUkVRX1NDUklQVCA9ICdzY3JpcHQnO1xuXG5cdFx0Ly8gSW5jb21pbmcgcmVzcG9uc2VzXG5cdFx0dGhpcy5SRVNfQ01EID0gJ2NtZCc7XG5cdFx0dGhpcy5SRVNfSElOVCA9ICdoaW50Jztcblx0XHR0aGlzLlJFU19TQ1JJUFQgPSAnc2NyaXB0Jztcblx0XHR0aGlzLlJFU19FUlJPUl9MT0NLRUQgPSAnbG9ja2VkJztcblxuXHRcdHRoaXMuVkVSU0lPTiA9ICczLjAuMCc7XG5cdFx0dGhpcy5UT0tFTlMgPSBbJz0nLCAnZnJvbSAnLCAnaW1wb3J0ICddO1xuXG5cdFx0dGhpcy5UUkFOU0NSSVBUX1RFTVBMQVRFID0gYFxuXHRcdDxodG1sPlxuXHRcdDxoZWFkPlxuXHRcdFx0PHRpdGxlPlNGUzJYIEFETUlOIENPTlNPTEUgU2Vzc2lvbiBUcmFuc2NyaXB0PC90aXRsZT5cblx0XHRcdDxzdHlsZSB0eXBlPSd0ZXh0L2NzcycgbWVkaWE9J3NjcmVlbic+XG5cdFx0XHRcdGJvZHksIHByZSB7XG5cdFx0XHRcdFx0YmFja2dyb3VuZC1jb2xvcjogIzMzMztcblx0XHRcdFx0XHRmb250LXNpemU6IC44cmVtO1xuXHRcdFx0XHRcdGZvbnQtZmFtaWx5OiBNb25hY28sJ0NvdXJpZXIgTmV3JywgbW9ub3NwYWNlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aDMge1xuXHRcdFx0XHRcdGNvbG9yOiAjZjhmOWZhO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cHJlIHtcblx0XHRcdFx0XHR3aGl0ZS1zcGFjZTogcHJlLXdyYXA7XG5cdFx0XHRcdFx0LW1vei10YWItc2l6ZTogNTtcblx0XHRcdFx0XHR0YWItc2l6ZTogNTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC50ZXh0LWNvbnNvbGUge1xuXHRcdFx0XHRcdGNvbG9yOiAjMjhGMzJEO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0LnRleHQtZXJyb3Ige1xuXHRcdFx0XHRcdGNvbG9yOiAjZGMzNTQ1O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0LnRleHQtaGlnaGxpZ2h0IHtcblx0XHRcdFx0XHRjb2xvcjogI2ZmYzEwNztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC50ZXh0LWNvbW1hbmQge1xuXHRcdFx0XHRcdGNvbG9yOiAjZjhmOWZhO1xuXHRcdFx0XHR9XG5cdFx0XHQ8L3N0eWxlPlxuXHRcdDwvaGVhZD5cblx0XHQ8Ym9keT5cblx0XHRcdDxoMz48IS0tSEVBREVSLS0+PC9oMz5cblx0XHRcdDxwcmU+PCEtLVRSQU5TQ1JJUFQtLT48L3ByZT5cblx0XHQ8L2JvZHk+XG5cdFx0PC9odG1sPlxuXHRcdGA7XG5cblx0XHR0aGlzLl9jbWRIaXN0b3J5ID0gbmV3IENvbW1hbmRIaXN0b3J5KCk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBDT01NT04gTU9EVUxFIElOVEVSRkFDRSBNRVRIT0RTXG5cdC8vIFRoaXMgbWVtYmVycyBhcmUgdXNlZCBieSB0aGUgbWFpbiBjb250cm9sbGVyXG5cdC8vIHRvIGNvbW11bmljYXRlIHdpdGggdGhlIG1vZHVsZSdzIGNvbnRyb2xsZXIuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0aW5pdGlhbGl6ZShpZERhdGEsIHNoZWxsQ29udHJvbGxlcilcblx0e1xuXHRcdC8vIENhbGwgc3VwZXIgbWV0aG9kXG5cdFx0c3VwZXIuaW5pdGlhbGl6ZShpZERhdGEsIHNoZWxsQ29udHJvbGxlcik7XG5cblx0XHQkKCcjY25zLWlucHV0Jykub24oJ2tleXVwJywgJC5wcm94eSh0aGlzLm9uSW5wdXRLZXlVcCwgdGhpcykpO1xuXHRcdCQoJyNjbnMtaW5wdXQnKS5vbigna2V5ZG93bicsICQucHJveHkodGhpcy5vbklucHV0S2V5RG93biwgdGhpcykpO1xuXG5cdFx0Ly8gU2hvdyB3ZWxjb21lIG1lc3NhZ2Vcblx0XHR0aGlzLl9zaG93V2VsY29tZU1lc3NhZ2UoKTtcblxuXHRcdC8vIEZvY3VzIG9uIHByb21wdCBpbnB1dFxuXHRcdCQoJyNjbnMtaW5wdXQnKS5mb2N1cygpO1xuXG5cdFx0Ly8gQWRkIGdsb2JhbCBjbGljayBsaXN0ZW5lciB0byBjbG9zZSBoaW50IHBhbmVsXG5cdFx0JCh0aGlzKS5vbignY2xpY2snLCAkLnByb3h5KHRoaXMuX29uR2VuZXJpY0NsaWNrLCB0aGlzKSk7XG5cblx0XHQvLyBBZGQgZ2xvYmFsIHdpbmRvdyByZXNpemUgbGlzdGVuZXIgdG8gY2xvc2UgaGludCBwYW5lbFxuXHRcdCQod2luZG93KS5vbigncmVzaXplJywgJC5wcm94eSh0aGlzLl9vbkdlbmVyaWNDbGljaywgdGhpcykpO1xuXG5cdFx0Ly8gQWRkIGJ1dHRvbnMgY2xpY2sgbGlzdGVuZXJzXG5cdFx0JCgnI2Nucy1jbGVhckJ1dHRvbicpLm9uKCdjbGljaycsICQucHJveHkodGhpcy5fb25DbGVhckNvbnNvbGVDbGljaywgdGhpcykpO1xuXHRcdCQoJyNjbnMtcnVuQnV0dG9uJykub24oJ2NsaWNrJywgJC5wcm94eSh0aGlzLl9vblJ1blNjcmlwdENsaWNrLCB0aGlzKSk7XG5cdFx0JCgnI2Nucy1leHBvcnRCdXR0b24nKS5vbignY2xpY2snLCAkLnByb3h5KHRoaXMuX29uRXhwb3J0U2Vzc2lvbkNsaWNrLCB0aGlzKSk7XG5cblx0XHQvLyBJbml0aWFsaXplIFwidXBsb2FkIHNjcmlwdFwiIG1vZGFsXG5cdFx0dGhpcy5fdXBsb2FkU2NyaXB0TW9kYWwgPSAkKCcjY25zLXVwbG9hZE1vZGFsJyk7XG5cdFx0dGhpcy5fdXBsb2FkU2NyaXB0TW9kYWwubW9kYWwoe1xuXHRcdFx0YmFja2Ryb3A6ICdzdGF0aWMnLFxuXHRcdFx0a2V5Ym9hcmQ6IGZhbHNlLFxuXHRcdFx0c2hvdzogZmFsc2Vcblx0XHR9KTtcblxuXHRcdC8vIEluaXRpYWxpemUga2VuZG8gdXBsb2FkZXJcblx0XHR0aGlzLl91cGxvYWRlciA9ICQoJyNjbnMtdXBsb2FkZXInKS5rZW5kb1VwbG9hZCh7XG5cdFx0XHRhbGxvd2VkRXh0ZW5zaW9uczogWycucHknXSxcblx0XHRcdG11bHRpcGxlOiBmYWxzZSxcblx0XHRcdHRlbXBsYXRlOiBmdW5jdGlvbihkYXRhSXRlbSkge1xuXHRcdFx0XHRkYXRhSXRlbS5ieXRlc1RvU2l6ZSA9IGJ5dGVzVG9TaXplOyAvLyBQYXNzIGJ5dGVzVG9TaXplIHV0aWxpdHkgZnVuY3Rpb24gdG8gdGVtcGxhdGVcblx0XHRcdFx0cmV0dXJuIGtlbmRvLnRlbXBsYXRlKGBcblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz0nay1wcm9ncmVzcyB3LTEwMCc+PC9zcGFuPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwiXCI+XG5cdFx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cImstZmlsZS1uYW1lXCIgdGl0bGU9XCIjPW5hbWUjXCI+Iz1uYW1lIzwvc3Bhbj5cblx0XHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwiay1maWxlLXNpemVcIj5TaXplOiAjPWJ5dGVzVG9TaXplKHNpemUsIDEsICdCeXRlcycpIzwvc3Bhbj5cblx0XHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdGApKGRhdGFJdGVtKTtcblx0XHRcdH0sXG5cdCAgICAgICAgbG9jYWxpemF0aW9uOiB7XG5cdCAgICAgICAgICAgIHNlbGVjdDogJ1NlbGVjdCBmaWxlLi4uJ1xuXHQgICAgICAgIH1cblx0XHR9KS5kYXRhKCdrZW5kb1VwbG9hZCcpO1xuXG5cdFx0Ly8gQWRkIGxpc3RlbmVyIHRvIG1vZGFsIGhpZGUgZXZlbnRcblx0XHR0aGlzLl91cGxvYWRTY3JpcHRNb2RhbC5vbignaGlkZGVuLmJzLm1vZGFsJywgJC5wcm94eSh0aGlzLl9vblVwbG9hZFNjcmlwdHJNb2RhbEhpZGRlbiwgdGhpcykpO1xuXG5cdFx0Ly8gQWRkIGxpc3RlbmVyIHRvIG1vZGFsIGJ1dHRvblxuXHRcdCQoJyNjbnMtdXBsb2FkU2NyaXB0QnV0dG9uJykub24oJ2NsaWNrJywgJC5wcm94eSh0aGlzLl9vblVwbG9hZFNjcmlwdHJCdXR0b25DTGljaywgdGhpcykpO1xuXHR9XG5cblx0ZGVzdHJveSgpXG5cdHtcblx0XHQvLyBDYWxsIHN1cGVyIG1ldGhvZFxuXHRcdHN1cGVyLmRlc3Ryb3koKTtcblxuXHRcdCQoJyNjbnMtY2xlYXJCdXR0b24nKS5vZmYoJ2NsaWNrJyk7XG5cdFx0JCgnI2Nucy1ydW5CdXR0b24nKS5vZmYoJ2NsaWNrJyk7XG5cdFx0JCgnI2Nucy1leHBvcnRCdXR0b24nKS5vZmYoJ2NsaWNrJyk7XG5cdFx0JCgnI2Nucy11cGxvYWRTY3JpcHRCdXR0b24nKS5vZmYoJ2NsaWNrJyk7XG5cblx0XHQkKHRoaXMpLm9mZignY2xpY2snKTtcblx0XHQkKHdpbmRvdykub2ZmKCdyZXNpemUnKTtcblxuXHRcdHRoaXMuX3VwbG9hZFNjcmlwdE1vZGFsLm9mZignaGlkZGVuLmJzLm1vZGFsJyk7XG5cdFx0dGhpcy5fdXBsb2FkU2NyaXB0TW9kYWwubW9kYWwoJ2Rpc3Bvc2UnKTtcblx0fVxuXG5cdG9uRXh0ZW5zaW9uQ29tbWFuZChjb21tYW5kLCBkYXRhKVxuXHR7XG5cdFx0aWYgKGNvbW1hbmQgPT0gdGhpcy5SRVNfQ01EIHx8IGNvbW1hbmQgPT0gdGhpcy5SRVNfU0NSSVBUKVxuXHRcdHtcblx0XHRcdGNvbnN0IHJlc3VsdCA9IGRhdGEuZ2V0VXRmU3RyaW5nKCdyJyk7XG5cdFx0XHRjb25zdCBlcnJvciA9IGRhdGEuZ2V0VXRmU3RyaW5nKCdlJyk7XG5cblx0XHRcdGlmIChyZXN1bHQgIT0gbnVsbClcblx0XHRcdFx0dGhpcy5fd3JpdGVDb25zb2xlKHJlc3VsdCk7XG5cdFx0XHRlbHNlIGlmIChlcnJvciAhPSBudWxsKVxuXHRcdFx0XHR0aGlzLl93cml0ZUNvbnNvbGUoYDxzcGFuIGNsYXNzPVwidGV4dC1lcnJvclwiPkVSUk9SPC9zcGFuPiAke3RoaXMuX3BhcnNlSHRtbChlcnJvcil9YCk7XG5cdFx0fVxuXG5cdFx0ZWxzZSBpZiAoY29tbWFuZCA9PSB0aGlzLlJFU19ISU5UKVxuXHRcdHtcblx0XHRcdHRoaXMuX2xhc3RIaW50cyA9IGRhdGEuZ2V0VXRmU3RyaW5nQXJyYXkoJ2gnKTtcblxuXHRcdFx0dGhpcy5fc2hvd0hpbnRQYW5lbCgpO1xuXHRcdH1cblxuXHRcdGVsc2UgaWYgKGNvbW1hbmQgPT0gdGhpcy5SRVNfRVJST1JfTE9DS0VEKVxuXHRcdHtcblx0XHRcdHRoaXMuX3dyaXRlQ29uc29sZShgPHNwYW4gY2xhc3M9XCJ0ZXh0LWVycm9yXCI+RVJST1I8L3NwYW4+IDxzcGFuIGNsYXNzPVwidGV4dC1oaWdobGlnaHRcIj5Db25zb2xlIG1vZHVsZSBpcyBsb2NrZWQgZnJvbSBzZXJ2ZXIgc2lkZS4gUGxlYXNlIGZvbGxvdyB0aGUgaW5zdHJ1Y3Rpb25zIHlvdSB3ZXJlIGdpdmVuIHRvIHVubG9jayBpdC48L3NwYW4+YCk7XG5cdFx0fVxuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8gVUkgRVZFTlQgTElTVEVORVJTXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0b25JbnB1dEtleURvd24oZSlcblx0e1xuXHRcdC8vIFNhdmUgcHJldmlvdXMgaW5wdXQgdmFsdWVcblx0XHR0aGlzLl9wcmV2SW5wdXQgPSAkKCcjY25zLWlucHV0JykudmFsKCk7XG5cblx0XHRjb25zdCBrZXlOYW1lID0gZS5rZXk7XG5cblx0XHRpZiAoa2V5TmFtZSA9PSAnQXJyb3dVcCcgfHwga2V5TmFtZSA9PSAnQXJyb3dEb3duJyB8fCBrZXlOYW1lID09ICdUYWInKVxuXHRcdHtcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cdH1cblxuXHRvbklucHV0S2V5VXAoZSlcblx0e1xuXHRcdGNvbnN0IGtleU5hbWUgPSBlLmtleTtcblx0XHRjb25zdCBpbnB1dCA9ICQoJyNjbnMtaW5wdXQnKS52YWwoKTtcblxuXHRcdC8vIENvcHkgaW5wdXQgdG8gZHVtbXlcblx0XHQkKCcjY25zLWlucHV0LWR1bW15JykuaHRtbChpbnB1dCk7XG5cblx0XHQvLy0tLSBET1QgKENPREUgSElOVElORykgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHRpZiAoa2V5TmFtZSA9PSAnLicpXG5cdFx0e1xuXHRcdFx0Ly8gQ2xvc2UgaGludCBwYW5lbCBpZiBvcGVuXG5cdFx0XHRpZiAodGhpcy5faXNIaW50UGFuZWxPcGVuKVxuXHRcdFx0XHR0aGlzLl9jbG9zZUhpbnRQYW5lbCgpO1xuXG5cdFx0XHQvLyBSZXF1ZXN0IGNvZGUgaGludHNcblx0XHRcdHRoaXMuX3JlcXVlc3RIaW50cyhpbnB1dCk7XG5cdFx0fVxuXG5cdFx0Ly8tLS0gRU5URVIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdFx0ZWxzZSBpZlx0KGtleU5hbWUgPT0gJ0VudGVyJyAmJiBpbnB1dC5sZW5ndGggPiAwKVxuXHRcdHtcblx0XHRcdC8vIEdldCBzZWxlY3RlZCBoaW50XG5cdFx0XHRpZiAodGhpcy5faXNIaW50UGFuZWxPcGVuKVxuXHRcdFx0e1xuXHRcdFx0XHRpZiAodGhpcy5faGludFBhbmVsLmZpbmQoJy5oaW50LWl0ZW0uc2VsZWN0ZWQnKS5sZW5ndGggPiAwKVxuXHRcdFx0XHRcdHRoaXMuX3NldElucHV0T25IaW50U2VsZWN0ZWQoKTtcblx0XHRcdH1cblx0XHRcdGVsc2Vcblx0XHRcdHtcblx0XHRcdFx0Ly8gU2VuZCBjb21tYW5kIHRvIHNlcnZlclxuXHRcdFx0XHRsZXQgc2ZzbyA9IG5ldyBTRlMyWC5TRlNPYmplY3QoKTtcblx0XHRcdFx0c2Zzby5wdXRVdGZTdHJpbmcoJ2MnLCBpbnB1dCk7XG5cdFx0XHRcdHRoaXMuc2VuZEV4dGVuc2lvblJlcXVlc3QodGhpcy5SRVFfQ01ELCBzZnNvKTtcblxuXHRcdFx0XHQvLyBXcml0ZSBjb21tYW5kIHRvIGNvbnNvbGVcblx0XHRcdFx0dGhpcy5fd3JpdGVDb25zb2xlKGlucHV0LCB0cnVlKTtcblxuXHRcdFx0XHQvLyBDbGVhciBoaW50c1xuXHRcdFx0XHR0aGlzLl9sYXN0SGludHMgPSBudWxsO1xuXG5cdFx0XHRcdC8vIENsZWFyIGlucHV0XG5cdFx0XHRcdHRoaXMuX2NsZWFySW5wdXQoKTtcblxuXHRcdFx0XHQvLyBBZGQgY29tbWFuZCB0byBoaXN0b3J5XG5cdFx0XHRcdHRoaXMuX2NtZEhpc3RvcnkuYWRkQ29tbWFuZChpbnB1dCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8tLS0gRU5URVIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdFx0ZWxzZSBpZlx0KGtleU5hbWUgPT0gJ1RhYicpXG5cdFx0e1xuXHRcdFx0Ly8gR2V0IHNlbGVjdGVkIGhpbnRcblx0XHRcdGlmICh0aGlzLl9pc0hpbnRQYW5lbE9wZW4pXG5cdFx0XHR7XG5cdFx0XHRcdGlmICh0aGlzLl9oaW50UGFuZWwuZmluZCgnLmhpbnQtaXRlbS5zZWxlY3RlZCcpLmxlbmd0aCA+IDApXG5cdFx0XHRcdFx0dGhpcy5fc2V0SW5wdXRPbkhpbnRTZWxlY3RlZCgpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vLS0tIENUUkwrQkFDS1NQQUNFIChDTEVBUiBDT05TT0xFKSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHRcdGVsc2UgaWYgKGUuY3RybEtleSAmJiBrZXlOYW1lID09ICdCYWNrc3BhY2UnKVxuXHRcdHtcblx0XHRcdHRoaXMuX29uQ2xlYXJDb25zb2xlQ2xpY2soKTtcblx0XHR9XG5cblx0XHQvLy0tLSBCQUNLU1BBQ0UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdFx0ZWxzZSBpZiAoa2V5TmFtZSA9PSAnQmFja3NwYWNlJylcblx0XHR7XG5cdFx0XHQvLyBDaGVjayB0aGUgZGVsZXRlZCBjaGFyXG5cdFx0XHRpZiAodGhpcy5fcHJldklucHV0LnN1YnN0cmluZyh0aGlzLl9wcmV2SW5wdXQubGVuZ3RoIC0gMSkgPT0gJy4nKVxuXHRcdFx0e1xuXHRcdFx0XHQvLyBSZXNldCBoaW50aW5nXG5cdFx0XHRcdHRoaXMuX3Jlc2V0SGludGluZyhpbnB1dCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFVwZGF0ZSBoaW50IHBhbmVsIGlmIG9wZW5cblx0XHRcdGlmICh0aGlzLl9pc0hpbnRQYW5lbE9wZW4pXG5cdFx0XHRcdHRoaXMuX3VwZGF0ZUhpbnRQYW5lbCgpO1xuXHRcdH1cblxuXHRcdC8vLS0tIEVTQyAoQ0xFQVIpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHRcdGVsc2UgaWYgKGtleU5hbWUgPT0gJ0VzY2FwZScpXG5cdFx0e1xuXHRcdFx0Ly8gQ2xvc2UgaGludCBwYW5lbCBpZiBvcGVuXG5cdFx0XHRpZiAodGhpcy5faXNIaW50UGFuZWxPcGVuKVxuXHRcdFx0XHR0aGlzLl9jbG9zZUhpbnRQYW5lbCgpO1xuXG5cdFx0XHRlbHNlXG5cdFx0XHR7XG5cdFx0XHRcdC8vIENsZWFyIGhpbnRzXG5cdFx0XHRcdHRoaXMuX2xhc3RIaW50cyA9IG51bGw7XG5cblx0XHRcdFx0Ly8gQ2xlYXIgaW5wdXRcblx0XHRcdFx0dGhpcy5fY2xlYXJJbnB1dCgpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vLS0tIEFSUk9XIFVQIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHRcdGVsc2UgaWYgKGtleU5hbWUgPT0gJ0Fycm93VXAnKVxuXHRcdHtcblx0XHRcdC8vIElmIGhpbnQgcGFuZWwgaXMgb3Blbiwgc2V0IHNlbGVjdGlvblxuXHRcdFx0aWYgKHRoaXMuX2lzSGludFBhbmVsT3Blbilcblx0XHRcdHtcblx0XHRcdFx0dGhpcy5fY3VyckhpbnRGb2N1cy0tO1xuXG5cdFx0XHRcdHRoaXMuX3NldEhpbnRJdGVtU2VsZWN0ZWQoKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQnJvd3NlIGhpc3Rvcnlcblx0XHRcdGVsc2Vcblx0XHRcdHtcblx0XHRcdFx0dGhpcy5fc2V0SW5wdXRPbkhpc3RvcnlTZWxlY3RlZCh0aGlzLl9jbWRIaXN0b3J5LnJld2luZCgpKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLy0tLSBBUlJPVyBET1dOIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHRlbHNlIGlmIChrZXlOYW1lID09ICdBcnJvd0Rvd24nKVxuXHRcdHtcblx0XHRcdC8vIElmIGhpbnQgcGFuZWwgaXMgb3Blbiwgc2V0IHNlbGVjdGlvblxuXHRcdFx0aWYgKHRoaXMuX2lzSGludFBhbmVsT3Blbilcblx0XHRcdHtcblx0XHRcdFx0dGhpcy5fY3VyckhpbnRGb2N1cysrO1xuXG5cdFx0XHRcdHRoaXMuX3NldEhpbnRJdGVtU2VsZWN0ZWQoKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQnJvd3NlIGhpc3Rvcnlcblx0XHRcdGVsc2Vcblx0XHRcdHtcblx0XHRcdFx0dGhpcy5fc2V0SW5wdXRPbkhpc3RvcnlTZWxlY3RlZCh0aGlzLl9jbWRIaXN0b3J5LmZvcndhcmQoKSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8tLS0gQVJST1cgTEVGVCAmIFJJR0hUIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdFx0ZWxzZSBpZiAoa2V5TmFtZSA9PSAnQXJyb3dMZWZ0JyB8fCBrZXlOYW1lID09ICdBcnJvd1JpZ2h0Jylcblx0XHR7XG5cdFx0XHQvLyBDbG9zZSBoaW50IHBhbmVsIGlmIG9wZW5cblx0XHRcdGlmICh0aGlzLl9pc0hpbnRQYW5lbE9wZW4pXG5cdFx0XHRcdHRoaXMuX2Nsb3NlSGludFBhbmVsKCk7XG5cdFx0fVxuXG5cdFx0Ly8tLS0gQU5ZIE9USEVSIEtFWSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdFx0ZWxzZVxuXHRcdHtcblx0XHRcdC8vIFVwZGF0ZSB0ZW1wIGluIGNvbW1hbmQgaGlzdG9yeVxuXHRcdFx0dGhpcy5fY21kSGlzdG9yeS5hZGRUZW1wQ29tbWFuZChpbnB1dCk7XG5cblx0XHRcdGlmIChpbnB1dC5sZW5ndGggPT0gJCgnI2Nucy1pbnB1dCcpWzBdLnNlbGVjdGlvbkVuZClcblx0XHRcdHtcblx0XHRcdFx0Ly8gVXBkYXRlIGhpbnQgcGFuZWwgaWYgb3BlblxuXHRcdFx0XHRpZiAodGhpcy5faXNIaW50UGFuZWxPcGVuKVxuXHRcdFx0XHRcdHRoaXMuX3VwZGF0ZUhpbnRQYW5lbCgpO1xuXG5cdFx0XHRcdC8vIFNob3cgaGludCBwYW5lbFxuXHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0dGhpcy5fc2hvd0hpbnRQYW5lbCgpO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0XHQvLyBSZXNldCBoaW50aW5nXG5cdFx0XHRcdHRoaXMuX3Jlc2V0SGludGluZyhpbnB1dCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0X29uQ2xlYXJDb25zb2xlQ2xpY2soKVxuXHR7XG5cdFx0JCgnI2Nucy1jb25zb2xlJykuZW1wdHkoKTtcblx0fVxuXG5cdF9vbkhpbnRJdGVtQ2xpY2soZSlcblx0e1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblxuXHRcdC8vIFNldCBjbGlja2VkIGl0ZW0gYXMgc2VsZWN0ZWRcblx0XHRlLmN1cnJlbnRUYXJnZXQuY2xhc3NMaXN0LmFkZCgnc2VsZWN0ZWQnKTtcblxuXHRcdC8vIFNldCBpbnB1dCB2YWx1ZVxuXHRcdHRoaXMuX3NldElucHV0T25IaW50U2VsZWN0ZWQoKTtcblxuXHRcdC8vIEZvY3VzIG9uIHByb21wdCBpbnB1dFxuXHRcdCQoJyNjbnMtaW5wdXQnKS5mb2N1cygpO1xuXHR9XG5cblx0X29uR2VuZXJpY0NsaWNrKClcblx0e1xuXHRcdC8vIENsb3NlIGhpbnQgcGFuZWwgaWYgb3BlblxuXHRcdGlmICh0aGlzLl9pc0hpbnRQYW5lbE9wZW4pXG5cdFx0XHR0aGlzLl9jbG9zZUhpbnRQYW5lbCgpO1xuXHR9XG5cblx0X29uRXhwb3J0U2Vzc2lvbkNsaWNrKClcblx0e1xuXHRcdGxldCBkYXRlID0gbW9tZW50KCk7XG5cblx0XHRsZXQgdHJhbnNjcmlwdCA9IHRoaXMuVFJBTlNDUklQVF9URU1QTEFURS5yZXBsYWNlKCc8IS0tSEVBREVSLS0+JywgYFNhdmVkIG9uICR7ZGF0ZS5mb3JtYXQoJ2RkZGQsIE1NTU0gRG8gWVlZWSwgSEg6bW06c3MnKX1gKTtcblx0XHR0cmFuc2NyaXB0ID0gdHJhbnNjcmlwdC5yZXBsYWNlKCc8IS0tVFJBTlNDUklQVC0tPicsICQoJyNjbnMtY29uc29sZScpLmh0bWwoKSk7XG5cblx0XHRsZXQgYmxvYiA9IG5ldyBCbG9iKFt0cmFuc2NyaXB0XSwge3R5cGU6ICd0ZXh0L2h0bWw7Y2hhcnNldD11dGYtOCd9KTtcblxuXHRcdEZpbGVTYXZlci5zYXZlQXMoYmxvYiwgYENvbnNvbGVTZXNzaW9uXyR7ZGF0ZS5mb3JtYXQoJ1lZWVlNTUREX0hIbW1zcycpfS5odG1sYCk7XG5cdH1cblxuXHRfb25SdW5TY3JpcHRDbGljaygpXG5cdHtcblx0XHQvLyBPcGVuIG1vZGFsXG5cdFx0dGhpcy5fdXBsb2FkU2NyaXB0TW9kYWwubW9kYWwoJ3Nob3cnKTtcblx0fVxuXG5cdF9vblVwbG9hZFNjcmlwdHJNb2RhbEhpZGRlbigpXG5cdHtcblx0XHQvLyBDbGVhciB1cGxvYWRlclxuXHRcdHRoaXMuX3VwbG9hZGVyLmNsZWFyQWxsRmlsZXMoKTtcblx0fVxuXG5cdF9vblVwbG9hZFNjcmlwdHJCdXR0b25DTGljaygpXG5cdHtcblx0XHRpZiAodGhpcy5fdXBsb2FkZXIuZ2V0RmlsZXMoKS5sZW5ndGggPiAwKVxuXHRcdHtcblx0XHRcdGxldCBmaWxlID0gdGhpcy5fdXBsb2FkZXIuZ2V0RmlsZXMoKVswXS5yYXdGaWxlO1xuXG5cdFx0XHRmaWxlLmFycmF5QnVmZmVyKCkudGhlbihidWZmZXIgPT4ge1xuXHRcdFx0XHR0aGlzLl93cml0ZUNvbnNvbGUoYEVYRUM6ICR7ZmlsZS5uYW1lfWAsIHRydWUpO1xuXG5cdFx0XHRcdGxldCBzZnNvID0gbmV3IFNGUzJYLlNGU09iamVjdCgpO1xuXHRcdFx0XHRzZnNvLnB1dEJ5dGVBcnJheSgnc2NyaXB0JywgbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSk7XG5cblx0XHRcdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9TQ1JJUFQsIHNmc28pO1xuXHRcdFx0fSk7XG5cblx0XHRcdC8vIENsb3NlIG1vZGFsXG5cdFx0XHR0aGlzLl91cGxvYWRTY3JpcHRNb2RhbC5tb2RhbCgnaGlkZScpO1xuXHRcdH1cblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vIFBSSVZBVEUgTUVUSE9EU1xuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdF9zaG93V2VsY29tZU1lc3NhZ2UoKVxuXHR7XG5cdFx0dGhpcy5fd3JpdGVDb25zb2xlKGAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxcbkFETUlOX0NPTlNPTEUsIHZlcnNpb24gJHt0aGlzLlZFUlNJT059XFxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cXG5UeXBlIGhlbHAoKSBmb3IgYXNzaXN0YW5jZS5cXG5gLCBmYWxzZSwgZmFsc2UpO1xuXHR9XG5cblx0X2NsZWFySW5wdXQoKVxuXHR7XG5cdFx0JCgnI2Nucy1pbnB1dCcpLnZhbCgnJyk7XG5cdFx0JCgnI2Nucy1pbnB1dC1kdW1teScpLmh0bWwoJycpO1xuXHR9XG5cblx0X3NldElucHV0T25IaW50U2VsZWN0ZWQoKVxuXHR7XG5cdFx0aWYgKHRoaXMuX2hpbnRQYW5lbClcblx0XHR7XG5cdFx0XHRjb25zdCBpbnB1dCA9ICQoJyNjbnMtaW5wdXQnKS52YWwoKTtcblx0XHRcdGNvbnN0IHNlbGVjdGVkVmFsID0gdGhpcy5faGludFBhbmVsLmZpbmQoJy5oaW50LWl0ZW0uc2VsZWN0ZWQgaW5wdXQnKS52YWwoKTtcblx0XHRcdGNvbnN0IG5ld0lucHV0ID0gaW5wdXQuc3Vic3RyaW5nKDAsIGlucHV0Lmxhc3RJbmRleE9mKCcuJykpICsgJy4nICsgc2VsZWN0ZWRWYWw7XG5cblx0XHRcdCQoJyNjbnMtaW5wdXQnKS52YWwobmV3SW5wdXQpO1xuXHRcdFx0JCgnI2Nucy1pbnB1dC1kdW1teScpLmh0bWwobmV3SW5wdXQpO1xuXG5cdFx0XHR0aGlzLl9jbG9zZUhpbnRQYW5lbCgpO1xuXHRcdH1cblx0fVxuXG5cdF9zZXRJbnB1dE9uSGlzdG9yeVNlbGVjdGVkKGNvbW1hbmQpXG5cdHtcblx0XHQkKCcjY25zLWlucHV0JykudmFsKGNvbW1hbmQpO1xuXHRcdCQoJyNjbnMtaW5wdXQtZHVtbXknKS5odG1sKGNvbW1hbmQpO1xuXHR9XG5cblx0X3dyaXRlQ29uc29sZSh0eHQsIGlzSW5wdXQgPSBmYWxzZSwgbGluZWJyZWFrID0gdHJ1ZSlcblx0e1xuXHRcdGxldCBtc2c7XG5cblx0XHRpZiAoaXNJbnB1dClcblx0XHRcdG1zZyA9IGA8c3BhbiBjbGFzcz1cInRleHQtY29tbWFuZFwiPiZndDsgJHt0eHR9PC9zcGFuPmA7XG5cdFx0ZWxzZVxuXHRcdFx0bXNnID0gYDxzcGFuIGNsYXNzPVwidGV4dC1jb25zb2xlXCI+JHt0eHR9PC9zcGFuPmA7XG5cblx0XHRpZiAobGluZWJyZWFrKVxuXHRcdFx0bXNnID0gYFxcbiR7bXNnfWA7XG5cblx0XHQvLyBBcHBlbmQgdGV4dCB0byBjb25zb2xlXG5cdFx0JCgnI2Nucy1jb25zb2xlJykuYXBwZW5kKG1zZyk7XG5cblx0XHQvLyBzY3JvbGwgY29uc29sZSB0byBib3R0b21cblx0XHQkKCcjY25zLWNvbnNvbGUnKS5zY3JvbGxUb3AoZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLnNjcm9sbEhlaWdodDsgfSk7XG5cdH1cblxuXHRfcGFyc2VIdG1sKHNzKVxuXHR7XG5cdFx0c3MgPSBzcy5yZXBsYWNlKCc8JywgJyZsdDsnKTtcblx0XHRzcyA9IHNzLnJlcGxhY2UoJz4nLCAnJmd0OycpO1xuXG5cdFx0cmV0dXJuIHNzO1xuXHR9XG5cblx0X3Nob3dIaW50UGFuZWwoKVxuXHR7XG5cdFx0aWYgKHRoaXMuX2xhc3RIaW50cyAhPSBudWxsICYmIHRoaXMuX2xhc3RIaW50cy5sZW5ndGggPiAwKVxuXHRcdHtcblx0XHRcdHRoaXMuX2N1cnJIaW50Rm9jdXMgPSAtMTtcblxuXHRcdFx0Ly8gQ3JlYXRlIHBhbmVsXG5cdFx0XHR0aGlzLl9oaW50UGFuZWwgPSAkKCc8ZGl2PicsIHsnY2xhc3MnOiAnaGludC1wYW5lbCd9KTtcblx0XHRcdCQodGhpcykuYXBwZW5kKHRoaXMuX2hpbnRQYW5lbCk7XG5cblx0XHRcdC8vIFNob3cgaGludHNcblx0XHRcdHRoaXMuX3VwZGF0ZUhpbnRQYW5lbCgpO1xuXHRcdH1cblx0fVxuXG5cdF9jbG9zZUhpbnRQYW5lbCgpXG5cdHtcblx0XHR0aGlzLl9oaW50UGFuZWwucmVtb3ZlKCk7XG5cdFx0dGhpcy5faGludFBhbmVsID0gbnVsbDtcblx0fVxuXG5cdF91cGRhdGVIaW50UGFuZWwoKVxuXHR7XG5cdFx0aWYgKHRoaXMuX2xhc3RIaW50cyAhPSBudWxsICYmIHRoaXMuX2xhc3RIaW50cy5sZW5ndGggPiAwKVxuXHRcdHtcblx0XHRcdC8vIENsZWFyIGhpbnRzIHBhbmVsXG5cdFx0XHR0aGlzLl9oaW50UGFuZWwuZW1wdHkoKTtcblxuXHRcdFx0Y29uc3QgZG90SW5kZXggPSAkKCcjY25zLWlucHV0JykudmFsKCkubGFzdEluZGV4T2YoJy4nKTtcblx0XHRcdGxldCBsYXN0V29yZCA9ICcnO1xuXG5cdFx0XHRpZiAoZG90SW5kZXggPiAtMSlcblx0XHRcdFx0bGFzdFdvcmQgPSAkKCcjY25zLWlucHV0JykudmFsKCkuc3Vic3RyKGRvdEluZGV4ICsgMSwgJCgnI2Nucy1pbnB1dCcpLnZhbCgpLmxlbmd0aCk7XG5cblx0XHRcdGxldCBpc0VtcHR5ID0gdHJ1ZTtcblxuXHRcdFx0Zm9yIChsZXQgd29yZCBvZiB0aGlzLl9sYXN0SGludHMpXG5cdFx0XHR7XG5cdFx0XHRcdC8vIENoZWNrIGlmIHRoZSBpdGVtIHN0YXJ0cyB3aXRoIHRoZSBzYW1lIGxldHRlcnMgYXMgdGhlIGlucHV0J3MgbGFzdCB3b3JkXG5cdFx0XHRcdGlmIChsYXN0V29yZCA9PSAnJyB8fCB3b3JkLnN1YnN0cigwLCBsYXN0V29yZC5sZW5ndGgpLnRvVXBwZXJDYXNlKCkgPT0gbGFzdFdvcmQudG9VcHBlckNhc2UoKSlcblx0XHRcdFx0e1xuXHRcdFx0XHRcdC8vIENyZWF0ZSBkaXZcblx0XHRcdFx0XHRsZXQgaXRlbSA9ICQoJzxkaXY+JywgeydjbGFzcyc6ICdoaW50LWl0ZW0nfSk7XG5cblx0XHRcdFx0XHQvLyBTaG93IHZhbHVlLCBhbmQgbWFrZSB0aGUgbWF0Y2hpbmcgbGV0dGVycyBib2xkXG5cdFx0XHRcdFx0aXRlbS5hcHBlbmQoYDxzdHJvbmc+JHt3b3JkLnN1YnN0cigwLCBsYXN0V29yZC5sZW5ndGgpfTwvc3Ryb25nPiR7d29yZC5zdWJzdHIobGFzdFdvcmQubGVuZ3RoKX1gKTtcblxuXHRcdFx0XHRcdC8vIEluc2VydCBhbiBpbnB1dCBmaWVsZCB0aGF0IHdpbGwgaG9sZCB0aGUgY3VycmVudCBpdGVtJ3MgdmFsdWVcblx0XHRcdFx0XHRpdGVtLmFwcGVuZChgPGlucHV0IHR5cGU9XCJoaWRkZW5cIiB2YWx1ZT1cIiR7d29yZH1cIj5gKTtcblxuXHRcdFx0XHRcdC8vIEFkZCBjbGljayBsaXN0ZW5lclxuXHRcdFx0XHRcdGl0ZW0ub24oJ2NsaWNrJywgJC5wcm94eSh0aGlzLl9vbkhpbnRJdGVtQ2xpY2ssIHRoaXMpKTtcblxuXHRcdFx0XHRcdHRoaXMuX2hpbnRQYW5lbC5hcHBlbmQoaXRlbSk7XG5cblx0XHRcdFx0XHRpc0VtcHR5ID0gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgcGFuZWwgaXMgZW1wdHksIHJlbW92ZSBpdFxuXHRcdFx0aWYgKGlzRW1wdHkpXG5cdFx0XHRcdHRoaXMuX2Nsb3NlSGludFBhbmVsKCk7XG5cblx0XHRcdC8vIEVsc2Ugc2V0IHBhbmVsIHBvc2l0aW9uXG5cdFx0XHRlbHNlXG5cdFx0XHR7XG5cdFx0XHRcdGNvbnN0IGV4dENvbnRQb3MgPSAkKCcjY25zLWlucHV0LWNvbnRhaW5lci0yJykucG9zaXRpb24oKTtcblx0XHRcdFx0Y29uc3QgaW50Q29udFBvcyA9ICQoJyNjbnMtaW5wdXQtY29udGFpbmVyLTEnKS5wb3NpdGlvbigpO1xuXG5cdFx0XHRcdGxldCBsZWZ0ID0gZXh0Q29udFBvcy5sZWZ0ICsgaW50Q29udFBvcy5sZWZ0ICsgJCgnI2Nucy1pbnB1dC1kdW1teScpLm91dGVyV2lkdGgoKTtcblx0XHRcdFx0bGV0IHRvcCA9IGV4dENvbnRQb3MudG9wICsgaW50Q29udFBvcy50b3AgLSB0aGlzLl9oaW50UGFuZWwub3V0ZXJIZWlnaHQoKTtcblxuXHRcdFx0XHRpZiAobGVmdCA+IHdpbmRvdy5pbm5lcldpZHRoIC0gdGhpcy5faGludFBhbmVsLm91dGVyV2lkdGgoKSlcblx0XHRcdFx0XHRsZWZ0ID0gd2luZG93LmlubmVyV2lkdGggLSB0aGlzLl9oaW50UGFuZWwub3V0ZXJXaWR0aCgpO1xuXG5cdFx0XHRcdHRoaXMuX2hpbnRQYW5lbC5jc3Moe3RvcDogdG9wLCBsZWZ0OiBsZWZ0LCBwb3NpdGlvbjogJ2Fic29sdXRlJ30pO1xuXG5cdFx0XHRcdC8vIFNlbGVjdCBmaXJzdCBpdGVtXG5cdFx0XHRcdHRoaXMuX2N1cnJIaW50Rm9jdXMgPSAwO1xuXHRcdFx0XHR0aGlzLl9zZXRIaW50SXRlbVNlbGVjdGVkKCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0X3JlcXVlc3RIaW50cyhpbnB1dClcblx0e1xuXHRcdC8vIENsZWFyIHByZXZpb3VzIGhpbnRzXG5cdFx0dGhpcy5fbGFzdEhpbnRzID0gbnVsbDtcblxuXHRcdC8vIFBhcnNlIGlucHV0XG5cdFx0bGV0IGhpbnRQYXJlbnQgPSB0aGlzLl9leHRyYWN0SGludFBhcmVudChpbnB1dCk7XG5cblx0XHQvLyBSZXF1ZXN0IGNvZGUgaGludFxuXHRcdGxldCBwYXJhbXMgPSBuZXcgU0ZTMlguU0ZTT2JqZWN0KCk7XG5cdFx0cGFyYW1zLnB1dFV0ZlN0cmluZygnYycsIGhpbnRQYXJlbnQpO1xuXG5cdFx0dGhpcy5zZW5kRXh0ZW5zaW9uUmVxdWVzdCh0aGlzLlJFUV9ISU5ULCBwYXJhbXMpO1xuXHR9XG5cblx0X2V4dHJhY3RIaW50UGFyZW50KGluVmFsKVxuXHR7XG5cdFx0bGV0IG91dFZhbCA9IG51bGw7XG5cblx0XHRmb3IgKGxldCB0b2sgb2YgdGhpcy5UT0tFTlMpXG5cdFx0e1xuXHRcdFx0Y29uc3QgcCA9IGluVmFsLmluZGV4T2YodG9rKTtcblxuXHRcdFx0aWYgKHAgPiAtMSlcblx0XHRcdHtcblx0XHRcdFx0b3V0VmFsID0gaW5WYWwuc3Vic3RyaW5nKHAgKyB0b2subGVuZ3RoLCBpblZhbC5sZW5ndGgpLnRyaW0oKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKG91dFZhbCA9PSBudWxsKVxuXHRcdFx0b3V0VmFsID0gaW5WYWw7XG5cblx0XHQvLyBSZW1vdmUgZG90IGF0IHRoZSBlbmQgaWYgbmVlZGVkXG5cdFx0aWYgKG91dFZhbC5lbmRzV2l0aCgnLicpKVxuXHRcdFx0b3V0VmFsID0gb3V0VmFsLnN1YnN0cigwLCBvdXRWYWwubGVuZ3RoIC0gMSk7XG5cblx0XHRyZXR1cm4gb3V0VmFsO1xuXHR9XG5cblx0X3NldEhpbnRJdGVtU2VsZWN0ZWQoKVxuXHR7XG5cdFx0bGV0IGl0ZW1zID0gdGhpcy5faGludFBhbmVsLmZpbmQoJy5oaW50LWl0ZW0nKTtcblx0XHRpdGVtcy5yZW1vdmVDbGFzcygnc2VsZWN0ZWQnKTtcblxuXHRcdGlmICh0aGlzLl9jdXJySGludEZvY3VzID49IGl0ZW1zLmxlbmd0aClcblx0XHRcdHRoaXMuX2N1cnJIaW50Rm9jdXMgPSAwO1xuXG4gICAgXHRpZiAodGhpcy5fY3VyckhpbnRGb2N1cyA8IDApXG5cdFx0XHR0aGlzLl9jdXJySGludEZvY3VzID0gaXRlbXMubGVuZ3RoIC0gMTtcblxuXHRcdGxldCBpdGVtID0gaXRlbXMuZXEodGhpcy5fY3VyckhpbnRGb2N1cyk7XG5cdFx0aXRlbS5hZGRDbGFzcygnc2VsZWN0ZWQnKTtcblxuXHRcdC8vIFNjcm9sbCB0byBpdGVtXG5cdFx0dGhpcy5faGludFBhbmVsLnNjcm9sbFRvcCh0aGlzLl9oaW50UGFuZWwuc2Nyb2xsVG9wKCkgKyBpdGVtLnBvc2l0aW9uKCkudG9wKTtcblx0fVxuXG5cdF9yZXNldEhpbnRpbmcoaW5wdXQpXG5cdHtcblx0XHQvLyBDbG9zZSBoaW50IHBhbmVsXG5cdFx0aWYgKHRoaXMuX2lzSGludFBhbmVsT3Blbilcblx0XHRcdHRoaXMuX2Nsb3NlSGludFBhbmVsKCk7XG5cblx0XHQvLyBDbGVhciBoaW50c1xuXHRcdHRoaXMuX2xhc3RIaW50cyA9IG51bGw7XG5cblx0XHQvLyBHZXQgcHJldmlvdXMgd29yZFxuXHRcdGNvbnN0IGRvdEluZGV4ID0gaW5wdXQubGFzdEluZGV4T2YoJy4nKTtcblxuXHRcdGlmIChkb3RJbmRleCA+IC0xKVxuXHRcdHtcblx0XHRcdGxldCB2YWx1ZSA9IGlucHV0LnN1YnN0cmluZygwLCBkb3RJbmRleCk7XG5cblx0XHRcdC8vIFJlcXVlc3QgY29kZSBoaW50c1xuXHRcdFx0dGhpcy5fcmVxdWVzdEhpbnRzKHZhbHVlKTtcblx0XHR9XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBQUklWQVRFIEdFVFRFUlNcblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRnZXQgX2lzSGludFBhbmVsT3BlbigpXG5cdHtcblx0XHRyZXR1cm4gdGhpcy5faGludFBhbmVsICE9IG51bGw7XG5cdH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUNuQkE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ3RGQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0EiLCJzb3VyY2VSb290IjoiIn0=